Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/slate-react/components/leaf.tsx
1698 views
1
import React from "react";
2
import { Element, Text } from "slate";
3
import String from "./string";
4
import { PLACEHOLDER_SYMBOL } from "../utils/weak-maps";
5
import { RenderLeafProps } from "./editable";
6
import { isEqual } from "lodash";
7
8
/**
9
* Individual leaves in a text node with unique formatting.
10
*/
11
12
const Leaf = (props: {
13
isLast: boolean;
14
leaf: Text;
15
parent: Element;
16
renderLeaf?: React.FC<RenderLeafProps>;
17
text: Text;
18
}) => {
19
const {
20
leaf,
21
isLast,
22
text,
23
parent,
24
renderLeaf = (props: RenderLeafProps) => <DefaultLeaf {...props} />,
25
} = props;
26
27
let children = (
28
<String isLast={isLast} leaf={leaf} parent={parent} text={text} />
29
);
30
31
if (leaf[PLACEHOLDER_SYMBOL]) {
32
children = (
33
<React.Fragment>
34
<span
35
contentEditable={false}
36
style={{
37
pointerEvents: "none",
38
display: "inline-block",
39
width: "0",
40
maxWidth: "100%",
41
whiteSpace: "nowrap",
42
opacity: "0.333",
43
userSelect: "none",
44
fontStyle: "normal",
45
fontWeight: "normal",
46
textDecoration: "none",
47
}}
48
>
49
{leaf["placeholder"]}
50
</span>
51
{children}
52
</React.Fragment>
53
);
54
}
55
56
// COMPAT: Having the `data-` attributes on these leaf elements ensures that
57
// in certain misbehaving browsers they aren't weirdly cloned/destroyed by
58
// contenteditable behaviors. (2019/05/08)
59
const attributes: {
60
"data-slate-leaf": true;
61
} = {
62
"data-slate-leaf": true,
63
};
64
65
return React.createElement(renderLeaf, { attributes, children, leaf, text });
66
};
67
68
const MemoizedLeaf = React.memo(Leaf, (prev, next) => {
69
return (
70
next.parent === prev.parent &&
71
next.isLast === prev.isLast &&
72
next.renderLeaf === prev.renderLeaf &&
73
next.text === prev.text &&
74
isEqual(next.leaf, prev.leaf)
75
);
76
});
77
78
export const DefaultLeaf = (props: RenderLeafProps) => {
79
const { attributes, children } = props;
80
return <span {...attributes}>{children}</span>;
81
};
82
83
export default MemoizedLeaf;
84
85