@ohhwells/bridge 0.1.38-next.68 → 0.1.38
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 +1 -13
- package/dist/index.cjs +682 -3006
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -98
- package/dist/index.d.ts +6 -98
- package/dist/index.js +691 -3012
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -169
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import
|
|
4
|
+
import React9, { useCallback as useCallback2, useEffect as useEffect4, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState5 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -10,9 +10,6 @@ var linkHrefStore = /* @__PURE__ */ new Map();
|
|
|
10
10
|
function setStoredLinkHref(key, href) {
|
|
11
11
|
linkHrefStore.set(key, href);
|
|
12
12
|
}
|
|
13
|
-
function getStoredLinkHref(key) {
|
|
14
|
-
return linkHrefStore.get(key);
|
|
15
|
-
}
|
|
16
13
|
function enforceLinkHrefs() {
|
|
17
14
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
18
15
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -48,13 +45,12 @@ function useLinkHrefGuardian(...deps) {
|
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
// src/ui/SchedulingWidget.tsx
|
|
51
|
-
import {
|
|
48
|
+
import { useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
52
49
|
|
|
53
50
|
// src/ui/EmailCaptureModal.tsx
|
|
54
51
|
import { useState } from "react";
|
|
55
52
|
import { Dialog } from "radix-ui";
|
|
56
53
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
57
|
-
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
58
54
|
function Spinner() {
|
|
59
55
|
return /* @__PURE__ */ jsxs(
|
|
60
56
|
"svg",
|
|
@@ -88,17 +84,12 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
88
84
|
const [error, setError] = useState(null);
|
|
89
85
|
const isBook = title === "Confirm your spot";
|
|
90
86
|
const handleSubmit = async () => {
|
|
91
|
-
|
|
92
|
-
if (!trimmed) return;
|
|
93
|
-
if (!isValidEmail(trimmed)) {
|
|
94
|
-
setError("Please enter a valid email address.");
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
87
|
+
if (!email.trim()) return;
|
|
97
88
|
setLoading(true);
|
|
98
89
|
setError(null);
|
|
99
90
|
try {
|
|
100
|
-
await onSubmit(
|
|
101
|
-
setSubmittedEmail(
|
|
91
|
+
await onSubmit(email.trim());
|
|
92
|
+
setSubmittedEmail(email.trim());
|
|
102
93
|
setSuccess(true);
|
|
103
94
|
} catch (e) {
|
|
104
95
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -173,10 +164,7 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
173
164
|
{
|
|
174
165
|
type: "email",
|
|
175
166
|
value: email,
|
|
176
|
-
onChange: (e) =>
|
|
177
|
-
setEmail(e.target.value);
|
|
178
|
-
if (error) setError(null);
|
|
179
|
-
},
|
|
167
|
+
onChange: (e) => setEmail(e.target.value),
|
|
180
168
|
onKeyDown: handleKeyDown,
|
|
181
169
|
placeholder: "hello@gmail.com",
|
|
182
170
|
autoFocus: true,
|
|
@@ -233,20 +221,12 @@ function formatClassTime(cls) {
|
|
|
233
221
|
const em = endTotal % 60;
|
|
234
222
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
235
223
|
}
|
|
236
|
-
function formatBookingLabel(cls) {
|
|
237
|
-
const price = cls.price;
|
|
238
|
-
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
239
|
-
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
240
|
-
}
|
|
241
224
|
function getBookingsOnDate(cls, date) {
|
|
242
225
|
if (!cls.bookings?.length) return 0;
|
|
243
|
-
const
|
|
244
|
-
target.setHours(0, 0, 0, 0);
|
|
226
|
+
const ds = date.toISOString().split("T")[0];
|
|
245
227
|
return cls.bookings.filter((b) => {
|
|
246
228
|
try {
|
|
247
|
-
|
|
248
|
-
bookingDate.setHours(0, 0, 0, 0);
|
|
249
|
-
return bookingDate.getTime() === target.getTime();
|
|
229
|
+
return new Date(b.classDate).toISOString().split("T")[0] === ds;
|
|
250
230
|
} catch {
|
|
251
231
|
return false;
|
|
252
232
|
}
|
|
@@ -511,7 +491,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
511
491
|
}
|
|
512
492
|
)
|
|
513
493
|
] }),
|
|
514
|
-
|
|
494
|
+
/* @__PURE__ */ jsx2("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
515
495
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
516
496
|
available,
|
|
517
497
|
"/",
|
|
@@ -523,10 +503,9 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
523
503
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
524
504
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
525
505
|
/* @__PURE__ */ jsx2("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
526
|
-
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
527
|
-
cls.description && /* @__PURE__ */ jsx2("span", { className: "font-body text-sm font-normal text-(--color-dark,#200C02) opacity-70 block truncate", children: cls.description })
|
|
506
|
+
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
528
507
|
] }),
|
|
529
|
-
|
|
508
|
+
/* @__PURE__ */ jsx2("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
530
509
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
531
510
|
available,
|
|
532
511
|
"/",
|
|
@@ -551,7 +530,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
551
530
|
if (!cls.id) return;
|
|
552
531
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
553
532
|
},
|
|
554
|
-
children: isFull ? "Join Waitlist" :
|
|
533
|
+
children: isFull ? "Join Waitlist" : "Book Now"
|
|
555
534
|
}
|
|
556
535
|
)
|
|
557
536
|
] })
|
|
@@ -593,17 +572,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
593
572
|
const [isHovered, setIsHovered] = useState2(false);
|
|
594
573
|
const [modalState, setModalState] = useState2(null);
|
|
595
574
|
const switchScheduleIdRef = useRef(null);
|
|
596
|
-
const liveScheduleIdRef = useRef(null);
|
|
597
|
-
const refetchLiveSchedule = useCallback(async () => {
|
|
598
|
-
const id = liveScheduleIdRef.current;
|
|
599
|
-
if (!id) return;
|
|
600
|
-
try {
|
|
601
|
-
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
602
|
-
const data = await res.json();
|
|
603
|
-
if (data?.id) setSchedule(data);
|
|
604
|
-
} catch {
|
|
605
|
-
}
|
|
606
|
-
}, []);
|
|
607
575
|
const dates = useMemo(() => {
|
|
608
576
|
const today = /* @__PURE__ */ new Date();
|
|
609
577
|
today.setHours(0, 0, 0, 0);
|
|
@@ -623,18 +591,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
623
591
|
}
|
|
624
592
|
}
|
|
625
593
|
}, [schedule, dates]);
|
|
626
|
-
useEffect(() => {
|
|
627
|
-
if (typeof window === "undefined") return;
|
|
628
|
-
const onVisible = () => {
|
|
629
|
-
if (!document.hidden) void refetchLiveSchedule();
|
|
630
|
-
};
|
|
631
|
-
window.addEventListener("focus", refetchLiveSchedule);
|
|
632
|
-
document.addEventListener("visibilitychange", onVisible);
|
|
633
|
-
return () => {
|
|
634
|
-
window.removeEventListener("focus", refetchLiveSchedule);
|
|
635
|
-
document.removeEventListener("visibilitychange", onVisible);
|
|
636
|
-
};
|
|
637
|
-
}, [refetchLiveSchedule]);
|
|
638
594
|
useEffect(() => {
|
|
639
595
|
if (typeof window === "undefined") return;
|
|
640
596
|
const isInEditor = window.self !== window.top;
|
|
@@ -696,7 +652,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
696
652
|
setLoading(false);
|
|
697
653
|
return;
|
|
698
654
|
}
|
|
699
|
-
|
|
655
|
+
;
|
|
700
656
|
(async () => {
|
|
701
657
|
try {
|
|
702
658
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -753,14 +709,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
753
709
|
const data = await res.json().catch(() => ({}));
|
|
754
710
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
755
711
|
}
|
|
756
|
-
await refetchLiveSchedule();
|
|
757
712
|
};
|
|
758
713
|
const handleReplaceSchedule = () => {
|
|
759
714
|
setIsHovered(false);
|
|
760
|
-
|
|
761
|
-
{
|
|
762
|
-
|
|
763
|
-
|
|
715
|
+
if (schedule) {
|
|
716
|
+
window.parent.postMessage({
|
|
717
|
+
type: "ow:schedule-connected",
|
|
718
|
+
schedule: { id: schedule.id, name: schedule.name },
|
|
719
|
+
insertAfter
|
|
720
|
+
}, "*");
|
|
721
|
+
} else {
|
|
722
|
+
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
723
|
+
}
|
|
764
724
|
};
|
|
765
725
|
if (!inEditor && !loading && !schedule) return null;
|
|
766
726
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -803,19 +763,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
803
763
|
),
|
|
804
764
|
/* @__PURE__ */ jsxs2("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
805
765
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center gap-4", children: [
|
|
806
|
-
/* @__PURE__ */ jsx2(
|
|
807
|
-
"h2",
|
|
808
|
-
{
|
|
809
|
-
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
810
|
-
style: {
|
|
811
|
-
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
812
|
-
fontWeight: "var(--font-weight-heading, 400)",
|
|
813
|
-
lineHeight: 1.05,
|
|
814
|
-
letterSpacing: "-0.02em"
|
|
815
|
-
},
|
|
816
|
-
children: schedule?.name ?? "Book an appointment"
|
|
817
|
-
}
|
|
818
|
-
),
|
|
766
|
+
/* @__PURE__ */ jsx2("h2", { className: "font-display text-4xl sm:text-5xl font-bold text-center m-0 text-(--color-dark,#200C02)", children: schedule?.name ?? "Book an appointment" }),
|
|
819
767
|
schedule?.description && /* @__PURE__ */ jsx2("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
820
768
|
] }),
|
|
821
769
|
/* @__PURE__ */ jsxs2("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4401,7 +4349,6 @@ function ItemActionToolbar({
|
|
|
4401
4349
|
onEditLink,
|
|
4402
4350
|
onAddItem,
|
|
4403
4351
|
onMore,
|
|
4404
|
-
editLinkDisabled = false,
|
|
4405
4352
|
addItemDisabled = true,
|
|
4406
4353
|
moreDisabled = true,
|
|
4407
4354
|
tooltipSide = "bottom"
|
|
@@ -4410,12 +4357,10 @@ function ItemActionToolbar({
|
|
|
4410
4357
|
/* @__PURE__ */ jsx8(
|
|
4411
4358
|
ToolbarActionTooltip,
|
|
4412
4359
|
{
|
|
4413
|
-
label: "
|
|
4360
|
+
label: "Add link",
|
|
4414
4361
|
side: tooltipSide,
|
|
4415
|
-
disabled: editLinkDisabled,
|
|
4416
4362
|
buttonProps: {
|
|
4417
4363
|
onMouseDown: (e) => {
|
|
4418
|
-
if (editLinkDisabled) return;
|
|
4419
4364
|
e.preventDefault();
|
|
4420
4365
|
e.stopPropagation();
|
|
4421
4366
|
onEditLink?.();
|
|
@@ -4493,7 +4438,7 @@ function getChromeStyle(state) {
|
|
|
4493
4438
|
case "dragging":
|
|
4494
4439
|
return {
|
|
4495
4440
|
border: `2px solid ${PRIMARY}`,
|
|
4496
|
-
boxShadow:
|
|
4441
|
+
boxShadow: DRAG_SHADOW
|
|
4497
4442
|
};
|
|
4498
4443
|
default:
|
|
4499
4444
|
return {};
|
|
@@ -4509,8 +4454,6 @@ function ItemInteractionLayer({
|
|
|
4509
4454
|
dragHandleLabel = "Reorder item",
|
|
4510
4455
|
onDragHandleDragStart,
|
|
4511
4456
|
onDragHandleDragEnd,
|
|
4512
|
-
onItemPointerDown,
|
|
4513
|
-
onItemClick,
|
|
4514
4457
|
chromeGap = 6,
|
|
4515
4458
|
className
|
|
4516
4459
|
}) {
|
|
@@ -4518,8 +4461,7 @@ function ItemInteractionLayer({
|
|
|
4518
4461
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4519
4462
|
const isDragging = state === "dragging";
|
|
4520
4463
|
const showToolbar = isActive && toolbar;
|
|
4521
|
-
const showDragHandle =
|
|
4522
|
-
const itemDragEnabled = isActive && showHandle && !isDragging && !dragDisabled;
|
|
4464
|
+
const showDragHandle = isActive && showHandle && !isDragging;
|
|
4523
4465
|
return /* @__PURE__ */ jsxs4(
|
|
4524
4466
|
"div",
|
|
4525
4467
|
{
|
|
@@ -4544,28 +4486,11 @@ function ItemInteractionLayer({
|
|
|
4544
4486
|
style: getChromeStyle(state)
|
|
4545
4487
|
}
|
|
4546
4488
|
),
|
|
4547
|
-
itemDragEnabled && /* @__PURE__ */ jsx9(
|
|
4548
|
-
"div",
|
|
4549
|
-
{
|
|
4550
|
-
"data-ohw-item-drag-surface": "",
|
|
4551
|
-
className: "pointer-events-auto absolute inset-0 cursor-grab rounded-lg active:cursor-grabbing",
|
|
4552
|
-
onPointerDown: (e) => {
|
|
4553
|
-
if (e.button !== 0) return;
|
|
4554
|
-
onItemPointerDown?.(e);
|
|
4555
|
-
},
|
|
4556
|
-
onClick: (e) => {
|
|
4557
|
-
e.preventDefault();
|
|
4558
|
-
e.stopPropagation();
|
|
4559
|
-
onItemClick?.(e.clientX, e.clientY);
|
|
4560
|
-
}
|
|
4561
|
-
}
|
|
4562
|
-
),
|
|
4563
4489
|
showDragHandle && /* @__PURE__ */ jsx9(
|
|
4564
4490
|
"div",
|
|
4565
4491
|
{
|
|
4566
4492
|
"data-ohw-drag-handle-container": "",
|
|
4567
|
-
className: "pointer-events-auto absolute left-0 top-1/2
|
|
4568
|
-
style: isDragging ? { visibility: "hidden" } : void 0,
|
|
4493
|
+
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4569
4494
|
children: /* @__PURE__ */ jsx9(
|
|
4570
4495
|
DragHandle,
|
|
4571
4496
|
{
|
|
@@ -4788,12 +4713,15 @@ function MediaOverlay({
|
|
|
4788
4713
|
className: "flex items-center justify-center cursor-pointer",
|
|
4789
4714
|
style: {
|
|
4790
4715
|
...box,
|
|
4791
|
-
//
|
|
4792
|
-
//
|
|
4793
|
-
|
|
4716
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
4717
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
4718
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
4719
|
+
// Replace still works.
|
|
4720
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4794
4721
|
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4795
4722
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4796
4723
|
},
|
|
4724
|
+
onClick: () => onReplace(hover.key),
|
|
4797
4725
|
children: /* @__PURE__ */ jsxs5(
|
|
4798
4726
|
Button,
|
|
4799
4727
|
{
|
|
@@ -4818,64 +4746,9 @@ function MediaOverlay({
|
|
|
4818
4746
|
] });
|
|
4819
4747
|
}
|
|
4820
4748
|
|
|
4821
|
-
// src/ui/CarouselOverlay.tsx
|
|
4822
|
-
import { GalleryHorizontal } from "lucide-react";
|
|
4823
|
-
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4824
|
-
var OVERLAY_BUTTON_STYLE2 = {
|
|
4825
|
-
pointerEvents: "auto",
|
|
4826
|
-
fontFamily: "Inter, sans-serif",
|
|
4827
|
-
fontSize: 12,
|
|
4828
|
-
color: "#000"
|
|
4829
|
-
};
|
|
4830
|
-
function CarouselOverlay({
|
|
4831
|
-
hover,
|
|
4832
|
-
onEdit
|
|
4833
|
-
}) {
|
|
4834
|
-
const { rect } = hover;
|
|
4835
|
-
return /* @__PURE__ */ jsx12(
|
|
4836
|
-
"div",
|
|
4837
|
-
{
|
|
4838
|
-
"data-ohw-bridge": "",
|
|
4839
|
-
"data-ohw-carousel-overlay": "",
|
|
4840
|
-
className: "flex cursor-pointer items-center justify-center",
|
|
4841
|
-
style: {
|
|
4842
|
-
position: "fixed",
|
|
4843
|
-
top: rect.top,
|
|
4844
|
-
left: rect.left,
|
|
4845
|
-
width: rect.width,
|
|
4846
|
-
height: rect.height,
|
|
4847
|
-
zIndex: 2147483646,
|
|
4848
|
-
pointerEvents: "auto",
|
|
4849
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4850
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4851
|
-
},
|
|
4852
|
-
onClick: () => onEdit(hover.key),
|
|
4853
|
-
children: /* @__PURE__ */ jsxs6(
|
|
4854
|
-
Button,
|
|
4855
|
-
{
|
|
4856
|
-
"data-ohw-carousel-overlay": "",
|
|
4857
|
-
variant: "outline",
|
|
4858
|
-
size: "sm",
|
|
4859
|
-
className: "cursor-pointer gap-1.5 hover:bg-background",
|
|
4860
|
-
style: OVERLAY_BUTTON_STYLE2,
|
|
4861
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
4862
|
-
onClick: (e) => {
|
|
4863
|
-
e.stopPropagation();
|
|
4864
|
-
onEdit(hover.key);
|
|
4865
|
-
},
|
|
4866
|
-
children: [
|
|
4867
|
-
/* @__PURE__ */ jsx12(GalleryHorizontal, { size: 14 }),
|
|
4868
|
-
"Edit gallery"
|
|
4869
|
-
]
|
|
4870
|
-
}
|
|
4871
|
-
)
|
|
4872
|
-
}
|
|
4873
|
-
);
|
|
4874
|
-
}
|
|
4875
|
-
|
|
4876
4749
|
// src/OhhwellsBridge.tsx
|
|
4877
|
-
import { createPortal
|
|
4878
|
-
import { usePathname
|
|
4750
|
+
import { createPortal } from "react-dom";
|
|
4751
|
+
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
4879
4752
|
|
|
4880
4753
|
// src/lib/session-search.ts
|
|
4881
4754
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -4905,7 +4778,6 @@ function parseSectionsFromRoot(root) {
|
|
|
4905
4778
|
for (const el of root.querySelectorAll("[data-ohw-section]")) {
|
|
4906
4779
|
const id = el.getAttribute("data-ohw-section") ?? "";
|
|
4907
4780
|
if (!id || seen.has(id)) continue;
|
|
4908
|
-
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
4909
4781
|
seen.add(id);
|
|
4910
4782
|
const label = el.getAttribute("data-ohw-section-label") ?? titleCaseSectionId(id);
|
|
4911
4783
|
sections.push({ id, label });
|
|
@@ -5152,22 +5024,54 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5152
5024
|
tick();
|
|
5153
5025
|
}
|
|
5154
5026
|
|
|
5155
|
-
// src/ui/link-modal/LinkPopover.tsx
|
|
5156
|
-
import { useEffect as useEffect6 } from "react";
|
|
5157
|
-
|
|
5158
5027
|
// src/ui/dialog.tsx
|
|
5159
5028
|
import * as React7 from "react";
|
|
5160
5029
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
5161
|
-
|
|
5030
|
+
|
|
5031
|
+
// src/ui/icons.tsx
|
|
5032
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5033
|
+
function IconX({ className, ...props }) {
|
|
5034
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5035
|
+
/* @__PURE__ */ jsx12("path", { d: "M18 6 6 18" }),
|
|
5036
|
+
/* @__PURE__ */ jsx12("path", { d: "m6 6 12 12" })
|
|
5037
|
+
] });
|
|
5038
|
+
}
|
|
5039
|
+
function IconChevronDown({ className, ...props }) {
|
|
5040
|
+
return /* @__PURE__ */ jsx12("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) });
|
|
5041
|
+
}
|
|
5042
|
+
function IconFile({ className, ...props }) {
|
|
5043
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5044
|
+
/* @__PURE__ */ jsx12("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5045
|
+
/* @__PURE__ */ jsx12("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
5046
|
+
] });
|
|
5047
|
+
}
|
|
5048
|
+
function IconInfo({ className, ...props }) {
|
|
5049
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5050
|
+
/* @__PURE__ */ jsx12("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5051
|
+
/* @__PURE__ */ jsx12("path", { d: "M12 16v-4" }),
|
|
5052
|
+
/* @__PURE__ */ jsx12("path", { d: "M12 8h.01" })
|
|
5053
|
+
] });
|
|
5054
|
+
}
|
|
5055
|
+
function IconArrowRight({ className, ...props }) {
|
|
5056
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5057
|
+
/* @__PURE__ */ jsx12("path", { d: "M5 12h14" }),
|
|
5058
|
+
/* @__PURE__ */ jsx12("path", { d: "m12 5 7 7-7 7" })
|
|
5059
|
+
] });
|
|
5060
|
+
}
|
|
5061
|
+
function IconSection({ className, ...props }) {
|
|
5062
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5063
|
+
/* @__PURE__ */ jsx12("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
5064
|
+
/* @__PURE__ */ jsx12("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
5065
|
+
/* @__PURE__ */ jsx12("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
5066
|
+
] });
|
|
5067
|
+
}
|
|
5068
|
+
|
|
5069
|
+
// src/ui/dialog.tsx
|
|
5162
5070
|
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5163
|
-
function Dialog2({
|
|
5164
|
-
...props
|
|
5165
|
-
}) {
|
|
5071
|
+
function Dialog2({ ...props }) {
|
|
5166
5072
|
return /* @__PURE__ */ jsx13(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
5167
5073
|
}
|
|
5168
|
-
function DialogPortal({
|
|
5169
|
-
...props
|
|
5170
|
-
}) {
|
|
5074
|
+
function DialogPortal({ ...props }) {
|
|
5171
5075
|
return /* @__PURE__ */ jsx13(DialogPrimitive.Portal, { ...props });
|
|
5172
5076
|
}
|
|
5173
5077
|
function DialogOverlay({
|
|
@@ -5184,69 +5088,52 @@ function DialogOverlay({
|
|
|
5184
5088
|
}
|
|
5185
5089
|
);
|
|
5186
5090
|
}
|
|
5187
|
-
var DialogContent = React7.forwardRef(
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
children
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
}
|
|
5222
|
-
);
|
|
5091
|
+
var DialogContent = React7.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5092
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5093
|
+
return /* @__PURE__ */ jsxs7(DialogPortal, { container: container ?? void 0, children: [
|
|
5094
|
+
/* @__PURE__ */ jsx13(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5095
|
+
/* @__PURE__ */ jsxs7(
|
|
5096
|
+
DialogPrimitive.Content,
|
|
5097
|
+
{
|
|
5098
|
+
ref,
|
|
5099
|
+
"data-slot": "dialog-content",
|
|
5100
|
+
className: cn(
|
|
5101
|
+
positionMode,
|
|
5102
|
+
"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",
|
|
5103
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5104
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
5105
|
+
className
|
|
5106
|
+
),
|
|
5107
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5108
|
+
...props,
|
|
5109
|
+
children: [
|
|
5110
|
+
children,
|
|
5111
|
+
showCloseButton ? /* @__PURE__ */ jsx13(
|
|
5112
|
+
DialogPrimitive.Close,
|
|
5113
|
+
{
|
|
5114
|
+
type: "button",
|
|
5115
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5116
|
+
"aria-label": "Close",
|
|
5117
|
+
children: /* @__PURE__ */ jsx13(IconX, { "aria-hidden": true })
|
|
5118
|
+
}
|
|
5119
|
+
) : null
|
|
5120
|
+
]
|
|
5121
|
+
}
|
|
5122
|
+
)
|
|
5123
|
+
] });
|
|
5124
|
+
});
|
|
5223
5125
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5224
|
-
function DialogHeader({
|
|
5225
|
-
className,
|
|
5226
|
-
...props
|
|
5227
|
-
}) {
|
|
5126
|
+
function DialogHeader({ className, ...props }) {
|
|
5228
5127
|
return /* @__PURE__ */ jsx13("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5229
5128
|
}
|
|
5230
|
-
function DialogFooter({
|
|
5231
|
-
className,
|
|
5232
|
-
...props
|
|
5233
|
-
}) {
|
|
5234
|
-
return /* @__PURE__ */ jsx13(
|
|
5235
|
-
"div",
|
|
5236
|
-
{
|
|
5237
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
5238
|
-
...props
|
|
5239
|
-
}
|
|
5240
|
-
);
|
|
5129
|
+
function DialogFooter({ className, ...props }) {
|
|
5130
|
+
return /* @__PURE__ */ jsx13("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
5241
5131
|
}
|
|
5242
5132
|
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
|
|
5243
5133
|
DialogPrimitive.Title,
|
|
5244
5134
|
{
|
|
5245
5135
|
ref,
|
|
5246
|
-
className: cn(
|
|
5247
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5248
|
-
className
|
|
5249
|
-
),
|
|
5136
|
+
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
5250
5137
|
...props
|
|
5251
5138
|
}
|
|
5252
5139
|
));
|
|
@@ -5262,40 +5149,19 @@ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5262
5149
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5263
5150
|
var DialogClose = DialogPrimitive.Close;
|
|
5264
5151
|
|
|
5265
|
-
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5266
|
-
import { Info, X as X3 } from "lucide-react";
|
|
5267
|
-
|
|
5268
5152
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5269
|
-
import { ArrowRight, File, GalleryVertical } from "lucide-react";
|
|
5270
5153
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5271
|
-
function DestinationBreadcrumb({
|
|
5272
|
-
pageTitle,
|
|
5273
|
-
sectionLabel
|
|
5274
|
-
}) {
|
|
5154
|
+
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
5275
5155
|
return /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5276
|
-
/* @__PURE__ */ jsx14("p", { className: "text-sm font-medium
|
|
5156
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5277
5157
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
|
|
5278
5158
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
5279
|
-
/* @__PURE__ */ jsx14(
|
|
5280
|
-
/* @__PURE__ */ jsx14("span", { className: "text-sm font-medium leading-none text-foreground
|
|
5159
|
+
/* @__PURE__ */ jsx14(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5160
|
+
/* @__PURE__ */ jsx14("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5281
5161
|
] }),
|
|
5282
|
-
/* @__PURE__ */ jsx14(
|
|
5283
|
-
ArrowRight,
|
|
5284
|
-
{
|
|
5285
|
-
size: 16,
|
|
5286
|
-
className: "shrink-0 text-muted-foreground",
|
|
5287
|
-
"aria-hidden": true
|
|
5288
|
-
}
|
|
5289
|
-
),
|
|
5162
|
+
/* @__PURE__ */ jsx14(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5290
5163
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5291
|
-
/* @__PURE__ */ jsx14(
|
|
5292
|
-
GalleryVertical,
|
|
5293
|
-
{
|
|
5294
|
-
size: 16,
|
|
5295
|
-
className: "shrink-0 text-foreground",
|
|
5296
|
-
"aria-hidden": true
|
|
5297
|
-
}
|
|
5298
|
-
),
|
|
5164
|
+
/* @__PURE__ */ jsx14(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5299
5165
|
/* @__PURE__ */ jsx14("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5300
5166
|
] })
|
|
5301
5167
|
] })
|
|
@@ -5303,13 +5169,8 @@ function DestinationBreadcrumb({
|
|
|
5303
5169
|
}
|
|
5304
5170
|
|
|
5305
5171
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5306
|
-
import { GalleryVertical as GalleryVertical2 } from "lucide-react";
|
|
5307
5172
|
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5308
|
-
function SectionTreeItem({
|
|
5309
|
-
section,
|
|
5310
|
-
onSelect,
|
|
5311
|
-
selected
|
|
5312
|
-
}) {
|
|
5173
|
+
function SectionTreeItem({ section, onSelect, selected }) {
|
|
5313
5174
|
const interactive = Boolean(onSelect);
|
|
5314
5175
|
return /* @__PURE__ */ jsxs9("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5315
5176
|
/* @__PURE__ */ jsx15(
|
|
@@ -5337,23 +5198,25 @@ function SectionTreeItem({
|
|
|
5337
5198
|
interactive && selected && "border-primary"
|
|
5338
5199
|
),
|
|
5339
5200
|
children: [
|
|
5340
|
-
/* @__PURE__ */ jsx15(
|
|
5341
|
-
GalleryVertical2,
|
|
5342
|
-
{
|
|
5343
|
-
size: 16,
|
|
5344
|
-
className: "shrink-0 text-foreground",
|
|
5345
|
-
"aria-hidden": true
|
|
5346
|
-
}
|
|
5347
|
-
),
|
|
5201
|
+
/* @__PURE__ */ jsx15(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5348
5202
|
/* @__PURE__ */ jsx15("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5349
5203
|
]
|
|
5350
5204
|
}
|
|
5351
5205
|
)
|
|
5352
5206
|
] });
|
|
5353
5207
|
}
|
|
5208
|
+
function SectionPickerList({ sections, onSelect }) {
|
|
5209
|
+
if (sections.length === 0) {
|
|
5210
|
+
return /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5211
|
+
}
|
|
5212
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1", children: [
|
|
5213
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5214
|
+
sections.map((section) => /* @__PURE__ */ jsx15(SectionTreeItem, { section, onSelect }, section.id))
|
|
5215
|
+
] });
|
|
5216
|
+
}
|
|
5354
5217
|
|
|
5355
5218
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5356
|
-
import {
|
|
5219
|
+
import { useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
5357
5220
|
|
|
5358
5221
|
// src/ui/input.tsx
|
|
5359
5222
|
import * as React8 from "react";
|
|
@@ -5392,11 +5255,8 @@ function Label({ className, ...props }) {
|
|
|
5392
5255
|
}
|
|
5393
5256
|
|
|
5394
5257
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5395
|
-
import { ChevronDown, File as File2, X as X2 } from "lucide-react";
|
|
5396
5258
|
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5397
|
-
function FieldChevron({
|
|
5398
|
-
onClick
|
|
5399
|
-
}) {
|
|
5259
|
+
function FieldChevron({ onClick }) {
|
|
5400
5260
|
return /* @__PURE__ */ jsx18(
|
|
5401
5261
|
"button",
|
|
5402
5262
|
{
|
|
@@ -5405,7 +5265,7 @@ function FieldChevron({
|
|
|
5405
5265
|
onClick,
|
|
5406
5266
|
"aria-label": "Open page list",
|
|
5407
5267
|
tabIndex: -1,
|
|
5408
|
-
children: /* @__PURE__ */ jsx18(
|
|
5268
|
+
children: /* @__PURE__ */ jsx18(IconChevronDown, {})
|
|
5409
5269
|
}
|
|
5410
5270
|
);
|
|
5411
5271
|
}
|
|
@@ -5423,29 +5283,7 @@ function UrlOrPageInput({
|
|
|
5423
5283
|
}) {
|
|
5424
5284
|
const inputId = useId2();
|
|
5425
5285
|
const inputRef = useRef3(null);
|
|
5426
|
-
const rootRef = useRef3(null);
|
|
5427
5286
|
const [isFocused, setIsFocused] = useState3(false);
|
|
5428
|
-
useEffect3(() => {
|
|
5429
|
-
if (!dropdownOpen) return;
|
|
5430
|
-
const isOutside = (e) => {
|
|
5431
|
-
const root = rootRef.current;
|
|
5432
|
-
if (!root) return true;
|
|
5433
|
-
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5434
|
-
if (path.includes(root)) return false;
|
|
5435
|
-
const target = e.target;
|
|
5436
|
-
return !(target instanceof Node && root.contains(target));
|
|
5437
|
-
};
|
|
5438
|
-
const closeIfOutside = (e) => {
|
|
5439
|
-
if (!isOutside(e)) return;
|
|
5440
|
-
onDropdownOpenChange(false);
|
|
5441
|
-
};
|
|
5442
|
-
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5443
|
-
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5444
|
-
return () => {
|
|
5445
|
-
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5446
|
-
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5447
|
-
};
|
|
5448
|
-
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5449
5287
|
const openDropdown = () => {
|
|
5450
5288
|
if (readOnly || filteredPages.length === 0) return;
|
|
5451
5289
|
onDropdownOpenChange(true);
|
|
@@ -5463,21 +5301,14 @@ function UrlOrPageInput({
|
|
|
5463
5301
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
5464
5302
|
};
|
|
5465
5303
|
const fieldClassName = cn(
|
|
5466
|
-
"data-ohw-link-field flex h-
|
|
5304
|
+
"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]",
|
|
5467
5305
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5468
5306
|
);
|
|
5469
5307
|
return /* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5470
5308
|
/* @__PURE__ */ jsx18(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5471
|
-
/* @__PURE__ */ jsxs10("div", {
|
|
5309
|
+
/* @__PURE__ */ jsxs10("div", { className: "relative w-full", children: [
|
|
5472
5310
|
/* @__PURE__ */ jsxs10("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5473
|
-
selectedPage ? /* @__PURE__ */ jsx18("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx18(
|
|
5474
|
-
File2,
|
|
5475
|
-
{
|
|
5476
|
-
size: 16,
|
|
5477
|
-
className: "shrink-0 text-foreground",
|
|
5478
|
-
"aria-hidden": true
|
|
5479
|
-
}
|
|
5480
|
-
) }) : null,
|
|
5311
|
+
selectedPage ? /* @__PURE__ */ jsx18("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx18(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5481
5312
|
readOnly ? /* @__PURE__ */ jsx18("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx18(
|
|
5482
5313
|
Input,
|
|
5483
5314
|
{
|
|
@@ -5489,14 +5320,7 @@ function UrlOrPageInput({
|
|
|
5489
5320
|
setIsFocused(true);
|
|
5490
5321
|
if (!selectedPage) openDropdown();
|
|
5491
5322
|
},
|
|
5492
|
-
onBlur: () =>
|
|
5493
|
-
setIsFocused(false);
|
|
5494
|
-
requestAnimationFrame(() => {
|
|
5495
|
-
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5496
|
-
onDropdownOpenChange(false);
|
|
5497
|
-
}
|
|
5498
|
-
});
|
|
5499
|
-
},
|
|
5323
|
+
onBlur: () => setIsFocused(false),
|
|
5500
5324
|
placeholder,
|
|
5501
5325
|
className: cn(
|
|
5502
5326
|
"min-w-0 flex-1 truncate border-0 bg-transparent p-0 text-sm font-normal leading-5 shadow-none outline-none ring-0 caret-foreground",
|
|
@@ -5512,7 +5336,7 @@ function UrlOrPageInput({
|
|
|
5512
5336
|
onMouseDown: clearSelection,
|
|
5513
5337
|
"aria-label": "Clear selected page",
|
|
5514
5338
|
tabIndex: -1,
|
|
5515
|
-
children: /* @__PURE__ */ jsx18(
|
|
5339
|
+
children: /* @__PURE__ */ jsx18(IconX, { "aria-hidden": true })
|
|
5516
5340
|
}
|
|
5517
5341
|
) : null,
|
|
5518
5342
|
!readOnly ? /* @__PURE__ */ jsx18(FieldChevron, { onClick: toggleDropdown }) : null
|
|
@@ -5521,7 +5345,7 @@ function UrlOrPageInput({
|
|
|
5521
5345
|
"div",
|
|
5522
5346
|
{
|
|
5523
5347
|
"data-ohw-link-page-dropdown": "",
|
|
5524
|
-
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-
|
|
5348
|
+
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",
|
|
5525
5349
|
onMouseDown: (e) => e.preventDefault(),
|
|
5526
5350
|
children: filteredPages.map((page) => /* @__PURE__ */ jsxs10(
|
|
5527
5351
|
"button",
|
|
@@ -5530,7 +5354,7 @@ function UrlOrPageInput({
|
|
|
5530
5354
|
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",
|
|
5531
5355
|
onClick: () => onPageSelect(page),
|
|
5532
5356
|
children: [
|
|
5533
|
-
/* @__PURE__ */ jsx18(
|
|
5357
|
+
/* @__PURE__ */ jsx18(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5534
5358
|
/* @__PURE__ */ jsx18("span", { className: "truncate", children: page.title })
|
|
5535
5359
|
]
|
|
5536
5360
|
},
|
|
@@ -5543,458 +5367,30 @@ function UrlOrPageInput({
|
|
|
5543
5367
|
] });
|
|
5544
5368
|
}
|
|
5545
5369
|
|
|
5546
|
-
// src/ui/link-modal/
|
|
5547
|
-
import {
|
|
5548
|
-
function
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
)
|
|
5561
|
-
|
|
5562
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5563
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx19(
|
|
5564
|
-
DestinationBreadcrumb,
|
|
5565
|
-
{
|
|
5566
|
-
pageTitle: state.selectedPage.title,
|
|
5567
|
-
sectionLabel: state.selectedSection.label
|
|
5568
|
-
}
|
|
5569
|
-
) : /* @__PURE__ */ jsx19(
|
|
5570
|
-
UrlOrPageInput,
|
|
5571
|
-
{
|
|
5572
|
-
value: state.searchValue,
|
|
5573
|
-
selectedPage: state.selectedPage,
|
|
5574
|
-
dropdownOpen: state.dropdownOpen,
|
|
5575
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5576
|
-
filteredPages: state.filteredPages,
|
|
5577
|
-
onInputChange: state.handleInputChange,
|
|
5578
|
-
onPageSelect: state.handlePageSelect,
|
|
5579
|
-
urlError: state.urlError
|
|
5580
|
-
}
|
|
5581
|
-
),
|
|
5582
|
-
state.showChooseSection ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5583
|
-
/* @__PURE__ */ jsx19(
|
|
5584
|
-
Button,
|
|
5585
|
-
{
|
|
5586
|
-
type: "button",
|
|
5587
|
-
variant: "outline",
|
|
5588
|
-
className: "w-fit cursor-pointer",
|
|
5589
|
-
size: "sm",
|
|
5590
|
-
onClick: state.handleChooseSection,
|
|
5591
|
-
children: "Choose a section"
|
|
5592
|
-
}
|
|
5593
|
-
),
|
|
5594
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5595
|
-
/* @__PURE__ */ jsx19(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5596
|
-
/* @__PURE__ */ jsx19("span", { children: "Pick a section this link should scroll to." })
|
|
5597
|
-
] })
|
|
5598
|
-
] }) : null,
|
|
5599
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx19(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5600
|
-
] }),
|
|
5601
|
-
/* @__PURE__ */ jsxs11(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5602
|
-
/* @__PURE__ */ jsx19(
|
|
5603
|
-
Button,
|
|
5604
|
-
{
|
|
5605
|
-
type: "button",
|
|
5606
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5607
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5608
|
-
style: isCancel ? {
|
|
5609
|
-
backgroundColor: "var(--ohw-background)",
|
|
5610
|
-
borderColor: "var(--ohw-border)",
|
|
5611
|
-
color: "var(--ohw-foreground)"
|
|
5612
|
-
} : void 0,
|
|
5613
|
-
onClick: state.handleSecondary,
|
|
5614
|
-
children: state.secondaryLabel
|
|
5615
|
-
}
|
|
5616
|
-
),
|
|
5617
|
-
/* @__PURE__ */ jsx19(
|
|
5618
|
-
Button,
|
|
5619
|
-
{
|
|
5620
|
-
type: "button",
|
|
5621
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5622
|
-
style: {
|
|
5623
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5624
|
-
color: "var(--ohw-primary-foreground)"
|
|
5625
|
-
},
|
|
5626
|
-
disabled: !state.isValid,
|
|
5627
|
-
onClick: state.handleSubmit,
|
|
5628
|
-
children: state.submitLabel
|
|
5629
|
-
}
|
|
5630
|
-
)
|
|
5631
|
-
] })
|
|
5632
|
-
] });
|
|
5633
|
-
}
|
|
5634
|
-
|
|
5635
|
-
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5636
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
|
|
5637
|
-
import { createPortal } from "react-dom";
|
|
5638
|
-
import { ArrowLeft, Check } from "lucide-react";
|
|
5639
|
-
import { usePathname, useRouter } from "next/navigation";
|
|
5640
|
-
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5641
|
-
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5642
|
-
function rectsEqual(a, b) {
|
|
5643
|
-
if (a.size !== b.size) return false;
|
|
5644
|
-
for (const [id, rect] of a) {
|
|
5645
|
-
const other = b.get(id);
|
|
5646
|
-
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5647
|
-
return false;
|
|
5648
|
-
}
|
|
5649
|
-
}
|
|
5650
|
-
return true;
|
|
5651
|
-
}
|
|
5652
|
-
function readSectionRects(sectionIds) {
|
|
5653
|
-
const next = /* @__PURE__ */ new Map();
|
|
5654
|
-
for (const id of sectionIds) {
|
|
5655
|
-
const el = document.querySelector(
|
|
5656
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5657
|
-
);
|
|
5658
|
-
if (el) next.set(id, el.getBoundingClientRect());
|
|
5659
|
-
}
|
|
5660
|
-
return next;
|
|
5661
|
-
}
|
|
5662
|
-
function hitTestSectionId(x, y, sectionIds, rects) {
|
|
5663
|
-
for (const id of sectionIds) {
|
|
5664
|
-
const rect = rects.get(id);
|
|
5665
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) continue;
|
|
5666
|
-
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
|
5667
|
-
return id;
|
|
5668
|
-
}
|
|
5669
|
-
}
|
|
5670
|
-
return null;
|
|
5671
|
-
}
|
|
5672
|
-
function useSectionRects(sectionIdsKey, enabled) {
|
|
5673
|
-
const [rects, setRects] = useState4(/* @__PURE__ */ new Map());
|
|
5674
|
-
const sectionIds = useMemo2(
|
|
5675
|
-
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5676
|
-
[sectionIdsKey]
|
|
5370
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5371
|
+
import { useCallback, useEffect as useEffect3, useMemo as useMemo2, useState as useState4 } from "react";
|
|
5372
|
+
function useLinkModalState({
|
|
5373
|
+
open,
|
|
5374
|
+
mode,
|
|
5375
|
+
pages,
|
|
5376
|
+
sections: _sections,
|
|
5377
|
+
sectionsByPath,
|
|
5378
|
+
initialTarget,
|
|
5379
|
+
existingTargets,
|
|
5380
|
+
onClose,
|
|
5381
|
+
onSubmit
|
|
5382
|
+
}) {
|
|
5383
|
+
const availablePages = useMemo2(
|
|
5384
|
+
() => mode === "create" ? filterAvailablePages(pages, existingTargets) : pages,
|
|
5385
|
+
[mode, pages, existingTargets]
|
|
5677
5386
|
);
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5686
|
-
};
|
|
5687
|
-
update();
|
|
5688
|
-
const opts = { capture: true, passive: true };
|
|
5689
|
-
window.addEventListener("scroll", update, opts);
|
|
5690
|
-
window.addEventListener("resize", update);
|
|
5691
|
-
const vv = window.visualViewport;
|
|
5692
|
-
vv?.addEventListener("resize", update);
|
|
5693
|
-
vv?.addEventListener("scroll", update);
|
|
5694
|
-
const ro = new ResizeObserver(update);
|
|
5695
|
-
for (const id of sectionIds) {
|
|
5696
|
-
const el = document.querySelector(
|
|
5697
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5698
|
-
);
|
|
5699
|
-
if (el) ro.observe(el);
|
|
5700
|
-
}
|
|
5701
|
-
return () => {
|
|
5702
|
-
window.removeEventListener("scroll", update, opts);
|
|
5703
|
-
window.removeEventListener("resize", update);
|
|
5704
|
-
vv?.removeEventListener("resize", update);
|
|
5705
|
-
vv?.removeEventListener("scroll", update);
|
|
5706
|
-
ro.disconnect();
|
|
5707
|
-
};
|
|
5708
|
-
}, [sectionIds, enabled]);
|
|
5709
|
-
return rects;
|
|
5710
|
-
}
|
|
5711
|
-
function SectionPickerOverlay({
|
|
5712
|
-
pagePath,
|
|
5713
|
-
sections,
|
|
5714
|
-
onBack,
|
|
5715
|
-
onSelect
|
|
5716
|
-
}) {
|
|
5717
|
-
const router = useRouter();
|
|
5718
|
-
const pathname = usePathname();
|
|
5719
|
-
const [selectedId, setSelectedId] = useState4(null);
|
|
5720
|
-
const [hoveredId, setHoveredId] = useState4(null);
|
|
5721
|
-
const pointerRef = useRef4(null);
|
|
5722
|
-
const pointerScreenRef = useRef4(null);
|
|
5723
|
-
const iframeOffsetTopRef = useRef4(null);
|
|
5724
|
-
const sectionIdsRef = useRef4([]);
|
|
5725
|
-
const [chromeClip, setChromeClip] = useState4(
|
|
5726
|
-
() => ({
|
|
5727
|
-
top: 0,
|
|
5728
|
-
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5729
|
-
})
|
|
5730
|
-
);
|
|
5731
|
-
const normalizedTarget = normalizePath(pagePath);
|
|
5732
|
-
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5733
|
-
useEffect4(() => {
|
|
5734
|
-
if (isOnTargetPage) return;
|
|
5735
|
-
const search = readPreservedSearch();
|
|
5736
|
-
router.push(`${normalizedTarget}${search}`);
|
|
5737
|
-
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5738
|
-
useEffect4(() => {
|
|
5739
|
-
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5740
|
-
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5741
|
-
el.removeAttribute("data-ohw-hovered");
|
|
5742
|
-
});
|
|
5743
|
-
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => {
|
|
5744
|
-
el.removeAttribute("data-ohw-state-hovered");
|
|
5745
|
-
});
|
|
5746
|
-
return () => {
|
|
5747
|
-
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5748
|
-
};
|
|
5749
|
-
}, []);
|
|
5750
|
-
const liveSections = useMemo2(() => {
|
|
5751
|
-
if (!isOnTargetPage) return sections;
|
|
5752
|
-
const live = collectSectionsFromDom();
|
|
5753
|
-
if (live.length === 0) return sections;
|
|
5754
|
-
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5755
|
-
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5756
|
-
}, [isOnTargetPage, sections, pathname]);
|
|
5757
|
-
const sectionIdsKey = useMemo2(
|
|
5758
|
-
() => liveSections.map((s) => s.id).join("\0"),
|
|
5759
|
-
[liveSections]
|
|
5760
|
-
);
|
|
5761
|
-
const sectionIds = useMemo2(
|
|
5762
|
-
() => liveSections.map((s) => s.id),
|
|
5763
|
-
[liveSections]
|
|
5764
|
-
);
|
|
5765
|
-
sectionIdsRef.current = sectionIds;
|
|
5766
|
-
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5767
|
-
const applyHoverAt = useCallback2(
|
|
5768
|
-
(x, y, liveRects) => {
|
|
5769
|
-
const ids = sectionIdsRef.current;
|
|
5770
|
-
const map = liveRects ?? readSectionRects(ids);
|
|
5771
|
-
const next = hitTestSectionId(x, y, ids, map);
|
|
5772
|
-
setHoveredId((prev) => prev === next ? prev : next);
|
|
5773
|
-
},
|
|
5774
|
-
[]
|
|
5775
|
-
);
|
|
5776
|
-
useEffect4(() => {
|
|
5777
|
-
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5778
|
-
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5779
|
-
const bottom = Math.min(
|
|
5780
|
-
window.innerHeight,
|
|
5781
|
-
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5782
|
-
);
|
|
5783
|
-
setChromeClip(
|
|
5784
|
-
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5785
|
-
);
|
|
5786
|
-
};
|
|
5787
|
-
const onParentScroll = (e) => {
|
|
5788
|
-
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5789
|
-
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5790
|
-
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5791
|
-
iframeOffsetTopRef.current = iframeOffsetTop;
|
|
5792
|
-
if (!pointerScreenRef.current && pointerRef.current) {
|
|
5793
|
-
pointerScreenRef.current = {
|
|
5794
|
-
x: pointerRef.current.x,
|
|
5795
|
-
y: pointerRef.current.y + iframeOffsetTop
|
|
5796
|
-
};
|
|
5797
|
-
}
|
|
5798
|
-
const screen = pointerScreenRef.current;
|
|
5799
|
-
if (screen) {
|
|
5800
|
-
const next = { x: screen.x, y: screen.y - iframeOffsetTop };
|
|
5801
|
-
pointerRef.current = next;
|
|
5802
|
-
applyHoverAt(next.x, next.y);
|
|
5803
|
-
}
|
|
5804
|
-
};
|
|
5805
|
-
const onResize = () => {
|
|
5806
|
-
setChromeClip((prev) => {
|
|
5807
|
-
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5808
|
-
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5809
|
-
});
|
|
5810
|
-
};
|
|
5811
|
-
window.addEventListener("message", onParentScroll);
|
|
5812
|
-
window.addEventListener("resize", onResize);
|
|
5813
|
-
return () => {
|
|
5814
|
-
window.removeEventListener("message", onParentScroll);
|
|
5815
|
-
window.removeEventListener("resize", onResize);
|
|
5816
|
-
};
|
|
5817
|
-
}, [applyHoverAt]);
|
|
5818
|
-
useEffect4(() => {
|
|
5819
|
-
const ptr = pointerRef.current;
|
|
5820
|
-
if (!ptr) return;
|
|
5821
|
-
applyHoverAt(ptr.x, ptr.y, rects);
|
|
5822
|
-
}, [rects, applyHoverAt]);
|
|
5823
|
-
useEffect4(() => {
|
|
5824
|
-
const rememberPointer = (clientX, clientY) => {
|
|
5825
|
-
pointerRef.current = { x: clientX, y: clientY };
|
|
5826
|
-
const top = iframeOffsetTopRef.current;
|
|
5827
|
-
if (top != null) {
|
|
5828
|
-
pointerScreenRef.current = { x: clientX, y: clientY + top };
|
|
5829
|
-
}
|
|
5830
|
-
applyHoverAt(clientX, clientY, rects);
|
|
5831
|
-
};
|
|
5832
|
-
const onPointerMove = (e) => {
|
|
5833
|
-
rememberPointer(e.clientX, e.clientY);
|
|
5834
|
-
};
|
|
5835
|
-
const onPointerSync = (e) => {
|
|
5836
|
-
if (e.data?.type !== "ow:pointer-sync") return;
|
|
5837
|
-
const { clientX, clientY } = e.data;
|
|
5838
|
-
rememberPointer(clientX, clientY);
|
|
5839
|
-
};
|
|
5840
|
-
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
5841
|
-
window.addEventListener("message", onPointerSync);
|
|
5842
|
-
return () => {
|
|
5843
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
5844
|
-
window.removeEventListener("message", onPointerSync);
|
|
5845
|
-
};
|
|
5846
|
-
}, [rects, applyHoverAt]);
|
|
5847
|
-
const handleSelect = useCallback2(
|
|
5848
|
-
(section) => {
|
|
5849
|
-
if (selectedId) return;
|
|
5850
|
-
setSelectedId(section.id);
|
|
5851
|
-
onSelect(section);
|
|
5852
|
-
},
|
|
5853
|
-
[selectedId, onSelect]
|
|
5854
|
-
);
|
|
5855
|
-
useEffect4(() => {
|
|
5856
|
-
const onKeyDown = (e) => {
|
|
5857
|
-
if (e.key === "Escape") {
|
|
5858
|
-
e.preventDefault();
|
|
5859
|
-
e.stopPropagation();
|
|
5860
|
-
onBack();
|
|
5861
|
-
}
|
|
5862
|
-
};
|
|
5863
|
-
window.addEventListener("keydown", onKeyDown, true);
|
|
5864
|
-
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5865
|
-
}, [onBack]);
|
|
5866
|
-
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5867
|
-
if (!portalRoot) return null;
|
|
5868
|
-
return createPortal(
|
|
5869
|
-
/* @__PURE__ */ jsxs12(
|
|
5870
|
-
"div",
|
|
5871
|
-
{
|
|
5872
|
-
"data-ohw-section-picker": "",
|
|
5873
|
-
"data-ohw-bridge": "",
|
|
5874
|
-
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5875
|
-
"aria-modal": true,
|
|
5876
|
-
role: "dialog",
|
|
5877
|
-
"aria-label": "Choose a section",
|
|
5878
|
-
children: [
|
|
5879
|
-
/* @__PURE__ */ jsx20(
|
|
5880
|
-
"div",
|
|
5881
|
-
{
|
|
5882
|
-
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5883
|
-
style: { top: chromeClip.top + 20 },
|
|
5884
|
-
children: /* @__PURE__ */ jsxs12(
|
|
5885
|
-
Button,
|
|
5886
|
-
{
|
|
5887
|
-
type: "button",
|
|
5888
|
-
variant: "outline",
|
|
5889
|
-
size: "sm",
|
|
5890
|
-
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5891
|
-
onClick: onBack,
|
|
5892
|
-
children: [
|
|
5893
|
-
/* @__PURE__ */ jsx20(ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5894
|
-
"Back"
|
|
5895
|
-
]
|
|
5896
|
-
}
|
|
5897
|
-
)
|
|
5898
|
-
}
|
|
5899
|
-
),
|
|
5900
|
-
/* @__PURE__ */ jsx20(
|
|
5901
|
-
"div",
|
|
5902
|
-
{
|
|
5903
|
-
className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
|
|
5904
|
-
style: {
|
|
5905
|
-
top: chromeClip.bottom - 20,
|
|
5906
|
-
transform: "translate(-50%, -100%)",
|
|
5907
|
-
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5908
|
-
},
|
|
5909
|
-
"data-ohw-section-picker-hint": "",
|
|
5910
|
-
children: "Click on section to select"
|
|
5911
|
-
}
|
|
5912
|
-
),
|
|
5913
|
-
!isOnTargetPage ? /* @__PURE__ */ jsx20(
|
|
5914
|
-
"div",
|
|
5915
|
-
{
|
|
5916
|
-
className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md bg-background/90 px-3 py-2 text-sm text-muted-foreground shadow-sm",
|
|
5917
|
-
style: { top: chromeClip.top + 64 },
|
|
5918
|
-
children: "Loading page preview\u2026"
|
|
5919
|
-
}
|
|
5920
|
-
) : null,
|
|
5921
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx20("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5922
|
-
isOnTargetPage ? liveSections.map((section) => {
|
|
5923
|
-
const rect = rects.get(section.id);
|
|
5924
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5925
|
-
const isSelected = selectedId === section.id;
|
|
5926
|
-
const isHovered = hoveredId === section.id;
|
|
5927
|
-
const isLit = isSelected || isHovered;
|
|
5928
|
-
return /* @__PURE__ */ jsxs12(
|
|
5929
|
-
"button",
|
|
5930
|
-
{
|
|
5931
|
-
type: "button",
|
|
5932
|
-
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5933
|
-
style: {
|
|
5934
|
-
top: rect.top,
|
|
5935
|
-
left: rect.left,
|
|
5936
|
-
width: rect.width,
|
|
5937
|
-
height: rect.height,
|
|
5938
|
-
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
5939
|
-
},
|
|
5940
|
-
"aria-label": `Select section ${section.label}`,
|
|
5941
|
-
onClick: () => handleSelect(section),
|
|
5942
|
-
children: [
|
|
5943
|
-
isLit ? /* @__PURE__ */ jsx20(
|
|
5944
|
-
"span",
|
|
5945
|
-
{
|
|
5946
|
-
className: "pointer-events-none absolute",
|
|
5947
|
-
style: {
|
|
5948
|
-
inset: 4,
|
|
5949
|
-
borderRadius: "var(--radius, 6px)",
|
|
5950
|
-
border: "1.5px dashed var(--primary, #0885FE)",
|
|
5951
|
-
boxSizing: "border-box"
|
|
5952
|
-
},
|
|
5953
|
-
"aria-hidden": true
|
|
5954
|
-
}
|
|
5955
|
-
) : null,
|
|
5956
|
-
isSelected ? /* @__PURE__ */ jsx20(
|
|
5957
|
-
"span",
|
|
5958
|
-
{
|
|
5959
|
-
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5960
|
-
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5961
|
-
"aria-hidden": true,
|
|
5962
|
-
children: /* @__PURE__ */ jsx20(Check, { className: "size-5" })
|
|
5963
|
-
}
|
|
5964
|
-
) : null
|
|
5965
|
-
]
|
|
5966
|
-
},
|
|
5967
|
-
section.id
|
|
5968
|
-
);
|
|
5969
|
-
}) : null
|
|
5970
|
-
]
|
|
5971
|
-
}
|
|
5972
|
-
),
|
|
5973
|
-
portalRoot
|
|
5974
|
-
);
|
|
5975
|
-
}
|
|
5976
|
-
|
|
5977
|
-
// src/ui/link-modal/useLinkModalState.ts
|
|
5978
|
-
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
5979
|
-
function useLinkModalState({
|
|
5980
|
-
open,
|
|
5981
|
-
mode,
|
|
5982
|
-
pages,
|
|
5983
|
-
sections: _sections,
|
|
5984
|
-
sectionsByPath,
|
|
5985
|
-
initialTarget,
|
|
5986
|
-
existingTargets: _existingTargets,
|
|
5987
|
-
onClose,
|
|
5988
|
-
onSubmit
|
|
5989
|
-
}) {
|
|
5990
|
-
const availablePages = useMemo3(() => pages, [pages]);
|
|
5991
|
-
const [searchValue, setSearchValue] = useState5("");
|
|
5992
|
-
const [selectedPage, setSelectedPage] = useState5(null);
|
|
5993
|
-
const [selectedSection, setSelectedSection] = useState5(null);
|
|
5994
|
-
const [step, setStep] = useState5("input");
|
|
5995
|
-
const [dropdownOpen, setDropdownOpen] = useState5(false);
|
|
5996
|
-
const [urlError, setUrlError] = useState5("");
|
|
5997
|
-
const reset = useCallback3(() => {
|
|
5387
|
+
const [searchValue, setSearchValue] = useState4("");
|
|
5388
|
+
const [selectedPage, setSelectedPage] = useState4(null);
|
|
5389
|
+
const [selectedSection, setSelectedSection] = useState4(null);
|
|
5390
|
+
const [step, setStep] = useState4("input");
|
|
5391
|
+
const [dropdownOpen, setDropdownOpen] = useState4(false);
|
|
5392
|
+
const [urlError, setUrlError] = useState4("");
|
|
5393
|
+
const reset = useCallback(() => {
|
|
5998
5394
|
setSearchValue("");
|
|
5999
5395
|
setSelectedPage(null);
|
|
6000
5396
|
setSelectedSection(null);
|
|
@@ -6002,7 +5398,7 @@ function useLinkModalState({
|
|
|
6002
5398
|
setDropdownOpen(false);
|
|
6003
5399
|
setUrlError("");
|
|
6004
5400
|
}, []);
|
|
6005
|
-
|
|
5401
|
+
useEffect3(() => {
|
|
6006
5402
|
if (!open) return;
|
|
6007
5403
|
if (mode === "edit" && initialTarget) {
|
|
6008
5404
|
const { pageRoute } = parseTarget(initialTarget);
|
|
@@ -6017,12 +5413,12 @@ function useLinkModalState({
|
|
|
6017
5413
|
}
|
|
6018
5414
|
setDropdownOpen(false);
|
|
6019
5415
|
setUrlError("");
|
|
6020
|
-
}, [open, mode, initialTarget, reset]);
|
|
6021
|
-
const filteredPages =
|
|
5416
|
+
}, [open, mode, initialTarget, pages, sectionsByPath, reset]);
|
|
5417
|
+
const filteredPages = useMemo2(() => {
|
|
6022
5418
|
if (!searchValue.trim()) return availablePages;
|
|
6023
5419
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
6024
5420
|
}, [availablePages, searchValue]);
|
|
6025
|
-
const activeSections =
|
|
5421
|
+
const activeSections = useMemo2(() => {
|
|
6026
5422
|
if (!selectedPage) return [];
|
|
6027
5423
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
6028
5424
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -6064,14 +5460,11 @@ function useLinkModalState({
|
|
|
6064
5460
|
const handleBackToSections = () => {
|
|
6065
5461
|
setStep("sectionPicker");
|
|
6066
5462
|
};
|
|
6067
|
-
const handleSectionPickerBack = () => {
|
|
6068
|
-
setStep("input");
|
|
6069
|
-
};
|
|
6070
5463
|
const handleClose = () => {
|
|
6071
5464
|
reset();
|
|
6072
5465
|
onClose();
|
|
6073
5466
|
};
|
|
6074
|
-
const isValid =
|
|
5467
|
+
const isValid = useMemo2(() => {
|
|
6075
5468
|
if (urlError) return false;
|
|
6076
5469
|
if (showBreadcrumb) return true;
|
|
6077
5470
|
if (selectedPage) return true;
|
|
@@ -6104,7 +5497,7 @@ function useLinkModalState({
|
|
|
6104
5497
|
onSubmit(normalizeUrl(searchValue));
|
|
6105
5498
|
handleClose();
|
|
6106
5499
|
};
|
|
6107
|
-
const submitLabel =
|
|
5500
|
+
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
6108
5501
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
6109
5502
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
6110
5503
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -6131,29 +5524,23 @@ function useLinkModalState({
|
|
|
6131
5524
|
handleChooseSection,
|
|
6132
5525
|
handleSectionSelect,
|
|
6133
5526
|
handleBackToSections,
|
|
6134
|
-
handleSectionPickerBack,
|
|
6135
5527
|
handleClose,
|
|
6136
5528
|
handleSecondary,
|
|
6137
5529
|
handleSubmit
|
|
6138
5530
|
};
|
|
6139
5531
|
}
|
|
6140
5532
|
|
|
6141
|
-
// src/ui/link-modal/
|
|
6142
|
-
import { Fragment as
|
|
6143
|
-
function
|
|
6144
|
-
window.parent?.postMessage(data, "*");
|
|
6145
|
-
}
|
|
6146
|
-
function LinkPopover({
|
|
5533
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5534
|
+
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5535
|
+
function LinkEditorPanel({
|
|
6147
5536
|
open = true,
|
|
6148
|
-
panelRef,
|
|
6149
|
-
portalContainer,
|
|
6150
|
-
onClose,
|
|
6151
5537
|
mode = "create",
|
|
6152
5538
|
pages,
|
|
6153
5539
|
sections = [],
|
|
6154
5540
|
sectionsByPath,
|
|
6155
5541
|
initialTarget,
|
|
6156
5542
|
existingTargets = [],
|
|
5543
|
+
onClose,
|
|
6157
5544
|
onSubmit
|
|
6158
5545
|
}) {
|
|
6159
5546
|
const state = useLinkModalState({
|
|
@@ -6167,109 +5554,115 @@ function LinkPopover({
|
|
|
6167
5554
|
onClose,
|
|
6168
5555
|
onSubmit
|
|
6169
5556
|
});
|
|
6170
|
-
const
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
postToParent({ type: "ui:unlock" });
|
|
6175
|
-
postToParent({ type: "ow:section-picker", active: true });
|
|
6176
|
-
document.documentElement.style.overflow = "";
|
|
6177
|
-
document.body.style.overflow = "";
|
|
6178
|
-
return () => {
|
|
6179
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6180
|
-
};
|
|
6181
|
-
}
|
|
6182
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6183
|
-
postToParent({ type: "ui:lock" });
|
|
6184
|
-
const html = document.documentElement;
|
|
6185
|
-
const body = document.body;
|
|
6186
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6187
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6188
|
-
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6189
|
-
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6190
|
-
html.style.overflow = "hidden";
|
|
6191
|
-
body.style.overflow = "hidden";
|
|
6192
|
-
html.style.overscrollBehavior = "none";
|
|
6193
|
-
body.style.overscrollBehavior = "none";
|
|
6194
|
-
const canScrollElement = (el, deltaY) => {
|
|
6195
|
-
const { overflowY } = getComputedStyle(el);
|
|
6196
|
-
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6197
|
-
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6198
|
-
if (deltaY < 0) return el.scrollTop > 0;
|
|
6199
|
-
if (deltaY > 0)
|
|
6200
|
-
return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6201
|
-
return true;
|
|
6202
|
-
};
|
|
6203
|
-
const allowsInternalScroll = (e) => {
|
|
6204
|
-
const target = e.target;
|
|
6205
|
-
if (!(target instanceof Element)) return false;
|
|
6206
|
-
const scrollRoot = target.closest(
|
|
6207
|
-
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6208
|
-
);
|
|
6209
|
-
if (!scrollRoot) return false;
|
|
6210
|
-
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6211
|
-
return canScrollElement(scrollRoot, deltaY);
|
|
6212
|
-
};
|
|
6213
|
-
const preventBackgroundScroll = (e) => {
|
|
6214
|
-
if (allowsInternalScroll(e)) return;
|
|
6215
|
-
e.preventDefault();
|
|
6216
|
-
};
|
|
6217
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6218
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6219
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6220
|
-
return () => {
|
|
6221
|
-
postToParent({ type: "ui:unlock" });
|
|
6222
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6223
|
-
body.style.overflow = prevBodyOverflow;
|
|
6224
|
-
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6225
|
-
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6226
|
-
document.removeEventListener(
|
|
6227
|
-
"wheel",
|
|
6228
|
-
preventBackgroundScroll,
|
|
6229
|
-
scrollOpts
|
|
6230
|
-
);
|
|
6231
|
-
document.removeEventListener(
|
|
6232
|
-
"touchmove",
|
|
6233
|
-
preventBackgroundScroll,
|
|
6234
|
-
scrollOpts
|
|
6235
|
-
);
|
|
6236
|
-
};
|
|
6237
|
-
}, [open, sectionPickerActive]);
|
|
6238
|
-
return /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
6239
|
-
/* @__PURE__ */ jsx21(
|
|
6240
|
-
Dialog2,
|
|
6241
|
-
{
|
|
6242
|
-
open: open && !sectionPickerActive,
|
|
6243
|
-
onOpenChange: (next) => {
|
|
6244
|
-
if (!next) onClose?.();
|
|
6245
|
-
},
|
|
6246
|
-
children: /* @__PURE__ */ jsx21(
|
|
6247
|
-
DialogContent,
|
|
6248
|
-
{
|
|
6249
|
-
ref: panelRef,
|
|
6250
|
-
container: portalContainer,
|
|
6251
|
-
"data-ohw-link-popover-root": "",
|
|
6252
|
-
"data-ohw-link-modal-root": "",
|
|
6253
|
-
"data-ohw-bridge": "",
|
|
6254
|
-
showCloseButton: false,
|
|
6255
|
-
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6256
|
-
children: /* @__PURE__ */ jsx21(LinkEditorPanel, { state, onClose })
|
|
6257
|
-
}
|
|
6258
|
-
)
|
|
6259
|
-
}
|
|
6260
|
-
),
|
|
6261
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx21(
|
|
6262
|
-
SectionPickerOverlay,
|
|
5557
|
+
const isCancel = state.secondaryLabel === "Cancel";
|
|
5558
|
+
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
5559
|
+
/* @__PURE__ */ jsx19(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx19(
|
|
5560
|
+
"button",
|
|
6263
5561
|
{
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
5562
|
+
type: "button",
|
|
5563
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5564
|
+
"aria-label": "Close",
|
|
5565
|
+
children: /* @__PURE__ */ jsx19(IconX, { "aria-hidden": true })
|
|
6268
5566
|
}
|
|
6269
|
-
)
|
|
5567
|
+
) }),
|
|
5568
|
+
/* @__PURE__ */ jsx19(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx19(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5569
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5570
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx19(
|
|
5571
|
+
DestinationBreadcrumb,
|
|
5572
|
+
{
|
|
5573
|
+
pageTitle: state.selectedPage.title,
|
|
5574
|
+
sectionLabel: state.selectedSection.label
|
|
5575
|
+
}
|
|
5576
|
+
) : /* @__PURE__ */ jsx19(
|
|
5577
|
+
UrlOrPageInput,
|
|
5578
|
+
{
|
|
5579
|
+
value: state.searchValue,
|
|
5580
|
+
selectedPage: state.selectedPage,
|
|
5581
|
+
dropdownOpen: state.dropdownOpen,
|
|
5582
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5583
|
+
filteredPages: state.filteredPages,
|
|
5584
|
+
onInputChange: state.handleInputChange,
|
|
5585
|
+
onPageSelect: state.handlePageSelect,
|
|
5586
|
+
urlError: state.urlError
|
|
5587
|
+
}
|
|
5588
|
+
),
|
|
5589
|
+
state.showChooseSection ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5590
|
+
/* @__PURE__ */ jsx19(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5591
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5592
|
+
/* @__PURE__ */ jsx19(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5593
|
+
/* @__PURE__ */ jsx19("span", { children: "Pick a section this link should scroll to." })
|
|
5594
|
+
] })
|
|
5595
|
+
] }) : null,
|
|
5596
|
+
state.showSectionPicker ? /* @__PURE__ */ jsx19(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5597
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx19(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5598
|
+
] }),
|
|
5599
|
+
/* @__PURE__ */ jsxs11(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5600
|
+
/* @__PURE__ */ jsx19(
|
|
5601
|
+
Button,
|
|
5602
|
+
{
|
|
5603
|
+
type: "button",
|
|
5604
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5605
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5606
|
+
style: isCancel ? {
|
|
5607
|
+
backgroundColor: "var(--ohw-background)",
|
|
5608
|
+
borderColor: "var(--ohw-border)",
|
|
5609
|
+
color: "var(--ohw-foreground)"
|
|
5610
|
+
} : void 0,
|
|
5611
|
+
onClick: state.handleSecondary,
|
|
5612
|
+
children: state.secondaryLabel
|
|
5613
|
+
}
|
|
5614
|
+
),
|
|
5615
|
+
/* @__PURE__ */ jsx19(
|
|
5616
|
+
Button,
|
|
5617
|
+
{
|
|
5618
|
+
type: "button",
|
|
5619
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5620
|
+
style: {
|
|
5621
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5622
|
+
color: "var(--ohw-primary-foreground)"
|
|
5623
|
+
},
|
|
5624
|
+
disabled: !state.isValid,
|
|
5625
|
+
onClick: state.handleSubmit,
|
|
5626
|
+
children: state.submitLabel
|
|
5627
|
+
}
|
|
5628
|
+
)
|
|
5629
|
+
] })
|
|
6270
5630
|
] });
|
|
6271
5631
|
}
|
|
6272
5632
|
|
|
5633
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5634
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
5635
|
+
function LinkPopover({
|
|
5636
|
+
open = true,
|
|
5637
|
+
panelRef,
|
|
5638
|
+
portalContainer,
|
|
5639
|
+
onClose,
|
|
5640
|
+
...editorProps
|
|
5641
|
+
}) {
|
|
5642
|
+
return /* @__PURE__ */ jsx20(
|
|
5643
|
+
Dialog2,
|
|
5644
|
+
{
|
|
5645
|
+
open,
|
|
5646
|
+
onOpenChange: (next) => {
|
|
5647
|
+
if (!next) onClose?.();
|
|
5648
|
+
},
|
|
5649
|
+
children: /* @__PURE__ */ jsx20(
|
|
5650
|
+
DialogContent,
|
|
5651
|
+
{
|
|
5652
|
+
ref: panelRef,
|
|
5653
|
+
container: portalContainer,
|
|
5654
|
+
"data-ohw-link-popover-root": "",
|
|
5655
|
+
"data-ohw-link-modal-root": "",
|
|
5656
|
+
"data-ohw-bridge": "",
|
|
5657
|
+
showCloseButton: false,
|
|
5658
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5659
|
+
children: /* @__PURE__ */ jsx20(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5660
|
+
}
|
|
5661
|
+
)
|
|
5662
|
+
}
|
|
5663
|
+
);
|
|
5664
|
+
}
|
|
5665
|
+
|
|
6273
5666
|
// src/ui/link-modal/devFixtures.ts
|
|
6274
5667
|
var DEV_SITE_PAGES = [
|
|
6275
5668
|
{ path: "/", title: "Home" },
|
|
@@ -6288,767 +5681,48 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
6288
5681
|
{ id: "feel-split", label: "Feel Split" },
|
|
6289
5682
|
{ id: "founder-teaser", label: "Founder" },
|
|
6290
5683
|
{ id: "plan-form", label: "Plan Form" },
|
|
6291
|
-
{ id: "testimonials", label: "Testimonials" },
|
|
6292
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
{ id: "
|
|
6297
|
-
{ id: "
|
|
6298
|
-
{ id: "
|
|
6299
|
-
{ id: "
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
{ id: "class-
|
|
6305
|
-
{ id: "
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
{ id: "
|
|
6309
|
-
{ id: "
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
{ id: "
|
|
6313
|
-
{ id: "
|
|
6314
|
-
{ id: "
|
|
6315
|
-
{ id: "
|
|
6316
|
-
],
|
|
6317
|
-
"/
|
|
6318
|
-
|
|
6319
|
-
{ id: "
|
|
6320
|
-
{ id: "
|
|
6321
|
-
{ id: "
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
"
|
|
6329
|
-
{ id: "hello-hero", label: "Hello" },
|
|
6330
|
-
{ id: "contact-form", label: "Contact Form" },
|
|
6331
|
-
{ id: "faq", label: "FAQ" },
|
|
6332
|
-
{ id: "footer", label: "Footer" }
|
|
6333
|
-
]
|
|
6334
|
-
};
|
|
6335
|
-
function shouldUseDevFixtures() {
|
|
6336
|
-
if (typeof window === "undefined") return false;
|
|
6337
|
-
const raw = readPreservedSearch();
|
|
6338
|
-
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
6339
|
-
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6340
|
-
}
|
|
6341
|
-
|
|
6342
|
-
// src/lib/nav-items.ts
|
|
6343
|
-
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6344
|
-
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6345
|
-
function getLinkHref(el) {
|
|
6346
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6347
|
-
if (key) {
|
|
6348
|
-
const stored = getStoredLinkHref(key);
|
|
6349
|
-
if (stored !== void 0) return stored;
|
|
6350
|
-
}
|
|
6351
|
-
return el.getAttribute("href") ?? "";
|
|
6352
|
-
}
|
|
6353
|
-
function isNavbarButton(el) {
|
|
6354
|
-
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6355
|
-
}
|
|
6356
|
-
function isNavbarLinkItem(el) {
|
|
6357
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6358
|
-
if (isNavbarButton(el)) return false;
|
|
6359
|
-
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6360
|
-
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6361
|
-
}
|
|
6362
|
-
function getNavbarDesktopContainer() {
|
|
6363
|
-
return document.querySelector("[data-ohw-nav-container]");
|
|
6364
|
-
}
|
|
6365
|
-
function getNavbarDrawerContainer() {
|
|
6366
|
-
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6367
|
-
}
|
|
6368
|
-
function listNavbarItems() {
|
|
6369
|
-
const desktop = getNavbarDesktopContainer();
|
|
6370
|
-
if (desktop) {
|
|
6371
|
-
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6372
|
-
}
|
|
6373
|
-
const drawer = getNavbarDrawerContainer();
|
|
6374
|
-
if (drawer) {
|
|
6375
|
-
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6376
|
-
}
|
|
6377
|
-
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6378
|
-
}
|
|
6379
|
-
function parseNavIndexFromKey(key) {
|
|
6380
|
-
if (!key) return null;
|
|
6381
|
-
const match = key.match(/^nav-(\d+)-href$/);
|
|
6382
|
-
if (!match) return null;
|
|
6383
|
-
return parseInt(match[1], 10);
|
|
6384
|
-
}
|
|
6385
|
-
function getNavbarIndicesInDom() {
|
|
6386
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6387
|
-
for (const item of listNavbarItems()) {
|
|
6388
|
-
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6389
|
-
if (idx !== null) indices.add(idx);
|
|
6390
|
-
}
|
|
6391
|
-
return [...indices].sort((a, b) => a - b);
|
|
6392
|
-
}
|
|
6393
|
-
function getNextNavbarIndex() {
|
|
6394
|
-
const indices = getNavbarIndicesInDom();
|
|
6395
|
-
if (indices.length === 0) return 0;
|
|
6396
|
-
return Math.max(...indices) + 1;
|
|
6397
|
-
}
|
|
6398
|
-
function getNavbarExistingTargets() {
|
|
6399
|
-
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6400
|
-
}
|
|
6401
|
-
function getNavOrderFromDom() {
|
|
6402
|
-
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6403
|
-
}
|
|
6404
|
-
function parseNavOrder(content) {
|
|
6405
|
-
const raw = content[NAV_ORDER_KEY];
|
|
6406
|
-
if (!raw) return null;
|
|
6407
|
-
try {
|
|
6408
|
-
const parsed = JSON.parse(raw);
|
|
6409
|
-
if (!Array.isArray(parsed)) return null;
|
|
6410
|
-
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6411
|
-
} catch {
|
|
6412
|
-
return null;
|
|
6413
|
-
}
|
|
6414
|
-
}
|
|
6415
|
-
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6416
|
-
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6417
|
-
}
|
|
6418
|
-
function cloneNavLinkShell(template) {
|
|
6419
|
-
const anchor = document.createElement("a");
|
|
6420
|
-
if (template) {
|
|
6421
|
-
anchor.style.cssText = template.style.cssText;
|
|
6422
|
-
if (template.className) anchor.className = template.className;
|
|
6423
|
-
}
|
|
6424
|
-
anchor.style.cursor = "pointer";
|
|
6425
|
-
anchor.style.textDecoration = "none";
|
|
6426
|
-
return anchor;
|
|
6427
|
-
}
|
|
6428
|
-
function buildNavLink(index, href, label, template) {
|
|
6429
|
-
const anchor = cloneNavLinkShell(template);
|
|
6430
|
-
anchor.href = href;
|
|
6431
|
-
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6432
|
-
const span = document.createElement("span");
|
|
6433
|
-
span.setAttribute("data-ohw-editable", "text");
|
|
6434
|
-
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6435
|
-
span.textContent = label;
|
|
6436
|
-
anchor.appendChild(span);
|
|
6437
|
-
return anchor;
|
|
6438
|
-
}
|
|
6439
|
-
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6440
|
-
if (!afterHrefKey) {
|
|
6441
|
-
container.appendChild(anchor);
|
|
6442
|
-
return;
|
|
6443
|
-
}
|
|
6444
|
-
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6445
|
-
if (afterEl?.parentElement === container) {
|
|
6446
|
-
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6447
|
-
return;
|
|
6448
|
-
}
|
|
6449
|
-
container.appendChild(anchor);
|
|
6450
|
-
}
|
|
6451
|
-
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6452
|
-
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6453
|
-
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6454
|
-
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6455
|
-
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6456
|
-
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6457
|
-
let primary = null;
|
|
6458
|
-
const desktopContainer = getNavbarDesktopContainer();
|
|
6459
|
-
if (desktopContainer) {
|
|
6460
|
-
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6461
|
-
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6462
|
-
primary = desktopAnchor;
|
|
6463
|
-
}
|
|
6464
|
-
const drawerContainer = getNavbarDrawerContainer();
|
|
6465
|
-
if (drawerContainer) {
|
|
6466
|
-
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6467
|
-
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6468
|
-
if (!primary) primary = drawerAnchor;
|
|
6469
|
-
}
|
|
6470
|
-
if (!primary) {
|
|
6471
|
-
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6472
|
-
const nav = document.querySelector("nav");
|
|
6473
|
-
nav?.appendChild(fallback);
|
|
6474
|
-
primary = fallback;
|
|
6475
|
-
}
|
|
6476
|
-
return primary;
|
|
6477
|
-
}
|
|
6478
|
-
function applyNavOrderToContainer(container, order) {
|
|
6479
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6480
|
-
for (const hrefKey of order) {
|
|
6481
|
-
if (seen.has(hrefKey)) continue;
|
|
6482
|
-
seen.add(hrefKey);
|
|
6483
|
-
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6484
|
-
if (el) container.appendChild(el);
|
|
6485
|
-
}
|
|
6486
|
-
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6487
|
-
if (!isNavbarLinkItem(el)) continue;
|
|
6488
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6489
|
-
if (!key || seen.has(key)) continue;
|
|
6490
|
-
container.appendChild(el);
|
|
6491
|
-
}
|
|
6492
|
-
}
|
|
6493
|
-
function applyNavOrder(order) {
|
|
6494
|
-
const desktop = getNavbarDesktopContainer();
|
|
6495
|
-
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6496
|
-
const drawer = getNavbarDrawerContainer();
|
|
6497
|
-
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6498
|
-
}
|
|
6499
|
-
function collectNavbarIndicesFromContent(content) {
|
|
6500
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6501
|
-
for (const key of Object.keys(content)) {
|
|
6502
|
-
const idx = parseNavIndexFromKey(key);
|
|
6503
|
-
if (idx !== null) indices.add(idx);
|
|
6504
|
-
}
|
|
6505
|
-
const countRaw = content[NAV_COUNT_KEY];
|
|
6506
|
-
if (countRaw) {
|
|
6507
|
-
const count = parseInt(countRaw, 10);
|
|
6508
|
-
if (Number.isFinite(count) && count > 0) {
|
|
6509
|
-
for (let i = 0; i < count; i++) indices.add(i);
|
|
6510
|
-
}
|
|
6511
|
-
}
|
|
6512
|
-
return [...indices].sort((a, b) => a - b);
|
|
6513
|
-
}
|
|
6514
|
-
function navbarIndexExistsInDom(index) {
|
|
6515
|
-
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6516
|
-
}
|
|
6517
|
-
function reconcileNavbarItemsFromContent(content) {
|
|
6518
|
-
const indices = collectNavbarIndicesFromContent(content);
|
|
6519
|
-
for (const index of indices) {
|
|
6520
|
-
if (navbarIndexExistsInDom(index)) continue;
|
|
6521
|
-
const href = content[`nav-${index}-href`];
|
|
6522
|
-
const label = content[`nav-${index}-label`];
|
|
6523
|
-
if (!href && !label) continue;
|
|
6524
|
-
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6525
|
-
}
|
|
6526
|
-
const order = parseNavOrder(content);
|
|
6527
|
-
if (order?.length) applyNavOrder(order);
|
|
6528
|
-
}
|
|
6529
|
-
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6530
|
-
const order = getNavOrderFromDom();
|
|
6531
|
-
if (!afterAnchor) {
|
|
6532
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6533
|
-
return order;
|
|
6534
|
-
}
|
|
6535
|
-
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6536
|
-
if (!afterKey) {
|
|
6537
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6538
|
-
return order;
|
|
6539
|
-
}
|
|
6540
|
-
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6541
|
-
const pos = withoutNew.indexOf(afterKey);
|
|
6542
|
-
if (pos >= 0) {
|
|
6543
|
-
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6544
|
-
return withoutNew;
|
|
6545
|
-
}
|
|
6546
|
-
withoutNew.push(newHrefKey);
|
|
6547
|
-
return withoutNew;
|
|
6548
|
-
}
|
|
6549
|
-
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6550
|
-
const index = getNextNavbarIndex();
|
|
6551
|
-
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6552
|
-
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6553
|
-
const hrefKey = `nav-${index}-href`;
|
|
6554
|
-
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6555
|
-
applyNavOrder(order);
|
|
6556
|
-
return {
|
|
6557
|
-
anchor,
|
|
6558
|
-
index,
|
|
6559
|
-
hrefKey,
|
|
6560
|
-
labelKey: `nav-${index}-label`,
|
|
6561
|
-
href,
|
|
6562
|
-
label,
|
|
6563
|
-
order
|
|
6564
|
-
};
|
|
6565
|
-
}
|
|
6566
|
-
|
|
6567
|
-
// src/lib/footer-items.ts
|
|
6568
|
-
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6569
|
-
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6570
|
-
function parseFooterHrefKey(key) {
|
|
6571
|
-
if (!key) return null;
|
|
6572
|
-
const match = key.match(FOOTER_HREF_RE);
|
|
6573
|
-
if (!match) return null;
|
|
6574
|
-
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6575
|
-
}
|
|
6576
|
-
function isFooterHrefKey(key) {
|
|
6577
|
-
return parseFooterHrefKey(key) !== null;
|
|
6578
|
-
}
|
|
6579
|
-
function getFooterRoot() {
|
|
6580
|
-
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6581
|
-
}
|
|
6582
|
-
function getFooterLinksContainer() {
|
|
6583
|
-
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6584
|
-
}
|
|
6585
|
-
function isFooterLinkAnchor(el) {
|
|
6586
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6587
|
-
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6588
|
-
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6589
|
-
}
|
|
6590
|
-
function listFooterColumns() {
|
|
6591
|
-
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6592
|
-
if (!root) return [];
|
|
6593
|
-
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6594
|
-
if (explicit.length > 0) return explicit;
|
|
6595
|
-
return Array.from(root.children).filter((el) => {
|
|
6596
|
-
if (!(el instanceof HTMLElement)) return false;
|
|
6597
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6598
|
-
isFooterLinkAnchor
|
|
6599
|
-
);
|
|
6600
|
-
});
|
|
6601
|
-
}
|
|
6602
|
-
function listFooterLinksInColumn(column) {
|
|
6603
|
-
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6604
|
-
isFooterLinkAnchor
|
|
6605
|
-
);
|
|
6606
|
-
}
|
|
6607
|
-
function findFooterColumnForLink(anchor) {
|
|
6608
|
-
const columns = listFooterColumns();
|
|
6609
|
-
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6610
|
-
}
|
|
6611
|
-
function getFooterOrderFromDom() {
|
|
6612
|
-
return listFooterColumns().map(
|
|
6613
|
-
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6614
|
-
);
|
|
6615
|
-
}
|
|
6616
|
-
function findFooterLinkByKey(hrefKey) {
|
|
6617
|
-
return document.querySelector(
|
|
6618
|
-
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6619
|
-
);
|
|
6620
|
-
}
|
|
6621
|
-
function syncFooterColumnIndices(columns) {
|
|
6622
|
-
columns.forEach((col, index) => {
|
|
6623
|
-
const next = String(index);
|
|
6624
|
-
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6625
|
-
col.setAttribute("data-ohw-footer-col", next);
|
|
6626
|
-
}
|
|
6627
|
-
});
|
|
6628
|
-
}
|
|
6629
|
-
function appendChildIfNeeded(parent, child) {
|
|
6630
|
-
if (parent.lastElementChild !== child) {
|
|
6631
|
-
parent.appendChild(child);
|
|
6632
|
-
}
|
|
6633
|
-
}
|
|
6634
|
-
function insertLinkBeforeNext(col, el, nextEl) {
|
|
6635
|
-
if (nextEl) {
|
|
6636
|
-
if (el.nextElementSibling !== nextEl) {
|
|
6637
|
-
col.insertBefore(el, nextEl);
|
|
6638
|
-
}
|
|
6639
|
-
return;
|
|
6640
|
-
}
|
|
6641
|
-
if (col.lastElementChild !== el) {
|
|
6642
|
-
col.appendChild(el);
|
|
6643
|
-
}
|
|
6644
|
-
}
|
|
6645
|
-
function applyFooterOrder(order) {
|
|
6646
|
-
const container = getFooterLinksContainer();
|
|
6647
|
-
if (!container) return;
|
|
6648
|
-
const columns = listFooterColumns();
|
|
6649
|
-
if (columns.length === 0) return;
|
|
6650
|
-
const currentOrder = getFooterOrderFromDom();
|
|
6651
|
-
if (ordersEqual(order, currentOrder)) {
|
|
6652
|
-
syncFooterColumnIndices(columns);
|
|
6653
|
-
return;
|
|
6654
|
-
}
|
|
6655
|
-
const colCount = Math.max(columns.length, order.length);
|
|
6656
|
-
const working = columns.slice(0, colCount);
|
|
6657
|
-
for (let i = 0; i < order.length && i < working.length; i++) {
|
|
6658
|
-
appendChildIfNeeded(container, working[i]);
|
|
6659
|
-
}
|
|
6660
|
-
for (let i = order.length; i < working.length; i++) {
|
|
6661
|
-
appendChildIfNeeded(container, working[i]);
|
|
6662
|
-
}
|
|
6663
|
-
const freshColumns = listFooterColumns();
|
|
6664
|
-
syncFooterColumnIndices(freshColumns);
|
|
6665
|
-
for (let c = 0; c < order.length; c++) {
|
|
6666
|
-
const col = freshColumns[c];
|
|
6667
|
-
if (!col) continue;
|
|
6668
|
-
const colOrder = order[c];
|
|
6669
|
-
for (let j = 0; j < colOrder.length; j++) {
|
|
6670
|
-
const hrefKey = colOrder[j];
|
|
6671
|
-
const el = findFooterLinkByKey(hrefKey);
|
|
6672
|
-
if (!el) continue;
|
|
6673
|
-
if (el.parentElement !== col) {
|
|
6674
|
-
col.appendChild(el);
|
|
6675
|
-
}
|
|
6676
|
-
const nextKey = colOrder[j + 1];
|
|
6677
|
-
const nextEl = nextKey ? findFooterLinkByKey(nextKey) : null;
|
|
6678
|
-
insertLinkBeforeNext(col, el, nextEl?.parentElement === col ? nextEl : null);
|
|
6679
|
-
}
|
|
6680
|
-
}
|
|
6681
|
-
}
|
|
6682
|
-
function ordersEqual(a, b) {
|
|
6683
|
-
if (a.length !== b.length) return false;
|
|
6684
|
-
for (let i = 0; i < a.length; i++) {
|
|
6685
|
-
const left = a[i];
|
|
6686
|
-
const right = b[i];
|
|
6687
|
-
if (left.length !== right.length) return false;
|
|
6688
|
-
for (let j = 0; j < left.length; j++) {
|
|
6689
|
-
if (left[j] !== right[j]) return false;
|
|
6690
|
-
}
|
|
6691
|
-
}
|
|
6692
|
-
return true;
|
|
6693
|
-
}
|
|
6694
|
-
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6695
|
-
const order = getFooterOrderFromDom();
|
|
6696
|
-
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6697
|
-
let fromCol = -1;
|
|
6698
|
-
let fromIdx = -1;
|
|
6699
|
-
for (let c = 0; c < order.length; c++) {
|
|
6700
|
-
const idx = order[c].indexOf(hrefKey);
|
|
6701
|
-
if (idx >= 0) {
|
|
6702
|
-
fromCol = c;
|
|
6703
|
-
fromIdx = idx;
|
|
6704
|
-
break;
|
|
6705
|
-
}
|
|
6706
|
-
}
|
|
6707
|
-
if (fromCol < 0) return null;
|
|
6708
|
-
const next = order.map((col) => [...col]);
|
|
6709
|
-
next[fromCol].splice(fromIdx, 1);
|
|
6710
|
-
let adjusted = insertIndex;
|
|
6711
|
-
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6712
|
-
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6713
|
-
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6714
|
-
if (ordersEqual(next, order)) return null;
|
|
6715
|
-
return next;
|
|
6716
|
-
}
|
|
6717
|
-
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6718
|
-
const order = getFooterOrderFromDom();
|
|
6719
|
-
const columns = listFooterColumns();
|
|
6720
|
-
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6721
|
-
return null;
|
|
6722
|
-
}
|
|
6723
|
-
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6724
|
-
const nextOrder = order.map((col) => [...col]);
|
|
6725
|
-
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6726
|
-
if (!movedOrder) return null;
|
|
6727
|
-
let adjusted = toIndex;
|
|
6728
|
-
if (fromIndex < toIndex) adjusted -= 1;
|
|
6729
|
-
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6730
|
-
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6731
|
-
if (ordersEqual(nextOrder, order)) return null;
|
|
6732
|
-
return nextOrder;
|
|
6733
|
-
}
|
|
6734
|
-
function parseFooterOrder(content) {
|
|
6735
|
-
const raw = content[FOOTER_ORDER_KEY];
|
|
6736
|
-
if (!raw) return null;
|
|
6737
|
-
try {
|
|
6738
|
-
const parsed = JSON.parse(raw);
|
|
6739
|
-
if (!Array.isArray(parsed)) return null;
|
|
6740
|
-
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6741
|
-
} catch {
|
|
6742
|
-
return null;
|
|
6743
|
-
}
|
|
6744
|
-
}
|
|
6745
|
-
function reconcileFooterOrderFromContent(content) {
|
|
6746
|
-
const order = parseFooterOrder(content);
|
|
6747
|
-
if (!order?.length) return;
|
|
6748
|
-
const current = getFooterOrderFromDom();
|
|
6749
|
-
if (ordersEqual(order, current)) {
|
|
6750
|
-
syncFooterColumnIndices(listFooterColumns());
|
|
6751
|
-
return;
|
|
6752
|
-
}
|
|
6753
|
-
applyFooterOrder(order);
|
|
6754
|
-
}
|
|
6755
|
-
function buildLinkDropSlots(column, columnIndex) {
|
|
6756
|
-
const links = listFooterLinksInColumn(column);
|
|
6757
|
-
const colRect = column.getBoundingClientRect();
|
|
6758
|
-
const slots = [];
|
|
6759
|
-
const barThickness = 3;
|
|
6760
|
-
if (links.length === 0) {
|
|
6761
|
-
slots.push({
|
|
6762
|
-
insertIndex: 0,
|
|
6763
|
-
columnIndex,
|
|
6764
|
-
left: colRect.left,
|
|
6765
|
-
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6766
|
-
width: colRect.width,
|
|
6767
|
-
height: barThickness,
|
|
6768
|
-
direction: "horizontal"
|
|
6769
|
-
});
|
|
6770
|
-
return slots;
|
|
6771
|
-
}
|
|
6772
|
-
for (let i = 0; i <= links.length; i++) {
|
|
6773
|
-
let top;
|
|
6774
|
-
if (i === 0) {
|
|
6775
|
-
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6776
|
-
} else if (i === links.length) {
|
|
6777
|
-
const last = links[links.length - 1].getBoundingClientRect();
|
|
6778
|
-
top = last.bottom - barThickness / 2;
|
|
6779
|
-
} else {
|
|
6780
|
-
const prev = links[i - 1].getBoundingClientRect();
|
|
6781
|
-
const next = links[i].getBoundingClientRect();
|
|
6782
|
-
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6783
|
-
}
|
|
6784
|
-
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6785
|
-
slots.push({
|
|
6786
|
-
insertIndex: i,
|
|
6787
|
-
columnIndex,
|
|
6788
|
-
left: widthRef.left,
|
|
6789
|
-
top,
|
|
6790
|
-
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6791
|
-
height: barThickness,
|
|
6792
|
-
direction: "horizontal"
|
|
6793
|
-
});
|
|
6794
|
-
}
|
|
6795
|
-
return slots;
|
|
6796
|
-
}
|
|
6797
|
-
function buildColumnDropSlots() {
|
|
6798
|
-
const columns = listFooterColumns();
|
|
6799
|
-
const slots = [];
|
|
6800
|
-
const barThickness = 3;
|
|
6801
|
-
if (columns.length === 0) return slots;
|
|
6802
|
-
for (let i = 0; i <= columns.length; i++) {
|
|
6803
|
-
let left;
|
|
6804
|
-
let height;
|
|
6805
|
-
let top;
|
|
6806
|
-
if (i === 0) {
|
|
6807
|
-
const first = columns[0].getBoundingClientRect();
|
|
6808
|
-
left = first.left - barThickness / 2;
|
|
6809
|
-
top = first.top;
|
|
6810
|
-
height = first.height;
|
|
6811
|
-
} else if (i === columns.length) {
|
|
6812
|
-
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
6813
|
-
left = last.right - barThickness / 2;
|
|
6814
|
-
top = last.top;
|
|
6815
|
-
height = last.height;
|
|
6816
|
-
} else {
|
|
6817
|
-
const prev = columns[i - 1].getBoundingClientRect();
|
|
6818
|
-
const next = columns[i].getBoundingClientRect();
|
|
6819
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
6820
|
-
top = Math.min(prev.top, next.top);
|
|
6821
|
-
height = Math.max(prev.bottom, next.bottom) - top;
|
|
6822
|
-
}
|
|
6823
|
-
slots.push({
|
|
6824
|
-
insertIndex: i,
|
|
6825
|
-
columnIndex: i,
|
|
6826
|
-
left,
|
|
6827
|
-
top,
|
|
6828
|
-
width: barThickness,
|
|
6829
|
-
height: Math.max(height, 24),
|
|
6830
|
-
direction: "vertical"
|
|
6831
|
-
});
|
|
6832
|
-
}
|
|
6833
|
-
return slots;
|
|
6834
|
-
}
|
|
6835
|
-
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
6836
|
-
const columns = listFooterColumns();
|
|
6837
|
-
let best = null;
|
|
6838
|
-
for (let c = 0; c < columns.length; c++) {
|
|
6839
|
-
const col = columns[c];
|
|
6840
|
-
const colRect = col.getBoundingClientRect();
|
|
6841
|
-
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
6842
|
-
if (!inColX) continue;
|
|
6843
|
-
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
6844
|
-
const links = listFooterLinksInColumn(col);
|
|
6845
|
-
const fromIdx = links.findIndex(
|
|
6846
|
-
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
6847
|
-
);
|
|
6848
|
-
if (fromIdx < 0) return true;
|
|
6849
|
-
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
6850
|
-
return true;
|
|
6851
|
-
}
|
|
6852
|
-
return true;
|
|
6853
|
-
});
|
|
6854
|
-
for (const slot of slots) {
|
|
6855
|
-
const cy = slot.top + slot.height / 2;
|
|
6856
|
-
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
6857
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
6858
|
-
}
|
|
6859
|
-
}
|
|
6860
|
-
return best?.slot ?? null;
|
|
6861
|
-
}
|
|
6862
|
-
function findColumnIndexForKey(hrefKey) {
|
|
6863
|
-
const order = getFooterOrderFromDom();
|
|
6864
|
-
for (let c = 0; c < order.length; c++) {
|
|
6865
|
-
if (order[c].includes(hrefKey)) return c;
|
|
6866
|
-
}
|
|
6867
|
-
return -1;
|
|
6868
|
-
}
|
|
6869
|
-
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
6870
|
-
const slots = buildColumnDropSlots();
|
|
6871
|
-
let best = null;
|
|
6872
|
-
for (const slot of slots) {
|
|
6873
|
-
const cx2 = slot.left + slot.width / 2;
|
|
6874
|
-
const dist = Math.abs(clientX - cx2);
|
|
6875
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
6876
|
-
}
|
|
6877
|
-
return best?.slot ?? null;
|
|
6878
|
-
}
|
|
6879
|
-
|
|
6880
|
-
// src/lib/carousel.ts
|
|
6881
|
-
import { useEffect as useEffect7, useState as useState6 } from "react";
|
|
6882
|
-
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
6883
|
-
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
6884
|
-
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
6885
|
-
var CAROUSEL_EVENT = "ohw:carousel-change";
|
|
6886
|
-
function listCarouselKeys() {
|
|
6887
|
-
const keys = /* @__PURE__ */ new Set();
|
|
6888
|
-
document.querySelectorAll(`[${CAROUSEL_ATTR}]`).forEach((el) => {
|
|
6889
|
-
const key = el.getAttribute("data-ohw-key");
|
|
6890
|
-
if (key) keys.add(key);
|
|
6891
|
-
});
|
|
6892
|
-
return [...keys];
|
|
6893
|
-
}
|
|
6894
|
-
function containersForKey(key) {
|
|
6895
|
-
return Array.from(
|
|
6896
|
-
document.querySelectorAll(`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`)
|
|
6897
|
-
);
|
|
6898
|
-
}
|
|
6899
|
-
function isCarouselKey(key) {
|
|
6900
|
-
return containersForKey(key).length > 0;
|
|
6901
|
-
}
|
|
6902
|
-
function parseSlides(raw) {
|
|
6903
|
-
if (!raw) return [];
|
|
6904
|
-
try {
|
|
6905
|
-
const parsed = JSON.parse(raw);
|
|
6906
|
-
if (!Array.isArray(parsed)) return [];
|
|
6907
|
-
return parsed.filter((s) => Boolean(s) && typeof s === "object").map((s) => ({ src: String(s.src ?? ""), alt: String(s.alt ?? "") }));
|
|
6908
|
-
} catch {
|
|
6909
|
-
return [];
|
|
6910
|
-
}
|
|
6911
|
-
}
|
|
6912
|
-
function readCarouselValue(key) {
|
|
6913
|
-
const container = containersForKey(key)[0];
|
|
6914
|
-
if (!container) return [];
|
|
6915
|
-
const fromAttr = parseSlides(container.getAttribute(CAROUSEL_VALUE_ATTR));
|
|
6916
|
-
if (fromAttr.length > 0) return fromAttr;
|
|
6917
|
-
return Array.from(container.querySelectorAll(`[${CAROUSEL_SLIDE_ATTR}]`)).filter((slide) => slide.closest(`[${CAROUSEL_ATTR}]`) === container).sort((a, b) => slideIndex(a) - slideIndex(b)).map((slide) => {
|
|
6918
|
-
const img = slide instanceof HTMLImageElement ? slide : slide.querySelector("img");
|
|
6919
|
-
return { src: img?.src ?? "", alt: img?.alt ?? "" };
|
|
6920
|
-
});
|
|
6921
|
-
}
|
|
6922
|
-
function slideIndex(el) {
|
|
6923
|
-
const raw = el.getAttribute(CAROUSEL_SLIDE_ATTR);
|
|
6924
|
-
const n = raw ? parseInt(raw, 10) : NaN;
|
|
6925
|
-
return Number.isFinite(n) ? n : 0;
|
|
6926
|
-
}
|
|
6927
|
-
function applyCarouselValue(key, slides) {
|
|
6928
|
-
const value = JSON.stringify(slides);
|
|
6929
|
-
for (const container of containersForKey(key)) {
|
|
6930
|
-
if (container.getAttribute(CAROUSEL_VALUE_ATTR) === value) continue;
|
|
6931
|
-
container.setAttribute(CAROUSEL_VALUE_ATTR, value);
|
|
6932
|
-
container.dispatchEvent(
|
|
6933
|
-
new CustomEvent(CAROUSEL_EVENT, { detail: { images: slides } })
|
|
6934
|
-
);
|
|
6935
|
-
}
|
|
6936
|
-
}
|
|
6937
|
-
function applyCarouselNode(key, val) {
|
|
6938
|
-
if (!isCarouselKey(key)) return false;
|
|
6939
|
-
applyCarouselValue(key, parseSlides(val));
|
|
6940
|
-
return true;
|
|
6941
|
-
}
|
|
6942
|
-
function useOhwCarousel(key, initial) {
|
|
6943
|
-
const [images, setImages] = useState6(initial);
|
|
6944
|
-
useEffect7(() => {
|
|
6945
|
-
const el = document.querySelector(
|
|
6946
|
-
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
6947
|
-
);
|
|
6948
|
-
if (!el) return;
|
|
6949
|
-
const onChange = (e) => {
|
|
6950
|
-
const detail = e.detail;
|
|
6951
|
-
if (Array.isArray(detail?.images)) setImages(detail.images);
|
|
6952
|
-
};
|
|
6953
|
-
el.addEventListener(CAROUSEL_EVENT, onChange);
|
|
6954
|
-
return () => el.removeEventListener(CAROUSEL_EVENT, onChange);
|
|
6955
|
-
}, [key]);
|
|
6956
|
-
const bind = {
|
|
6957
|
-
[CAROUSEL_ATTR]: "",
|
|
6958
|
-
"data-ohw-key": key,
|
|
6959
|
-
[CAROUSEL_VALUE_ATTR]: JSON.stringify(images)
|
|
6960
|
-
};
|
|
6961
|
-
return { images, setImages, bind };
|
|
6962
|
-
}
|
|
6963
|
-
|
|
6964
|
-
// src/ui/navbar-container-chrome.tsx
|
|
6965
|
-
import { Plus as Plus2 } from "lucide-react";
|
|
6966
|
-
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
6967
|
-
function NavbarContainerChrome({
|
|
6968
|
-
rect,
|
|
6969
|
-
onAdd
|
|
6970
|
-
}) {
|
|
6971
|
-
const chromeGap = 6;
|
|
6972
|
-
return /* @__PURE__ */ jsx22(
|
|
6973
|
-
"div",
|
|
6974
|
-
{
|
|
6975
|
-
"data-ohw-navbar-container-chrome": "",
|
|
6976
|
-
"data-ohw-bridge": "",
|
|
6977
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
6978
|
-
style: {
|
|
6979
|
-
top: rect.top - chromeGap,
|
|
6980
|
-
left: rect.left - chromeGap,
|
|
6981
|
-
width: rect.width + chromeGap * 2,
|
|
6982
|
-
height: rect.height + chromeGap * 2
|
|
6983
|
-
},
|
|
6984
|
-
children: /* @__PURE__ */ jsx22(
|
|
6985
|
-
"button",
|
|
6986
|
-
{
|
|
6987
|
-
type: "button",
|
|
6988
|
-
"data-ohw-navbar-add-button": "",
|
|
6989
|
-
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
6990
|
-
style: { top: "70%" },
|
|
6991
|
-
"aria-label": "Add item",
|
|
6992
|
-
onMouseDown: (e) => {
|
|
6993
|
-
e.preventDefault();
|
|
6994
|
-
e.stopPropagation();
|
|
6995
|
-
},
|
|
6996
|
-
onClick: (e) => {
|
|
6997
|
-
e.preventDefault();
|
|
6998
|
-
e.stopPropagation();
|
|
6999
|
-
onAdd();
|
|
7000
|
-
},
|
|
7001
|
-
children: /* @__PURE__ */ jsx22(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7002
|
-
}
|
|
7003
|
-
)
|
|
7004
|
-
}
|
|
7005
|
-
);
|
|
5684
|
+
{ id: "testimonials", label: "Testimonials" },
|
|
5685
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
5686
|
+
],
|
|
5687
|
+
"/about": [
|
|
5688
|
+
{ id: "manifesto", label: "Manifesto" },
|
|
5689
|
+
{ id: "story-letter", label: "Our Story" },
|
|
5690
|
+
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
5691
|
+
{ id: "waitlist-cta", label: "Waitlist" },
|
|
5692
|
+
{ id: "personal-training", label: "Personal training" }
|
|
5693
|
+
],
|
|
5694
|
+
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5695
|
+
"/pricing": [
|
|
5696
|
+
{ id: "page-header", label: "Page Header" },
|
|
5697
|
+
{ id: "free-class-cta", label: "Free Class" },
|
|
5698
|
+
{ id: "benefits-marquee", label: "Benefits" },
|
|
5699
|
+
{ id: "monthly-memberships", label: "Memberships" },
|
|
5700
|
+
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5701
|
+
{ id: "package-matcher", label: "Packages" },
|
|
5702
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
5703
|
+
],
|
|
5704
|
+
"/studio": [
|
|
5705
|
+
{ id: "studio-intro", label: "Studio Intro" },
|
|
5706
|
+
{ id: "studio-features", label: "Studio Features" },
|
|
5707
|
+
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5708
|
+
{ id: "studio-visit", label: "Visit Studio" }
|
|
5709
|
+
],
|
|
5710
|
+
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5711
|
+
"/contact": [
|
|
5712
|
+
{ id: "hello-hero", label: "Hello" },
|
|
5713
|
+
{ id: "contact-form", label: "Contact Form" },
|
|
5714
|
+
{ id: "faq", label: "FAQ" }
|
|
5715
|
+
]
|
|
5716
|
+
};
|
|
5717
|
+
function shouldUseDevFixtures() {
|
|
5718
|
+
if (typeof window === "undefined") return false;
|
|
5719
|
+
const raw = readPreservedSearch();
|
|
5720
|
+
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
5721
|
+
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
7006
5722
|
}
|
|
7007
5723
|
|
|
7008
|
-
// src/ui/drop-indicator.tsx
|
|
7009
|
-
import * as React9 from "react";
|
|
7010
|
-
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
7011
|
-
var dropIndicatorVariants = cva(
|
|
7012
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7013
|
-
{
|
|
7014
|
-
variants: {
|
|
7015
|
-
direction: {
|
|
7016
|
-
vertical: "h-6 w-[3px]",
|
|
7017
|
-
horizontal: "h-[3px] w-[200px]"
|
|
7018
|
-
},
|
|
7019
|
-
state: {
|
|
7020
|
-
default: "opacity-0",
|
|
7021
|
-
hover: "opacity-100",
|
|
7022
|
-
dragIdle: "opacity-40",
|
|
7023
|
-
dragActive: "opacity-100"
|
|
7024
|
-
}
|
|
7025
|
-
},
|
|
7026
|
-
defaultVariants: {
|
|
7027
|
-
direction: "vertical",
|
|
7028
|
-
state: "default"
|
|
7029
|
-
}
|
|
7030
|
-
}
|
|
7031
|
-
);
|
|
7032
|
-
var DropIndicator = React9.forwardRef(
|
|
7033
|
-
({ className, direction, state, ...props }, ref) => {
|
|
7034
|
-
return /* @__PURE__ */ jsx23(
|
|
7035
|
-
"div",
|
|
7036
|
-
{
|
|
7037
|
-
ref,
|
|
7038
|
-
"data-slot": "drop-indicator",
|
|
7039
|
-
"data-direction": direction ?? "vertical",
|
|
7040
|
-
"data-state": state ?? "default",
|
|
7041
|
-
"aria-hidden": "true",
|
|
7042
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7043
|
-
...props
|
|
7044
|
-
}
|
|
7045
|
-
);
|
|
7046
|
-
}
|
|
7047
|
-
);
|
|
7048
|
-
DropIndicator.displayName = "DropIndicator";
|
|
7049
|
-
|
|
7050
5724
|
// src/ui/badge.tsx
|
|
7051
|
-
import { jsx as
|
|
5725
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
7052
5726
|
var badgeVariants = cva(
|
|
7053
5727
|
"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",
|
|
7054
5728
|
{
|
|
@@ -7066,12 +5740,12 @@ var badgeVariants = cva(
|
|
|
7066
5740
|
}
|
|
7067
5741
|
);
|
|
7068
5742
|
function Badge({ className, variant, ...props }) {
|
|
7069
|
-
return /* @__PURE__ */
|
|
5743
|
+
return /* @__PURE__ */ jsx21("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7070
5744
|
}
|
|
7071
5745
|
|
|
7072
5746
|
// src/OhhwellsBridge.tsx
|
|
7073
5747
|
import { Link as Link2 } from "lucide-react";
|
|
7074
|
-
import { Fragment as
|
|
5748
|
+
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
7075
5749
|
var PRIMARY2 = "#0885FE";
|
|
7076
5750
|
var IMAGE_FADE_MS = 300;
|
|
7077
5751
|
function runOpacityFade(el, onDone) {
|
|
@@ -7250,7 +5924,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
7250
5924
|
const root = createRoot(container);
|
|
7251
5925
|
flushSync(() => {
|
|
7252
5926
|
root.render(
|
|
7253
|
-
/* @__PURE__ */
|
|
5927
|
+
/* @__PURE__ */ jsx22(
|
|
7254
5928
|
SchedulingWidget,
|
|
7255
5929
|
{
|
|
7256
5930
|
notifyOnConnect,
|
|
@@ -7290,7 +5964,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
7290
5964
|
}
|
|
7291
5965
|
}
|
|
7292
5966
|
}
|
|
7293
|
-
function
|
|
5967
|
+
function getLinkHref(el) {
|
|
7294
5968
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
7295
5969
|
return anchor?.getAttribute("href") ?? "";
|
|
7296
5970
|
}
|
|
@@ -7312,7 +5986,7 @@ function isDragHandleDisabled(el) {
|
|
|
7312
5986
|
return raw === "true" || raw === "";
|
|
7313
5987
|
});
|
|
7314
5988
|
}
|
|
7315
|
-
function collectEditableNodes(
|
|
5989
|
+
function collectEditableNodes() {
|
|
7316
5990
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
7317
5991
|
if (el.dataset.ohwEditable === "image") {
|
|
7318
5992
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7327,7 +6001,7 @@ function collectEditableNodes(extraContent) {
|
|
|
7327
6001
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
7328
6002
|
}
|
|
7329
6003
|
if (el.dataset.ohwEditable === "link") {
|
|
7330
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6004
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
7331
6005
|
}
|
|
7332
6006
|
return {
|
|
7333
6007
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -7338,16 +6012,8 @@ function collectEditableNodes(extraContent) {
|
|
|
7338
6012
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
7339
6013
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
7340
6014
|
if (!key) return;
|
|
7341
|
-
nodes.push({ key, type: "link", text:
|
|
6015
|
+
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
7342
6016
|
});
|
|
7343
|
-
if (extraContent) {
|
|
7344
|
-
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
7345
|
-
const text = extraContent[key];
|
|
7346
|
-
if (typeof text === "string" && text.length > 0) {
|
|
7347
|
-
nodes.push({ key, type: "meta", text });
|
|
7348
|
-
}
|
|
7349
|
-
}
|
|
7350
|
-
}
|
|
7351
6017
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
7352
6018
|
const key = el.dataset.ohwKey ?? "";
|
|
7353
6019
|
const video = getVideoEl(el);
|
|
@@ -7355,9 +6021,6 @@ function collectEditableNodes(extraContent) {
|
|
|
7355
6021
|
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
7356
6022
|
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
7357
6023
|
});
|
|
7358
|
-
for (const key of listCarouselKeys()) {
|
|
7359
|
-
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
7360
|
-
}
|
|
7361
6024
|
return nodes;
|
|
7362
6025
|
}
|
|
7363
6026
|
function isMediaEditable(el) {
|
|
@@ -7435,7 +6098,7 @@ function applyLinkByKey(key, val) {
|
|
|
7435
6098
|
}
|
|
7436
6099
|
function isInsideLinkEditor(target) {
|
|
7437
6100
|
return Boolean(
|
|
7438
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest(
|
|
6101
|
+
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"]')
|
|
7439
6102
|
);
|
|
7440
6103
|
}
|
|
7441
6104
|
function getHrefKeyFromElement(el) {
|
|
@@ -7446,30 +6109,7 @@ function getHrefKeyFromElement(el) {
|
|
|
7446
6109
|
if (!key) return null;
|
|
7447
6110
|
return { anchor, key };
|
|
7448
6111
|
}
|
|
7449
|
-
function
|
|
7450
|
-
if (el.draggable) el.draggable = false;
|
|
7451
|
-
if (el.getAttribute("draggable") !== "false") {
|
|
7452
|
-
el.setAttribute("draggable", "false");
|
|
7453
|
-
}
|
|
7454
|
-
}
|
|
7455
|
-
function clearTextSelection() {
|
|
7456
|
-
const sel = window.getSelection();
|
|
7457
|
-
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7458
|
-
}
|
|
7459
|
-
function armFooterPressDrag() {
|
|
7460
|
-
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7461
|
-
}
|
|
7462
|
-
function lockFooterDuringDrag() {
|
|
7463
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7464
|
-
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7465
|
-
clearTextSelection();
|
|
7466
|
-
}
|
|
7467
|
-
function unlockFooterDragInteraction() {
|
|
7468
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7469
|
-
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7470
|
-
clearTextSelection();
|
|
7471
|
-
}
|
|
7472
|
-
function isNavbarButton2(el) {
|
|
6112
|
+
function isNavbarButton(el) {
|
|
7473
6113
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
7474
6114
|
}
|
|
7475
6115
|
function getNavigationItemAnchor(el) {
|
|
@@ -7481,8 +6121,19 @@ function getNavigationItemAnchor(el) {
|
|
|
7481
6121
|
function isNavigationItem(el) {
|
|
7482
6122
|
return getNavigationItemAnchor(el) !== null;
|
|
7483
6123
|
}
|
|
6124
|
+
function getNavigationItemAddHintTarget(anchor) {
|
|
6125
|
+
const items = listNavigationItems();
|
|
6126
|
+
const idx = items.indexOf(anchor);
|
|
6127
|
+
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
6128
|
+
return anchor;
|
|
6129
|
+
}
|
|
6130
|
+
function listNavigationItems() {
|
|
6131
|
+
return Array.from(
|
|
6132
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
6133
|
+
).filter((el) => isNavigationItem(el));
|
|
6134
|
+
}
|
|
7484
6135
|
function getNavigationItemReorderState(anchor) {
|
|
7485
|
-
if (
|
|
6136
|
+
if (isNavbarButton(anchor)) return { key: null, disabled: false };
|
|
7486
6137
|
return getReorderHandleStateFromAnchor(anchor);
|
|
7487
6138
|
}
|
|
7488
6139
|
function getReorderHandleState(el) {
|
|
@@ -7504,120 +6155,6 @@ function clearHrefKeyHover(anchor) {
|
|
|
7504
6155
|
function isInsideNavigationItem(el) {
|
|
7505
6156
|
return getNavigationItemAnchor(el) !== null;
|
|
7506
6157
|
}
|
|
7507
|
-
function getNavigationRoot(el) {
|
|
7508
|
-
const explicit = el.closest("[data-ohw-nav-root]");
|
|
7509
|
-
if (explicit) return explicit;
|
|
7510
|
-
return el.closest("nav, footer, aside");
|
|
7511
|
-
}
|
|
7512
|
-
function findFooterItemGroup(item) {
|
|
7513
|
-
const footer = item.closest("footer");
|
|
7514
|
-
if (!footer) return null;
|
|
7515
|
-
let node = item.parentElement;
|
|
7516
|
-
while (node && node !== footer) {
|
|
7517
|
-
const hasDirectNavItems = Array.from(
|
|
7518
|
-
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
7519
|
-
).some(isNavigationItem);
|
|
7520
|
-
if (hasDirectNavItems) return node;
|
|
7521
|
-
node = node.parentElement;
|
|
7522
|
-
}
|
|
7523
|
-
return null;
|
|
7524
|
-
}
|
|
7525
|
-
function isNavigationRoot(el) {
|
|
7526
|
-
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
7527
|
-
}
|
|
7528
|
-
function isInferredFooterGroup(el) {
|
|
7529
|
-
const footer = el.closest("footer");
|
|
7530
|
-
if (!footer || el === footer) return false;
|
|
7531
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
7532
|
-
}
|
|
7533
|
-
function isNavigationContainer(el) {
|
|
7534
|
-
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
7535
|
-
}
|
|
7536
|
-
function isPointOverNavigation(x, y) {
|
|
7537
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
7538
|
-
if (!navRoot) return false;
|
|
7539
|
-
const r2 = navRoot.getBoundingClientRect();
|
|
7540
|
-
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
7541
|
-
}
|
|
7542
|
-
function isPointOverNavItem(container, x, y) {
|
|
7543
|
-
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
7544
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
7545
|
-
const itemRect = el.getBoundingClientRect();
|
|
7546
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
7547
|
-
});
|
|
7548
|
-
}
|
|
7549
|
-
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
7550
|
-
if (getNavigationItemAnchor(target)) return null;
|
|
7551
|
-
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
7552
|
-
const plainLink = target.closest("a");
|
|
7553
|
-
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
7554
|
-
return null;
|
|
7555
|
-
}
|
|
7556
|
-
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
7557
|
-
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
7558
|
-
return fromClosest;
|
|
7559
|
-
}
|
|
7560
|
-
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
7561
|
-
if (!navRoot) return null;
|
|
7562
|
-
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
7563
|
-
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
7564
|
-
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
7565
|
-
return container;
|
|
7566
|
-
}
|
|
7567
|
-
return null;
|
|
7568
|
-
}
|
|
7569
|
-
function getNavigationSelectionParent(el) {
|
|
7570
|
-
if (isNavigationItem(el)) {
|
|
7571
|
-
const explicit = el.closest("[data-ohw-nav-container]");
|
|
7572
|
-
if (explicit) return explicit;
|
|
7573
|
-
const footerGroup = findFooterItemGroup(el);
|
|
7574
|
-
if (footerGroup) return footerGroup;
|
|
7575
|
-
return getNavigationRoot(el);
|
|
7576
|
-
}
|
|
7577
|
-
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
7578
|
-
return getNavigationRoot(el);
|
|
7579
|
-
}
|
|
7580
|
-
return null;
|
|
7581
|
-
}
|
|
7582
|
-
function placeCaretAtPoint(el, x, y) {
|
|
7583
|
-
const selection = window.getSelection();
|
|
7584
|
-
if (!selection) return;
|
|
7585
|
-
if (typeof document.caretRangeFromPoint === "function") {
|
|
7586
|
-
const range = document.caretRangeFromPoint(x, y);
|
|
7587
|
-
if (range && el.contains(range.startContainer)) {
|
|
7588
|
-
selection.removeAllRanges();
|
|
7589
|
-
selection.addRange(range);
|
|
7590
|
-
return;
|
|
7591
|
-
}
|
|
7592
|
-
}
|
|
7593
|
-
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
7594
|
-
if (typeof caretPositionFromPoint === "function") {
|
|
7595
|
-
const position = caretPositionFromPoint(x, y);
|
|
7596
|
-
if (position && el.contains(position.offsetNode)) {
|
|
7597
|
-
const range = document.createRange();
|
|
7598
|
-
range.setStart(position.offsetNode, position.offset);
|
|
7599
|
-
range.collapse(true);
|
|
7600
|
-
selection.removeAllRanges();
|
|
7601
|
-
selection.addRange(range);
|
|
7602
|
-
}
|
|
7603
|
-
}
|
|
7604
|
-
}
|
|
7605
|
-
function selectAllTextInEditable(el) {
|
|
7606
|
-
const selection = window.getSelection();
|
|
7607
|
-
if (!selection) return;
|
|
7608
|
-
const range = document.createRange();
|
|
7609
|
-
range.selectNodeContents(el);
|
|
7610
|
-
selection.removeAllRanges();
|
|
7611
|
-
selection.addRange(range);
|
|
7612
|
-
}
|
|
7613
|
-
function getNavigationLabelEditable(target) {
|
|
7614
|
-
const editable = target.closest('[data-ohw-editable="text"]');
|
|
7615
|
-
if (!editable) return null;
|
|
7616
|
-
const hrefCtx = getHrefKeyFromElement(editable);
|
|
7617
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7618
|
-
if (!navAnchor) return null;
|
|
7619
|
-
return { editable, navAnchor };
|
|
7620
|
-
}
|
|
7621
6158
|
function collectSections() {
|
|
7622
6159
|
return collectSectionsFromDom();
|
|
7623
6160
|
}
|
|
@@ -7741,8 +6278,6 @@ var ICONS = {
|
|
|
7741
6278
|
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"/>',
|
|
7742
6279
|
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"/>'
|
|
7743
6280
|
};
|
|
7744
|
-
var TOOLBAR_PILL_PADDING = 2;
|
|
7745
|
-
var TOOLBAR_TOGGLE_GAP = 4;
|
|
7746
6281
|
var TOOLBAR_GROUPS = [
|
|
7747
6282
|
[
|
|
7748
6283
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -7767,7 +6302,7 @@ function EditGlowChrome({
|
|
|
7767
6302
|
dragDisabled = false
|
|
7768
6303
|
}) {
|
|
7769
6304
|
const GAP = 6;
|
|
7770
|
-
return /* @__PURE__ */
|
|
6305
|
+
return /* @__PURE__ */ jsxs12(
|
|
7771
6306
|
"div",
|
|
7772
6307
|
{
|
|
7773
6308
|
ref: elRef,
|
|
@@ -7782,7 +6317,7 @@ function EditGlowChrome({
|
|
|
7782
6317
|
zIndex: 2147483646
|
|
7783
6318
|
},
|
|
7784
6319
|
children: [
|
|
7785
|
-
/* @__PURE__ */
|
|
6320
|
+
/* @__PURE__ */ jsx22(
|
|
7786
6321
|
"div",
|
|
7787
6322
|
{
|
|
7788
6323
|
style: {
|
|
@@ -7795,7 +6330,7 @@ function EditGlowChrome({
|
|
|
7795
6330
|
}
|
|
7796
6331
|
}
|
|
7797
6332
|
),
|
|
7798
|
-
reorderHrefKey && /* @__PURE__ */
|
|
6333
|
+
reorderHrefKey && /* @__PURE__ */ jsx22(
|
|
7799
6334
|
"div",
|
|
7800
6335
|
{
|
|
7801
6336
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7807,7 +6342,7 @@ function EditGlowChrome({
|
|
|
7807
6342
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7808
6343
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7809
6344
|
},
|
|
7810
|
-
children: /* @__PURE__ */
|
|
6345
|
+
children: /* @__PURE__ */ jsx22(
|
|
7811
6346
|
DragHandle,
|
|
7812
6347
|
{
|
|
7813
6348
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7911,7 +6446,7 @@ function FloatingToolbar({
|
|
|
7911
6446
|
onEditLink
|
|
7912
6447
|
}) {
|
|
7913
6448
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7914
|
-
return /* @__PURE__ */
|
|
6449
|
+
return /* @__PURE__ */ jsx22(
|
|
7915
6450
|
"div",
|
|
7916
6451
|
{
|
|
7917
6452
|
ref: elRef,
|
|
@@ -7921,23 +6456,14 @@ function FloatingToolbar({
|
|
|
7921
6456
|
left,
|
|
7922
6457
|
transform,
|
|
7923
6458
|
zIndex: 2147483647,
|
|
7924
|
-
background: "#fff",
|
|
7925
|
-
border: "1px solid #E7E5E4",
|
|
7926
|
-
borderRadius: 6,
|
|
7927
|
-
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
7928
|
-
display: "flex",
|
|
7929
|
-
alignItems: "center",
|
|
7930
|
-
padding: TOOLBAR_PILL_PADDING,
|
|
7931
|
-
gap: TOOLBAR_TOGGLE_GAP,
|
|
7932
|
-
fontFamily: "sans-serif",
|
|
7933
6459
|
pointerEvents: "auto"
|
|
7934
6460
|
},
|
|
7935
|
-
children: /* @__PURE__ */
|
|
7936
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
7937
|
-
gi > 0 && /* @__PURE__ */
|
|
6461
|
+
children: /* @__PURE__ */ jsxs12(CustomToolbar, { children: [
|
|
6462
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs12(React9.Fragment, { children: [
|
|
6463
|
+
gi > 0 && /* @__PURE__ */ jsx22(CustomToolbarDivider, {}),
|
|
7938
6464
|
btns.map((btn) => {
|
|
7939
6465
|
const isActive = activeCommands.has(btn.cmd);
|
|
7940
|
-
return /* @__PURE__ */
|
|
6466
|
+
return /* @__PURE__ */ jsx22(
|
|
7941
6467
|
CustomToolbarButton,
|
|
7942
6468
|
{
|
|
7943
6469
|
title: btn.title,
|
|
@@ -7946,7 +6472,7 @@ function FloatingToolbar({
|
|
|
7946
6472
|
e.preventDefault();
|
|
7947
6473
|
onCommand(btn.cmd);
|
|
7948
6474
|
},
|
|
7949
|
-
children: /* @__PURE__ */
|
|
6475
|
+
children: /* @__PURE__ */ jsx22(
|
|
7950
6476
|
"svg",
|
|
7951
6477
|
{
|
|
7952
6478
|
width: "16",
|
|
@@ -7967,7 +6493,7 @@ function FloatingToolbar({
|
|
|
7967
6493
|
);
|
|
7968
6494
|
})
|
|
7969
6495
|
] }, gi)),
|
|
7970
|
-
showEditLink ? /* @__PURE__ */
|
|
6496
|
+
showEditLink ? /* @__PURE__ */ jsx22(
|
|
7971
6497
|
CustomToolbarButton,
|
|
7972
6498
|
{
|
|
7973
6499
|
type: "button",
|
|
@@ -7981,7 +6507,7 @@ function FloatingToolbar({
|
|
|
7981
6507
|
e.preventDefault();
|
|
7982
6508
|
e.stopPropagation();
|
|
7983
6509
|
},
|
|
7984
|
-
children: /* @__PURE__ */
|
|
6510
|
+
children: /* @__PURE__ */ jsx22(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7985
6511
|
}
|
|
7986
6512
|
) : null
|
|
7987
6513
|
] })
|
|
@@ -7998,7 +6524,7 @@ function StateToggle({
|
|
|
7998
6524
|
states,
|
|
7999
6525
|
onStateChange
|
|
8000
6526
|
}) {
|
|
8001
|
-
return /* @__PURE__ */
|
|
6527
|
+
return /* @__PURE__ */ jsx22(
|
|
8002
6528
|
ToggleGroup,
|
|
8003
6529
|
{
|
|
8004
6530
|
"data-ohw-state-toggle": "",
|
|
@@ -8012,7 +6538,7 @@ function StateToggle({
|
|
|
8012
6538
|
left: rect.right - 8,
|
|
8013
6539
|
transform: "translateX(-100%)"
|
|
8014
6540
|
},
|
|
8015
|
-
children: states.map((state) => /* @__PURE__ */
|
|
6541
|
+
children: states.map((state) => /* @__PURE__ */ jsx22(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
8016
6542
|
}
|
|
8017
6543
|
);
|
|
8018
6544
|
}
|
|
@@ -8035,12 +6561,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
8035
6561
|
return "";
|
|
8036
6562
|
}
|
|
8037
6563
|
function OhhwellsBridge() {
|
|
8038
|
-
const pathname =
|
|
8039
|
-
const router =
|
|
6564
|
+
const pathname = usePathname();
|
|
6565
|
+
const router = useRouter();
|
|
8040
6566
|
const searchParams = useSearchParams();
|
|
8041
6567
|
const isEditMode = isEditSessionActive();
|
|
8042
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
8043
|
-
|
|
6568
|
+
const [bridgeRoot, setBridgeRoot] = useState5(null);
|
|
6569
|
+
useEffect4(() => {
|
|
8044
6570
|
const figtreeFontId = "ohw-figtree-font";
|
|
8045
6571
|
if (!document.getElementById(figtreeFontId)) {
|
|
8046
6572
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -8068,100 +6594,83 @@ function OhhwellsBridge() {
|
|
|
8068
6594
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
8069
6595
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
8070
6596
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
8071
|
-
const
|
|
6597
|
+
const postToParent = useCallback2((data) => {
|
|
8072
6598
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
8073
6599
|
window.parent.postMessage(data, "*");
|
|
8074
6600
|
}
|
|
8075
6601
|
}, []);
|
|
8076
|
-
const [fetchState, setFetchState] =
|
|
8077
|
-
const autoSaveTimers =
|
|
8078
|
-
const activeElRef =
|
|
8079
|
-
const selectedElRef =
|
|
8080
|
-
const originalContentRef =
|
|
8081
|
-
const activeStateElRef =
|
|
8082
|
-
const parentScrollRef =
|
|
8083
|
-
const visibleViewportRef =
|
|
8084
|
-
const [dialogPortalContainer, setDialogPortalContainer] =
|
|
8085
|
-
const attachVisibleViewport =
|
|
6602
|
+
const [fetchState, setFetchState] = useState5("idle");
|
|
6603
|
+
const autoSaveTimers = useRef4(/* @__PURE__ */ new Map());
|
|
6604
|
+
const activeElRef = useRef4(null);
|
|
6605
|
+
const selectedElRef = useRef4(null);
|
|
6606
|
+
const originalContentRef = useRef4(null);
|
|
6607
|
+
const activeStateElRef = useRef4(null);
|
|
6608
|
+
const parentScrollRef = useRef4(null);
|
|
6609
|
+
const visibleViewportRef = useRef4(null);
|
|
6610
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState5(null);
|
|
6611
|
+
const attachVisibleViewport = useCallback2((node) => {
|
|
8086
6612
|
visibleViewportRef.current = node;
|
|
8087
6613
|
setDialogPortalContainer(node);
|
|
8088
6614
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
8089
6615
|
}, []);
|
|
8090
|
-
const toolbarElRef =
|
|
8091
|
-
const glowElRef =
|
|
8092
|
-
const hoveredImageRef =
|
|
8093
|
-
const hoveredImageHasTextOverlapRef =
|
|
8094
|
-
const dragOverElRef =
|
|
8095
|
-
const [mediaHover, setMediaHover] =
|
|
8096
|
-
const [
|
|
8097
|
-
const
|
|
8098
|
-
const
|
|
8099
|
-
const
|
|
8100
|
-
const
|
|
8101
|
-
const
|
|
8102
|
-
const activateRef = useRef5(() => {
|
|
6616
|
+
const toolbarElRef = useRef4(null);
|
|
6617
|
+
const glowElRef = useRef4(null);
|
|
6618
|
+
const hoveredImageRef = useRef4(null);
|
|
6619
|
+
const hoveredImageHasTextOverlapRef = useRef4(false);
|
|
6620
|
+
const dragOverElRef = useRef4(null);
|
|
6621
|
+
const [mediaHover, setMediaHover] = useState5(null);
|
|
6622
|
+
const [uploadingRects, setUploadingRects] = useState5({});
|
|
6623
|
+
const hoveredGapRef = useRef4(null);
|
|
6624
|
+
const imageUnhoverTimerRef = useRef4(null);
|
|
6625
|
+
const imageShowTimerRef = useRef4(null);
|
|
6626
|
+
const editStylesRef = useRef4(null);
|
|
6627
|
+
const activateRef = useRef4(() => {
|
|
8103
6628
|
});
|
|
8104
|
-
const deactivateRef =
|
|
6629
|
+
const deactivateRef = useRef4(() => {
|
|
8105
6630
|
});
|
|
8106
|
-
const selectRef =
|
|
6631
|
+
const selectRef = useRef4(() => {
|
|
8107
6632
|
});
|
|
8108
|
-
const
|
|
6633
|
+
const deselectRef = useRef4(() => {
|
|
8109
6634
|
});
|
|
8110
|
-
const
|
|
6635
|
+
const reselectNavigationItemRef = useRef4(() => {
|
|
8111
6636
|
});
|
|
8112
|
-
const
|
|
6637
|
+
const commitNavigationTextEditRef = useRef4(() => {
|
|
8113
6638
|
});
|
|
8114
|
-
const
|
|
6639
|
+
const refreshActiveCommandsRef = useRef4(() => {
|
|
8115
6640
|
});
|
|
8116
|
-
const
|
|
8117
|
-
|
|
8118
|
-
const
|
|
8119
|
-
|
|
8120
|
-
const
|
|
8121
|
-
const
|
|
8122
|
-
const
|
|
8123
|
-
const [toolbarVariant, setToolbarVariant] = useState7("none");
|
|
8124
|
-
const toolbarVariantRef = useRef5("none");
|
|
6641
|
+
const postToParentRef = useRef4(postToParent);
|
|
6642
|
+
postToParentRef.current = postToParent;
|
|
6643
|
+
const sectionsLoadedRef = useRef4(false);
|
|
6644
|
+
const pendingScheduleConfigRequests = useRef4([]);
|
|
6645
|
+
const [toolbarRect, setToolbarRect] = useState5(null);
|
|
6646
|
+
const [toolbarVariant, setToolbarVariant] = useState5("none");
|
|
6647
|
+
const toolbarVariantRef = useRef4("none");
|
|
8125
6648
|
toolbarVariantRef.current = toolbarVariant;
|
|
8126
|
-
const [reorderHrefKey, setReorderHrefKey] =
|
|
8127
|
-
const [reorderDragDisabled, setReorderDragDisabled] =
|
|
8128
|
-
const [toggleState, setToggleState] =
|
|
8129
|
-
const [maxBadge, setMaxBadge] =
|
|
8130
|
-
const [activeCommands, setActiveCommands] =
|
|
8131
|
-
const [sectionGap, setSectionGap] =
|
|
8132
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] =
|
|
8133
|
-
const
|
|
8134
|
-
const [
|
|
8135
|
-
const
|
|
8136
|
-
const [
|
|
8137
|
-
const
|
|
8138
|
-
const [
|
|
8139
|
-
const [
|
|
8140
|
-
const [
|
|
8141
|
-
const
|
|
8142
|
-
const
|
|
8143
|
-
const
|
|
8144
|
-
const
|
|
8145
|
-
const
|
|
8146
|
-
const footerPointerDragRef = useRef5(null);
|
|
8147
|
-
const suppressNextClickRef = useRef5(false);
|
|
8148
|
-
const [linkPopover, setLinkPopover] = useState7(null);
|
|
8149
|
-
const linkPopoverSessionRef = useRef5(null);
|
|
8150
|
-
const addNavAfterAnchorRef = useRef5(null);
|
|
8151
|
-
const editContentRef = useRef5({});
|
|
8152
|
-
const [sitePages, setSitePages] = useState7([]);
|
|
8153
|
-
const [sectionsByPath, setSectionsByPath] = useState7({});
|
|
8154
|
-
const sectionsPrefetchGenRef = useRef5(0);
|
|
8155
|
-
const setLinkPopoverRef = useRef5(setLinkPopover);
|
|
8156
|
-
const linkPopoverPanelRef = useRef5(null);
|
|
8157
|
-
const linkPopoverOpenRef = useRef5(false);
|
|
8158
|
-
const linkPopoverGraceUntilRef = useRef5(0);
|
|
6649
|
+
const [reorderHrefKey, setReorderHrefKey] = useState5(null);
|
|
6650
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState5(false);
|
|
6651
|
+
const [toggleState, setToggleState] = useState5(null);
|
|
6652
|
+
const [maxBadge, setMaxBadge] = useState5(null);
|
|
6653
|
+
const [activeCommands, setActiveCommands] = useState5(/* @__PURE__ */ new Set());
|
|
6654
|
+
const [sectionGap, setSectionGap] = useState5(null);
|
|
6655
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState5(false);
|
|
6656
|
+
const hoveredItemElRef = useRef4(null);
|
|
6657
|
+
const [hoveredItemRect, setHoveredItemRect] = useState5(null);
|
|
6658
|
+
const siblingHintElRef = useRef4(null);
|
|
6659
|
+
const [siblingHintRect, setSiblingHintRect] = useState5(null);
|
|
6660
|
+
const [isItemDragging, setIsItemDragging] = useState5(false);
|
|
6661
|
+
const [linkPopover, setLinkPopover] = useState5(null);
|
|
6662
|
+
const [sitePages, setSitePages] = useState5([]);
|
|
6663
|
+
const [sectionsByPath, setSectionsByPath] = useState5({});
|
|
6664
|
+
const sectionsPrefetchGenRef = useRef4(0);
|
|
6665
|
+
const setLinkPopoverRef = useRef4(setLinkPopover);
|
|
6666
|
+
const linkPopoverPanelRef = useRef4(null);
|
|
6667
|
+
const linkPopoverOpenRef = useRef4(false);
|
|
6668
|
+
const linkPopoverGraceUntilRef = useRef4(0);
|
|
8159
6669
|
setLinkPopoverRef.current = setLinkPopover;
|
|
8160
|
-
linkPopoverSessionRef.current = linkPopover;
|
|
8161
6670
|
const bumpLinkPopoverGrace = () => {
|
|
8162
6671
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
8163
6672
|
};
|
|
8164
|
-
const runSectionsPrefetch =
|
|
6673
|
+
const runSectionsPrefetch = useCallback2((pages) => {
|
|
8165
6674
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
8166
6675
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
8167
6676
|
const paths = pages.map((p) => p.path);
|
|
@@ -8180,9 +6689,9 @@ function OhhwellsBridge() {
|
|
|
8180
6689
|
);
|
|
8181
6690
|
});
|
|
8182
6691
|
}, [isEditMode, pathname]);
|
|
8183
|
-
const runSectionsPrefetchRef =
|
|
6692
|
+
const runSectionsPrefetchRef = useRef4(runSectionsPrefetch);
|
|
8184
6693
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
8185
|
-
|
|
6694
|
+
useEffect4(() => {
|
|
8186
6695
|
if (!linkPopover) return;
|
|
8187
6696
|
if (hoveredImageRef.current) {
|
|
8188
6697
|
hoveredImageRef.current = null;
|
|
@@ -8190,9 +6699,33 @@ function OhhwellsBridge() {
|
|
|
8190
6699
|
}
|
|
8191
6700
|
hoveredGapRef.current = null;
|
|
8192
6701
|
setSectionGap(null);
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
6702
|
+
setMediaHover(null);
|
|
6703
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6704
|
+
const html = document.documentElement;
|
|
6705
|
+
const body = document.body;
|
|
6706
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6707
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6708
|
+
html.style.overflow = "hidden";
|
|
6709
|
+
body.style.overflow = "hidden";
|
|
6710
|
+
const preventBackgroundScroll = (e) => {
|
|
6711
|
+
const target = e.target;
|
|
6712
|
+
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6713
|
+
return;
|
|
6714
|
+
}
|
|
6715
|
+
e.preventDefault();
|
|
6716
|
+
};
|
|
6717
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6718
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6719
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6720
|
+
return () => {
|
|
6721
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6722
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6723
|
+
body.style.overflow = prevBodyOverflow;
|
|
6724
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6725
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6726
|
+
};
|
|
6727
|
+
}, [linkPopover, postToParent]);
|
|
6728
|
+
useEffect4(() => {
|
|
8196
6729
|
if (!isEditMode) return;
|
|
8197
6730
|
const useFixtures = shouldUseDevFixtures();
|
|
8198
6731
|
if (useFixtures) {
|
|
@@ -8213,17 +6746,17 @@ function OhhwellsBridge() {
|
|
|
8213
6746
|
runSectionsPrefetchRef.current(mapped);
|
|
8214
6747
|
};
|
|
8215
6748
|
window.addEventListener("message", onSitePages);
|
|
8216
|
-
if (!useFixtures)
|
|
6749
|
+
if (!useFixtures) postToParent({ type: "ow:request-site-pages" });
|
|
8217
6750
|
return () => window.removeEventListener("message", onSitePages);
|
|
8218
|
-
}, [isEditMode,
|
|
8219
|
-
|
|
6751
|
+
}, [isEditMode, postToParent]);
|
|
6752
|
+
useEffect4(() => {
|
|
8220
6753
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
8221
6754
|
void loadAllSectionsManifest().then((manifest) => {
|
|
8222
6755
|
if (Object.keys(manifest).length === 0) return;
|
|
8223
6756
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
8224
6757
|
});
|
|
8225
6758
|
}, [isEditMode]);
|
|
8226
|
-
|
|
6759
|
+
useEffect4(() => {
|
|
8227
6760
|
const update = () => {
|
|
8228
6761
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
8229
6762
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -8247,10 +6780,10 @@ function OhhwellsBridge() {
|
|
|
8247
6780
|
vvp.removeEventListener("resize", update);
|
|
8248
6781
|
};
|
|
8249
6782
|
}, []);
|
|
8250
|
-
const refreshStateRules =
|
|
6783
|
+
const refreshStateRules = useCallback2(() => {
|
|
8251
6784
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
8252
6785
|
}, []);
|
|
8253
|
-
const processConfigRequest =
|
|
6786
|
+
const processConfigRequest = useCallback2((insertAfterVal) => {
|
|
8254
6787
|
const tracker = getSectionsTracker();
|
|
8255
6788
|
let entries = [];
|
|
8256
6789
|
try {
|
|
@@ -8273,7 +6806,7 @@ function OhhwellsBridge() {
|
|
|
8273
6806
|
}
|
|
8274
6807
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
8275
6808
|
}, [isEditMode]);
|
|
8276
|
-
const deactivate =
|
|
6809
|
+
const deactivate = useCallback2(() => {
|
|
8277
6810
|
const el = activeElRef.current;
|
|
8278
6811
|
if (!el) return;
|
|
8279
6812
|
const key = el.dataset.ohwKey;
|
|
@@ -8302,25 +6835,21 @@ function OhhwellsBridge() {
|
|
|
8302
6835
|
setMaxBadge(null);
|
|
8303
6836
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8304
6837
|
setToolbarShowEditLink(false);
|
|
8305
|
-
|
|
8306
|
-
}, [
|
|
8307
|
-
const deselect =
|
|
6838
|
+
postToParent({ type: "ow:exit-edit" });
|
|
6839
|
+
}, [postToParent]);
|
|
6840
|
+
const deselect = useCallback2(() => {
|
|
8308
6841
|
selectedElRef.current = null;
|
|
8309
6842
|
setReorderHrefKey(null);
|
|
8310
6843
|
setReorderDragDisabled(false);
|
|
8311
|
-
setIsFooterFrameSelection(false);
|
|
8312
6844
|
siblingHintElRef.current = null;
|
|
8313
6845
|
setSiblingHintRect(null);
|
|
8314
|
-
setSiblingHintRects([]);
|
|
8315
6846
|
setIsItemDragging(false);
|
|
8316
|
-
hoveredNavContainerRef.current = null;
|
|
8317
|
-
setHoveredNavContainerRect(null);
|
|
8318
6847
|
if (!activeElRef.current) {
|
|
8319
6848
|
setToolbarRect(null);
|
|
8320
6849
|
setToolbarVariant("none");
|
|
8321
6850
|
}
|
|
8322
6851
|
}, []);
|
|
8323
|
-
const reselectNavigationItem =
|
|
6852
|
+
const reselectNavigationItem = useCallback2((navAnchor) => {
|
|
8324
6853
|
selectedElRef.current = navAnchor;
|
|
8325
6854
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
8326
6855
|
setReorderHrefKey(key);
|
|
@@ -8330,7 +6859,7 @@ function OhhwellsBridge() {
|
|
|
8330
6859
|
setToolbarShowEditLink(false);
|
|
8331
6860
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8332
6861
|
}, []);
|
|
8333
|
-
const commitNavigationTextEdit =
|
|
6862
|
+
const commitNavigationTextEdit = useCallback2((navAnchor) => {
|
|
8334
6863
|
const el = activeElRef.current;
|
|
8335
6864
|
if (!el) return;
|
|
8336
6865
|
const key = el.dataset.ohwKey;
|
|
@@ -8343,9 +6872,9 @@ function OhhwellsBridge() {
|
|
|
8343
6872
|
const html = sanitizeHtml(el.innerHTML);
|
|
8344
6873
|
const original = originalContentRef.current ?? "";
|
|
8345
6874
|
if (html !== sanitizeHtml(original)) {
|
|
8346
|
-
|
|
6875
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
8347
6876
|
const h = document.documentElement.scrollHeight;
|
|
8348
|
-
if (h > 50)
|
|
6877
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8349
6878
|
}
|
|
8350
6879
|
}
|
|
8351
6880
|
el.removeAttribute("contenteditable");
|
|
@@ -8353,364 +6882,79 @@ function OhhwellsBridge() {
|
|
|
8353
6882
|
setMaxBadge(null);
|
|
8354
6883
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8355
6884
|
setToolbarShowEditLink(false);
|
|
8356
|
-
|
|
6885
|
+
postToParent({ type: "ow:exit-edit" });
|
|
8357
6886
|
reselectNavigationItem(navAnchor);
|
|
8358
|
-
}, [
|
|
8359
|
-
const
|
|
8360
|
-
const items = listNavbarItems();
|
|
8361
|
-
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
8362
|
-
deselectRef.current();
|
|
8363
|
-
deactivateRef.current();
|
|
8364
|
-
bumpLinkPopoverGrace();
|
|
8365
|
-
setLinkPopover({
|
|
8366
|
-
key: "__add-nav__",
|
|
8367
|
-
mode: "create",
|
|
8368
|
-
intent: "add-nav"
|
|
8369
|
-
});
|
|
8370
|
-
}, []);
|
|
8371
|
-
const clearFooterDragVisuals = useCallback4(() => {
|
|
8372
|
-
footerDragRef.current = null;
|
|
8373
|
-
setSiblingHintRects([]);
|
|
8374
|
-
setFooterDropSlots([]);
|
|
8375
|
-
setActiveFooterDropIndex(null);
|
|
8376
|
-
setDraggedItemRect(null);
|
|
8377
|
-
setIsItemDragging(false);
|
|
8378
|
-
unlockFooterDragInteraction();
|
|
8379
|
-
}, []);
|
|
8380
|
-
const refreshFooterDragVisuals = useCallback4((session, activeSlot, clientX, clientY) => {
|
|
8381
|
-
const dragged = session.draggedEl;
|
|
8382
|
-
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
8383
|
-
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
8384
|
-
session.lastClientX = clientX;
|
|
8385
|
-
session.lastClientY = clientY;
|
|
8386
|
-
}
|
|
8387
|
-
session.activeSlot = activeSlot;
|
|
8388
|
-
if (session.kind === "link") {
|
|
8389
|
-
const columns2 = listFooterColumns();
|
|
8390
|
-
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
8391
|
-
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
8392
|
-
const siblingRects = [];
|
|
8393
|
-
columns2.forEach((col, i) => {
|
|
8394
|
-
if (!focusCols.has(i)) return;
|
|
8395
|
-
for (const link of listFooterLinksInColumn(col)) {
|
|
8396
|
-
if (link === dragged) continue;
|
|
8397
|
-
siblingRects.push(link.getBoundingClientRect());
|
|
8398
|
-
}
|
|
8399
|
-
});
|
|
8400
|
-
setSiblingHintRects(siblingRects);
|
|
8401
|
-
const slots2 = [];
|
|
8402
|
-
columns2.forEach((col, i) => {
|
|
8403
|
-
slots2.push(...buildLinkDropSlots(col, i));
|
|
8404
|
-
});
|
|
8405
|
-
setFooterDropSlots(slots2);
|
|
8406
|
-
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8407
|
-
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
8408
|
-
return;
|
|
8409
|
-
}
|
|
8410
|
-
const columns = listFooterColumns();
|
|
8411
|
-
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
8412
|
-
const slots = buildColumnDropSlots();
|
|
8413
|
-
setFooterDropSlots(slots);
|
|
8414
|
-
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8415
|
-
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
8416
|
-
}, []);
|
|
8417
|
-
const refreshFooterDragVisualsRef = useRef5(refreshFooterDragVisuals);
|
|
8418
|
-
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
8419
|
-
const commitFooterDragRef = useRef5(() => {
|
|
8420
|
-
});
|
|
8421
|
-
const beginFooterDragRef = useRef5(() => {
|
|
8422
|
-
});
|
|
8423
|
-
const beginFooterDrag = useCallback4(
|
|
8424
|
-
(session) => {
|
|
8425
|
-
const rect = session.draggedEl.getBoundingClientRect();
|
|
8426
|
-
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
8427
|
-
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
8428
|
-
session.activeSlot = session.activeSlot ?? null;
|
|
8429
|
-
footerDragRef.current = session;
|
|
8430
|
-
setIsItemDragging(true);
|
|
8431
|
-
lockFooterDuringDrag();
|
|
8432
|
-
siblingHintElRef.current = null;
|
|
8433
|
-
setSiblingHintRect(null);
|
|
8434
|
-
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
8435
|
-
setToolbarRect(rect);
|
|
8436
|
-
}
|
|
8437
|
-
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
8438
|
-
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
8439
|
-
},
|
|
8440
|
-
[refreshFooterDragVisuals]
|
|
8441
|
-
);
|
|
8442
|
-
beginFooterDragRef.current = beginFooterDrag;
|
|
8443
|
-
const commitFooterDrag = useCallback4(
|
|
8444
|
-
(clientX, clientY) => {
|
|
8445
|
-
const session = footerDragRef.current;
|
|
8446
|
-
if (!session) {
|
|
8447
|
-
clearFooterDragVisuals();
|
|
8448
|
-
return;
|
|
8449
|
-
}
|
|
8450
|
-
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
8451
|
-
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
8452
|
-
let nextOrder = null;
|
|
8453
|
-
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
8454
|
-
if (session.kind === "link" && session.hrefKey && slot) {
|
|
8455
|
-
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
8456
|
-
} else if (session.kind === "column" && slot) {
|
|
8457
|
-
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
8458
|
-
}
|
|
8459
|
-
const wasSelected = session.wasSelected;
|
|
8460
|
-
const draggedEl = session.draggedEl;
|
|
8461
|
-
const hrefKey = session.hrefKey;
|
|
8462
|
-
let movedColumnIndex = null;
|
|
8463
|
-
if (session.kind === "column" && slot && nextOrder) {
|
|
8464
|
-
let adjusted = slot.insertIndex;
|
|
8465
|
-
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
8466
|
-
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
8467
|
-
}
|
|
8468
|
-
clearFooterDragVisuals();
|
|
8469
|
-
if (nextOrder) {
|
|
8470
|
-
const orderJson = JSON.stringify(nextOrder);
|
|
8471
|
-
editContentRef.current = {
|
|
8472
|
-
...editContentRef.current,
|
|
8473
|
-
[FOOTER_ORDER_KEY]: orderJson
|
|
8474
|
-
};
|
|
8475
|
-
applyFooterOrder(nextOrder);
|
|
8476
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8477
|
-
requestAnimationFrame(() => {
|
|
8478
|
-
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
8479
|
-
applyFooterOrder(nextOrder);
|
|
8480
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8481
|
-
}
|
|
8482
|
-
});
|
|
8483
|
-
postToParentRef.current({
|
|
8484
|
-
type: "ow:change",
|
|
8485
|
-
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
8486
|
-
});
|
|
8487
|
-
}
|
|
8488
|
-
const still = (hrefKey ? document.querySelector(`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`) : null) ?? (movedColumnIndex !== null ? listFooterColumns()[movedColumnIndex] ?? null : null) ?? (document.body.contains(draggedEl) ? draggedEl : null);
|
|
8489
|
-
if (still && isNavigationItem(still)) {
|
|
8490
|
-
selectRef.current(still);
|
|
8491
|
-
} else if (still && isNavigationContainer(still)) {
|
|
8492
|
-
selectFrameRef.current(still);
|
|
8493
|
-
} else if (wasSelected) {
|
|
8494
|
-
deselectRef.current();
|
|
8495
|
-
}
|
|
8496
|
-
},
|
|
8497
|
-
[clearFooterDragVisuals]
|
|
8498
|
-
);
|
|
8499
|
-
commitFooterDragRef.current = commitFooterDrag;
|
|
8500
|
-
const startFooterLinkDrag = useCallback4(
|
|
8501
|
-
(anchor, clientX, clientY, wasSelected) => {
|
|
8502
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
8503
|
-
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
8504
|
-
const column = findFooterColumnForLink(anchor);
|
|
8505
|
-
const columns = listFooterColumns();
|
|
8506
|
-
beginFooterDrag({
|
|
8507
|
-
kind: "link",
|
|
8508
|
-
hrefKey,
|
|
8509
|
-
columnEl: column,
|
|
8510
|
-
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
8511
|
-
wasSelected,
|
|
8512
|
-
draggedEl: anchor,
|
|
8513
|
-
lastClientX: clientX,
|
|
8514
|
-
lastClientY: clientY,
|
|
8515
|
-
activeSlot: null
|
|
8516
|
-
});
|
|
8517
|
-
return true;
|
|
8518
|
-
},
|
|
8519
|
-
[beginFooterDrag]
|
|
8520
|
-
);
|
|
8521
|
-
const startFooterColumnDrag = useCallback4(
|
|
8522
|
-
(columnEl, clientX, clientY, wasSelected) => {
|
|
8523
|
-
const columns = listFooterColumns();
|
|
8524
|
-
const idx = columns.indexOf(columnEl);
|
|
8525
|
-
if (idx < 0) return false;
|
|
8526
|
-
beginFooterDrag({
|
|
8527
|
-
kind: "column",
|
|
8528
|
-
hrefKey: null,
|
|
8529
|
-
columnEl,
|
|
8530
|
-
sourceColumnIndex: idx,
|
|
8531
|
-
wasSelected,
|
|
8532
|
-
draggedEl: columnEl,
|
|
8533
|
-
lastClientX: clientX,
|
|
8534
|
-
lastClientY: clientY,
|
|
8535
|
-
activeSlot: null
|
|
8536
|
-
});
|
|
8537
|
-
return true;
|
|
8538
|
-
},
|
|
8539
|
-
[beginFooterDrag]
|
|
8540
|
-
);
|
|
8541
|
-
const handleItemDragStart = useCallback4(
|
|
8542
|
-
(e) => {
|
|
8543
|
-
const selected = selectedElRef.current;
|
|
8544
|
-
if (!selected) {
|
|
8545
|
-
setIsItemDragging(true);
|
|
8546
|
-
return;
|
|
8547
|
-
}
|
|
8548
|
-
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
8549
|
-
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
8550
|
-
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
8551
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8552
|
-
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
8553
|
-
}
|
|
8554
|
-
siblingHintElRef.current = null;
|
|
8555
|
-
setSiblingHintRect(null);
|
|
8556
|
-
setIsItemDragging(true);
|
|
8557
|
-
},
|
|
8558
|
-
[startFooterColumnDrag, startFooterLinkDrag]
|
|
8559
|
-
);
|
|
8560
|
-
const handleItemDragEnd = useCallback4(
|
|
8561
|
-
(e) => {
|
|
8562
|
-
if (footerDragRef.current) {
|
|
8563
|
-
const x = e?.clientX;
|
|
8564
|
-
const y = e?.clientY;
|
|
8565
|
-
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
8566
|
-
commitFooterDrag(x, y);
|
|
8567
|
-
} else {
|
|
8568
|
-
commitFooterDrag();
|
|
8569
|
-
}
|
|
8570
|
-
return;
|
|
8571
|
-
}
|
|
8572
|
-
setIsItemDragging(false);
|
|
8573
|
-
},
|
|
8574
|
-
[commitFooterDrag]
|
|
8575
|
-
);
|
|
8576
|
-
const handleItemChromePointerDown = useCallback4((e) => {
|
|
8577
|
-
if (e.button !== 0) return;
|
|
6887
|
+
}, [postToParent, reselectNavigationItem]);
|
|
6888
|
+
const handleAddNavigationItem = useCallback2(() => {
|
|
8578
6889
|
const selected = selectedElRef.current;
|
|
8579
6890
|
if (!selected) return;
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
footerPointerDragRef.current = {
|
|
8584
|
-
el: selected,
|
|
8585
|
-
kind: "link",
|
|
8586
|
-
startX: e.clientX,
|
|
8587
|
-
startY: e.clientY,
|
|
8588
|
-
pointerId: e.pointerId,
|
|
8589
|
-
wasSelected: true,
|
|
8590
|
-
started: false
|
|
8591
|
-
};
|
|
8592
|
-
return;
|
|
8593
|
-
}
|
|
8594
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8595
|
-
footerPointerDragRef.current = {
|
|
8596
|
-
el: selected,
|
|
8597
|
-
kind: "column",
|
|
8598
|
-
startX: e.clientX,
|
|
8599
|
-
startY: e.clientY,
|
|
8600
|
-
pointerId: e.pointerId,
|
|
8601
|
-
wasSelected: true,
|
|
8602
|
-
started: false
|
|
8603
|
-
};
|
|
8604
|
-
}
|
|
6891
|
+
const target = getNavigationItemAddHintTarget(selected);
|
|
6892
|
+
siblingHintElRef.current = target;
|
|
6893
|
+
setSiblingHintRect(target.getBoundingClientRect());
|
|
8605
6894
|
}, []);
|
|
8606
|
-
const
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
8614
|
-
if (!editable) return;
|
|
8615
|
-
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
6895
|
+
const handleItemDragStart = useCallback2(() => {
|
|
6896
|
+
siblingHintElRef.current = null;
|
|
6897
|
+
setSiblingHintRect(null);
|
|
6898
|
+
setIsItemDragging(true);
|
|
6899
|
+
}, []);
|
|
6900
|
+
const handleItemDragEnd = useCallback2(() => {
|
|
6901
|
+
setIsItemDragging(false);
|
|
8616
6902
|
}, []);
|
|
8617
6903
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
8618
6904
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
8619
|
-
const select =
|
|
8620
|
-
(anchor)
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
(
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
8659
|
-
);
|
|
8660
|
-
setIsItemDragging(false);
|
|
6905
|
+
const select = useCallback2((anchor) => {
|
|
6906
|
+
if (!isNavigationItem(anchor)) return;
|
|
6907
|
+
if (activeElRef.current) deactivate();
|
|
6908
|
+
selectedElRef.current = anchor;
|
|
6909
|
+
clearHrefKeyHover(anchor);
|
|
6910
|
+
setHoveredItemRect(null);
|
|
6911
|
+
hoveredItemElRef.current = null;
|
|
6912
|
+
siblingHintElRef.current = null;
|
|
6913
|
+
setSiblingHintRect(null);
|
|
6914
|
+
setIsItemDragging(false);
|
|
6915
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
6916
|
+
setReorderHrefKey(key);
|
|
6917
|
+
setReorderDragDisabled(disabled);
|
|
6918
|
+
setToolbarVariant("link-action");
|
|
6919
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
6920
|
+
setToolbarShowEditLink(false);
|
|
6921
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6922
|
+
}, [deactivate]);
|
|
6923
|
+
const activate = useCallback2((el) => {
|
|
6924
|
+
if (activeElRef.current === el) return;
|
|
6925
|
+
selectedElRef.current = null;
|
|
6926
|
+
deactivate();
|
|
6927
|
+
if (hoveredImageRef.current) {
|
|
6928
|
+
hoveredImageRef.current = null;
|
|
6929
|
+
setMediaHover(null);
|
|
6930
|
+
}
|
|
6931
|
+
setToolbarVariant("rich-text");
|
|
6932
|
+
siblingHintElRef.current = null;
|
|
6933
|
+
setSiblingHintRect(null);
|
|
6934
|
+
setIsItemDragging(false);
|
|
6935
|
+
el.setAttribute("contenteditable", "true");
|
|
6936
|
+
el.removeAttribute("data-ohw-hovered");
|
|
6937
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
6938
|
+
activeElRef.current = el;
|
|
6939
|
+
originalContentRef.current = el.innerHTML;
|
|
6940
|
+
el.focus();
|
|
6941
|
+
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
6942
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
6943
|
+
if (navAnchor) {
|
|
8661
6944
|
setReorderHrefKey(null);
|
|
8662
6945
|
setReorderDragDisabled(false);
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
(el, options) => {
|
|
8673
|
-
if (activeElRef.current === el) return;
|
|
8674
|
-
selectedElRef.current = null;
|
|
8675
|
-
deactivate();
|
|
8676
|
-
if (hoveredImageRef.current) {
|
|
8677
|
-
hoveredImageRef.current = null;
|
|
8678
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8679
|
-
}
|
|
8680
|
-
setToolbarVariant("rich-text");
|
|
8681
|
-
siblingHintElRef.current = null;
|
|
8682
|
-
setSiblingHintRect(null);
|
|
8683
|
-
setSiblingHintRects([]);
|
|
8684
|
-
setIsItemDragging(false);
|
|
8685
|
-
el.setAttribute("contenteditable", "true");
|
|
8686
|
-
el.removeAttribute("data-ohw-hovered");
|
|
8687
|
-
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
8688
|
-
activeElRef.current = el;
|
|
8689
|
-
originalContentRef.current = el.innerHTML;
|
|
8690
|
-
el.focus();
|
|
8691
|
-
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8692
|
-
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
8693
|
-
}
|
|
8694
|
-
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
8695
|
-
const navAnchor = getNavigationItemAnchor(el);
|
|
8696
|
-
if (navAnchor) {
|
|
8697
|
-
setReorderHrefKey(null);
|
|
8698
|
-
setReorderDragDisabled(false);
|
|
8699
|
-
} else {
|
|
8700
|
-
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
8701
|
-
setReorderHrefKey(reorderKey);
|
|
8702
|
-
setReorderDragDisabled(reorderDisabled);
|
|
8703
|
-
}
|
|
8704
|
-
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
8705
|
-
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
8706
|
-
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
8707
|
-
},
|
|
8708
|
-
[deactivate, postToParent2]
|
|
8709
|
-
);
|
|
6946
|
+
} else {
|
|
6947
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
6948
|
+
setReorderHrefKey(reorderKey);
|
|
6949
|
+
setReorderDragDisabled(reorderDisabled);
|
|
6950
|
+
}
|
|
6951
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6952
|
+
postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6953
|
+
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6954
|
+
}, [deactivate, postToParent]);
|
|
8710
6955
|
activateRef.current = activate;
|
|
8711
6956
|
deactivateRef.current = deactivate;
|
|
8712
6957
|
selectRef.current = select;
|
|
8713
|
-
selectFrameRef.current = selectFrame;
|
|
8714
6958
|
deselectRef.current = deselect;
|
|
8715
6959
|
useLayoutEffect2(() => {
|
|
8716
6960
|
if (!subdomain || isEditMode) {
|
|
@@ -8722,7 +6966,6 @@ function OhhwellsBridge() {
|
|
|
8722
6966
|
for (const [key, val] of Object.entries(content)) {
|
|
8723
6967
|
if (key === "__ohw_sections") continue;
|
|
8724
6968
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8725
|
-
if (applyCarouselNode(key, val)) continue;
|
|
8726
6969
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8727
6970
|
if (el.dataset.ohwEditable === "image") {
|
|
8728
6971
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8753,8 +6996,6 @@ function OhhwellsBridge() {
|
|
|
8753
6996
|
});
|
|
8754
6997
|
applyLinkByKey(key, val);
|
|
8755
6998
|
}
|
|
8756
|
-
reconcileNavbarItemsFromContent(content);
|
|
8757
|
-
reconcileFooterOrderFromContent(content);
|
|
8758
6999
|
enforceLinkHrefs();
|
|
8759
7000
|
initSectionsFromContent(content, true);
|
|
8760
7001
|
sectionsLoadedRef.current = true;
|
|
@@ -8783,7 +7024,7 @@ function OhhwellsBridge() {
|
|
|
8783
7024
|
cancelled = true;
|
|
8784
7025
|
};
|
|
8785
7026
|
}, [subdomain, isEditMode]);
|
|
8786
|
-
|
|
7027
|
+
useEffect4(() => {
|
|
8787
7028
|
if (!subdomain || isEditMode) return;
|
|
8788
7029
|
let debounceTimer = null;
|
|
8789
7030
|
let observer = null;
|
|
@@ -8796,7 +7037,6 @@ function OhhwellsBridge() {
|
|
|
8796
7037
|
for (const [key, val] of Object.entries(content)) {
|
|
8797
7038
|
if (key === "__ohw_sections") continue;
|
|
8798
7039
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8799
|
-
if (applyCarouselNode(key, val)) continue;
|
|
8800
7040
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8801
7041
|
if (el.dataset.ohwEditable === "image") {
|
|
8802
7042
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8815,8 +7055,6 @@ function OhhwellsBridge() {
|
|
|
8815
7055
|
});
|
|
8816
7056
|
applyLinkByKey(key, val);
|
|
8817
7057
|
}
|
|
8818
|
-
reconcileNavbarItemsFromContent(content);
|
|
8819
|
-
reconcileFooterOrderFromContent(content);
|
|
8820
7058
|
} finally {
|
|
8821
7059
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8822
7060
|
}
|
|
@@ -8840,65 +7078,20 @@ function OhhwellsBridge() {
|
|
|
8840
7078
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
8841
7079
|
el.style.display = visible ? "flex" : "none";
|
|
8842
7080
|
}, [subdomain, fetchState]);
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
}, [pathname,
|
|
8846
|
-
|
|
7081
|
+
useEffect4(() => {
|
|
7082
|
+
postToParent({ type: "ow:navigation", path: pathname });
|
|
7083
|
+
}, [pathname, postToParent]);
|
|
7084
|
+
useEffect4(() => {
|
|
8847
7085
|
if (!isEditMode) return;
|
|
8848
|
-
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8849
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
8850
7086
|
setLinkPopover(null);
|
|
8851
7087
|
deselectRef.current();
|
|
8852
7088
|
deactivateRef.current();
|
|
8853
7089
|
}, [pathname, isEditMode]);
|
|
8854
|
-
|
|
8855
|
-
const contentForNav = () => {
|
|
8856
|
-
if (isEditMode) return editContentRef.current;
|
|
8857
|
-
if (!subdomain) return {};
|
|
8858
|
-
return contentCache.get(subdomain) ?? {};
|
|
8859
|
-
};
|
|
8860
|
-
let applying = false;
|
|
8861
|
-
let rafId = null;
|
|
8862
|
-
const run = () => {
|
|
8863
|
-
if (footerDragRef.current || applying) return;
|
|
8864
|
-
applying = true;
|
|
8865
|
-
try {
|
|
8866
|
-
const content = contentForNav();
|
|
8867
|
-
reconcileNavbarItemsFromContent(content);
|
|
8868
|
-
reconcileFooterOrderFromContent(content);
|
|
8869
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
8870
|
-
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
8871
|
-
disableNativeHrefDrag(el);
|
|
8872
|
-
}
|
|
8873
|
-
});
|
|
8874
|
-
} finally {
|
|
8875
|
-
applying = false;
|
|
8876
|
-
}
|
|
8877
|
-
};
|
|
8878
|
-
const scheduleRun = () => {
|
|
8879
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8880
|
-
rafId = requestAnimationFrame(() => {
|
|
8881
|
-
rafId = null;
|
|
8882
|
-
run();
|
|
8883
|
-
});
|
|
8884
|
-
};
|
|
8885
|
-
run();
|
|
8886
|
-
const nav = document.querySelector("nav");
|
|
8887
|
-
const footer = document.querySelector("footer");
|
|
8888
|
-
const observer = new MutationObserver(scheduleRun);
|
|
8889
|
-
if (nav) observer.observe(nav, { childList: true, subtree: true });
|
|
8890
|
-
if (footer) observer.observe(footer, { childList: true, subtree: true });
|
|
8891
|
-
if (!nav && !footer) return;
|
|
8892
|
-
return () => {
|
|
8893
|
-
observer.disconnect();
|
|
8894
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8895
|
-
};
|
|
8896
|
-
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8897
|
-
useEffect8(() => {
|
|
7090
|
+
useEffect4(() => {
|
|
8898
7091
|
if (!isEditMode) return;
|
|
8899
7092
|
const measure = () => {
|
|
8900
7093
|
const h = document.body.scrollHeight;
|
|
8901
|
-
if (h > 50)
|
|
7094
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8902
7095
|
};
|
|
8903
7096
|
const t1 = setTimeout(measure, 50);
|
|
8904
7097
|
const t2 = setTimeout(measure, 500);
|
|
@@ -8917,8 +7110,8 @@ function OhhwellsBridge() {
|
|
|
8917
7110
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
8918
7111
|
window.removeEventListener("resize", handleResize);
|
|
8919
7112
|
};
|
|
8920
|
-
}, [pathname, isEditMode,
|
|
8921
|
-
|
|
7113
|
+
}, [pathname, isEditMode, postToParent]);
|
|
7114
|
+
useEffect4(() => {
|
|
8922
7115
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8923
7116
|
const handleClick = (e) => {
|
|
8924
7117
|
const anchor = e.target.closest("a");
|
|
@@ -8934,7 +7127,7 @@ function OhhwellsBridge() {
|
|
|
8934
7127
|
document.addEventListener("click", handleClick, true);
|
|
8935
7128
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8936
7129
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8937
|
-
|
|
7130
|
+
useEffect4(() => {
|
|
8938
7131
|
if (!isEditMode) {
|
|
8939
7132
|
editStylesRef.current?.base.remove();
|
|
8940
7133
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -8957,29 +7150,6 @@ function OhhwellsBridge() {
|
|
|
8957
7150
|
[data-ohw-editable] {
|
|
8958
7151
|
display: block;
|
|
8959
7152
|
}
|
|
8960
|
-
/* Native <a> drag steals clicks \u2014 disable for edit links; reorder via press-to-drag / handle. */
|
|
8961
|
-
footer [data-ohw-href-key] {
|
|
8962
|
-
-webkit-user-drag: none !important;
|
|
8963
|
-
}
|
|
8964
|
-
footer [data-ohw-footer-col]:hover {
|
|
8965
|
-
outline: 1.5px dashed ${PRIMARY2} !important;
|
|
8966
|
-
outline-offset: 6px;
|
|
8967
|
-
border-radius: 8px;
|
|
8968
|
-
}
|
|
8969
|
-
html[data-ohw-footer-press-drag] footer,
|
|
8970
|
-
html[data-ohw-footer-press-drag] footer * {
|
|
8971
|
-
user-select: none !important;
|
|
8972
|
-
-webkit-user-select: none !important;
|
|
8973
|
-
}
|
|
8974
|
-
html[data-ohw-item-dragging] footer,
|
|
8975
|
-
html[data-ohw-item-dragging] footer * {
|
|
8976
|
-
user-select: none !important;
|
|
8977
|
-
-webkit-user-select: none !important;
|
|
8978
|
-
pointer-events: none !important;
|
|
8979
|
-
}
|
|
8980
|
-
html[data-ohw-item-dragging] {
|
|
8981
|
-
cursor: grabbing !important;
|
|
8982
|
-
}
|
|
8983
7153
|
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
8984
7154
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8985
7155
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
@@ -9022,49 +7192,15 @@ function OhhwellsBridge() {
|
|
|
9022
7192
|
document.head.appendChild(forceHover);
|
|
9023
7193
|
document.head.appendChild(stateViews);
|
|
9024
7194
|
editStylesRef.current = { base, forceHover, stateViews };
|
|
9025
|
-
}
|
|
9026
|
-
refreshStateRules();
|
|
9027
|
-
const handleClick = (e) => {
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
const target = e.target;
|
|
9035
|
-
if (target.closest("[data-ohw-toolbar]")) return;
|
|
9036
|
-
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
9037
|
-
if (target.closest("[data-ohw-max-badge]")) return;
|
|
9038
|
-
if (isInsideLinkEditor(target)) return;
|
|
9039
|
-
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9040
|
-
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
9041
|
-
e.preventDefault();
|
|
9042
|
-
e.stopPropagation();
|
|
9043
|
-
const selected = selectedElRef.current;
|
|
9044
|
-
if (selected && isNavigationItem(selected)) {
|
|
9045
|
-
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9046
|
-
if (editable2) {
|
|
9047
|
-
activateRef.current(editable2, {
|
|
9048
|
-
caretX: e.clientX,
|
|
9049
|
-
caretY: e.clientY
|
|
9050
|
-
});
|
|
9051
|
-
}
|
|
9052
|
-
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
9053
|
-
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
9054
|
-
const r2 = el.getBoundingClientRect();
|
|
9055
|
-
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
9056
|
-
});
|
|
9057
|
-
if (link) selectRef.current(link);
|
|
9058
|
-
}
|
|
9059
|
-
return;
|
|
9060
|
-
}
|
|
9061
|
-
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
9062
|
-
if (navFromChrome) {
|
|
9063
|
-
e.preventDefault();
|
|
9064
|
-
e.stopPropagation();
|
|
9065
|
-
selectFrameRef.current(navFromChrome);
|
|
9066
|
-
return;
|
|
9067
|
-
}
|
|
7195
|
+
}
|
|
7196
|
+
refreshStateRules();
|
|
7197
|
+
const handleClick = (e) => {
|
|
7198
|
+
const target = e.target;
|
|
7199
|
+
if (target.closest("[data-ohw-toolbar]")) return;
|
|
7200
|
+
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
7201
|
+
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7202
|
+
if (isInsideLinkEditor(target)) return;
|
|
7203
|
+
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9068
7204
|
e.preventDefault();
|
|
9069
7205
|
e.stopPropagation();
|
|
9070
7206
|
return;
|
|
@@ -9079,8 +7215,7 @@ function OhhwellsBridge() {
|
|
|
9079
7215
|
bumpLinkPopoverGrace();
|
|
9080
7216
|
setLinkPopoverRef.current({
|
|
9081
7217
|
key: editable.dataset.ohwKey ?? "",
|
|
9082
|
-
|
|
9083
|
-
target: getLinkHref2(editable)
|
|
7218
|
+
target: getLinkHref(editable)
|
|
9084
7219
|
});
|
|
9085
7220
|
return;
|
|
9086
7221
|
}
|
|
@@ -9096,8 +7231,7 @@ function OhhwellsBridge() {
|
|
|
9096
7231
|
e.preventDefault();
|
|
9097
7232
|
e.stopPropagation();
|
|
9098
7233
|
if (selectedElRef.current === navAnchor) {
|
|
9099
|
-
|
|
9100
|
-
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
7234
|
+
activateRef.current(editable);
|
|
9101
7235
|
return;
|
|
9102
7236
|
}
|
|
9103
7237
|
selectRef.current(navAnchor);
|
|
@@ -9112,42 +7246,10 @@ function OhhwellsBridge() {
|
|
|
9112
7246
|
if (hrefAnchor) {
|
|
9113
7247
|
e.preventDefault();
|
|
9114
7248
|
e.stopPropagation();
|
|
9115
|
-
if (selectedElRef.current === hrefAnchor)
|
|
9116
|
-
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
9117
|
-
if (textEditable) {
|
|
9118
|
-
activateRef.current(textEditable, {
|
|
9119
|
-
caretX: e.clientX,
|
|
9120
|
-
caretY: e.clientY
|
|
9121
|
-
});
|
|
9122
|
-
}
|
|
9123
|
-
return;
|
|
9124
|
-
}
|
|
7249
|
+
if (selectedElRef.current === hrefAnchor) return;
|
|
9125
7250
|
selectRef.current(hrefAnchor);
|
|
9126
7251
|
return;
|
|
9127
7252
|
}
|
|
9128
|
-
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
9129
|
-
if (footerColClick) {
|
|
9130
|
-
e.preventDefault();
|
|
9131
|
-
e.stopPropagation();
|
|
9132
|
-
selectFrameRef.current(footerColClick);
|
|
9133
|
-
return;
|
|
9134
|
-
}
|
|
9135
|
-
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
9136
|
-
if (navContainerToSelect) {
|
|
9137
|
-
e.preventDefault();
|
|
9138
|
-
e.stopPropagation();
|
|
9139
|
-
selectFrameRef.current(navContainerToSelect);
|
|
9140
|
-
return;
|
|
9141
|
-
}
|
|
9142
|
-
const selectedContainer = selectedElRef.current;
|
|
9143
|
-
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
9144
|
-
const navItem = getNavigationItemAnchor(target);
|
|
9145
|
-
if (!navItem && (selectedContainer === target || selectedContainer.contains(target))) {
|
|
9146
|
-
e.preventDefault();
|
|
9147
|
-
e.stopPropagation();
|
|
9148
|
-
return;
|
|
9149
|
-
}
|
|
9150
|
-
}
|
|
9151
7253
|
if (activeElRef.current) {
|
|
9152
7254
|
const sel = window.getSelection();
|
|
9153
7255
|
if (sel && !sel.isCollapsed) {
|
|
@@ -9173,58 +7275,10 @@ function OhhwellsBridge() {
|
|
|
9173
7275
|
deselectRef.current();
|
|
9174
7276
|
deactivateRef.current();
|
|
9175
7277
|
};
|
|
9176
|
-
const handleDblClick = (e) => {
|
|
9177
|
-
const target = e.target;
|
|
9178
|
-
if (target.closest("[data-ohw-toolbar]")) return;
|
|
9179
|
-
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
9180
|
-
if (target.closest("[data-ohw-max-badge]")) return;
|
|
9181
|
-
if (isInsideLinkEditor(target)) return;
|
|
9182
|
-
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9183
|
-
return;
|
|
9184
|
-
}
|
|
9185
|
-
const navLabel = getNavigationLabelEditable(target);
|
|
9186
|
-
if (!navLabel) return;
|
|
9187
|
-
const { editable } = navLabel;
|
|
9188
|
-
e.preventDefault();
|
|
9189
|
-
e.stopPropagation();
|
|
9190
|
-
if (activeElRef.current !== editable) {
|
|
9191
|
-
activateRef.current(editable);
|
|
9192
|
-
}
|
|
9193
|
-
requestAnimationFrame(() => {
|
|
9194
|
-
selectAllTextInEditable(editable);
|
|
9195
|
-
refreshActiveCommandsRef.current();
|
|
9196
|
-
});
|
|
9197
|
-
};
|
|
9198
7278
|
const handleMouseOver = (e) => {
|
|
9199
|
-
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
9200
7279
|
const target = e.target;
|
|
9201
|
-
if (toolbarVariantRef.current !== "select-frame") {
|
|
9202
|
-
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
9203
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
9204
|
-
hoveredNavContainerRef.current = navContainer;
|
|
9205
|
-
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
9206
|
-
hoveredItemElRef.current = null;
|
|
9207
|
-
setHoveredItemRect(null);
|
|
9208
|
-
return;
|
|
9209
|
-
}
|
|
9210
|
-
if (!target.closest("[data-ohw-nav-container]")) {
|
|
9211
|
-
hoveredNavContainerRef.current = null;
|
|
9212
|
-
setHoveredNavContainerRect(null);
|
|
9213
|
-
}
|
|
9214
|
-
}
|
|
9215
|
-
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9216
|
-
if (footerCol) {
|
|
9217
|
-
hoveredNavContainerRef.current = null;
|
|
9218
|
-
setHoveredNavContainerRect(null);
|
|
9219
|
-
if (selectedElRef.current === footerCol) return;
|
|
9220
|
-
hoveredItemElRef.current = footerCol;
|
|
9221
|
-
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
9222
|
-
return;
|
|
9223
|
-
}
|
|
9224
7280
|
const navAnchor = getNavigationItemAnchor(target);
|
|
9225
7281
|
if (navAnchor) {
|
|
9226
|
-
hoveredNavContainerRef.current = null;
|
|
9227
|
-
setHoveredNavContainerRect(null);
|
|
9228
7282
|
const selected2 = selectedElRef.current;
|
|
9229
7283
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
9230
7284
|
clearHrefKeyHover(navAnchor);
|
|
@@ -9249,23 +7303,6 @@ function OhhwellsBridge() {
|
|
|
9249
7303
|
};
|
|
9250
7304
|
const handleMouseOut = (e) => {
|
|
9251
7305
|
const target = e.target;
|
|
9252
|
-
if (target.closest("[data-ohw-nav-container]")) {
|
|
9253
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9254
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
9255
|
-
return;
|
|
9256
|
-
}
|
|
9257
|
-
hoveredNavContainerRef.current = null;
|
|
9258
|
-
setHoveredNavContainerRect(null);
|
|
9259
|
-
}
|
|
9260
|
-
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9261
|
-
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
9262
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9263
|
-
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
9264
|
-
if (related2?.closest("[data-ohw-footer-col]") === footerCol) return;
|
|
9265
|
-
hoveredItemElRef.current = null;
|
|
9266
|
-
setHoveredItemRect(null);
|
|
9267
|
-
return;
|
|
9268
|
-
}
|
|
9269
7306
|
const navAnchor = getNavigationItemAnchor(target);
|
|
9270
7307
|
if (navAnchor) {
|
|
9271
7308
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -9387,85 +7424,42 @@ function OhhwellsBridge() {
|
|
|
9387
7424
|
}
|
|
9388
7425
|
return smallest;
|
|
9389
7426
|
};
|
|
9390
|
-
const dismissImageHover = () => {
|
|
9391
|
-
if (hoveredImageRef.current) {
|
|
9392
|
-
hoveredImageRef.current = null;
|
|
9393
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
9394
|
-
resumeAnimTracks();
|
|
9395
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
9396
|
-
}
|
|
9397
|
-
clearImageHover();
|
|
9398
|
-
};
|
|
9399
|
-
const probeNavigationHoverAt = (x, y) => {
|
|
9400
|
-
if (toolbarVariantRef.current === "select-frame") {
|
|
9401
|
-
hoveredNavContainerRef.current = null;
|
|
9402
|
-
setHoveredNavContainerRect(null);
|
|
9403
|
-
return;
|
|
9404
|
-
}
|
|
9405
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9406
|
-
if (!navContainer) {
|
|
9407
|
-
hoveredNavContainerRef.current = null;
|
|
9408
|
-
setHoveredNavContainerRect(null);
|
|
9409
|
-
return;
|
|
9410
|
-
}
|
|
9411
|
-
const containerRect = navContainer.getBoundingClientRect();
|
|
9412
|
-
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
9413
|
-
if (!overContainer) {
|
|
9414
|
-
hoveredNavContainerRef.current = null;
|
|
9415
|
-
setHoveredNavContainerRect(null);
|
|
9416
|
-
return;
|
|
9417
|
-
}
|
|
9418
|
-
const navItemHit = Array.from(
|
|
9419
|
-
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
9420
|
-
).find((el) => {
|
|
9421
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
9422
|
-
const itemRect = el.getBoundingClientRect();
|
|
9423
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
9424
|
-
});
|
|
9425
|
-
if (navItemHit) {
|
|
9426
|
-
hoveredNavContainerRef.current = null;
|
|
9427
|
-
setHoveredNavContainerRect(null);
|
|
9428
|
-
const selected = selectedElRef.current;
|
|
9429
|
-
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
9430
|
-
clearHrefKeyHover(navItemHit);
|
|
9431
|
-
hoveredItemElRef.current = navItemHit;
|
|
9432
|
-
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
9433
|
-
}
|
|
9434
|
-
return;
|
|
9435
|
-
}
|
|
9436
|
-
hoveredNavContainerRef.current = navContainer;
|
|
9437
|
-
setHoveredNavContainerRect(containerRect);
|
|
9438
|
-
hoveredItemElRef.current = null;
|
|
9439
|
-
setHoveredItemRect(null);
|
|
9440
|
-
};
|
|
9441
7427
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
9442
7428
|
if (linkPopoverOpenRef.current) {
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
probeNavigationHoverAt(x, y);
|
|
7429
|
+
if (hoveredImageRef.current) {
|
|
7430
|
+
hoveredImageRef.current = null;
|
|
7431
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7432
|
+
resumeAnimTracks();
|
|
7433
|
+
clearImageHover();
|
|
7434
|
+
}
|
|
9450
7435
|
return;
|
|
9451
7436
|
}
|
|
9452
|
-
hoveredNavContainerRef.current = null;
|
|
9453
|
-
setHoveredNavContainerRect(null);
|
|
9454
7437
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
9455
7438
|
if (toggleEl) {
|
|
7439
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9456
7440
|
const tr = toggleEl.getBoundingClientRect();
|
|
9457
7441
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
9458
|
-
|
|
7442
|
+
if (hoveredImageRef.current) {
|
|
7443
|
+
hoveredImageRef.current = null;
|
|
7444
|
+
resumeAnimTracks();
|
|
7445
|
+
clearImageHover();
|
|
7446
|
+
}
|
|
9459
7447
|
return;
|
|
9460
7448
|
}
|
|
9461
7449
|
}
|
|
9462
7450
|
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
9463
7451
|
const activeEl = activeElRef.current;
|
|
9464
7452
|
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
9465
|
-
|
|
7453
|
+
if (hoveredImageRef.current) {
|
|
7454
|
+
hoveredImageRef.current = null;
|
|
7455
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7456
|
+
resumeAnimTracks();
|
|
7457
|
+
clearImageHover();
|
|
7458
|
+
}
|
|
9466
7459
|
return;
|
|
9467
7460
|
}
|
|
9468
7461
|
if (imgEl) {
|
|
7462
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9469
7463
|
const topEl = document.elementFromPoint(x, y);
|
|
9470
7464
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9471
7465
|
if (hoveredImageRef.current) {
|
|
@@ -9565,12 +7559,12 @@ function OhhwellsBridge() {
|
|
|
9565
7559
|
resumeAnimTracks();
|
|
9566
7560
|
clearImageHover();
|
|
9567
7561
|
}
|
|
9568
|
-
const { x
|
|
7562
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9569
7563
|
const textEl = Array.from(
|
|
9570
7564
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
9571
7565
|
).find((el) => {
|
|
9572
7566
|
const er = el.getBoundingClientRect();
|
|
9573
|
-
return
|
|
7567
|
+
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
9574
7568
|
});
|
|
9575
7569
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
9576
7570
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -9594,14 +7588,6 @@ function OhhwellsBridge() {
|
|
|
9594
7588
|
}
|
|
9595
7589
|
};
|
|
9596
7590
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
9597
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
9598
|
-
if (activeStateElRef.current) {
|
|
9599
|
-
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
9600
|
-
activeStateElRef.current = null;
|
|
9601
|
-
setToggleState(null);
|
|
9602
|
-
}
|
|
9603
|
-
return;
|
|
9604
|
-
}
|
|
9605
7591
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9606
7592
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
9607
7593
|
if (toggleEl) {
|
|
@@ -9674,14 +7660,6 @@ function OhhwellsBridge() {
|
|
|
9674
7660
|
probeHoverCardsAt(clientX, clientY);
|
|
9675
7661
|
};
|
|
9676
7662
|
const handleDragOver = (e) => {
|
|
9677
|
-
const footerSession = footerDragRef.current;
|
|
9678
|
-
if (footerSession) {
|
|
9679
|
-
e.preventDefault();
|
|
9680
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
9681
|
-
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
9682
|
-
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
9683
|
-
return;
|
|
9684
|
-
}
|
|
9685
7663
|
e.preventDefault();
|
|
9686
7664
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
9687
7665
|
if (!el) {
|
|
@@ -9864,7 +7842,6 @@ function OhhwellsBridge() {
|
|
|
9864
7842
|
continue;
|
|
9865
7843
|
}
|
|
9866
7844
|
if (applyVideoSettingNode(key, val)) continue;
|
|
9867
|
-
if (applyCarouselNode(key, val)) continue;
|
|
9868
7845
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9869
7846
|
if (el.dataset.ohwEditable === "image") {
|
|
9870
7847
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -9887,9 +7864,6 @@ function OhhwellsBridge() {
|
|
|
9887
7864
|
sectionsLoadedRef.current = true;
|
|
9888
7865
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
9889
7866
|
}
|
|
9890
|
-
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9891
|
-
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
9892
|
-
reconcileFooterOrderFromContent(editContentRef.current);
|
|
9893
7867
|
enforceLinkHrefs();
|
|
9894
7868
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9895
7869
|
};
|
|
@@ -9897,7 +7871,6 @@ function OhhwellsBridge() {
|
|
|
9897
7871
|
const handleDeactivate = (e) => {
|
|
9898
7872
|
if (e.data?.type !== "ow:deactivate") return;
|
|
9899
7873
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
9900
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
9901
7874
|
if (linkPopoverOpenRef.current) {
|
|
9902
7875
|
setLinkPopoverRef.current(null);
|
|
9903
7876
|
return;
|
|
@@ -9906,40 +7879,13 @@ function OhhwellsBridge() {
|
|
|
9906
7879
|
deactivateRef.current();
|
|
9907
7880
|
};
|
|
9908
7881
|
window.addEventListener("message", handleDeactivate);
|
|
9909
|
-
const handleUiEscape = (e) => {
|
|
9910
|
-
if (e.data?.type !== "ui:escape") return;
|
|
9911
|
-
if (linkPopoverOpenRef.current) {
|
|
9912
|
-
setLinkPopoverRef.current(null);
|
|
9913
|
-
}
|
|
9914
|
-
};
|
|
9915
|
-
window.addEventListener("message", handleUiEscape);
|
|
9916
7882
|
const handleKeyDown = (e) => {
|
|
9917
|
-
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
9918
|
-
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
9919
|
-
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
9920
|
-
if (navAnchor) {
|
|
9921
|
-
e.preventDefault();
|
|
9922
|
-
selectAllTextInEditable(activeElRef.current);
|
|
9923
|
-
refreshActiveCommandsRef.current();
|
|
9924
|
-
return;
|
|
9925
|
-
}
|
|
9926
|
-
}
|
|
9927
7883
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
9928
7884
|
setLinkPopoverRef.current(null);
|
|
9929
7885
|
return;
|
|
9930
7886
|
}
|
|
9931
7887
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
9932
|
-
|
|
9933
|
-
deselectRef.current();
|
|
9934
|
-
return;
|
|
9935
|
-
}
|
|
9936
|
-
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
9937
|
-
if (parent) {
|
|
9938
|
-
e.preventDefault();
|
|
9939
|
-
selectFrameRef.current(parent);
|
|
9940
|
-
} else {
|
|
9941
|
-
deselectRef.current();
|
|
9942
|
-
}
|
|
7888
|
+
deselectRef.current();
|
|
9943
7889
|
return;
|
|
9944
7890
|
}
|
|
9945
7891
|
if (e.key === "Escape" && activeElRef.current) {
|
|
@@ -9997,23 +7943,9 @@ function OhhwellsBridge() {
|
|
|
9997
7943
|
if (hoveredItemElRef.current) {
|
|
9998
7944
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
9999
7945
|
}
|
|
10000
|
-
if (hoveredNavContainerRef.current) {
|
|
10001
|
-
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
10002
|
-
}
|
|
10003
7946
|
if (siblingHintElRef.current) {
|
|
10004
7947
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
10005
7948
|
}
|
|
10006
|
-
const selected = selectedElRef.current;
|
|
10007
|
-
if (selected && !footerDragRef.current && (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)))) {
|
|
10008
|
-
setSiblingHintRects(
|
|
10009
|
-
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
10010
|
-
);
|
|
10011
|
-
}
|
|
10012
|
-
if (footerDragRef.current) {
|
|
10013
|
-
const session = footerDragRef.current;
|
|
10014
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
10015
|
-
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
10016
|
-
}
|
|
10017
7949
|
if (hoveredImageRef.current) {
|
|
10018
7950
|
const el = hoveredImageRef.current;
|
|
10019
7951
|
const r2 = el.getBoundingClientRect();
|
|
@@ -10024,7 +7956,7 @@ function OhhwellsBridge() {
|
|
|
10024
7956
|
};
|
|
10025
7957
|
const handleSave = (e) => {
|
|
10026
7958
|
if (e.data?.type !== "ow:save") return;
|
|
10027
|
-
const nodes = collectEditableNodes(
|
|
7959
|
+
const nodes = collectEditableNodes();
|
|
10028
7960
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
10029
7961
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
10030
7962
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -10109,7 +8041,6 @@ function OhhwellsBridge() {
|
|
|
10109
8041
|
const handleDocMouseLeave = () => {
|
|
10110
8042
|
hoveredImageRef.current = null;
|
|
10111
8043
|
setMediaHover(null);
|
|
10112
|
-
setCarouselHover(null);
|
|
10113
8044
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
10114
8045
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
10115
8046
|
activeStateElRef.current = null;
|
|
@@ -10149,48 +8080,6 @@ function OhhwellsBridge() {
|
|
|
10149
8080
|
if (e.data?.type !== "ow:canvas-height" || typeof e.data.height !== "number") return;
|
|
10150
8081
|
document.documentElement.style.setProperty("--ohw-canvas-h", `${e.data.height}px`);
|
|
10151
8082
|
};
|
|
10152
|
-
const handleCarouselChange = (e) => {
|
|
10153
|
-
if (e.data?.type !== "ow:carousel-change") return;
|
|
10154
|
-
const { key, images } = e.data;
|
|
10155
|
-
if (!key || !Array.isArray(images)) return;
|
|
10156
|
-
const text = JSON.stringify(images);
|
|
10157
|
-
applyCarouselValue(key, images);
|
|
10158
|
-
editContentRef.current = { ...editContentRef.current, [key]: text };
|
|
10159
|
-
postToParentRef.current({ type: "ow:change", nodes: [{ key, text }] });
|
|
10160
|
-
setCarouselHover(null);
|
|
10161
|
-
};
|
|
10162
|
-
const findCarouselAtPoint = (clientX, clientY) => {
|
|
10163
|
-
const containers = Array.from(document.querySelectorAll(`[${CAROUSEL_ATTR}]`));
|
|
10164
|
-
for (let i = containers.length - 1; i >= 0; i--) {
|
|
10165
|
-
const r2 = containers[i].getBoundingClientRect();
|
|
10166
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) {
|
|
10167
|
-
return containers[i];
|
|
10168
|
-
}
|
|
10169
|
-
}
|
|
10170
|
-
return null;
|
|
10171
|
-
};
|
|
10172
|
-
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
10173
|
-
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
10174
|
-
for (const el of editables) {
|
|
10175
|
-
const r2 = el.getBoundingClientRect();
|
|
10176
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
10177
|
-
}
|
|
10178
|
-
return false;
|
|
10179
|
-
};
|
|
10180
|
-
const handleCarouselHover = (e) => {
|
|
10181
|
-
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
10182
|
-
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
10183
|
-
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
10184
|
-
setCarouselHover((prev) => prev ? null : prev);
|
|
10185
|
-
return;
|
|
10186
|
-
}
|
|
10187
|
-
const key = container.getAttribute("data-ohw-key") ?? "";
|
|
10188
|
-
if (!key) return;
|
|
10189
|
-
const r2 = getVisibleRect(container);
|
|
10190
|
-
setCarouselHover(
|
|
10191
|
-
(prev) => prev && prev.key === key && prev.rect.top === r2.top && prev.rect.left === r2.left && prev.rect.width === r2.width && prev.rect.height === r2.height ? prev : { key, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
10192
|
-
);
|
|
10193
|
-
};
|
|
10194
8083
|
const applyToolbarPos = (rect) => {
|
|
10195
8084
|
const ps = parentScrollRef.current;
|
|
10196
8085
|
const approxW = 330;
|
|
@@ -10250,45 +8139,9 @@ function OhhwellsBridge() {
|
|
|
10250
8139
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
10251
8140
|
});
|
|
10252
8141
|
if (textEditable) {
|
|
10253
|
-
|
|
10254
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
10255
|
-
if (navAnchor) {
|
|
10256
|
-
if (selectedElRef.current === navAnchor) {
|
|
10257
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
10258
|
-
} else {
|
|
10259
|
-
selectRef.current(navAnchor);
|
|
10260
|
-
}
|
|
10261
|
-
return;
|
|
10262
|
-
}
|
|
10263
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8142
|
+
activateRef.current(textEditable);
|
|
10264
8143
|
return;
|
|
10265
8144
|
}
|
|
10266
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
10267
|
-
if (navContainer) {
|
|
10268
|
-
const r2 = navContainer.getBoundingClientRect();
|
|
10269
|
-
const pad = 8;
|
|
10270
|
-
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
10271
|
-
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
10272
|
-
selectFrameRef.current(navContainer);
|
|
10273
|
-
return;
|
|
10274
|
-
}
|
|
10275
|
-
}
|
|
10276
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
10277
|
-
if (navRoot && navContainer) {
|
|
10278
|
-
const rr = navRoot.getBoundingClientRect();
|
|
10279
|
-
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
10280
|
-
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
10281
|
-
if (book) {
|
|
10282
|
-
const br = book.getBoundingClientRect();
|
|
10283
|
-
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
10284
|
-
deactivateRef.current();
|
|
10285
|
-
return;
|
|
10286
|
-
}
|
|
10287
|
-
}
|
|
10288
|
-
selectFrameRef.current(navContainer);
|
|
10289
|
-
return;
|
|
10290
|
-
}
|
|
10291
|
-
}
|
|
10292
8145
|
deactivateRef.current();
|
|
10293
8146
|
};
|
|
10294
8147
|
window.addEventListener("message", handleSave);
|
|
@@ -10299,7 +8152,6 @@ function OhhwellsBridge() {
|
|
|
10299
8152
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
10300
8153
|
window.addEventListener("message", handleImageUrl);
|
|
10301
8154
|
window.addEventListener("message", handleImageUploading);
|
|
10302
|
-
window.addEventListener("message", handleCarouselChange);
|
|
10303
8155
|
window.addEventListener("message", handleCanvasHeight);
|
|
10304
8156
|
window.addEventListener("message", handleParentScroll);
|
|
10305
8157
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -10311,13 +8163,11 @@ function OhhwellsBridge() {
|
|
|
10311
8163
|
};
|
|
10312
8164
|
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
10313
8165
|
document.addEventListener("click", handleClick, true);
|
|
10314
|
-
document.addEventListener("dblclick", handleDblClick, true);
|
|
10315
8166
|
document.addEventListener("paste", handlePaste, true);
|
|
10316
8167
|
document.addEventListener("input", handleInput, true);
|
|
10317
8168
|
document.addEventListener("mouseover", handleMouseOver, true);
|
|
10318
8169
|
document.addEventListener("mouseout", handleMouseOut, true);
|
|
10319
8170
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
10320
|
-
document.addEventListener("mousemove", handleCarouselHover, true);
|
|
10321
8171
|
document.addEventListener("mouseleave", handleDocMouseLeave);
|
|
10322
8172
|
document.addEventListener("dragover", handleDragOver, true);
|
|
10323
8173
|
document.addEventListener("dragleave", handleDragLeave, true);
|
|
@@ -10327,13 +8177,11 @@ function OhhwellsBridge() {
|
|
|
10327
8177
|
window.addEventListener("scroll", handleScroll, true);
|
|
10328
8178
|
return () => {
|
|
10329
8179
|
document.removeEventListener("click", handleClick, true);
|
|
10330
|
-
document.removeEventListener("dblclick", handleDblClick, true);
|
|
10331
8180
|
document.removeEventListener("paste", handlePaste, true);
|
|
10332
8181
|
document.removeEventListener("input", handleInput, true);
|
|
10333
8182
|
document.removeEventListener("mouseover", handleMouseOver, true);
|
|
10334
8183
|
document.removeEventListener("mouseout", handleMouseOut, true);
|
|
10335
8184
|
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
10336
|
-
document.removeEventListener("mousemove", handleCarouselHover, true);
|
|
10337
8185
|
document.removeEventListener("mouseleave", handleDocMouseLeave);
|
|
10338
8186
|
document.removeEventListener("dragover", handleDragOver, true);
|
|
10339
8187
|
document.removeEventListener("dragleave", handleDragLeave, true);
|
|
@@ -10349,7 +8197,6 @@ function OhhwellsBridge() {
|
|
|
10349
8197
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
10350
8198
|
window.removeEventListener("message", handleImageUrl);
|
|
10351
8199
|
window.removeEventListener("message", handleImageUploading);
|
|
10352
|
-
window.removeEventListener("message", handleCarouselChange);
|
|
10353
8200
|
window.removeEventListener("message", handleCanvasHeight);
|
|
10354
8201
|
window.removeEventListener("message", handleParentScroll);
|
|
10355
8202
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -10357,162 +8204,13 @@ function OhhwellsBridge() {
|
|
|
10357
8204
|
window.removeEventListener("message", handleClickAt);
|
|
10358
8205
|
window.removeEventListener("message", handleHydrate);
|
|
10359
8206
|
window.removeEventListener("message", handleDeactivate);
|
|
10360
|
-
window.removeEventListener("message", handleUiEscape);
|
|
10361
8207
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
10362
8208
|
autoSaveTimers.current.clear();
|
|
10363
8209
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
10364
8210
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
10365
8211
|
};
|
|
10366
8212
|
}, [isEditMode, refreshStateRules]);
|
|
10367
|
-
|
|
10368
|
-
if (!isEditMode) return;
|
|
10369
|
-
const THRESHOLD = 10;
|
|
10370
|
-
const resolveWasSelected = (el) => {
|
|
10371
|
-
if (selectedElRef.current === el) return true;
|
|
10372
|
-
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
10373
|
-
return activeAnchor === el;
|
|
10374
|
-
};
|
|
10375
|
-
const onPointerDown = (e) => {
|
|
10376
|
-
if (e.button !== 0) return;
|
|
10377
|
-
if (footerDragRef.current) return;
|
|
10378
|
-
const target = e.target;
|
|
10379
|
-
if (!target) return;
|
|
10380
|
-
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]')) {
|
|
10381
|
-
return;
|
|
10382
|
-
}
|
|
10383
|
-
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
10384
|
-
const anchor = getNavigationItemAnchor(target);
|
|
10385
|
-
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
10386
|
-
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
10387
|
-
armFooterPressDrag();
|
|
10388
|
-
footerPointerDragRef.current = {
|
|
10389
|
-
el: anchor,
|
|
10390
|
-
kind: "link",
|
|
10391
|
-
startX: e.clientX,
|
|
10392
|
-
startY: e.clientY,
|
|
10393
|
-
pointerId: e.pointerId,
|
|
10394
|
-
wasSelected: resolveWasSelected(anchor),
|
|
10395
|
-
started: false
|
|
10396
|
-
};
|
|
10397
|
-
return;
|
|
10398
|
-
}
|
|
10399
|
-
const col = target.closest("[data-ohw-footer-col]");
|
|
10400
|
-
if (col && !getNavigationItemAnchor(target)) {
|
|
10401
|
-
armFooterPressDrag();
|
|
10402
|
-
footerPointerDragRef.current = {
|
|
10403
|
-
el: col,
|
|
10404
|
-
kind: "column",
|
|
10405
|
-
startX: e.clientX,
|
|
10406
|
-
startY: e.clientY,
|
|
10407
|
-
pointerId: e.pointerId,
|
|
10408
|
-
wasSelected: resolveWasSelected(col),
|
|
10409
|
-
started: false
|
|
10410
|
-
};
|
|
10411
|
-
}
|
|
10412
|
-
};
|
|
10413
|
-
const onPointerMove = (e) => {
|
|
10414
|
-
const pending = footerPointerDragRef.current;
|
|
10415
|
-
if (!pending) return;
|
|
10416
|
-
if (pending.started) {
|
|
10417
|
-
e.preventDefault();
|
|
10418
|
-
clearTextSelection();
|
|
10419
|
-
const session = footerDragRef.current;
|
|
10420
|
-
if (!session) return;
|
|
10421
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10422
|
-
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
10423
|
-
return;
|
|
10424
|
-
}
|
|
10425
|
-
const dx = e.clientX - pending.startX;
|
|
10426
|
-
const dy = e.clientY - pending.startY;
|
|
10427
|
-
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
10428
|
-
e.preventDefault();
|
|
10429
|
-
pending.started = true;
|
|
10430
|
-
clearTextSelection();
|
|
10431
|
-
try {
|
|
10432
|
-
document.body.setPointerCapture(pending.pointerId);
|
|
10433
|
-
} catch {
|
|
10434
|
-
}
|
|
10435
|
-
if (linkPopoverOpenRef.current) {
|
|
10436
|
-
setLinkPopoverRef.current(null);
|
|
10437
|
-
}
|
|
10438
|
-
if (activeElRef.current) {
|
|
10439
|
-
deactivateRef.current();
|
|
10440
|
-
}
|
|
10441
|
-
if (pending.kind === "link") {
|
|
10442
|
-
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
10443
|
-
if (!key) return;
|
|
10444
|
-
const column = findFooterColumnForLink(pending.el);
|
|
10445
|
-
const columns2 = listFooterColumns();
|
|
10446
|
-
beginFooterDragRef.current({
|
|
10447
|
-
kind: "link",
|
|
10448
|
-
hrefKey: key,
|
|
10449
|
-
columnEl: column,
|
|
10450
|
-
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
10451
|
-
wasSelected: pending.wasSelected,
|
|
10452
|
-
draggedEl: pending.el,
|
|
10453
|
-
lastClientX: e.clientX,
|
|
10454
|
-
lastClientY: e.clientY,
|
|
10455
|
-
activeSlot: null
|
|
10456
|
-
});
|
|
10457
|
-
return;
|
|
10458
|
-
}
|
|
10459
|
-
const columns = listFooterColumns();
|
|
10460
|
-
const idx = columns.indexOf(pending.el);
|
|
10461
|
-
if (idx < 0) return;
|
|
10462
|
-
beginFooterDragRef.current({
|
|
10463
|
-
kind: "column",
|
|
10464
|
-
hrefKey: null,
|
|
10465
|
-
columnEl: pending.el,
|
|
10466
|
-
sourceColumnIndex: idx,
|
|
10467
|
-
wasSelected: pending.wasSelected,
|
|
10468
|
-
draggedEl: pending.el,
|
|
10469
|
-
lastClientX: e.clientX,
|
|
10470
|
-
lastClientY: e.clientY,
|
|
10471
|
-
activeSlot: null
|
|
10472
|
-
});
|
|
10473
|
-
};
|
|
10474
|
-
const endPointerDrag = (e) => {
|
|
10475
|
-
const pending = footerPointerDragRef.current;
|
|
10476
|
-
footerPointerDragRef.current = null;
|
|
10477
|
-
try {
|
|
10478
|
-
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
10479
|
-
document.body.releasePointerCapture(e.pointerId);
|
|
10480
|
-
}
|
|
10481
|
-
} catch {
|
|
10482
|
-
}
|
|
10483
|
-
if (!pending?.started) {
|
|
10484
|
-
unlockFooterDragInteraction();
|
|
10485
|
-
return;
|
|
10486
|
-
}
|
|
10487
|
-
suppressNextClickRef.current = true;
|
|
10488
|
-
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
10489
|
-
};
|
|
10490
|
-
const blockSelectStart = (e) => {
|
|
10491
|
-
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
10492
|
-
e.preventDefault();
|
|
10493
|
-
}
|
|
10494
|
-
};
|
|
10495
|
-
const onDragEnd = (_e) => {
|
|
10496
|
-
if (!footerDragRef.current) return;
|
|
10497
|
-
commitFooterDragRef.current();
|
|
10498
|
-
};
|
|
10499
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
10500
|
-
document.addEventListener("pointermove", onPointerMove, true);
|
|
10501
|
-
document.addEventListener("pointerup", endPointerDrag, true);
|
|
10502
|
-
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
10503
|
-
document.addEventListener("selectstart", blockSelectStart, true);
|
|
10504
|
-
document.addEventListener("dragend", onDragEnd, true);
|
|
10505
|
-
return () => {
|
|
10506
|
-
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
10507
|
-
document.removeEventListener("pointermove", onPointerMove, true);
|
|
10508
|
-
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
10509
|
-
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
10510
|
-
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
10511
|
-
document.removeEventListener("dragend", onDragEnd, true);
|
|
10512
|
-
unlockFooterDragInteraction();
|
|
10513
|
-
};
|
|
10514
|
-
}, [isEditMode]);
|
|
10515
|
-
useEffect8(() => {
|
|
8213
|
+
useEffect4(() => {
|
|
10516
8214
|
const handler = (e) => {
|
|
10517
8215
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
10518
8216
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -10528,7 +8226,7 @@ function OhhwellsBridge() {
|
|
|
10528
8226
|
window.addEventListener("message", handler);
|
|
10529
8227
|
return () => window.removeEventListener("message", handler);
|
|
10530
8228
|
}, [processConfigRequest]);
|
|
10531
|
-
|
|
8229
|
+
useEffect4(() => {
|
|
10532
8230
|
if (!isEditMode) return;
|
|
10533
8231
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
10534
8232
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -10549,33 +8247,27 @@ function OhhwellsBridge() {
|
|
|
10549
8247
|
const next = { ...prev, [pathKey]: sections };
|
|
10550
8248
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
10551
8249
|
});
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
version: "1",
|
|
10555
|
-
path: pathname,
|
|
10556
|
-
nodes: collectEditableNodes(editContentRef.current),
|
|
10557
|
-
sections
|
|
10558
|
-
});
|
|
10559
|
-
postToParent2({ type: "ow:request-site-pages" });
|
|
8250
|
+
postToParent({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
8251
|
+
postToParent({ type: "ow:request-site-pages" });
|
|
10560
8252
|
}, 150);
|
|
10561
8253
|
return () => {
|
|
10562
8254
|
cancelAnimationFrame(raf);
|
|
10563
8255
|
clearTimeout(timer);
|
|
10564
8256
|
};
|
|
10565
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
10566
|
-
|
|
8257
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent]);
|
|
8258
|
+
useEffect4(() => {
|
|
10567
8259
|
scrollToHashSectionWhenReady();
|
|
10568
8260
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
10569
8261
|
window.addEventListener("hashchange", onHashChange);
|
|
10570
8262
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
10571
8263
|
}, [pathname]);
|
|
10572
|
-
const handleCommand =
|
|
8264
|
+
const handleCommand = useCallback2((cmd) => {
|
|
10573
8265
|
document.execCommand(cmd, false);
|
|
10574
8266
|
activeElRef.current?.focus();
|
|
10575
8267
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
10576
8268
|
refreshActiveCommandsRef.current();
|
|
10577
8269
|
}, []);
|
|
10578
|
-
const handleStateChange =
|
|
8270
|
+
const handleStateChange = useCallback2((state) => {
|
|
10579
8271
|
if (!activeStateElRef.current) return;
|
|
10580
8272
|
const el = activeStateElRef.current;
|
|
10581
8273
|
if (state === "Default") {
|
|
@@ -10588,22 +8280,18 @@ function OhhwellsBridge() {
|
|
|
10588
8280
|
}
|
|
10589
8281
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
10590
8282
|
}, [deactivate]);
|
|
10591
|
-
const closeLinkPopover =
|
|
10592
|
-
|
|
10593
|
-
setLinkPopover(null);
|
|
10594
|
-
}, []);
|
|
10595
|
-
const openLinkPopoverForActive = useCallback4(() => {
|
|
8283
|
+
const closeLinkPopover = useCallback2(() => setLinkPopover(null), []);
|
|
8284
|
+
const openLinkPopoverForActive = useCallback2(() => {
|
|
10596
8285
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
10597
8286
|
if (!hrefCtx) return;
|
|
10598
8287
|
bumpLinkPopoverGrace();
|
|
10599
8288
|
setLinkPopover({
|
|
10600
8289
|
key: hrefCtx.key,
|
|
10601
|
-
|
|
10602
|
-
target: getLinkHref2(hrefCtx.anchor)
|
|
8290
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
10603
8291
|
});
|
|
10604
8292
|
deactivate();
|
|
10605
8293
|
}, [deactivate]);
|
|
10606
|
-
const openLinkPopoverForSelected =
|
|
8294
|
+
const openLinkPopoverForSelected = useCallback2(() => {
|
|
10607
8295
|
const anchor = selectedElRef.current;
|
|
10608
8296
|
if (!anchor) return;
|
|
10609
8297
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -10611,80 +8299,30 @@ function OhhwellsBridge() {
|
|
|
10611
8299
|
bumpLinkPopoverGrace();
|
|
10612
8300
|
setLinkPopover({
|
|
10613
8301
|
key,
|
|
10614
|
-
|
|
10615
|
-
target: getLinkHref2(anchor)
|
|
8302
|
+
target: getLinkHref(anchor)
|
|
10616
8303
|
});
|
|
10617
8304
|
deselect();
|
|
10618
8305
|
}, [deselect]);
|
|
10619
|
-
const handleLinkPopoverSubmit =
|
|
8306
|
+
const handleLinkPopoverSubmit = useCallback2(
|
|
10620
8307
|
(target) => {
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
if (session.intent === "add-nav") {
|
|
10624
|
-
const trimmed = target.trim();
|
|
10625
|
-
let href = trimmed;
|
|
10626
|
-
let label = "Untitled";
|
|
10627
|
-
if (trimmed) {
|
|
10628
|
-
const { pageRoute, sectionId } = parseTarget(trimmed);
|
|
10629
|
-
const page = resolvePage(pageRoute, sitePages);
|
|
10630
|
-
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
10631
|
-
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
10632
|
-
label = section?.label ?? page.title;
|
|
10633
|
-
href = trimmed;
|
|
10634
|
-
}
|
|
10635
|
-
const afterAnchor = addNavAfterAnchorRef.current;
|
|
10636
|
-
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(href, label, afterAnchor);
|
|
10637
|
-
applyLinkByKey(hrefKey, href);
|
|
10638
|
-
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
10639
|
-
el.textContent = label;
|
|
10640
|
-
});
|
|
10641
|
-
const navCount = String(index + 1);
|
|
10642
|
-
const orderJson = JSON.stringify(order);
|
|
10643
|
-
editContentRef.current = {
|
|
10644
|
-
...editContentRef.current,
|
|
10645
|
-
[hrefKey]: href,
|
|
10646
|
-
[labelKey]: label,
|
|
10647
|
-
[NAV_COUNT_KEY]: navCount,
|
|
10648
|
-
[NAV_ORDER_KEY]: orderJson
|
|
10649
|
-
};
|
|
10650
|
-
postToParent2({
|
|
10651
|
-
type: "ow:change",
|
|
10652
|
-
nodes: [
|
|
10653
|
-
{ key: hrefKey, text: href },
|
|
10654
|
-
{ key: labelKey, text: label },
|
|
10655
|
-
{ key: NAV_COUNT_KEY, text: navCount },
|
|
10656
|
-
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
10657
|
-
]
|
|
10658
|
-
});
|
|
10659
|
-
postToParent2({ type: "ow:toast", title: "Link added", toastType: "success" });
|
|
10660
|
-
addNavAfterAnchorRef.current = null;
|
|
10661
|
-
setLinkPopover(null);
|
|
10662
|
-
enforceLinkHrefs();
|
|
10663
|
-
requestAnimationFrame(() => {
|
|
10664
|
-
selectRef.current(anchor);
|
|
10665
|
-
});
|
|
10666
|
-
return;
|
|
10667
|
-
}
|
|
10668
|
-
const { key } = session;
|
|
8308
|
+
if (!linkPopover) return;
|
|
8309
|
+
const { key } = linkPopover;
|
|
10669
8310
|
applyLinkByKey(key, target);
|
|
10670
|
-
|
|
8311
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
10671
8312
|
setLinkPopover(null);
|
|
10672
8313
|
},
|
|
10673
|
-
[
|
|
10674
|
-
);
|
|
10675
|
-
const handleMediaReplace = useCallback4(
|
|
10676
|
-
(key) => {
|
|
10677
|
-
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
10678
|
-
},
|
|
10679
|
-
[postToParent2, mediaHover?.elementType]
|
|
8314
|
+
[linkPopover, postToParent]
|
|
10680
8315
|
);
|
|
10681
|
-
const
|
|
8316
|
+
const showEditLink = toolbarShowEditLink;
|
|
8317
|
+
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8318
|
+
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8319
|
+
const handleMediaReplace = useCallback2(
|
|
10682
8320
|
(key) => {
|
|
10683
|
-
|
|
8321
|
+
postToParent({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
10684
8322
|
},
|
|
10685
|
-
[
|
|
8323
|
+
[postToParent, mediaHover?.elementType]
|
|
10686
8324
|
);
|
|
10687
|
-
const handleMediaFadeOutComplete =
|
|
8325
|
+
const handleMediaFadeOutComplete = useCallback2((key) => {
|
|
10688
8326
|
setUploadingRects((prev) => {
|
|
10689
8327
|
if (!(key in prev)) return prev;
|
|
10690
8328
|
const next = { ...prev };
|
|
@@ -10692,7 +8330,7 @@ function OhhwellsBridge() {
|
|
|
10692
8330
|
return next;
|
|
10693
8331
|
});
|
|
10694
8332
|
}, []);
|
|
10695
|
-
const handleVideoSettingsChange =
|
|
8333
|
+
const handleVideoSettingsChange = useCallback2(
|
|
10696
8334
|
(key, settings) => {
|
|
10697
8335
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
10698
8336
|
const video = getVideoEl(el);
|
|
@@ -10700,7 +8338,7 @@ function OhhwellsBridge() {
|
|
|
10700
8338
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
10701
8339
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
10702
8340
|
syncVideoPlayback(video);
|
|
10703
|
-
|
|
8341
|
+
postToParent({
|
|
10704
8342
|
type: "ow:change",
|
|
10705
8343
|
nodes: [
|
|
10706
8344
|
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
@@ -10712,15 +8350,12 @@ function OhhwellsBridge() {
|
|
|
10712
8350
|
);
|
|
10713
8351
|
});
|
|
10714
8352
|
},
|
|
10715
|
-
[
|
|
8353
|
+
[postToParent]
|
|
10716
8354
|
);
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
/* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
10722
|
-
/* @__PURE__ */ jsx25("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
10723
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx25(
|
|
8355
|
+
return bridgeRoot ? createPortal(
|
|
8356
|
+
/* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
8357
|
+
/* @__PURE__ */ jsx22("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8358
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx22(
|
|
10724
8359
|
MediaOverlay,
|
|
10725
8360
|
{
|
|
10726
8361
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -10731,7 +8366,7 @@ function OhhwellsBridge() {
|
|
|
10731
8366
|
},
|
|
10732
8367
|
`uploading-${key}`
|
|
10733
8368
|
)),
|
|
10734
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
8369
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx22(
|
|
10735
8370
|
MediaOverlay,
|
|
10736
8371
|
{
|
|
10737
8372
|
hover: mediaHover,
|
|
@@ -10740,33 +8375,53 @@ function OhhwellsBridge() {
|
|
|
10740
8375
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
10741
8376
|
}
|
|
10742
8377
|
),
|
|
10743
|
-
|
|
10744
|
-
siblingHintRect && !isItemDragging &&
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx25(
|
|
10748
|
-
"div",
|
|
8378
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ jsx22(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8379
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx22(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8380
|
+
toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ jsx22(
|
|
8381
|
+
ItemInteractionLayer,
|
|
10749
8382
|
{
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
8383
|
+
rect: toolbarRect,
|
|
8384
|
+
elRef: glowElRef,
|
|
8385
|
+
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8386
|
+
showHandle: Boolean(reorderHrefKey),
|
|
8387
|
+
dragDisabled: reorderDragDisabled,
|
|
8388
|
+
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8389
|
+
onDragHandleDragStart: handleItemDragStart,
|
|
8390
|
+
onDragHandleDragEnd: handleItemDragEnd,
|
|
8391
|
+
toolbar: isItemDragging ? void 0 : /* @__PURE__ */ jsx22(
|
|
8392
|
+
ItemActionToolbar,
|
|
8393
|
+
{
|
|
8394
|
+
onEditLink: openLinkPopoverForSelected,
|
|
8395
|
+
onAddItem: handleAddNavigationItem,
|
|
8396
|
+
addItemDisabled: false
|
|
8397
|
+
}
|
|
8398
|
+
)
|
|
8399
|
+
}
|
|
8400
|
+
),
|
|
8401
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
8402
|
+
/* @__PURE__ */ jsx22(
|
|
8403
|
+
EditGlowChrome,
|
|
8404
|
+
{
|
|
8405
|
+
rect: toolbarRect,
|
|
8406
|
+
elRef: glowElRef,
|
|
8407
|
+
reorderHrefKey,
|
|
8408
|
+
dragDisabled: reorderDragDisabled
|
|
8409
|
+
}
|
|
8410
|
+
),
|
|
8411
|
+
/* @__PURE__ */ jsx22(
|
|
8412
|
+
FloatingToolbar,
|
|
8413
|
+
{
|
|
8414
|
+
rect: toolbarRect,
|
|
8415
|
+
parentScroll: parentScrollRef.current,
|
|
8416
|
+
elRef: toolbarElRef,
|
|
8417
|
+
onCommand: handleCommand,
|
|
8418
|
+
activeCommands,
|
|
8419
|
+
showEditLink,
|
|
8420
|
+
onEditLink: openLinkPopoverForActive
|
|
8421
|
+
}
|
|
8422
|
+
)
|
|
10768
8423
|
] }),
|
|
10769
|
-
maxBadge && /* @__PURE__ */
|
|
8424
|
+
maxBadge && /* @__PURE__ */ jsxs12(
|
|
10770
8425
|
"div",
|
|
10771
8426
|
{
|
|
10772
8427
|
"data-ohw-max-badge": "",
|
|
@@ -10792,29 +8447,56 @@ function OhhwellsBridge() {
|
|
|
10792
8447
|
]
|
|
10793
8448
|
}
|
|
10794
8449
|
),
|
|
10795
|
-
toggleState &&
|
|
10796
|
-
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
8450
|
+
toggleState && /* @__PURE__ */ jsx22(
|
|
8451
|
+
StateToggle,
|
|
8452
|
+
{
|
|
8453
|
+
rect: toggleState.rect,
|
|
8454
|
+
activeState: toggleState.activeState,
|
|
8455
|
+
states: toggleState.states,
|
|
8456
|
+
onStateChange: handleStateChange
|
|
8457
|
+
}
|
|
8458
|
+
),
|
|
8459
|
+
sectionGap && /* @__PURE__ */ jsxs12(
|
|
8460
|
+
"div",
|
|
8461
|
+
{
|
|
8462
|
+
"data-ohw-section-insert-line": "",
|
|
8463
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8464
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8465
|
+
children: [
|
|
8466
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8467
|
+
/* @__PURE__ */ jsx22(
|
|
8468
|
+
Badge,
|
|
8469
|
+
{
|
|
8470
|
+
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",
|
|
8471
|
+
onClick: () => {
|
|
8472
|
+
window.parent.postMessage(
|
|
8473
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
8474
|
+
"*"
|
|
8475
|
+
);
|
|
10808
8476
|
},
|
|
10809
|
-
"
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
8477
|
+
children: "Add Section"
|
|
8478
|
+
}
|
|
8479
|
+
),
|
|
8480
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8481
|
+
]
|
|
8482
|
+
}
|
|
8483
|
+
),
|
|
8484
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx22(
|
|
8485
|
+
LinkPopover,
|
|
8486
|
+
{
|
|
8487
|
+
panelRef: linkPopoverPanelRef,
|
|
8488
|
+
portalContainer: dialogPortalContainer,
|
|
8489
|
+
open: true,
|
|
8490
|
+
mode: "edit",
|
|
8491
|
+
pages: sitePages,
|
|
8492
|
+
sections: currentSections,
|
|
8493
|
+
sectionsByPath,
|
|
8494
|
+
initialTarget: linkPopover.target,
|
|
8495
|
+
onClose: closeLinkPopover,
|
|
8496
|
+
onSubmit: handleLinkPopoverSubmit
|
|
8497
|
+
},
|
|
8498
|
+
`${linkPopover.key}-${pathname}`
|
|
8499
|
+
) : null
|
|
10818
8500
|
] }),
|
|
10819
8501
|
bridgeRoot
|
|
10820
8502
|
) : null;
|
|
@@ -10824,7 +8506,6 @@ export {
|
|
|
10824
8506
|
CustomToolbarButton,
|
|
10825
8507
|
CustomToolbarDivider,
|
|
10826
8508
|
DragHandle,
|
|
10827
|
-
DropIndicator,
|
|
10828
8509
|
ItemActionToolbar,
|
|
10829
8510
|
ItemInteractionLayer,
|
|
10830
8511
|
LinkEditorPanel,
|
|
@@ -10839,14 +8520,12 @@ export {
|
|
|
10839
8520
|
TooltipProvider,
|
|
10840
8521
|
TooltipTrigger,
|
|
10841
8522
|
buildTarget,
|
|
10842
|
-
dropIndicatorVariants,
|
|
10843
8523
|
filterAvailablePages,
|
|
10844
8524
|
getEditModeInitialState,
|
|
10845
8525
|
isEditSessionActive,
|
|
10846
8526
|
isValidUrl,
|
|
10847
8527
|
parseTarget,
|
|
10848
8528
|
toggleVariants,
|
|
10849
|
-
useOhwCarousel,
|
|
10850
8529
|
validateUrlInput
|
|
10851
8530
|
};
|
|
10852
8531
|
//# sourceMappingURL=index.js.map
|