@meowdown/react 0.57.2 → 0.58.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 (3) hide show
  1. package/README.md +7 -0
  2. package/dist/index.js +23 -12
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -60,6 +60,13 @@ The caret glides between positions by default; pass `caretGlide={false}` to move
60
60
 
61
61
  `MarkdownView` folds collapsed (`+`) bullets like the editor; pass `expandCollapsed` to render them expanded at every depth, for views that show slices of a note (e.g. a backlinks panel) where the source's fold state must not hide the content the view exists to show.
62
62
 
63
+ Both `MeowdownEditor` and `MarkdownView` resolve CommonMark full, collapsed,
64
+ and shortcut reference links and images. The editor keeps reference definitions
65
+ visible as editable source and preserves them through `getMarkdown()`.
66
+ `MarkdownView` uses the same first-definition-wins resolution but omits
67
+ definition paragraphs from its rendered output. Reference links are read-only
68
+ in the editor's link menu; edit their definition source to change the target.
69
+
63
70
  ### Wiki embeds
64
71
 
65
72
  Obsidian-style wiki embeds (`![[path]]`, with optional `|width` or
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { clsx } from "clsx/lite";
2
2
  import { Fragment, cloneElement, createElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
3
- import { buildFileMarkdown, codeBlockLanguages, 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, inlineTextToMarkChunks, isCodeBlockPreviewHiddenDecoration, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, renderMathInto } from "@meowdown/core";
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";
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";
@@ -564,7 +564,7 @@ function LinkInfoContent({ href, onLinkClick, onLinkCopy, onEdit, onRemove }) {
564
564
  className: link_menu_module_default.Button,
565
565
  onCopy: () => onLinkCopy?.({ href })
566
566
  }),
567
- /* @__PURE__ */ jsx("button", {
567
+ onEdit && /* @__PURE__ */ jsx("button", {
568
568
  type: "button",
569
569
  className: link_menu_module_default.Button,
570
570
  title: "Edit link",
@@ -572,7 +572,7 @@ function LinkInfoContent({ href, onLinkClick, onLinkCopy, onEdit, onRemove }) {
572
572
  onClick: onEdit,
573
573
  children: /* @__PURE__ */ jsx(PencilIcon, {})
574
574
  }),
575
- /* @__PURE__ */ jsx("button", {
575
+ onRemove && /* @__PURE__ */ jsx("button", {
576
576
  type: "button",
577
577
  className: link_menu_module_default.Button,
578
578
  title: "Remove link",
@@ -700,6 +700,7 @@ function LinkMenu({ onLinkClick, onLinkCopy }) {
700
700
  });
701
701
  if (hoverOpen && hover) {
702
702
  const link = hover;
703
+ const editable = link.label != null && link.dest != null;
703
704
  return /* @__PURE__ */ jsx(LinkPopover, {
704
705
  anchor,
705
706
  onClose: closeHover,
@@ -708,7 +709,7 @@ function LinkMenu({ onLinkClick, onLinkCopy }) {
708
709
  href: link.href,
709
710
  onLinkClick,
710
711
  onLinkCopy,
711
- onEdit: () => {
712
+ onEdit: editable ? () => {
712
713
  selectLinkUnit(editor, link);
713
714
  setEdit({
714
715
  from: link.unit.from,
@@ -716,12 +717,12 @@ function LinkMenu({ onLinkClick, onLinkCopy }) {
716
717
  link
717
718
  });
718
719
  closeHover();
719
- },
720
- onRemove: () => {
720
+ } : void 0,
721
+ onRemove: editable ? () => {
721
722
  selectLinkUnit(editor, link);
722
723
  editor.commands.removeLink();
723
724
  closeHover();
724
- }
725
+ } : void 0
725
726
  })
726
727
  });
727
728
  }
@@ -2398,10 +2399,13 @@ function wrapMark(mark, children, context) {
2398
2399
  className: "md-link",
2399
2400
  children
2400
2401
  });
2401
- const handleClick = context.onLinkClick ? (event) => context.onLinkClick?.({
2402
- href: attrs.href,
2403
- event: event.nativeEvent
2404
- }) : void 0;
2402
+ const handleClick = context.onLinkClick ? (event) => {
2403
+ event.preventDefault();
2404
+ context.onLinkClick?.({
2405
+ href: attrs.href,
2406
+ event: event.nativeEvent
2407
+ });
2408
+ } : void 0;
2405
2409
  return /* @__PURE__ */ jsx("a", {
2406
2410
  className: "md-link",
2407
2411
  href: attrs.href,
@@ -2445,15 +2449,19 @@ function renderRuns(runs, depth, context) {
2445
2449
  function renderInline(node, context) {
2446
2450
  const text = node.textContent;
2447
2451
  if (!text) return null;
2448
- return renderRuns(inlineTextToMarkChunks(getMarkBuilders(), text, {
2452
+ return renderRuns(inlineTextToMarkChunksWithContext(getMarkBuilders(), text, {
2449
2453
  resolveFileLink: context.resolveFileLink,
2450
2454
  resolveWikiEmbed: context.resolveWikiEmbed
2455
+ }, {
2456
+ referenceDefinitions: context.referenceDefinitions,
2457
+ isReferenceDefinition: context.referenceDefinitionNodes.has(node)
2451
2458
  }).map(([from, to, marks]) => ({
2452
2459
  text: text.slice(from, to),
2453
2460
  marks: Mark.setFrom(marks)
2454
2461
  })), 0, context);
2455
2462
  }
2456
2463
  function renderBlock(node, context) {
2464
+ if (context.referenceDefinitionNodes.has(node)) return null;
2457
2465
  const key = context.keyCounter.value++;
2458
2466
  const typeName = node.type.name;
2459
2467
  let handleTaskClick;
@@ -2518,6 +2526,7 @@ function renderBlock(node, context) {
2518
2526
  function MarkdownView({ markdown, markMode = "hide", frontmatter = false, interactive = true, expandCollapsed = false, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }) {
2519
2527
  const content = useMemo(() => {
2520
2528
  const doc = markdownToDoc(markdown, { frontmatter });
2529
+ const referenceIndex = collectReferenceDefinitions(doc);
2521
2530
  const context = {
2522
2531
  interactive,
2523
2532
  expandCollapsed,
@@ -2530,6 +2539,8 @@ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, intera
2530
2539
  onImageClick: interactive ? onImageClick : void 0,
2531
2540
  onFileClick: interactive ? onFileClick : void 0,
2532
2541
  onTaskClick: interactive ? onTaskClick : void 0,
2542
+ referenceDefinitions: referenceIndex.definitions,
2543
+ referenceDefinitionNodes: referenceIndex.nodes,
2533
2544
  taskCounter: { value: 0 },
2534
2545
  keyCounter: { value: 0 }
2535
2546
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.57.2",
4
+ "version": "0.58.0",
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.57.2"
34
+ "@meowdown/core": "0.58.0"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "react": "^19.0.0",