@meowdown/react 0.69.0 → 0.70.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/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, WikilinkResolver } 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, XPostResolver, XPostResolver as XPostResolver$1, YouTubeVideoResolver, YouTubeVideoResolver as YouTubeVideoResolver$1 } from "@meowdown/core";
3
3
  import { SelectionJSON, SelectionJSON as SelectionJSON$1 } from "@prosekit/core";
4
4
  import { ReactNodeViewComponent, ReactNodeViewComponent as ReactNodeViewComponent$1, useEditor, useExtension, useKeymap } from "@prosekit/react";
5
5
  //#region src/utils/date-format.d.ts
@@ -408,6 +408,20 @@ interface EditorProps {
408
408
  * (e.g. from `useCallback`).
409
409
  */
410
410
  resolveFileInfo?: FileViewOptions['resolveFileInfo'];
411
+ /**
412
+ * Resolves the data behind an X post URL, directly or as a promise; the post
413
+ * renders as a `post-embed-x-post` card. Defaults to `defaultResolveXPost`,
414
+ * which fetches through react-tweet's hosted proxy. Pass a stable function
415
+ * (e.g. from `useCallback`).
416
+ */
417
+ resolveXPost?: XPostResolver$1;
418
+ /**
419
+ * Resolves the data behind a YouTube video URL, directly or as a promise;
420
+ * the video renders as a `post-embed-youtube-video` card. Defaults to
421
+ * `defaultResolveYouTubeVideo`, which reads YouTube's oEmbed endpoint. Pass
422
+ * a stable function (e.g. from `useCallback`).
423
+ */
424
+ resolveYouTubeVideo?: YouTubeVideoResolver$1;
411
425
  /**
412
426
  * Called when the user clicks a rendered file pill (or presses `Mod-Enter`
413
427
  * with the caret on one), with its `href`, `name`, and the originating
@@ -529,7 +543,7 @@ interface EditorProps {
529
543
  *
530
544
  * Callbacks and resolvers should be stable; pass them via `useCallback`.
531
545
  */
532
- 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, CodeBlockView, handleRef, children }: EditorProps): ReactElement;
546
+ 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, resolveXPost, resolveYouTubeVideo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, frontmatter, blockHandle, caretGlide, placeholder, readOnly, spellCheck, searchQuery, onSearchChange, timeFormat, editorClassName, wrapperClassName, CodeBlockView, handleRef, children }: EditorProps): ReactElement;
533
547
  //#endregion
534
548
  //#region src/components/markdown-view.d.ts
535
549
  /**
@@ -618,6 +632,16 @@ interface MarkdownViewProps {
618
632
  * Resolve metadata shown on a file pill.
619
633
  */
620
634
  resolveFileInfo?: FileInfoResolver;
635
+ /**
636
+ * Resolve the data behind an X post URL, rendered as a `post-embed-x-post`
637
+ * card. Defaults to `defaultResolveXPost`.
638
+ */
639
+ resolveXPost?: XPostResolver$1;
640
+ /**
641
+ * Resolve the data behind a YouTube video URL, rendered as a
642
+ * `post-embed-youtube-video` card. Defaults to `defaultResolveYouTubeVideo`.
643
+ */
644
+ resolveYouTubeVideo?: YouTubeVideoResolver$1;
621
645
  /**
622
646
  * Called when a rendered wikilink is clicked. Pass a stable function.
623
647
  */
@@ -654,7 +678,7 @@ interface MarkdownViewProps {
654
678
  * Callbacks (`onWikilinkClick`, etc.) and resolvers should be stable; pass them via
655
679
  * `useCallback` to avoid re-rendering the whole tree.
656
680
  */
657
- export declare function MarkdownView({ markdown, markMode, frontmatter, interactive, expandCollapsed, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }: MarkdownViewProps): ReactElement;
681
+ export declare function MarkdownView({ markdown, markMode, frontmatter, interactive, expandCollapsed, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, resolveXPost, resolveYouTubeVideo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }: MarkdownViewProps): ReactElement;
658
682
  //#endregion
659
683
  //#region src/components/wikilink-hover-card.d.ts
660
684
  /**
@@ -680,4 +704,4 @@ interface WikilinkHoverCardProps {
680
704
  */
681
705
  export declare function WikilinkHoverCard({ children, className }: WikilinkHoverCardProps): ReactNode;
682
706
  //#endregion
683
- export { type EditorHandle, type EditorMode, type EditorProps, type EditorStateSnapshot, type LinkPreview, type LinkPreviewResolver, type MarkdownViewProps, type PendingReplacementResolveHandler, type ReactNodeViewComponent, type SelectionHint, type SelectionJSON, type SelectionMenuContext, type SelectionMenuItem, type SelectionMenuSearchHandler, type SlashMenuItem, type SlashMenuSearchHandler, type TagItem, type TagSearchHandler, type TaskClickHandler, type TaskClickPayload, type TimeFormat, type WikilinkHoverCardProps, type WikilinkItem, type WikilinkSearchHandler, useEditor, useExtension, useKeymap };
707
+ export { type EditorHandle, type EditorMode, type EditorProps, type EditorStateSnapshot, type LinkPreview, type LinkPreviewResolver, type MarkdownViewProps, type PendingReplacementResolveHandler, type ReactNodeViewComponent, type SelectionHint, type SelectionJSON, type SelectionMenuContext, type SelectionMenuItem, type SelectionMenuSearchHandler, type SlashMenuItem, type SlashMenuSearchHandler, type TagItem, type TagSearchHandler, type TaskClickHandler, type TaskClickPayload, type TimeFormat, type WikilinkHoverCardProps, type WikilinkItem, type WikilinkSearchHandler, type XPostResolver, type YouTubeVideoResolver, useEditor, useExtension, useKeymap };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { clsx } from "clsx/lite";
2
2
  import { Fragment, cloneElement, createElement, memo, 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, defineSearchStatusHandler, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineVirtualCaret, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, docToMarkdown, formatFileSize, getCodeTokens, getFileKind, getLinkText, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunksWithContext, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, normalizeHref, renderMathInto } from "@meowdown/core";
3
+ import { buildFileMarkdown, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defaultResolveXPost, defaultResolveYouTubeVideo, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSearchStatusHandler, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineVirtualCaret, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, docToMarkdown, formatFileSize, getCodeTokens, getFileKind, getLinkText, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunksWithContext, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, loadKaTeX, markdownToDoc, matchPostEmbed, normalizeHref, parsePostEmbedSnapshot, 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";
@@ -15,6 +15,8 @@ import { Popover } from "@base-ui/react/popover";
15
15
  import { AutocompleteEmpty, AutocompleteItem, AutocompletePopup, AutocompletePositioner, AutocompleteRoot } from "@prosekit/react/autocomplete";
16
16
  import { MenuItem, MenuPopup, MenuPositioner } from "@prosekit/react/menu";
17
17
  import { TableHandleColumnMenuRoot, TableHandleColumnMenuTrigger, TableHandleColumnPopup, TableHandleColumnPositioner, TableHandleDragPreview, TableHandleDropIndicator, TableHandleRoot, TableHandleRowMenuRoot, TableHandleRowMenuTrigger, TableHandleRowPopup, TableHandleRowPositioner } from "@prosekit/react/table-handle";
18
+ import { registerXPost } from "@post-embed/elements/x";
19
+ import { registerYouTubeVideo } from "@post-embed/elements/youtube";
18
20
  import { Mark } from "@prosekit/pm/model";
19
21
  import { BOOLEAN, OVERLOADED_BOOLEAN, getPropertyInfo, possibleStandardNames } from "react-property";
20
22
  import { PreviewCard } from "@base-ui/react/preview-card";
@@ -401,7 +403,7 @@ function DropIndicator$1() {
401
403
 
402
404
  //#endregion
403
405
  //#region src/components/editor-extensions.tsx
404
- function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick, onTagClick, onExitBoundary, resolveImageUrl, resolveFileInfo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, placeholder, readOnly, wikilinkEnabled, spellCheck, searchQuery, onSearchChange, editorClassName }) {
406
+ function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick, onTagClick, onExitBoundary, resolveImageUrl, resolveFileInfo, resolveXPost, resolveYouTubeVideo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution, placeholder, readOnly, wikilinkEnabled, spellCheck, searchQuery, onSearchChange, editorClassName }) {
405
407
  const editor = useEditor$1();
406
408
  useLayoutEffect(() => {
407
409
  editor.commands.setMarkMode(markMode);
@@ -458,8 +460,16 @@ function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick,
458
460
  return onExitBoundary ? defineExitBoundaryHandler(onExitBoundary) : null;
459
461
  }, [onExitBoundary]));
460
462
  useExtension$1(useMemo(() => {
461
- return defineImage({ resolveImageUrl });
462
- }, [resolveImageUrl]));
463
+ return defineImage({
464
+ resolveImageUrl,
465
+ resolveXPost,
466
+ resolveYouTubeVideo
467
+ });
468
+ }, [
469
+ resolveImageUrl,
470
+ resolveXPost,
471
+ resolveYouTubeVideo
472
+ ]));
463
473
  useExtension$1(useMemo(() => {
464
474
  return defineFileView({ resolveFileInfo });
465
475
  }, [resolveFileInfo]));
@@ -1925,7 +1935,7 @@ function findHeadingPosition(doc, fragment) {
1925
1935
  });
1926
1936
  return match;
1927
1937
  }
1928
- 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, CodeBlockView, ref, children }) {
1938
+ 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, resolveXPost, resolveYouTubeVideo, onFileClick, onFilePaste, onFileSaveError, onImageClick, embedPaste, linkPaste, bulletAfterHeading, substitution = true, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, searchQuery = "", onSearchChange, timeFormat, editorClassName, CodeBlockView, ref, children }) {
1929
1939
  const [editor] = useState(() => {
1930
1940
  const baseExtension = defineEditorExtension({
1931
1941
  resolveFileLink,
@@ -2092,6 +2102,8 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onSl
2092
2102
  onExitBoundary,
2093
2103
  resolveImageUrl,
2094
2104
  resolveFileInfo,
2105
+ resolveXPost,
2106
+ resolveYouTubeVideo,
2095
2107
  onFileClick,
2096
2108
  onFilePaste,
2097
2109
  onFileSaveError,
@@ -2150,7 +2162,7 @@ const CARET_GLIDE_OFF = { "--meowdown-caret-glide": "0ms" };
2150
2162
  *
2151
2163
  * Callbacks and resolvers should be stable; pass them via `useCallback`.
2152
2164
  */
2153
- 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, CodeBlockView, handleRef, children }) {
2165
+ 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, resolveXPost, resolveYouTubeVideo, 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, CodeBlockView, handleRef, children }) {
2154
2166
  const childRef = useRef(null);
2155
2167
  useImperativeHandle(handleRef, () => {
2156
2168
  function getMarkdown() {
@@ -2269,6 +2281,8 @@ function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onSlashM
2269
2281
  resolveWikiEmbed,
2270
2282
  resolveWikilink,
2271
2283
  resolveFileInfo,
2284
+ resolveXPost,
2285
+ resolveYouTubeVideo,
2272
2286
  onFileClick,
2273
2287
  onFilePaste,
2274
2288
  onFileSaveError,
@@ -2420,44 +2434,45 @@ function WikilinkChip(props) {
2420
2434
  })]
2421
2435
  });
2422
2436
  }
2423
- function EmbedFrame(props) {
2424
- const { embed, width, height } = props;
2425
- const iframeRef = useRef(null);
2426
- useEffect(() => {
2427
- if (embed.kind !== "tweet") return;
2428
- const iframe = iframeRef.current;
2429
- if (!iframe) return;
2430
- return listenForTweetHeight(iframe);
2431
- }, [embed.kind, embed.key]);
2432
- const youtubeWidth = embed.kind === "youtube" ? width : null;
2433
- const tweetHeight = embed.kind === "tweet" ? height : null;
2437
+ function PostEmbed(props) {
2438
+ const { kind, src, width, snapshot, resolveXPost, resolveYouTubeVideo } = props;
2439
+ registerXPost();
2440
+ registerYouTubeVideo();
2441
+ const saved = snapshot == null ? void 0 : parsePostEmbedSnapshot(snapshot);
2434
2442
  return /* @__PURE__ */ jsx("span", {
2435
2443
  className: "md-image-view-preview md-atom-view-preview",
2436
2444
  contentEditable: false,
2437
- children: /* @__PURE__ */ jsx("iframe", {
2438
- ref: iframeRef,
2439
- src: embed.src,
2440
- title: embed.title,
2441
- className: embed.className,
2442
- "data-testid": embed.testid,
2443
- loading: "lazy",
2444
- referrerPolicy: "strict-origin-when-cross-origin",
2445
- frameBorder: "0",
2446
- allow: embed.allow,
2447
- allowFullScreen: embed.allowFullscreen,
2448
- style: youtubeWidth != null ? { width: youtubeWidth } : tweetHeight != null ? { height: tweetHeight } : void 0,
2449
- "data-sized": tweetHeight == null ? void 0 : ""
2450
- }, embed.key)
2445
+ "data-testid": `${kind}-embed`,
2446
+ children: kind === "x-post" ? createElement("post-embed-x-post", {
2447
+ data: saved?.kind === "x-post" ? saved.data : null,
2448
+ url: src,
2449
+ resolver: resolveXPost
2450
+ }) : createElement("post-embed-youtube-video", {
2451
+ data: saved?.kind === "youtube-video" ? saved.data : null,
2452
+ url: src,
2453
+ resolver: resolveYouTubeVideo,
2454
+ playback: "inline",
2455
+ style: width == null ? void 0 : {
2456
+ width,
2457
+ maxWidth: "none"
2458
+ }
2459
+ })
2451
2460
  });
2452
2461
  }
2453
2462
  function ImagePreview(props) {
2454
- const { src, alt, width, height, resolveImageUrl, onImageClick, interactive } = props;
2455
- const embed = matchEmbed(src);
2456
- if (embed) return interactive ? /* @__PURE__ */ jsx(EmbedFrame, {
2457
- embed,
2458
- width,
2459
- height
2460
- }) : null;
2463
+ const { src, alt, width, snapshot, resolveImageUrl, resolveXPost, resolveYouTubeVideo, onImageClick, interactive } = props;
2464
+ const kind = matchPostEmbed(src);
2465
+ if (kind) {
2466
+ if (!interactive) return null;
2467
+ return /* @__PURE__ */ jsx(PostEmbed, {
2468
+ kind,
2469
+ src,
2470
+ width,
2471
+ snapshot,
2472
+ resolveXPost: resolveXPost ?? defaultResolveXPost,
2473
+ resolveYouTubeVideo: resolveYouTubeVideo ?? defaultResolveYouTubeVideo
2474
+ }, src);
2475
+ }
2461
2476
  const url = (resolveImageUrl ?? defaultResolveImageUrl)(src);
2462
2477
  if (!url) return null;
2463
2478
  return /* @__PURE__ */ jsx("span", {
@@ -2481,15 +2496,17 @@ function ImagePreview(props) {
2481
2496
  });
2482
2497
  }
2483
2498
  function ImageView(props) {
2484
- const { src, alt, width, height, context, children } = props;
2499
+ const { src, alt, width, snapshot, context, children } = props;
2485
2500
  return /* @__PURE__ */ jsxs("span", {
2486
2501
  className: "md-image-view md-atom-view",
2487
2502
  children: [/* @__PURE__ */ jsx(ImagePreview, {
2488
2503
  src,
2489
2504
  alt,
2490
2505
  width,
2491
- height,
2506
+ snapshot,
2492
2507
  resolveImageUrl: context.resolveImageUrl,
2508
+ resolveXPost: context.resolveXPost,
2509
+ resolveYouTubeVideo: context.resolveYouTubeVideo,
2493
2510
  onImageClick: context.onImageClick,
2494
2511
  interactive: context.interactive
2495
2512
  }), /* @__PURE__ */ jsx("span", {
@@ -2685,7 +2702,7 @@ function wrapMark(mark, children, context) {
2685
2702
  src: attrs.src,
2686
2703
  alt: attrs.alt,
2687
2704
  width: attrs.width,
2688
- height: attrs.height,
2705
+ snapshot: attrs.snapshot,
2689
2706
  context,
2690
2707
  children
2691
2708
  });
@@ -2896,7 +2913,7 @@ const MarkdownBlock = memo(function MarkdownBlock({ node, taskBase, context, ref
2896
2913
  * Callbacks (`onWikilinkClick`, etc.) and resolvers should be stable; pass them via
2897
2914
  * `useCallback` to avoid re-rendering the whole tree.
2898
2915
  */
2899
- function MarkdownView({ markdown, markMode = "hide", frontmatter = false, interactive = true, expandCollapsed = false, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }) {
2916
+ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, interactive = true, expandCollapsed = false, resolveImageUrl, resolveFileLink, resolveWikiEmbed, resolveWikilink, resolveFileInfo, resolveXPost, resolveYouTubeVideo, onWikilinkClick, onLinkClick, onImageClick, onFileClick, onTaskClick, className }) {
2900
2917
  const context = useMemo(() => ({
2901
2918
  interactive,
2902
2919
  expandCollapsed,
@@ -2905,6 +2922,8 @@ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, intera
2905
2922
  resolveWikiEmbed,
2906
2923
  resolveWikilink,
2907
2924
  resolveFileInfo,
2925
+ resolveXPost,
2926
+ resolveYouTubeVideo,
2908
2927
  onWikilinkClick: interactive ? onWikilinkClick : void 0,
2909
2928
  onLinkClick: interactive ? onLinkClick : void 0,
2910
2929
  onImageClick: interactive ? onImageClick : void 0,
@@ -2918,6 +2937,8 @@ function MarkdownView({ markdown, markMode = "hide", frontmatter = false, intera
2918
2937
  resolveWikiEmbed,
2919
2938
  resolveWikilink,
2920
2939
  resolveFileInfo,
2940
+ resolveXPost,
2941
+ resolveYouTubeVideo,
2921
2942
  onWikilinkClick,
2922
2943
  onLinkClick,
2923
2944
  onImageClick,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.69.0",
4
+ "version": "0.70.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -23,6 +23,8 @@
23
23
  "dependencies": {
24
24
  "@base-ui/react": "^1.7.0",
25
25
  "@ocavue/utils": "^1.8.0",
26
+ "@post-embed/elements": "^0.2.0",
27
+ "@post-embed/types": "^0.2.0",
26
28
  "@prosekit/core": "^0.13.2",
27
29
  "@prosekit/pm": "^0.1.19",
28
30
  "@prosekit/react": "^0.8.2",
@@ -31,7 +33,7 @@
31
33
  "github-slugger": "^2.0.0",
32
34
  "lucide-react": "^1.38.0",
33
35
  "react-property": "^2.0.2",
34
- "@meowdown/core": "0.69.0"
36
+ "@meowdown/core": "0.70.0"
35
37
  },
36
38
  "peerDependencies": {
37
39
  "react": "^19.0.0",