Newer
Older
import React, { createRef, useState, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
Joel Jeremy Marquez
committed
import { css } from 'glamor';
import { useLiveQuery } from 'loot-core/src/client/query-hooks';
import { send } from 'loot-core/src/platform/client/fetch';
import CustomNotesPaper from '../icons/v2/CustomNotesPaper';
Joel Jeremy Marquez
committed
import { type CSSProperties, colors } from '../style';
import { remarkBreaks, sequentialNewlinesPlugin } from '../util/markdown';
Matiss Janis Aboltins
committed
import Button from './common/Button';
import Text from './common/Text';
import View from './common/View';
import { Tooltip, useTooltip } from './tooltips';
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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;
position?: string;
onClose?: (notes: string) => void;
};
function NotesTooltip({
}: NotesTooltipProps) {
let [notes, setNotes] = useState<string>(defaultNotes);
let inputRef = createRef<HTMLTextAreaElement>();
if (editable) {
inputRef.current.focus();
}
}, [inputRef, editable]);
return (
<Tooltip position={position} onClose={() => onClose(notes)}>
{editable ? (
<textarea
ref={inputRef}
{...css({
border: '1px solid ' + colors.border,
padding: 7,
})}
value={notes || ''}
onChange={e => setNotes(e.target.value)}
placeholder="Notes (markdown supported)"
<Text {...markdownStyles}>
<ReactMarkdown
remarkPlugins={remarkPlugins}
linkTarget="_blank"
children={notes}
/>
type NotesButtonProps = {
id: string;
width?: number;
height?: number;
defaultColor?: string;
tooltipPosition?: string;
style?: CSSProperties;
};
export default function NotesButton({
id,
width = 12,
height = 12,
defaultColor = colors.n8,
tooltipPosition,
let [hover, setHover] = useState(false);
let data = useLiveQuery(() => q('notes').filter({ id }).select('*'), [id]);
let note = data && data.length > 0 ? data[0].note : null;
let hasNotes = note && note !== '';
function onClose(notes) {
send('notes-save', { id, note: notes });
tooltip.close();
}
const [delayHandler, setDelayHandler] = useState(null);
const handleMouseEnter = () => {
setDelayHandler(
setTimeout(() => {
setHover(true);
}, 300),
);
};
const handleMouseLeave = () => {
clearTimeout(delayHandler);
setHover(false);
};
// This account for both the tooltip hover, and editing tooltip
const tooltipOpen = tooltip.isOpen || (hasNotes && hover);
Joel Jeremy Marquez
committed
style={{ flexShrink: 0 }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className={!hasNotes && !tooltipOpen ? 'hover-visible' : ''}
Joel Jeremy Marquez
committed
style={{
color: defaultColor,
...style,
...(hasNotes && { display: 'flex !important' }),
...(tooltipOpen && { color: colors.n1 }),
}}
<CustomNotesPaper style={{ width, height }} />
{tooltipOpen && (
editable={tooltip.isOpen}
defaultNotes={note}
position={tooltipPosition}
onClose={onClose}
/>
)}
</View>
);
}