@meowdown/react 0.33.0 → 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 +2 -1
- package/dist/index.js +51 -16
- package/dist/style.css +4 -1
- package/package.json +5 -5
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
|
|
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
|
@@ -493,11 +493,13 @@ function LinkMenu({ onLinkClick, onLinkCopy }) {
|
|
|
493
493
|
let rangeFrom;
|
|
494
494
|
let rangeTo;
|
|
495
495
|
if (edit) {
|
|
496
|
-
|
|
497
|
-
|
|
496
|
+
const anchorRange = edit.link?.label ?? edit;
|
|
497
|
+
rangeFrom = anchorRange.from;
|
|
498
|
+
rangeTo = anchorRange.to;
|
|
498
499
|
} else if (hover) {
|
|
499
|
-
|
|
500
|
-
|
|
500
|
+
const anchorRange = hover.label ?? hover.unit;
|
|
501
|
+
rangeFrom = anchorRange.from;
|
|
502
|
+
rangeTo = anchorRange.to;
|
|
501
503
|
}
|
|
502
504
|
const anchor = useMemo(() => {
|
|
503
505
|
if (rangeFrom == null || rangeTo == null) return;
|
|
@@ -575,10 +577,27 @@ var pending_replacement_preview_module_default = {
|
|
|
575
577
|
//#endregion
|
|
576
578
|
//#region src/components/pending-replacement-preview.tsx
|
|
577
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
|
+
/**
|
|
578
595
|
* The preview for a staged (pending) replacement: a popover anchored to the
|
|
579
|
-
* source range showing the accumulated text, with
|
|
580
|
-
*
|
|
581
|
-
*
|
|
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.
|
|
582
601
|
*/
|
|
583
602
|
function PendingReplacementPreview({ actions, onResolve }) {
|
|
584
603
|
const editor = useEditor$1();
|
|
@@ -592,19 +611,35 @@ function PendingReplacementPreview({ actions, onResolve }) {
|
|
|
592
611
|
}
|
|
593
612
|
});
|
|
594
613
|
}, [onResolve]));
|
|
595
|
-
const from = pending?.from;
|
|
596
614
|
const to = pending?.to;
|
|
597
615
|
const anchor = useMemo(() => {
|
|
598
|
-
if (
|
|
616
|
+
if (to == null) return;
|
|
599
617
|
return getVirtualElementFromRange(editor.view, {
|
|
600
|
-
from,
|
|
618
|
+
from: to,
|
|
601
619
|
to
|
|
602
620
|
});
|
|
603
|
-
}, [
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
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]);
|
|
608
643
|
if (!pending) return null;
|
|
609
644
|
const discard = () => {
|
|
610
645
|
editor.commands.discardPendingReplacement();
|
|
@@ -654,7 +689,7 @@ function PendingReplacementPreview({ actions, onResolve }) {
|
|
|
654
689
|
"data-testid": "pending-replacement-accept",
|
|
655
690
|
disabled: !pending.text.trim(),
|
|
656
691
|
onClick: accept,
|
|
657
|
-
children: "
|
|
692
|
+
children: pending.mode === "replace" ? "Replace selection" : "Insert below"
|
|
658
693
|
})
|
|
659
694
|
]
|
|
660
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(
|
|
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.
|
|
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.
|
|
24
|
-
"@prosekit/pm": "^0.1.19-beta.
|
|
25
|
-
"@prosekit/react": "^0.8.0-beta.
|
|
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.
|
|
28
|
+
"@meowdown/core": "0.34.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"react": "^19.0.0",
|