@meowdown/react 0.33.1 → 0.34.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
@@ -226,7 +226,8 @@ interface EditorProps {
226
226
  selectionMenuAffordance?: boolean;
227
227
  /**
228
228
  * Extra controls rendered in the pending-replacement preview footer, next to
229
- * the built-in Accept and Discard buttons (e.g. a retry button).
229
+ * the built-in accept ("Replace selection" / "Insert below", per the staged
230
+ * mode) and Discard buttons (e.g. a retry button).
230
231
  */
231
232
  pendingReplacementActions?: ReactNode;
232
233
  /**
package/dist/index.js CHANGED
@@ -577,10 +577,27 @@ var pending_replacement_preview_module_default = {
577
577
  //#endregion
578
578
  //#region src/components/pending-replacement-preview.tsx
579
579
  /**
580
+ * Vertical room (px) the popover needs under its anchor: the text area's
581
+ * 14rem max-height plus the footer, borders, and the anchor offset.
582
+ */
583
+ const PREVIEW_CLEARANCE = 320;
584
+ /** Minimum gap (px) kept above the anchor line when scrolling to make room. */
585
+ const SCROLL_TOP_MARGIN = 16;
586
+ /** The nearest ancestor that can scroll vertically, or the page scroller. */
587
+ function closestScrollable(element) {
588
+ for (let node = element.parentElement; node; node = node.parentElement) {
589
+ const { overflowY } = getComputedStyle(node);
590
+ if (/(auto|scroll|overlay)/.test(overflowY) && node.scrollHeight > node.clientHeight) return node;
591
+ }
592
+ return document.scrollingElement;
593
+ }
594
+ /**
580
595
  * The preview for a staged (pending) replacement: a popover anchored to the
581
- * source range showing the accumulated text, with Accept and Discard controls
582
- * plus a host-provided `actions` slot. Dismissing the popover (Escape or an
583
- * outside press) discards the stage; the document is only touched on accept.
596
+ * end of the source range showing the accumulated text, with a Discard control
597
+ * and an accept control labeled by what accepting does ("Replace selection" or
598
+ * "Insert below", per the staged mode), plus a host-provided `actions` slot.
599
+ * Dismissing the popover (Escape or an outside press) discards the stage; the
600
+ * document is only touched on accept.
584
601
  */
585
602
  function PendingReplacementPreview({ actions, onResolve }) {
586
603
  const editor = useEditor$1();
@@ -594,19 +611,35 @@ function PendingReplacementPreview({ actions, onResolve }) {
594
611
  }
595
612
  });
596
613
  }, [onResolve]));
597
- const from = pending?.from;
598
614
  const to = pending?.to;
599
615
  const anchor = useMemo(() => {
600
- if (from == null || to == null) return;
616
+ if (to == null) return;
601
617
  return getVirtualElementFromRange(editor.view, {
602
- from,
618
+ from: to,
603
619
  to
604
620
  });
605
- }, [
606
- from,
607
- to,
608
- editor
609
- ]);
621
+ }, [to, editor]);
622
+ const staged = pending !== null;
623
+ useEffect(() => {
624
+ if (!staged) return;
625
+ const view = editor.view;
626
+ const position = getPendingReplacement(view.state)?.to;
627
+ if (position == null) return;
628
+ const clearanceBottom = window.innerHeight - PREVIEW_CLEARANCE;
629
+ let coords = view.coordsAtPos(position);
630
+ if (coords.top >= 0 && coords.bottom <= clearanceBottom) return;
631
+ const { node } = view.domAtPos(position);
632
+ const element = node instanceof Element ? node : node.parentElement;
633
+ if (!element) return;
634
+ element.scrollIntoView({ block: "center" });
635
+ coords = view.coordsAtPos(position);
636
+ const overflow = coords.bottom - clearanceBottom;
637
+ const nudge = Math.min(overflow, Math.max(0, coords.top - SCROLL_TOP_MARGIN));
638
+ if (nudge > 0) {
639
+ const scroller = closestScrollable(element);
640
+ if (scroller) scroller.scrollTop += nudge;
641
+ }
642
+ }, [staged, editor]);
610
643
  if (!pending) return null;
611
644
  const discard = () => {
612
645
  editor.commands.discardPendingReplacement();
@@ -656,7 +689,7 @@ function PendingReplacementPreview({ actions, onResolve }) {
656
689
  "data-testid": "pending-replacement-accept",
657
690
  disabled: !pending.text.trim(),
658
691
  onClick: accept,
659
- children: "Accept"
692
+ children: pending.mode === "replace" ? "Replace selection" : "Insert below"
660
693
  })
661
694
  ]
662
695
  })]
package/dist/style.css CHANGED
@@ -346,7 +346,7 @@
346
346
  }
347
347
  .meow_Positioner_DPJ5ia {
348
348
  z-index: 50;
349
- width: min(24rem, 100vw - 1rem);
349
+ width: min(30rem, 100vw - 1rem);
350
350
  display: block;
351
351
  }
352
352
 
@@ -377,6 +377,7 @@
377
377
 
378
378
  .meow_Footer_DPJ5ia {
379
379
  border-top: 1px solid var(--meowdown-border);
380
+ flex-wrap: wrap;
380
381
  align-items: center;
381
382
  gap: .25rem;
382
383
  padding: .375rem;
@@ -389,6 +390,7 @@
389
390
 
390
391
  .meow_Button_DPJ5ia {
391
392
  color: var(--meowdown-text);
393
+ white-space: nowrap;
392
394
  cursor: pointer;
393
395
  border-radius: .5rem;
394
396
  align-items: center;
@@ -403,6 +405,7 @@
403
405
  .meow_AcceptButton_DPJ5ia {
404
406
  color: var(--meowdown-popover-bg);
405
407
  background: var(--meowdown-accent);
408
+ white-space: nowrap;
406
409
  cursor: pointer;
407
410
  border-radius: .5rem;
408
411
  align-items: center;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.33.1",
4
+ "version": "0.34.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -20,12 +20,12 @@
20
20
  "dependencies": {
21
21
  "@base-ui/react": "^1.6.0",
22
22
  "@ocavue/utils": "^1.7.0",
23
- "@prosekit/core": "^0.13.0-beta.4",
24
- "@prosekit/pm": "^0.1.19-beta.1",
25
- "@prosekit/react": "^0.8.0-beta.15",
23
+ "@prosekit/core": "^0.13.0-beta.5",
24
+ "@prosekit/pm": "^0.1.19-beta.2",
25
+ "@prosekit/react": "^0.8.0-beta.16",
26
26
  "clsx": "^2.1.1",
27
27
  "lucide-react": "^1.21.0",
28
- "@meowdown/core": "0.33.1"
28
+ "@meowdown/core": "0.34.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "react": "^19.0.0",