@haklex/rich-editor 0.1.1 → 0.3.0

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 (65) hide show
  1. package/dist/AlertQuoteEditNode-C55sxsR3.js +267 -0
  2. package/dist/KaTeXRenderer-CQQT3BMw.js +215 -0
  3. package/dist/LinkCardRenderer-CigqFwCv.js +45 -0
  4. package/dist/MermaidPlugin-BrOr-wQi.js +67 -0
  5. package/dist/RubyRenderer-jOkydJHg.js +15 -0
  6. package/dist/SubmitShortcutPlugin-DhyVFzoj.js +2186 -0
  7. package/dist/commands-entry.mjs +54 -74
  8. package/dist/components/decorators/PollEditDecorator.d.ts +13 -0
  9. package/dist/components/decorators/PollEditDecorator.d.ts.map +1 -0
  10. package/dist/components/renderers/PollRenderer.d.ts +3 -0
  11. package/dist/components/renderers/PollRenderer.d.ts.map +1 -0
  12. package/dist/config-B5BuLljq.js +1633 -0
  13. package/dist/config-edit.d.ts.map +1 -1
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/context/PollDataContext.d.ts +11 -0
  16. package/dist/context/PollDataContext.d.ts.map +1 -0
  17. package/dist/extractPolls-DO31LNrp.js +116 -0
  18. package/dist/grid.css-CJCkLTZc.js +44 -0
  19. package/dist/index.d.ts +5 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.mjs +121 -180
  22. package/dist/katex.css-CIOEOXyd.js +145 -0
  23. package/dist/node-registry-Dz5OTkh4.js +946 -0
  24. package/dist/nodes/PollEditNode.d.ts +14 -0
  25. package/dist/nodes/PollEditNode.d.ts.map +1 -0
  26. package/dist/nodes/PollNode.d.ts +52 -0
  27. package/dist/nodes/PollNode.d.ts.map +1 -0
  28. package/dist/nodes-entry.d.ts +3 -0
  29. package/dist/nodes-entry.d.ts.map +1 -1
  30. package/dist/nodes-entry.mjs +5 -50
  31. package/dist/normalizeSerializedEditorState-B-1wmGzd.js +78 -0
  32. package/dist/plugins-entry.mjs +3 -28
  33. package/dist/renderers-entry.mjs +41 -61
  34. package/dist/rich-editor.css +2 -1
  35. package/dist/static-entry.d.ts +5 -0
  36. package/dist/static-entry.d.ts.map +1 -1
  37. package/dist/static-entry.mjs +16 -66
  38. package/dist/styles/index.d.ts +2 -0
  39. package/dist/styles/index.d.ts.map +1 -1
  40. package/dist/styles/poll-edit.css.d.ts +35 -0
  41. package/dist/styles/poll-edit.css.d.ts.map +1 -0
  42. package/dist/styles/poll.css.d.ts +43 -0
  43. package/dist/styles/poll.css.d.ts.map +1 -0
  44. package/dist/styles-entry.mjs +3 -21
  45. package/dist/theme-B5B2EOWM.js +1099 -0
  46. package/dist/types/poll.d.ts +36 -0
  47. package/dist/types/poll.d.ts.map +1 -0
  48. package/dist/types/renderer-config.d.ts +3 -0
  49. package/dist/types/renderer-config.d.ts.map +1 -1
  50. package/dist/utils/extractPolls.d.ts +4 -0
  51. package/dist/utils/extractPolls.d.ts.map +1 -0
  52. package/package.json +30 -30
  53. package/dist/AlertQuoteEditNode-sPNf3_7P.js +0 -293
  54. package/dist/KaTeXRenderer-CQyQzNTJ.js +0 -218
  55. package/dist/LinkCardRenderer-QmkOlyXb.js +0 -36
  56. package/dist/MermaidPlugin-DKuGUcCG.js +0 -101
  57. package/dist/PresentDialogContext-DRroMIoK.js +0 -71
  58. package/dist/RubyRenderer-CJQmODir.js +0 -14
  59. package/dist/SubmitShortcutPlugin-D9uKYHda.js +0 -2427
  60. package/dist/config-Dl3ZkytB.js +0 -1362
  61. package/dist/grid.css-Md5-Cfx_.js +0 -11
  62. package/dist/katex.css-Csc-7N7u.js +0 -28
  63. package/dist/node-registry-CovhHUB6.js +0 -824
  64. package/dist/normalizeSerializedEditorState-k5G4xSi9.js +0 -85
  65. package/dist/theme-lEwScxEX.js +0 -1113
@@ -1,1113 +0,0 @@
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, getRegisteredNode, $getEditor, $getSelection, $isRangeSelection, $getNodeByKey, ElementNode, TextNode } 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-CQyQzNTJ.js";
8
- import { OctagonAlert, TriangleAlert, MessageSquareWarning, Lightbulb, Info, ImageIcon, Sigma, Workflow, Tag } from "lucide-react";
9
- import { s as semanticClassNames, d as sharedStyles } from "./katex.css-Csc-7N7u.js";
10
- const NestedContentRendererContext = createContext(null);
11
- const NestedContentRendererProvider = NestedContentRendererContext.Provider;
12
- function useOptionalNestedContentRenderer() {
13
- return use(NestedContentRendererContext);
14
- }
15
- function useNestedContentRenderer() {
16
- const fn = use(NestedContentRendererContext);
17
- if (!fn) {
18
- throw new Error("useNestedContentRenderer must be used within a NestedContentRendererProvider");
19
- }
20
- return fn;
21
- }
22
- const InfoIcon = () => /* @__PURE__ */ jsx(Info, { size: 16 });
23
- const LightbulbIcon = () => /* @__PURE__ */ jsx(Lightbulb, { size: 16 });
24
- const MessageWarningIcon = () => /* @__PURE__ */ jsx(MessageSquareWarning, { size: 16 });
25
- const TriangleAlertIcon = () => /* @__PURE__ */ jsx(TriangleAlert, { size: 16 });
26
- const OctagonAlertIcon = () => /* @__PURE__ */ jsx(OctagonAlert, { size: 16 });
27
- const ALERT_ICONS = {
28
- note: InfoIcon,
29
- tip: LightbulbIcon,
30
- important: MessageWarningIcon,
31
- warning: TriangleAlertIcon,
32
- caution: OctagonAlertIcon
33
- };
34
- const AlertRenderer = ({ type }) => {
35
- const Icon = ALERT_ICONS[type];
36
- return /* @__PURE__ */ jsxs("div", { className: `rich-alert-header rich-alert-header-${type}`, children: [
37
- /* @__PURE__ */ jsx("span", { className: "rich-alert-icon", children: /* @__PURE__ */ jsx(Icon, {}) }),
38
- /* @__PURE__ */ jsx("span", { className: "rich-alert-label", children: ALERT_LABELS[type] })
39
- ] });
40
- };
41
- function AlertStaticDecorator({ alertType, contentState }) {
42
- const renderContent = useNestedContentRenderer();
43
- return /* @__PURE__ */ jsxs(Fragment, { children: [
44
- /* @__PURE__ */ jsx(
45
- RendererWrapper,
46
- {
47
- defaultRenderer: AlertRenderer,
48
- props: { type: alertType },
49
- rendererKey: "Alert"
50
- }
51
- ),
52
- /* @__PURE__ */ jsx("div", { className: "rich-alert-content", children: renderContent(contentState) })
53
- ] });
54
- }
55
- function extractTextContent(state) {
56
- function walk(node) {
57
- if (node.text) return node.text;
58
- if (node.children) return node.children.map(walk).join("");
59
- if (node.root) return walk(node.root);
60
- return "";
61
- }
62
- return walk(state);
63
- }
64
- const ALERT_TYPES = ["note", "tip", "important", "warning", "caution"];
65
- const ALERT_LABELS = {
66
- note: "Note",
67
- tip: "Tip",
68
- important: "Important",
69
- warning: "Warning",
70
- caution: "Caution"
71
- };
72
- class AlertQuoteNode extends DecoratorNode {
73
- constructor(alertType, contentState, key) {
74
- super(key);
75
- __publicField(this, "__alertType");
76
- __publicField(this, "__contentState");
77
- this.__alertType = alertType;
78
- this.__contentState = contentState || {
79
- root: {
80
- children: [
81
- {
82
- type: "paragraph",
83
- children: [],
84
- direction: null,
85
- format: "",
86
- indent: 0,
87
- textFormat: 0,
88
- textStyle: "",
89
- version: 1
90
- }
91
- ],
92
- direction: null,
93
- format: "",
94
- indent: 0,
95
- type: "root",
96
- version: 1
97
- }
98
- };
99
- }
100
- static getType() {
101
- return "alert-quote";
102
- }
103
- static clone(node) {
104
- return new AlertQuoteNode(node.__alertType, node.__contentState, node.__key);
105
- }
106
- createDOM(_config) {
107
- const div = document.createElement("div");
108
- div.className = `${semanticClassNames.alert} ${sharedStyles.alert} rich-alert-${this.__alertType}`;
109
- return div;
110
- }
111
- updateDOM(prevNode, dom) {
112
- if (prevNode.__alertType !== this.__alertType) {
113
- dom.className = `${semanticClassNames.alert} ${sharedStyles.alert} rich-alert-${this.__alertType}`;
114
- }
115
- return false;
116
- }
117
- isInline() {
118
- return false;
119
- }
120
- getAlertType() {
121
- return this.__alertType;
122
- }
123
- setAlertType(alertType) {
124
- const writable = this.getWritable();
125
- writable.__alertType = alertType;
126
- }
127
- getContentState() {
128
- return this.getLatest().__contentState;
129
- }
130
- setContentState(state) {
131
- const writable = this.getWritable();
132
- writable.__contentState = state;
133
- }
134
- getTextContent() {
135
- return extractTextContent(this.__contentState);
136
- }
137
- static importJSON(serializedNode) {
138
- return new AlertQuoteNode(serializedNode.alertType, serializedNode.content);
139
- }
140
- exportJSON() {
141
- return {
142
- ...super.exportJSON(),
143
- type: "alert-quote",
144
- alertType: this.__alertType,
145
- content: this.__contentState,
146
- version: 1
147
- };
148
- }
149
- decorate(_editor, _config) {
150
- return createElement(AlertStaticDecorator, {
151
- alertType: this.__alertType,
152
- contentState: this.__contentState
153
- });
154
- }
155
- }
156
- function $isAlertQuoteNode(node) {
157
- return node instanceof AlertQuoteNode;
158
- }
159
- class FootnoteNode extends DecoratorNode {
160
- constructor(identifier, key) {
161
- super(key);
162
- __publicField(this, "__identifier");
163
- this.__identifier = identifier;
164
- }
165
- static getType() {
166
- return "footnote";
167
- }
168
- static clone(node) {
169
- return new FootnoteNode(node.__identifier, node.__key);
170
- }
171
- createDOM(_config) {
172
- const sup = document.createElement("sup");
173
- sup.className = `${semanticClassNames.footnote} ${sharedStyles.footnote}`;
174
- return sup;
175
- }
176
- updateDOM() {
177
- return false;
178
- }
179
- isInline() {
180
- return true;
181
- }
182
- static importJSON(serializedNode) {
183
- return $createFootnoteNode(serializedNode.identifier);
184
- }
185
- exportJSON() {
186
- return {
187
- ...super.exportJSON(),
188
- type: "footnote",
189
- identifier: this.__identifier,
190
- version: 1
191
- };
192
- }
193
- getIdentifier() {
194
- return this.getLatest().__identifier;
195
- }
196
- setIdentifier(identifier) {
197
- const writable = this.getWritable();
198
- writable.__identifier = identifier;
199
- }
200
- decorate(_editor, _config) {
201
- return createRendererDecoration("Footnote", FootnoteStaticRenderer, {
202
- identifier: this.__identifier
203
- });
204
- }
205
- }
206
- function $createFootnoteNode(identifier) {
207
- return new FootnoteNode(identifier);
208
- }
209
- function ImageRenderer({
210
- src,
211
- altText,
212
- width,
213
- height,
214
- caption,
215
- thumbhash,
216
- accent
217
- }) {
218
- const [loaded, setLoaded] = useState(false);
219
- const [zoomed, setZoomed] = useState(false);
220
- const handleLoad = useCallback(() => setLoaded(true), []);
221
- const handleZoomOpen = useCallback(() => {
222
- if (!loaded) return;
223
- setZoomed(true);
224
- }, [loaded]);
225
- const handleZoomClose = useCallback(() => setZoomed(false), []);
226
- useEffect(() => {
227
- if (!zoomed) return;
228
- const onKeyDown = (e) => {
229
- if (e.key === "Escape") setZoomed(false);
230
- };
231
- document.addEventListener("keydown", onKeyDown);
232
- return () => document.removeEventListener("keydown", onKeyDown);
233
- }, [zoomed]);
234
- useEffect(() => {
235
- if (!zoomed) return;
236
- const prev = document.body.style.overflow;
237
- document.body.style.overflow = "hidden";
238
- return () => {
239
- document.body.style.overflow = prev;
240
- };
241
- }, [zoomed]);
242
- const handleContainerKeyDown = useCallback(
243
- (e) => {
244
- if ((e.key === "Enter" || e.key === " ") && loaded) {
245
- e.preventDefault();
246
- setZoomed(true);
247
- }
248
- },
249
- [loaded]
250
- );
251
- const placeholderUrl = useMemo(
252
- () => thumbhash ? decodeThumbHash(thumbhash) : void 0,
253
- [thumbhash]
254
- );
255
- const aspectStyle = width && height ? { aspectRatio: `${width} / ${height}`, maxWidth: "100%", width } : { maxWidth: "100%" };
256
- return /* @__PURE__ */ jsxs("figure", { className: "rich-image", children: [
257
- /* @__PURE__ */ jsx(
258
- "div",
259
- {
260
- "aria-label": loaded ? `Zoom image: ${altText}` : void 0,
261
- className: `rich-image-container${loaded ? " rich-image-loaded" : ""}`,
262
- role: "button",
263
- tabIndex: loaded ? 0 : -1,
264
- style: {
265
- ...aspectStyle,
266
- backgroundColor: !loaded && !placeholderUrl ? accent : void 0,
267
- backgroundImage: !loaded && placeholderUrl ? `url(${placeholderUrl})` : void 0,
268
- backgroundSize: "cover",
269
- cursor: loaded ? "zoom-in" : void 0
270
- },
271
- onClick: handleZoomOpen,
272
- onKeyDown: handleContainerKeyDown,
273
- children: /* @__PURE__ */ jsx(
274
- "img",
275
- {
276
- alt: altText,
277
- className: loaded ? "rich-image-visible" : "rich-image-hidden",
278
- height,
279
- loading: "lazy",
280
- src,
281
- style: { maxWidth: "100%", height: "auto" },
282
- width,
283
- onLoad: handleLoad
284
- }
285
- )
286
- }
287
- ),
288
- caption && /* @__PURE__ */ jsx("figcaption", { children: caption }),
289
- zoomed && /* @__PURE__ */ jsx(
290
- "div",
291
- {
292
- "aria-label": `Zoomed image: ${altText}`,
293
- "aria-modal": "true",
294
- className: "rich-image-zoom-overlay",
295
- role: "dialog",
296
- tabIndex: 0,
297
- onClick: handleZoomClose,
298
- children: /* @__PURE__ */ jsx("img", { alt: altText, className: "rich-image-zoom-img", src })
299
- }
300
- )
301
- ] });
302
- }
303
- const OPEN_IMAGE_UPLOAD_DIALOG_COMMAND = createCommand(
304
- "OPEN_IMAGE_UPLOAD_DIALOG_COMMAND"
305
- );
306
- function sanitizeImageSrc(src) {
307
- const trimmed = src.trim();
308
- if (/^(?:javascript\s*:|vbscript\s*:|data\s*:(?!image\/))/i.test(trimmed)) {
309
- return "";
310
- }
311
- return trimmed;
312
- }
313
- function sanitizeColor(value) {
314
- if (!value) return void 0;
315
- const trimmed = value.trim();
316
- if (/^#[\da-f]{3,8}$/i.test(trimmed)) return trimmed;
317
- if (/^(?:rgb|hsl)a?\([^)]+\)$/i.test(trimmed)) return trimmed;
318
- if (/^[a-z]{3,20}$/i.test(trimmed)) return trimmed;
319
- return void 0;
320
- }
321
- const _ImageNode = class _ImageNode extends DecoratorNode {
322
- constructor(payload, key) {
323
- super(key);
324
- __publicField(this, "__src");
325
- __publicField(this, "__altText");
326
- __publicField(this, "__width");
327
- __publicField(this, "__height");
328
- __publicField(this, "__caption");
329
- __publicField(this, "__thumbhash");
330
- __publicField(this, "__accent");
331
- this.__src = sanitizeImageSrc(payload.src);
332
- this.__altText = payload.altText;
333
- this.__width = payload.width;
334
- this.__height = payload.height;
335
- this.__caption = payload.caption;
336
- this.__thumbhash = payload.thumbhash;
337
- this.__accent = sanitizeColor(payload.accent);
338
- }
339
- static getType() {
340
- return "image";
341
- }
342
- static clone(node) {
343
- return new _ImageNode(
344
- {
345
- src: node.__src,
346
- altText: node.__altText,
347
- width: node.__width,
348
- height: node.__height,
349
- caption: node.__caption,
350
- thumbhash: node.__thumbhash,
351
- accent: node.__accent
352
- },
353
- node.__key
354
- );
355
- }
356
- createDOM(_config) {
357
- const div = document.createElement("div");
358
- div.className = "rich-image-wrapper";
359
- return div;
360
- }
361
- updateDOM() {
362
- return false;
363
- }
364
- isInline() {
365
- return false;
366
- }
367
- static importJSON(serializedNode) {
368
- return $createImageNode({
369
- src: serializedNode.src,
370
- altText: serializedNode.altText,
371
- width: serializedNode.width,
372
- height: serializedNode.height,
373
- caption: serializedNode.caption,
374
- thumbhash: serializedNode.thumbhash,
375
- accent: serializedNode.accent
376
- });
377
- }
378
- exportJSON() {
379
- return {
380
- ...super.exportJSON(),
381
- type: "image",
382
- src: this.__src,
383
- altText: this.__altText,
384
- width: this.__width,
385
- height: this.__height,
386
- caption: this.__caption,
387
- thumbhash: this.__thumbhash,
388
- accent: this.__accent,
389
- version: 1
390
- };
391
- }
392
- setSrc(src) {
393
- const writable = this.getWritable();
394
- writable.__src = sanitizeImageSrc(src);
395
- }
396
- setAltText(altText) {
397
- const writable = this.getWritable();
398
- writable.__altText = altText;
399
- }
400
- setCaption(caption) {
401
- const writable = this.getWritable();
402
- writable.__caption = caption;
403
- }
404
- setDimensions(width, height) {
405
- const writable = this.getWritable();
406
- writable.__width = width;
407
- writable.__height = height;
408
- }
409
- setThumbhash(thumbhash) {
410
- const writable = this.getWritable();
411
- writable.__thumbhash = thumbhash;
412
- }
413
- setAccent(accent) {
414
- const writable = this.getWritable();
415
- writable.__accent = sanitizeColor(accent);
416
- }
417
- getSrc() {
418
- return this.__src;
419
- }
420
- getAltText() {
421
- return this.__altText;
422
- }
423
- getCaption() {
424
- return this.__caption;
425
- }
426
- getWidth() {
427
- return this.__width;
428
- }
429
- getHeight() {
430
- return this.__height;
431
- }
432
- getThumbhash() {
433
- return this.__thumbhash;
434
- }
435
- getAccent() {
436
- return this.__accent;
437
- }
438
- decorate(_editor, _config) {
439
- return createRendererDecoration("Image", ImageRenderer, {
440
- src: this.__src,
441
- altText: this.__altText,
442
- width: this.__width,
443
- height: this.__height,
444
- caption: this.__caption,
445
- thumbhash: this.__thumbhash,
446
- accent: this.__accent
447
- });
448
- }
449
- };
450
- __publicField(_ImageNode, "commandItems", [
451
- {
452
- title: "Image",
453
- icon: createElement(ImageIcon, { size: 20 }),
454
- description: "Upload or embed an image",
455
- keywords: ["image", "picture", "photo"],
456
- section: "MEDIA",
457
- placement: ["slash", "toolbar"],
458
- group: "insert",
459
- onSelect: (editor) => {
460
- const opened = editor.dispatchCommand(OPEN_IMAGE_UPLOAD_DIALOG_COMMAND, void 0);
461
- if (opened) return;
462
- editor.update(() => {
463
- $insertNodes([$createImageNode({ src: "", altText: "" })]);
464
- });
465
- }
466
- }
467
- ]);
468
- let ImageNode = _ImageNode;
469
- function $createImageNode(payload) {
470
- return new ImageNode(payload);
471
- }
472
- function $isImageNode(node) {
473
- return node instanceof ImageNode;
474
- }
475
- const DEFAULT_KATEX_EQUATION = "x^2 + y^2 = z^2";
476
- function resolveKaTeXEquation(equation, options) {
477
- if (options?.autoOpenOnMount && !equation.trim()) {
478
- return DEFAULT_KATEX_EQUATION;
479
- }
480
- return equation;
481
- }
482
- function isMissingActiveEditorError(error) {
483
- return error instanceof Error && error.message.includes("Unable to find an active editor");
484
- }
485
- function getRegisteredNodeKlass(nodeType, fallbackKlass) {
486
- try {
487
- const registeredNode = getRegisteredNode($getEditor(), nodeType);
488
- const registeredKlass = registeredNode?.klass;
489
- if (registeredKlass && (registeredKlass === fallbackKlass || registeredKlass.prototype instanceof fallbackKlass)) {
490
- return registeredKlass;
491
- }
492
- } catch (error) {
493
- if (!isMissingActiveEditorError(error)) {
494
- throw error;
495
- }
496
- }
497
- return fallbackKlass;
498
- }
499
- const _KaTeXBlockNode = class _KaTeXBlockNode extends DecoratorNode {
500
- constructor(equation, key, autoOpenOnMount = false) {
501
- super(key);
502
- __publicField(this, "__equation");
503
- __publicField(this, "__autoOpenOnMount");
504
- this.__equation = equation;
505
- this.__autoOpenOnMount = autoOpenOnMount;
506
- }
507
- static getType() {
508
- return "katex-block";
509
- }
510
- static clone(node) {
511
- return new _KaTeXBlockNode(
512
- node.__equation,
513
- node.__key,
514
- node.__autoOpenOnMount
515
- );
516
- }
517
- createDOM(_config) {
518
- const div = document.createElement("div");
519
- div.className = "rich-katex-block-wrapper";
520
- return div;
521
- }
522
- updateDOM() {
523
- return false;
524
- }
525
- isInline() {
526
- return false;
527
- }
528
- static importJSON(serializedNode) {
529
- return $createKaTeXBlockNode(serializedNode.equation);
530
- }
531
- exportJSON() {
532
- return {
533
- ...super.exportJSON(),
534
- type: "katex-block",
535
- equation: this.__equation,
536
- version: 1
537
- };
538
- }
539
- getEquation() {
540
- return this.__equation;
541
- }
542
- setEquation(equation) {
543
- const writable = this.getWritable();
544
- writable.__equation = equation;
545
- }
546
- getShouldAutoOpenOnMount() {
547
- return this.getLatest().__autoOpenOnMount;
548
- }
549
- setShouldAutoOpenOnMount(autoOpenOnMount) {
550
- const writable = this.getWritable();
551
- writable.__autoOpenOnMount = autoOpenOnMount;
552
- }
553
- decorate(_editor, _config) {
554
- return createRendererDecoration("KaTeX", KaTeXRenderer, {
555
- equation: this.__equation,
556
- displayMode: true
557
- });
558
- }
559
- };
560
- __publicField(_KaTeXBlockNode, "slashMenuItems", [
561
- {
562
- title: "Math Equation",
563
- icon: createElement(Sigma, { size: 20 }),
564
- description: "KaTeX block formula",
565
- keywords: ["math", "equation", "latex", "katex"],
566
- section: "ADVANCED",
567
- onSelect: (editor) => {
568
- editor.update(() => {
569
- $insertNodes([
570
- $createKaTeXBlockNode("", { autoOpenOnMount: true })
571
- ]);
572
- });
573
- }
574
- }
575
- ]);
576
- let KaTeXBlockNode = _KaTeXBlockNode;
577
- function $createKaTeXBlockNode(equation, options) {
578
- const NodeKlass = getRegisteredNodeKlass(
579
- KaTeXBlockNode.getType(),
580
- KaTeXBlockNode
581
- );
582
- const node = new NodeKlass(resolveKaTeXEquation(equation, options));
583
- if (options?.autoOpenOnMount) {
584
- node.setShouldAutoOpenOnMount(true);
585
- }
586
- return node;
587
- }
588
- function $isKaTeXBlockNode(node) {
589
- return node instanceof KaTeXBlockNode;
590
- }
591
- class KaTeXInlineNode extends DecoratorNode {
592
- constructor(equation, key, autoOpenOnMount = false, color = null) {
593
- super(key);
594
- __publicField(this, "__equation");
595
- __publicField(this, "__autoOpenOnMount");
596
- __publicField(this, "__color");
597
- this.__equation = equation;
598
- this.__autoOpenOnMount = autoOpenOnMount;
599
- this.__color = color;
600
- }
601
- static getType() {
602
- return "katex-inline";
603
- }
604
- static clone(node) {
605
- return new KaTeXInlineNode(node.__equation, node.__key, node.__autoOpenOnMount, node.__color);
606
- }
607
- createDOM(_config) {
608
- return document.createElement("span");
609
- }
610
- updateDOM() {
611
- return false;
612
- }
613
- isInline() {
614
- return true;
615
- }
616
- static importJSON(serializedNode) {
617
- const node = $createKaTeXInlineNode(serializedNode.equation);
618
- if (serializedNode.color) node.setColor(serializedNode.color);
619
- return node;
620
- }
621
- exportJSON() {
622
- return {
623
- ...super.exportJSON(),
624
- type: "katex-inline",
625
- equation: this.__equation,
626
- color: this.__color,
627
- version: 1
628
- };
629
- }
630
- getEquation() {
631
- return this.__equation;
632
- }
633
- setEquation(equation) {
634
- const writable = this.getWritable();
635
- writable.__equation = equation;
636
- }
637
- getShouldAutoOpenOnMount() {
638
- return this.getLatest().__autoOpenOnMount;
639
- }
640
- setShouldAutoOpenOnMount(autoOpenOnMount) {
641
- const writable = this.getWritable();
642
- writable.__autoOpenOnMount = autoOpenOnMount;
643
- }
644
- getColor() {
645
- return this.getLatest().__color;
646
- }
647
- setColor(color) {
648
- const writable = this.getWritable();
649
- writable.__color = color;
650
- }
651
- decorate(_editor, _config) {
652
- const decoration = createRendererDecoration("KaTeX", KaTeXRenderer, {
653
- equation: this.__equation,
654
- displayMode: false
655
- });
656
- if (!this.__color) return decoration;
657
- return createElement("span", { style: { color: this.__color } }, decoration);
658
- }
659
- }
660
- function $createKaTeXInlineNode(equation, options) {
661
- const NodeKlass = getRegisteredNodeKlass(KaTeXInlineNode.getType(), KaTeXInlineNode);
662
- const node = new NodeKlass(resolveKaTeXEquation(equation, options));
663
- if (options?.autoOpenOnMount) {
664
- node.setShouldAutoOpenOnMount(true);
665
- }
666
- return node;
667
- }
668
- function $isKaTeXInlineNode(node) {
669
- return node instanceof KaTeXInlineNode;
670
- }
671
- function MentionRenderer({ handle, displayName }) {
672
- const normalizedHandle = handle.replace(/^@+/, "");
673
- const label = displayName || normalizedHandle;
674
- return /* @__PURE__ */ jsx("span", { className: "rich-mention rich-mention-plain", children: /* @__PURE__ */ jsxs("span", { className: "rich-mention-handle", children: [
675
- "@",
676
- label
677
- ] }) });
678
- }
679
- const _MentionNode = class _MentionNode extends DecoratorNode {
680
- constructor(platform, handle, displayName, key) {
681
- super(key);
682
- __publicField(this, "__platform");
683
- __publicField(this, "__handle");
684
- __publicField(this, "__displayName");
685
- this.__platform = platform;
686
- this.__handle = handle;
687
- this.__displayName = displayName;
688
- }
689
- static getType() {
690
- return "mention";
691
- }
692
- static clone(node) {
693
- return new _MentionNode(
694
- node.__platform,
695
- node.__handle,
696
- node.__displayName,
697
- node.__key
698
- );
699
- }
700
- createDOM(_config) {
701
- const el = document.createElement("span");
702
- el.style.display = "inline-flex";
703
- el.style.alignItems = "center";
704
- el.style.height = "1lh";
705
- return el;
706
- }
707
- updateDOM() {
708
- return false;
709
- }
710
- isInline() {
711
- return true;
712
- }
713
- getPlatform() {
714
- return this.getLatest().__platform;
715
- }
716
- getHandle() {
717
- return this.getLatest().__handle;
718
- }
719
- getDisplayName() {
720
- return this.getLatest().__displayName;
721
- }
722
- static importJSON(serializedNode) {
723
- return $createMentionNode(
724
- serializedNode.platform,
725
- serializedNode.handle,
726
- serializedNode.displayName
727
- );
728
- }
729
- exportJSON() {
730
- return {
731
- ...super.exportJSON(),
732
- type: "mention",
733
- platform: this.__platform,
734
- handle: this.__handle,
735
- ...this.__displayName ? { displayName: this.__displayName } : {},
736
- version: 1
737
- };
738
- }
739
- decorate(_editor, _config) {
740
- return createRendererDecoration("Mention", MentionRenderer, {
741
- platform: this.__platform,
742
- handle: this.__handle,
743
- displayName: this.__displayName
744
- });
745
- }
746
- };
747
- __publicField(_MentionNode, "slashMenuItems", [
748
- {
749
- title: "Mention",
750
- icon: createElement(
751
- "span",
752
- { style: { fontSize: 16, fontWeight: 700 } },
753
- "@"
754
- ),
755
- description: "Mention a social account",
756
- keywords: ["mention", "at", "@", "github", "twitter"],
757
- section: "INLINE",
758
- onSelect: (editor) => {
759
- editor.update(() => {
760
- const selection = $getSelection();
761
- if ($isRangeSelection(selection)) {
762
- selection.insertText("@");
763
- }
764
- });
765
- }
766
- }
767
- ]);
768
- let MentionNode = _MentionNode;
769
- function $createMentionNode(platform, handle, displayName) {
770
- return new MentionNode(platform, handle, displayName);
771
- }
772
- function $isMentionNode(node) {
773
- return node instanceof MentionNode;
774
- }
775
- function MermaidRenderer({ content }) {
776
- return /* @__PURE__ */ jsx("div", { className: "rich-mermaid-block", children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: content }) }) });
777
- }
778
- const _MermaidNode = class _MermaidNode extends DecoratorNode {
779
- constructor(diagram, key) {
780
- super(key);
781
- __publicField(this, "__diagram");
782
- this.__diagram = diagram;
783
- }
784
- static getType() {
785
- return "mermaid";
786
- }
787
- static clone(node) {
788
- return new _MermaidNode(node.__diagram, node.__key);
789
- }
790
- createDOM(_config) {
791
- const div = document.createElement("div");
792
- div.className = "rich-mermaid-wrapper";
793
- return div;
794
- }
795
- updateDOM() {
796
- return false;
797
- }
798
- isInline() {
799
- return false;
800
- }
801
- static importJSON(serializedNode) {
802
- return $createMermaidNode(serializedNode.diagram);
803
- }
804
- exportJSON() {
805
- return {
806
- ...super.exportJSON(),
807
- type: "mermaid",
808
- diagram: this.__diagram,
809
- version: 1
810
- };
811
- }
812
- getDiagram() {
813
- return this.__diagram;
814
- }
815
- setDiagram(diagram) {
816
- const writable = this.getWritable();
817
- writable.__diagram = diagram;
818
- }
819
- decorate(editor, _config) {
820
- const nodeKey = this.__key;
821
- return createRendererDecoration("Mermaid", MermaidRenderer, {
822
- content: this.__diagram,
823
- onContentChange: (newDiagram) => {
824
- editor.update(() => {
825
- const node = $getNodeByKey(nodeKey);
826
- if (node) {
827
- node.setDiagram(newDiagram);
828
- }
829
- });
830
- }
831
- });
832
- }
833
- };
834
- __publicField(_MermaidNode, "commandItems", [
835
- {
836
- title: "Mermaid Diagram",
837
- icon: createElement(Workflow, { size: 20 }),
838
- description: "Flowchart, sequence diagram",
839
- keywords: ["mermaid", "diagram", "chart", "flowchart"],
840
- section: "MEDIA",
841
- placement: ["slash", "toolbar"],
842
- group: "insert",
843
- onSelect: (editor) => {
844
- editor.update(() => {
845
- $insertNodes([
846
- $createMermaidNode("graph TD\n A[Start] --> B[End]")
847
- ]);
848
- });
849
- }
850
- }
851
- ]);
852
- let MermaidNode = _MermaidNode;
853
- function $createMermaidNode(diagram) {
854
- return new MermaidNode(diagram);
855
- }
856
- function $isMermaidNode(node) {
857
- return node instanceof MermaidNode;
858
- }
859
- class SpoilerNode extends ElementNode {
860
- static getType() {
861
- return "spoiler";
862
- }
863
- static clone(node) {
864
- return new SpoilerNode(node.__key);
865
- }
866
- constructor(key) {
867
- super(key);
868
- }
869
- createDOM(_config) {
870
- const span = document.createElement("span");
871
- span.className = `${semanticClassNames.spoiler} ${sharedStyles.spoiler}`;
872
- span.setAttribute("role", "button");
873
- span.setAttribute("tabindex", "0");
874
- span.setAttribute("aria-label", "Spoiler (click to reveal)");
875
- const toggle = () => {
876
- if (span.isContentEditable) return;
877
- span.classList.toggle(semanticClassNames.spoilerRevealed);
878
- const revealed = span.classList.toggle(sharedStyles.spoilerRevealed);
879
- span.setAttribute(
880
- "aria-label",
881
- revealed ? "Spoiler (revealed)" : "Spoiler (click to reveal)"
882
- );
883
- };
884
- span.addEventListener("click", toggle);
885
- span.addEventListener("keydown", (e) => {
886
- if (e.key === "Enter" || e.key === " ") {
887
- e.preventDefault();
888
- toggle();
889
- }
890
- });
891
- return span;
892
- }
893
- updateDOM() {
894
- return false;
895
- }
896
- static importJSON(_serializedNode) {
897
- return $createSpoilerNode();
898
- }
899
- exportJSON() {
900
- return {
901
- ...super.exportJSON(),
902
- type: "spoiler",
903
- version: 1
904
- };
905
- }
906
- canInsertTextBefore() {
907
- return true;
908
- }
909
- canInsertTextAfter() {
910
- return true;
911
- }
912
- isInline() {
913
- return true;
914
- }
915
- }
916
- function $createSpoilerNode() {
917
- return new SpoilerNode();
918
- }
919
- function $isSpoilerNode(node) {
920
- return node instanceof SpoilerNode;
921
- }
922
- function stringToHue(str) {
923
- let hash = 0;
924
- for (let i = 0; i < str.length; i++) {
925
- hash = str.charCodeAt(i) + ((hash << 5) - hash);
926
- }
927
- const hue = hash % 360;
928
- return hue < 0 ? hue + 360 : hue;
929
- }
930
- function getTagBgColor(text) {
931
- const hue = stringToHue(text);
932
- const sat = 70 + hue % 21;
933
- const light = 40 + hue % 31;
934
- const bgSat = sat > 30 ? sat - 30 : 0;
935
- const bgLight = light < 80 ? light + 20 : 100;
936
- return `hsla(${hue}, ${bgSat}%, ${bgLight}%, 0.7)`;
937
- }
938
- const tagClassName = `${semanticClassNames.tag} ${sharedStyles.tag}`;
939
- const _TagNode = class _TagNode extends TextNode {
940
- static getType() {
941
- return "tag";
942
- }
943
- static clone(node) {
944
- return new _TagNode(node.__text, node.__key);
945
- }
946
- static importDOM() {
947
- return {
948
- span: () => ({
949
- conversion: (domNode) => {
950
- if (!(domNode instanceof HTMLElement)) return null;
951
- if (!domNode.classList.contains(semanticClassNames.tag)) return null;
952
- return {
953
- node: $createTagNode(domNode.textContent ?? "")
954
- };
955
- },
956
- priority: 2
957
- })
958
- };
959
- }
960
- constructor(text, key) {
961
- super(text, key);
962
- }
963
- createDOM(config) {
964
- const element = super.createDOM(config);
965
- element.classList.add(semanticClassNames.tag, sharedStyles.tag);
966
- element.style.backgroundColor = getTagBgColor(this.getTextContent());
967
- return element;
968
- }
969
- updateDOM(prevNode, dom, config) {
970
- const updated = super.updateDOM(prevNode, dom, config);
971
- dom.classList.add(semanticClassNames.tag, sharedStyles.tag);
972
- if (prevNode.__text !== this.__text) {
973
- dom.style.backgroundColor = getTagBgColor(this.__text);
974
- }
975
- return updated;
976
- }
977
- exportDOM(_editor) {
978
- const element = document.createElement("span");
979
- element.className = tagClassName;
980
- element.style.backgroundColor = getTagBgColor(this.getTextContent());
981
- element.textContent = this.getTextContent();
982
- return { element };
983
- }
984
- getText() {
985
- return this.getTextContent();
986
- }
987
- canInsertTextBefore() {
988
- return false;
989
- }
990
- canInsertTextAfter() {
991
- return false;
992
- }
993
- isTextEntity() {
994
- return true;
995
- }
996
- static importJSON(serializedNode) {
997
- const node = $createTagNode(serializedNode.text ?? "");
998
- node.setFormat(serializedNode.format ?? 0);
999
- node.setDetail(serializedNode.detail ?? 0);
1000
- node.setMode(serializedNode.mode ?? "normal");
1001
- node.setStyle(serializedNode.style ?? "");
1002
- return node;
1003
- }
1004
- exportJSON() {
1005
- return {
1006
- ...super.exportJSON(),
1007
- type: "tag",
1008
- version: 1
1009
- };
1010
- }
1011
- };
1012
- __publicField(_TagNode, "commandItems", [
1013
- {
1014
- title: "Tag",
1015
- icon: createElement(Tag, { size: 20 }),
1016
- description: "Insert a tag",
1017
- keywords: ["tag", "label", "badge"],
1018
- section: "INLINE",
1019
- placement: ["slash", "toolbar"],
1020
- group: "insert",
1021
- onSelect: (editor, queryString) => {
1022
- editor.update(() => {
1023
- $insertNodes([$createTagNode(queryString || "tag")]);
1024
- });
1025
- }
1026
- }
1027
- ]);
1028
- let TagNode = _TagNode;
1029
- function $createTagNode(text) {
1030
- return new TagNode(text);
1031
- }
1032
- function $isTagNode(node) {
1033
- return node instanceof TagNode;
1034
- }
1035
- const shared = (key) => `${semanticClassNames[key]} ${sharedStyles[key]}`;
1036
- const editorTheme = {
1037
- text: {
1038
- bold: shared("textBold"),
1039
- italic: shared("textItalic"),
1040
- underline: shared("textUnderline"),
1041
- strikethrough: shared("textStrikethrough"),
1042
- superscript: shared("textSuperscript"),
1043
- subscript: shared("textSubscript"),
1044
- code: shared("textCode"),
1045
- highlight: shared("textHighlight")
1046
- },
1047
- heading: {
1048
- h1: shared("headingH1"),
1049
- h2: shared("headingH2"),
1050
- h3: shared("headingH3"),
1051
- h4: shared("headingH4"),
1052
- h5: shared("headingH5"),
1053
- h6: shared("headingH6")
1054
- },
1055
- list: {
1056
- ol: shared("listOl"),
1057
- ul: shared("listUl"),
1058
- listitem: shared("listItem"),
1059
- listitemChecked: shared("listItemChecked"),
1060
- listitemUnchecked: shared("listItemUnchecked"),
1061
- checklist: shared("checklist"),
1062
- nested: {
1063
- listitem: shared("listNestedItem")
1064
- }
1065
- },
1066
- quote: shared("quote"),
1067
- link: shared("link"),
1068
- paragraph: shared("paragraph"),
1069
- code: "rich-code-block",
1070
- table: shared("table"),
1071
- tableCell: shared("tableCell"),
1072
- tableCellHeader: shared("tableCellHeader"),
1073
- tableScrollableWrapper: shared("tableScrollableWrapper"),
1074
- /** Used by @lexical/extension HorizontalRuleNode */
1075
- hr: shared("hr")
1076
- };
1077
- export {
1078
- $createImageNode as $,
1079
- ALERT_LABELS as A,
1080
- FootnoteNode as F,
1081
- ImageNode as I,
1082
- KaTeXBlockNode as K,
1083
- MentionNode as M,
1084
- NestedContentRendererProvider as N,
1085
- OPEN_IMAGE_UPLOAD_DIALOG_COMMAND as O,
1086
- SpoilerNode as S,
1087
- TagNode as T,
1088
- $createMentionNode as a,
1089
- $createMermaidNode as b,
1090
- $createTagNode as c,
1091
- $isImageNode as d,
1092
- $isKaTeXBlockNode as e,
1093
- $isKaTeXInlineNode as f,
1094
- $isMentionNode as g,
1095
- $isMermaidNode as h,
1096
- $isTagNode as i,
1097
- ALERT_TYPES as j,
1098
- KaTeXInlineNode as k,
1099
- MermaidNode as l,
1100
- getTagBgColor as m,
1101
- editorTheme as n,
1102
- extractTextContent as o,
1103
- useOptionalNestedContentRenderer as p,
1104
- $createSpoilerNode as q,
1105
- $isSpoilerNode as r,
1106
- $isAlertQuoteNode as s,
1107
- AlertRenderer as t,
1108
- useNestedContentRenderer as u,
1109
- AlertQuoteNode as v,
1110
- $createKaTeXInlineNode as w,
1111
- $createKaTeXBlockNode as x,
1112
- $createFootnoteNode as y
1113
- };