Skip to content

Commit

Permalink
Add support for markdown in notes (#1587)
Browse files Browse the repository at this point in the history
  • Loading branch information
OlegWock authored Sep 4, 2023
1 parent 63c3d07 commit 65899b0
Show file tree
Hide file tree
Showing 5 changed files with 1,055 additions and 14 deletions.
3 changes: 3 additions & 0 deletions packages/desktop-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"inter-ui": "^3.19.3",
"jest": "^27.0.0",
"jest-watch-typeahead": "^2.2.2",
"mdast-util-newline-to-break": "^2.0.0",
"memoize-one": "^6.0.0",
"pikaday": "1.8.0",
"react": "18.2.0",
Expand All @@ -44,6 +45,7 @@
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.2.0",
"react-error-boundary": "^4.0.11",
"react-markdown": "^8.0.7",
"react-merge-refs": "^1.1.0",
"react-modal": "3.16.1",
"react-redux": "7.2.1",
Expand All @@ -53,6 +55,7 @@
"react-virtualized-auto-sizer": "^1.0.2",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"remark-gfm": "^3.0.1",
"sass": "^1.63.6",
"uuid": "^9.0.0",
"victory": "^36.6.8",
Expand Down
88 changes: 77 additions & 11 deletions packages/desktop-client/src/components/NotesButton.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,88 @@
import React, { createRef, useState, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';

import { css } from 'glamor';
import remarkGfm from 'remark-gfm';

import q from 'loot-core/src/client/query-helpers';
import { useLiveQuery } from 'loot-core/src/client/query-hooks';
import { send } from 'loot-core/src/platform/client/fetch';

import CustomNotesPaper from '../icons/v2/CustomNotesPaper';
import { type CSSProperties, colors } from '../style';
import { remarkBreaks, sequentialNewlinesPlugin } from '../util/markdown';

import Button from './common/Button';
import Text from './common/Text';
import View from './common/View';
import { Tooltip, useTooltip } from './tooltips';

const remarkPlugins = [sequentialNewlinesPlugin, remarkGfm, remarkBreaks];

const markdownStyles = css({
display: 'block',
maxWidth: 350,
padding: 8,
overflowWrap: 'break-word',
'& p': {
margin: 0,
':not(:first-child)': {
marginTop: '0.25rem',
},
},
'& ul, & ol': {
listStylePosition: 'inside',
margin: 0,
paddingLeft: 0,
},
'&>* ul, &>* ol': {
marginLeft: '1.5rem',
},
'& li>p': {
display: 'contents',
},
'& blockquote': {
paddingLeft: '0.75rem',
borderLeft: '3px solid ' + colors.p6,
margin: 0,
},
'& hr': {
borderTop: 'none',
borderLeft: 'none',
borderRight: 'none',
borderBottom: '1px solid ' + colors.p9,
},
'& code': {
backgroundColor: colors.p10,
padding: '0.1rem 0.5rem',
borderRadius: '0.25rem',
},
'& pre': {
padding: '0.5rem',
backgroundColor: colors.p10,
borderRadius: '0.5rem',
margin: 0,
':not(:first-child)': {
marginTop: '0.25rem',
},
'& code': {
background: 'inherit',
padding: 0,
borderRadius: 0,
},
},
'& table, & th, & td': {
border: '1px solid ' + colors.p9,
},
'& table': {
borderCollapse: 'collapse',
wordBreak: 'break-word',
},
'& td': {
padding: '0.25rem 0.75rem',
},
});

type NotesTooltipProps = {
editable?: boolean;
defaultNotes?: string;
Expand Down Expand Up @@ -43,24 +112,21 @@ function NotesTooltip({
{...css({
border: '1px solid ' + colors.border,
padding: 7,
minWidth: 300,
minWidth: 350,
minHeight: 120,
outline: 'none',
})}
value={notes || ''}
onChange={e => setNotes(e.target.value)}
placeholder="Notes (markdown supported)"
/>
) : (
<Text
style={{
display: 'block',
maxWidth: 225,
padding: 8,
whiteSpace: 'pre-wrap',
overflowWrap: 'break-word',
}}
>
{notes}
<Text {...markdownStyles}>
<ReactMarkdown
remarkPlugins={remarkPlugins}
linkTarget="_blank"
children={notes}
/>
</Text>
)}
</Tooltip>
Expand Down
38 changes: 38 additions & 0 deletions packages/desktop-client/src/util/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { newlineToBreak } from 'mdast-util-newline-to-break';

export function sequentialNewlinesPlugin() {
// Adapted from https://codesandbox.io/s/create-react-app-forked-h3rmcy?file=/src/sequentialNewlinePlugin.js:0-774
const data = this.data();

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function add(field: string, value: any) {
const list = data[field] ? data[field] : (data[field] = []);

list.push(value);
}

add('fromMarkdownExtensions', {
enter: {
lineEndingBlank: function enterLineEndingBlank(token: unknown) {
this.enter(
{
type: 'break',
value: '',
data: {},
children: [],
},
token,
);
},
},
exit: {
lineEndingBlank: function exitLineEndingBlank(token: unknown) {
this.exit(token);
},
},
});
}

export function remarkBreaks() {
return newlineToBreak;
}
6 changes: 6 additions & 0 deletions upcoming-release-notes/1587.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [OlegWock]
---

Support markdown in notes
Loading

0 comments on commit 65899b0

Please sign in to comment.