forked from ianstormtaylor/slate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuse-children.tsx
105 lines (95 loc) · 2.63 KB
/
use-children.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
import React from 'react'
import {
Ancestor,
Descendant,
Editor,
Element,
Range,
DecoratedRange,
} from 'slate'
import {
RenderElementProps,
RenderLeafProps,
RenderPlaceholderProps,
} from '../components/editable'
import ElementComponent from '../components/element'
import TextComponent from '../components/text'
import { ReactEditor } from '../plugin/react-editor'
import { IS_NODE_MAP_DIRTY, NODE_TO_INDEX, NODE_TO_PARENT } from 'slate-dom'
import { useDecorate } from './use-decorate'
import { SelectedContext } from './use-selected'
import { useSlateStatic } from './use-slate-static'
/**
* Children.
*/
const useChildren = (props: {
decorations: DecoratedRange[]
node: Ancestor
renderElement?: (props: RenderElementProps) => JSX.Element
renderPlaceholder: (props: RenderPlaceholderProps) => JSX.Element
renderLeaf?: (props: RenderLeafProps) => JSX.Element
selection: Range | null
}) => {
const {
decorations,
node,
renderElement,
renderPlaceholder,
renderLeaf,
selection,
} = props
const decorate = useDecorate()
const editor = useSlateStatic()
IS_NODE_MAP_DIRTY.set(editor as ReactEditor, false)
const path = ReactEditor.findPath(editor, node)
const children = []
const isLeafBlock =
Element.isElement(node) &&
!editor.isInline(node) &&
Editor.hasInlines(editor, node)
for (let i = 0; i < node.children.length; i++) {
const p = path.concat(i)
const n = node.children[i] as Descendant
const key = ReactEditor.findKey(editor, n)
const range = Editor.range(editor, p)
const sel = selection && Range.intersection(range, selection)
const ds = decorate([n, p])
for (const dec of decorations) {
const d = Range.intersection(dec, range)
if (d) {
ds.push(d)
}
}
if (Element.isElement(n)) {
children.push(
<SelectedContext.Provider key={`provider-${key.id}`} value={!!sel}>
<ElementComponent
decorations={ds}
element={n}
key={key.id}
renderElement={renderElement}
renderPlaceholder={renderPlaceholder}
renderLeaf={renderLeaf}
selection={sel}
/>
</SelectedContext.Provider>
)
} else {
children.push(
<TextComponent
decorations={ds}
key={key.id}
isLast={isLeafBlock && i === node.children.length - 1}
parent={node}
renderPlaceholder={renderPlaceholder}
renderLeaf={renderLeaf}
text={n}
/>
)
}
NODE_TO_INDEX.set(n, i)
NODE_TO_PARENT.set(n, node)
}
return children
}
export default useChildren