@ohhwells/bridge 0.1.29-next.24 → 0.1.29-next.26
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 +2 -2
- package/dist/index.cjs +325 -168
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -9
- package/dist/index.d.ts +4 -9
- package/dist/index.js +340 -183
- package/dist/index.js.map +1 -1
- package/dist/styles.css +50 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4489,26 +4489,135 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
4489
4489
|
tick();
|
|
4490
4490
|
}
|
|
4491
4491
|
|
|
4492
|
-
// src/ui/
|
|
4493
|
-
function calcPopoverPos(rect, parentScroll, approxW = 483, approxH = 320) {
|
|
4494
|
-
const GAP = 8;
|
|
4495
|
-
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
4496
|
-
const visibleTop = rect.top - canvasTopInIframe;
|
|
4497
|
-
let top = rect.top - GAP;
|
|
4498
|
-
let transform = "translateX(-50%) translateY(-100%)";
|
|
4499
|
-
if (visibleTop < approxH + GAP) {
|
|
4500
|
-
top = rect.bottom + GAP;
|
|
4501
|
-
transform = "translateX(-50%)";
|
|
4502
|
-
}
|
|
4503
|
-
const rawLeft = rect.left + rect.width / 2;
|
|
4504
|
-
const left = Math.max(GAP + approxW / 2, Math.min(rawLeft, window.innerWidth - GAP - approxW / 2));
|
|
4505
|
-
return { top, left, transform };
|
|
4506
|
-
}
|
|
4507
|
-
|
|
4508
|
-
// src/ui/button.tsx
|
|
4492
|
+
// src/ui/dialog.tsx
|
|
4509
4493
|
var React3 = __toESM(require("react"), 1);
|
|
4510
4494
|
var import_radix_ui3 = require("radix-ui");
|
|
4495
|
+
|
|
4496
|
+
// src/ui/icons.tsx
|
|
4511
4497
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
4498
|
+
function IconX({ className, ...props }) {
|
|
4499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4500
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6 6 18" }),
|
|
4501
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 6 12 12" })
|
|
4502
|
+
] });
|
|
4503
|
+
}
|
|
4504
|
+
function IconChevronDown({ className, ...props }) {
|
|
4505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
4506
|
+
}
|
|
4507
|
+
function IconFile({ className, ...props }) {
|
|
4508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4509
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
4510
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4511
|
+
] });
|
|
4512
|
+
}
|
|
4513
|
+
function IconInfo({ className, ...props }) {
|
|
4514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4515
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4516
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 16v-4" }),
|
|
4517
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 8h.01" })
|
|
4518
|
+
] });
|
|
4519
|
+
}
|
|
4520
|
+
function IconArrowRight({ className, ...props }) {
|
|
4521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4522
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M5 12h14" }),
|
|
4523
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
4524
|
+
] });
|
|
4525
|
+
}
|
|
4526
|
+
function IconSection({ className, ...props }) {
|
|
4527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4528
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4529
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4530
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4531
|
+
] });
|
|
4532
|
+
}
|
|
4533
|
+
|
|
4534
|
+
// src/ui/dialog.tsx
|
|
4535
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4536
|
+
function Dialog2({ ...props }) {
|
|
4537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_radix_ui3.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
4538
|
+
}
|
|
4539
|
+
function DialogPortal({ ...props }) {
|
|
4540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_radix_ui3.Dialog.Portal, { ...props });
|
|
4541
|
+
}
|
|
4542
|
+
function DialogOverlay({
|
|
4543
|
+
className,
|
|
4544
|
+
...props
|
|
4545
|
+
}) {
|
|
4546
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4547
|
+
import_radix_ui3.Dialog.Overlay,
|
|
4548
|
+
{
|
|
4549
|
+
"data-slot": "dialog-overlay",
|
|
4550
|
+
"data-ohw-link-modal-root": "",
|
|
4551
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
4552
|
+
...props
|
|
4553
|
+
}
|
|
4554
|
+
);
|
|
4555
|
+
}
|
|
4556
|
+
var DialogContent = React3.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
4557
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
4558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
4559
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
4560
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
4561
|
+
import_radix_ui3.Dialog.Content,
|
|
4562
|
+
{
|
|
4563
|
+
ref,
|
|
4564
|
+
"data-slot": "dialog-content",
|
|
4565
|
+
className: cn(
|
|
4566
|
+
positionMode,
|
|
4567
|
+
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[483px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden",
|
|
4568
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
4569
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
4570
|
+
className
|
|
4571
|
+
),
|
|
4572
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
4573
|
+
...props,
|
|
4574
|
+
children: [
|
|
4575
|
+
children,
|
|
4576
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4577
|
+
import_radix_ui3.Dialog.Close,
|
|
4578
|
+
{
|
|
4579
|
+
type: "button",
|
|
4580
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
4581
|
+
"aria-label": "Close",
|
|
4582
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconX, { "aria-hidden": true })
|
|
4583
|
+
}
|
|
4584
|
+
) : null
|
|
4585
|
+
]
|
|
4586
|
+
}
|
|
4587
|
+
)
|
|
4588
|
+
] });
|
|
4589
|
+
});
|
|
4590
|
+
DialogContent.displayName = import_radix_ui3.Dialog.Content.displayName;
|
|
4591
|
+
function DialogHeader({ className, ...props }) {
|
|
4592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
4593
|
+
}
|
|
4594
|
+
function DialogFooter({ className, ...props }) {
|
|
4595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
4596
|
+
}
|
|
4597
|
+
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4598
|
+
import_radix_ui3.Dialog.Title,
|
|
4599
|
+
{
|
|
4600
|
+
ref,
|
|
4601
|
+
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
4602
|
+
...props
|
|
4603
|
+
}
|
|
4604
|
+
));
|
|
4605
|
+
DialogTitle.displayName = import_radix_ui3.Dialog.Title.displayName;
|
|
4606
|
+
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4607
|
+
import_radix_ui3.Dialog.Description,
|
|
4608
|
+
{
|
|
4609
|
+
ref,
|
|
4610
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
4611
|
+
...props
|
|
4612
|
+
}
|
|
4613
|
+
));
|
|
4614
|
+
DialogDescription.displayName = import_radix_ui3.Dialog.Description.displayName;
|
|
4615
|
+
var DialogClose = import_radix_ui3.Dialog.Close;
|
|
4616
|
+
|
|
4617
|
+
// src/ui/button.tsx
|
|
4618
|
+
var React4 = __toESM(require("react"), 1);
|
|
4619
|
+
var import_radix_ui4 = require("radix-ui");
|
|
4620
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
4512
4621
|
var buttonVariants = cva(
|
|
4513
4622
|
"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
|
|
4514
4623
|
{
|
|
@@ -4529,10 +4638,10 @@ var buttonVariants = cva(
|
|
|
4529
4638
|
}
|
|
4530
4639
|
}
|
|
4531
4640
|
);
|
|
4532
|
-
var Button =
|
|
4641
|
+
var Button = React4.forwardRef(
|
|
4533
4642
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4534
|
-
const Comp = asChild ?
|
|
4535
|
-
return /* @__PURE__ */ (0,
|
|
4643
|
+
const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
|
|
4644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4536
4645
|
Comp,
|
|
4537
4646
|
{
|
|
4538
4647
|
ref,
|
|
@@ -4545,76 +4654,38 @@ var Button = React3.forwardRef(
|
|
|
4545
4654
|
);
|
|
4546
4655
|
Button.displayName = "Button";
|
|
4547
4656
|
|
|
4548
|
-
// src/ui/icons.tsx
|
|
4549
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4550
|
-
function IconX({ className, ...props }) {
|
|
4551
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4552
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M18 6 6 18" }),
|
|
4553
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 6 12 12" })
|
|
4554
|
-
] });
|
|
4555
|
-
}
|
|
4556
|
-
function IconChevronDown({ className, ...props }) {
|
|
4557
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
4558
|
-
}
|
|
4559
|
-
function IconFile({ className, ...props }) {
|
|
4560
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4561
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
4562
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4563
|
-
] });
|
|
4564
|
-
}
|
|
4565
|
-
function IconInfo({ className, ...props }) {
|
|
4566
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4567
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4568
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 16v-4" }),
|
|
4569
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 8h.01" })
|
|
4570
|
-
] });
|
|
4571
|
-
}
|
|
4572
|
-
function IconArrowRight({ className, ...props }) {
|
|
4573
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4574
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5 12h14" }),
|
|
4575
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
4576
|
-
] });
|
|
4577
|
-
}
|
|
4578
|
-
function IconSection({ className, ...props }) {
|
|
4579
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4580
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4581
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4582
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4583
|
-
] });
|
|
4584
|
-
}
|
|
4585
|
-
|
|
4586
4657
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
4587
|
-
var
|
|
4658
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
4588
4659
|
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
4589
|
-
return /* @__PURE__ */ (0,
|
|
4590
|
-
/* @__PURE__ */ (0,
|
|
4591
|
-
/* @__PURE__ */ (0,
|
|
4592
|
-
/* @__PURE__ */ (0,
|
|
4593
|
-
/* @__PURE__ */ (0,
|
|
4594
|
-
/* @__PURE__ */ (0,
|
|
4660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
4661
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
4662
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
4663
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4664
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
4665
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
4595
4666
|
] }),
|
|
4596
|
-
/* @__PURE__ */ (0,
|
|
4597
|
-
/* @__PURE__ */ (0,
|
|
4598
|
-
/* @__PURE__ */ (0,
|
|
4599
|
-
/* @__PURE__ */ (0,
|
|
4667
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
4668
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
4669
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
4670
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
4600
4671
|
] })
|
|
4601
4672
|
] })
|
|
4602
4673
|
] });
|
|
4603
4674
|
}
|
|
4604
4675
|
|
|
4605
4676
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
4606
|
-
var
|
|
4677
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4607
4678
|
function SectionTreeItem({ section, onSelect, selected }) {
|
|
4608
4679
|
const interactive = Boolean(onSelect);
|
|
4609
|
-
return /* @__PURE__ */ (0,
|
|
4610
|
-
/* @__PURE__ */ (0,
|
|
4680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
4681
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4611
4682
|
"div",
|
|
4612
4683
|
{
|
|
4613
4684
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
4614
4685
|
"aria-hidden": true
|
|
4615
4686
|
}
|
|
4616
4687
|
),
|
|
4617
|
-
/* @__PURE__ */ (0,
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4618
4689
|
"div",
|
|
4619
4690
|
{
|
|
4620
4691
|
role: interactive ? "button" : void 0,
|
|
@@ -4632,8 +4703,8 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
4632
4703
|
interactive && selected && "border-primary"
|
|
4633
4704
|
),
|
|
4634
4705
|
children: [
|
|
4635
|
-
/* @__PURE__ */ (0,
|
|
4636
|
-
/* @__PURE__ */ (0,
|
|
4706
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
4707
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
4637
4708
|
]
|
|
4638
4709
|
}
|
|
4639
4710
|
)
|
|
@@ -4641,11 +4712,11 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
4641
4712
|
}
|
|
4642
4713
|
function SectionPickerList({ sections, onSelect }) {
|
|
4643
4714
|
if (sections.length === 0) {
|
|
4644
|
-
return /* @__PURE__ */ (0,
|
|
4715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
4645
4716
|
}
|
|
4646
|
-
return /* @__PURE__ */ (0,
|
|
4647
|
-
/* @__PURE__ */ (0,
|
|
4648
|
-
sections.map((section) => /* @__PURE__ */ (0,
|
|
4717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
4718
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
4719
|
+
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
4649
4720
|
] });
|
|
4650
4721
|
}
|
|
4651
4722
|
|
|
@@ -4653,11 +4724,11 @@ function SectionPickerList({ sections, onSelect }) {
|
|
|
4653
4724
|
var import_react3 = require("react");
|
|
4654
4725
|
|
|
4655
4726
|
// src/ui/input.tsx
|
|
4656
|
-
var
|
|
4657
|
-
var
|
|
4658
|
-
var Input =
|
|
4727
|
+
var React5 = __toESM(require("react"), 1);
|
|
4728
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4729
|
+
var Input = React5.forwardRef(
|
|
4659
4730
|
({ className, type, ...props }, ref) => {
|
|
4660
|
-
return /* @__PURE__ */ (0,
|
|
4731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4661
4732
|
"input",
|
|
4662
4733
|
{
|
|
4663
4734
|
type,
|
|
@@ -4675,11 +4746,11 @@ var Input = React4.forwardRef(
|
|
|
4675
4746
|
Input.displayName = "Input";
|
|
4676
4747
|
|
|
4677
4748
|
// src/ui/label.tsx
|
|
4678
|
-
var
|
|
4679
|
-
var
|
|
4749
|
+
var import_radix_ui5 = require("radix-ui");
|
|
4750
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4680
4751
|
function Label({ className, ...props }) {
|
|
4681
|
-
return /* @__PURE__ */ (0,
|
|
4682
|
-
|
|
4752
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4753
|
+
import_radix_ui5.Label.Root,
|
|
4683
4754
|
{
|
|
4684
4755
|
"data-slot": "label",
|
|
4685
4756
|
className: cn("text-sm font-medium leading-5 text-foreground", className),
|
|
@@ -4688,36 +4759,6 @@ function Label({ className, ...props }) {
|
|
|
4688
4759
|
);
|
|
4689
4760
|
}
|
|
4690
4761
|
|
|
4691
|
-
// src/ui/popover.tsx
|
|
4692
|
-
var import_radix_ui5 = require("radix-ui");
|
|
4693
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4694
|
-
function Popover({ ...props }) {
|
|
4695
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui5.Popover.Root, { "data-slot": "popover", ...props });
|
|
4696
|
-
}
|
|
4697
|
-
function PopoverTrigger({ ...props }) {
|
|
4698
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui5.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
4699
|
-
}
|
|
4700
|
-
function PopoverContent({
|
|
4701
|
-
className,
|
|
4702
|
-
align = "start",
|
|
4703
|
-
sideOffset = 6,
|
|
4704
|
-
...props
|
|
4705
|
-
}) {
|
|
4706
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui5.Popover.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4707
|
-
import_radix_ui5.Popover.Content,
|
|
4708
|
-
{
|
|
4709
|
-
"data-slot": "popover-content",
|
|
4710
|
-
align,
|
|
4711
|
-
sideOffset,
|
|
4712
|
-
className: cn(
|
|
4713
|
-
"z-[2147483647] w-[var(--radix-popover-trigger-width)] overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg outline-none",
|
|
4714
|
-
className
|
|
4715
|
-
),
|
|
4716
|
-
...props
|
|
4717
|
-
}
|
|
4718
|
-
) });
|
|
4719
|
-
}
|
|
4720
|
-
|
|
4721
4762
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
4722
4763
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4723
4764
|
function FieldChevron({ onClick }) {
|
|
@@ -4770,8 +4811,8 @@ function UrlOrPageInput({
|
|
|
4770
4811
|
);
|
|
4771
4812
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
4772
4813
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
4773
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4774
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.
|
|
4814
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative w-full", children: [
|
|
4815
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
4775
4816
|
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
4776
4817
|
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4777
4818
|
Input,
|
|
@@ -4804,20 +4845,28 @@ function UrlOrPageInput({
|
|
|
4804
4845
|
}
|
|
4805
4846
|
) : null,
|
|
4806
4847
|
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
4807
|
-
] })
|
|
4808
|
-
filteredPages.length > 0
|
|
4809
|
-
"
|
|
4848
|
+
] }),
|
|
4849
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4850
|
+
"div",
|
|
4810
4851
|
{
|
|
4811
|
-
|
|
4812
|
-
className: "
|
|
4813
|
-
|
|
4814
|
-
children:
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4852
|
+
"data-ohw-link-page-dropdown": "",
|
|
4853
|
+
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-10 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
4854
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4855
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4856
|
+
"button",
|
|
4857
|
+
{
|
|
4858
|
+
type: "button",
|
|
4859
|
+
className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
|
|
4860
|
+
onClick: () => onPageSelect(page),
|
|
4861
|
+
children: [
|
|
4862
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
4863
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate", children: page.title })
|
|
4864
|
+
]
|
|
4865
|
+
},
|
|
4866
|
+
page.path
|
|
4867
|
+
))
|
|
4868
|
+
}
|
|
4869
|
+
) : null
|
|
4821
4870
|
] }),
|
|
4822
4871
|
urlError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
4823
4872
|
] });
|
|
@@ -5012,17 +5061,16 @@ function LinkEditorPanel({
|
|
|
5012
5061
|
});
|
|
5013
5062
|
const isCancel = state.secondaryLabel === "Cancel";
|
|
5014
5063
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
5015
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5064
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5016
5065
|
"button",
|
|
5017
5066
|
{
|
|
5018
5067
|
type: "button",
|
|
5019
5068
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5020
|
-
onClick: state.handleClose,
|
|
5021
5069
|
"aria-label": "Close",
|
|
5022
5070
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconX, { "aria-hidden": true })
|
|
5023
5071
|
}
|
|
5024
|
-
),
|
|
5025
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5072
|
+
) }),
|
|
5073
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5026
5074
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5027
5075
|
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5028
5076
|
DestinationBreadcrumb,
|
|
@@ -5053,7 +5101,7 @@ function LinkEditorPanel({
|
|
|
5053
5101
|
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5054
5102
|
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5055
5103
|
] }),
|
|
5056
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
5104
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5057
5105
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5058
5106
|
Button,
|
|
5059
5107
|
{
|
|
@@ -5090,26 +5138,32 @@ function LinkEditorPanel({
|
|
|
5090
5138
|
// src/ui/link-modal/LinkPopover.tsx
|
|
5091
5139
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5092
5140
|
function LinkPopover({
|
|
5093
|
-
|
|
5094
|
-
parentScroll,
|
|
5141
|
+
open = true,
|
|
5095
5142
|
panelRef,
|
|
5143
|
+
portalContainer,
|
|
5144
|
+
onClose,
|
|
5096
5145
|
...editorProps
|
|
5097
5146
|
}) {
|
|
5098
|
-
const { top, left, transform } = calcPopoverPos(rect, parentScroll);
|
|
5099
5147
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5100
|
-
|
|
5148
|
+
Dialog2,
|
|
5101
5149
|
{
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5150
|
+
open,
|
|
5151
|
+
onOpenChange: (next) => {
|
|
5152
|
+
if (!next) onClose?.();
|
|
5153
|
+
},
|
|
5154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5155
|
+
DialogContent,
|
|
5156
|
+
{
|
|
5157
|
+
ref: panelRef,
|
|
5158
|
+
container: portalContainer,
|
|
5159
|
+
"data-ohw-link-popover-root": "",
|
|
5160
|
+
"data-ohw-link-modal-root": "",
|
|
5161
|
+
"data-ohw-bridge": "",
|
|
5162
|
+
showCloseButton: false,
|
|
5163
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5164
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5165
|
+
}
|
|
5166
|
+
)
|
|
5113
5167
|
}
|
|
5114
5168
|
);
|
|
5115
5169
|
}
|
|
@@ -5455,7 +5509,7 @@ function applyLinkByKey(key, val) {
|
|
|
5455
5509
|
}
|
|
5456
5510
|
function isInsideLinkEditor(target) {
|
|
5457
5511
|
return Boolean(
|
|
5458
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest('[data-slot="popover-content"]')
|
|
5512
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
5459
5513
|
);
|
|
5460
5514
|
}
|
|
5461
5515
|
function getHrefKeyFromElement(el) {
|
|
@@ -5636,15 +5690,57 @@ function GlowFrame({ rect, elRef }) {
|
|
|
5636
5690
|
}
|
|
5637
5691
|
);
|
|
5638
5692
|
}
|
|
5693
|
+
function getIframeVisibleClip(parentScroll) {
|
|
5694
|
+
if (!parentScroll) return null;
|
|
5695
|
+
const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
|
|
5696
|
+
const clipTop = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5697
|
+
const clipBottom = Math.min(
|
|
5698
|
+
window.innerHeight,
|
|
5699
|
+
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5700
|
+
);
|
|
5701
|
+
return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
|
|
5702
|
+
}
|
|
5703
|
+
function applyVisibleViewport(el, parentScroll) {
|
|
5704
|
+
const clip = getIframeVisibleClip(parentScroll);
|
|
5705
|
+
const top = clip?.top ?? 0;
|
|
5706
|
+
const height = clip ? clip.bottom - clip.top : window.innerHeight;
|
|
5707
|
+
el.style.top = `${top}px`;
|
|
5708
|
+
el.style.height = `${height}px`;
|
|
5709
|
+
}
|
|
5710
|
+
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
5711
|
+
const isAbove = transform.includes("translateY(-100%)");
|
|
5712
|
+
let visualTop = isAbove ? top - approxH : top;
|
|
5713
|
+
let visualBottom = isAbove ? top : top + approxH;
|
|
5714
|
+
const minTop = clip.top + gap;
|
|
5715
|
+
const maxBottom = clip.bottom - gap;
|
|
5716
|
+
if (visualTop >= minTop && visualBottom <= maxBottom) {
|
|
5717
|
+
return { top, transform };
|
|
5718
|
+
}
|
|
5719
|
+
const belowTop = rect.bottom + gap;
|
|
5720
|
+
if (belowTop + approxH <= maxBottom && belowTop >= minTop) {
|
|
5721
|
+
return { top: belowTop, transform: "translateX(-50%)" };
|
|
5722
|
+
}
|
|
5723
|
+
const aboveTop = rect.top - gap;
|
|
5724
|
+
if (aboveTop - approxH >= minTop && aboveTop <= maxBottom) {
|
|
5725
|
+
return { top: aboveTop, transform: "translateX(-50%) translateY(-100%)" };
|
|
5726
|
+
}
|
|
5727
|
+
if (belowTop + approxH <= maxBottom) {
|
|
5728
|
+
return { top: belowTop, transform: "translateX(-50%)" };
|
|
5729
|
+
}
|
|
5730
|
+
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
5731
|
+
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
5732
|
+
}
|
|
5639
5733
|
function calcToolbarPos(rect, parentScroll, approxW = 330) {
|
|
5640
5734
|
const GAP = 8;
|
|
5641
5735
|
const APPROX_H = 36;
|
|
5642
5736
|
const APPROX_W = approxW;
|
|
5737
|
+
const clip = getIframeVisibleClip(parentScroll);
|
|
5738
|
+
const clipTop = clip?.top ?? 0;
|
|
5643
5739
|
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
5644
5740
|
const visibleTop = rect.top - canvasTopInIframe;
|
|
5645
5741
|
const visibleBottom = rect.bottom - canvasTopInIframe;
|
|
5646
5742
|
const isTall = rect.height > APPROX_H + GAP;
|
|
5647
|
-
const spaceAbove = rect.top - (
|
|
5743
|
+
const spaceAbove = rect.top - (clipTop + GAP);
|
|
5648
5744
|
const fitsAbove = spaceAbove >= APPROX_H + GAP;
|
|
5649
5745
|
let top;
|
|
5650
5746
|
let transform;
|
|
@@ -5655,12 +5751,17 @@ function calcToolbarPos(rect, parentScroll, approxW = 330) {
|
|
|
5655
5751
|
top = rect.bottom + GAP;
|
|
5656
5752
|
transform = "translateX(-50%)";
|
|
5657
5753
|
} else if (visibleBottom > APPROX_H + GAP) {
|
|
5658
|
-
top =
|
|
5754
|
+
top = clipTop + GAP;
|
|
5659
5755
|
transform = "translateX(-50%)";
|
|
5660
5756
|
} else {
|
|
5661
5757
|
top = rect.bottom + GAP;
|
|
5662
5758
|
transform = "translateX(-50%)";
|
|
5663
5759
|
}
|
|
5760
|
+
if (clip) {
|
|
5761
|
+
const clamped = clampToolbarToClip(top, transform, rect, clip, APPROX_H, GAP);
|
|
5762
|
+
top = clamped.top;
|
|
5763
|
+
transform = clamped.transform;
|
|
5764
|
+
}
|
|
5664
5765
|
const rawLeft = rect.left + rect.width / 2;
|
|
5665
5766
|
const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
|
|
5666
5767
|
return { top, left, transform };
|
|
@@ -5975,6 +6076,13 @@ function OhhwellsBridge() {
|
|
|
5975
6076
|
const originalContentRef = (0, import_react5.useRef)(null);
|
|
5976
6077
|
const activeStateElRef = (0, import_react5.useRef)(null);
|
|
5977
6078
|
const parentScrollRef = (0, import_react5.useRef)(null);
|
|
6079
|
+
const visibleViewportRef = (0, import_react5.useRef)(null);
|
|
6080
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react5.useState)(null);
|
|
6081
|
+
const attachVisibleViewport = (0, import_react5.useCallback)((node) => {
|
|
6082
|
+
visibleViewportRef.current = node;
|
|
6083
|
+
setDialogPortalContainer(node);
|
|
6084
|
+
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6085
|
+
}, []);
|
|
5978
6086
|
const toolbarElRef = (0, import_react5.useRef)(null);
|
|
5979
6087
|
const glowElRef = (0, import_react5.useRef)(null);
|
|
5980
6088
|
const hoveredImageRef = (0, import_react5.useRef)(null);
|
|
@@ -6045,7 +6153,33 @@ function OhhwellsBridge() {
|
|
|
6045
6153
|
hoveredImageRef.current = null;
|
|
6046
6154
|
hoveredImageHasTextOverlapRef.current = false;
|
|
6047
6155
|
}
|
|
6156
|
+
hoveredGapRef.current = null;
|
|
6157
|
+
setSectionGap(null);
|
|
6048
6158
|
postToParent({ type: "ow:image-unhover" });
|
|
6159
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6160
|
+
const html = document.documentElement;
|
|
6161
|
+
const body = document.body;
|
|
6162
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6163
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6164
|
+
html.style.overflow = "hidden";
|
|
6165
|
+
body.style.overflow = "hidden";
|
|
6166
|
+
const preventBackgroundScroll = (e) => {
|
|
6167
|
+
const target = e.target;
|
|
6168
|
+
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6169
|
+
return;
|
|
6170
|
+
}
|
|
6171
|
+
e.preventDefault();
|
|
6172
|
+
};
|
|
6173
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6174
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6175
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6176
|
+
return () => {
|
|
6177
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6178
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6179
|
+
body.style.overflow = prevBodyOverflow;
|
|
6180
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6181
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6182
|
+
};
|
|
6049
6183
|
}, [linkPopover, postToParent]);
|
|
6050
6184
|
(0, import_react5.useEffect)(() => {
|
|
6051
6185
|
if (!isEditMode) return;
|
|
@@ -6300,6 +6434,12 @@ function OhhwellsBridge() {
|
|
|
6300
6434
|
(0, import_react5.useEffect)(() => {
|
|
6301
6435
|
postToParent({ type: "ow:navigation", path: pathname });
|
|
6302
6436
|
}, [pathname, postToParent]);
|
|
6437
|
+
(0, import_react5.useEffect)(() => {
|
|
6438
|
+
if (!isEditMode) return;
|
|
6439
|
+
setLinkPopover(null);
|
|
6440
|
+
deselectRef.current();
|
|
6441
|
+
deactivateRef.current();
|
|
6442
|
+
}, [pathname, isEditMode]);
|
|
6303
6443
|
(0, import_react5.useEffect)(() => {
|
|
6304
6444
|
if (!isEditMode) return;
|
|
6305
6445
|
const measure = () => {
|
|
@@ -6415,8 +6555,7 @@ function OhhwellsBridge() {
|
|
|
6415
6555
|
bumpLinkPopoverGrace();
|
|
6416
6556
|
setLinkPopoverRef.current({
|
|
6417
6557
|
key: editable.dataset.ohwKey ?? "",
|
|
6418
|
-
target: getLinkHref(editable)
|
|
6419
|
-
rect: editable.getBoundingClientRect()
|
|
6558
|
+
target: getLinkHref(editable)
|
|
6420
6559
|
});
|
|
6421
6560
|
return;
|
|
6422
6561
|
}
|
|
@@ -6616,7 +6755,7 @@ function OhhwellsBridge() {
|
|
|
6616
6755
|
}
|
|
6617
6756
|
return;
|
|
6618
6757
|
}
|
|
6619
|
-
if (topEl?.closest("[data-ohw-link-popover-root]") || topEl?.closest("[data-ohw-link-modal-root]")) {
|
|
6758
|
+
if (topEl?.closest("[data-ohw-link-popover-root]") || topEl?.closest("[data-ohw-link-modal-root]") || topEl?.closest("[data-ohw-link-page-dropdown]")) {
|
|
6620
6759
|
if (hoveredImageRef.current) {
|
|
6621
6760
|
hoveredImageRef.current = null;
|
|
6622
6761
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -6744,6 +6883,13 @@ function OhhwellsBridge() {
|
|
|
6744
6883
|
}
|
|
6745
6884
|
};
|
|
6746
6885
|
const probeSectionGapAt = (clientX, clientY, fromParentViewport = false) => {
|
|
6886
|
+
if (linkPopoverOpenRef.current) {
|
|
6887
|
+
if (hoveredGapRef.current) {
|
|
6888
|
+
hoveredGapRef.current = null;
|
|
6889
|
+
setSectionGap(null);
|
|
6890
|
+
}
|
|
6891
|
+
return;
|
|
6892
|
+
}
|
|
6747
6893
|
const { y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
6748
6894
|
const sections = Array.from(document.querySelectorAll("[data-ohw-section]")).sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);
|
|
6749
6895
|
const ZONE = 20;
|
|
@@ -7140,6 +7286,9 @@ function OhhwellsBridge() {
|
|
|
7140
7286
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
7141
7287
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
7142
7288
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
7289
|
+
if (visibleViewportRef.current) {
|
|
7290
|
+
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7291
|
+
}
|
|
7143
7292
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7144
7293
|
if (focusEl) applyToolbarPos(focusEl.getBoundingClientRect());
|
|
7145
7294
|
};
|
|
@@ -7191,6 +7340,12 @@ function OhhwellsBridge() {
|
|
|
7191
7340
|
window.addEventListener("message", handleParentScroll);
|
|
7192
7341
|
window.addEventListener("message", handlePointerSync);
|
|
7193
7342
|
window.addEventListener("message", handleClickAt);
|
|
7343
|
+
const handleViewportResize = () => {
|
|
7344
|
+
if (visibleViewportRef.current) {
|
|
7345
|
+
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7346
|
+
}
|
|
7347
|
+
};
|
|
7348
|
+
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
7194
7349
|
document.addEventListener("click", handleClick, true);
|
|
7195
7350
|
document.addEventListener("paste", handlePaste, true);
|
|
7196
7351
|
document.addEventListener("input", handleInput, true);
|
|
@@ -7228,6 +7383,7 @@ function OhhwellsBridge() {
|
|
|
7228
7383
|
window.removeEventListener("message", handleAnimLock);
|
|
7229
7384
|
window.removeEventListener("message", handleCanvasHeight);
|
|
7230
7385
|
window.removeEventListener("message", handleParentScroll);
|
|
7386
|
+
window.removeEventListener("resize", handleViewportResize);
|
|
7231
7387
|
window.removeEventListener("message", handlePointerSync);
|
|
7232
7388
|
window.removeEventListener("message", handleClickAt);
|
|
7233
7389
|
window.removeEventListener("message", handleHydrate);
|
|
@@ -7315,10 +7471,10 @@ function OhhwellsBridge() {
|
|
|
7315
7471
|
bumpLinkPopoverGrace();
|
|
7316
7472
|
setLinkPopover({
|
|
7317
7473
|
key: hrefCtx.key,
|
|
7318
|
-
target: getLinkHref(hrefCtx.anchor)
|
|
7319
|
-
rect: hrefCtx.anchor.getBoundingClientRect()
|
|
7474
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
7320
7475
|
});
|
|
7321
|
-
|
|
7476
|
+
deactivate();
|
|
7477
|
+
}, [deactivate]);
|
|
7322
7478
|
const openLinkPopoverForSelected = (0, import_react5.useCallback)(() => {
|
|
7323
7479
|
const anchor = selectedElRef.current;
|
|
7324
7480
|
if (!anchor) return;
|
|
@@ -7327,10 +7483,10 @@ function OhhwellsBridge() {
|
|
|
7327
7483
|
bumpLinkPopoverGrace();
|
|
7328
7484
|
setLinkPopover({
|
|
7329
7485
|
key,
|
|
7330
|
-
target: getLinkHref(anchor)
|
|
7331
|
-
rect: anchor.getBoundingClientRect()
|
|
7486
|
+
target: getLinkHref(anchor)
|
|
7332
7487
|
});
|
|
7333
|
-
|
|
7488
|
+
deselect();
|
|
7489
|
+
}, [deselect]);
|
|
7334
7490
|
const handleLinkPopoverSubmit = (0, import_react5.useCallback)(
|
|
7335
7491
|
(target) => {
|
|
7336
7492
|
if (!linkPopover) return;
|
|
@@ -7346,6 +7502,7 @@ function OhhwellsBridge() {
|
|
|
7346
7502
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
7347
7503
|
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
7348
7504
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
7505
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
7349
7506
|
toolbarRect && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
7350
7507
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GlowFrame, { rect: toolbarRect, elRef: glowElRef }),
|
|
7351
7508
|
toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
@@ -7434,12 +7591,11 @@ function OhhwellsBridge() {
|
|
|
7434
7591
|
]
|
|
7435
7592
|
}
|
|
7436
7593
|
),
|
|
7437
|
-
linkPopover ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7594
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7438
7595
|
LinkPopover,
|
|
7439
7596
|
{
|
|
7440
|
-
rect: linkPopover.rect,
|
|
7441
|
-
parentScroll: parentScrollRef.current,
|
|
7442
7597
|
panelRef: linkPopoverPanelRef,
|
|
7598
|
+
portalContainer: dialogPortalContainer,
|
|
7443
7599
|
open: true,
|
|
7444
7600
|
mode: "edit",
|
|
7445
7601
|
pages: sitePages,
|
|
@@ -7448,7 +7604,8 @@ function OhhwellsBridge() {
|
|
|
7448
7604
|
initialTarget: linkPopover.target,
|
|
7449
7605
|
onClose: closeLinkPopover,
|
|
7450
7606
|
onSubmit: handleLinkPopoverSubmit
|
|
7451
|
-
}
|
|
7607
|
+
},
|
|
7608
|
+
`${linkPopover.key}-${pathname}`
|
|
7452
7609
|
) : null,
|
|
7453
7610
|
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
7454
7611
|
"div",
|