5htp-core 0.4.8 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/package.json +5 -1
  2. package/src/client/assets/css/components/table.less +2 -0
  3. package/src/client/components/Form.ts +1 -1
  4. package/src/client/components/button.tsx +2 -1
  5. package/src/client/components/containers/Popover/index.tsx +2 -2
  6. package/src/client/components/dropdown/index.tsx +16 -6
  7. package/src/client/components/input/Slider/index.tsx +0 -2
  8. package/src/client/components/inputv3/Rte/Editor.tsx +271 -0
  9. package/src/client/components/inputv3/Rte/ToolbarPlugin/BlockFormat.tsx +220 -0
  10. package/src/client/components/inputv3/Rte/ToolbarPlugin/ElementFormat.tsx +107 -0
  11. package/src/client/components/inputv3/Rte/ToolbarPlugin/index.tsx +768 -0
  12. package/src/client/components/inputv3/Rte/appSettings.ts +36 -0
  13. package/src/client/components/inputv3/Rte/context/FlashMessageContext.tsx +68 -0
  14. package/src/client/components/inputv3/Rte/context/SettingsContext.tsx +71 -0
  15. package/src/client/components/inputv3/Rte/context/SharedAutocompleteContext.tsx +71 -0
  16. package/src/client/components/inputv3/Rte/context/SharedHistoryContext.tsx +35 -0
  17. package/src/client/components/inputv3/Rte/currentEditor.ts +42 -0
  18. package/src/client/components/inputv3/Rte/hooks/useFlashMessage.tsx +16 -0
  19. package/src/client/components/inputv3/Rte/hooks/useReport.ts +67 -0
  20. package/src/client/components/inputv3/Rte/images/emoji/1F600.png +0 -0
  21. package/src/client/components/inputv3/Rte/images/emoji/1F641.png +0 -0
  22. package/src/client/components/inputv3/Rte/images/emoji/1F642.png +0 -0
  23. package/src/client/components/inputv3/Rte/images/emoji/2764.png +0 -0
  24. package/src/client/components/inputv3/Rte/images/emoji/LICENSE.md +5 -0
  25. package/src/client/components/inputv3/Rte/images/icons/draggable-block-menu.svg +1 -0
  26. package/src/client/components/inputv3/Rte/images/icons/prettier-error.svg +1 -0
  27. package/src/client/components/inputv3/Rte/images/icons/prettier.svg +1 -0
  28. package/src/client/components/inputv3/Rte/images/image/LICENSE.md +5 -0
  29. package/src/client/components/inputv3/Rte/images/image-broken.svg +4 -0
  30. package/src/client/components/inputv3/Rte/images/logo.svg +1 -0
  31. package/src/client/components/inputv3/Rte/index.tsx +63 -79
  32. package/src/client/components/inputv3/Rte/nodes/AutocompleteNode.tsx +119 -0
  33. package/src/client/components/inputv3/Rte/nodes/EmojiNode.tsx +102 -0
  34. package/src/client/components/inputv3/Rte/nodes/EquationComponent.tsx +141 -0
  35. package/src/client/components/inputv3/Rte/nodes/EquationNode.tsx +174 -0
  36. package/src/client/components/inputv3/Rte/nodes/FigmaNode.tsx +135 -0
  37. package/src/client/components/inputv3/Rte/nodes/ImageComponent.tsx +468 -0
  38. package/src/client/components/inputv3/Rte/nodes/ImageNode.css +43 -0
  39. package/src/client/components/inputv3/Rte/nodes/ImageNode.tsx +266 -0
  40. package/src/client/components/inputv3/Rte/nodes/InlineImageNode/InlineImageComponent.tsx +402 -0
  41. package/src/client/components/inputv3/Rte/nodes/InlineImageNode/InlineImageNode.css +94 -0
  42. package/src/client/components/inputv3/Rte/nodes/InlineImageNode/InlineImageNode.tsx +294 -0
  43. package/src/client/components/inputv3/Rte/nodes/KeywordNode.ts +67 -0
  44. package/src/client/components/inputv3/Rte/nodes/LayoutContainerNode.ts +137 -0
  45. package/src/client/components/inputv3/Rte/nodes/LayoutItemNode.ts +71 -0
  46. package/src/client/components/inputv3/Rte/nodes/MentionNode.ts +130 -0
  47. package/src/client/components/inputv3/Rte/nodes/PageBreakNode/index.css +62 -0
  48. package/src/client/components/inputv3/Rte/nodes/PageBreakNode/index.tsx +170 -0
  49. package/src/client/components/inputv3/Rte/nodes/PlaygroundNodes.ts +76 -0
  50. package/src/client/components/inputv3/Rte/nodes/PollComponent.tsx +249 -0
  51. package/src/client/components/inputv3/Rte/nodes/PollNode.css +187 -0
  52. package/src/client/components/inputv3/Rte/nodes/PollNode.tsx +209 -0
  53. package/src/client/components/inputv3/Rte/nodes/StickyComponent.tsx +261 -0
  54. package/src/client/components/inputv3/Rte/nodes/StickyNode.css +37 -0
  55. package/src/client/components/inputv3/Rte/nodes/StickyNode.tsx +150 -0
  56. package/src/client/components/inputv3/Rte/nodes/TweetNode.tsx +223 -0
  57. package/src/client/components/inputv3/Rte/nodes/YouTubeNode.tsx +184 -0
  58. package/src/client/components/inputv3/Rte/plugins/ActionsPlugin/index.tsx +334 -0
  59. package/src/client/components/inputv3/Rte/plugins/AutoEmbedPlugin/index.tsx +352 -0
  60. package/src/client/components/inputv3/Rte/plugins/AutoLinkPlugin/index.tsx +32 -0
  61. package/src/client/components/inputv3/Rte/plugins/AutocompletePlugin/index.tsx +2529 -0
  62. package/src/client/components/inputv3/Rte/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx +70 -0
  63. package/src/client/components/inputv3/Rte/plugins/CodeActionMenuPlugin/components/PrettierButton/index.css +14 -0
  64. package/src/client/components/inputv3/Rte/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx +156 -0
  65. package/src/client/components/inputv3/Rte/plugins/CodeActionMenuPlugin/index.css +54 -0
  66. package/src/client/components/inputv3/Rte/plugins/CodeActionMenuPlugin/index.tsx +190 -0
  67. package/src/client/components/inputv3/Rte/plugins/CodeActionMenuPlugin/utils.ts +33 -0
  68. package/src/client/components/inputv3/Rte/plugins/CodeHighlightPlugin/index.ts +21 -0
  69. package/src/client/components/inputv3/Rte/plugins/CollapsiblePlugin/Collapsible.css +57 -0
  70. package/src/client/components/inputv3/Rte/plugins/CollapsiblePlugin/CollapsibleContainerNode.ts +168 -0
  71. package/src/client/components/inputv3/Rte/plugins/CollapsiblePlugin/CollapsibleContentNode.ts +127 -0
  72. package/src/client/components/inputv3/Rte/plugins/CollapsiblePlugin/CollapsibleTitleNode.ts +152 -0
  73. package/src/client/components/inputv3/Rte/plugins/CollapsiblePlugin/CollapsibleUtils.ts +17 -0
  74. package/src/client/components/inputv3/Rte/plugins/CollapsiblePlugin/index.ts +284 -0
  75. package/src/client/components/inputv3/Rte/plugins/ComponentPickerPlugin/index.tsx +370 -0
  76. package/src/client/components/inputv3/Rte/plugins/ContextMenuPlugin/index.tsx +270 -0
  77. package/src/client/components/inputv3/Rte/plugins/DocsPlugin/index.tsx +20 -0
  78. package/src/client/components/inputv3/Rte/plugins/DragDropPastePlugin/index.ts +51 -0
  79. package/src/client/components/inputv3/Rte/plugins/DraggableBlockPlugin/index.css +36 -0
  80. package/src/client/components/inputv3/Rte/plugins/DraggableBlockPlugin/index.tsx +43 -0
  81. package/src/client/components/inputv3/Rte/plugins/EmojiPickerPlugin/index.tsx +198 -0
  82. package/src/client/components/inputv3/Rte/plugins/EmojisPlugin/index.ts +75 -0
  83. package/src/client/components/inputv3/Rte/plugins/EquationsPlugin/index.tsx +82 -0
  84. package/src/client/components/inputv3/Rte/plugins/FigmaPlugin/index.tsx +40 -0
  85. package/src/client/components/inputv3/Rte/plugins/FloatingLinkEditorPlugin/index.css +41 -0
  86. package/src/client/components/inputv3/Rte/plugins/FloatingLinkEditorPlugin/index.tsx +393 -0
  87. package/src/client/components/inputv3/Rte/plugins/FloatingTextFormatToolbarPlugin/index.css +141 -0
  88. package/src/client/components/inputv3/Rte/plugins/FloatingTextFormatToolbarPlugin/index.tsx +388 -0
  89. package/src/client/components/inputv3/Rte/plugins/ImagesPlugin/index.tsx +350 -0
  90. package/src/client/components/inputv3/Rte/plugins/InlineImagePlugin/index.tsx +336 -0
  91. package/src/client/components/inputv3/Rte/plugins/KeywordsPlugin/index.ts +56 -0
  92. package/src/client/components/inputv3/Rte/plugins/LayoutPlugin/InsertLayoutDialog.tsx +58 -0
  93. package/src/client/components/inputv3/Rte/plugins/LayoutPlugin/LayoutPlugin.tsx +219 -0
  94. package/src/client/components/inputv3/Rte/plugins/LinkPlugin/index.tsx +34 -0
  95. package/src/client/components/inputv3/Rte/plugins/ListMaxIndentLevelPlugin/index.ts +85 -0
  96. package/src/client/components/inputv3/Rte/plugins/MarkdownShortcutPlugin/index.tsx +16 -0
  97. package/src/client/components/inputv3/Rte/plugins/MarkdownTransformers/index.ts +324 -0
  98. package/src/client/components/inputv3/Rte/plugins/MaxLengthPlugin/index.tsx +53 -0
  99. package/src/client/components/inputv3/Rte/plugins/MentionsPlugin/index.tsx +696 -0
  100. package/src/client/components/inputv3/Rte/plugins/PageBreakPlugin/index.tsx +57 -0
  101. package/src/client/components/inputv3/Rte/plugins/PasteLogPlugin/index.tsx +54 -0
  102. package/src/client/components/inputv3/Rte/plugins/PollPlugin/index.tsx +86 -0
  103. package/src/client/components/inputv3/Rte/plugins/SpeechToTextPlugin/index.ts +125 -0
  104. package/src/client/components/inputv3/Rte/plugins/StickyPlugin/index.ts +22 -0
  105. package/src/client/components/inputv3/Rte/plugins/TabFocusPlugin/index.tsx +65 -0
  106. package/src/client/components/inputv3/Rte/plugins/TableActionMenuPlugin/index.tsx +773 -0
  107. package/src/client/components/inputv3/Rte/plugins/TableCellResizer/index.css +12 -0
  108. package/src/client/components/inputv3/Rte/plugins/TableCellResizer/index.tsx +436 -0
  109. package/src/client/components/inputv3/Rte/plugins/TableHoverActionsPlugin/index.tsx +287 -0
  110. package/src/client/components/inputv3/Rte/plugins/TableOfContentsPlugin/index.css +95 -0
  111. package/src/client/components/inputv3/Rte/plugins/TableOfContentsPlugin/index.tsx +197 -0
  112. package/src/client/components/inputv3/Rte/plugins/TablePlugin.tsx +178 -0
  113. package/src/client/components/inputv3/Rte/plugins/TestRecorderPlugin/index.tsx +468 -0
  114. package/src/client/components/inputv3/Rte/plugins/TreeViewPlugin/index.tsx +26 -0
  115. package/src/client/components/inputv3/Rte/plugins/TwitterPlugin/index.ts +41 -0
  116. package/src/client/components/inputv3/Rte/plugins/TypingPerfPlugin/index.ts +117 -0
  117. package/src/client/components/inputv3/Rte/plugins/YouTubePlugin/index.ts +41 -0
  118. package/src/client/components/inputv3/Rte/shared/canUseDOM.ts +4 -0
  119. package/src/client/components/inputv3/Rte/shared/caretFromPoint.ts +40 -0
  120. package/src/client/components/inputv3/Rte/shared/environment.ts +56 -0
  121. package/src/client/components/inputv3/Rte/shared/invariant.ts +26 -0
  122. package/src/client/components/inputv3/Rte/shared/normalizeClassNames.ts +21 -0
  123. package/src/client/components/inputv3/Rte/shared/react-test-utils.ts +18 -0
  124. package/src/client/components/inputv3/Rte/shared/reactPatches.ts +22 -0
  125. package/src/client/components/inputv3/Rte/shared/simpleDiffWithCursor.ts +49 -0
  126. package/src/client/components/inputv3/Rte/shared/useLayoutEffect.ts +19 -0
  127. package/src/client/components/inputv3/Rte/shared/warnOnlyOnce.ts +20 -0
  128. package/src/client/components/inputv3/Rte/style.less +30 -60
  129. package/src/client/components/inputv3/Rte/themes/CommentEditorTheme.css +13 -0
  130. package/src/client/components/inputv3/Rte/themes/CommentEditorTheme.ts +20 -0
  131. package/src/client/components/inputv3/Rte/themes/PlaygroundEditorTheme.css +447 -0
  132. package/src/client/components/inputv3/Rte/themes/PlaygroundEditorTheme.ts +120 -0
  133. package/src/client/components/inputv3/Rte/themes/StickyEditorTheme.css +13 -0
  134. package/src/client/components/inputv3/Rte/themes/StickyEditorTheme.ts +20 -0
  135. package/src/client/components/inputv3/Rte/ui/ColorPicker.css +88 -0
  136. package/src/client/components/inputv3/Rte/ui/ColorPicker.tsx +365 -0
  137. package/src/client/components/inputv3/Rte/ui/ContentEditable.css +44 -0
  138. package/src/client/components/inputv3/Rte/ui/ContentEditable.tsx +36 -0
  139. package/src/client/components/inputv3/Rte/ui/DropDown.tsx +259 -0
  140. package/src/client/components/inputv3/Rte/ui/DropdownColorPicker.tsx +41 -0
  141. package/src/client/components/inputv3/Rte/ui/EquationEditor.css +38 -0
  142. package/src/client/components/inputv3/Rte/ui/EquationEditor.tsx +56 -0
  143. package/src/client/components/inputv3/Rte/ui/FileInput.tsx +38 -0
  144. package/src/client/components/inputv3/Rte/ui/FlashMessage.css +28 -0
  145. package/src/client/components/inputv3/Rte/ui/FlashMessage.tsx +29 -0
  146. package/src/client/components/inputv3/Rte/ui/ImageResizer.tsx +316 -0
  147. package/src/client/components/inputv3/Rte/ui/Input.css +32 -0
  148. package/src/client/components/inputv3/Rte/ui/KatexRenderer.tsx +54 -0
  149. package/src/client/components/inputv3/Rte/ui/Switch.tsx +36 -0
  150. package/src/client/components/inputv3/Rte/utils/docSerialization.ts +77 -0
  151. package/src/client/components/inputv3/Rte/utils/emoji-list.ts +16615 -0
  152. package/src/client/components/inputv3/Rte/utils/getDOMRangeRect.ts +27 -0
  153. package/src/client/components/inputv3/Rte/utils/getSelectedNode.ts +27 -0
  154. package/src/client/components/inputv3/Rte/utils/guard.ts +10 -0
  155. package/src/client/components/inputv3/Rte/utils/isMobileWidth.ts +7 -0
  156. package/src/client/components/inputv3/Rte/utils/joinClasses.ts +13 -0
  157. package/src/client/components/inputv3/Rte/utils/setFloatingElemPosition.ts +51 -0
  158. package/src/client/components/inputv3/Rte/utils/setFloatingElemPositionForLinkEditor.ts +46 -0
  159. package/src/client/components/inputv3/Rte/utils/swipe.ts +127 -0
  160. package/src/client/components/inputv3/Rte/utils/url.ts +38 -0
  161. package/src/client/components/inputv3/base.tsx +8 -5
  162. package/src/client/components/inputv3/file/index.tsx +11 -5
  163. package/src/common/data/rte/nodes.ts +60 -9
  164. package/src/common/validation/index.ts +21 -2
  165. package/src/common/validation/schema.ts +42 -10
  166. package/src/common/validation/validator.ts +12 -4
  167. package/src/common/validation/validators.ts +82 -53
  168. package/src/server/services/router/http/multipart.ts +0 -1
  169. package/src/server/services/schema/index.ts +24 -2
  170. package/src/server/services/schema/request.ts +3 -2
  171. package/src/server/services/schema/rte.ts +110 -0
  172. package/src/{common/data/rte/index.ts → server/utils/rte.ts} +27 -16
  173. package/src/client/components/inputv3/Rte/ExampleTheme.tsx +0 -42
  174. package/src/client/components/inputv3/Rte/ToolbarPlugin.tsx +0 -167
  175. package/src/client/components/inputv3/Rte/icons/LICENSE.md +0 -5
  176. package/src/client/components/inputv3/Rte/icons/arrow-clockwise.svg +0 -4
  177. package/src/client/components/inputv3/Rte/icons/arrow-counterclockwise.svg +0 -4
  178. package/src/client/components/inputv3/Rte/icons/journal-text.svg +0 -5
  179. package/src/client/components/inputv3/Rte/icons/justify.svg +0 -3
  180. package/src/client/components/inputv3/Rte/icons/text-center.svg +0 -3
  181. package/src/client/components/inputv3/Rte/icons/text-left.svg +0 -3
  182. package/src/client/components/inputv3/Rte/icons/text-paragraph.svg +0 -3
  183. package/src/client/components/inputv3/Rte/icons/text-right.svg +0 -3
  184. package/src/client/components/inputv3/Rte/icons/type-bold.svg +0 -3
  185. package/src/client/components/inputv3/Rte/icons/type-italic.svg +0 -3
  186. package/src/client/components/inputv3/Rte/icons/type-strikethrough.svg +0 -3
  187. package/src/client/components/inputv3/Rte/icons/type-underline.svg +0 -3
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import {
10
+ DOMConversionMap,
11
+ DOMConversionOutput,
12
+ DOMExportOutput,
13
+ EditorConfig,
14
+ ElementNode,
15
+ isHTMLElement,
16
+ LexicalEditor,
17
+ LexicalNode,
18
+ NodeKey,
19
+ SerializedElementNode,
20
+ Spread,
21
+ } from 'lexical';
22
+ import {IS_CHROME} from '../../shared/environment';
23
+ import invariant from '../../shared/invariant';
24
+
25
+ import {setDomHiddenUntilFound} from './CollapsibleUtils';
26
+
27
+ type SerializedCollapsibleContainerNode = Spread<
28
+ {
29
+ open: boolean;
30
+ },
31
+ SerializedElementNode
32
+ >;
33
+
34
+ export function $convertDetailsElement(
35
+ domNode: HTMLDetailsElement,
36
+ ): DOMConversionOutput | null {
37
+ const isOpen = domNode.open !== undefined ? domNode.open : true;
38
+ const node = $createCollapsibleContainerNode(isOpen);
39
+ return {
40
+ node,
41
+ };
42
+ }
43
+
44
+ export class CollapsibleContainerNode extends ElementNode {
45
+ __open: boolean;
46
+
47
+ constructor(open: boolean, key?: NodeKey) {
48
+ super(key);
49
+ this.__open = open;
50
+ }
51
+
52
+ static getType(): string {
53
+ return 'collapsible-container';
54
+ }
55
+
56
+ static clone(node: CollapsibleContainerNode): CollapsibleContainerNode {
57
+ return new CollapsibleContainerNode(node.__open, node.__key);
58
+ }
59
+
60
+ createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {
61
+ // details is not well supported in Chrome #5582
62
+ let dom: HTMLElement;
63
+ if (IS_CHROME) {
64
+ dom = document.createElement('div');
65
+ dom.setAttribute('open', '');
66
+ } else {
67
+ const detailsDom = document.createElement('details');
68
+ detailsDom.open = this.__open;
69
+ detailsDom.addEventListener('toggle', () => {
70
+ const open = editor.getEditorState().read(() => this.getOpen());
71
+ if (open !== detailsDom.open) {
72
+ editor.update(() => this.toggleOpen());
73
+ }
74
+ });
75
+ dom = detailsDom;
76
+ }
77
+ dom.classList.add('Collapsible__container');
78
+
79
+ return dom;
80
+ }
81
+
82
+ updateDOM(
83
+ prevNode: CollapsibleContainerNode,
84
+ dom: HTMLDetailsElement,
85
+ ): boolean {
86
+ const currentOpen = this.__open;
87
+ if (prevNode.__open !== currentOpen) {
88
+ // details is not well supported in Chrome #5582
89
+ if (IS_CHROME) {
90
+ const contentDom = dom.children[1];
91
+ invariant(
92
+ isHTMLElement(contentDom),
93
+ 'Expected contentDom to be an HTMLElement',
94
+ );
95
+ if (currentOpen) {
96
+ dom.setAttribute('open', '');
97
+ contentDom.hidden = false;
98
+ } else {
99
+ dom.removeAttribute('open');
100
+ setDomHiddenUntilFound(contentDom);
101
+ }
102
+ } else {
103
+ dom.open = this.__open;
104
+ }
105
+ }
106
+
107
+ return false;
108
+ }
109
+
110
+ static importDOM(): DOMConversionMap<HTMLDetailsElement> | null {
111
+ return {
112
+ details: (domNode: HTMLDetailsElement) => {
113
+ return {
114
+ conversion: $convertDetailsElement,
115
+ priority: 1,
116
+ };
117
+ },
118
+ };
119
+ }
120
+
121
+ static importJSON(
122
+ serializedNode: SerializedCollapsibleContainerNode,
123
+ ): CollapsibleContainerNode {
124
+ const node = $createCollapsibleContainerNode(serializedNode.open);
125
+ return node;
126
+ }
127
+
128
+ exportDOM(): DOMExportOutput {
129
+ const element = document.createElement('details');
130
+ element.classList.add('Collapsible__container');
131
+ element.setAttribute('open', this.__open.toString());
132
+ return {element};
133
+ }
134
+
135
+ exportJSON(): SerializedCollapsibleContainerNode {
136
+ return {
137
+ ...super.exportJSON(),
138
+ open: this.__open,
139
+ type: 'collapsible-container',
140
+ version: 1,
141
+ };
142
+ }
143
+
144
+ setOpen(open: boolean): void {
145
+ const writable = this.getWritable();
146
+ writable.__open = open;
147
+ }
148
+
149
+ getOpen(): boolean {
150
+ return this.getLatest().__open;
151
+ }
152
+
153
+ toggleOpen(): void {
154
+ this.setOpen(!this.getOpen());
155
+ }
156
+ }
157
+
158
+ export function $createCollapsibleContainerNode(
159
+ isOpen: boolean,
160
+ ): CollapsibleContainerNode {
161
+ return new CollapsibleContainerNode(isOpen);
162
+ }
163
+
164
+ export function $isCollapsibleContainerNode(
165
+ node: LexicalNode | null | undefined,
166
+ ): node is CollapsibleContainerNode {
167
+ return node instanceof CollapsibleContainerNode;
168
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import {
10
+ DOMConversionMap,
11
+ DOMConversionOutput,
12
+ DOMExportOutput,
13
+ EditorConfig,
14
+ ElementNode,
15
+ LexicalEditor,
16
+ LexicalNode,
17
+ SerializedElementNode,
18
+ } from 'lexical';
19
+ import {IS_CHROME} from '../../shared/environment';
20
+ import invariant from '../../shared/invariant';
21
+
22
+ import {$isCollapsibleContainerNode} from './CollapsibleContainerNode';
23
+ import {domOnBeforeMatch, setDomHiddenUntilFound} from './CollapsibleUtils';
24
+
25
+ type SerializedCollapsibleContentNode = SerializedElementNode;
26
+
27
+ export function $convertCollapsibleContentElement(
28
+ domNode: HTMLElement,
29
+ ): DOMConversionOutput | null {
30
+ const node = $createCollapsibleContentNode();
31
+ return {
32
+ node,
33
+ };
34
+ }
35
+
36
+ export class CollapsibleContentNode extends ElementNode {
37
+ static getType(): string {
38
+ return 'collapsible-content';
39
+ }
40
+
41
+ static clone(node: CollapsibleContentNode): CollapsibleContentNode {
42
+ return new CollapsibleContentNode(node.__key);
43
+ }
44
+
45
+ createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {
46
+ const dom = document.createElement('div');
47
+ dom.classList.add('Collapsible__content');
48
+ if (IS_CHROME) {
49
+ editor.getEditorState().read(() => {
50
+ const containerNode = this.getParentOrThrow();
51
+ invariant(
52
+ $isCollapsibleContainerNode(containerNode),
53
+ 'Expected parent node to be a CollapsibleContainerNode',
54
+ );
55
+ if (!containerNode.__open) {
56
+ setDomHiddenUntilFound(dom);
57
+ }
58
+ });
59
+ domOnBeforeMatch(dom, () => {
60
+ editor.update(() => {
61
+ const containerNode = this.getParentOrThrow().getLatest();
62
+ invariant(
63
+ $isCollapsibleContainerNode(containerNode),
64
+ 'Expected parent node to be a CollapsibleContainerNode',
65
+ );
66
+ if (!containerNode.__open) {
67
+ containerNode.toggleOpen();
68
+ }
69
+ });
70
+ });
71
+ }
72
+ return dom;
73
+ }
74
+
75
+ updateDOM(prevNode: CollapsibleContentNode, dom: HTMLElement): boolean {
76
+ return false;
77
+ }
78
+
79
+ static importDOM(): DOMConversionMap | null {
80
+ return {
81
+ div: (domNode: HTMLElement) => {
82
+ if (!domNode.hasAttribute('data-lexical-collapsible-content')) {
83
+ return null;
84
+ }
85
+ return {
86
+ conversion: $convertCollapsibleContentElement,
87
+ priority: 2,
88
+ };
89
+ },
90
+ };
91
+ }
92
+
93
+ exportDOM(): DOMExportOutput {
94
+ const element = document.createElement('div');
95
+ element.classList.add('Collapsible__content');
96
+ element.setAttribute('data-lexical-collapsible-content', 'true');
97
+ return {element};
98
+ }
99
+
100
+ static importJSON(
101
+ serializedNode: SerializedCollapsibleContentNode,
102
+ ): CollapsibleContentNode {
103
+ return $createCollapsibleContentNode();
104
+ }
105
+
106
+ isShadowRoot(): boolean {
107
+ return true;
108
+ }
109
+
110
+ exportJSON(): SerializedCollapsibleContentNode {
111
+ return {
112
+ ...super.exportJSON(),
113
+ type: 'collapsible-content',
114
+ version: 1,
115
+ };
116
+ }
117
+ }
118
+
119
+ export function $createCollapsibleContentNode(): CollapsibleContentNode {
120
+ return new CollapsibleContentNode();
121
+ }
122
+
123
+ export function $isCollapsibleContentNode(
124
+ node: LexicalNode | null | undefined,
125
+ ): node is CollapsibleContentNode {
126
+ return node instanceof CollapsibleContentNode;
127
+ }
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import {
10
+ $createParagraphNode,
11
+ $isElementNode,
12
+ DOMConversionMap,
13
+ DOMConversionOutput,
14
+ EditorConfig,
15
+ ElementNode,
16
+ LexicalEditor,
17
+ LexicalNode,
18
+ RangeSelection,
19
+ SerializedElementNode,
20
+ } from 'lexical';
21
+ import {IS_CHROME} from '../../shared/environment';
22
+ import invariant from '../../shared/invariant';
23
+
24
+ import {$isCollapsibleContainerNode} from './CollapsibleContainerNode';
25
+ import {$isCollapsibleContentNode} from './CollapsibleContentNode';
26
+
27
+ type SerializedCollapsibleTitleNode = SerializedElementNode;
28
+
29
+ export function $convertSummaryElement(
30
+ domNode: HTMLElement,
31
+ ): DOMConversionOutput | null {
32
+ const node = $createCollapsibleTitleNode();
33
+ return {
34
+ node,
35
+ };
36
+ }
37
+
38
+ export class CollapsibleTitleNode extends ElementNode {
39
+ static getType(): string {
40
+ return 'collapsible-title';
41
+ }
42
+
43
+ static clone(node: CollapsibleTitleNode): CollapsibleTitleNode {
44
+ return new CollapsibleTitleNode(node.__key);
45
+ }
46
+
47
+ createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {
48
+ const dom = document.createElement('summary');
49
+ dom.classList.add('Collapsible__title');
50
+ if (IS_CHROME) {
51
+ dom.addEventListener('click', () => {
52
+ editor.update(() => {
53
+ const collapsibleContainer = this.getLatest().getParentOrThrow();
54
+ invariant(
55
+ $isCollapsibleContainerNode(collapsibleContainer),
56
+ 'Expected parent node to be a CollapsibleContainerNode',
57
+ );
58
+ collapsibleContainer.toggleOpen();
59
+ });
60
+ });
61
+ }
62
+ return dom;
63
+ }
64
+
65
+ updateDOM(prevNode: CollapsibleTitleNode, dom: HTMLElement): boolean {
66
+ return false;
67
+ }
68
+
69
+ static importDOM(): DOMConversionMap | null {
70
+ return {
71
+ summary: (domNode: HTMLElement) => {
72
+ return {
73
+ conversion: $convertSummaryElement,
74
+ priority: 1,
75
+ };
76
+ },
77
+ };
78
+ }
79
+
80
+ static importJSON(
81
+ serializedNode: SerializedCollapsibleTitleNode,
82
+ ): CollapsibleTitleNode {
83
+ return $createCollapsibleTitleNode();
84
+ }
85
+
86
+ exportJSON(): SerializedCollapsibleTitleNode {
87
+ return {
88
+ ...super.exportJSON(),
89
+ type: 'collapsible-title',
90
+ version: 1,
91
+ };
92
+ }
93
+
94
+ collapseAtStart(_selection: RangeSelection): boolean {
95
+ this.getParentOrThrow().insertBefore(this);
96
+ return true;
97
+ }
98
+
99
+ static transform(): (node: LexicalNode) => void {
100
+ return (node: LexicalNode) => {
101
+ invariant(
102
+ $isCollapsibleTitleNode(node),
103
+ 'node is not a CollapsibleTitleNode',
104
+ );
105
+ if (node.isEmpty()) {
106
+ node.remove();
107
+ }
108
+ };
109
+ }
110
+
111
+ insertNewAfter(_: RangeSelection, restoreSelection = true): ElementNode {
112
+ const containerNode = this.getParentOrThrow();
113
+
114
+ if (!$isCollapsibleContainerNode(containerNode)) {
115
+ throw new Error(
116
+ 'CollapsibleTitleNode expects to be child of CollapsibleContainerNode',
117
+ );
118
+ }
119
+
120
+ if (containerNode.getOpen()) {
121
+ const contentNode = this.getNextSibling();
122
+ if (!$isCollapsibleContentNode(contentNode)) {
123
+ throw new Error(
124
+ 'CollapsibleTitleNode expects to have CollapsibleContentNode sibling',
125
+ );
126
+ }
127
+
128
+ const firstChild = contentNode.getFirstChild();
129
+ if ($isElementNode(firstChild)) {
130
+ return firstChild;
131
+ } else {
132
+ const paragraph = $createParagraphNode();
133
+ contentNode.append(paragraph);
134
+ return paragraph;
135
+ }
136
+ } else {
137
+ const paragraph = $createParagraphNode();
138
+ containerNode.insertAfter(paragraph, restoreSelection);
139
+ return paragraph;
140
+ }
141
+ }
142
+ }
143
+
144
+ export function $createCollapsibleTitleNode(): CollapsibleTitleNode {
145
+ return new CollapsibleTitleNode();
146
+ }
147
+
148
+ export function $isCollapsibleTitleNode(
149
+ node: LexicalNode | null | undefined,
150
+ ): node is CollapsibleTitleNode {
151
+ return node instanceof CollapsibleTitleNode;
152
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ export function setDomHiddenUntilFound(dom: HTMLElement): void {
10
+ // @ts-expect-error
11
+ dom.hidden = 'until-found';
12
+ }
13
+
14
+ export function domOnBeforeMatch(dom: HTMLElement, callback: () => void): void {
15
+ // @ts-expect-error
16
+ dom.onbeforematch = callback;
17
+ }