@ohhwells/bridge 0.1.29-next.21 → 0.1.29-next.25
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 +563 -195
- 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 +558 -190
- package/dist/index.js.map +1 -1
- package/dist/styles.css +41 -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),
|
|
@@ -4689,13 +4760,13 @@ function Label({ className, ...props }) {
|
|
|
4689
4760
|
}
|
|
4690
4761
|
|
|
4691
4762
|
// src/ui/popover.tsx
|
|
4692
|
-
var
|
|
4693
|
-
var
|
|
4763
|
+
var import_radix_ui6 = require("radix-ui");
|
|
4764
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4694
4765
|
function Popover({ ...props }) {
|
|
4695
|
-
return /* @__PURE__ */ (0,
|
|
4766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui6.Popover.Root, { "data-slot": "popover", ...props });
|
|
4696
4767
|
}
|
|
4697
4768
|
function PopoverTrigger({ ...props }) {
|
|
4698
|
-
return /* @__PURE__ */ (0,
|
|
4769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui6.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
4699
4770
|
}
|
|
4700
4771
|
function PopoverContent({
|
|
4701
4772
|
className,
|
|
@@ -4703,8 +4774,8 @@ function PopoverContent({
|
|
|
4703
4774
|
sideOffset = 6,
|
|
4704
4775
|
...props
|
|
4705
4776
|
}) {
|
|
4706
|
-
return /* @__PURE__ */ (0,
|
|
4707
|
-
|
|
4777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui6.Popover.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4778
|
+
import_radix_ui6.Popover.Content,
|
|
4708
4779
|
{
|
|
4709
4780
|
"data-slot": "popover-content",
|
|
4710
4781
|
align,
|
|
@@ -4719,9 +4790,9 @@ function PopoverContent({
|
|
|
4719
4790
|
}
|
|
4720
4791
|
|
|
4721
4792
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
4722
|
-
var
|
|
4793
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4723
4794
|
function FieldChevron({ onClick }) {
|
|
4724
|
-
return /* @__PURE__ */ (0,
|
|
4795
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4725
4796
|
"button",
|
|
4726
4797
|
{
|
|
4727
4798
|
type: "button",
|
|
@@ -4729,7 +4800,7 @@ function FieldChevron({ onClick }) {
|
|
|
4729
4800
|
onClick,
|
|
4730
4801
|
"aria-label": "Open page list",
|
|
4731
4802
|
tabIndex: -1,
|
|
4732
|
-
children: /* @__PURE__ */ (0,
|
|
4803
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconChevronDown, {})
|
|
4733
4804
|
}
|
|
4734
4805
|
);
|
|
4735
4806
|
}
|
|
@@ -4768,12 +4839,12 @@ function UrlOrPageInput({
|
|
|
4768
4839
|
"data-ohw-link-field flex h-10 w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
4769
4840
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
4770
4841
|
);
|
|
4771
|
-
return /* @__PURE__ */ (0,
|
|
4772
|
-
/* @__PURE__ */ (0,
|
|
4773
|
-
/* @__PURE__ */ (0,
|
|
4774
|
-
/* @__PURE__ */ (0,
|
|
4775
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
4776
|
-
readOnly ? /* @__PURE__ */ (0,
|
|
4842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
4843
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
4844
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Popover, { open: dropdownOpen && !readOnly, onOpenChange: onDropdownOpenChange, children: [
|
|
4845
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
4846
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
4847
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4777
4848
|
Input,
|
|
4778
4849
|
{
|
|
4779
4850
|
ref: inputRef,
|
|
@@ -4792,7 +4863,7 @@ function UrlOrPageInput({
|
|
|
4792
4863
|
)
|
|
4793
4864
|
}
|
|
4794
4865
|
),
|
|
4795
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
4866
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4796
4867
|
"button",
|
|
4797
4868
|
{
|
|
4798
4869
|
type: "button",
|
|
@@ -4800,26 +4871,26 @@ function UrlOrPageInput({
|
|
|
4800
4871
|
onMouseDown: clearSelection,
|
|
4801
4872
|
"aria-label": "Clear selected page",
|
|
4802
4873
|
tabIndex: -1,
|
|
4803
|
-
children: /* @__PURE__ */ (0,
|
|
4874
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconX, { "aria-hidden": true })
|
|
4804
4875
|
}
|
|
4805
4876
|
) : null,
|
|
4806
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
4877
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
4807
4878
|
] }) }),
|
|
4808
|
-
filteredPages.length > 0 && /* @__PURE__ */ (0,
|
|
4879
|
+
filteredPages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverContent, { "data-ohw-link-popover-root": "", onOpenAutoFocus: (e) => e.preventDefault(), children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4809
4880
|
"button",
|
|
4810
4881
|
{
|
|
4811
4882
|
type: "button",
|
|
4812
4883
|
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",
|
|
4813
4884
|
onClick: () => onPageSelect(page),
|
|
4814
4885
|
children: [
|
|
4815
|
-
/* @__PURE__ */ (0,
|
|
4816
|
-
/* @__PURE__ */ (0,
|
|
4886
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
4887
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: page.title })
|
|
4817
4888
|
]
|
|
4818
4889
|
},
|
|
4819
4890
|
page.path
|
|
4820
4891
|
)) })
|
|
4821
4892
|
] }),
|
|
4822
|
-
urlError ? /* @__PURE__ */ (0,
|
|
4893
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
4823
4894
|
] });
|
|
4824
4895
|
}
|
|
4825
4896
|
|
|
@@ -4987,7 +5058,7 @@ function useLinkModalState({
|
|
|
4987
5058
|
}
|
|
4988
5059
|
|
|
4989
5060
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
4990
|
-
var
|
|
5061
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
4991
5062
|
function LinkEditorPanel({
|
|
4992
5063
|
open = true,
|
|
4993
5064
|
mode = "create",
|
|
@@ -5011,26 +5082,25 @@ function LinkEditorPanel({
|
|
|
5011
5082
|
onSubmit
|
|
5012
5083
|
});
|
|
5013
5084
|
const isCancel = state.secondaryLabel === "Cancel";
|
|
5014
|
-
return /* @__PURE__ */ (0,
|
|
5015
|
-
/* @__PURE__ */ (0,
|
|
5085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
5086
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5016
5087
|
"button",
|
|
5017
5088
|
{
|
|
5018
5089
|
type: "button",
|
|
5019
5090
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5020
|
-
onClick: state.handleClose,
|
|
5021
5091
|
"aria-label": "Close",
|
|
5022
|
-
children: /* @__PURE__ */ (0,
|
|
5092
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconX, { "aria-hidden": true })
|
|
5023
5093
|
}
|
|
5024
|
-
),
|
|
5025
|
-
/* @__PURE__ */ (0,
|
|
5026
|
-
/* @__PURE__ */ (0,
|
|
5027
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5094
|
+
) }),
|
|
5095
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5096
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5097
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5028
5098
|
DestinationBreadcrumb,
|
|
5029
5099
|
{
|
|
5030
5100
|
pageTitle: state.selectedPage.title,
|
|
5031
5101
|
sectionLabel: state.selectedSection.label
|
|
5032
5102
|
}
|
|
5033
|
-
) : /* @__PURE__ */ (0,
|
|
5103
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5034
5104
|
UrlOrPageInput,
|
|
5035
5105
|
{
|
|
5036
5106
|
value: state.searchValue,
|
|
@@ -5043,18 +5113,18 @@ function LinkEditorPanel({
|
|
|
5043
5113
|
urlError: state.urlError
|
|
5044
5114
|
}
|
|
5045
5115
|
),
|
|
5046
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
5047
|
-
/* @__PURE__ */ (0,
|
|
5048
|
-
/* @__PURE__ */ (0,
|
|
5049
|
-
/* @__PURE__ */ (0,
|
|
5050
|
-
/* @__PURE__ */ (0,
|
|
5116
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5117
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5118
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5119
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5120
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5051
5121
|
] })
|
|
5052
5122
|
] }) : null,
|
|
5053
|
-
state.showSectionPicker ? /* @__PURE__ */ (0,
|
|
5054
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5123
|
+
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5124
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5055
5125
|
] }),
|
|
5056
|
-
/* @__PURE__ */ (0,
|
|
5057
|
-
/* @__PURE__ */ (0,
|
|
5126
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5127
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5058
5128
|
Button,
|
|
5059
5129
|
{
|
|
5060
5130
|
type: "button",
|
|
@@ -5069,7 +5139,7 @@ function LinkEditorPanel({
|
|
|
5069
5139
|
children: state.secondaryLabel
|
|
5070
5140
|
}
|
|
5071
5141
|
),
|
|
5072
|
-
/* @__PURE__ */ (0,
|
|
5142
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5073
5143
|
Button,
|
|
5074
5144
|
{
|
|
5075
5145
|
type: "button",
|
|
@@ -5088,28 +5158,34 @@ function LinkEditorPanel({
|
|
|
5088
5158
|
}
|
|
5089
5159
|
|
|
5090
5160
|
// src/ui/link-modal/LinkPopover.tsx
|
|
5091
|
-
var
|
|
5161
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5092
5162
|
function LinkPopover({
|
|
5093
|
-
|
|
5094
|
-
parentScroll,
|
|
5163
|
+
open = true,
|
|
5095
5164
|
panelRef,
|
|
5165
|
+
portalContainer,
|
|
5166
|
+
onClose,
|
|
5096
5167
|
...editorProps
|
|
5097
5168
|
}) {
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
"div",
|
|
5169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5170
|
+
Dialog2,
|
|
5101
5171
|
{
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5172
|
+
open,
|
|
5173
|
+
onOpenChange: (next) => {
|
|
5174
|
+
if (!next) onClose?.();
|
|
5175
|
+
},
|
|
5176
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5177
|
+
DialogContent,
|
|
5178
|
+
{
|
|
5179
|
+
ref: panelRef,
|
|
5180
|
+
container: portalContainer,
|
|
5181
|
+
"data-ohw-link-popover-root": "",
|
|
5182
|
+
"data-ohw-link-modal-root": "",
|
|
5183
|
+
"data-ohw-bridge": "",
|
|
5184
|
+
showCloseButton: false,
|
|
5185
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5186
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5187
|
+
}
|
|
5188
|
+
)
|
|
5113
5189
|
}
|
|
5114
5190
|
);
|
|
5115
5191
|
}
|
|
@@ -5173,7 +5249,7 @@ function shouldUseDevFixtures() {
|
|
|
5173
5249
|
}
|
|
5174
5250
|
|
|
5175
5251
|
// src/ui/badge.tsx
|
|
5176
|
-
var
|
|
5252
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5177
5253
|
var badgeVariants = cva(
|
|
5178
5254
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
5179
5255
|
{
|
|
@@ -5191,11 +5267,11 @@ var badgeVariants = cva(
|
|
|
5191
5267
|
}
|
|
5192
5268
|
);
|
|
5193
5269
|
function Badge({ className, variant, ...props }) {
|
|
5194
|
-
return /* @__PURE__ */ (0,
|
|
5270
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5195
5271
|
}
|
|
5196
5272
|
|
|
5197
5273
|
// src/OhhwellsBridge.tsx
|
|
5198
|
-
var
|
|
5274
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5199
5275
|
var PRIMARY = "#0885FE";
|
|
5200
5276
|
var IMAGE_FADE_MS = 300;
|
|
5201
5277
|
function runOpacityFade(el, onDone) {
|
|
@@ -5369,7 +5445,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5369
5445
|
const root = (0, import_client.createRoot)(container);
|
|
5370
5446
|
(0, import_react_dom.flushSync)(() => {
|
|
5371
5447
|
root.render(
|
|
5372
|
-
/* @__PURE__ */ (0,
|
|
5448
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5373
5449
|
SchedulingWidget,
|
|
5374
5450
|
{
|
|
5375
5451
|
notifyOnConnect,
|
|
@@ -5455,7 +5531,7 @@ function applyLinkByKey(key, val) {
|
|
|
5455
5531
|
}
|
|
5456
5532
|
function isInsideLinkEditor(target) {
|
|
5457
5533
|
return Boolean(
|
|
5458
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest('[data-slot="popover-content"]')
|
|
5534
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
5459
5535
|
);
|
|
5460
5536
|
}
|
|
5461
5537
|
function getHrefKeyFromElement(el) {
|
|
@@ -5466,6 +5542,15 @@ function getHrefKeyFromElement(el) {
|
|
|
5466
5542
|
if (!key) return null;
|
|
5467
5543
|
return { anchor, key };
|
|
5468
5544
|
}
|
|
5545
|
+
function isNavbarButton(el) {
|
|
5546
|
+
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
5547
|
+
}
|
|
5548
|
+
function clearHrefKeyHover(anchor) {
|
|
5549
|
+
anchor.removeAttribute("data-ohw-hovered");
|
|
5550
|
+
anchor.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5551
|
+
el.removeAttribute("data-ohw-hovered");
|
|
5552
|
+
});
|
|
5553
|
+
}
|
|
5469
5554
|
function collectSections() {
|
|
5470
5555
|
return collectSectionsFromDom();
|
|
5471
5556
|
}
|
|
@@ -5608,7 +5693,7 @@ var TOOLBAR_GROUPS = [
|
|
|
5608
5693
|
];
|
|
5609
5694
|
function GlowFrame({ rect, elRef }) {
|
|
5610
5695
|
const GAP = 6;
|
|
5611
|
-
return /* @__PURE__ */ (0,
|
|
5696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5612
5697
|
"div",
|
|
5613
5698
|
{
|
|
5614
5699
|
ref: elRef,
|
|
@@ -5627,41 +5712,191 @@ function GlowFrame({ rect, elRef }) {
|
|
|
5627
5712
|
}
|
|
5628
5713
|
);
|
|
5629
5714
|
}
|
|
5630
|
-
function
|
|
5715
|
+
function getIframeVisibleClip(parentScroll) {
|
|
5716
|
+
if (!parentScroll) return null;
|
|
5717
|
+
const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
|
|
5718
|
+
const clipTop = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5719
|
+
const clipBottom = Math.min(
|
|
5720
|
+
window.innerHeight,
|
|
5721
|
+
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5722
|
+
);
|
|
5723
|
+
return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
|
|
5724
|
+
}
|
|
5725
|
+
function applyVisibleViewport(el, parentScroll) {
|
|
5726
|
+
const clip = getIframeVisibleClip(parentScroll);
|
|
5727
|
+
const top = clip?.top ?? 0;
|
|
5728
|
+
const height = clip ? clip.bottom - clip.top : window.innerHeight;
|
|
5729
|
+
el.style.top = `${top}px`;
|
|
5730
|
+
el.style.height = `${height}px`;
|
|
5731
|
+
}
|
|
5732
|
+
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
5733
|
+
const isAbove = transform.includes("translateY(-100%)");
|
|
5734
|
+
let visualTop = isAbove ? top - approxH : top;
|
|
5735
|
+
let visualBottom = isAbove ? top : top + approxH;
|
|
5736
|
+
const minTop = clip.top + gap;
|
|
5737
|
+
const maxBottom = clip.bottom - gap;
|
|
5738
|
+
if (visualTop >= minTop && visualBottom <= maxBottom) {
|
|
5739
|
+
return { top, transform };
|
|
5740
|
+
}
|
|
5741
|
+
const belowTop = rect.bottom + gap;
|
|
5742
|
+
if (belowTop + approxH <= maxBottom && belowTop >= minTop) {
|
|
5743
|
+
return { top: belowTop, transform: "translateX(-50%)" };
|
|
5744
|
+
}
|
|
5745
|
+
const aboveTop = rect.top - gap;
|
|
5746
|
+
if (aboveTop - approxH >= minTop && aboveTop <= maxBottom) {
|
|
5747
|
+
return { top: aboveTop, transform: "translateX(-50%) translateY(-100%)" };
|
|
5748
|
+
}
|
|
5749
|
+
if (belowTop + approxH <= maxBottom) {
|
|
5750
|
+
return { top: belowTop, transform: "translateX(-50%)" };
|
|
5751
|
+
}
|
|
5752
|
+
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
5753
|
+
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
5754
|
+
}
|
|
5755
|
+
function calcToolbarPos(rect, parentScroll, approxW = 330) {
|
|
5631
5756
|
const GAP = 8;
|
|
5632
5757
|
const APPROX_H = 36;
|
|
5633
|
-
const APPROX_W =
|
|
5758
|
+
const APPROX_W = approxW;
|
|
5759
|
+
const clip = getIframeVisibleClip(parentScroll);
|
|
5760
|
+
const clipTop = clip?.top ?? 0;
|
|
5634
5761
|
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
5635
5762
|
const visibleTop = rect.top - canvasTopInIframe;
|
|
5636
5763
|
const visibleBottom = rect.bottom - canvasTopInIframe;
|
|
5637
5764
|
const isTall = rect.height > APPROX_H + GAP;
|
|
5765
|
+
const spaceAbove = rect.top - (clipTop + GAP);
|
|
5766
|
+
const fitsAbove = spaceAbove >= APPROX_H + GAP;
|
|
5638
5767
|
let top;
|
|
5639
5768
|
let transform;
|
|
5640
|
-
if (visibleTop > 0 || !isTall) {
|
|
5769
|
+
if ((visibleTop > 0 || !isTall) && fitsAbove) {
|
|
5641
5770
|
top = rect.top - GAP;
|
|
5642
5771
|
transform = "translateX(-50%) translateY(-100%)";
|
|
5772
|
+
} else if (visibleTop > 0 || !isTall) {
|
|
5773
|
+
top = rect.bottom + GAP;
|
|
5774
|
+
transform = "translateX(-50%)";
|
|
5643
5775
|
} else if (visibleBottom > APPROX_H + GAP) {
|
|
5644
|
-
top =
|
|
5776
|
+
top = clipTop + GAP;
|
|
5645
5777
|
transform = "translateX(-50%)";
|
|
5646
5778
|
} else {
|
|
5647
5779
|
top = rect.bottom + GAP;
|
|
5648
5780
|
transform = "translateX(-50%)";
|
|
5649
5781
|
}
|
|
5782
|
+
if (clip) {
|
|
5783
|
+
const clamped = clampToolbarToClip(top, transform, rect, clip, APPROX_H, GAP);
|
|
5784
|
+
top = clamped.top;
|
|
5785
|
+
transform = clamped.transform;
|
|
5786
|
+
}
|
|
5650
5787
|
const rawLeft = rect.left + rect.width / 2;
|
|
5651
5788
|
const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
|
|
5652
5789
|
return { top, left, transform };
|
|
5653
5790
|
}
|
|
5791
|
+
var EDIT_LINK_ICON = /* @__PURE__ */ (0, import_jsx_runtime17.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: [
|
|
5792
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.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" }),
|
|
5793
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.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" })
|
|
5794
|
+
] });
|
|
5654
5795
|
function FloatingToolbar({
|
|
5655
5796
|
rect,
|
|
5656
5797
|
parentScroll,
|
|
5657
5798
|
elRef,
|
|
5799
|
+
variant = "rich-text",
|
|
5658
5800
|
onCommand,
|
|
5659
5801
|
activeCommands,
|
|
5660
5802
|
showEditLink,
|
|
5661
5803
|
onEditLink
|
|
5662
5804
|
}) {
|
|
5663
|
-
const
|
|
5664
|
-
|
|
5805
|
+
const approxW = variant === "link-action" ? 120 : 330;
|
|
5806
|
+
const { top, left, transform } = calcToolbarPos(rect, parentScroll, approxW);
|
|
5807
|
+
if (variant === "link-action") {
|
|
5808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5809
|
+
"div",
|
|
5810
|
+
{
|
|
5811
|
+
ref: elRef,
|
|
5812
|
+
"data-ohw-toolbar": "",
|
|
5813
|
+
style: {
|
|
5814
|
+
position: "fixed",
|
|
5815
|
+
top,
|
|
5816
|
+
left,
|
|
5817
|
+
transform,
|
|
5818
|
+
zIndex: 2147483647,
|
|
5819
|
+
background: "#fff",
|
|
5820
|
+
border: "1px solid #E7E5E4",
|
|
5821
|
+
borderRadius: 6,
|
|
5822
|
+
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5823
|
+
display: "flex",
|
|
5824
|
+
alignItems: "center",
|
|
5825
|
+
padding: 4,
|
|
5826
|
+
gap: 6,
|
|
5827
|
+
fontFamily: "sans-serif",
|
|
5828
|
+
pointerEvents: "auto",
|
|
5829
|
+
whiteSpace: "nowrap"
|
|
5830
|
+
},
|
|
5831
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5832
|
+
children: [
|
|
5833
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5834
|
+
"button",
|
|
5835
|
+
{
|
|
5836
|
+
type: "button",
|
|
5837
|
+
title: "Edit link",
|
|
5838
|
+
onMouseDown: (e) => {
|
|
5839
|
+
e.preventDefault();
|
|
5840
|
+
e.stopPropagation();
|
|
5841
|
+
onEditLink?.();
|
|
5842
|
+
},
|
|
5843
|
+
onClick: (e) => {
|
|
5844
|
+
e.preventDefault();
|
|
5845
|
+
e.stopPropagation();
|
|
5846
|
+
},
|
|
5847
|
+
onMouseEnter: (e) => {
|
|
5848
|
+
e.currentTarget.style.background = "#F5F5F4";
|
|
5849
|
+
},
|
|
5850
|
+
onMouseLeave: (e) => {
|
|
5851
|
+
e.currentTarget.style.background = "transparent";
|
|
5852
|
+
},
|
|
5853
|
+
style: {
|
|
5854
|
+
display: "flex",
|
|
5855
|
+
alignItems: "center",
|
|
5856
|
+
justifyContent: "center",
|
|
5857
|
+
border: "none",
|
|
5858
|
+
background: "transparent",
|
|
5859
|
+
borderRadius: 4,
|
|
5860
|
+
cursor: "pointer",
|
|
5861
|
+
color: "#1C1917",
|
|
5862
|
+
flexShrink: 0,
|
|
5863
|
+
padding: 6
|
|
5864
|
+
},
|
|
5865
|
+
children: EDIT_LINK_ICON
|
|
5866
|
+
}
|
|
5867
|
+
),
|
|
5868
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
5869
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5870
|
+
"button",
|
|
5871
|
+
{
|
|
5872
|
+
type: "button",
|
|
5873
|
+
title: "Coming soon",
|
|
5874
|
+
disabled: true,
|
|
5875
|
+
style: {
|
|
5876
|
+
display: "flex",
|
|
5877
|
+
alignItems: "center",
|
|
5878
|
+
justifyContent: "center",
|
|
5879
|
+
border: "none",
|
|
5880
|
+
background: "transparent",
|
|
5881
|
+
borderRadius: 4,
|
|
5882
|
+
cursor: "not-allowed",
|
|
5883
|
+
color: "#A8A29E",
|
|
5884
|
+
flexShrink: 0,
|
|
5885
|
+
padding: 6,
|
|
5886
|
+
opacity: 0.6
|
|
5887
|
+
},
|
|
5888
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: [
|
|
5889
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
5890
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
5891
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
5892
|
+
] })
|
|
5893
|
+
}
|
|
5894
|
+
)
|
|
5895
|
+
]
|
|
5896
|
+
}
|
|
5897
|
+
);
|
|
5898
|
+
}
|
|
5899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5665
5900
|
"div",
|
|
5666
5901
|
{
|
|
5667
5902
|
ref: elRef,
|
|
@@ -5686,11 +5921,11 @@ function FloatingToolbar({
|
|
|
5686
5921
|
},
|
|
5687
5922
|
onMouseDown: (e) => e.stopPropagation(),
|
|
5688
5923
|
children: [
|
|
5689
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
5690
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
5924
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react5.default.Fragment, { children: [
|
|
5925
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
5691
5926
|
btns.map((btn) => {
|
|
5692
5927
|
const isActive = activeCommands.has(btn.cmd);
|
|
5693
|
-
return /* @__PURE__ */ (0,
|
|
5928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5694
5929
|
"button",
|
|
5695
5930
|
{
|
|
5696
5931
|
title: btn.title,
|
|
@@ -5716,7 +5951,7 @@ function FloatingToolbar({
|
|
|
5716
5951
|
flexShrink: 0,
|
|
5717
5952
|
padding: 6
|
|
5718
5953
|
},
|
|
5719
|
-
children: /* @__PURE__ */ (0,
|
|
5954
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5720
5955
|
"svg",
|
|
5721
5956
|
{
|
|
5722
5957
|
width: "16",
|
|
@@ -5736,7 +5971,7 @@ function FloatingToolbar({
|
|
|
5736
5971
|
);
|
|
5737
5972
|
})
|
|
5738
5973
|
] }, gi)),
|
|
5739
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
5974
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5740
5975
|
"button",
|
|
5741
5976
|
{
|
|
5742
5977
|
type: "button",
|
|
@@ -5768,10 +6003,7 @@ function FloatingToolbar({
|
|
|
5768
6003
|
flexShrink: 0,
|
|
5769
6004
|
padding: 6
|
|
5770
6005
|
},
|
|
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
|
-
] })
|
|
6006
|
+
children: EDIT_LINK_ICON
|
|
5775
6007
|
}
|
|
5776
6008
|
) : null
|
|
5777
6009
|
]
|
|
@@ -5788,7 +6020,7 @@ function StateToggle({
|
|
|
5788
6020
|
states,
|
|
5789
6021
|
onStateChange
|
|
5790
6022
|
}) {
|
|
5791
|
-
return /* @__PURE__ */ (0,
|
|
6023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5792
6024
|
ToggleGroup,
|
|
5793
6025
|
{
|
|
5794
6026
|
"data-ohw-state-toggle": "",
|
|
@@ -5802,7 +6034,7 @@ function StateToggle({
|
|
|
5802
6034
|
left: rect.right - 8,
|
|
5803
6035
|
transform: "translateX(-100%)"
|
|
5804
6036
|
},
|
|
5805
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
6037
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
5806
6038
|
}
|
|
5807
6039
|
);
|
|
5808
6040
|
}
|
|
@@ -5862,9 +6094,17 @@ function OhhwellsBridge() {
|
|
|
5862
6094
|
const [fetchState, setFetchState] = (0, import_react5.useState)("idle");
|
|
5863
6095
|
const autoSaveTimers = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
5864
6096
|
const activeElRef = (0, import_react5.useRef)(null);
|
|
6097
|
+
const selectedElRef = (0, import_react5.useRef)(null);
|
|
5865
6098
|
const originalContentRef = (0, import_react5.useRef)(null);
|
|
5866
6099
|
const activeStateElRef = (0, import_react5.useRef)(null);
|
|
5867
6100
|
const parentScrollRef = (0, import_react5.useRef)(null);
|
|
6101
|
+
const visibleViewportRef = (0, import_react5.useRef)(null);
|
|
6102
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react5.useState)(null);
|
|
6103
|
+
const attachVisibleViewport = (0, import_react5.useCallback)((node) => {
|
|
6104
|
+
visibleViewportRef.current = node;
|
|
6105
|
+
setDialogPortalContainer(node);
|
|
6106
|
+
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6107
|
+
}, []);
|
|
5868
6108
|
const toolbarElRef = (0, import_react5.useRef)(null);
|
|
5869
6109
|
const glowElRef = (0, import_react5.useRef)(null);
|
|
5870
6110
|
const hoveredImageRef = (0, import_react5.useRef)(null);
|
|
@@ -5877,6 +6117,10 @@ function OhhwellsBridge() {
|
|
|
5877
6117
|
});
|
|
5878
6118
|
const deactivateRef = (0, import_react5.useRef)(() => {
|
|
5879
6119
|
});
|
|
6120
|
+
const selectRef = (0, import_react5.useRef)(() => {
|
|
6121
|
+
});
|
|
6122
|
+
const deselectRef = (0, import_react5.useRef)(() => {
|
|
6123
|
+
});
|
|
5880
6124
|
const refreshActiveCommandsRef = (0, import_react5.useRef)(() => {
|
|
5881
6125
|
});
|
|
5882
6126
|
const postToParentRef = (0, import_react5.useRef)(postToParent);
|
|
@@ -5884,9 +6128,13 @@ function OhhwellsBridge() {
|
|
|
5884
6128
|
const sectionsLoadedRef = (0, import_react5.useRef)(false);
|
|
5885
6129
|
const pendingScheduleConfigRequests = (0, import_react5.useRef)([]);
|
|
5886
6130
|
const [toolbarRect, setToolbarRect] = (0, import_react5.useState)(null);
|
|
6131
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react5.useState)("none");
|
|
6132
|
+
const toolbarVariantRef = (0, import_react5.useRef)("none");
|
|
6133
|
+
toolbarVariantRef.current = toolbarVariant;
|
|
5887
6134
|
const [toggleState, setToggleState] = (0, import_react5.useState)(null);
|
|
5888
6135
|
const [maxBadge, setMaxBadge] = (0, import_react5.useState)(null);
|
|
5889
6136
|
const [activeCommands, setActiveCommands] = (0, import_react5.useState)(/* @__PURE__ */ new Set());
|
|
6137
|
+
const [sectionGap, setSectionGap] = (0, import_react5.useState)(null);
|
|
5890
6138
|
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react5.useState)(false);
|
|
5891
6139
|
const [linkPopover, setLinkPopover] = (0, import_react5.useState)(null);
|
|
5892
6140
|
const [sitePages, setSitePages] = (0, import_react5.useState)([]);
|
|
@@ -5953,7 +6201,6 @@ function OhhwellsBridge() {
|
|
|
5953
6201
|
if (!useFixtures) postToParent({ type: "ow:request-site-pages" });
|
|
5954
6202
|
return () => window.removeEventListener("message", onSitePages);
|
|
5955
6203
|
}, [isEditMode, postToParent]);
|
|
5956
|
-
const [sectionGap, setSectionGap] = (0, import_react5.useState)(null);
|
|
5957
6204
|
(0, import_react5.useEffect)(() => {
|
|
5958
6205
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
5959
6206
|
void loadAllSectionsManifest().then((manifest) => {
|
|
@@ -5963,7 +6210,7 @@ function OhhwellsBridge() {
|
|
|
5963
6210
|
}, [isEditMode]);
|
|
5964
6211
|
(0, import_react5.useEffect)(() => {
|
|
5965
6212
|
const update = () => {
|
|
5966
|
-
const el = activeElRef.current;
|
|
6213
|
+
const el = activeElRef.current ?? selectedElRef.current;
|
|
5967
6214
|
if (el) setToolbarRect(el.getBoundingClientRect());
|
|
5968
6215
|
setToggleState((prev) => {
|
|
5969
6216
|
if (!prev || !activeStateElRef.current) return prev;
|
|
@@ -6031,19 +6278,41 @@ function OhhwellsBridge() {
|
|
|
6031
6278
|
}
|
|
6032
6279
|
el.removeAttribute("contenteditable");
|
|
6033
6280
|
activeElRef.current = null;
|
|
6034
|
-
|
|
6281
|
+
if (!selectedElRef.current) {
|
|
6282
|
+
setToolbarRect(null);
|
|
6283
|
+
setToolbarVariant("none");
|
|
6284
|
+
}
|
|
6035
6285
|
setMaxBadge(null);
|
|
6036
6286
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6037
6287
|
setToolbarShowEditLink(false);
|
|
6038
6288
|
postToParent({ type: "ow:exit-edit" });
|
|
6039
6289
|
}, [postToParent]);
|
|
6290
|
+
const deselect = (0, import_react5.useCallback)(() => {
|
|
6291
|
+
selectedElRef.current = null;
|
|
6292
|
+
if (!activeElRef.current) {
|
|
6293
|
+
setToolbarRect(null);
|
|
6294
|
+
setToolbarVariant("none");
|
|
6295
|
+
}
|
|
6296
|
+
}, []);
|
|
6297
|
+
const select = (0, import_react5.useCallback)((anchor) => {
|
|
6298
|
+
if (!isNavbarButton(anchor)) return;
|
|
6299
|
+
if (activeElRef.current) deactivate();
|
|
6300
|
+
selectedElRef.current = anchor;
|
|
6301
|
+
clearHrefKeyHover(anchor);
|
|
6302
|
+
setToolbarVariant("link-action");
|
|
6303
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
6304
|
+
setToolbarShowEditLink(false);
|
|
6305
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6306
|
+
}, [deactivate]);
|
|
6040
6307
|
const activate = (0, import_react5.useCallback)((el) => {
|
|
6041
6308
|
if (activeElRef.current === el) return;
|
|
6309
|
+
selectedElRef.current = null;
|
|
6042
6310
|
deactivate();
|
|
6043
6311
|
if (hoveredImageRef.current) {
|
|
6044
6312
|
hoveredImageRef.current = null;
|
|
6045
6313
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
6046
6314
|
}
|
|
6315
|
+
setToolbarVariant("rich-text");
|
|
6047
6316
|
el.setAttribute("contenteditable", "true");
|
|
6048
6317
|
el.removeAttribute("data-ohw-hovered");
|
|
6049
6318
|
activeElRef.current = el;
|
|
@@ -6056,6 +6325,8 @@ function OhhwellsBridge() {
|
|
|
6056
6325
|
}, [deactivate, postToParent]);
|
|
6057
6326
|
activateRef.current = activate;
|
|
6058
6327
|
deactivateRef.current = deactivate;
|
|
6328
|
+
selectRef.current = select;
|
|
6329
|
+
deselectRef.current = deselect;
|
|
6059
6330
|
(0, import_react5.useLayoutEffect)(() => {
|
|
6060
6331
|
if (!subdomain || isEditMode) {
|
|
6061
6332
|
setFetchState("done");
|
|
@@ -6269,12 +6540,12 @@ function OhhwellsBridge() {
|
|
|
6269
6540
|
if (editable.dataset.ohwEditable === "link") {
|
|
6270
6541
|
e.preventDefault();
|
|
6271
6542
|
e.stopPropagation();
|
|
6543
|
+
deselectRef.current();
|
|
6272
6544
|
deactivateRef.current();
|
|
6273
6545
|
bumpLinkPopoverGrace();
|
|
6274
6546
|
setLinkPopoverRef.current({
|
|
6275
6547
|
key: editable.dataset.ohwKey ?? "",
|
|
6276
|
-
target: getLinkHref(editable)
|
|
6277
|
-
rect: editable.getBoundingClientRect()
|
|
6548
|
+
target: getLinkHref(editable)
|
|
6278
6549
|
});
|
|
6279
6550
|
return;
|
|
6280
6551
|
}
|
|
@@ -6284,11 +6555,31 @@ function OhhwellsBridge() {
|
|
|
6284
6555
|
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
6285
6556
|
return;
|
|
6286
6557
|
}
|
|
6558
|
+
const hrefCtx = getHrefKeyFromElement(editable);
|
|
6559
|
+
if (hrefCtx && isNavbarButton(hrefCtx.anchor)) {
|
|
6560
|
+
e.preventDefault();
|
|
6561
|
+
e.stopPropagation();
|
|
6562
|
+
const { anchor: anchor2 } = hrefCtx;
|
|
6563
|
+
if (selectedElRef.current === anchor2) {
|
|
6564
|
+
activateRef.current(editable);
|
|
6565
|
+
return;
|
|
6566
|
+
}
|
|
6567
|
+
selectRef.current(anchor2);
|
|
6568
|
+
return;
|
|
6569
|
+
}
|
|
6287
6570
|
e.preventDefault();
|
|
6288
6571
|
e.stopPropagation();
|
|
6289
6572
|
activateRef.current(editable);
|
|
6290
6573
|
return;
|
|
6291
6574
|
}
|
|
6575
|
+
const hrefAnchor = target.closest("[data-ohw-href-key]");
|
|
6576
|
+
if (hrefAnchor && isNavbarButton(hrefAnchor)) {
|
|
6577
|
+
e.preventDefault();
|
|
6578
|
+
e.stopPropagation();
|
|
6579
|
+
if (selectedElRef.current === hrefAnchor) return;
|
|
6580
|
+
selectRef.current(hrefAnchor);
|
|
6581
|
+
return;
|
|
6582
|
+
}
|
|
6292
6583
|
if (activeElRef.current) {
|
|
6293
6584
|
const sel = window.getSelection();
|
|
6294
6585
|
if (sel && !sel.isCollapsed) {
|
|
@@ -6303,15 +6594,22 @@ function OhhwellsBridge() {
|
|
|
6303
6594
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
6304
6595
|
if (hrefCtx && (hrefCtx.anchor === target || hrefCtx.anchor.contains(target))) return;
|
|
6305
6596
|
}
|
|
6597
|
+
if (linkPopoverOpenRef.current && selectedElRef.current) {
|
|
6598
|
+
const selected = selectedElRef.current;
|
|
6599
|
+
if (selected === target || selected.contains(target)) return;
|
|
6600
|
+
}
|
|
6306
6601
|
if (linkPopoverOpenRef.current) {
|
|
6307
6602
|
setLinkPopoverRef.current(null);
|
|
6308
6603
|
return;
|
|
6309
6604
|
}
|
|
6605
|
+
deselectRef.current();
|
|
6310
6606
|
deactivateRef.current();
|
|
6311
6607
|
};
|
|
6312
6608
|
const handleMouseOver = (e) => {
|
|
6313
6609
|
const editable = e.target.closest("[data-ohw-editable]");
|
|
6314
6610
|
if (!editable) return;
|
|
6611
|
+
const selected = selectedElRef.current;
|
|
6612
|
+
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
6315
6613
|
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
|
|
6316
6614
|
editable.setAttribute("data-ohw-hovered", "");
|
|
6317
6615
|
}
|
|
@@ -6798,6 +7096,7 @@ function OhhwellsBridge() {
|
|
|
6798
7096
|
setLinkPopoverRef.current(null);
|
|
6799
7097
|
return;
|
|
6800
7098
|
}
|
|
7099
|
+
deselectRef.current();
|
|
6801
7100
|
deactivateRef.current();
|
|
6802
7101
|
};
|
|
6803
7102
|
window.addEventListener("message", handleDeactivate);
|
|
@@ -6806,6 +7105,10 @@ function OhhwellsBridge() {
|
|
|
6806
7105
|
setLinkPopoverRef.current(null);
|
|
6807
7106
|
return;
|
|
6808
7107
|
}
|
|
7108
|
+
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
7109
|
+
deselectRef.current();
|
|
7110
|
+
return;
|
|
7111
|
+
}
|
|
6809
7112
|
if (e.key !== "Escape") return;
|
|
6810
7113
|
const el = activeElRef.current;
|
|
6811
7114
|
if (el && originalContentRef.current !== null) {
|
|
@@ -6815,13 +7118,16 @@ function OhhwellsBridge() {
|
|
|
6815
7118
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: originalContentRef.current }] });
|
|
6816
7119
|
}
|
|
6817
7120
|
}
|
|
7121
|
+
deselectRef.current();
|
|
6818
7122
|
deactivateRef.current();
|
|
6819
7123
|
};
|
|
6820
7124
|
const handleScroll = () => {
|
|
6821
|
-
|
|
6822
|
-
|
|
7125
|
+
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7126
|
+
if (focusEl) {
|
|
7127
|
+
const r2 = focusEl.getBoundingClientRect();
|
|
6823
7128
|
applyToolbarPos(r2);
|
|
6824
|
-
|
|
7129
|
+
setToolbarRect(r2);
|
|
7130
|
+
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
6825
7131
|
}
|
|
6826
7132
|
if (activeStateElRef.current) {
|
|
6827
7133
|
const rect = activeStateElRef.current.getBoundingClientRect();
|
|
@@ -6946,8 +7252,9 @@ function OhhwellsBridge() {
|
|
|
6946
7252
|
};
|
|
6947
7253
|
const applyToolbarPos = (rect) => {
|
|
6948
7254
|
const ps = parentScrollRef.current;
|
|
7255
|
+
const approxW = toolbarVariantRef.current === "link-action" ? 120 : 330;
|
|
6949
7256
|
if (toolbarElRef.current) {
|
|
6950
|
-
const { top, left, transform } = calcToolbarPos(rect, ps);
|
|
7257
|
+
const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
|
|
6951
7258
|
toolbarElRef.current.style.top = `${top}px`;
|
|
6952
7259
|
toolbarElRef.current.style.left = `${left}px`;
|
|
6953
7260
|
toolbarElRef.current.style.transform = transform;
|
|
@@ -6962,7 +7269,11 @@ function OhhwellsBridge() {
|
|
|
6962
7269
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
6963
7270
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
6964
7271
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
6965
|
-
if (
|
|
7272
|
+
if (visibleViewportRef.current) {
|
|
7273
|
+
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7274
|
+
}
|
|
7275
|
+
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7276
|
+
if (focusEl) applyToolbarPos(focusEl.getBoundingClientRect());
|
|
6966
7277
|
};
|
|
6967
7278
|
const handleClickAt = (e) => {
|
|
6968
7279
|
if (e.data?.type !== "ow:click-at") return;
|
|
@@ -7012,6 +7323,12 @@ function OhhwellsBridge() {
|
|
|
7012
7323
|
window.addEventListener("message", handleParentScroll);
|
|
7013
7324
|
window.addEventListener("message", handlePointerSync);
|
|
7014
7325
|
window.addEventListener("message", handleClickAt);
|
|
7326
|
+
const handleViewportResize = () => {
|
|
7327
|
+
if (visibleViewportRef.current) {
|
|
7328
|
+
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7329
|
+
}
|
|
7330
|
+
};
|
|
7331
|
+
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
7015
7332
|
document.addEventListener("click", handleClick, true);
|
|
7016
7333
|
document.addEventListener("paste", handlePaste, true);
|
|
7017
7334
|
document.addEventListener("input", handleInput, true);
|
|
@@ -7049,6 +7366,7 @@ function OhhwellsBridge() {
|
|
|
7049
7366
|
window.removeEventListener("message", handleAnimLock);
|
|
7050
7367
|
window.removeEventListener("message", handleCanvasHeight);
|
|
7051
7368
|
window.removeEventListener("message", handleParentScroll);
|
|
7369
|
+
window.removeEventListener("resize", handleViewportResize);
|
|
7052
7370
|
window.removeEventListener("message", handlePointerSync);
|
|
7053
7371
|
window.removeEventListener("message", handleClickAt);
|
|
7054
7372
|
window.removeEventListener("message", handleHydrate);
|
|
@@ -7136,10 +7454,22 @@ function OhhwellsBridge() {
|
|
|
7136
7454
|
bumpLinkPopoverGrace();
|
|
7137
7455
|
setLinkPopover({
|
|
7138
7456
|
key: hrefCtx.key,
|
|
7139
|
-
target: getLinkHref(hrefCtx.anchor)
|
|
7140
|
-
rect: hrefCtx.anchor.getBoundingClientRect()
|
|
7457
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
7141
7458
|
});
|
|
7142
|
-
|
|
7459
|
+
deactivate();
|
|
7460
|
+
}, [deactivate]);
|
|
7461
|
+
const openLinkPopoverForSelected = (0, import_react5.useCallback)(() => {
|
|
7462
|
+
const anchor = selectedElRef.current;
|
|
7463
|
+
if (!anchor) return;
|
|
7464
|
+
const key = anchor.getAttribute("data-ohw-href-key");
|
|
7465
|
+
if (!key) return;
|
|
7466
|
+
bumpLinkPopoverGrace();
|
|
7467
|
+
setLinkPopover({
|
|
7468
|
+
key,
|
|
7469
|
+
target: getLinkHref(anchor)
|
|
7470
|
+
});
|
|
7471
|
+
deselect();
|
|
7472
|
+
}, [deselect]);
|
|
7143
7473
|
const handleLinkPopoverSubmit = (0, import_react5.useCallback)(
|
|
7144
7474
|
(target) => {
|
|
7145
7475
|
if (!linkPopover) return;
|
|
@@ -7154,12 +7484,14 @@ function OhhwellsBridge() {
|
|
|
7154
7484
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
7155
7485
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
7156
7486
|
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
7157
|
-
/* @__PURE__ */ (0,
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
/* @__PURE__ */ (0,
|
|
7487
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
7488
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
7489
|
+
toolbarRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
7490
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(GlowFrame, { rect: toolbarRect, elRef: glowElRef }),
|
|
7491
|
+
toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7161
7492
|
FloatingToolbar,
|
|
7162
7493
|
{
|
|
7494
|
+
variant: "rich-text",
|
|
7163
7495
|
rect: toolbarRect,
|
|
7164
7496
|
parentScroll: parentScrollRef.current,
|
|
7165
7497
|
elRef: toolbarElRef,
|
|
@@ -7168,9 +7500,21 @@ function OhhwellsBridge() {
|
|
|
7168
7500
|
showEditLink,
|
|
7169
7501
|
onEditLink: openLinkPopoverForActive
|
|
7170
7502
|
}
|
|
7503
|
+
),
|
|
7504
|
+
toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7505
|
+
FloatingToolbar,
|
|
7506
|
+
{
|
|
7507
|
+
variant: "link-action",
|
|
7508
|
+
rect: toolbarRect,
|
|
7509
|
+
parentScroll: parentScrollRef.current,
|
|
7510
|
+
elRef: toolbarElRef,
|
|
7511
|
+
onCommand: handleCommand,
|
|
7512
|
+
activeCommands,
|
|
7513
|
+
onEditLink: openLinkPopoverForSelected
|
|
7514
|
+
}
|
|
7171
7515
|
)
|
|
7172
7516
|
] }),
|
|
7173
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
7517
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
7174
7518
|
"div",
|
|
7175
7519
|
{
|
|
7176
7520
|
"data-ohw-max-badge": "",
|
|
@@ -7196,7 +7540,7 @@ function OhhwellsBridge() {
|
|
|
7196
7540
|
]
|
|
7197
7541
|
}
|
|
7198
7542
|
),
|
|
7199
|
-
toggleState && /* @__PURE__ */ (0,
|
|
7543
|
+
toggleState && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7200
7544
|
StateToggle,
|
|
7201
7545
|
{
|
|
7202
7546
|
rect: toggleState.rect,
|
|
@@ -7205,12 +7549,36 @@ function OhhwellsBridge() {
|
|
|
7205
7549
|
onStateChange: handleStateChange
|
|
7206
7550
|
}
|
|
7207
7551
|
),
|
|
7208
|
-
|
|
7552
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
7553
|
+
"div",
|
|
7554
|
+
{
|
|
7555
|
+
"data-ohw-section-insert-line": "",
|
|
7556
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
7557
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
7558
|
+
children: [
|
|
7559
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
7560
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7561
|
+
Badge,
|
|
7562
|
+
{
|
|
7563
|
+
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",
|
|
7564
|
+
onClick: () => {
|
|
7565
|
+
window.parent.postMessage(
|
|
7566
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
7567
|
+
"*"
|
|
7568
|
+
);
|
|
7569
|
+
},
|
|
7570
|
+
children: "Add Section"
|
|
7571
|
+
}
|
|
7572
|
+
),
|
|
7573
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
7574
|
+
]
|
|
7575
|
+
}
|
|
7576
|
+
),
|
|
7577
|
+
linkPopover ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7209
7578
|
LinkPopover,
|
|
7210
7579
|
{
|
|
7211
|
-
rect: linkPopover.rect,
|
|
7212
|
-
parentScroll: parentScrollRef.current,
|
|
7213
7580
|
panelRef: linkPopoverPanelRef,
|
|
7581
|
+
portalContainer: dialogPortalContainer,
|
|
7214
7582
|
open: true,
|
|
7215
7583
|
mode: "edit",
|
|
7216
7584
|
pages: sitePages,
|
|
@@ -7221,15 +7589,15 @@ function OhhwellsBridge() {
|
|
|
7221
7589
|
onSubmit: handleLinkPopoverSubmit
|
|
7222
7590
|
}
|
|
7223
7591
|
) : null,
|
|
7224
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
7592
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
7225
7593
|
"div",
|
|
7226
7594
|
{
|
|
7227
7595
|
"data-ohw-section-insert-line": "",
|
|
7228
7596
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
7229
7597
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
7230
7598
|
children: [
|
|
7231
|
-
/* @__PURE__ */ (0,
|
|
7232
|
-
/* @__PURE__ */ (0,
|
|
7599
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
7600
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7233
7601
|
Badge,
|
|
7234
7602
|
{
|
|
7235
7603
|
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",
|
|
@@ -7242,7 +7610,7 @@ function OhhwellsBridge() {
|
|
|
7242
7610
|
children: "Add Section"
|
|
7243
7611
|
}
|
|
7244
7612
|
),
|
|
7245
|
-
/* @__PURE__ */ (0,
|
|
7613
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
7246
7614
|
]
|
|
7247
7615
|
}
|
|
7248
7616
|
)
|