@ohhwells/bridge 0.1.30 → 0.1.31-next.29
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 +571 -183
- 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 +582 -194
- package/dist/index.js.map +1 -1
- package/dist/styles.css +53 -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 h-20 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) {
|
|
@@ -5466,6 +5520,15 @@ function getHrefKeyFromElement(el) {
|
|
|
5466
5520
|
if (!key) return null;
|
|
5467
5521
|
return { anchor, key };
|
|
5468
5522
|
}
|
|
5523
|
+
function isNavbarButton(el) {
|
|
5524
|
+
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
5525
|
+
}
|
|
5526
|
+
function clearHrefKeyHover(anchor) {
|
|
5527
|
+
anchor.removeAttribute("data-ohw-hovered");
|
|
5528
|
+
anchor.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5529
|
+
el.removeAttribute("data-ohw-hovered");
|
|
5530
|
+
});
|
|
5531
|
+
}
|
|
5469
5532
|
function collectSections() {
|
|
5470
5533
|
return collectSectionsFromDom();
|
|
5471
5534
|
}
|
|
@@ -5589,6 +5652,8 @@ var ICONS = {
|
|
|
5589
5652
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
5590
5653
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
5591
5654
|
};
|
|
5655
|
+
var TOOLBAR_PILL_PADDING = 2;
|
|
5656
|
+
var TOOLBAR_TOGGLE_GAP = 4;
|
|
5592
5657
|
var TOOLBAR_GROUPS = [
|
|
5593
5658
|
[
|
|
5594
5659
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -5627,40 +5692,190 @@ function GlowFrame({ rect, elRef }) {
|
|
|
5627
5692
|
}
|
|
5628
5693
|
);
|
|
5629
5694
|
}
|
|
5630
|
-
function
|
|
5695
|
+
function getIframeVisibleClip(parentScroll) {
|
|
5696
|
+
if (!parentScroll) return null;
|
|
5697
|
+
const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
|
|
5698
|
+
const clipTop = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5699
|
+
const clipBottom = Math.min(
|
|
5700
|
+
window.innerHeight,
|
|
5701
|
+
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5702
|
+
);
|
|
5703
|
+
return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
|
|
5704
|
+
}
|
|
5705
|
+
function applyVisibleViewport(el, parentScroll) {
|
|
5706
|
+
const clip = getIframeVisibleClip(parentScroll);
|
|
5707
|
+
const top = clip?.top ?? 0;
|
|
5708
|
+
const height = clip ? clip.bottom - clip.top : window.innerHeight;
|
|
5709
|
+
el.style.top = `${top}px`;
|
|
5710
|
+
el.style.height = `${height}px`;
|
|
5711
|
+
}
|
|
5712
|
+
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
5713
|
+
const isAbove = transform.includes("translateY(-100%)");
|
|
5714
|
+
let visualTop = isAbove ? top - approxH : top;
|
|
5715
|
+
let visualBottom = isAbove ? top : top + approxH;
|
|
5716
|
+
const minTop = clip.top + gap;
|
|
5717
|
+
const maxBottom = clip.bottom - gap;
|
|
5718
|
+
if (visualTop >= minTop && visualBottom <= maxBottom) {
|
|
5719
|
+
return { top, transform };
|
|
5720
|
+
}
|
|
5721
|
+
const belowTop = rect.bottom + gap;
|
|
5722
|
+
if (belowTop + approxH <= maxBottom && belowTop >= minTop) {
|
|
5723
|
+
return { top: belowTop, transform: "translateX(-50%)" };
|
|
5724
|
+
}
|
|
5725
|
+
const aboveTop = rect.top - gap;
|
|
5726
|
+
if (aboveTop - approxH >= minTop && aboveTop <= maxBottom) {
|
|
5727
|
+
return { top: aboveTop, transform: "translateX(-50%) translateY(-100%)" };
|
|
5728
|
+
}
|
|
5729
|
+
if (belowTop + approxH <= maxBottom) {
|
|
5730
|
+
return { top: belowTop, transform: "translateX(-50%)" };
|
|
5731
|
+
}
|
|
5732
|
+
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
5733
|
+
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
5734
|
+
}
|
|
5735
|
+
function calcToolbarPos(rect, parentScroll, approxW = 306) {
|
|
5631
5736
|
const GAP = 8;
|
|
5632
|
-
const APPROX_H =
|
|
5633
|
-
const APPROX_W =
|
|
5737
|
+
const APPROX_H = 32;
|
|
5738
|
+
const APPROX_W = approxW;
|
|
5739
|
+
const clip = getIframeVisibleClip(parentScroll);
|
|
5740
|
+
const clipTop = clip?.top ?? 0;
|
|
5634
5741
|
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
5635
5742
|
const visibleTop = rect.top - canvasTopInIframe;
|
|
5636
5743
|
const visibleBottom = rect.bottom - canvasTopInIframe;
|
|
5637
5744
|
const isTall = rect.height > APPROX_H + GAP;
|
|
5745
|
+
const spaceAbove = rect.top - (clipTop + GAP);
|
|
5746
|
+
const fitsAbove = spaceAbove >= APPROX_H + GAP;
|
|
5638
5747
|
let top;
|
|
5639
5748
|
let transform;
|
|
5640
|
-
if (visibleTop > 0 || !isTall) {
|
|
5749
|
+
if ((visibleTop > 0 || !isTall) && fitsAbove) {
|
|
5641
5750
|
top = rect.top - GAP;
|
|
5642
5751
|
transform = "translateX(-50%) translateY(-100%)";
|
|
5752
|
+
} else if (visibleTop > 0 || !isTall) {
|
|
5753
|
+
top = rect.bottom + GAP;
|
|
5754
|
+
transform = "translateX(-50%)";
|
|
5643
5755
|
} else if (visibleBottom > APPROX_H + GAP) {
|
|
5644
|
-
top =
|
|
5756
|
+
top = clipTop + GAP;
|
|
5645
5757
|
transform = "translateX(-50%)";
|
|
5646
5758
|
} else {
|
|
5647
5759
|
top = rect.bottom + GAP;
|
|
5648
5760
|
transform = "translateX(-50%)";
|
|
5649
5761
|
}
|
|
5762
|
+
if (clip) {
|
|
5763
|
+
const clamped = clampToolbarToClip(top, transform, rect, clip, APPROX_H, GAP);
|
|
5764
|
+
top = clamped.top;
|
|
5765
|
+
transform = clamped.transform;
|
|
5766
|
+
}
|
|
5650
5767
|
const rawLeft = rect.left + rect.width / 2;
|
|
5651
5768
|
const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
|
|
5652
5769
|
return { top, left, transform };
|
|
5653
5770
|
}
|
|
5771
|
+
var EDIT_LINK_ICON = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
5772
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
5773
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
5774
|
+
] });
|
|
5654
5775
|
function FloatingToolbar({
|
|
5655
5776
|
rect,
|
|
5656
5777
|
parentScroll,
|
|
5657
5778
|
elRef,
|
|
5779
|
+
variant = "rich-text",
|
|
5658
5780
|
onCommand,
|
|
5659
5781
|
activeCommands,
|
|
5660
5782
|
showEditLink,
|
|
5661
5783
|
onEditLink
|
|
5662
5784
|
}) {
|
|
5663
|
-
const
|
|
5785
|
+
const approxW = variant === "link-action" ? 112 : 306;
|
|
5786
|
+
const { top, left, transform } = calcToolbarPos(rect, parentScroll, approxW);
|
|
5787
|
+
if (variant === "link-action") {
|
|
5788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
5789
|
+
"div",
|
|
5790
|
+
{
|
|
5791
|
+
ref: elRef,
|
|
5792
|
+
"data-ohw-toolbar": "",
|
|
5793
|
+
style: {
|
|
5794
|
+
position: "fixed",
|
|
5795
|
+
top,
|
|
5796
|
+
left,
|
|
5797
|
+
transform,
|
|
5798
|
+
zIndex: 2147483647,
|
|
5799
|
+
background: "#fff",
|
|
5800
|
+
border: "1px solid #E7E5E4",
|
|
5801
|
+
borderRadius: 6,
|
|
5802
|
+
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5803
|
+
display: "flex",
|
|
5804
|
+
alignItems: "center",
|
|
5805
|
+
padding: TOOLBAR_PILL_PADDING,
|
|
5806
|
+
gap: TOOLBAR_TOGGLE_GAP,
|
|
5807
|
+
fontFamily: "sans-serif",
|
|
5808
|
+
pointerEvents: "auto",
|
|
5809
|
+
whiteSpace: "nowrap"
|
|
5810
|
+
},
|
|
5811
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5812
|
+
children: [
|
|
5813
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5814
|
+
"button",
|
|
5815
|
+
{
|
|
5816
|
+
type: "button",
|
|
5817
|
+
title: "Edit link",
|
|
5818
|
+
onMouseDown: (e) => {
|
|
5819
|
+
e.preventDefault();
|
|
5820
|
+
e.stopPropagation();
|
|
5821
|
+
onEditLink?.();
|
|
5822
|
+
},
|
|
5823
|
+
onClick: (e) => {
|
|
5824
|
+
e.preventDefault();
|
|
5825
|
+
e.stopPropagation();
|
|
5826
|
+
},
|
|
5827
|
+
onMouseEnter: (e) => {
|
|
5828
|
+
e.currentTarget.style.background = "#F5F5F4";
|
|
5829
|
+
},
|
|
5830
|
+
onMouseLeave: (e) => {
|
|
5831
|
+
e.currentTarget.style.background = "transparent";
|
|
5832
|
+
},
|
|
5833
|
+
style: {
|
|
5834
|
+
display: "flex",
|
|
5835
|
+
alignItems: "center",
|
|
5836
|
+
justifyContent: "center",
|
|
5837
|
+
border: "none",
|
|
5838
|
+
background: "transparent",
|
|
5839
|
+
borderRadius: 4,
|
|
5840
|
+
cursor: "pointer",
|
|
5841
|
+
color: "#1C1917",
|
|
5842
|
+
flexShrink: 0,
|
|
5843
|
+
padding: 6
|
|
5844
|
+
},
|
|
5845
|
+
children: EDIT_LINK_ICON
|
|
5846
|
+
}
|
|
5847
|
+
),
|
|
5848
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
5849
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5850
|
+
"button",
|
|
5851
|
+
{
|
|
5852
|
+
type: "button",
|
|
5853
|
+
title: "Coming soon",
|
|
5854
|
+
disabled: true,
|
|
5855
|
+
style: {
|
|
5856
|
+
display: "flex",
|
|
5857
|
+
alignItems: "center",
|
|
5858
|
+
justifyContent: "center",
|
|
5859
|
+
border: "none",
|
|
5860
|
+
background: "transparent",
|
|
5861
|
+
borderRadius: 4,
|
|
5862
|
+
cursor: "not-allowed",
|
|
5863
|
+
color: "#A8A29E",
|
|
5864
|
+
flexShrink: 0,
|
|
5865
|
+
padding: 6,
|
|
5866
|
+
opacity: 0.6
|
|
5867
|
+
},
|
|
5868
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: [
|
|
5869
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
5870
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
5871
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
5872
|
+
] })
|
|
5873
|
+
}
|
|
5874
|
+
)
|
|
5875
|
+
]
|
|
5876
|
+
}
|
|
5877
|
+
);
|
|
5878
|
+
}
|
|
5664
5879
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
5665
5880
|
"div",
|
|
5666
5881
|
{
|
|
@@ -5678,8 +5893,8 @@ function FloatingToolbar({
|
|
|
5678
5893
|
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5679
5894
|
display: "flex",
|
|
5680
5895
|
alignItems: "center",
|
|
5681
|
-
padding:
|
|
5682
|
-
gap:
|
|
5896
|
+
padding: TOOLBAR_PILL_PADDING,
|
|
5897
|
+
gap: TOOLBAR_TOGGLE_GAP,
|
|
5683
5898
|
fontFamily: "sans-serif",
|
|
5684
5899
|
pointerEvents: "auto",
|
|
5685
5900
|
whiteSpace: "nowrap"
|
|
@@ -5768,10 +5983,7 @@ function FloatingToolbar({
|
|
|
5768
5983
|
flexShrink: 0,
|
|
5769
5984
|
padding: 6
|
|
5770
5985
|
},
|
|
5771
|
-
children:
|
|
5772
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
5773
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
5774
|
-
] })
|
|
5986
|
+
children: EDIT_LINK_ICON
|
|
5775
5987
|
}
|
|
5776
5988
|
) : null
|
|
5777
5989
|
]
|
|
@@ -5862,9 +6074,17 @@ function OhhwellsBridge() {
|
|
|
5862
6074
|
const [fetchState, setFetchState] = (0, import_react5.useState)("idle");
|
|
5863
6075
|
const autoSaveTimers = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
5864
6076
|
const activeElRef = (0, import_react5.useRef)(null);
|
|
6077
|
+
const selectedElRef = (0, import_react5.useRef)(null);
|
|
5865
6078
|
const originalContentRef = (0, import_react5.useRef)(null);
|
|
5866
6079
|
const activeStateElRef = (0, import_react5.useRef)(null);
|
|
5867
6080
|
const parentScrollRef = (0, import_react5.useRef)(null);
|
|
6081
|
+
const visibleViewportRef = (0, import_react5.useRef)(null);
|
|
6082
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react5.useState)(null);
|
|
6083
|
+
const attachVisibleViewport = (0, import_react5.useCallback)((node) => {
|
|
6084
|
+
visibleViewportRef.current = node;
|
|
6085
|
+
setDialogPortalContainer(node);
|
|
6086
|
+
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6087
|
+
}, []);
|
|
5868
6088
|
const toolbarElRef = (0, import_react5.useRef)(null);
|
|
5869
6089
|
const glowElRef = (0, import_react5.useRef)(null);
|
|
5870
6090
|
const hoveredImageRef = (0, import_react5.useRef)(null);
|
|
@@ -5877,6 +6097,10 @@ function OhhwellsBridge() {
|
|
|
5877
6097
|
});
|
|
5878
6098
|
const deactivateRef = (0, import_react5.useRef)(() => {
|
|
5879
6099
|
});
|
|
6100
|
+
const selectRef = (0, import_react5.useRef)(() => {
|
|
6101
|
+
});
|
|
6102
|
+
const deselectRef = (0, import_react5.useRef)(() => {
|
|
6103
|
+
});
|
|
5880
6104
|
const refreshActiveCommandsRef = (0, import_react5.useRef)(() => {
|
|
5881
6105
|
});
|
|
5882
6106
|
const postToParentRef = (0, import_react5.useRef)(postToParent);
|
|
@@ -5884,6 +6108,9 @@ function OhhwellsBridge() {
|
|
|
5884
6108
|
const sectionsLoadedRef = (0, import_react5.useRef)(false);
|
|
5885
6109
|
const pendingScheduleConfigRequests = (0, import_react5.useRef)([]);
|
|
5886
6110
|
const [toolbarRect, setToolbarRect] = (0, import_react5.useState)(null);
|
|
6111
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react5.useState)("none");
|
|
6112
|
+
const toolbarVariantRef = (0, import_react5.useRef)("none");
|
|
6113
|
+
toolbarVariantRef.current = toolbarVariant;
|
|
5887
6114
|
const [toggleState, setToggleState] = (0, import_react5.useState)(null);
|
|
5888
6115
|
const [maxBadge, setMaxBadge] = (0, import_react5.useState)(null);
|
|
5889
6116
|
const [activeCommands, setActiveCommands] = (0, import_react5.useState)(/* @__PURE__ */ new Set());
|
|
@@ -5928,7 +6155,33 @@ function OhhwellsBridge() {
|
|
|
5928
6155
|
hoveredImageRef.current = null;
|
|
5929
6156
|
hoveredImageHasTextOverlapRef.current = false;
|
|
5930
6157
|
}
|
|
6158
|
+
hoveredGapRef.current = null;
|
|
6159
|
+
setSectionGap(null);
|
|
5931
6160
|
postToParent({ type: "ow:image-unhover" });
|
|
6161
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6162
|
+
const html = document.documentElement;
|
|
6163
|
+
const body = document.body;
|
|
6164
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6165
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6166
|
+
html.style.overflow = "hidden";
|
|
6167
|
+
body.style.overflow = "hidden";
|
|
6168
|
+
const preventBackgroundScroll = (e) => {
|
|
6169
|
+
const target = e.target;
|
|
6170
|
+
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6171
|
+
return;
|
|
6172
|
+
}
|
|
6173
|
+
e.preventDefault();
|
|
6174
|
+
};
|
|
6175
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6176
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6177
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6178
|
+
return () => {
|
|
6179
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6180
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6181
|
+
body.style.overflow = prevBodyOverflow;
|
|
6182
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6183
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6184
|
+
};
|
|
5932
6185
|
}, [linkPopover, postToParent]);
|
|
5933
6186
|
(0, import_react5.useEffect)(() => {
|
|
5934
6187
|
if (!isEditMode) return;
|
|
@@ -5963,7 +6216,7 @@ function OhhwellsBridge() {
|
|
|
5963
6216
|
}, [isEditMode]);
|
|
5964
6217
|
(0, import_react5.useEffect)(() => {
|
|
5965
6218
|
const update = () => {
|
|
5966
|
-
const el = activeElRef.current;
|
|
6219
|
+
const el = activeElRef.current ?? selectedElRef.current;
|
|
5967
6220
|
if (el) setToolbarRect(el.getBoundingClientRect());
|
|
5968
6221
|
setToggleState((prev) => {
|
|
5969
6222
|
if (!prev || !activeStateElRef.current) return prev;
|
|
@@ -6031,19 +6284,41 @@ function OhhwellsBridge() {
|
|
|
6031
6284
|
}
|
|
6032
6285
|
el.removeAttribute("contenteditable");
|
|
6033
6286
|
activeElRef.current = null;
|
|
6034
|
-
|
|
6287
|
+
if (!selectedElRef.current) {
|
|
6288
|
+
setToolbarRect(null);
|
|
6289
|
+
setToolbarVariant("none");
|
|
6290
|
+
}
|
|
6035
6291
|
setMaxBadge(null);
|
|
6036
6292
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6037
6293
|
setToolbarShowEditLink(false);
|
|
6038
6294
|
postToParent({ type: "ow:exit-edit" });
|
|
6039
6295
|
}, [postToParent]);
|
|
6296
|
+
const deselect = (0, import_react5.useCallback)(() => {
|
|
6297
|
+
selectedElRef.current = null;
|
|
6298
|
+
if (!activeElRef.current) {
|
|
6299
|
+
setToolbarRect(null);
|
|
6300
|
+
setToolbarVariant("none");
|
|
6301
|
+
}
|
|
6302
|
+
}, []);
|
|
6303
|
+
const select = (0, import_react5.useCallback)((anchor) => {
|
|
6304
|
+
if (!isNavbarButton(anchor)) return;
|
|
6305
|
+
if (activeElRef.current) deactivate();
|
|
6306
|
+
selectedElRef.current = anchor;
|
|
6307
|
+
clearHrefKeyHover(anchor);
|
|
6308
|
+
setToolbarVariant("link-action");
|
|
6309
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
6310
|
+
setToolbarShowEditLink(false);
|
|
6311
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6312
|
+
}, [deactivate]);
|
|
6040
6313
|
const activate = (0, import_react5.useCallback)((el) => {
|
|
6041
6314
|
if (activeElRef.current === el) return;
|
|
6315
|
+
selectedElRef.current = null;
|
|
6042
6316
|
deactivate();
|
|
6043
6317
|
if (hoveredImageRef.current) {
|
|
6044
6318
|
hoveredImageRef.current = null;
|
|
6045
6319
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
6046
6320
|
}
|
|
6321
|
+
setToolbarVariant("rich-text");
|
|
6047
6322
|
el.setAttribute("contenteditable", "true");
|
|
6048
6323
|
el.removeAttribute("data-ohw-hovered");
|
|
6049
6324
|
activeElRef.current = el;
|
|
@@ -6056,6 +6331,8 @@ function OhhwellsBridge() {
|
|
|
6056
6331
|
}, [deactivate, postToParent]);
|
|
6057
6332
|
activateRef.current = activate;
|
|
6058
6333
|
deactivateRef.current = deactivate;
|
|
6334
|
+
selectRef.current = select;
|
|
6335
|
+
deselectRef.current = deselect;
|
|
6059
6336
|
(0, import_react5.useLayoutEffect)(() => {
|
|
6060
6337
|
if (!subdomain || isEditMode) {
|
|
6061
6338
|
setFetchState("done");
|
|
@@ -6159,6 +6436,12 @@ function OhhwellsBridge() {
|
|
|
6159
6436
|
(0, import_react5.useEffect)(() => {
|
|
6160
6437
|
postToParent({ type: "ow:navigation", path: pathname });
|
|
6161
6438
|
}, [pathname, postToParent]);
|
|
6439
|
+
(0, import_react5.useEffect)(() => {
|
|
6440
|
+
if (!isEditMode) return;
|
|
6441
|
+
setLinkPopover(null);
|
|
6442
|
+
deselectRef.current();
|
|
6443
|
+
deactivateRef.current();
|
|
6444
|
+
}, [pathname, isEditMode]);
|
|
6162
6445
|
(0, import_react5.useEffect)(() => {
|
|
6163
6446
|
if (!isEditMode) return;
|
|
6164
6447
|
const measure = () => {
|
|
@@ -6269,12 +6552,12 @@ function OhhwellsBridge() {
|
|
|
6269
6552
|
if (editable.dataset.ohwEditable === "link") {
|
|
6270
6553
|
e.preventDefault();
|
|
6271
6554
|
e.stopPropagation();
|
|
6555
|
+
deselectRef.current();
|
|
6272
6556
|
deactivateRef.current();
|
|
6273
6557
|
bumpLinkPopoverGrace();
|
|
6274
6558
|
setLinkPopoverRef.current({
|
|
6275
6559
|
key: editable.dataset.ohwKey ?? "",
|
|
6276
|
-
target: getLinkHref(editable)
|
|
6277
|
-
rect: editable.getBoundingClientRect()
|
|
6560
|
+
target: getLinkHref(editable)
|
|
6278
6561
|
});
|
|
6279
6562
|
return;
|
|
6280
6563
|
}
|
|
@@ -6284,11 +6567,31 @@ function OhhwellsBridge() {
|
|
|
6284
6567
|
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
6285
6568
|
return;
|
|
6286
6569
|
}
|
|
6570
|
+
const hrefCtx = getHrefKeyFromElement(editable);
|
|
6571
|
+
if (hrefCtx && isNavbarButton(hrefCtx.anchor)) {
|
|
6572
|
+
e.preventDefault();
|
|
6573
|
+
e.stopPropagation();
|
|
6574
|
+
const { anchor: anchor2 } = hrefCtx;
|
|
6575
|
+
if (selectedElRef.current === anchor2) {
|
|
6576
|
+
activateRef.current(editable);
|
|
6577
|
+
return;
|
|
6578
|
+
}
|
|
6579
|
+
selectRef.current(anchor2);
|
|
6580
|
+
return;
|
|
6581
|
+
}
|
|
6287
6582
|
e.preventDefault();
|
|
6288
6583
|
e.stopPropagation();
|
|
6289
6584
|
activateRef.current(editable);
|
|
6290
6585
|
return;
|
|
6291
6586
|
}
|
|
6587
|
+
const hrefAnchor = target.closest("[data-ohw-href-key]");
|
|
6588
|
+
if (hrefAnchor && isNavbarButton(hrefAnchor)) {
|
|
6589
|
+
e.preventDefault();
|
|
6590
|
+
e.stopPropagation();
|
|
6591
|
+
if (selectedElRef.current === hrefAnchor) return;
|
|
6592
|
+
selectRef.current(hrefAnchor);
|
|
6593
|
+
return;
|
|
6594
|
+
}
|
|
6292
6595
|
if (activeElRef.current) {
|
|
6293
6596
|
const sel = window.getSelection();
|
|
6294
6597
|
if (sel && !sel.isCollapsed) {
|
|
@@ -6303,15 +6606,22 @@ function OhhwellsBridge() {
|
|
|
6303
6606
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
6304
6607
|
if (hrefCtx && (hrefCtx.anchor === target || hrefCtx.anchor.contains(target))) return;
|
|
6305
6608
|
}
|
|
6609
|
+
if (linkPopoverOpenRef.current && selectedElRef.current) {
|
|
6610
|
+
const selected = selectedElRef.current;
|
|
6611
|
+
if (selected === target || selected.contains(target)) return;
|
|
6612
|
+
}
|
|
6306
6613
|
if (linkPopoverOpenRef.current) {
|
|
6307
6614
|
setLinkPopoverRef.current(null);
|
|
6308
6615
|
return;
|
|
6309
6616
|
}
|
|
6617
|
+
deselectRef.current();
|
|
6310
6618
|
deactivateRef.current();
|
|
6311
6619
|
};
|
|
6312
6620
|
const handleMouseOver = (e) => {
|
|
6313
6621
|
const editable = e.target.closest("[data-ohw-editable]");
|
|
6314
6622
|
if (!editable) return;
|
|
6623
|
+
const selected = selectedElRef.current;
|
|
6624
|
+
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
6315
6625
|
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
|
|
6316
6626
|
editable.setAttribute("data-ohw-hovered", "");
|
|
6317
6627
|
}
|
|
@@ -6447,7 +6757,7 @@ function OhhwellsBridge() {
|
|
|
6447
6757
|
}
|
|
6448
6758
|
return;
|
|
6449
6759
|
}
|
|
6450
|
-
if (topEl?.closest("[data-ohw-link-popover-root]") || topEl?.closest("[data-ohw-link-modal-root]")) {
|
|
6760
|
+
if (topEl?.closest("[data-ohw-link-popover-root]") || topEl?.closest("[data-ohw-link-modal-root]") || topEl?.closest("[data-ohw-link-page-dropdown]")) {
|
|
6451
6761
|
if (hoveredImageRef.current) {
|
|
6452
6762
|
hoveredImageRef.current = null;
|
|
6453
6763
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -6575,6 +6885,13 @@ function OhhwellsBridge() {
|
|
|
6575
6885
|
}
|
|
6576
6886
|
};
|
|
6577
6887
|
const probeSectionGapAt = (clientX, clientY, fromParentViewport = false) => {
|
|
6888
|
+
if (linkPopoverOpenRef.current) {
|
|
6889
|
+
if (hoveredGapRef.current) {
|
|
6890
|
+
hoveredGapRef.current = null;
|
|
6891
|
+
setSectionGap(null);
|
|
6892
|
+
}
|
|
6893
|
+
return;
|
|
6894
|
+
}
|
|
6578
6895
|
const { y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
6579
6896
|
const sections = Array.from(document.querySelectorAll("[data-ohw-section]")).sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);
|
|
6580
6897
|
const ZONE = 20;
|
|
@@ -6798,6 +7115,7 @@ function OhhwellsBridge() {
|
|
|
6798
7115
|
setLinkPopoverRef.current(null);
|
|
6799
7116
|
return;
|
|
6800
7117
|
}
|
|
7118
|
+
deselectRef.current();
|
|
6801
7119
|
deactivateRef.current();
|
|
6802
7120
|
};
|
|
6803
7121
|
window.addEventListener("message", handleDeactivate);
|
|
@@ -6806,6 +7124,10 @@ function OhhwellsBridge() {
|
|
|
6806
7124
|
setLinkPopoverRef.current(null);
|
|
6807
7125
|
return;
|
|
6808
7126
|
}
|
|
7127
|
+
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
7128
|
+
deselectRef.current();
|
|
7129
|
+
return;
|
|
7130
|
+
}
|
|
6809
7131
|
if (e.key !== "Escape") return;
|
|
6810
7132
|
const el = activeElRef.current;
|
|
6811
7133
|
if (el && originalContentRef.current !== null) {
|
|
@@ -6815,13 +7137,16 @@ function OhhwellsBridge() {
|
|
|
6815
7137
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: originalContentRef.current }] });
|
|
6816
7138
|
}
|
|
6817
7139
|
}
|
|
7140
|
+
deselectRef.current();
|
|
6818
7141
|
deactivateRef.current();
|
|
6819
7142
|
};
|
|
6820
7143
|
const handleScroll = () => {
|
|
6821
|
-
|
|
6822
|
-
|
|
7144
|
+
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7145
|
+
if (focusEl) {
|
|
7146
|
+
const r2 = focusEl.getBoundingClientRect();
|
|
6823
7147
|
applyToolbarPos(r2);
|
|
6824
|
-
|
|
7148
|
+
setToolbarRect(r2);
|
|
7149
|
+
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
6825
7150
|
}
|
|
6826
7151
|
if (activeStateElRef.current) {
|
|
6827
7152
|
const rect = activeStateElRef.current.getBoundingClientRect();
|
|
@@ -6946,8 +7271,9 @@ function OhhwellsBridge() {
|
|
|
6946
7271
|
};
|
|
6947
7272
|
const applyToolbarPos = (rect) => {
|
|
6948
7273
|
const ps = parentScrollRef.current;
|
|
7274
|
+
const approxW = toolbarVariantRef.current === "link-action" ? 112 : 306;
|
|
6949
7275
|
if (toolbarElRef.current) {
|
|
6950
|
-
const { top, left, transform } = calcToolbarPos(rect, ps);
|
|
7276
|
+
const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
|
|
6951
7277
|
toolbarElRef.current.style.top = `${top}px`;
|
|
6952
7278
|
toolbarElRef.current.style.left = `${left}px`;
|
|
6953
7279
|
toolbarElRef.current.style.transform = transform;
|
|
@@ -6962,7 +7288,11 @@ function OhhwellsBridge() {
|
|
|
6962
7288
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
6963
7289
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
6964
7290
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
6965
|
-
if (
|
|
7291
|
+
if (visibleViewportRef.current) {
|
|
7292
|
+
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7293
|
+
}
|
|
7294
|
+
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7295
|
+
if (focusEl) applyToolbarPos(focusEl.getBoundingClientRect());
|
|
6966
7296
|
};
|
|
6967
7297
|
const handleClickAt = (e) => {
|
|
6968
7298
|
if (e.data?.type !== "ow:click-at") return;
|
|
@@ -7012,6 +7342,12 @@ function OhhwellsBridge() {
|
|
|
7012
7342
|
window.addEventListener("message", handleParentScroll);
|
|
7013
7343
|
window.addEventListener("message", handlePointerSync);
|
|
7014
7344
|
window.addEventListener("message", handleClickAt);
|
|
7345
|
+
const handleViewportResize = () => {
|
|
7346
|
+
if (visibleViewportRef.current) {
|
|
7347
|
+
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7348
|
+
}
|
|
7349
|
+
};
|
|
7350
|
+
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
7015
7351
|
document.addEventListener("click", handleClick, true);
|
|
7016
7352
|
document.addEventListener("paste", handlePaste, true);
|
|
7017
7353
|
document.addEventListener("input", handleInput, true);
|
|
@@ -7049,6 +7385,7 @@ function OhhwellsBridge() {
|
|
|
7049
7385
|
window.removeEventListener("message", handleAnimLock);
|
|
7050
7386
|
window.removeEventListener("message", handleCanvasHeight);
|
|
7051
7387
|
window.removeEventListener("message", handleParentScroll);
|
|
7388
|
+
window.removeEventListener("resize", handleViewportResize);
|
|
7052
7389
|
window.removeEventListener("message", handlePointerSync);
|
|
7053
7390
|
window.removeEventListener("message", handleClickAt);
|
|
7054
7391
|
window.removeEventListener("message", handleHydrate);
|
|
@@ -7136,10 +7473,22 @@ function OhhwellsBridge() {
|
|
|
7136
7473
|
bumpLinkPopoverGrace();
|
|
7137
7474
|
setLinkPopover({
|
|
7138
7475
|
key: hrefCtx.key,
|
|
7139
|
-
target: getLinkHref(hrefCtx.anchor)
|
|
7140
|
-
rect: hrefCtx.anchor.getBoundingClientRect()
|
|
7476
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
7141
7477
|
});
|
|
7142
|
-
|
|
7478
|
+
deactivate();
|
|
7479
|
+
}, [deactivate]);
|
|
7480
|
+
const openLinkPopoverForSelected = (0, import_react5.useCallback)(() => {
|
|
7481
|
+
const anchor = selectedElRef.current;
|
|
7482
|
+
if (!anchor) return;
|
|
7483
|
+
const key = anchor.getAttribute("data-ohw-href-key");
|
|
7484
|
+
if (!key) return;
|
|
7485
|
+
bumpLinkPopoverGrace();
|
|
7486
|
+
setLinkPopover({
|
|
7487
|
+
key,
|
|
7488
|
+
target: getLinkHref(anchor)
|
|
7489
|
+
});
|
|
7490
|
+
deselect();
|
|
7491
|
+
}, [deselect]);
|
|
7143
7492
|
const handleLinkPopoverSubmit = (0, import_react5.useCallback)(
|
|
7144
7493
|
(target) => {
|
|
7145
7494
|
if (!linkPopover) return;
|
|
@@ -7155,11 +7504,13 @@ function OhhwellsBridge() {
|
|
|
7155
7504
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
7156
7505
|
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
7157
7506
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
7507
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
7158
7508
|
toolbarRect && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
7159
7509
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GlowFrame, { rect: toolbarRect, elRef: glowElRef }),
|
|
7160
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7510
|
+
toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7161
7511
|
FloatingToolbar,
|
|
7162
7512
|
{
|
|
7513
|
+
variant: "rich-text",
|
|
7163
7514
|
rect: toolbarRect,
|
|
7164
7515
|
parentScroll: parentScrollRef.current,
|
|
7165
7516
|
elRef: toolbarElRef,
|
|
@@ -7168,6 +7519,18 @@ function OhhwellsBridge() {
|
|
|
7168
7519
|
showEditLink,
|
|
7169
7520
|
onEditLink: openLinkPopoverForActive
|
|
7170
7521
|
}
|
|
7522
|
+
),
|
|
7523
|
+
toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7524
|
+
FloatingToolbar,
|
|
7525
|
+
{
|
|
7526
|
+
variant: "link-action",
|
|
7527
|
+
rect: toolbarRect,
|
|
7528
|
+
parentScroll: parentScrollRef.current,
|
|
7529
|
+
elRef: toolbarElRef,
|
|
7530
|
+
onCommand: handleCommand,
|
|
7531
|
+
activeCommands,
|
|
7532
|
+
onEditLink: openLinkPopoverForSelected
|
|
7533
|
+
}
|
|
7171
7534
|
)
|
|
7172
7535
|
] }),
|
|
7173
7536
|
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
@@ -7230,12 +7593,11 @@ function OhhwellsBridge() {
|
|
|
7230
7593
|
]
|
|
7231
7594
|
}
|
|
7232
7595
|
),
|
|
7233
|
-
linkPopover ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7596
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7234
7597
|
LinkPopover,
|
|
7235
7598
|
{
|
|
7236
|
-
rect: linkPopover.rect,
|
|
7237
|
-
parentScroll: parentScrollRef.current,
|
|
7238
7599
|
panelRef: linkPopoverPanelRef,
|
|
7600
|
+
portalContainer: dialogPortalContainer,
|
|
7239
7601
|
open: true,
|
|
7240
7602
|
mode: "edit",
|
|
7241
7603
|
pages: sitePages,
|
|
@@ -7244,8 +7606,34 @@ function OhhwellsBridge() {
|
|
|
7244
7606
|
initialTarget: linkPopover.target,
|
|
7245
7607
|
onClose: closeLinkPopover,
|
|
7246
7608
|
onSubmit: handleLinkPopoverSubmit
|
|
7609
|
+
},
|
|
7610
|
+
`${linkPopover.key}-${pathname}`
|
|
7611
|
+
) : null,
|
|
7612
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
7613
|
+
"div",
|
|
7614
|
+
{
|
|
7615
|
+
"data-ohw-section-insert-line": "",
|
|
7616
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
7617
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
7618
|
+
children: [
|
|
7619
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
7620
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7621
|
+
Badge,
|
|
7622
|
+
{
|
|
7623
|
+
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
7624
|
+
onClick: () => {
|
|
7625
|
+
window.parent.postMessage(
|
|
7626
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
7627
|
+
"*"
|
|
7628
|
+
);
|
|
7629
|
+
},
|
|
7630
|
+
children: "Add Section"
|
|
7631
|
+
}
|
|
7632
|
+
),
|
|
7633
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
7634
|
+
]
|
|
7247
7635
|
}
|
|
7248
|
-
)
|
|
7636
|
+
)
|
|
7249
7637
|
] }),
|
|
7250
7638
|
bridgeRoot
|
|
7251
7639
|
) : null;
|