@meowdown/react 0.67.1 → 0.68.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.
package/README.md CHANGED
@@ -62,7 +62,7 @@ Common `MeowdownEditor` props:
62
62
  | `mode` | `'focus'` (default), `'show'`, or `'hide'`: how much Markdown syntax stays in view |
63
63
  | `searchQuery` / `onSearchChange` | Find in document, with `EditorHandle.findNext()` / `findPrevious()` |
64
64
  | `onWikilinkClick` / `onLinkClick` / `onTagClick` / `onImageClick` / `onFileClick` | Click handling for the rendered atoms |
65
- | `resolveImageUrl` / `resolveWikiEmbed` / `resolveFileLink` / `resolveFileInfo` | Resolve and classify local content |
65
+ | `resolveImageUrl` / `resolveWikiEmbed` / `resolveWikilink` / `resolveFileLink` / `resolveFileInfo` | Resolve and classify local content |
66
66
  | `onFilePaste` | Persist pasted or dropped files |
67
67
  | `onSlashMenuSearch` / `onTagSearch` / `onWikilinkSearch` / `onSelectionMenuSearch` | Search menus for `/`, `#`, `[[`, and selection commands |
68
68
  | `readOnly` / `placeholder` / `blockHandle` / `caretGlide` / `embedPaste` / `linkPaste` / `bulletAfterHeading` | Behavior toggles |
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ReactElement, ReactNode, Ref } from "react";
2
- import { AcceptPendingReplacementOptions, ExitBoundaryHandler, FileClickHandler, FileInfoResolver, FileLinkResolver, FilePasteOptions, FileViewOptions, ImageClickHandler, ImageOptions, LinkClickHandler, LinkCopyHandler, LinkPreview, LinkPreviewResolver, LinkPreviewResolver as LinkPreviewResolver$1, ListMarker, MarkMode, PendingReplacement, PendingReplacementOutcome, PlaceholderOptions, SearchStatusHandler, StartPendingReplacementOptions, TagClickHandler, TypedEditor, WikiEmbedResolver, WikilinkClickHandler, WikilinkHoverHit } from "@meowdown/core";
2
+ import { AcceptPendingReplacementOptions, ExitBoundaryHandler, FileClickHandler, FileInfoResolver, FileLinkResolver, FilePasteOptions, FileViewOptions, ImageClickHandler, ImageOptions, LinkClickHandler, LinkCopyHandler, LinkPreview, LinkPreviewResolver, LinkPreviewResolver as LinkPreviewResolver$1, ListMarker, MarkMode, PendingReplacement, PendingReplacementOutcome, PlaceholderOptions, SearchStatusHandler, StartPendingReplacementOptions, TagClickHandler, TypedEditor, WikiEmbedResolver, WikilinkClickHandler, WikilinkHoverHit, WikilinkResolver } from "@meowdown/core";
3
3
  import { SelectionJSON, SelectionJSON as SelectionJSON$1 } from "@prosekit/core";
4
4
  import { useEditor, useExtension, useKeymap } from "@prosekit/react";
5
5
  //#region src/utils/date-format.d.ts
@@ -391,6 +391,15 @@ interface EditorProps {
391
391
  * and editable. Must be pure and is read once when the editor is created.
392
392
  */
393
393
  resolveWikiEmbed?: WikiEmbedResolver;
394
+ /**
395
+ * Resolves a `[[...]]` wikilink into the target its click and hover
396
+ * handlers receive and the label its chip shows. Meowdown reads no syntax
397
+ * inside the brackets, so an alias form such as `[[target|alias]]` is
398
+ * split here by the host. Return `undefined` to use the bracketed text as
399
+ * both; the markdown text is untouched either way. Must be pure and is
400
+ * read once when the editor is created.
401
+ */
402
+ resolveWikilink?: WikilinkResolver;
394
403
  /**
395
404
  * Resolves the metadata (file size in bytes) shown on a file pill, directly
396
405
  * or as a promise; the pill renders immediately and fills the size in when
@@ -515,7 +524,7 @@ interface EditorProps {
515
524
  *
516
525
  * Callbacks and resolvers should be stable; pass them via `useCallback`.
517
526
  */
518
- export declare function MeowdownEditor({ mode, initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, resolveLinkPreview, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, frontmatter, blockHandle, caretGlide, placeholder, readOnly, spellCheck, searchQuery, onSearchChange, timeFormat, editorClassName, wrapperClassName, handleRef, children }: EditorProps): ReactElement;
527
+ export declare function MeowdownEditor({ mode, initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, resolveLinkPreview, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, frontmatter, blockHandle, caretGlide, placeholder, readOnly, spellCheck, searchQuery, onSearchChange, timeFormat, editorClassName, wrapperClassName, handleRef, children }: EditorProps): ReactElement;
519
528
  //#endregion
520
529
  //#region src/components/markdown-view.d.ts
521
530
  /**
@@ -595,6 +604,11 @@ interface MarkdownViewProps {
595
604
  * Classify `![[target]]` as an image, file, or note; unresolved source stays literal.
596
605
  */
597
606
  resolveWikiEmbed?: WikiEmbedResolver;
607
+ /**
608
+ * Resolve a `[[...]]` wikilink into its target and chip label; the bracketed
609
+ * text is both by default. Must be pure.
610
+ */
611
+ resolveWikilink?: WikilinkResolver;
598
612
  /**
599
613
  * Resolve metadata shown on a file pill.
600
614
  */
@@ -635,7 +649,7 @@ interface MarkdownViewProps {
635
649
  * Callbacks (`onWikilinkClick`, etc.) and resolvers should be stable; pass them via
636
650
  * `useCallback` to avoid re-rendering the whole tree.
637
651
  */
638
- export declare function MarkdownView({ markdown, markMode, frontmatter, interactive, expandCollapsed, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }: MarkdownViewProps): ReactElement;
652
+ export declare function MarkdownView({ markdown, markMode, frontmatter, interactive, expandCollapsed, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }: MarkdownViewProps): ReactElement;
639
653
  //#endregion
640
654
  //#region src/components/wikilink-hover-card.d.ts
641
655
  /**
package/dist/index.js CHANGED
@@ -815,16 +815,20 @@ function LinkMenu({ onLinkClick, onLinkCopy, resolveLinkPreview, readOnly = fals
815
815
  const [link, setLink] = useState();
816
816
  const [edit, setEdit] = useState();
817
817
  const isPointerOverPopupRef = useRef(false);
818
- const linkHoverExtension = useMemo(() => defineLinkHoverHandler((nextHit) => {
819
- setInfoOpen(nextHit != null);
820
- if (nextHit) setLink(nextHit.payload);
821
- }, { canLeave: () => !isPointerOverPopupRef.current }), []);
818
+ const linkHoverExtension = useMemo(() => {
819
+ return defineLinkHoverHandler((nextHit) => {
820
+ setInfoOpen(nextHit != null);
821
+ if (nextHit) setLink(nextHit.payload);
822
+ }, { canLeave: () => !isPointerOverPopupRef.current });
823
+ }, []);
822
824
  useExtension$1(linkHoverExtension);
823
- const linkEditExtension = useMemo(() => readOnly ? null : defineLinkEditKeymap((options) => {
824
- setEdit(options);
825
- setEditOpen(true);
826
- setInfoOpen(false);
827
- }), [readOnly]);
825
+ const linkEditExtension = useMemo(() => {
826
+ return readOnly ? null : defineLinkEditKeymap((options) => {
827
+ setEdit(options);
828
+ setEditOpen(true);
829
+ setInfoOpen(false);
830
+ });
831
+ }, [readOnly]);
828
832
  useExtension$1(linkEditExtension);
829
833
  const handlePointerHover = useCallback((over) => {
830
834
  isPointerOverPopupRef.current = over;
@@ -1546,7 +1550,9 @@ function getTableHandleState(editor) {
1546
1550
  columnAlign,
1547
1551
  setTableColumnAlign: {
1548
1552
  canExec: commands.setTableColumnAlign.canExec("left"),
1549
- command: (align) => commands.setTableColumnAlign(columnAlign === align ? null : align)
1553
+ command: (align) => {
1554
+ return commands.setTableColumnAlign(columnAlign === align ? null : align);
1555
+ }
1550
1556
  },
1551
1557
  addTableColumnBefore: {
1552
1558
  canExec: commands.addTableColumnBefore.canExec(),
@@ -1913,11 +1919,12 @@ function findHeadingPosition(doc, fragment) {
1913
1919
  });
1914
1920
  return match;
1915
1921
  }
1916
- function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance = true, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, resolveLinkPreview, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution = true, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, searchQuery = "", onSearchChange, timeFormat, editorClassName, ref, children }) {
1922
+ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance = true, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, resolveLinkPreview, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution = true, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, searchQuery = "", onSearchChange, timeFormat, editorClassName, ref, children }) {
1917
1923
  const [editor] = useState(() => {
1918
1924
  const baseExtension = defineEditorExtension({
1919
1925
  resolveFileLink,
1920
1926
  resolveWikiEmbed,
1927
+ resolveWikilink,
1921
1928
  markMode
1922
1929
  });
1923
1930
  const extension = union(baseExtension, defineCodeBlockView());
@@ -2137,7 +2144,7 @@ const CARET_GLIDE_OFF = { "--meowdown-caret-glide": "0ms" };
2137
2144
  *
2138
2145
  * Callbacks and resolvers should be stable; pass them via `useCallback`.
2139
2146
  */
2140
- function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance = true, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, resolveLinkPreview, 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, searchQuery, onSearchChange, timeFormat, editorClassName, wrapperClassName, handleRef, children }) {
2147
+ function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onSlashMenuSearch, onTagSearch, onWikilinkSearch, onSelectionMenuSearch, selectionMenuAffordance = true, pendingReplacementActions, onPendingReplacementResolve, onWikilinkClick, onLinkClick, onLinkCopy, resolveLinkPreview, onTagClick, onExitBoundary, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste = true, linkPaste = true, bulletAfterHeading = false, substitution = true, frontmatter = false, blockHandle = true, caretGlide = true, placeholder, readOnly, spellCheck, searchQuery, onSearchChange, timeFormat, editorClassName, wrapperClassName, handleRef, children }) {
2141
2148
  const childRef = useRef(null);
2142
2149
  useImperativeHandle(handleRef, () => {
2143
2150
  function getMarkdown() {
@@ -2254,6 +2261,7 @@ function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onSlashM
2254
2261
  resolveImageUrl,
2255
2262
  resolveFileLink,
2256
2263
  resolveWikiEmbed,
2264
+ resolveWikilink,
2257
2265
  resolveFileInfo,
2258
2266
  onFileClick,
2259
2267
  onFilePaste,
@@ -2387,11 +2395,13 @@ function WikilinkChip(props) {
2387
2395
  className: "md-wikilink-view-preview md-atom-view-preview",
2388
2396
  "data-testid": "wikilink",
2389
2397
  contentEditable: false,
2390
- onClick: onWikilinkClick ? (event) => onWikilinkClick({
2391
- target,
2392
- event: event.nativeEvent,
2393
- mod: isModEvent(event)
2394
- }) : void 0,
2398
+ onClick: onWikilinkClick ? (event) => {
2399
+ return onWikilinkClick({
2400
+ target,
2401
+ event: event.nativeEvent,
2402
+ mod: isModEvent(event)
2403
+ });
2404
+ } : void 0,
2395
2405
  children: /* @__PURE__ */ jsx("span", {
2396
2406
  className: "md-wikilink-view-label",
2397
2407
  contentEditable: false,
@@ -2451,12 +2461,14 @@ function ImagePreview(props) {
2451
2461
  src: url,
2452
2462
  alt,
2453
2463
  draggable: false,
2454
- onClick: onImageClick ? (event) => onImageClick({
2455
- src,
2456
- alt,
2457
- event: event.nativeEvent,
2458
- mod: isModEvent(event)
2459
- }) : void 0,
2464
+ onClick: onImageClick ? (event) => {
2465
+ return onImageClick({
2466
+ src,
2467
+ alt,
2468
+ event: event.nativeEvent,
2469
+ mod: isModEvent(event)
2470
+ });
2471
+ } : void 0,
2460
2472
  style: width == null ? void 0 : { width: `${width}px` }
2461
2473
  })
2462
2474
  });
@@ -2746,7 +2758,8 @@ function renderInline(node, context) {
2746
2758
  if (!text) return null;
2747
2759
  return renderRuns(inlineTextToMarkChunksWithContext(getMarkBuilders(), text, {
2748
2760
  resolveFileLink: context.resolveFileLink,
2749
- resolveWikiEmbed: context.resolveWikiEmbed
2761
+ resolveWikiEmbed: context.resolveWikiEmbed,
2762
+ resolveWikilink: context.resolveWikilink
2750
2763
  }, {
2751
2764
  referenceDefinitions: context.referenceDefinitions,
2752
2765
  isReferenceDefinition: context.referenceDefinitionNodes.has(node)
@@ -2826,7 +2839,7 @@ function renderBlock(node, context) {
2826
2839
  * Callbacks (`onWikilinkClick`, etc.) and resolvers should be stable; pass them via
2827
2840
  * `useCallback` to avoid re-rendering the whole tree.
2828
2841
  */
2829
- function MarkdownView({ markdown, markMode = "hide", frontmatter = false, interactive = true, expandCollapsed = false, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }) {
2842
+ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, interactive = true, expandCollapsed = false, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }) {
2830
2843
  const content = useMemo(() => {
2831
2844
  const doc = markdownToDoc(markdown, { frontmatter });
2832
2845
  const referenceIndex = collectReferenceDefinitions(doc);
@@ -2836,6 +2849,7 @@ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, intera
2836
2849
  resolveImageUrl,
2837
2850
  resolveFileLink,
2838
2851
  resolveWikiEmbed,
2852
+ resolveWikilink,
2839
2853
  resolveFileInfo,
2840
2854
  onWikilinkClick: interactive ? onWikilinkClick : void 0,
2841
2855
  onLinkClick: interactive ? onLinkClick : void 0,
@@ -2856,6 +2870,7 @@ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, intera
2856
2870
  resolveImageUrl,
2857
2871
  resolveFileLink,
2858
2872
  resolveWikiEmbed,
2873
+ resolveWikilink,
2859
2874
  resolveFileInfo,
2860
2875
  onWikilinkClick,
2861
2876
  onLinkClick,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.67.1",
4
+ "version": "0.68.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -23,15 +23,15 @@
23
23
  "dependencies": {
24
24
  "@base-ui/react": "^1.7.0",
25
25
  "@ocavue/utils": "^1.7.0",
26
- "@prosekit/core": "^0.13.1",
26
+ "@prosekit/core": "^0.13.2",
27
27
  "@prosekit/pm": "^0.1.19",
28
- "@prosekit/react": "^0.8.1",
28
+ "@prosekit/react": "^0.8.2",
29
29
  "beautiful-mermaid": "^1.1.3",
30
30
  "clsx": "^2.1.1",
31
31
  "github-slugger": "^2.0.0",
32
- "lucide-react": "^1.28.0",
32
+ "lucide-react": "^1.38.0",
33
33
  "react-property": "^2.0.2",
34
- "@meowdown/core": "0.67.1"
34
+ "@meowdown/core": "0.68.0"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "react": "^19.0.0",
@@ -48,16 +48,16 @@
48
48
  "devDependencies": {
49
49
  "@css-modules-kit/codegen": "^1.4.0",
50
50
  "@ocavue/tsconfig": "^0.7.1",
51
- "@tsdown/css": "^0.23.0-beta.2",
51
+ "@tsdown/css": "^0.23.0-rc.1",
52
52
  "@types/react": "^19.2.18",
53
- "@types/react-dom": "^19.2.4",
53
+ "@types/react-dom": "^19.2.5",
54
54
  "@vitest/browser-playwright": "^4.1.11",
55
55
  "dedent": "^1.7.2",
56
56
  "react": "^19.2.8",
57
57
  "react-dom": "^19.2.8",
58
- "tsdown": "^0.23.0-beta.2",
58
+ "tsdown": "^0.23.0-rc.1",
59
59
  "vitest": "^4.1.11",
60
- "vitest-browser-commands": "^0.2.1",
60
+ "vitest-browser-commands": "^0.4.1",
61
61
  "vitest-browser-react": "^2.2.0",
62
62
  "@meowdown/vitest": "0.0.0"
63
63
  },