@haklex/rich-editor 0.0.82 → 0.0.84

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 (81) hide show
  1. package/dist/AlertQuoteEditNode-CB8C24Xf.js +293 -0
  2. package/dist/KaTeXRenderer-CQyQzNTJ.js +218 -0
  3. package/dist/LinkCardRenderer-QmkOlyXb.js +36 -0
  4. package/dist/MermaidPlugin-DfIhGe-1.js +97 -0
  5. package/dist/PresentDialogContext-B4E78UB5.js +58 -0
  6. package/dist/RubyRenderer-CJQmODir.js +14 -0
  7. package/dist/SubmitShortcutPlugin-CkuM_8Wk.js +1650 -0
  8. package/dist/commands-entry.mjs +23 -14
  9. package/dist/components/LinkFavicon.d.ts.map +1 -1
  10. package/dist/components/decorators/GridEditDecorator.d.ts.map +1 -1
  11. package/dist/components/renderers/FootnoteRenderer.d.ts.map +1 -1
  12. package/dist/components/renderers/FootnoteSectionEditRenderer.d.ts.map +1 -1
  13. package/dist/components/renderers/FootnoteSectionRenderer.d.ts.map +1 -1
  14. package/dist/components/renderers/FootnoteStaticRenderer.d.ts.map +1 -1
  15. package/dist/components/renderers/GridStaticDecorator.d.ts.map +1 -1
  16. package/dist/components/renderers/KaTeXRenderer.d.ts.map +1 -1
  17. package/dist/components/renderers/RubyRenderer.d.ts.map +1 -1
  18. package/dist/components/renderers/TagRenderer.d.ts.map +1 -1
  19. package/dist/config-BulxE6hd.js +1362 -0
  20. package/dist/config-edit.d.ts.map +1 -1
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/favicon-BQgbXF_a.js +43 -0
  23. package/dist/grid.css-Md5-Cfx_.js +11 -0
  24. package/dist/index.mjs +292 -259
  25. package/dist/katex.css-Csc-7N7u.js +28 -0
  26. package/dist/node-registry-eMijRh3N.js +824 -0
  27. package/dist/nodes/AlertQuoteNode.d.ts.map +1 -1
  28. package/dist/nodes/CommentNode.d.ts +21 -0
  29. package/dist/nodes/CommentNode.d.ts.map +1 -0
  30. package/dist/nodes/DetailsNode.d.ts.map +1 -1
  31. package/dist/nodes/FootnoteNode.d.ts.map +1 -1
  32. package/dist/nodes/FootnoteSectionNode.d.ts.map +1 -1
  33. package/dist/nodes/GridContainerNode.d.ts.map +1 -1
  34. package/dist/nodes/RubyNode.d.ts.map +1 -1
  35. package/dist/nodes/SpoilerNode.d.ts.map +1 -1
  36. package/dist/nodes/TagNode.d.ts.map +1 -1
  37. package/dist/nodes-entry.d.ts +2 -0
  38. package/dist/nodes-entry.d.ts.map +1 -1
  39. package/dist/nodes-entry.mjs +50 -7
  40. package/dist/plugins/MarkdownPastePlugin.d.ts.map +1 -1
  41. package/dist/plugins-entry.mjs +27 -10
  42. package/dist/renderers-entry.mjs +61 -40
  43. package/dist/rich-editor.css +1 -2
  44. package/dist/static-entry.d.ts +4 -1
  45. package/dist/static-entry.d.ts.map +1 -1
  46. package/dist/static-entry.mjs +62 -16
  47. package/dist/styles/article.css.d.ts.map +1 -1
  48. package/dist/styles/comment.css.d.ts.map +1 -1
  49. package/dist/styles/details.css.d.ts +19 -1
  50. package/dist/styles/details.css.d.ts.map +1 -1
  51. package/dist/styles/grid.css.d.ts +34 -1
  52. package/dist/styles/grid.css.d.ts.map +1 -1
  53. package/dist/styles/index.d.ts +5 -2
  54. package/dist/styles/index.d.ts.map +1 -1
  55. package/dist/styles/katex.css.d.ts +13 -1
  56. package/dist/styles/katex.css.d.ts.map +1 -1
  57. package/dist/styles/note.css.d.ts.map +1 -1
  58. package/dist/styles/shared.css.d.ts +164 -0
  59. package/dist/styles/shared.css.d.ts.map +1 -1
  60. package/dist/styles/theme.d.ts.map +1 -1
  61. package/dist/styles-entry.d.ts +5 -2
  62. package/dist/styles-entry.d.ts.map +1 -1
  63. package/dist/styles-entry.mjs +21 -3
  64. package/dist/theme-D_efLk4K.js +1034 -0
  65. package/dist/transformers/comment.d.ts +4 -0
  66. package/dist/transformers/comment.d.ts.map +1 -0
  67. package/dist/transformers/index.d.ts +1 -0
  68. package/dist/transformers/index.d.ts.map +1 -1
  69. package/package.json +4 -4
  70. package/dist/AlertQuoteEditNode-BDoonB4u.js +0 -267
  71. package/dist/KaTeXRenderer-BsyRH5_t.js +0 -214
  72. package/dist/LinkCardRenderer-OEMBDUhD.js +0 -45
  73. package/dist/MermaidPlugin-Df2Cm2yX.js +0 -67
  74. package/dist/PresentDialogContext-DQw6MrNh.js +0 -59
  75. package/dist/RubyRenderer-BpDb_amz.js +0 -14
  76. package/dist/SubmitShortcutPlugin-6IvsbZD-.js +0 -1463
  77. package/dist/config-tfg1FWhG.js +0 -1149
  78. package/dist/favicon-DIWusrrw.js +0 -41
  79. package/dist/node-registry-CeVi2y9f.js +0 -666
  80. package/dist/shared.css-wgGgtK_e.js +0 -23
  81. package/dist/theme-DHOUKKSr.js +0 -1034
@@ -0,0 +1,293 @@
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 { $getNodeByKey, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_ARROW_DOWN_COMMAND, COMMAND_PRIORITY_HIGH, $getRoot, $createParagraphNode, $isParagraphNode, $getSelection, $isRangeSelection, $insertNodes, createEditor } from "lexical";
5
+ import { Info, Lightbulb, TriangleAlert } from "lucide-react";
6
+ import { useCallback, useEffect, createElement } from "react";
7
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
8
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
9
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
10
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
11
+ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
12
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
13
+ import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
14
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
15
+ import { q as $isAlertQuoteNode, r as AlertRenderer, S as SpoilerNode, M as MentionNode, F as FootnoteNode, k as KaTeXInlineNode, T as TagNode, s as AlertQuoteNode, n as editorTheme } from "./theme-D_efLk4K.js";
16
+ import { a as RendererWrapper } from "./KaTeXRenderer-CQyQzNTJ.js";
17
+ import { CodeNode } from "@lexical/code";
18
+ import { HorizontalRuleNode } from "@lexical/extension";
19
+ import { LinkNode, AutoLinkNode } from "@lexical/link";
20
+ import { ListNode, ListItemNode } from "@lexical/list";
21
+ import { HeadingNode, QuoteNode } from "@lexical/rich-text";
22
+ import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
23
+ function ExitBlockPlugin({
24
+ parentEditor,
25
+ nodeKey
26
+ }) {
27
+ const [editor] = useLexicalComposerContext();
28
+ useEffect(() => {
29
+ const focusParent = () => {
30
+ parentEditor.focus(() => {
31
+ parentEditor.update(() => {
32
+ const alertNode = $getNodeByKey(nodeKey);
33
+ if (alertNode) {
34
+ const next = alertNode.getNextSibling();
35
+ if (next) {
36
+ next.selectStart();
37
+ }
38
+ }
39
+ });
40
+ });
41
+ };
42
+ const exitAlert = (removeEmpty) => {
43
+ const root = $getRoot();
44
+ const lastChild = root.getLastChild();
45
+ const shouldRemoveAlert = removeEmpty && root.getChildrenSize() <= 1;
46
+ if (removeEmpty && lastChild) {
47
+ lastChild.remove();
48
+ }
49
+ if (shouldRemoveAlert) {
50
+ parentEditor.update(
51
+ () => {
52
+ const alertNode = $getNodeByKey(nodeKey);
53
+ if (alertNode) {
54
+ const paragraph = $createParagraphNode();
55
+ alertNode.insertAfter(paragraph);
56
+ alertNode.remove();
57
+ paragraph.selectStart();
58
+ }
59
+ },
60
+ { onUpdate: focusParent }
61
+ );
62
+ } else {
63
+ parentEditor.update(
64
+ () => {
65
+ const alertNode = $getNodeByKey(nodeKey);
66
+ if (alertNode) {
67
+ let next = alertNode.getNextSibling();
68
+ if (!next || !$isParagraphNode(next)) {
69
+ next = $createParagraphNode();
70
+ alertNode.insertAfter(next);
71
+ }
72
+ next.selectStart();
73
+ }
74
+ },
75
+ { onUpdate: focusParent }
76
+ );
77
+ }
78
+ };
79
+ const isAtLastEmptyParagraph = () => {
80
+ const selection = $getSelection();
81
+ if (!$isRangeSelection(selection) || !selection.isCollapsed()) return false;
82
+ const anchorNode = selection.anchor.getNode();
83
+ const topLevelElement = anchorNode.getTopLevelElement();
84
+ return topLevelElement && $isParagraphNode(topLevelElement) && topLevelElement.getTextContent() === "" && topLevelElement.getNextSibling() === null;
85
+ };
86
+ const unregisterEnter = editor.registerCommand(
87
+ KEY_ENTER_COMMAND,
88
+ (event) => {
89
+ if (event?.metaKey || event?.ctrlKey) {
90
+ event.preventDefault();
91
+ exitAlert(false);
92
+ return true;
93
+ }
94
+ if (!isAtLastEmptyParagraph()) return false;
95
+ event?.preventDefault();
96
+ exitAlert(true);
97
+ return true;
98
+ },
99
+ COMMAND_PRIORITY_CRITICAL
100
+ );
101
+ const unregisterArrowDown = editor.registerCommand(
102
+ KEY_ARROW_DOWN_COMMAND,
103
+ (event) => {
104
+ if (!isAtLastEmptyParagraph()) return false;
105
+ event?.preventDefault();
106
+ exitAlert(false);
107
+ return true;
108
+ },
109
+ COMMAND_PRIORITY_HIGH
110
+ );
111
+ return () => {
112
+ unregisterEnter();
113
+ unregisterArrowDown();
114
+ };
115
+ }, [editor, parentEditor, nodeKey]);
116
+ return null;
117
+ }
118
+ function AlertEditDecorator({ nodeKey, alertType, contentEditor }) {
119
+ const [editor] = useLexicalComposerContext();
120
+ const editable = editor.isEditable();
121
+ const handleTypeChange = useCallback(
122
+ (newType) => {
123
+ editor.update(() => {
124
+ const node = $getNodeByKey(nodeKey);
125
+ if ($isAlertQuoteNode(node)) {
126
+ node.setAlertType(newType);
127
+ }
128
+ });
129
+ },
130
+ [editor, nodeKey]
131
+ );
132
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
133
+ /* @__PURE__ */ jsx(
134
+ RendererWrapper,
135
+ {
136
+ defaultRenderer: AlertRenderer,
137
+ rendererKey: "Alert",
138
+ props: {
139
+ type: alertType,
140
+ editable,
141
+ onTypeChange: editable ? handleTypeChange : void 0
142
+ }
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsx("div", { className: "rich-alert-content", children: /* @__PURE__ */ jsxs(LexicalNestedComposer, { initialEditor: contentEditor, children: [
146
+ /* @__PURE__ */ jsx(
147
+ RichTextPlugin,
148
+ {
149
+ ErrorBoundary: LexicalErrorBoundary,
150
+ contentEditable: /* @__PURE__ */ jsx(
151
+ ContentEditable,
152
+ {
153
+ "aria-placeholder": "",
154
+ className: "rich-alert-content-editable",
155
+ placeholder: /* @__PURE__ */ jsx("span", { style: { display: "none" } }),
156
+ style: { outline: "none" }
157
+ }
158
+ )
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsx(ListPlugin, {}),
162
+ /* @__PURE__ */ jsx(LinkPlugin, {}),
163
+ /* @__PURE__ */ jsx(ExitBlockPlugin, { nodeKey, parentEditor: editor })
164
+ ] }) })
165
+ ] });
166
+ }
167
+ const NESTED_EDITOR_NODES = [
168
+ HeadingNode,
169
+ QuoteNode,
170
+ ListNode,
171
+ ListItemNode,
172
+ LinkNode,
173
+ AutoLinkNode,
174
+ HorizontalRuleNode,
175
+ CodeNode,
176
+ TableNode,
177
+ TableCellNode,
178
+ TableRowNode,
179
+ SpoilerNode,
180
+ MentionNode,
181
+ FootnoteNode,
182
+ KaTeXInlineNode,
183
+ TagNode
184
+ ];
185
+ function createContentEditor() {
186
+ return createEditor({
187
+ namespace: "AlertContent",
188
+ nodes: NESTED_EDITOR_NODES,
189
+ theme: editorTheme,
190
+ onError: (error) => {
191
+ console.error("[AlertContent]", error);
192
+ }
193
+ });
194
+ }
195
+ const _AlertQuoteEditNode = class _AlertQuoteEditNode extends AlertQuoteNode {
196
+ constructor(alertType, contentState, key) {
197
+ super(alertType, contentState, key);
198
+ __publicField(this, "__contentEditor");
199
+ this.__contentEditor = createContentEditor();
200
+ if (contentState) {
201
+ const editorState = this.__contentEditor.parseEditorState(contentState);
202
+ this.__contentEditor.setEditorState(editorState);
203
+ }
204
+ }
205
+ static clone(node) {
206
+ const cloned = new _AlertQuoteEditNode(
207
+ node.__alertType,
208
+ node.__contentState,
209
+ node.__key
210
+ );
211
+ cloned.__contentEditor = node.__contentEditor;
212
+ return cloned;
213
+ }
214
+ getContentEditor() {
215
+ return this.__contentEditor;
216
+ }
217
+ static importJSON(serializedNode) {
218
+ const node = new _AlertQuoteEditNode(
219
+ serializedNode.alertType,
220
+ serializedNode.content
221
+ );
222
+ return node;
223
+ }
224
+ exportJSON() {
225
+ return {
226
+ ...super.exportJSON(),
227
+ type: "alert-quote",
228
+ alertType: this.__alertType,
229
+ content: this.__contentEditor.getEditorState().toJSON(),
230
+ version: 1
231
+ };
232
+ }
233
+ decorate(_editor, _config) {
234
+ return createElement(AlertEditDecorator, {
235
+ nodeKey: this.__key,
236
+ alertType: this.__alertType,
237
+ contentEditor: this.__contentEditor
238
+ });
239
+ }
240
+ };
241
+ __publicField(_AlertQuoteEditNode, "commandItems", [
242
+ {
243
+ title: "Callout",
244
+ icon: createElement(Info, { size: 20 }),
245
+ description: "Info callout block",
246
+ keywords: ["alert", "note", "info", "callout"],
247
+ section: "ADVANCED",
248
+ placement: ["slash", "toolbar"],
249
+ group: "insert",
250
+ onSelect: (editor) => {
251
+ editor.update(() => {
252
+ $insertNodes([$createAlertQuoteEditNode("note")]);
253
+ });
254
+ }
255
+ },
256
+ {
257
+ title: "Tip",
258
+ icon: createElement(Lightbulb, { size: 20 }),
259
+ description: "Highlight a useful tip",
260
+ keywords: ["alert", "tip", "hint"],
261
+ section: "ADVANCED",
262
+ placement: ["slash", "toolbar"],
263
+ group: "insert",
264
+ onSelect: (editor) => {
265
+ editor.update(() => {
266
+ $insertNodes([$createAlertQuoteEditNode("tip")]);
267
+ });
268
+ }
269
+ },
270
+ {
271
+ title: "Warning",
272
+ icon: createElement(TriangleAlert, { size: 20 }),
273
+ description: "Warn about something",
274
+ keywords: ["alert", "warning", "caution"],
275
+ section: "ADVANCED",
276
+ placement: ["slash", "toolbar"],
277
+ group: "insert",
278
+ onSelect: (editor) => {
279
+ editor.update(() => {
280
+ $insertNodes([$createAlertQuoteEditNode("warning")]);
281
+ });
282
+ }
283
+ }
284
+ ]);
285
+ let AlertQuoteEditNode = _AlertQuoteEditNode;
286
+ function $createAlertQuoteEditNode(alertType, contentState) {
287
+ return new AlertQuoteEditNode(alertType, contentState);
288
+ }
289
+ export {
290
+ $createAlertQuoteEditNode as $,
291
+ AlertQuoteEditNode as A,
292
+ NESTED_EDITOR_NODES as N
293
+ };
@@ -0,0 +1,218 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, use, useMemo, createElement, useCallback, useState, useEffect } from "react";
3
+ import { s as semanticClassNames, d as sharedStyles, e as clsx, b as katexStyles, k as katexClassNames } from "./katex.css-Csc-7N7u.js";
4
+ import { thumbHashToDataURL, rgbaToThumbHash } from "thumbhash";
5
+ const RendererConfigContext = createContext({
6
+ config: void 0,
7
+ mode: "renderer",
8
+ variant: "article"
9
+ });
10
+ function RendererConfigProvider({
11
+ config,
12
+ mode,
13
+ variant,
14
+ children
15
+ }) {
16
+ const value = useMemo(() => ({ config, mode, variant }), [config, mode, variant]);
17
+ return /* @__PURE__ */ jsx(RendererConfigContext.Provider, { value, children });
18
+ }
19
+ function useRendererConfig() {
20
+ return use(RendererConfigContext).config;
21
+ }
22
+ function useRendererMode() {
23
+ return use(RendererConfigContext).mode;
24
+ }
25
+ function useVariant() {
26
+ return use(RendererConfigContext).variant;
27
+ }
28
+ function RendererWrapper({
29
+ rendererKey,
30
+ defaultRenderer: DefaultRenderer,
31
+ props
32
+ }) {
33
+ const config = useRendererConfig();
34
+ const Renderer = config?.[rendererKey] ?? DefaultRenderer;
35
+ return /* @__PURE__ */ jsx(Renderer, { ...props });
36
+ }
37
+ function createRendererDecoration(rendererKey, defaultRenderer, props) {
38
+ return createElement(RendererWrapper, {
39
+ rendererKey,
40
+ defaultRenderer,
41
+ props
42
+ });
43
+ }
44
+ const FootnoteDefinitionsContext = createContext({
45
+ definitions: {},
46
+ displayNumberMap: {}
47
+ });
48
+ function FootnoteDefinitionsProvider({
49
+ definitions,
50
+ displayNumberMap,
51
+ children
52
+ }) {
53
+ const value = useMemo(
54
+ () => ({ definitions, displayNumberMap }),
55
+ [definitions, displayNumberMap]
56
+ );
57
+ return /* @__PURE__ */ jsx(FootnoteDefinitionsContext, { value, children });
58
+ }
59
+ function useFootnoteDefinitions() {
60
+ return use(FootnoteDefinitionsContext);
61
+ }
62
+ function useFootnoteContent(identifier) {
63
+ const { definitions } = use(FootnoteDefinitionsContext);
64
+ return definitions[identifier];
65
+ }
66
+ function useFootnoteDisplayNumber(identifier) {
67
+ const { displayNumberMap } = use(FootnoteDefinitionsContext);
68
+ return displayNumberMap[identifier];
69
+ }
70
+ function FootnoteStaticRenderer({ identifier }) {
71
+ const content = useFootnoteContent(identifier);
72
+ const displayNumber = useFootnoteDisplayNumber(identifier);
73
+ const referenceId = `footnote-ref-${identifier}`;
74
+ const targetId = `footnote-${identifier}`;
75
+ const handleClick = useCallback(
76
+ (e) => {
77
+ const target = document.getElementById(targetId) || document.getElementById(`fn-${identifier}`);
78
+ if (!target) return;
79
+ e.preventDefault();
80
+ target.scrollIntoView({ behavior: "smooth", block: "center" });
81
+ target.classList.add(semanticClassNames.footnoteHighlight, sharedStyles.footnoteHighlight);
82
+ window.setTimeout(() => {
83
+ target.classList.remove(
84
+ semanticClassNames.footnoteHighlight,
85
+ sharedStyles.footnoteHighlight
86
+ );
87
+ }, 1200);
88
+ },
89
+ [identifier, targetId]
90
+ );
91
+ const label = displayNumber ?? identifier;
92
+ return /* @__PURE__ */ jsx("span", { className: clsx(semanticClassNames.footnoteRefWrapper, sharedStyles.footnoteRefWrapper), children: /* @__PURE__ */ jsx(
93
+ "a",
94
+ {
95
+ "aria-label": content ? `Footnote ${label}: ${content}` : `Footnote ${label}`,
96
+ className: clsx(semanticClassNames.footnoteRef, sharedStyles.footnoteRef),
97
+ "data-footnote-ref": identifier,
98
+ href: `#${targetId}`,
99
+ id: referenceId,
100
+ role: "doc-noteref",
101
+ onClick: handleClick,
102
+ children: label
103
+ }
104
+ ) });
105
+ }
106
+ const MAX_DIM = 100;
107
+ async function computeImageMeta(file) {
108
+ const url = URL.createObjectURL(file);
109
+ try {
110
+ const img = await loadImage(url);
111
+ const { naturalWidth: w, naturalHeight: h } = img;
112
+ const scale = Math.min(MAX_DIM / w, MAX_DIM / h, 1);
113
+ const sw = Math.round(w * scale);
114
+ const sh = Math.round(h * scale);
115
+ const canvas = document.createElement("canvas");
116
+ canvas.width = sw;
117
+ canvas.height = sh;
118
+ const ctx = canvas.getContext("2d");
119
+ ctx.drawImage(img, 0, 0, sw, sh);
120
+ const { data } = ctx.getImageData(0, 0, sw, sh);
121
+ const hash = rgbaToThumbHash(sw, sh, data);
122
+ const thumbhash = uint8ToBase64(hash);
123
+ return { width: w, height: h, thumbhash };
124
+ } finally {
125
+ URL.revokeObjectURL(url);
126
+ }
127
+ }
128
+ function decodeThumbHash(hash) {
129
+ try {
130
+ const bytes = base64ToUint8(hash);
131
+ return thumbHashToDataURL(bytes);
132
+ } catch {
133
+ return void 0;
134
+ }
135
+ }
136
+ function loadImage(src) {
137
+ return new Promise((resolve, reject) => {
138
+ const img = new Image();
139
+ img.onload = () => resolve(img);
140
+ img.onerror = reject;
141
+ img.src = src;
142
+ });
143
+ }
144
+ function uint8ToBase64(bytes) {
145
+ let bin = "";
146
+ for (const b of bytes) bin += String.fromCodePoint(b);
147
+ return btoa(bin);
148
+ }
149
+ function base64ToUint8(str) {
150
+ const bin = atob(str);
151
+ const bytes = new Uint8Array(bin.length);
152
+ for (let i = 0; i < bin.length; i++) bytes[i] = bin.codePointAt(i);
153
+ return bytes;
154
+ }
155
+ let katexModule = null;
156
+ let katexLoadPromise = null;
157
+ function loadKaTeX() {
158
+ if (katexModule) return Promise.resolve(katexModule);
159
+ if (!katexLoadPromise) {
160
+ katexLoadPromise = import("katex").then((mod) => {
161
+ katexModule = mod;
162
+ return katexModule;
163
+ });
164
+ }
165
+ return katexLoadPromise;
166
+ }
167
+ function KaTeXRenderer({ equation, displayMode }) {
168
+ const [html, setHtml] = useState(null);
169
+ const [error, setError] = useState(null);
170
+ useEffect(() => {
171
+ let cancelled = false;
172
+ loadKaTeX().then((katex) => {
173
+ if (cancelled) return;
174
+ const rendered = katex.default.renderToString(equation, {
175
+ displayMode,
176
+ throwOnError: false
177
+ });
178
+ setHtml(rendered);
179
+ setError(null);
180
+ }).catch(() => {
181
+ if (cancelled) return;
182
+ setHtml(null);
183
+ setError("KaTeX is not available");
184
+ });
185
+ return () => {
186
+ cancelled = true;
187
+ };
188
+ }, [equation, displayMode]);
189
+ if (error) {
190
+ return /* @__PURE__ */ jsx("code", { className: clsx(katexClassNames.fallback, katexStyles.fallback), children: equation });
191
+ }
192
+ if (html) {
193
+ return /* @__PURE__ */ jsx(
194
+ "span",
195
+ {
196
+ dangerouslySetInnerHTML: { __html: html },
197
+ className: displayMode ? clsx(katexClassNames.block, katexStyles.block) : clsx(katexClassNames.inline, katexStyles.inline)
198
+ }
199
+ );
200
+ }
201
+ return /* @__PURE__ */ jsx("code", { className: clsx(katexClassNames.fallback, katexStyles.fallback), children: equation });
202
+ }
203
+ export {
204
+ FootnoteDefinitionsProvider as F,
205
+ KaTeXRenderer as K,
206
+ RendererConfigProvider as R,
207
+ RendererWrapper as a,
208
+ useFootnoteDefinitions as b,
209
+ createRendererDecoration as c,
210
+ useFootnoteDisplayNumber as d,
211
+ useRendererConfig as e,
212
+ useRendererMode as f,
213
+ useVariant as g,
214
+ FootnoteStaticRenderer as h,
215
+ computeImageMeta as i,
216
+ decodeThumbHash as j,
217
+ useFootnoteContent as u
218
+ };
@@ -0,0 +1,36 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ function LinkCardRenderer({
3
+ url,
4
+ title,
5
+ description,
6
+ favicon,
7
+ image
8
+ }) {
9
+ const displayTitle = title || url;
10
+ return /* @__PURE__ */ jsxs("a", { className: "rich-link-card", href: url, rel: "noopener noreferrer", target: "_blank", children: [
11
+ image && /* @__PURE__ */ jsx("span", { className: "rich-link-card-image", children: /* @__PURE__ */ jsx("img", { alt: "", loading: "lazy", src: image }) }),
12
+ /* @__PURE__ */ jsxs("span", { className: "rich-link-card-content", children: [
13
+ /* @__PURE__ */ jsxs("span", { className: "rich-link-card-title", children: [
14
+ favicon && /* @__PURE__ */ jsx(
15
+ "img",
16
+ {
17
+ alt: "",
18
+ className: "rich-link-card-favicon",
19
+ height: 16,
20
+ src: favicon,
21
+ width: 16,
22
+ onError: (e) => {
23
+ e.target.style.display = "none";
24
+ }
25
+ }
26
+ ),
27
+ displayTitle
28
+ ] }),
29
+ description && /* @__PURE__ */ jsx("span", { className: "rich-link-card-description", children: description }),
30
+ /* @__PURE__ */ jsx("span", { className: "rich-link-card-url", children: url })
31
+ ] })
32
+ ] });
33
+ }
34
+ export {
35
+ LinkCardRenderer as L
36
+ };
@@ -0,0 +1,97 @@
1
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
2
+ import { createCommand, $insertNodes, COMMAND_PRIORITY_EDITOR } from "lexical";
3
+ import { useEffect } from "react";
4
+ import { $ as $createAlertQuoteEditNode } from "./AlertQuoteEditNode-CB8C24Xf.js";
5
+ import { $ as $createImageNode, t as $createKaTeXInlineNode, v as $createKaTeXBlockNode, b as $createMermaidNode } from "./theme-D_efLk4K.js";
6
+ const INSERT_ALERT_COMMAND = createCommand("INSERT_ALERT");
7
+ function AlertPlugin() {
8
+ const [editor] = useLexicalComposerContext();
9
+ useEffect(() => {
10
+ return editor.registerCommand(
11
+ INSERT_ALERT_COMMAND,
12
+ (alertType) => {
13
+ $insertNodes([$createAlertQuoteEditNode(alertType)]);
14
+ return true;
15
+ },
16
+ COMMAND_PRIORITY_EDITOR
17
+ );
18
+ }, [editor]);
19
+ return null;
20
+ }
21
+ const INSERT_IMAGE_COMMAND = createCommand(
22
+ "INSERT_IMAGE_COMMAND"
23
+ );
24
+ function ImagePlugin() {
25
+ const [editor] = useLexicalComposerContext();
26
+ useEffect(() => {
27
+ return editor.registerCommand(
28
+ INSERT_IMAGE_COMMAND,
29
+ (payload) => {
30
+ const imageNode = $createImageNode(payload);
31
+ $insertNodes([imageNode]);
32
+ return true;
33
+ },
34
+ COMMAND_PRIORITY_EDITOR
35
+ );
36
+ }, [editor]);
37
+ return null;
38
+ }
39
+ const INSERT_KATEX_INLINE_COMMAND = createCommand(
40
+ "INSERT_KATEX_INLINE"
41
+ );
42
+ const INSERT_KATEX_BLOCK_COMMAND = createCommand("INSERT_KATEX_BLOCK");
43
+ function KaTeXPlugin() {
44
+ const [editor] = useLexicalComposerContext();
45
+ useEffect(() => {
46
+ const unregisterInline = editor.registerCommand(
47
+ INSERT_KATEX_INLINE_COMMAND,
48
+ (equation) => {
49
+ const node = $createKaTeXInlineNode(equation);
50
+ $insertNodes([node]);
51
+ return true;
52
+ },
53
+ COMMAND_PRIORITY_EDITOR
54
+ );
55
+ const unregisterBlock = editor.registerCommand(
56
+ INSERT_KATEX_BLOCK_COMMAND,
57
+ (equation) => {
58
+ const node = $createKaTeXBlockNode(equation);
59
+ $insertNodes([node]);
60
+ return true;
61
+ },
62
+ COMMAND_PRIORITY_EDITOR
63
+ );
64
+ return () => {
65
+ unregisterInline();
66
+ unregisterBlock();
67
+ };
68
+ }, [editor]);
69
+ return null;
70
+ }
71
+ const INSERT_MERMAID_COMMAND = createCommand("INSERT_MERMAID");
72
+ function MermaidPlugin() {
73
+ const [editor] = useLexicalComposerContext();
74
+ useEffect(() => {
75
+ return editor.registerCommand(
76
+ INSERT_MERMAID_COMMAND,
77
+ (diagram) => {
78
+ const node = $createMermaidNode(diagram);
79
+ $insertNodes([node]);
80
+ return true;
81
+ },
82
+ COMMAND_PRIORITY_EDITOR
83
+ );
84
+ }, [editor]);
85
+ return null;
86
+ }
87
+ export {
88
+ AlertPlugin as A,
89
+ ImagePlugin as I,
90
+ KaTeXPlugin as K,
91
+ MermaidPlugin as M,
92
+ INSERT_ALERT_COMMAND as a,
93
+ INSERT_IMAGE_COMMAND as b,
94
+ INSERT_KATEX_BLOCK_COMMAND as c,
95
+ INSERT_KATEX_INLINE_COMMAND as d,
96
+ INSERT_MERMAID_COMMAND as e
97
+ };
@@ -0,0 +1,58 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Mail, Globe } from "lucide-react";
3
+ import { useState, useEffect, createContext, use } from "react";
4
+ import { e as clsx, d as sharedStyles, s as semanticClassNames } from "./katex.css-Csc-7N7u.js";
5
+ import { g as getHostname, p as probeFavicon } from "./favicon-BQgbXF_a.js";
6
+ function LinkFavicon({
7
+ href,
8
+ source,
9
+ noIcon = false,
10
+ className,
11
+ platformIconMap,
12
+ getPlatformFromUrl
13
+ }) {
14
+ const faviconClassName = clsx(
15
+ semanticClassNames.linkFavicon,
16
+ sharedStyles.linkFavicon,
17
+ className
18
+ );
19
+ const [faviconUrl, setFaviconUrl] = useState(null);
20
+ useEffect(() => {
21
+ if (!href) return;
22
+ const hostname = getHostname(href);
23
+ if (!hostname) return;
24
+ let cancelled = false;
25
+ probeFavicon(hostname).then((url) => {
26
+ if (!cancelled) setFaviconUrl(url);
27
+ });
28
+ return () => {
29
+ cancelled = true;
30
+ };
31
+ }, [href]);
32
+ if (noIcon || !href && !source) return null;
33
+ let platformType = source;
34
+ if (!platformType && href && getPlatformFromUrl) {
35
+ try {
36
+ platformType = getPlatformFromUrl(new URL(href)) ?? void 0;
37
+ } catch {
38
+ }
39
+ }
40
+ if (platformType && platformIconMap?.[platformType]) {
41
+ return /* @__PURE__ */ jsx("span", { className: faviconClassName, children: platformIconMap[platformType] });
42
+ }
43
+ if (faviconUrl) {
44
+ return /* @__PURE__ */ jsx("span", { className: faviconClassName, children: /* @__PURE__ */ jsx("img", { alt: "", "aria-hidden": "true", height: 14, src: faviconUrl, width: 14 }) });
45
+ }
46
+ const isMailto = href?.toLowerCase().startsWith("mailto:");
47
+ return /* @__PURE__ */ jsx("span", { className: faviconClassName, children: isMailto ? /* @__PURE__ */ jsx(Mail, { "aria-hidden": true, size: 14 }) : /* @__PURE__ */ jsx(Globe, { "aria-hidden": true, size: 14 }) });
48
+ }
49
+ const PresentDialogContext = createContext(null);
50
+ const PresentDialogProvider = PresentDialogContext.Provider;
51
+ function usePresentDialog() {
52
+ return use(PresentDialogContext);
53
+ }
54
+ export {
55
+ LinkFavicon as L,
56
+ PresentDialogProvider as P,
57
+ usePresentDialog as u
58
+ };