-
-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathutils.ts
More file actions
67 lines (58 loc) · 1.51 KB
/
utils.ts
File metadata and controls
67 lines (58 loc) · 1.51 KB
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
import * as React from 'react'
import { useEffect, useRef, useState } from 'react'
import { flushSync } from 'react-dom'
export function Root({ children, rendered }: { children: React.JSX.Element | null, rendered: () => void }) {
useEffect(() => {
rendered()
})
return children
}
export function syncFlush() {
const ready = useRef(false)
useEffect(() => {
ready.current = true
}, [])
return {
apply(f: () => void) {
if (ready.current) {
queueMicrotask(() => {
flushSync(f)
})
} else {
f()
}
}
}
}
export function useRete<T extends { destroy(): void }>(create: (el: HTMLElement) => Promise<T>) {
const [container, setContainer] = useState<null | HTMLElement>(null)
const editorRef = useRef<T>(undefined)
const [editor, setEditor] = useState<T | null>(null)
// compatible RefObject type for React 18 and earlier
const ref = useRef<HTMLDivElement>(null) as React.RefObject<HTMLDivElement>
useEffect(() => {
if (container) {
if (editorRef.current) {
editorRef.current.destroy()
container.innerHTML = ''
}
void create(container).then(value => {
editorRef.current = value
setEditor(value)
})
}
}, [container, create])
useEffect(() => {
return () => {
if (editorRef.current) {
editorRef.current.destroy()
}
}
}, [])
useEffect(() => {
if (ref.current) {
setContainer(ref.current)
}
}, [ref.current])
return [ref, editor] as const
}