@haklex/rich-editor 0.0.31 → 0.0.33
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.
- package/dist/{RichEditor-D1twFNL-.js → RichEditor-CSw4Bj02.js} +425 -75
- package/dist/components/decorators/GridEditDecorator.d.ts.map +1 -1
- package/dist/components/renderers/AlertStaticDecorator.d.ts +9 -0
- package/dist/components/renderers/AlertStaticDecorator.d.ts.map +1 -0
- package/dist/components/renderers/BannerStaticDecorator.d.ts +9 -0
- package/dist/components/renderers/BannerStaticDecorator.d.ts.map +1 -0
- package/dist/components/renderers/FootnoteStaticRenderer.d.ts +5 -0
- package/dist/components/renderers/FootnoteStaticRenderer.d.ts.map +1 -0
- package/dist/components/renderers/GridStaticDecorator.d.ts +9 -0
- package/dist/components/renderers/GridStaticDecorator.d.ts.map +1 -0
- package/dist/components/utils.d.ts +1 -2
- package/dist/components/utils.d.ts.map +1 -1
- package/dist/context/NestedContentRendererContext.d.ts +6 -0
- package/dist/context/NestedContentRendererContext.d.ts.map +1 -0
- package/dist/editor.mjs +2 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +94 -56
- package/dist/nodes/AlertQuoteEditNode.d.ts +9 -2
- package/dist/nodes/AlertQuoteEditNode.d.ts.map +1 -1
- package/dist/nodes/AlertQuoteNode.d.ts +5 -6
- package/dist/nodes/AlertQuoteNode.d.ts.map +1 -1
- package/dist/nodes/BannerEditNode.d.ts +9 -2
- package/dist/nodes/BannerEditNode.d.ts.map +1 -1
- package/dist/nodes/BannerNode.d.ts +5 -6
- package/dist/nodes/BannerNode.d.ts.map +1 -1
- package/dist/nodes/GridContainerNode.d.ts +3 -5
- package/dist/nodes/GridContainerNode.d.ts.map +1 -1
- package/dist/nodes/GridEditNode.d.ts +12 -1
- package/dist/nodes/GridEditNode.d.ts.map +1 -1
- package/dist/plugins/AlertPlugin.d.ts.map +1 -1
- package/dist/plugins/FootnotePlugin.d.ts.map +1 -1
- package/dist/rich-editor.css +1 -1
- package/dist/shared.css-BqX4HjVE.js +5 -0
- package/dist/static-entry.d.ts +22 -0
- package/dist/static-entry.d.ts.map +1 -0
- package/dist/static-entry.mjs +34 -0
- package/dist/styles/article.css.d.ts +0 -1
- package/dist/styles/article.css.d.ts.map +1 -1
- package/dist/styles/comment.css.d.ts +0 -1
- package/dist/styles/comment.css.d.ts.map +1 -1
- package/dist/styles/index.d.ts +4 -4
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/note.css.d.ts +0 -1
- package/dist/styles/note.css.d.ts.map +1 -1
- package/dist/styles/shared.css.d.ts.map +1 -1
- package/dist/styles/theme.d.ts.map +1 -1
- package/dist/styles-entry.d.ts +7 -0
- package/dist/styles-entry.d.ts.map +1 -0
- package/dist/styles-entry.mjs +14 -0
- package/dist/{utils-BuZqZkYK.js → theme-C_ic3l9g.js} +665 -804
- package/dist/transformers/alert.d.ts.map +1 -1
- package/dist/transformers/container.d.ts.map +1 -1
- package/dist/transformers/grid-container.d.ts.map +1 -1
- package/dist/transformers/index.d.ts +1 -0
- package/dist/transformers/index.d.ts.map +1 -1
- package/dist/transformers/superscript-subscript.d.ts +2 -0
- package/dist/transformers/superscript-subscript.d.ts.map +1 -0
- package/dist/types.d.ts +0 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/extractTextContent.d.ts +3 -0
- package/dist/utils/extractTextContent.d.ts.map +1 -0
- package/dist/utils-fpeaZV1R.js +18 -0
- package/package.json +11 -7
- package/dist/RichRenderer-hHQ4JQs0.js +0 -113
- package/dist/components/RichRenderer.d.ts +0 -3
- package/dist/components/RichRenderer.d.ts.map +0 -1
- package/dist/renderer.d.ts +0 -3
- package/dist/renderer.d.ts.map +0 -1
- package/dist/renderer.mjs +0 -4
- package/dist/styles/vars.css.d.ts +0 -8
- package/dist/styles/vars.css.d.ts.map +0 -1
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1
4
|
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
5
|
import { PortalThemeProvider } from "@haklex/rich-style-token";
|
|
3
6
|
import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin";
|
|
@@ -9,18 +12,23 @@ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
|
|
9
12
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
10
13
|
import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
|
|
11
14
|
import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
12
|
-
import {
|
|
15
|
+
import { Q as $isAlertQuoteNode, d as RendererWrapper, S as AlertRenderer, T as SpoilerNode, U as MentionNode, V as FootnoteNode, H as KaTeXInlineNode, W as AlertQuoteNode, f as editorTheme, X as $isBannerNode, Y as BannerRenderer, Z as BannerNode, _ as normalizeBannerType, a0 as $isCodeBlockNode, a1 as CodeBlockRenderer, a2 as CodeBlockNode, i as useFootnoteDefinitions, D as FootnoteSectionNode, s as $isGridContainerNode, G as GridContainerNode, b as builtinNodes, K as KaTeXBlockNode, a3 as ImageNode, a4 as VideoNode, L as LinkCardNode, a5 as DetailsNode, M as MermaidNode, F as FootnoteDefinitionsProvider, a6 as $createImageNode, a7 as $createKaTeXInlineNode, a8 as $createKaTeXBlockNode, a9 as $createDetailsNode, aa as $createFootnoteNode, r as $isFootnoteSectionNode, $ as $createFootnoteSectionNode, ab as $createMentionNode, g as extractTextContent, ac as $createSpoilerNode, q as $createMermaidNode, C as ColorSchemeProvider, R as RendererConfigProvider } from "./theme-C_ic3l9g.js";
|
|
16
|
+
import { $getNodeByKey, $insertNodes, createEditor, $nodesOfType, $getRoot, createCommand, COMMAND_PRIORITY_EDITOR, $parseSerializedNode, $getSelection, $isRangeSelection, $createParagraphNode, $createTextNode, KEY_ENTER_COMMAND, COMMAND_PRIORITY_HIGH } from "lexical";
|
|
17
|
+
import { Info, Lightbulb, TriangleAlert, Flag, LayoutGrid, Plus, Minus } from "lucide-react";
|
|
13
18
|
import { useCallback, createElement, useState, useEffect, useRef } from "react";
|
|
14
19
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
15
20
|
import { ContentEditable as ContentEditable$1 } from "@lexical/react/LexicalContentEditable";
|
|
16
21
|
import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { createLinkMatcherWithRegExp, registerAutoLink } from "@lexical/link";
|
|
20
|
-
import {
|
|
22
|
+
import { CodeNode } from "@lexical/code";
|
|
23
|
+
import { HorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND, $createHorizontalRuleNode } from "@lexical/extension";
|
|
24
|
+
import { LinkNode, AutoLinkNode, createLinkMatcherWithRegExp, registerAutoLink } from "@lexical/link";
|
|
25
|
+
import { ListNode, ListItemNode } from "@lexical/list";
|
|
26
|
+
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
27
|
+
import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
|
|
21
28
|
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
|
22
29
|
import { CHECK_LIST, TRANSFORMERS } from "@lexical/markdown";
|
|
23
|
-
import { GIT_ALERT_TRANSFORMER as GIT_ALERT_TRANSFORMER$1, CONTAINER_TRANSFORMER as CONTAINER_TRANSFORMER$1, FOOTNOTE_TRANSFORMER as FOOTNOTE_TRANSFORMER$1, FOOTNOTE_SECTION_TRANSFORMER as FOOTNOTE_SECTION_TRANSFORMER$1, KATEX_INLINE_TRANSFORMER as KATEX_INLINE_TRANSFORMER$1, KATEX_BLOCK_TRANSFORMER as KATEX_BLOCK_TRANSFORMER$1, MENTION_TRANSFORMER as MENTION_TRANSFORMER$1, SPOILER_TRANSFORMER as SPOILER_TRANSFORMER$1, INSERT_TRANSFORMER, IMAGE_BLOCK_TRANSFORMER, VIDEO_BLOCK_TRANSFORMER, CODE_BLOCK_NODE_TRANSFORMER, LINK_CARD_BLOCK_TRANSFORMER, MERMAID_BLOCK_TRANSFORMER, HORIZONTAL_RULE_BLOCK_TRANSFORMER, TABLE_BLOCK_TRANSFORMER } from "@haklex/rich-headless/transformers";
|
|
30
|
+
import { GIT_ALERT_TRANSFORMER as GIT_ALERT_TRANSFORMER$1, CONTAINER_TRANSFORMER as CONTAINER_TRANSFORMER$1, FOOTNOTE_TRANSFORMER as FOOTNOTE_TRANSFORMER$1, FOOTNOTE_SECTION_TRANSFORMER as FOOTNOTE_SECTION_TRANSFORMER$1, KATEX_INLINE_TRANSFORMER as KATEX_INLINE_TRANSFORMER$1, KATEX_BLOCK_TRANSFORMER as KATEX_BLOCK_TRANSFORMER$1, MENTION_TRANSFORMER as MENTION_TRANSFORMER$1, SPOILER_TRANSFORMER as SPOILER_TRANSFORMER$1, INSERT_TRANSFORMER, SUPERSCRIPT_TRANSFORMER, SUBSCRIPT_TRANSFORMER, IMAGE_BLOCK_TRANSFORMER, VIDEO_BLOCK_TRANSFORMER, CODE_BLOCK_NODE_TRANSFORMER, LINK_CARD_BLOCK_TRANSFORMER, MERMAID_BLOCK_TRANSFORMER, HORIZONTAL_RULE_BLOCK_TRANSFORMER, TABLE_BLOCK_TRANSFORMER } from "@haklex/rich-headless/transformers";
|
|
31
|
+
import { b as clsx, g as getVariantClass } from "./utils-fpeaZV1R.js";
|
|
24
32
|
function AlertEditDecorator({
|
|
25
33
|
nodeKey,
|
|
26
34
|
alertType,
|
|
@@ -73,24 +81,71 @@ function AlertEditDecorator({
|
|
|
73
81
|
] }) })
|
|
74
82
|
] });
|
|
75
83
|
}
|
|
76
|
-
|
|
84
|
+
const NESTED_EDITOR_NODES = [
|
|
85
|
+
HeadingNode,
|
|
86
|
+
QuoteNode,
|
|
87
|
+
ListNode,
|
|
88
|
+
ListItemNode,
|
|
89
|
+
LinkNode,
|
|
90
|
+
AutoLinkNode,
|
|
91
|
+
HorizontalRuleNode,
|
|
92
|
+
CodeNode,
|
|
93
|
+
TableNode,
|
|
94
|
+
TableCellNode,
|
|
95
|
+
TableRowNode,
|
|
96
|
+
SpoilerNode,
|
|
97
|
+
MentionNode,
|
|
98
|
+
FootnoteNode,
|
|
99
|
+
KaTeXInlineNode
|
|
100
|
+
];
|
|
101
|
+
function createContentEditor$1() {
|
|
102
|
+
return createEditor({
|
|
103
|
+
namespace: "AlertContent",
|
|
104
|
+
nodes: NESTED_EDITOR_NODES,
|
|
105
|
+
theme: editorTheme,
|
|
106
|
+
onError: (error) => {
|
|
107
|
+
console.error("[AlertContent]", error);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const _AlertQuoteEditNode = class _AlertQuoteEditNode extends AlertQuoteNode {
|
|
112
|
+
constructor(alertType, contentState, key) {
|
|
113
|
+
super(alertType, contentState, key);
|
|
114
|
+
__publicField(this, "__contentEditor");
|
|
115
|
+
this.__contentEditor = createContentEditor$1();
|
|
116
|
+
if (contentState) {
|
|
117
|
+
const editorState = this.__contentEditor.parseEditorState(contentState);
|
|
118
|
+
this.__contentEditor.setEditorState(editorState);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
77
121
|
static clone(node) {
|
|
78
|
-
|
|
122
|
+
const cloned = new _AlertQuoteEditNode(
|
|
79
123
|
node.__alertType,
|
|
80
|
-
node.
|
|
124
|
+
node.__contentState,
|
|
81
125
|
node.__key
|
|
82
126
|
);
|
|
127
|
+
cloned.__contentEditor = node.__contentEditor;
|
|
128
|
+
return cloned;
|
|
129
|
+
}
|
|
130
|
+
getContentEditor() {
|
|
131
|
+
return this.__contentEditor;
|
|
83
132
|
}
|
|
84
133
|
static importJSON(serializedNode) {
|
|
85
|
-
const node = new
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
);
|
|
90
|
-
node.__contentEditor.setEditorState(editorState);
|
|
91
|
-
}
|
|
134
|
+
const node = new _AlertQuoteEditNode(
|
|
135
|
+
serializedNode.alertType,
|
|
136
|
+
serializedNode.content
|
|
137
|
+
);
|
|
92
138
|
return node;
|
|
93
139
|
}
|
|
140
|
+
exportJSON() {
|
|
141
|
+
return {
|
|
142
|
+
...super.exportJSON(),
|
|
143
|
+
type: "alert-quote",
|
|
144
|
+
alertType: this.__alertType,
|
|
145
|
+
content: this.__contentEditor.getEditorState().toJSON(),
|
|
146
|
+
version: 1
|
|
147
|
+
};
|
|
148
|
+
}
|
|
94
149
|
decorate(_editor, _config) {
|
|
95
150
|
return createElement(AlertEditDecorator, {
|
|
96
151
|
nodeKey: this.__key,
|
|
@@ -98,6 +153,48 @@ class AlertQuoteEditNode extends AlertQuoteNode {
|
|
|
98
153
|
contentEditor: this.__contentEditor
|
|
99
154
|
});
|
|
100
155
|
}
|
|
156
|
+
};
|
|
157
|
+
__publicField(_AlertQuoteEditNode, "slashMenuItems", [
|
|
158
|
+
{
|
|
159
|
+
title: "Callout",
|
|
160
|
+
icon: createElement(Info, { size: 20 }),
|
|
161
|
+
description: "Info callout block",
|
|
162
|
+
keywords: ["alert", "note", "info", "callout"],
|
|
163
|
+
section: "ADVANCED",
|
|
164
|
+
onSelect: (editor) => {
|
|
165
|
+
editor.update(() => {
|
|
166
|
+
$insertNodes([$createAlertQuoteEditNode("note")]);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
title: "Tip",
|
|
172
|
+
icon: createElement(Lightbulb, { size: 20 }),
|
|
173
|
+
description: "Highlight a useful tip",
|
|
174
|
+
keywords: ["alert", "tip", "hint"],
|
|
175
|
+
section: "ADVANCED",
|
|
176
|
+
onSelect: (editor) => {
|
|
177
|
+
editor.update(() => {
|
|
178
|
+
$insertNodes([$createAlertQuoteEditNode("tip")]);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
title: "Warning",
|
|
184
|
+
icon: createElement(TriangleAlert, { size: 20 }),
|
|
185
|
+
description: "Warn about something",
|
|
186
|
+
keywords: ["alert", "warning", "caution"],
|
|
187
|
+
section: "ADVANCED",
|
|
188
|
+
onSelect: (editor) => {
|
|
189
|
+
editor.update(() => {
|
|
190
|
+
$insertNodes([$createAlertQuoteEditNode("warning")]);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
]);
|
|
195
|
+
let AlertQuoteEditNode = _AlertQuoteEditNode;
|
|
196
|
+
function $createAlertQuoteEditNode(alertType, contentState) {
|
|
197
|
+
return new AlertQuoteEditNode(alertType, contentState);
|
|
101
198
|
}
|
|
102
199
|
function BannerEditDecorator({
|
|
103
200
|
nodeKey,
|
|
@@ -151,24 +248,45 @@ function BannerEditDecorator({
|
|
|
151
248
|
] }) })
|
|
152
249
|
] });
|
|
153
250
|
}
|
|
154
|
-
|
|
251
|
+
function createContentEditor() {
|
|
252
|
+
return createEditor({
|
|
253
|
+
namespace: "BannerContent",
|
|
254
|
+
nodes: NESTED_EDITOR_NODES,
|
|
255
|
+
theme: editorTheme,
|
|
256
|
+
onError: (error) => {
|
|
257
|
+
console.error("[BannerContent]", error);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
const _BannerEditNode = class _BannerEditNode extends BannerNode {
|
|
262
|
+
constructor(bannerType, contentState, key) {
|
|
263
|
+
super(bannerType, contentState, key);
|
|
264
|
+
__publicField(this, "__contentEditor");
|
|
265
|
+
this.__contentEditor = createContentEditor();
|
|
266
|
+
if (contentState) {
|
|
267
|
+
const editorState = this.__contentEditor.parseEditorState(contentState);
|
|
268
|
+
this.__contentEditor.setEditorState(editorState);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
155
271
|
static clone(node) {
|
|
156
|
-
|
|
272
|
+
const cloned = new _BannerEditNode(
|
|
157
273
|
node.__bannerType,
|
|
158
|
-
node.
|
|
274
|
+
node.__contentState,
|
|
159
275
|
node.__key
|
|
160
276
|
);
|
|
277
|
+
cloned.__contentEditor = node.__contentEditor;
|
|
278
|
+
return cloned;
|
|
279
|
+
}
|
|
280
|
+
getContentEditor() {
|
|
281
|
+
return this.__contentEditor;
|
|
161
282
|
}
|
|
162
283
|
static importJSON(serializedNode) {
|
|
163
284
|
const legacy = serializedNode;
|
|
164
285
|
const bannerType = normalizeBannerType(serializedNode.bannerType);
|
|
165
|
-
const node = new BannerEditNode(bannerType);
|
|
166
286
|
if (serializedNode.content) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
node.__contentEditor.setEditorState(editorState);
|
|
171
|
-
} else if (legacy.children) {
|
|
287
|
+
return new _BannerEditNode(bannerType, serializedNode.content);
|
|
288
|
+
}
|
|
289
|
+
if (legacy.children) {
|
|
172
290
|
const content = {
|
|
173
291
|
root: {
|
|
174
292
|
children: legacy.children,
|
|
@@ -179,10 +297,18 @@ class BannerEditNode extends BannerNode {
|
|
|
179
297
|
version: 1
|
|
180
298
|
}
|
|
181
299
|
};
|
|
182
|
-
|
|
183
|
-
node.__contentEditor.setEditorState(editorState);
|
|
300
|
+
return new _BannerEditNode(bannerType, content);
|
|
184
301
|
}
|
|
185
|
-
return
|
|
302
|
+
return new _BannerEditNode(bannerType);
|
|
303
|
+
}
|
|
304
|
+
exportJSON() {
|
|
305
|
+
return {
|
|
306
|
+
...super.exportJSON(),
|
|
307
|
+
type: "banner",
|
|
308
|
+
bannerType: this.__bannerType,
|
|
309
|
+
content: this.__contentEditor.getEditorState().toJSON(),
|
|
310
|
+
version: 1
|
|
311
|
+
};
|
|
186
312
|
}
|
|
187
313
|
decorate(_editor, _config) {
|
|
188
314
|
return createElement(BannerEditDecorator, {
|
|
@@ -191,6 +317,24 @@ class BannerEditNode extends BannerNode {
|
|
|
191
317
|
contentEditor: this.__contentEditor
|
|
192
318
|
});
|
|
193
319
|
}
|
|
320
|
+
};
|
|
321
|
+
__publicField(_BannerEditNode, "slashMenuItems", [
|
|
322
|
+
{
|
|
323
|
+
title: "Banner",
|
|
324
|
+
icon: createElement(Flag, { size: 20 }),
|
|
325
|
+
description: "Highlighted banner block",
|
|
326
|
+
keywords: ["banner", "notice", "announcement"],
|
|
327
|
+
section: "ADVANCED",
|
|
328
|
+
onSelect: (editor) => {
|
|
329
|
+
editor.update(() => {
|
|
330
|
+
$insertNodes([$createBannerEditNode("note")]);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
]);
|
|
335
|
+
let BannerEditNode = _BannerEditNode;
|
|
336
|
+
function $createBannerEditNode(bannerType, contentState) {
|
|
337
|
+
return new BannerEditNode(bannerType, contentState);
|
|
194
338
|
}
|
|
195
339
|
function CodeBlockEditDecorator({
|
|
196
340
|
nodeKey,
|
|
@@ -376,7 +520,7 @@ function GridEditDecorator({
|
|
|
376
520
|
const handleRemoveRow = useCallback(() => {
|
|
377
521
|
editor.update(() => {
|
|
378
522
|
const node = $getNodeByKey(nodeKey);
|
|
379
|
-
if (!$
|
|
523
|
+
if (!$isGridEditNode(node)) return;
|
|
380
524
|
const cols = node.getCols();
|
|
381
525
|
const editors = node.getCellEditors();
|
|
382
526
|
if (editors.length <= cols) return;
|
|
@@ -471,36 +615,52 @@ function createCellEditor() {
|
|
|
471
615
|
}
|
|
472
616
|
});
|
|
473
617
|
}
|
|
474
|
-
class
|
|
618
|
+
const _GridEditNode = class _GridEditNode extends GridContainerNode {
|
|
619
|
+
constructor(cols = 2, gap, cellStates, key) {
|
|
620
|
+
super(cols, gap, cellStates, key);
|
|
621
|
+
__publicField(this, "__cellEditors");
|
|
622
|
+
this.__cellEditors = this.__cellStates.map((state) => {
|
|
623
|
+
const editor = createCellEditor();
|
|
624
|
+
const editorState = editor.parseEditorState(state);
|
|
625
|
+
editor.setEditorState(editorState);
|
|
626
|
+
return editor;
|
|
627
|
+
});
|
|
628
|
+
}
|
|
475
629
|
static clone(node) {
|
|
476
|
-
|
|
630
|
+
const cloned = new _GridEditNode(
|
|
477
631
|
node.__cols,
|
|
478
632
|
node.__gap,
|
|
479
|
-
|
|
633
|
+
node.__cellStates,
|
|
480
634
|
node.__key
|
|
481
635
|
);
|
|
636
|
+
cloned.__cellEditors = [...node.__cellEditors];
|
|
637
|
+
return cloned;
|
|
482
638
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const editorState = editor.parseEditorState(cellState);
|
|
493
|
-
editor.setEditorState(editorState);
|
|
494
|
-
return editor;
|
|
495
|
-
});
|
|
496
|
-
node.__cellEditors = editors;
|
|
497
|
-
} else if (legacy.children) {
|
|
498
|
-
const { children } = legacy;
|
|
499
|
-
const editors = children.map((child) => {
|
|
639
|
+
getCellEditors() {
|
|
640
|
+
return this.getLatest().__cellEditors;
|
|
641
|
+
}
|
|
642
|
+
setCols(cols) {
|
|
643
|
+
const writable = this.getWritable();
|
|
644
|
+
const prev = writable.__cellEditors.length;
|
|
645
|
+
writable.__cols = cols;
|
|
646
|
+
if (cols > prev) {
|
|
647
|
+
for (let i = prev; i < cols; i++) {
|
|
500
648
|
const editor = createCellEditor();
|
|
501
|
-
|
|
649
|
+
writable.__cellEditors.push(editor);
|
|
650
|
+
const emptyState = {
|
|
502
651
|
root: {
|
|
503
|
-
children: [
|
|
652
|
+
children: [
|
|
653
|
+
{
|
|
654
|
+
type: "paragraph",
|
|
655
|
+
children: [],
|
|
656
|
+
direction: null,
|
|
657
|
+
format: "",
|
|
658
|
+
indent: 0,
|
|
659
|
+
textFormat: 0,
|
|
660
|
+
textStyle: "",
|
|
661
|
+
version: 1
|
|
662
|
+
}
|
|
663
|
+
],
|
|
504
664
|
direction: null,
|
|
505
665
|
format: "",
|
|
506
666
|
indent: 0,
|
|
@@ -508,13 +668,93 @@ class GridEditNode extends GridContainerNode {
|
|
|
508
668
|
version: 1
|
|
509
669
|
}
|
|
510
670
|
};
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
671
|
+
writable.__cellStates.push(emptyState);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
addCells(count) {
|
|
676
|
+
const writable = this.getWritable();
|
|
677
|
+
for (let i = 0; i < count; i++) {
|
|
678
|
+
const editor = createCellEditor();
|
|
679
|
+
writable.__cellEditors.push(editor);
|
|
680
|
+
const emptyState = {
|
|
681
|
+
root: {
|
|
682
|
+
children: [
|
|
683
|
+
{
|
|
684
|
+
type: "paragraph",
|
|
685
|
+
children: [],
|
|
686
|
+
direction: null,
|
|
687
|
+
format: "",
|
|
688
|
+
indent: 0,
|
|
689
|
+
textFormat: 0,
|
|
690
|
+
textStyle: "",
|
|
691
|
+
version: 1
|
|
692
|
+
}
|
|
693
|
+
],
|
|
694
|
+
direction: null,
|
|
695
|
+
format: "",
|
|
696
|
+
indent: 0,
|
|
697
|
+
type: "root",
|
|
698
|
+
version: 1
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
writable.__cellStates.push(emptyState);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
removeCells(count) {
|
|
705
|
+
const writable = this.getWritable();
|
|
706
|
+
const editors = writable.__cellEditors;
|
|
707
|
+
const states = writable.__cellStates;
|
|
708
|
+
const toRemove = Math.min(count, editors.length);
|
|
709
|
+
for (let i = 0; i < toRemove; i++) {
|
|
710
|
+
const editor = editors.at(-1);
|
|
711
|
+
if (!editor) break;
|
|
712
|
+
const isEmpty = editor.getEditorState().read(() => {
|
|
713
|
+
return $getRoot().getTextContentSize() === 0;
|
|
514
714
|
});
|
|
515
|
-
|
|
715
|
+
if (!isEmpty) break;
|
|
716
|
+
editors.pop();
|
|
717
|
+
states.pop();
|
|
516
718
|
}
|
|
517
|
-
|
|
719
|
+
}
|
|
720
|
+
static importJSON(serializedNode) {
|
|
721
|
+
const legacy = serializedNode;
|
|
722
|
+
const cols = legacy.cols || 2;
|
|
723
|
+
const rawGap = legacy.gap;
|
|
724
|
+
const gap = typeof rawGap === "number" ? `${rawGap}px` : rawGap;
|
|
725
|
+
if (legacy.cells && legacy.cells.length > 0) {
|
|
726
|
+
return new _GridEditNode(cols, gap, legacy.cells);
|
|
727
|
+
}
|
|
728
|
+
if (legacy.children) {
|
|
729
|
+
const cellStates = legacy.children.map(
|
|
730
|
+
(child) => {
|
|
731
|
+
return {
|
|
732
|
+
root: {
|
|
733
|
+
children: [child],
|
|
734
|
+
direction: null,
|
|
735
|
+
format: "",
|
|
736
|
+
indent: 0,
|
|
737
|
+
type: "root",
|
|
738
|
+
version: 1
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
);
|
|
743
|
+
return new _GridEditNode(cols, gap, cellStates);
|
|
744
|
+
}
|
|
745
|
+
return new _GridEditNode(cols, gap);
|
|
746
|
+
}
|
|
747
|
+
exportJSON() {
|
|
748
|
+
return {
|
|
749
|
+
...super.exportJSON(),
|
|
750
|
+
type: "grid-container",
|
|
751
|
+
cols: this.__cols,
|
|
752
|
+
gap: this.__gap,
|
|
753
|
+
cells: this.__cellEditors.map(
|
|
754
|
+
(editor) => editor.getEditorState().toJSON()
|
|
755
|
+
),
|
|
756
|
+
version: 1
|
|
757
|
+
};
|
|
518
758
|
}
|
|
519
759
|
decorate(_editor, _config) {
|
|
520
760
|
return createElement(GridEditDecorator, {
|
|
@@ -524,6 +764,27 @@ class GridEditNode extends GridContainerNode {
|
|
|
524
764
|
cellEditors: this.__cellEditors
|
|
525
765
|
});
|
|
526
766
|
}
|
|
767
|
+
};
|
|
768
|
+
__publicField(_GridEditNode, "slashMenuItems", [
|
|
769
|
+
{
|
|
770
|
+
title: "Grid",
|
|
771
|
+
icon: createElement(LayoutGrid, { size: 20 }),
|
|
772
|
+
description: "Grid layout container",
|
|
773
|
+
keywords: ["grid", "columns", "layout"],
|
|
774
|
+
section: "LAYOUT",
|
|
775
|
+
onSelect: (editor) => {
|
|
776
|
+
editor.update(() => {
|
|
777
|
+
$insertNodes([$createGridEditNode(2)]);
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
]);
|
|
782
|
+
let GridEditNode = _GridEditNode;
|
|
783
|
+
function $createGridEditNode(cols = 2, gap) {
|
|
784
|
+
return new GridEditNode(cols, gap);
|
|
785
|
+
}
|
|
786
|
+
function $isGridEditNode(node) {
|
|
787
|
+
return node instanceof GridEditNode;
|
|
527
788
|
}
|
|
528
789
|
const customEditNodes = [
|
|
529
790
|
SpoilerNode,
|
|
@@ -560,7 +821,7 @@ function AlertPlugin() {
|
|
|
560
821
|
return editor.registerCommand(
|
|
561
822
|
INSERT_ALERT_COMMAND,
|
|
562
823
|
(alertType) => {
|
|
563
|
-
$insertNodes([$
|
|
824
|
+
$insertNodes([$createAlertQuoteEditNode(alertType)]);
|
|
564
825
|
return true;
|
|
565
826
|
},
|
|
566
827
|
COMMAND_PRIORITY_EDITOR
|
|
@@ -608,6 +869,99 @@ function EditorRefPlugin({ onEditorReady }) {
|
|
|
608
869
|
}, [editor]);
|
|
609
870
|
return null;
|
|
610
871
|
}
|
|
872
|
+
function FootnotePlugin({ children }) {
|
|
873
|
+
const [editor] = useLexicalComposerContext();
|
|
874
|
+
const [definitions, setDefinitions] = useState({});
|
|
875
|
+
const [displayNumberMap, setDisplayNumberMap] = useState({});
|
|
876
|
+
const pendingUpdateRef = useRef(false);
|
|
877
|
+
useEffect(() => {
|
|
878
|
+
return editor.registerUpdateListener(({ editorState }) => {
|
|
879
|
+
editorState.read(() => {
|
|
880
|
+
const footnoteNodes = $nodesOfType(FootnoteNode);
|
|
881
|
+
const seen = /* @__PURE__ */ new Set();
|
|
882
|
+
const numberMap = {};
|
|
883
|
+
let counter = 1;
|
|
884
|
+
for (const node of footnoteNodes) {
|
|
885
|
+
const id = node.getIdentifier();
|
|
886
|
+
if (!seen.has(id)) {
|
|
887
|
+
seen.add(id);
|
|
888
|
+
numberMap[id] = counter++;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
setDisplayNumberMap(numberMap);
|
|
892
|
+
const sectionNodes = $nodesOfType(FootnoteSectionNode);
|
|
893
|
+
if (sectionNodes.length > 0) {
|
|
894
|
+
setDefinitions(sectionNodes[0].getDefinitions());
|
|
895
|
+
} else {
|
|
896
|
+
setDefinitions({});
|
|
897
|
+
}
|
|
898
|
+
if (!editor.isEditable() || pendingUpdateRef.current) return;
|
|
899
|
+
if (footnoteNodes.length === 0 && sectionNodes.length > 0) {
|
|
900
|
+
pendingUpdateRef.current = true;
|
|
901
|
+
queueMicrotask(() => {
|
|
902
|
+
editor.update(() => {
|
|
903
|
+
const sections = $nodesOfType(FootnoteSectionNode);
|
|
904
|
+
for (const s of sections) s.remove();
|
|
905
|
+
});
|
|
906
|
+
pendingUpdateRef.current = false;
|
|
907
|
+
});
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
if (footnoteNodes.length > 0 && sectionNodes.length === 0) {
|
|
911
|
+
const seenSnapshot = [...seen];
|
|
912
|
+
pendingUpdateRef.current = true;
|
|
913
|
+
queueMicrotask(() => {
|
|
914
|
+
editor.update(() => {
|
|
915
|
+
const root = $getRoot();
|
|
916
|
+
const defs = {};
|
|
917
|
+
for (const id of seenSnapshot) {
|
|
918
|
+
defs[id] = "";
|
|
919
|
+
}
|
|
920
|
+
const section = $parseSerializedNode({
|
|
921
|
+
type: "footnote-section",
|
|
922
|
+
definitions: defs,
|
|
923
|
+
version: 1
|
|
924
|
+
});
|
|
925
|
+
root.append(section);
|
|
926
|
+
});
|
|
927
|
+
pendingUpdateRef.current = false;
|
|
928
|
+
});
|
|
929
|
+
} else if (sectionNodes.length > 0) {
|
|
930
|
+
const existingDefs = sectionNodes[0].getDefinitions();
|
|
931
|
+
const missingIds = [...seen].filter((id) => !(id in existingDefs));
|
|
932
|
+
const orphanIds = Object.keys(existingDefs).filter(
|
|
933
|
+
(id) => !seen.has(id)
|
|
934
|
+
);
|
|
935
|
+
if (missingIds.length > 0 || orphanIds.length > 0) {
|
|
936
|
+
pendingUpdateRef.current = true;
|
|
937
|
+
queueMicrotask(() => {
|
|
938
|
+
editor.update(() => {
|
|
939
|
+
const freshSections = $nodesOfType(FootnoteSectionNode);
|
|
940
|
+
if (freshSections.length > 0) {
|
|
941
|
+
for (const id of missingIds) {
|
|
942
|
+
freshSections[0].setDefinition(id, "");
|
|
943
|
+
}
|
|
944
|
+
for (const id of orphanIds) {
|
|
945
|
+
freshSections[0].removeDefinition(id);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
pendingUpdateRef.current = false;
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
}, [editor]);
|
|
956
|
+
return /* @__PURE__ */ jsx(
|
|
957
|
+
FootnoteDefinitionsProvider,
|
|
958
|
+
{
|
|
959
|
+
definitions,
|
|
960
|
+
displayNumberMap,
|
|
961
|
+
children
|
|
962
|
+
}
|
|
963
|
+
);
|
|
964
|
+
}
|
|
611
965
|
function HorizontalRulePlugin() {
|
|
612
966
|
const [editor] = useLexicalComposerContext();
|
|
613
967
|
useEffect(() => {
|
|
@@ -695,7 +1049,6 @@ const GIT_ALERT_TRANSFORMER = {
|
|
|
695
1049
|
replace: (parentNode, children, match) => {
|
|
696
1050
|
const typeKey = match[1];
|
|
697
1051
|
const alertType = ALERT_TYPE_MAP[typeKey] || "note";
|
|
698
|
-
const alertNode = $createAlertQuoteNode(alertType);
|
|
699
1052
|
const serializedChildren = children.map((child) => child.exportJSON());
|
|
700
1053
|
const content = {
|
|
701
1054
|
root: {
|
|
@@ -718,8 +1071,7 @@ const GIT_ALERT_TRANSFORMER = {
|
|
|
718
1071
|
version: 1
|
|
719
1072
|
}
|
|
720
1073
|
};
|
|
721
|
-
const
|
|
722
|
-
alertNode.getContentEditor().setEditorState(editorState);
|
|
1074
|
+
const alertNode = $createAlertQuoteEditNode(alertType, content);
|
|
723
1075
|
parentNode.replace(alertNode);
|
|
724
1076
|
}
|
|
725
1077
|
};
|
|
@@ -744,7 +1096,6 @@ const CONTAINER_TRANSFORMER = {
|
|
|
744
1096
|
const params = match[2];
|
|
745
1097
|
if (type in BANNER_TYPE_MAP) {
|
|
746
1098
|
const bannerType = BANNER_TYPE_MAP[type];
|
|
747
|
-
const banner = $createBannerNode(bannerType);
|
|
748
1099
|
const serializedChildren = children.map(
|
|
749
1100
|
(child) => child.exportJSON()
|
|
750
1101
|
);
|
|
@@ -769,8 +1120,7 @@ const CONTAINER_TRANSFORMER = {
|
|
|
769
1120
|
version: 1
|
|
770
1121
|
}
|
|
771
1122
|
};
|
|
772
|
-
const
|
|
773
|
-
banner.getContentEditor().setEditorState(editorState);
|
|
1123
|
+
const banner = $createBannerEditNode(bannerType, content);
|
|
774
1124
|
parentNode.replace(banner);
|
|
775
1125
|
return;
|
|
776
1126
|
}
|
|
@@ -854,11 +1204,7 @@ const GRID_CONTAINER_BLOCK_TRANSFORMER = {
|
|
|
854
1204
|
dependencies: [],
|
|
855
1205
|
export: (node) => {
|
|
856
1206
|
if (!$isGridContainerNode(node)) return null;
|
|
857
|
-
const cells = node.
|
|
858
|
-
(editor) => editor.getEditorState().read(() => {
|
|
859
|
-
return $getRoot().getTextContent();
|
|
860
|
-
})
|
|
861
|
-
);
|
|
1207
|
+
const cells = node.getCellStates().map((state) => extractTextContent(state));
|
|
862
1208
|
const body = cells.map((content) => `::: cell
|
|
863
1209
|
${content}
|
|
864
1210
|
:::`).join("\n");
|
|
@@ -886,6 +1232,8 @@ const ALL_TRANSFORMERS = [
|
|
|
886
1232
|
MENTION_TRANSFORMER,
|
|
887
1233
|
FOOTNOTE_TRANSFORMER,
|
|
888
1234
|
INSERT_TRANSFORMER,
|
|
1235
|
+
SUPERSCRIPT_TRANSFORMER,
|
|
1236
|
+
SUBSCRIPT_TRANSFORMER,
|
|
889
1237
|
KATEX_INLINE_TRANSFORMER,
|
|
890
1238
|
// Block transformers (order matters - more specific first)
|
|
891
1239
|
FOOTNOTE_SECTION_TRANSFORMER,
|
|
@@ -1036,8 +1384,8 @@ function RichEditor({
|
|
|
1036
1384
|
},
|
|
1037
1385
|
...initialValue ? { editorState: JSON.stringify(initialValue) } : {}
|
|
1038
1386
|
};
|
|
1039
|
-
const variantClass = getVariantClass(variant
|
|
1040
|
-
return /* @__PURE__ */ jsx(PortalThemeProvider, { className: variantClass, children: /* @__PURE__ */ jsx(ColorSchemeProvider, { colorScheme: theme, children: /* @__PURE__ */ jsx(
|
|
1387
|
+
const variantClass = getVariantClass(variant);
|
|
1388
|
+
return /* @__PURE__ */ jsx(PortalThemeProvider, { className: variantClass, theme, children: /* @__PURE__ */ jsx(ColorSchemeProvider, { colorScheme: theme, children: /* @__PURE__ */ jsx(
|
|
1041
1389
|
RendererConfigProvider,
|
|
1042
1390
|
{
|
|
1043
1391
|
config: rendererConfig,
|
|
@@ -1090,15 +1438,17 @@ function RichEditor({
|
|
|
1090
1438
|
}
|
|
1091
1439
|
export {
|
|
1092
1440
|
ALL_TRANSFORMERS as A,
|
|
1093
|
-
|
|
1441
|
+
FootnotePlugin as F,
|
|
1094
1442
|
INSERT_ALERT_COMMAND as I,
|
|
1443
|
+
NESTED_EDITOR_NODES as N,
|
|
1095
1444
|
RichEditor as R,
|
|
1096
1445
|
allEditNodes as a,
|
|
1097
|
-
|
|
1446
|
+
FootnoteSectionEditNode as b,
|
|
1098
1447
|
customEditNodes as c,
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1448
|
+
INSERT_IMAGE_COMMAND as d,
|
|
1449
|
+
INSERT_KATEX_BLOCK_COMMAND as e,
|
|
1450
|
+
INSERT_KATEX_INLINE_COMMAND as f,
|
|
1102
1451
|
getResolvedEditNodes as g,
|
|
1452
|
+
INSERT_MERMAID_COMMAND as h,
|
|
1103
1453
|
setResolvedEditNodes as s
|
|
1104
1454
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridEditDecorator.d.ts","sourceRoot":"","sources":["../../../src/components/decorators/GridEditDecorator.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"GridEditDecorator.d.ts","sourceRoot":"","sources":["../../../src/components/decorators/GridEditDecorator.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAQ5C,UAAU,sBAAsB;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,aAAa,EAAE,CAAA;CAC7B;AAID,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,WAAW,EACjB,GAAG,EACH,WAAW,GACZ,EAAE,sBAAsB,+BAyHxB"}
|