@haklex/rich-editor 0.0.65 → 0.0.67

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 (123) hide show
  1. package/README.md +107 -300
  2. package/dist/AlertQuoteEditNode-AgVEMFEi.js +292 -0
  3. package/dist/KaTeXRenderer-C8jv_5xr.js +214 -0
  4. package/dist/LinkCardRenderer-QmkOlyXb.js +36 -0
  5. package/dist/{LinkFavicon-DpURZdO_.js → LinkFavicon-B9SOaYCR.js} +5 -24
  6. package/dist/MermaidPlugin-CIQbyjXF.js +97 -0
  7. package/dist/RubyRenderer-DbeobSoH.js +13 -0
  8. package/dist/SubmitShortcutPlugin-BRK63XHl.js +1511 -0
  9. package/dist/commands-entry.d.ts +9 -0
  10. package/dist/commands-entry.d.ts.map +1 -0
  11. package/dist/commands-entry.mjs +25 -0
  12. package/dist/components/ContentEditable.d.ts +2 -2
  13. package/dist/components/ContentEditable.d.ts.map +1 -1
  14. package/dist/components/CorePlugins.d.ts +2 -0
  15. package/dist/components/CorePlugins.d.ts.map +1 -0
  16. package/dist/components/LinkFavicon.d.ts.map +1 -1
  17. package/dist/components/RichEditor.d.ts +1 -1
  18. package/dist/components/RichEditor.d.ts.map +1 -1
  19. package/dist/components/RichEditorShell.d.ts +26 -0
  20. package/dist/components/RichEditorShell.d.ts.map +1 -0
  21. package/dist/components/decorators/AlertEditDecorator.d.ts +2 -2
  22. package/dist/components/decorators/AlertEditDecorator.d.ts.map +1 -1
  23. package/dist/components/decorators/BannerEditDecorator.d.ts +1 -1
  24. package/dist/components/decorators/BannerEditDecorator.d.ts.map +1 -1
  25. package/dist/components/decorators/CodeBlockEditDecorator.d.ts +2 -2
  26. package/dist/components/decorators/CodeBlockEditDecorator.d.ts.map +1 -1
  27. package/dist/components/decorators/GridEditDecorator.d.ts +2 -2
  28. package/dist/components/decorators/GridEditDecorator.d.ts.map +1 -1
  29. package/dist/components/renderers/AlertRenderer.d.ts +1 -1
  30. package/dist/components/renderers/AlertRenderer.d.ts.map +1 -1
  31. package/dist/components/renderers/AlertStaticDecorator.d.ts +1 -1
  32. package/dist/components/renderers/AlertStaticDecorator.d.ts.map +1 -1
  33. package/dist/components/renderers/BannerRenderer.d.ts +1 -1
  34. package/dist/components/renderers/BannerRenderer.d.ts.map +1 -1
  35. package/dist/components/renderers/BannerStaticDecorator.d.ts +1 -1
  36. package/dist/components/renderers/BannerStaticDecorator.d.ts.map +1 -1
  37. package/dist/components/renderers/CodeBlockRenderer.d.ts +5 -5
  38. package/dist/components/renderers/CodeBlockRenderer.d.ts.map +1 -1
  39. package/dist/components/renderers/FootnoteRenderer.d.ts.map +1 -1
  40. package/dist/components/renderers/FootnoteSectionEditRenderer.d.ts +1 -1
  41. package/dist/components/renderers/FootnoteSectionEditRenderer.d.ts.map +1 -1
  42. package/dist/components/renderers/FootnoteSectionRenderer.d.ts +1 -1
  43. package/dist/components/renderers/FootnoteSectionRenderer.d.ts.map +1 -1
  44. package/dist/components/renderers/FootnoteStaticRenderer.d.ts +1 -1
  45. package/dist/components/renderers/FootnoteStaticRenderer.d.ts.map +1 -1
  46. package/dist/components/renderers/GridStaticDecorator.d.ts +2 -2
  47. package/dist/components/renderers/GridStaticDecorator.d.ts.map +1 -1
  48. package/dist/components/renderers/ImageRenderer.d.ts +4 -4
  49. package/dist/components/renderers/ImageRenderer.d.ts.map +1 -1
  50. package/dist/components/renderers/KaTeXRenderer.d.ts +1 -1
  51. package/dist/components/renderers/KaTeXRenderer.d.ts.map +1 -1
  52. package/dist/components/renderers/LinkCardRenderer.d.ts +4 -4
  53. package/dist/components/renderers/LinkCardRenderer.d.ts.map +1 -1
  54. package/dist/components/renderers/MentionRenderer.d.ts +2 -2
  55. package/dist/components/renderers/MentionRenderer.d.ts.map +1 -1
  56. package/dist/components/renderers/RubyRenderer.d.ts +1 -1
  57. package/dist/components/renderers/RubyRenderer.d.ts.map +1 -1
  58. package/dist/components/renderers/VideoRenderer.d.ts +3 -3
  59. package/dist/components/renderers/VideoRenderer.d.ts.map +1 -1
  60. package/dist/config-QGdXDSW9.js +1235 -0
  61. package/dist/context/ImageUploadContext.d.ts.map +1 -1
  62. package/dist/context/RendererConfigContext.d.ts +1 -1
  63. package/dist/context/RendererConfigContext.d.ts.map +1 -1
  64. package/dist/favicon-BQgbXF_a.js +43 -0
  65. package/dist/index.d.ts +10 -80
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.mjs +151 -161
  68. package/dist/node-registry-CSRSWJ0q.js +765 -0
  69. package/dist/nodes/CodeBlockEditNode.d.ts +6 -6
  70. package/dist/nodes/DetailsNode.d.ts.map +1 -1
  71. package/dist/nodes/GridContainerNode.d.ts.map +1 -1
  72. package/dist/nodes/GridEditNode.d.ts.map +1 -1
  73. package/dist/nodes/ImageNode.d.ts +4 -4
  74. package/dist/nodes/ImageNode.d.ts.map +1 -1
  75. package/dist/nodes/LinkCardNode.d.ts +4 -4
  76. package/dist/nodes/LinkCardNode.d.ts.map +1 -1
  77. package/dist/nodes/VideoNode.d.ts +2 -2
  78. package/dist/nodes/VideoNode.d.ts.map +1 -1
  79. package/dist/nodes-entry.d.ts +28 -0
  80. package/dist/nodes-entry.d.ts.map +1 -0
  81. package/dist/nodes-entry.mjs +44 -0
  82. package/dist/plugins/AutoLinkPlugin.d.ts.map +1 -1
  83. package/dist/plugins/BlockIdPlugin.d.ts.map +1 -1
  84. package/dist/plugins/ImageUploadPlugin.d.ts +2 -2
  85. package/dist/plugins/ImageUploadPlugin.d.ts.map +1 -1
  86. package/dist/plugins/MarkdownPastePlugin.d.ts.map +1 -1
  87. package/dist/plugins/OnChangePlugin.d.ts +1 -1
  88. package/dist/plugins/OnChangePlugin.d.ts.map +1 -1
  89. package/dist/plugins/image-upload-command.d.ts.map +1 -1
  90. package/dist/plugins/image-upload.css.d.ts +1 -4
  91. package/dist/plugins/image-upload.css.d.ts.map +1 -1
  92. package/dist/plugins-entry.d.ts +22 -0
  93. package/dist/plugins-entry.d.ts.map +1 -0
  94. package/dist/plugins-entry.mjs +27 -0
  95. package/dist/renderers-entry.d.ts +23 -0
  96. package/dist/renderers-entry.d.ts.map +1 -0
  97. package/dist/renderers-entry.mjs +60 -0
  98. package/dist/rich-editor.css +1 -1
  99. package/dist/{utils-fpeaZV1R.js → shared.css-DNuMYx6Q.js} +4 -1
  100. package/dist/static-entry.mjs +23 -21
  101. package/dist/styles/article.css.d.ts.map +1 -1
  102. package/dist/styles-entry.mjs +1 -2
  103. package/dist/theme-CRza9nbF.js +924 -0
  104. package/dist/transformers/code-block.d.ts.map +1 -1
  105. package/dist/transformers/footnote.d.ts.map +1 -1
  106. package/dist/transformers/grid-container.d.ts.map +1 -1
  107. package/dist/types/renderer-config.d.ts +6 -6
  108. package/dist/types/renderer-config.d.ts.map +1 -1
  109. package/dist/types/slash-menu.d.ts +6 -6
  110. package/dist/types/slash-menu.d.ts.map +1 -1
  111. package/dist/types.d.ts +18 -13
  112. package/dist/types.d.ts.map +1 -1
  113. package/dist/utils/comment-anchor.d.ts +8 -8
  114. package/dist/utils/comment-anchor.d.ts.map +1 -1
  115. package/package.json +50 -33
  116. package/dist/RichEditor-EI3rR1-9.js +0 -2789
  117. package/dist/components/decorators/nested-doc-dialog.css.d.ts +0 -28
  118. package/dist/components/decorators/nested-doc-dialog.css.d.ts.map +0 -1
  119. package/dist/editor.d.ts +0 -6
  120. package/dist/editor.d.ts.map +0 -1
  121. package/dist/editor.mjs +0 -12
  122. package/dist/favicon-C6Esc0tp.js +0 -2470
  123. package/dist/shared.css-BqX4HjVE.js +0 -5
@@ -0,0 +1,924 @@
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);
4
+ import { DecoratorNode, createCommand, $insertNodes, $getSelection, $isRangeSelection, $getNodeByKey, ElementNode } from "lexical";
5
+ import { createContext, use, createElement, useState, useCallback, useEffect, useMemo } from "react";
6
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
7
+ import { a as RendererWrapper, c as createRendererDecoration, h as FootnoteStaticRenderer, j as decodeThumbHash, K as KaTeXRenderer } from "./KaTeXRenderer-C8jv_5xr.js";
8
+ import { OctagonAlert, TriangleAlert, MessageSquareWarning, Lightbulb, Info, ImageIcon, Sigma, Workflow } from "lucide-react";
9
+ const NestedContentRendererContext = createContext(
10
+ null
11
+ );
12
+ const NestedContentRendererProvider = NestedContentRendererContext.Provider;
13
+ function useOptionalNestedContentRenderer() {
14
+ return use(NestedContentRendererContext);
15
+ }
16
+ function useNestedContentRenderer() {
17
+ const fn = use(NestedContentRendererContext);
18
+ if (!fn) {
19
+ throw new Error(
20
+ "useNestedContentRenderer must be used within a NestedContentRendererProvider"
21
+ );
22
+ }
23
+ return fn;
24
+ }
25
+ const InfoIcon = () => /* @__PURE__ */ jsx(Info, { size: 16 });
26
+ const LightbulbIcon = () => /* @__PURE__ */ jsx(Lightbulb, { size: 16 });
27
+ const MessageWarningIcon = () => /* @__PURE__ */ jsx(MessageSquareWarning, { size: 16 });
28
+ const TriangleAlertIcon = () => /* @__PURE__ */ jsx(TriangleAlert, { size: 16 });
29
+ const OctagonAlertIcon = () => /* @__PURE__ */ jsx(OctagonAlert, { size: 16 });
30
+ const ALERT_ICONS = {
31
+ note: InfoIcon,
32
+ tip: LightbulbIcon,
33
+ important: MessageWarningIcon,
34
+ warning: TriangleAlertIcon,
35
+ caution: OctagonAlertIcon
36
+ };
37
+ const AlertRenderer = ({ type }) => {
38
+ const Icon = ALERT_ICONS[type];
39
+ return /* @__PURE__ */ jsxs("div", { className: `rich-alert-header rich-alert-header-${type}`, children: [
40
+ /* @__PURE__ */ jsx("span", { className: "rich-alert-icon", children: /* @__PURE__ */ jsx(Icon, {}) }),
41
+ /* @__PURE__ */ jsx("span", { className: "rich-alert-label", children: ALERT_LABELS[type] })
42
+ ] });
43
+ };
44
+ function AlertStaticDecorator({ alertType, contentState }) {
45
+ const renderContent = useNestedContentRenderer();
46
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
47
+ /* @__PURE__ */ jsx(
48
+ RendererWrapper,
49
+ {
50
+ defaultRenderer: AlertRenderer,
51
+ props: { type: alertType },
52
+ rendererKey: "Alert"
53
+ }
54
+ ),
55
+ /* @__PURE__ */ jsx("div", { className: "rich-alert-content", children: renderContent(contentState) })
56
+ ] });
57
+ }
58
+ function extractTextContent(state) {
59
+ function walk(node) {
60
+ if (node.text) return node.text;
61
+ if (node.children) return node.children.map(walk).join("");
62
+ if (node.root) return walk(node.root);
63
+ return "";
64
+ }
65
+ return walk(state);
66
+ }
67
+ const ALERT_TYPES = [
68
+ "note",
69
+ "tip",
70
+ "important",
71
+ "warning",
72
+ "caution"
73
+ ];
74
+ const ALERT_LABELS = {
75
+ note: "Note",
76
+ tip: "Tip",
77
+ important: "Important",
78
+ warning: "Warning",
79
+ caution: "Caution"
80
+ };
81
+ class AlertQuoteNode extends DecoratorNode {
82
+ constructor(alertType, contentState, key) {
83
+ super(key);
84
+ __publicField(this, "__alertType");
85
+ __publicField(this, "__contentState");
86
+ this.__alertType = alertType;
87
+ this.__contentState = contentState || {
88
+ root: {
89
+ children: [
90
+ {
91
+ type: "paragraph",
92
+ children: [],
93
+ direction: null,
94
+ format: "",
95
+ indent: 0,
96
+ textFormat: 0,
97
+ textStyle: "",
98
+ version: 1
99
+ }
100
+ ],
101
+ direction: null,
102
+ format: "",
103
+ indent: 0,
104
+ type: "root",
105
+ version: 1
106
+ }
107
+ };
108
+ }
109
+ static getType() {
110
+ return "alert-quote";
111
+ }
112
+ static clone(node) {
113
+ return new AlertQuoteNode(node.__alertType, node.__contentState, node.__key);
114
+ }
115
+ createDOM(_config) {
116
+ const div = document.createElement("div");
117
+ div.className = `rich-alert rich-alert-${this.__alertType}`;
118
+ return div;
119
+ }
120
+ updateDOM(prevNode, dom) {
121
+ if (prevNode.__alertType !== this.__alertType) {
122
+ dom.className = `rich-alert rich-alert-${this.__alertType}`;
123
+ }
124
+ return false;
125
+ }
126
+ isInline() {
127
+ return false;
128
+ }
129
+ getAlertType() {
130
+ return this.__alertType;
131
+ }
132
+ setAlertType(alertType) {
133
+ const writable = this.getWritable();
134
+ writable.__alertType = alertType;
135
+ }
136
+ getContentState() {
137
+ return this.getLatest().__contentState;
138
+ }
139
+ setContentState(state) {
140
+ const writable = this.getWritable();
141
+ writable.__contentState = state;
142
+ }
143
+ getTextContent() {
144
+ return extractTextContent(this.__contentState);
145
+ }
146
+ static importJSON(serializedNode) {
147
+ return new AlertQuoteNode(serializedNode.alertType, serializedNode.content);
148
+ }
149
+ exportJSON() {
150
+ return {
151
+ ...super.exportJSON(),
152
+ type: "alert-quote",
153
+ alertType: this.__alertType,
154
+ content: this.__contentState,
155
+ version: 1
156
+ };
157
+ }
158
+ decorate(_editor, _config) {
159
+ return createElement(AlertStaticDecorator, {
160
+ alertType: this.__alertType,
161
+ contentState: this.__contentState
162
+ });
163
+ }
164
+ }
165
+ function $isAlertQuoteNode(node) {
166
+ return node instanceof AlertQuoteNode;
167
+ }
168
+ class FootnoteNode extends DecoratorNode {
169
+ constructor(identifier, key) {
170
+ super(key);
171
+ __publicField(this, "__identifier");
172
+ this.__identifier = identifier;
173
+ }
174
+ static getType() {
175
+ return "footnote";
176
+ }
177
+ static clone(node) {
178
+ return new FootnoteNode(node.__identifier, node.__key);
179
+ }
180
+ createDOM(_config) {
181
+ const sup = document.createElement("sup");
182
+ sup.className = "rich-footnote";
183
+ return sup;
184
+ }
185
+ updateDOM() {
186
+ return false;
187
+ }
188
+ isInline() {
189
+ return true;
190
+ }
191
+ static importJSON(serializedNode) {
192
+ return $createFootnoteNode(serializedNode.identifier);
193
+ }
194
+ exportJSON() {
195
+ return {
196
+ ...super.exportJSON(),
197
+ type: "footnote",
198
+ identifier: this.__identifier,
199
+ version: 1
200
+ };
201
+ }
202
+ getIdentifier() {
203
+ return this.getLatest().__identifier;
204
+ }
205
+ setIdentifier(identifier) {
206
+ const writable = this.getWritable();
207
+ writable.__identifier = identifier;
208
+ }
209
+ decorate(_editor, _config) {
210
+ return createRendererDecoration("Footnote", FootnoteStaticRenderer, {
211
+ identifier: this.__identifier
212
+ });
213
+ }
214
+ }
215
+ function $createFootnoteNode(identifier) {
216
+ return new FootnoteNode(identifier);
217
+ }
218
+ function ImageRenderer({
219
+ src,
220
+ altText,
221
+ width,
222
+ height,
223
+ caption,
224
+ thumbhash,
225
+ accent
226
+ }) {
227
+ const [loaded, setLoaded] = useState(false);
228
+ const [zoomed, setZoomed] = useState(false);
229
+ const handleLoad = useCallback(() => setLoaded(true), []);
230
+ const handleZoomOpen = useCallback(() => {
231
+ if (!loaded) return;
232
+ setZoomed(true);
233
+ }, [loaded]);
234
+ const handleZoomClose = useCallback(() => setZoomed(false), []);
235
+ useEffect(() => {
236
+ if (!zoomed) return;
237
+ const onKeyDown = (e) => {
238
+ if (e.key === "Escape") setZoomed(false);
239
+ };
240
+ document.addEventListener("keydown", onKeyDown);
241
+ return () => document.removeEventListener("keydown", onKeyDown);
242
+ }, [zoomed]);
243
+ useEffect(() => {
244
+ if (!zoomed) return;
245
+ const prev = document.body.style.overflow;
246
+ document.body.style.overflow = "hidden";
247
+ return () => {
248
+ document.body.style.overflow = prev;
249
+ };
250
+ }, [zoomed]);
251
+ const handleContainerKeyDown = useCallback(
252
+ (e) => {
253
+ if ((e.key === "Enter" || e.key === " ") && loaded) {
254
+ e.preventDefault();
255
+ setZoomed(true);
256
+ }
257
+ },
258
+ [loaded]
259
+ );
260
+ const placeholderUrl = useMemo(
261
+ () => thumbhash ? decodeThumbHash(thumbhash) : void 0,
262
+ [thumbhash]
263
+ );
264
+ const aspectStyle = width && height ? { aspectRatio: `${width} / ${height}`, maxWidth: "100%", width } : { maxWidth: "100%" };
265
+ return /* @__PURE__ */ jsxs("figure", { className: "rich-image", children: [
266
+ /* @__PURE__ */ jsx(
267
+ "div",
268
+ {
269
+ "aria-label": loaded ? `Zoom image: ${altText}` : void 0,
270
+ className: `rich-image-container${loaded ? " rich-image-loaded" : ""}`,
271
+ role: "button",
272
+ tabIndex: loaded ? 0 : -1,
273
+ style: {
274
+ ...aspectStyle,
275
+ backgroundColor: !loaded && !placeholderUrl ? accent : void 0,
276
+ backgroundImage: !loaded && placeholderUrl ? `url(${placeholderUrl})` : void 0,
277
+ backgroundSize: "cover",
278
+ cursor: loaded ? "zoom-in" : void 0
279
+ },
280
+ onClick: handleZoomOpen,
281
+ onKeyDown: handleContainerKeyDown,
282
+ children: /* @__PURE__ */ jsx(
283
+ "img",
284
+ {
285
+ alt: altText,
286
+ className: loaded ? "rich-image-visible" : "rich-image-hidden",
287
+ height,
288
+ loading: "lazy",
289
+ src,
290
+ style: { maxWidth: "100%", height: "auto" },
291
+ width,
292
+ onLoad: handleLoad
293
+ }
294
+ )
295
+ }
296
+ ),
297
+ caption && /* @__PURE__ */ jsx("figcaption", { children: caption }),
298
+ zoomed && /* @__PURE__ */ jsx(
299
+ "div",
300
+ {
301
+ "aria-label": `Zoomed image: ${altText}`,
302
+ "aria-modal": "true",
303
+ className: "rich-image-zoom-overlay",
304
+ role: "dialog",
305
+ tabIndex: 0,
306
+ onClick: handleZoomClose,
307
+ children: /* @__PURE__ */ jsx("img", { alt: altText, className: "rich-image-zoom-img", src })
308
+ }
309
+ )
310
+ ] });
311
+ }
312
+ const OPEN_IMAGE_UPLOAD_DIALOG_COMMAND = createCommand(
313
+ "OPEN_IMAGE_UPLOAD_DIALOG_COMMAND"
314
+ );
315
+ function sanitizeImageSrc(src) {
316
+ const trimmed = src.trim();
317
+ if (/^(?:javascript\s*:|vbscript\s*:|data\s*:(?!image\/))/i.test(trimmed)) {
318
+ return "";
319
+ }
320
+ return trimmed;
321
+ }
322
+ function sanitizeColor(value) {
323
+ if (!value) return void 0;
324
+ const trimmed = value.trim();
325
+ if (/^#[\da-f]{3,8}$/i.test(trimmed)) return trimmed;
326
+ if (/^(?:rgb|hsl)a?\([^)]+\)$/i.test(trimmed)) return trimmed;
327
+ if (/^[a-z]{3,20}$/i.test(trimmed)) return trimmed;
328
+ return void 0;
329
+ }
330
+ const _ImageNode = class _ImageNode extends DecoratorNode {
331
+ constructor(payload, key) {
332
+ super(key);
333
+ __publicField(this, "__src");
334
+ __publicField(this, "__altText");
335
+ __publicField(this, "__width");
336
+ __publicField(this, "__height");
337
+ __publicField(this, "__caption");
338
+ __publicField(this, "__thumbhash");
339
+ __publicField(this, "__accent");
340
+ this.__src = sanitizeImageSrc(payload.src);
341
+ this.__altText = payload.altText;
342
+ this.__width = payload.width;
343
+ this.__height = payload.height;
344
+ this.__caption = payload.caption;
345
+ this.__thumbhash = payload.thumbhash;
346
+ this.__accent = sanitizeColor(payload.accent);
347
+ }
348
+ static getType() {
349
+ return "image";
350
+ }
351
+ static clone(node) {
352
+ return new _ImageNode(
353
+ {
354
+ src: node.__src,
355
+ altText: node.__altText,
356
+ width: node.__width,
357
+ height: node.__height,
358
+ caption: node.__caption,
359
+ thumbhash: node.__thumbhash,
360
+ accent: node.__accent
361
+ },
362
+ node.__key
363
+ );
364
+ }
365
+ createDOM(_config) {
366
+ const div = document.createElement("div");
367
+ div.className = "rich-image-wrapper";
368
+ return div;
369
+ }
370
+ updateDOM() {
371
+ return false;
372
+ }
373
+ isInline() {
374
+ return false;
375
+ }
376
+ static importJSON(serializedNode) {
377
+ return $createImageNode({
378
+ src: serializedNode.src,
379
+ altText: serializedNode.altText,
380
+ width: serializedNode.width,
381
+ height: serializedNode.height,
382
+ caption: serializedNode.caption,
383
+ thumbhash: serializedNode.thumbhash,
384
+ accent: serializedNode.accent
385
+ });
386
+ }
387
+ exportJSON() {
388
+ return {
389
+ ...super.exportJSON(),
390
+ type: "image",
391
+ src: this.__src,
392
+ altText: this.__altText,
393
+ width: this.__width,
394
+ height: this.__height,
395
+ caption: this.__caption,
396
+ thumbhash: this.__thumbhash,
397
+ accent: this.__accent,
398
+ version: 1
399
+ };
400
+ }
401
+ setSrc(src) {
402
+ const writable = this.getWritable();
403
+ writable.__src = sanitizeImageSrc(src);
404
+ }
405
+ setAltText(altText) {
406
+ const writable = this.getWritable();
407
+ writable.__altText = altText;
408
+ }
409
+ setCaption(caption) {
410
+ const writable = this.getWritable();
411
+ writable.__caption = caption;
412
+ }
413
+ setDimensions(width, height) {
414
+ const writable = this.getWritable();
415
+ writable.__width = width;
416
+ writable.__height = height;
417
+ }
418
+ setThumbhash(thumbhash) {
419
+ const writable = this.getWritable();
420
+ writable.__thumbhash = thumbhash;
421
+ }
422
+ setAccent(accent) {
423
+ const writable = this.getWritable();
424
+ writable.__accent = sanitizeColor(accent);
425
+ }
426
+ getSrc() {
427
+ return this.__src;
428
+ }
429
+ getAltText() {
430
+ return this.__altText;
431
+ }
432
+ getCaption() {
433
+ return this.__caption;
434
+ }
435
+ getWidth() {
436
+ return this.__width;
437
+ }
438
+ getHeight() {
439
+ return this.__height;
440
+ }
441
+ getThumbhash() {
442
+ return this.__thumbhash;
443
+ }
444
+ getAccent() {
445
+ return this.__accent;
446
+ }
447
+ decorate(_editor, _config) {
448
+ return createRendererDecoration("Image", ImageRenderer, {
449
+ src: this.__src,
450
+ altText: this.__altText,
451
+ width: this.__width,
452
+ height: this.__height,
453
+ caption: this.__caption,
454
+ thumbhash: this.__thumbhash,
455
+ accent: this.__accent
456
+ });
457
+ }
458
+ };
459
+ __publicField(_ImageNode, "commandItems", [
460
+ {
461
+ title: "Image",
462
+ icon: createElement(ImageIcon, { size: 20 }),
463
+ description: "Upload or embed an image",
464
+ keywords: ["image", "picture", "photo"],
465
+ section: "MEDIA",
466
+ placement: ["slash", "toolbar"],
467
+ group: "insert",
468
+ onSelect: (editor) => {
469
+ const opened = editor.dispatchCommand(OPEN_IMAGE_UPLOAD_DIALOG_COMMAND, void 0);
470
+ if (opened) return;
471
+ editor.update(() => {
472
+ $insertNodes([$createImageNode({ src: "", altText: "" })]);
473
+ });
474
+ }
475
+ }
476
+ ]);
477
+ let ImageNode = _ImageNode;
478
+ function $createImageNode(payload) {
479
+ return new ImageNode(payload);
480
+ }
481
+ function $isImageNode(node) {
482
+ return node instanceof ImageNode;
483
+ }
484
+ const _KaTeXBlockNode = class _KaTeXBlockNode extends DecoratorNode {
485
+ constructor(equation, key) {
486
+ super(key);
487
+ __publicField(this, "__equation");
488
+ this.__equation = equation;
489
+ }
490
+ static getType() {
491
+ return "katex-block";
492
+ }
493
+ static clone(node) {
494
+ return new _KaTeXBlockNode(node.__equation, node.__key);
495
+ }
496
+ createDOM(_config) {
497
+ const div = document.createElement("div");
498
+ div.className = "rich-katex-block-wrapper";
499
+ return div;
500
+ }
501
+ updateDOM() {
502
+ return false;
503
+ }
504
+ isInline() {
505
+ return false;
506
+ }
507
+ static importJSON(serializedNode) {
508
+ return $createKaTeXBlockNode(serializedNode.equation);
509
+ }
510
+ exportJSON() {
511
+ return {
512
+ ...super.exportJSON(),
513
+ type: "katex-block",
514
+ equation: this.__equation,
515
+ version: 1
516
+ };
517
+ }
518
+ getEquation() {
519
+ return this.__equation;
520
+ }
521
+ setEquation(equation) {
522
+ const writable = this.getWritable();
523
+ writable.__equation = equation;
524
+ }
525
+ decorate(_editor, _config) {
526
+ return createRendererDecoration("KaTeX", KaTeXRenderer, {
527
+ equation: this.__equation,
528
+ displayMode: true
529
+ });
530
+ }
531
+ };
532
+ __publicField(_KaTeXBlockNode, "slashMenuItems", [
533
+ {
534
+ title: "Math Equation",
535
+ icon: createElement(Sigma, { size: 20 }),
536
+ description: "KaTeX block formula",
537
+ keywords: ["math", "equation", "latex", "katex"],
538
+ section: "ADVANCED",
539
+ onSelect: (editor) => {
540
+ editor.update(() => {
541
+ $insertNodes([$createKaTeXBlockNode("")]);
542
+ });
543
+ }
544
+ }
545
+ ]);
546
+ let KaTeXBlockNode = _KaTeXBlockNode;
547
+ function $createKaTeXBlockNode(equation) {
548
+ return new KaTeXBlockNode(equation);
549
+ }
550
+ function $isKaTeXBlockNode(node) {
551
+ return node instanceof KaTeXBlockNode;
552
+ }
553
+ class KaTeXInlineNode extends DecoratorNode {
554
+ constructor(equation, key) {
555
+ super(key);
556
+ __publicField(this, "__equation");
557
+ this.__equation = equation;
558
+ }
559
+ static getType() {
560
+ return "katex-inline";
561
+ }
562
+ static clone(node) {
563
+ return new KaTeXInlineNode(node.__equation, node.__key);
564
+ }
565
+ createDOM(_config) {
566
+ return document.createElement("span");
567
+ }
568
+ updateDOM() {
569
+ return false;
570
+ }
571
+ isInline() {
572
+ return true;
573
+ }
574
+ static importJSON(serializedNode) {
575
+ return $createKaTeXInlineNode(serializedNode.equation);
576
+ }
577
+ exportJSON() {
578
+ return {
579
+ ...super.exportJSON(),
580
+ type: "katex-inline",
581
+ equation: this.__equation,
582
+ version: 1
583
+ };
584
+ }
585
+ getEquation() {
586
+ return this.__equation;
587
+ }
588
+ setEquation(equation) {
589
+ const writable = this.getWritable();
590
+ writable.__equation = equation;
591
+ }
592
+ decorate(_editor, _config) {
593
+ return createRendererDecoration("KaTeX", KaTeXRenderer, {
594
+ equation: this.__equation,
595
+ displayMode: false
596
+ });
597
+ }
598
+ }
599
+ function $createKaTeXInlineNode(equation) {
600
+ return new KaTeXInlineNode(equation);
601
+ }
602
+ function $isKaTeXInlineNode(node) {
603
+ return node instanceof KaTeXInlineNode;
604
+ }
605
+ function MentionRenderer({ handle, displayName }) {
606
+ const normalizedHandle = handle.replace(/^@+/, "");
607
+ const label = displayName || normalizedHandle;
608
+ return /* @__PURE__ */ jsx("span", { className: "rich-mention rich-mention-plain", children: /* @__PURE__ */ jsxs("span", { className: "rich-mention-handle", children: [
609
+ "@",
610
+ label
611
+ ] }) });
612
+ }
613
+ const _MentionNode = class _MentionNode extends DecoratorNode {
614
+ constructor(platform, handle, displayName, key) {
615
+ super(key);
616
+ __publicField(this, "__platform");
617
+ __publicField(this, "__handle");
618
+ __publicField(this, "__displayName");
619
+ this.__platform = platform;
620
+ this.__handle = handle;
621
+ this.__displayName = displayName;
622
+ }
623
+ static getType() {
624
+ return "mention";
625
+ }
626
+ static clone(node) {
627
+ return new _MentionNode(
628
+ node.__platform,
629
+ node.__handle,
630
+ node.__displayName,
631
+ node.__key
632
+ );
633
+ }
634
+ createDOM(_config) {
635
+ const el = document.createElement("span");
636
+ el.style.display = "inline-flex";
637
+ el.style.alignItems = "center";
638
+ el.style.height = "1lh";
639
+ return el;
640
+ }
641
+ updateDOM() {
642
+ return false;
643
+ }
644
+ isInline() {
645
+ return true;
646
+ }
647
+ getPlatform() {
648
+ return this.getLatest().__platform;
649
+ }
650
+ getHandle() {
651
+ return this.getLatest().__handle;
652
+ }
653
+ getDisplayName() {
654
+ return this.getLatest().__displayName;
655
+ }
656
+ static importJSON(serializedNode) {
657
+ return $createMentionNode(
658
+ serializedNode.platform,
659
+ serializedNode.handle,
660
+ serializedNode.displayName
661
+ );
662
+ }
663
+ exportJSON() {
664
+ return {
665
+ ...super.exportJSON(),
666
+ type: "mention",
667
+ platform: this.__platform,
668
+ handle: this.__handle,
669
+ ...this.__displayName ? { displayName: this.__displayName } : {},
670
+ version: 1
671
+ };
672
+ }
673
+ decorate(_editor, _config) {
674
+ return createRendererDecoration("Mention", MentionRenderer, {
675
+ platform: this.__platform,
676
+ handle: this.__handle,
677
+ displayName: this.__displayName
678
+ });
679
+ }
680
+ };
681
+ __publicField(_MentionNode, "slashMenuItems", [
682
+ {
683
+ title: "Mention",
684
+ icon: createElement(
685
+ "span",
686
+ { style: { fontSize: 16, fontWeight: 700 } },
687
+ "@"
688
+ ),
689
+ description: "Mention a social account",
690
+ keywords: ["mention", "at", "@", "github", "twitter"],
691
+ section: "INLINE",
692
+ onSelect: (editor) => {
693
+ editor.update(() => {
694
+ const selection = $getSelection();
695
+ if ($isRangeSelection(selection)) {
696
+ selection.insertText("@");
697
+ }
698
+ });
699
+ }
700
+ }
701
+ ]);
702
+ let MentionNode = _MentionNode;
703
+ function $createMentionNode(platform, handle, displayName) {
704
+ return new MentionNode(platform, handle, displayName);
705
+ }
706
+ function $isMentionNode(node) {
707
+ return node instanceof MentionNode;
708
+ }
709
+ function MermaidRenderer({ content }) {
710
+ return /* @__PURE__ */ jsx("div", { className: "rich-mermaid-block", children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: content }) }) });
711
+ }
712
+ const _MermaidNode = class _MermaidNode extends DecoratorNode {
713
+ constructor(diagram, key) {
714
+ super(key);
715
+ __publicField(this, "__diagram");
716
+ this.__diagram = diagram;
717
+ }
718
+ static getType() {
719
+ return "mermaid";
720
+ }
721
+ static clone(node) {
722
+ return new _MermaidNode(node.__diagram, node.__key);
723
+ }
724
+ createDOM(_config) {
725
+ const div = document.createElement("div");
726
+ div.className = "rich-mermaid-wrapper";
727
+ return div;
728
+ }
729
+ updateDOM() {
730
+ return false;
731
+ }
732
+ isInline() {
733
+ return false;
734
+ }
735
+ static importJSON(serializedNode) {
736
+ return $createMermaidNode(serializedNode.diagram);
737
+ }
738
+ exportJSON() {
739
+ return {
740
+ ...super.exportJSON(),
741
+ type: "mermaid",
742
+ diagram: this.__diagram,
743
+ version: 1
744
+ };
745
+ }
746
+ getDiagram() {
747
+ return this.__diagram;
748
+ }
749
+ setDiagram(diagram) {
750
+ const writable = this.getWritable();
751
+ writable.__diagram = diagram;
752
+ }
753
+ decorate(editor, _config) {
754
+ const nodeKey = this.__key;
755
+ return createRendererDecoration("Mermaid", MermaidRenderer, {
756
+ content: this.__diagram,
757
+ onContentChange: (newDiagram) => {
758
+ editor.update(() => {
759
+ const node = $getNodeByKey(nodeKey);
760
+ if (node) {
761
+ node.setDiagram(newDiagram);
762
+ }
763
+ });
764
+ }
765
+ });
766
+ }
767
+ };
768
+ __publicField(_MermaidNode, "commandItems", [
769
+ {
770
+ title: "Mermaid Diagram",
771
+ icon: createElement(Workflow, { size: 20 }),
772
+ description: "Flowchart, sequence diagram",
773
+ keywords: ["mermaid", "diagram", "chart", "flowchart"],
774
+ section: "MEDIA",
775
+ placement: ["slash", "toolbar"],
776
+ group: "insert",
777
+ onSelect: (editor) => {
778
+ editor.update(() => {
779
+ $insertNodes([
780
+ $createMermaidNode("graph TD\n A[Start] --> B[End]")
781
+ ]);
782
+ });
783
+ }
784
+ }
785
+ ]);
786
+ let MermaidNode = _MermaidNode;
787
+ function $createMermaidNode(diagram) {
788
+ return new MermaidNode(diagram);
789
+ }
790
+ function $isMermaidNode(node) {
791
+ return node instanceof MermaidNode;
792
+ }
793
+ class SpoilerNode extends ElementNode {
794
+ static getType() {
795
+ return "spoiler";
796
+ }
797
+ static clone(node) {
798
+ return new SpoilerNode(node.__key);
799
+ }
800
+ constructor(key) {
801
+ super(key);
802
+ }
803
+ createDOM(_config) {
804
+ const span = document.createElement("span");
805
+ span.className = "rich-spoiler";
806
+ span.setAttribute("role", "button");
807
+ span.setAttribute("tabindex", "0");
808
+ span.setAttribute("aria-label", "Spoiler (click to reveal)");
809
+ const toggle = () => {
810
+ if (span.isContentEditable) return;
811
+ const revealed = span.classList.toggle("rich-spoiler-revealed");
812
+ span.setAttribute(
813
+ "aria-label",
814
+ revealed ? "Spoiler (revealed)" : "Spoiler (click to reveal)"
815
+ );
816
+ };
817
+ span.addEventListener("click", toggle);
818
+ span.addEventListener("keydown", (e) => {
819
+ if (e.key === "Enter" || e.key === " ") {
820
+ e.preventDefault();
821
+ toggle();
822
+ }
823
+ });
824
+ return span;
825
+ }
826
+ updateDOM() {
827
+ return false;
828
+ }
829
+ static importJSON(_serializedNode) {
830
+ return $createSpoilerNode();
831
+ }
832
+ exportJSON() {
833
+ return {
834
+ ...super.exportJSON(),
835
+ type: "spoiler",
836
+ version: 1
837
+ };
838
+ }
839
+ canInsertTextBefore() {
840
+ return true;
841
+ }
842
+ canInsertTextAfter() {
843
+ return true;
844
+ }
845
+ isInline() {
846
+ return true;
847
+ }
848
+ }
849
+ function $createSpoilerNode() {
850
+ return new SpoilerNode();
851
+ }
852
+ const editorTheme = {
853
+ text: {
854
+ bold: "rich-text-bold",
855
+ italic: "rich-text-italic",
856
+ underline: "rich-text-underline",
857
+ strikethrough: "rich-text-strikethrough",
858
+ superscript: "rich-text-superscript",
859
+ subscript: "rich-text-subscript",
860
+ code: "rich-text-code",
861
+ highlight: "rich-text-highlight"
862
+ },
863
+ heading: {
864
+ h1: "rich-heading-h1",
865
+ h2: "rich-heading-h2",
866
+ h3: "rich-heading-h3",
867
+ h4: "rich-heading-h4",
868
+ h5: "rich-heading-h5",
869
+ h6: "rich-heading-h6"
870
+ },
871
+ list: {
872
+ ol: "rich-list-ol",
873
+ ul: "rich-list-ul",
874
+ listitem: "rich-list-item",
875
+ listitemChecked: "rich-list-item-checked",
876
+ listitemUnchecked: "rich-list-item-unchecked",
877
+ checklist: "rich-checklist",
878
+ nested: {
879
+ listitem: "rich-list-nested-item"
880
+ }
881
+ },
882
+ quote: "rich-quote",
883
+ link: "rich-link",
884
+ paragraph: "rich-paragraph",
885
+ code: "rich-code-block",
886
+ table: "rich-table",
887
+ tableCell: "rich-table-cell",
888
+ tableCellHeader: "rich-table-cell-header",
889
+ tableScrollableWrapper: "rich-table-scrollable-wrapper",
890
+ /** Used by @lexical/extension HorizontalRuleNode */
891
+ hr: "rich-hr"
892
+ };
893
+ export {
894
+ $createImageNode as $,
895
+ ALERT_LABELS as A,
896
+ FootnoteNode as F,
897
+ ImageNode as I,
898
+ KaTeXBlockNode as K,
899
+ MentionNode as M,
900
+ NestedContentRendererProvider as N,
901
+ OPEN_IMAGE_UPLOAD_DIALOG_COMMAND as O,
902
+ SpoilerNode as S,
903
+ extractTextContent as a,
904
+ useOptionalNestedContentRenderer as b,
905
+ $createMentionNode as c,
906
+ $createMermaidNode as d,
907
+ editorTheme as e,
908
+ $isImageNode as f,
909
+ $isKaTeXBlockNode as g,
910
+ $isKaTeXInlineNode as h,
911
+ $isMentionNode as i,
912
+ $isMermaidNode as j,
913
+ ALERT_TYPES as k,
914
+ KaTeXInlineNode as l,
915
+ MermaidNode as m,
916
+ $isAlertQuoteNode as n,
917
+ AlertRenderer as o,
918
+ AlertQuoteNode as p,
919
+ $createKaTeXInlineNode as q,
920
+ $createKaTeXBlockNode as r,
921
+ $createFootnoteNode as s,
922
+ $createSpoilerNode as t,
923
+ useNestedContentRenderer as u
924
+ };