-
-
Notifications
You must be signed in to change notification settings - Fork 380
/
Copy patheditor.tsx
123 lines (113 loc) Β· 3.28 KB
/
editor.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { FC, MutableRefObject, useEffect, useState } from 'react'
import { use100vh } from 'react-div-100vh'
import MarkdownEditor, { Props } from 'rich-markdown-editor'
import { useEditorTheme } from './theme'
import useMounted from 'libs/web/hooks/use-mounted'
import Tooltip from './tooltip'
import extensions from './extensions'
import EditorState from 'libs/web/state/editor'
import { useToast } from 'libs/web/hooks/use-toast'
import { useDictionary } from './dictionary'
import { useEmbeds } from './embeds'
export interface EditorProps extends Pick<Props, 'readOnly'> {
isPreview?: boolean
explicitSave?: boolean
saveState?: (state: boolean) => void
saveRef?: MutableRefObject<(() => void) | undefined>
}
const Editor: FC<EditorProps> = ({
readOnly,
isPreview,
explicitSave,
saveState,
saveRef,
}) => {
const {
onSearchLink,
onCreateLink,
onClickLink,
onUploadImage,
onHoverLink,
onEditorChange,
backlinks,
editorEl,
note,
} = EditorState.useContainer()
const height = use100vh()
const mounted = useMounted()
const editorTheme = useEditorTheme()
const [hasMinHeight, setHasMinHeight] = useState(true)
const toast = useToast()
const dictionary = useDictionary()
const embeds = useEmbeds()
useEffect(() => {
if (isPreview) return
setHasMinHeight((backlinks?.length ?? 0) <= 0)
}, [backlinks, isPreview])
useEffect(() => {
const handleKeyDown = () => {
if (editorEl.current?.value) {
onEditorChange(editorEl.current?.value)
saveState && saveState(true)
}
}
if (saveRef) (saveRef as MutableRefObject<() => void>).current = handleKeyDown
}, [saveState, saveRef, editorEl, onEditorChange])
return (
<>
<MarkdownEditor
readOnly={readOnly}
id={note?.id}
ref={editorEl}
value={mounted ? note?.content : ''}
onChange={
explicitSave ? () => saveState && saveState(false) : onEditorChange
}
onSave={explicitSave ? () => (saveRef as MutableRefObject<() => void>)?.current?.() : undefined}
placeholder={dictionary.editorPlaceholder}
theme={editorTheme}
uploadImage={(file) => onUploadImage(file, note?.id)}
onSearchLink={onSearchLink}
onCreateLink={onCreateLink}
onClickLink={onClickLink}
onHoverLink={onHoverLink}
onShowToast={toast}
dictionary={dictionary}
tooltip={Tooltip}
extensions={extensions}
className="px-4 md:px-0"
embeds={embeds}
/>
<style jsx global>{`
.ProseMirror ul {
list-style-type: disc;
}
.ProseMirror ol {
list-style-type: decimal;
}
.ProseMirror {
${hasMinHeight
? `min-height: calc(${height ? height + 'px' : '100vh'} - 14rem);`
: ''}
padding-bottom: 10rem;
}
.ProseMirror h1 {
font-size: 2.8em;
}
.ProseMirror h2 {
font-size: 1.8em;
}
.ProseMirror h3 {
font-size: 1.5em;
}
.ProseMirror a:not(.bookmark) {
text-decoration: underline;
}
.ProseMirror .image .ProseMirror-selectednode img {
pointer-events: unset;
}
`}</style>
</>
)
}
export default Editor