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,94 @@
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
+
10
+ .InlineImageNode__contentEditable {
11
+ min-height: 20px;
12
+ border: 0px;
13
+ resize: none;
14
+ cursor: text;
15
+ caret-color: rgb(5, 5, 5);
16
+ display: block;
17
+ position: relative;
18
+ tab-size: 1;
19
+ outline: 0px;
20
+ padding: 10px;
21
+ user-select: text;
22
+ font-size: 14px;
23
+ line-height: 1.4em;
24
+ width: calc(100% - 20px);
25
+ white-space: pre-wrap;
26
+ word-break: break-word;
27
+ }
28
+
29
+ .InlineImageNode__placeholder {
30
+ font-size: 12px;
31
+ color: #888;
32
+ overflow: hidden;
33
+ position: absolute;
34
+ text-overflow: ellipsis;
35
+ bottom: 10px;
36
+ left: 10px;
37
+ user-select: none;
38
+ white-space: nowrap;
39
+ display: inline-block;
40
+ pointer-events: none;
41
+ }
42
+
43
+ .InlineImageNode_Checkbox:checked,
44
+ .InlineImageNode_Checkbox:not(:checked) {
45
+ position: absolute;
46
+ left: -9999px;
47
+ }
48
+
49
+ .InlineImageNode_Checkbox:checked + label,
50
+ .InlineImageNode_Checkbox:not(:checked) + label {
51
+ position: absolute;
52
+ padding-right: 55px;
53
+ cursor: pointer;
54
+ line-height: 20px;
55
+ display: inline-block;
56
+ color: #666;
57
+ }
58
+
59
+ .InlineImageNode_Checkbox:checked + label:before,
60
+ .InlineImageNode_Checkbox:not(:checked) + label:before {
61
+ content: '';
62
+ position: absolute;
63
+ right: 0;
64
+ top: 0;
65
+ width: 18px;
66
+ height: 18px;
67
+ border: 1px solid #666;
68
+ background: #fff;
69
+ }
70
+
71
+ .InlineImageNode_Checkbox:checked + label:after,
72
+ .InlineImageNode_Checkbox:not(:checked) + label:after {
73
+ content: '';
74
+ width: 8px;
75
+ height: 8px;
76
+ background: #222222;
77
+ position: absolute;
78
+ top: 6px;
79
+ right: 6px;
80
+ -webkit-transition: all 0.2s ease;
81
+ transition: all 0.2s ease;
82
+ }
83
+
84
+ .InlineImageNode_Checkbox:not(:checked) + label:after {
85
+ opacity: 0;
86
+ -webkit-transform: scale(0);
87
+ transform: scale(0);
88
+ }
89
+
90
+ .InlineImageNode_Checkbox:checked + label:after {
91
+ opacity: 1;
92
+ -webkit-transform: scale(1);
93
+ transform: scale(1);
94
+ }
@@ -0,0 +1,294 @@
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 type {
10
+ DOMConversionMap,
11
+ DOMConversionOutput,
12
+ DOMExportOutput,
13
+ EditorConfig,
14
+ LexicalEditor,
15
+ LexicalNode,
16
+ NodeKey,
17
+ SerializedEditor,
18
+ SerializedLexicalNode,
19
+ Spread,
20
+ } from 'lexical';
21
+
22
+ import {$applyNodeReplacement, createEditor, DecoratorNode} from 'lexical';
23
+ import * as React from 'react';
24
+ import {Suspense} from 'react';
25
+
26
+ const InlineImageComponent = React.lazy(() => import('./InlineImageComponent'));
27
+
28
+ export type Position = 'left' | 'right' | 'full' | undefined;
29
+
30
+ export interface InlineImagePayload {
31
+ altText: string;
32
+ caption?: LexicalEditor;
33
+ height?: number;
34
+ key?: NodeKey;
35
+ showCaption?: boolean;
36
+ src: string;
37
+ width?: number;
38
+ position?: Position;
39
+ }
40
+
41
+ export interface UpdateInlineImagePayload {
42
+ altText?: string;
43
+ showCaption?: boolean;
44
+ position?: Position;
45
+ }
46
+
47
+ function $convertInlineImageElement(domNode: Node): null | DOMConversionOutput {
48
+ if (domNode instanceof HTMLImageElement) {
49
+ const {alt: altText, src, width, height} = domNode;
50
+ const node = $createInlineImageNode({altText, height, src, width});
51
+ return {node};
52
+ }
53
+ return null;
54
+ }
55
+
56
+ export type SerializedInlineImageNode = Spread<
57
+ {
58
+ altText: string;
59
+ caption: SerializedEditor;
60
+ height?: number;
61
+ showCaption: boolean;
62
+ src: string;
63
+ width?: number;
64
+ position?: Position;
65
+ },
66
+ SerializedLexicalNode
67
+ >;
68
+
69
+ export class InlineImageNode extends DecoratorNode<JSX.Element> {
70
+ __src: string;
71
+ __altText: string;
72
+ __width: 'inherit' | number;
73
+ __height: 'inherit' | number;
74
+ __showCaption: boolean;
75
+ __caption: LexicalEditor;
76
+ __position: Position;
77
+
78
+ static getType(): string {
79
+ return 'inline-image';
80
+ }
81
+
82
+ static clone(node: InlineImageNode): InlineImageNode {
83
+ return new InlineImageNode(
84
+ node.__src,
85
+ node.__altText,
86
+ node.__position,
87
+ node.__width,
88
+ node.__height,
89
+ node.__showCaption,
90
+ node.__caption,
91
+ node.__key,
92
+ );
93
+ }
94
+
95
+ static importJSON(
96
+ serializedNode: SerializedInlineImageNode,
97
+ ): InlineImageNode {
98
+ const {altText, height, width, caption, src, showCaption, position} =
99
+ serializedNode;
100
+ const node = $createInlineImageNode({
101
+ altText,
102
+ height,
103
+ position,
104
+ showCaption,
105
+ src,
106
+ width,
107
+ });
108
+ const nestedEditor = node.__caption;
109
+ const editorState = nestedEditor.parseEditorState(caption.editorState);
110
+ if (!editorState.isEmpty()) {
111
+ nestedEditor.setEditorState(editorState);
112
+ }
113
+ return node;
114
+ }
115
+
116
+ static importDOM(): DOMConversionMap | null {
117
+ return {
118
+ img: (node: Node) => ({
119
+ conversion: $convertInlineImageElement,
120
+ priority: 0,
121
+ }),
122
+ };
123
+ }
124
+
125
+ constructor(
126
+ src: string,
127
+ altText: string,
128
+ position: Position,
129
+ width?: 'inherit' | number,
130
+ height?: 'inherit' | number,
131
+ showCaption?: boolean,
132
+ caption?: LexicalEditor,
133
+ key?: NodeKey,
134
+ ) {
135
+ super(key);
136
+ this.__src = src;
137
+ this.__altText = altText;
138
+ this.__width = width || 'inherit';
139
+ this.__height = height || 'inherit';
140
+ this.__showCaption = showCaption || false;
141
+ this.__caption = caption || createEditor();
142
+ this.__position = position;
143
+ }
144
+
145
+ exportDOM(): DOMExportOutput {
146
+ const element = document.createElement('img');
147
+ element.setAttribute('src', this.__src);
148
+ element.setAttribute('alt', this.__altText);
149
+ element.setAttribute('width', this.__width.toString());
150
+ element.setAttribute('height', this.__height.toString());
151
+ return {element};
152
+ }
153
+
154
+ exportJSON(): SerializedInlineImageNode {
155
+ return {
156
+ altText: this.getAltText(),
157
+ caption: this.__caption.toJSON(),
158
+ height: this.__height === 'inherit' ? 0 : this.__height,
159
+ position: this.__position,
160
+ showCaption: this.__showCaption,
161
+ src: this.getSrc(),
162
+ type: 'inline-image',
163
+ version: 1,
164
+ width: this.__width === 'inherit' ? 0 : this.__width,
165
+ };
166
+ }
167
+
168
+ getSrc(): string {
169
+ return this.__src;
170
+ }
171
+
172
+ getAltText(): string {
173
+ return this.__altText;
174
+ }
175
+
176
+ setAltText(altText: string): void {
177
+ const writable = this.getWritable();
178
+ writable.__altText = altText;
179
+ }
180
+
181
+ setWidthAndHeight(
182
+ width: 'inherit' | number,
183
+ height: 'inherit' | number,
184
+ ): void {
185
+ const writable = this.getWritable();
186
+ writable.__width = width;
187
+ writable.__height = height;
188
+ }
189
+
190
+ getShowCaption(): boolean {
191
+ return this.__showCaption;
192
+ }
193
+
194
+ setShowCaption(showCaption: boolean): void {
195
+ const writable = this.getWritable();
196
+ writable.__showCaption = showCaption;
197
+ }
198
+
199
+ getPosition(): Position {
200
+ return this.__position;
201
+ }
202
+
203
+ setPosition(position: Position): void {
204
+ const writable = this.getWritable();
205
+ writable.__position = position;
206
+ }
207
+
208
+ update(payload: UpdateInlineImagePayload): void {
209
+ const writable = this.getWritable();
210
+ const {altText, showCaption, position} = payload;
211
+ if (altText !== undefined) {
212
+ writable.__altText = altText;
213
+ }
214
+ if (showCaption !== undefined) {
215
+ writable.__showCaption = showCaption;
216
+ }
217
+ if (position !== undefined) {
218
+ writable.__position = position;
219
+ }
220
+ }
221
+
222
+ // View
223
+
224
+ createDOM(config: EditorConfig): HTMLElement {
225
+ const span = document.createElement('span');
226
+ const className = `${config.theme.inlineImage} position-${this.__position}`;
227
+ if (className !== undefined) {
228
+ span.className = className;
229
+ }
230
+ return span;
231
+ }
232
+
233
+ updateDOM(
234
+ prevNode: InlineImageNode,
235
+ dom: HTMLElement,
236
+ config: EditorConfig,
237
+ ): false {
238
+ const position = this.__position;
239
+ if (position !== prevNode.__position) {
240
+ const className = `${config.theme.inlineImage} position-${position}`;
241
+ if (className !== undefined) {
242
+ dom.className = className;
243
+ }
244
+ }
245
+ return false;
246
+ }
247
+
248
+ decorate(): JSX.Element {
249
+ return (
250
+ <Suspense fallback={null}>
251
+ <InlineImageComponent
252
+ src={this.__src}
253
+ altText={this.__altText}
254
+ width={this.__width}
255
+ height={this.__height}
256
+ nodeKey={this.getKey()}
257
+ showCaption={this.__showCaption}
258
+ caption={this.__caption}
259
+ position={this.__position}
260
+ />
261
+ </Suspense>
262
+ );
263
+ }
264
+ }
265
+
266
+ export function $createInlineImageNode({
267
+ altText,
268
+ position,
269
+ height,
270
+ src,
271
+ width,
272
+ showCaption,
273
+ caption,
274
+ key,
275
+ }: InlineImagePayload): InlineImageNode {
276
+ return $applyNodeReplacement(
277
+ new InlineImageNode(
278
+ src,
279
+ altText,
280
+ position,
281
+ width,
282
+ height,
283
+ showCaption,
284
+ caption,
285
+ key,
286
+ ),
287
+ );
288
+ }
289
+
290
+ export function $isInlineImageNode(
291
+ node: LexicalNode | null | undefined,
292
+ ): node is InlineImageNode {
293
+ return node instanceof InlineImageNode;
294
+ }
@@ -0,0 +1,67 @@
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 type {EditorConfig, LexicalNode, SerializedTextNode} from 'lexical';
10
+
11
+ import {TextNode} from 'lexical';
12
+
13
+ export type SerializedKeywordNode = SerializedTextNode;
14
+
15
+ export class KeywordNode extends TextNode {
16
+ static getType(): string {
17
+ return 'keyword';
18
+ }
19
+
20
+ static clone(node: KeywordNode): KeywordNode {
21
+ return new KeywordNode(node.__text, node.__key);
22
+ }
23
+
24
+ static importJSON(serializedNode: SerializedKeywordNode): KeywordNode {
25
+ const node = $createKeywordNode(serializedNode.text);
26
+ node.setFormat(serializedNode.format);
27
+ node.setDetail(serializedNode.detail);
28
+ node.setMode(serializedNode.mode);
29
+ node.setStyle(serializedNode.style);
30
+ return node;
31
+ }
32
+
33
+ exportJSON(): SerializedKeywordNode {
34
+ return {
35
+ ...super.exportJSON(),
36
+ type: 'keyword',
37
+ version: 1,
38
+ };
39
+ }
40
+
41
+ createDOM(config: EditorConfig): HTMLElement {
42
+ const dom = super.createDOM(config);
43
+ dom.style.cursor = 'default';
44
+ dom.className = 'keyword';
45
+ return dom;
46
+ }
47
+
48
+ canInsertTextBefore(): boolean {
49
+ return false;
50
+ }
51
+
52
+ canInsertTextAfter(): boolean {
53
+ return false;
54
+ }
55
+
56
+ isTextEntity(): true {
57
+ return true;
58
+ }
59
+ }
60
+
61
+ export function $createKeywordNode(keyword: string): KeywordNode {
62
+ return new KeywordNode(keyword);
63
+ }
64
+
65
+ export function $isKeywordNode(node: LexicalNode | null | undefined): boolean {
66
+ return node instanceof KeywordNode;
67
+ }
@@ -0,0 +1,137 @@
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 type {
10
+ DOMConversionMap,
11
+ DOMConversionOutput,
12
+ DOMExportOutput,
13
+ EditorConfig,
14
+ LexicalNode,
15
+ NodeKey,
16
+ SerializedElementNode,
17
+ Spread,
18
+ } from 'lexical';
19
+
20
+ import {addClassNamesToElement} from '@lexical/utils';
21
+ import {ElementNode} from 'lexical';
22
+
23
+ export type SerializedLayoutContainerNode = Spread<
24
+ {
25
+ templateColumns: string;
26
+ },
27
+ SerializedElementNode
28
+ >;
29
+
30
+ function $convertLayoutContainerElement(
31
+ domNode: HTMLElement,
32
+ ): DOMConversionOutput | null {
33
+ const styleAttributes = window.getComputedStyle(domNode);
34
+ const templateColumns = styleAttributes.getPropertyValue(
35
+ 'grid-template-columns',
36
+ );
37
+ if (templateColumns) {
38
+ const node = $createLayoutContainerNode(templateColumns);
39
+ return {node};
40
+ }
41
+ return null;
42
+ }
43
+
44
+ export class LayoutContainerNode extends ElementNode {
45
+ __templateColumns: string;
46
+
47
+ constructor(templateColumns: string, key?: NodeKey) {
48
+ super(key);
49
+ this.__templateColumns = templateColumns;
50
+ }
51
+
52
+ static getType(): string {
53
+ return 'layout-container';
54
+ }
55
+
56
+ static clone(node: LayoutContainerNode): LayoutContainerNode {
57
+ return new LayoutContainerNode(node.__templateColumns, node.__key);
58
+ }
59
+
60
+ createDOM(config: EditorConfig): HTMLElement {
61
+ const dom = document.createElement('div');
62
+ dom.style.gridTemplateColumns = this.__templateColumns;
63
+ if (typeof config.theme.layoutContainer === 'string') {
64
+ addClassNamesToElement(dom, config.theme.layoutContainer);
65
+ }
66
+ return dom;
67
+ }
68
+
69
+ exportDOM(): DOMExportOutput {
70
+ const element = document.createElement('div');
71
+ element.style.gridTemplateColumns = this.__templateColumns;
72
+ element.setAttribute('data-lexical-layout-container', 'true');
73
+ return {element};
74
+ }
75
+
76
+ updateDOM(prevNode: LayoutContainerNode, dom: HTMLElement): boolean {
77
+ if (prevNode.__templateColumns !== this.__templateColumns) {
78
+ dom.style.gridTemplateColumns = this.__templateColumns;
79
+ }
80
+ return false;
81
+ }
82
+
83
+ static importDOM(): DOMConversionMap | null {
84
+ return {
85
+ div: (domNode: HTMLElement) => {
86
+ if (!domNode.hasAttribute('data-lexical-layout-container')) {
87
+ return null;
88
+ }
89
+ return {
90
+ conversion: $convertLayoutContainerElement,
91
+ priority: 2,
92
+ };
93
+ },
94
+ };
95
+ }
96
+
97
+ static importJSON(json: SerializedLayoutContainerNode): LayoutContainerNode {
98
+ return $createLayoutContainerNode(json.templateColumns);
99
+ }
100
+
101
+ isShadowRoot(): boolean {
102
+ return true;
103
+ }
104
+
105
+ canBeEmpty(): boolean {
106
+ return false;
107
+ }
108
+
109
+ exportJSON(): SerializedLayoutContainerNode {
110
+ return {
111
+ ...super.exportJSON(),
112
+ templateColumns: this.__templateColumns,
113
+ type: 'layout-container',
114
+ version: 1,
115
+ };
116
+ }
117
+
118
+ getTemplateColumns(): string {
119
+ return this.getLatest().__templateColumns;
120
+ }
121
+
122
+ setTemplateColumns(templateColumns: string) {
123
+ this.getWritable().__templateColumns = templateColumns;
124
+ }
125
+ }
126
+
127
+ export function $createLayoutContainerNode(
128
+ templateColumns: string,
129
+ ): LayoutContainerNode {
130
+ return new LayoutContainerNode(templateColumns);
131
+ }
132
+
133
+ export function $isLayoutContainerNode(
134
+ node: LexicalNode | null | undefined,
135
+ ): node is LayoutContainerNode {
136
+ return node instanceof LayoutContainerNode;
137
+ }
@@ -0,0 +1,71 @@
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 type {
10
+ DOMConversionMap,
11
+ EditorConfig,
12
+ LexicalNode,
13
+ SerializedElementNode,
14
+ } from 'lexical';
15
+
16
+ import {addClassNamesToElement} from '@lexical/utils';
17
+ import {ElementNode} from 'lexical';
18
+
19
+ export type SerializedLayoutItemNode = SerializedElementNode;
20
+
21
+ export class LayoutItemNode extends ElementNode {
22
+ static getType(): string {
23
+ return 'layout-item';
24
+ }
25
+
26
+ static clone(node: LayoutItemNode): LayoutItemNode {
27
+ return new LayoutItemNode(node.__key);
28
+ }
29
+
30
+ createDOM(config: EditorConfig): HTMLElement {
31
+ const dom = document.createElement('div');
32
+ if (typeof config.theme.layoutItem === 'string') {
33
+ addClassNamesToElement(dom, config.theme.layoutItem);
34
+ }
35
+ return dom;
36
+ }
37
+
38
+ updateDOM(): boolean {
39
+ return false;
40
+ }
41
+
42
+ static importDOM(): DOMConversionMap | null {
43
+ return {};
44
+ }
45
+
46
+ static importJSON(): LayoutItemNode {
47
+ return $createLayoutItemNode();
48
+ }
49
+
50
+ isShadowRoot(): boolean {
51
+ return true;
52
+ }
53
+
54
+ exportJSON(): SerializedLayoutItemNode {
55
+ return {
56
+ ...super.exportJSON(),
57
+ type: 'layout-item',
58
+ version: 1,
59
+ };
60
+ }
61
+ }
62
+
63
+ export function $createLayoutItemNode(): LayoutItemNode {
64
+ return new LayoutItemNode();
65
+ }
66
+
67
+ export function $isLayoutItemNode(
68
+ node: LexicalNode | null | undefined,
69
+ ): node is LayoutItemNode {
70
+ return node instanceof LayoutItemNode;
71
+ }