@meowdown/react 0.58.1 → 0.58.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +12 -1
- package/dist/index.js +126 -108
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,11 @@ type SelectionHint = SelectionJSON$1 | 'start' | 'end';
|
|
|
13
13
|
* editor's coordinate space and are not portable across editors.
|
|
14
14
|
*/
|
|
15
15
|
type EditorStateSnapshot = [markdown: string, selection: SelectionJSON$1];
|
|
16
|
+
/**
|
|
17
|
+
* The imperative API of a mounted editor: read and write the document,
|
|
18
|
+
* move the selection, and drive the selection menu and pending replacements
|
|
19
|
+
* from outside React.
|
|
20
|
+
*/
|
|
16
21
|
interface EditorHandle {
|
|
17
22
|
/**
|
|
18
23
|
* Reconciles pending native input, then serializes the current document to
|
|
@@ -398,7 +403,13 @@ interface EditorProps {
|
|
|
398
403
|
/** Nodes rendered inside the editor's ProseKit context. */
|
|
399
404
|
children?: ReactNode;
|
|
400
405
|
}
|
|
401
|
-
|
|
406
|
+
/**
|
|
407
|
+
* A hybrid live-preview Markdown editor: the document stays Markdown text,
|
|
408
|
+
* rendered in place as rich content.
|
|
409
|
+
*
|
|
410
|
+
* Callbacks and resolvers should be stable; pass them via `useCallback`.
|
|
411
|
+
*/
|
|
412
|
+
declare function MeowdownEditor({ mode, initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, frontmatter, blockHandle, caretGlide, placeholder, readOnly, spellCheck, timeFormat, editorClassName, wrapperClassName, handleRef, children }: EditorProps): ReactElement;
|
|
402
413
|
//#endregion
|
|
403
414
|
//#region src/components/markdown-view.d.ts
|
|
404
415
|
/** Payload for {@link TaskClickHandler}. */
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clsx } from "clsx/lite";
|
|
2
|
-
import { Fragment, cloneElement, createElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { buildFileMarkdown, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSpellCheckPlugin, defineSubstitution, defineTagClickHandler, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, docToMarkdown, formatFileSize, getCodeTokens, getFileKind, getMarkBuilders, getPendingReplacement, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunksWithContext, isCodeBlockPreviewHiddenDecoration, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, renderMathInto } from "@meowdown/core";
|
|
2
|
+
import { Fragment, cloneElement, createElement, useCallback, useDeferredValue, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { buildFileMarkdown, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSpellCheckPlugin, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, docToMarkdown, formatFileSize, getCodeTokens, getFileKind, getMarkBuilders, getPendingReplacement, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunksWithContext, isCodeBlockPreviewHiddenDecoration, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, renderMathInto } from "@meowdown/core";
|
|
4
4
|
import { clamp } from "@ocavue/utils";
|
|
5
5
|
import { canUseRegexLookbehind, createEditor, defineDocChangeHandler, defineUpdateHandler, isTextSelection, union } from "@prosekit/core";
|
|
6
6
|
import { Selection, TextSelection } from "@prosekit/pm/state";
|
|
@@ -35,7 +35,7 @@ function useBeautifulMermaid(enabled) {
|
|
|
35
35
|
let cancelled = false;
|
|
36
36
|
loadBeautifulMermaid().then((loadedRenderer) => {
|
|
37
37
|
if (!cancelled) setRenderer(() => loadedRenderer);
|
|
38
|
-
})
|
|
38
|
+
});
|
|
39
39
|
return () => {
|
|
40
40
|
cancelled = true;
|
|
41
41
|
};
|
|
@@ -131,7 +131,7 @@ function MathRender(props) {
|
|
|
131
131
|
const ref = useRef(null);
|
|
132
132
|
useLayoutEffect(() => {
|
|
133
133
|
const element = ref.current;
|
|
134
|
-
if (!element
|
|
134
|
+
if (!element) return;
|
|
135
135
|
renderMathInto(katex, element, formula, displayMode);
|
|
136
136
|
}, [
|
|
137
137
|
katex,
|
|
@@ -200,122 +200,46 @@ function MermaidRender(props) {
|
|
|
200
200
|
//#endregion
|
|
201
201
|
//#region src/components/code-block-view.tsx
|
|
202
202
|
function CodeBlockView(props) {
|
|
203
|
-
const
|
|
203
|
+
const { node, view, getPos, decorations, selected, setAttrs, contentRef } = props;
|
|
204
|
+
const language = node.attrs.language || "";
|
|
204
205
|
const isMath = language === "math";
|
|
205
206
|
const isMermaid = language === "mermaid";
|
|
206
|
-
const code =
|
|
207
|
-
const caretInside =
|
|
207
|
+
const code = node.textContent;
|
|
208
|
+
const caretInside = decorations.some(isCodeBlockPreviewHiddenDecoration);
|
|
208
209
|
const katex = useKaTeX(isMath);
|
|
209
210
|
const mermaid = useBeautifulMermaid(isMermaid);
|
|
210
211
|
const showMathPreview = isMath && katex != null;
|
|
211
212
|
const showMermaidPreview = isMermaid && mermaid != null;
|
|
212
|
-
const
|
|
213
|
-
const
|
|
213
|
+
const showPreview = showMathPreview || showMermaidPreview;
|
|
214
|
+
const previewCode = useDeferredValue(showPreview ? code : "");
|
|
215
|
+
const previewOnly = showPreview && !caretInside && code.trim() !== "";
|
|
216
|
+
const focusSource = useCallback((event) => {
|
|
214
217
|
event.preventDefault();
|
|
215
|
-
const pos =
|
|
218
|
+
const pos = getPos();
|
|
216
219
|
if (pos == null) return;
|
|
217
|
-
const { view } = props;
|
|
218
220
|
const selection = TextSelection.near(view.state.doc.resolve(pos + 1), 1);
|
|
219
221
|
view.dispatch(view.state.tr.setSelection(selection));
|
|
220
222
|
view.focus();
|
|
221
|
-
};
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
label: language
|
|
226
|
-
};
|
|
227
|
-
}, [language]);
|
|
228
|
-
const [query, setQuery] = useState("");
|
|
229
|
-
const [comboboxOpen, setComboboxOpen] = useState(false);
|
|
230
|
-
const itemsForView = useMemo(() => {
|
|
231
|
-
const value = query.trim();
|
|
232
|
-
if (!value) return codeBlockLanguages;
|
|
233
|
-
const lowercased = value.toLowerCase();
|
|
234
|
-
return codeBlockLanguages.some((item) => item.value.toLowerCase() === lowercased || item.label.toLowerCase() === lowercased) ? codeBlockLanguages : [...codeBlockLanguages, {
|
|
235
|
-
value,
|
|
236
|
-
label: `Use "${value}"`
|
|
237
|
-
}];
|
|
238
|
-
}, [query]);
|
|
239
|
-
const setLanguage = (item) => {
|
|
240
|
-
props.setAttrs({ language: item?.value ?? "" });
|
|
241
|
-
};
|
|
223
|
+
}, [view, getPos]);
|
|
224
|
+
const setLanguage = useCallback((language) => {
|
|
225
|
+
setAttrs({ language });
|
|
226
|
+
}, [setAttrs]);
|
|
242
227
|
return /* @__PURE__ */ jsxs("div", {
|
|
243
228
|
className: code_block_view_module_default.Root,
|
|
244
229
|
"data-preview": previewOnly || void 0,
|
|
245
230
|
children: [
|
|
246
|
-
/* @__PURE__ */ jsxs("div", {
|
|
247
|
-
className: code_block_view_module_default.Toolbar,
|
|
248
|
-
contentEditable: false,
|
|
249
|
-
"data-open": comboboxOpen || void 0,
|
|
250
|
-
children: [/* @__PURE__ */ jsxs(Combobox.Root, {
|
|
251
|
-
items: itemsForView,
|
|
252
|
-
value: selected,
|
|
253
|
-
onValueChange: setLanguage,
|
|
254
|
-
inputValue: query,
|
|
255
|
-
onInputValueChange: setQuery,
|
|
256
|
-
onOpenChange: (open) => {
|
|
257
|
-
if (open) setComboboxOpen(true);
|
|
258
|
-
else setQuery("");
|
|
259
|
-
},
|
|
260
|
-
onOpenChangeComplete: (open) => {
|
|
261
|
-
if (!open) setComboboxOpen(false);
|
|
262
|
-
},
|
|
263
|
-
children: [/* @__PURE__ */ jsxs(Combobox.Trigger, {
|
|
264
|
-
className: code_block_view_module_default.Trigger,
|
|
265
|
-
"data-testid": "code-block-language",
|
|
266
|
-
children: [/* @__PURE__ */ jsx(Combobox.Value, { placeholder: "Plain Text" }), /* @__PURE__ */ jsx(Combobox.Icon, {
|
|
267
|
-
className: code_block_view_module_default.TriggerIcon,
|
|
268
|
-
children: /* @__PURE__ */ jsx(ChevronsUpDownIcon, {})
|
|
269
|
-
})]
|
|
270
|
-
}), /* @__PURE__ */ jsx(Combobox.Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, {
|
|
271
|
-
className: code_block_view_module_default.Positioner,
|
|
272
|
-
sideOffset: 4,
|
|
273
|
-
children: /* @__PURE__ */ jsxs(Combobox.Popup, {
|
|
274
|
-
className: code_block_view_module_default.Popup,
|
|
275
|
-
children: [
|
|
276
|
-
/* @__PURE__ */ jsx("div", {
|
|
277
|
-
className: code_block_view_module_default.SearchRow,
|
|
278
|
-
children: /* @__PURE__ */ jsx(Combobox.Input, {
|
|
279
|
-
className: code_block_view_module_default.Search,
|
|
280
|
-
placeholder: "Search or type a language",
|
|
281
|
-
"data-testid": "code-block-language-search"
|
|
282
|
-
})
|
|
283
|
-
}),
|
|
284
|
-
/* @__PURE__ */ jsx(Combobox.Empty, {
|
|
285
|
-
className: code_block_view_module_default.Empty,
|
|
286
|
-
children: "No languages found."
|
|
287
|
-
}),
|
|
288
|
-
/* @__PURE__ */ jsx(Combobox.List, {
|
|
289
|
-
className: code_block_view_module_default.List,
|
|
290
|
-
children: (item) => /* @__PURE__ */ jsxs(Combobox.Item, {
|
|
291
|
-
value: item,
|
|
292
|
-
className: code_block_view_module_default.Item,
|
|
293
|
-
children: [/* @__PURE__ */ jsx(Combobox.ItemIndicator, {
|
|
294
|
-
className: code_block_view_module_default.ItemIndicator,
|
|
295
|
-
children: /* @__PURE__ */ jsx(CheckIcon, {})
|
|
296
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
297
|
-
className: code_block_view_module_default.ItemText,
|
|
298
|
-
children: item.label
|
|
299
|
-
})]
|
|
300
|
-
}, item.label)
|
|
301
|
-
})
|
|
302
|
-
]
|
|
303
|
-
})
|
|
304
|
-
}) })]
|
|
305
|
-
}), /* @__PURE__ */ jsx(CopyButton, {
|
|
306
|
-
getText: () => props.node.textContent,
|
|
307
|
-
label: "Copy code",
|
|
308
|
-
className: code_block_view_module_default.CopyButton,
|
|
309
|
-
"data-testid": "code-block-copy"
|
|
310
|
-
})]
|
|
311
|
-
}),
|
|
312
231
|
/* @__PURE__ */ jsx("pre", {
|
|
313
|
-
ref:
|
|
232
|
+
ref: contentRef,
|
|
314
233
|
"data-language": language
|
|
315
234
|
}),
|
|
235
|
+
selected ? null : /* @__PURE__ */ jsx(CodeBlockToolbar, {
|
|
236
|
+
code,
|
|
237
|
+
language,
|
|
238
|
+
setLanguage
|
|
239
|
+
}),
|
|
316
240
|
showMathPreview && /* @__PURE__ */ jsx(MathRender, {
|
|
317
241
|
katex,
|
|
318
|
-
formula:
|
|
242
|
+
formula: previewCode,
|
|
319
243
|
displayMode: true,
|
|
320
244
|
className: code_block_view_module_default.Preview,
|
|
321
245
|
"data-testid": "code-block-math-preview",
|
|
@@ -323,7 +247,7 @@ function CodeBlockView(props) {
|
|
|
323
247
|
}),
|
|
324
248
|
showMermaidPreview && /* @__PURE__ */ jsx(MermaidRender, {
|
|
325
249
|
renderer: mermaid,
|
|
326
|
-
source:
|
|
250
|
+
source: previewCode,
|
|
327
251
|
className: `${code_block_view_module_default.Preview} ${code_block_view_module_default.MermaidPreview}`,
|
|
328
252
|
"data-testid": "code-block-mermaid-preview",
|
|
329
253
|
onMouseDown: focusSource
|
|
@@ -331,6 +255,91 @@ function CodeBlockView(props) {
|
|
|
331
255
|
]
|
|
332
256
|
});
|
|
333
257
|
}
|
|
258
|
+
function CodeBlockToolbar({ code, language, setLanguage }) {
|
|
259
|
+
const selected = useMemo(() => {
|
|
260
|
+
return codeBlockLanguages.find((item) => item.value === language) ?? {
|
|
261
|
+
value: language,
|
|
262
|
+
label: language
|
|
263
|
+
};
|
|
264
|
+
}, [language]);
|
|
265
|
+
const [query, setQuery] = useState("");
|
|
266
|
+
const [comboboxOpen, setComboboxOpen] = useState(false);
|
|
267
|
+
const itemsForView = useMemo(() => {
|
|
268
|
+
const value = query.trim();
|
|
269
|
+
if (!value) return codeBlockLanguages;
|
|
270
|
+
const lowercased = value.toLowerCase();
|
|
271
|
+
return codeBlockLanguages.some((item) => item.value.toLowerCase() === lowercased || item.label.toLowerCase() === lowercased) ? codeBlockLanguages : [...codeBlockLanguages, {
|
|
272
|
+
value,
|
|
273
|
+
label: `Use "${value}"`
|
|
274
|
+
}];
|
|
275
|
+
}, [query]);
|
|
276
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
277
|
+
className: code_block_view_module_default.Toolbar,
|
|
278
|
+
contentEditable: false,
|
|
279
|
+
"data-open": comboboxOpen || void 0,
|
|
280
|
+
children: [/* @__PURE__ */ jsxs(Combobox.Root, {
|
|
281
|
+
items: itemsForView,
|
|
282
|
+
value: selected,
|
|
283
|
+
onValueChange: (item) => setLanguage(item?.value ?? ""),
|
|
284
|
+
inputValue: query,
|
|
285
|
+
onInputValueChange: setQuery,
|
|
286
|
+
onOpenChange: (open) => {
|
|
287
|
+
if (open) setComboboxOpen(true);
|
|
288
|
+
else setQuery("");
|
|
289
|
+
},
|
|
290
|
+
onOpenChangeComplete: (open) => {
|
|
291
|
+
if (!open) setComboboxOpen(false);
|
|
292
|
+
},
|
|
293
|
+
children: [/* @__PURE__ */ jsxs(Combobox.Trigger, {
|
|
294
|
+
className: code_block_view_module_default.Trigger,
|
|
295
|
+
"data-testid": "code-block-language",
|
|
296
|
+
children: [/* @__PURE__ */ jsx(Combobox.Value, { placeholder: "Plain Text" }), /* @__PURE__ */ jsx(Combobox.Icon, {
|
|
297
|
+
className: code_block_view_module_default.TriggerIcon,
|
|
298
|
+
children: /* @__PURE__ */ jsx(ChevronsUpDownIcon, {})
|
|
299
|
+
})]
|
|
300
|
+
}), /* @__PURE__ */ jsx(Combobox.Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, {
|
|
301
|
+
className: code_block_view_module_default.Positioner,
|
|
302
|
+
sideOffset: 4,
|
|
303
|
+
children: /* @__PURE__ */ jsxs(Combobox.Popup, {
|
|
304
|
+
className: code_block_view_module_default.Popup,
|
|
305
|
+
children: [
|
|
306
|
+
/* @__PURE__ */ jsx("div", {
|
|
307
|
+
className: code_block_view_module_default.SearchRow,
|
|
308
|
+
children: /* @__PURE__ */ jsx(Combobox.Input, {
|
|
309
|
+
className: code_block_view_module_default.Search,
|
|
310
|
+
placeholder: "Search or type a language",
|
|
311
|
+
"data-testid": "code-block-language-search"
|
|
312
|
+
})
|
|
313
|
+
}),
|
|
314
|
+
/* @__PURE__ */ jsx(Combobox.Empty, {
|
|
315
|
+
className: code_block_view_module_default.Empty,
|
|
316
|
+
children: "No languages found."
|
|
317
|
+
}),
|
|
318
|
+
/* @__PURE__ */ jsx(Combobox.List, {
|
|
319
|
+
className: code_block_view_module_default.List,
|
|
320
|
+
children: (item) => /* @__PURE__ */ jsxs(Combobox.Item, {
|
|
321
|
+
value: item,
|
|
322
|
+
className: code_block_view_module_default.Item,
|
|
323
|
+
children: [/* @__PURE__ */ jsx(Combobox.ItemIndicator, {
|
|
324
|
+
className: code_block_view_module_default.ItemIndicator,
|
|
325
|
+
children: /* @__PURE__ */ jsx(CheckIcon, {})
|
|
326
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
327
|
+
className: code_block_view_module_default.ItemText,
|
|
328
|
+
children: item.label
|
|
329
|
+
})]
|
|
330
|
+
}, item.label)
|
|
331
|
+
})
|
|
332
|
+
]
|
|
333
|
+
})
|
|
334
|
+
}) })]
|
|
335
|
+
}), /* @__PURE__ */ jsx(CopyButton, {
|
|
336
|
+
getText: () => code,
|
|
337
|
+
label: "Copy code",
|
|
338
|
+
className: code_block_view_module_default.CopyButton,
|
|
339
|
+
"data-testid": "code-block-copy"
|
|
340
|
+
})]
|
|
341
|
+
});
|
|
342
|
+
}
|
|
334
343
|
|
|
335
344
|
//#endregion
|
|
336
345
|
//#region src/extensions/code-block-view.ts
|
|
@@ -382,7 +391,7 @@ function DropIndicator$1() {
|
|
|
382
391
|
|
|
383
392
|
//#endregion
|
|
384
393
|
//#region src/components/editor-extensions.tsx
|
|
385
|
-
function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick, onTagClick, onExitBoundary, resolveImageUrl, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, placeholder, readOnly, wikilinkEnabled, spellCheck }) {
|
|
394
|
+
function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick, onTagClick, onExitBoundary, resolveImageUrl, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, placeholder, readOnly, wikilinkEnabled, spellCheck, editorClassName }) {
|
|
386
395
|
const editor = useEditor$1();
|
|
387
396
|
useEffect(() => {
|
|
388
397
|
editor.commands.setMarkMode(markMode);
|
|
@@ -460,6 +469,9 @@ function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick,
|
|
|
460
469
|
useExtension$1(useMemo(() => {
|
|
461
470
|
return spellCheck == null ? null : defineSpellCheckPlugin(spellCheck);
|
|
462
471
|
}, [spellCheck]));
|
|
472
|
+
useExtension$1(useMemo(() => {
|
|
473
|
+
return editorClassName ? defineViewAttributes({ class: editorClassName }) : null;
|
|
474
|
+
}, [editorClassName]));
|
|
463
475
|
return null;
|
|
464
476
|
}
|
|
465
477
|
|
|
@@ -1815,10 +1827,7 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onSl
|
|
|
1815
1827
|
return /* @__PURE__ */ jsxs(ProseKit, {
|
|
1816
1828
|
editor,
|
|
1817
1829
|
children: [
|
|
1818
|
-
/* @__PURE__ */ jsx("div", {
|
|
1819
|
-
ref: editor.mount,
|
|
1820
|
-
className: clsx("meowdown-content", editorClassName)
|
|
1821
|
-
}),
|
|
1830
|
+
/* @__PURE__ */ jsx("div", { ref: editor.mount }),
|
|
1822
1831
|
/* @__PURE__ */ jsx(EditorExtensions, {
|
|
1823
1832
|
markMode,
|
|
1824
1833
|
onDocChange: handleDocChange,
|
|
@@ -1839,7 +1848,8 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onSl
|
|
|
1839
1848
|
placeholder,
|
|
1840
1849
|
readOnly,
|
|
1841
1850
|
wikilinkEnabled: !!onWikilinkSearch,
|
|
1842
|
-
spellCheck
|
|
1851
|
+
spellCheck,
|
|
1852
|
+
editorClassName
|
|
1843
1853
|
}),
|
|
1844
1854
|
blockHandle && !readOnly && /* @__PURE__ */ jsx(BlockHandle, {}),
|
|
1845
1855
|
!readOnly && /* @__PURE__ */ jsx(TableHandle, {}),
|
|
@@ -1875,6 +1885,12 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onSl
|
|
|
1875
1885
|
//#endregion
|
|
1876
1886
|
//#region src/components/editor.tsx
|
|
1877
1887
|
const CARET_GLIDE_OFF = { "--meowdown-caret-glide": "0ms" };
|
|
1888
|
+
/**
|
|
1889
|
+
* A hybrid live-preview Markdown editor: the document stays Markdown text,
|
|
1890
|
+
* rendered in place as rich content.
|
|
1891
|
+
*
|
|
1892
|
+
* Callbacks and resolvers should be stable; pass them via `useCallback`.
|
|
1893
|
+
*/
|
|
1878
1894
|
function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance = true, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste = true, linkPaste = true, bulletAfterHeading = false, substitution = true, frontmatter = false, blockHandle = true, caretGlide = true, placeholder, readOnly, spellCheck, timeFormat, editorClassName, wrapperClassName, handleRef, children }) {
|
|
1879
1895
|
const childRef = useRef(null);
|
|
1880
1896
|
useImperativeHandle(handleRef, () => {
|
|
@@ -2313,10 +2329,12 @@ function CodeBlock({ code, language }) {
|
|
|
2313
2329
|
*/
|
|
2314
2330
|
function MathView(props) {
|
|
2315
2331
|
const { formula, children } = props;
|
|
2332
|
+
const katex = useKaTeX(true);
|
|
2333
|
+
if (!katex) return /* @__PURE__ */ jsx("span", { children: formula });
|
|
2316
2334
|
return /* @__PURE__ */ jsxs("span", {
|
|
2317
2335
|
className: "md-math-view",
|
|
2318
2336
|
children: [/* @__PURE__ */ jsx(MathRender, {
|
|
2319
|
-
katex
|
|
2337
|
+
katex,
|
|
2320
2338
|
formula,
|
|
2321
2339
|
displayMode: false,
|
|
2322
2340
|
className: "md-math-view-preview",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meowdown/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.58.
|
|
4
|
+
"version": "0.58.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"github-slugger": "^2.0.0",
|
|
32
32
|
"lucide-react": "^1.24.0",
|
|
33
33
|
"react-property": "^2.0.2",
|
|
34
|
-
"@meowdown/core": "0.58.
|
|
34
|
+
"@meowdown/core": "0.58.3"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"react": "^19.0.0",
|