@meowdown/react 0.45.1 → 0.46.1

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
@@ -60,12 +60,18 @@ Slash menu host items can include `keywords` to match hidden terms without chang
60
60
 
61
61
  Mount `WikilinkHoverCard` inside `MeowdownEditor` and render host-owned preview
62
62
  content from the hovered wiki link's `target`. Returning `null` renders no
63
- card.
63
+ card. The render function may also return a promise: the card stays closed
64
+ until it resolves, resolving to `null` (or rejecting) renders no card, and a
65
+ result that lands after the pointer moved on is discarded, so a host can look
66
+ up local content without ever flashing an empty card.
64
67
 
65
68
  ```tsx
66
69
  <MeowdownEditor initialMarkdown="See [[Project plan]]">
67
70
  <WikilinkHoverCard>
68
- {(hit) => <LocalNotePreview key={hit.target} target={hit.target} />}
71
+ {async (hit) => {
72
+ const note = await readLocalNote(hit.target)
73
+ return note == null ? null : <LocalNotePreview note={note} />
74
+ }}
69
75
  </WikilinkHoverCard>
70
76
  </MeowdownEditor>
71
77
  ```
package/dist/index.d.ts CHANGED
@@ -446,9 +446,13 @@ declare function MarkdownView({ markdown, markMode, frontmatter, interactive, re
446
446
  interface WikilinkHoverCardProps {
447
447
  /**
448
448
  * Render the card body from the hovered wiki link. Returning `null` renders
449
- * no card.
449
+ * no card. A returned promise keeps the card closed until it resolves;
450
+ * resolving to `null` or rejecting renders no card, and a result that lands
451
+ * after the pointer moved on is discarded. The function runs once per
452
+ * hovered link rather than on every render, and a new function identity
453
+ * re-runs it for the current link.
450
454
  */
451
- readonly children: (hit: WikilinkHoverHit) => ReactNode;
455
+ readonly children: (hit: WikilinkHoverHit) => ReactNode | Promise<ReactNode>;
452
456
  /** Optional class applied to the popup, after the default card surface. */
453
457
  readonly className?: string;
454
458
  }
package/dist/index.js CHANGED
@@ -2302,7 +2302,7 @@ var wikilink_hover_card_module_default = {
2302
2302
  //#endregion
2303
2303
  //#region src/components/wikilink-hover-card.tsx
2304
2304
  const OPEN_DELAY = 300;
2305
- const CLOSE_DELAY = 200;
2305
+ const CLOSE_DELAY = 100;
2306
2306
  /**
2307
2307
  * Show host-rendered content after a 300ms dwell over a rendered wiki link.
2308
2308
  */
@@ -2311,6 +2311,7 @@ function WikilinkHoverCard({ children, className }) {
2311
2311
  const lastRectRef = useRef(null);
2312
2312
  const [displayed, setDisplayed] = useState();
2313
2313
  const [open, setOpen] = useState(false);
2314
+ const [body, setBody] = useState(null);
2314
2315
  const [hoverExtension] = useState(() => {
2315
2316
  return defineWikilinkHoverHandler((nextHit) => setHit(nextHit));
2316
2317
  });
@@ -2323,10 +2324,31 @@ function WikilinkHoverCard({ children, className }) {
2323
2324
  const anchor = useMemo(() => {
2324
2325
  return { getBoundingClientRect: getRect };
2325
2326
  }, [getRect]);
2327
+ useEffect(() => {
2328
+ let stale = false;
2329
+ const resolveBody = async () => {
2330
+ try {
2331
+ const resolved = await (displayed ? children(displayed) : null);
2332
+ if (!stale) setBody(resolved);
2333
+ } catch (error) {
2334
+ if (stale) return;
2335
+ console.error("[meowdown] wikilink hover card body rejected:", error);
2336
+ setBody(null);
2337
+ }
2338
+ };
2339
+ resolveBody();
2340
+ return () => {
2341
+ stale = true;
2342
+ };
2343
+ }, [children, displayed]);
2326
2344
  const hasDisplayed = !!displayed;
2345
+ const hasBody = body != null;
2327
2346
  useEffect(() => {
2328
2347
  if (!hit) {
2329
- const timer = setTimeout(() => setOpen(false), CLOSE_DELAY);
2348
+ const timer = setTimeout(() => {
2349
+ setOpen(false);
2350
+ if (!hasBody) setDisplayed(void 0);
2351
+ }, hasBody ? CLOSE_DELAY : 0);
2330
2352
  return () => clearTimeout(timer);
2331
2353
  }
2332
2354
  const timer = setTimeout(() => {
@@ -2334,8 +2356,11 @@ function WikilinkHoverCard({ children, className }) {
2334
2356
  setOpen(true);
2335
2357
  }, hasDisplayed ? 0 : OPEN_DELAY);
2336
2358
  return () => clearTimeout(timer);
2337
- }, [hit, hasDisplayed]);
2338
- const body = displayed ? children(displayed) : null;
2359
+ }, [
2360
+ hit,
2361
+ hasDisplayed,
2362
+ hasBody
2363
+ ]);
2339
2364
  return /* @__PURE__ */ jsx(PreviewCard.Root, {
2340
2365
  open: open && body != null,
2341
2366
  onOpenChange: (nextOpen) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.45.1",
4
+ "version": "0.46.1",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "clsx": "^2.1.1",
27
27
  "lucide-react": "^1.21.0",
28
28
  "react-property": "^2.0.2",
29
- "@meowdown/core": "0.45.1"
29
+ "@meowdown/core": "0.46.1"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "^19.0.0",