@ohhwells/bridge 0.1.41 → 0.1.42-next.81
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 +13 -1
- package/dist/index.cjs +1737 -489
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -3
- package/dist/index.d.ts +48 -3
- package/dist/index.js +1688 -443
- package/dist/index.js.map +1 -1
- package/dist/styles.css +42 -18
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
CustomToolbarButton: () => CustomToolbarButton,
|
|
36
36
|
CustomToolbarDivider: () => CustomToolbarDivider,
|
|
37
37
|
DragHandle: () => DragHandle,
|
|
38
|
+
DropIndicator: () => DropIndicator,
|
|
38
39
|
ItemActionToolbar: () => ItemActionToolbar,
|
|
39
40
|
ItemInteractionLayer: () => ItemInteractionLayer,
|
|
40
41
|
LinkEditorPanel: () => LinkEditorPanel,
|
|
@@ -49,18 +50,20 @@ __export(index_exports, {
|
|
|
49
50
|
TooltipProvider: () => TooltipProvider,
|
|
50
51
|
TooltipTrigger: () => TooltipTrigger,
|
|
51
52
|
buildTarget: () => buildTarget,
|
|
53
|
+
dropIndicatorVariants: () => dropIndicatorVariants,
|
|
52
54
|
filterAvailablePages: () => filterAvailablePages,
|
|
53
55
|
getEditModeInitialState: () => getEditModeInitialState,
|
|
54
56
|
isEditSessionActive: () => isEditSessionActive,
|
|
55
57
|
isValidUrl: () => isValidUrl,
|
|
56
58
|
parseTarget: () => parseTarget,
|
|
57
59
|
toggleVariants: () => toggleVariants,
|
|
60
|
+
useOhwCarousel: () => useOhwCarousel,
|
|
58
61
|
validateUrlInput: () => validateUrlInput
|
|
59
62
|
});
|
|
60
63
|
module.exports = __toCommonJS(index_exports);
|
|
61
64
|
|
|
62
65
|
// src/OhhwellsBridge.tsx
|
|
63
|
-
var
|
|
66
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
64
67
|
var import_client = require("react-dom/client");
|
|
65
68
|
var import_react_dom2 = require("react-dom");
|
|
66
69
|
|
|
@@ -113,6 +116,7 @@ var import_react3 = require("react");
|
|
|
113
116
|
var import_react2 = require("react");
|
|
114
117
|
var import_radix_ui = require("radix-ui");
|
|
115
118
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
119
|
+
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
116
120
|
function Spinner() {
|
|
117
121
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
118
122
|
"svg",
|
|
@@ -146,12 +150,17 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
146
150
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
147
151
|
const isBook = title === "Confirm your spot";
|
|
148
152
|
const handleSubmit = async () => {
|
|
149
|
-
|
|
153
|
+
const trimmed = email.trim();
|
|
154
|
+
if (!trimmed) return;
|
|
155
|
+
if (!isValidEmail(trimmed)) {
|
|
156
|
+
setError("Please enter a valid email address.");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
150
159
|
setLoading(true);
|
|
151
160
|
setError(null);
|
|
152
161
|
try {
|
|
153
|
-
await onSubmit(
|
|
154
|
-
setSubmittedEmail(
|
|
162
|
+
await onSubmit(trimmed);
|
|
163
|
+
setSubmittedEmail(trimmed);
|
|
155
164
|
setSuccess(true);
|
|
156
165
|
} catch (e) {
|
|
157
166
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -226,7 +235,10 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
226
235
|
{
|
|
227
236
|
type: "email",
|
|
228
237
|
value: email,
|
|
229
|
-
onChange: (e) =>
|
|
238
|
+
onChange: (e) => {
|
|
239
|
+
setEmail(e.target.value);
|
|
240
|
+
if (error) setError(null);
|
|
241
|
+
},
|
|
230
242
|
onKeyDown: handleKeyDown,
|
|
231
243
|
placeholder: "hello@gmail.com",
|
|
232
244
|
autoFocus: true,
|
|
@@ -283,12 +295,20 @@ function formatClassTime(cls) {
|
|
|
283
295
|
const em = endTotal % 60;
|
|
284
296
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
285
297
|
}
|
|
298
|
+
function formatBookingLabel(cls) {
|
|
299
|
+
const price = cls.price;
|
|
300
|
+
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
301
|
+
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
302
|
+
}
|
|
286
303
|
function getBookingsOnDate(cls, date) {
|
|
287
304
|
if (!cls.bookings?.length) return 0;
|
|
288
|
-
const
|
|
305
|
+
const target = new Date(date);
|
|
306
|
+
target.setHours(0, 0, 0, 0);
|
|
289
307
|
return cls.bookings.filter((b) => {
|
|
290
308
|
try {
|
|
291
|
-
|
|
309
|
+
const bookingDate = new Date(b.classDate);
|
|
310
|
+
bookingDate.setHours(0, 0, 0, 0);
|
|
311
|
+
return bookingDate.getTime() === target.getTime();
|
|
292
312
|
} catch {
|
|
293
313
|
return false;
|
|
294
314
|
}
|
|
@@ -553,7 +573,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
553
573
|
}
|
|
554
574
|
)
|
|
555
575
|
] }),
|
|
556
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
576
|
+
cls.showAvailability !== false && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
557
577
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
558
578
|
available,
|
|
559
579
|
"/",
|
|
@@ -565,9 +585,10 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
565
585
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
566
586
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
567
587
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
568
|
-
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
588
|
+
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName }),
|
|
589
|
+
cls.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm font-normal text-(--color-dark,#200C02) opacity-70 block truncate", children: cls.description })
|
|
569
590
|
] }),
|
|
570
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
591
|
+
cls.showAvailability !== false && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
571
592
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
572
593
|
available,
|
|
573
594
|
"/",
|
|
@@ -592,7 +613,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
592
613
|
if (!cls.id) return;
|
|
593
614
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
594
615
|
},
|
|
595
|
-
children: isFull ? "Join Waitlist" :
|
|
616
|
+
children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
|
|
596
617
|
}
|
|
597
618
|
)
|
|
598
619
|
] })
|
|
@@ -634,6 +655,17 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
634
655
|
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
635
656
|
const [modalState, setModalState] = (0, import_react3.useState)(null);
|
|
636
657
|
const switchScheduleIdRef = (0, import_react3.useRef)(null);
|
|
658
|
+
const liveScheduleIdRef = (0, import_react3.useRef)(null);
|
|
659
|
+
const refetchLiveSchedule = (0, import_react3.useCallback)(async () => {
|
|
660
|
+
const id = liveScheduleIdRef.current;
|
|
661
|
+
if (!id) return;
|
|
662
|
+
try {
|
|
663
|
+
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
664
|
+
const data = await res.json();
|
|
665
|
+
if (data?.id) setSchedule(data);
|
|
666
|
+
} catch {
|
|
667
|
+
}
|
|
668
|
+
}, []);
|
|
637
669
|
const dates = (0, import_react3.useMemo)(() => {
|
|
638
670
|
const today = /* @__PURE__ */ new Date();
|
|
639
671
|
today.setHours(0, 0, 0, 0);
|
|
@@ -653,6 +685,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
653
685
|
}
|
|
654
686
|
}
|
|
655
687
|
}, [schedule, dates]);
|
|
688
|
+
(0, import_react3.useEffect)(() => {
|
|
689
|
+
if (typeof window === "undefined") return;
|
|
690
|
+
const onVisible = () => {
|
|
691
|
+
if (!document.hidden) void refetchLiveSchedule();
|
|
692
|
+
};
|
|
693
|
+
window.addEventListener("focus", refetchLiveSchedule);
|
|
694
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
695
|
+
return () => {
|
|
696
|
+
window.removeEventListener("focus", refetchLiveSchedule);
|
|
697
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
698
|
+
};
|
|
699
|
+
}, [refetchLiveSchedule]);
|
|
656
700
|
(0, import_react3.useEffect)(() => {
|
|
657
701
|
if (typeof window === "undefined") return;
|
|
658
702
|
const isInEditor = window.self !== window.top;
|
|
@@ -714,7 +758,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
714
758
|
setLoading(false);
|
|
715
759
|
return;
|
|
716
760
|
}
|
|
717
|
-
;
|
|
761
|
+
liveScheduleIdRef.current = effectiveId;
|
|
718
762
|
(async () => {
|
|
719
763
|
try {
|
|
720
764
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -771,18 +815,14 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
771
815
|
const data = await res.json().catch(() => ({}));
|
|
772
816
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
773
817
|
}
|
|
818
|
+
await refetchLiveSchedule();
|
|
774
819
|
};
|
|
775
820
|
const handleReplaceSchedule = () => {
|
|
776
821
|
setIsHovered(false);
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
insertAfter
|
|
782
|
-
}, "*");
|
|
783
|
-
} else {
|
|
784
|
-
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
785
|
-
}
|
|
822
|
+
window.parent.postMessage(
|
|
823
|
+
{ type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
|
|
824
|
+
"*"
|
|
825
|
+
);
|
|
786
826
|
};
|
|
787
827
|
if (!inEditor && !loading && !schedule) return null;
|
|
788
828
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -825,7 +865,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
825
865
|
),
|
|
826
866
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
827
867
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
828
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
868
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
869
|
+
"h2",
|
|
870
|
+
{
|
|
871
|
+
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
872
|
+
style: {
|
|
873
|
+
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
874
|
+
fontWeight: "var(--font-weight-heading, 400)",
|
|
875
|
+
lineHeight: 1.05,
|
|
876
|
+
letterSpacing: "-0.02em"
|
|
877
|
+
},
|
|
878
|
+
children: schedule?.name ?? "Book an appointment"
|
|
879
|
+
}
|
|
880
|
+
),
|
|
829
881
|
schedule?.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
830
882
|
] }),
|
|
831
883
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4503,7 +4555,7 @@ function getChromeStyle(state) {
|
|
|
4503
4555
|
case "dragging":
|
|
4504
4556
|
return {
|
|
4505
4557
|
border: `2px solid ${PRIMARY}`,
|
|
4506
|
-
boxShadow: DRAG_SHADOW
|
|
4558
|
+
boxShadow: `${FOCUS_RING}, ${DRAG_SHADOW}`
|
|
4507
4559
|
};
|
|
4508
4560
|
default:
|
|
4509
4561
|
return {};
|
|
@@ -4519,6 +4571,8 @@ function ItemInteractionLayer({
|
|
|
4519
4571
|
dragHandleLabel = "Reorder item",
|
|
4520
4572
|
onDragHandleDragStart,
|
|
4521
4573
|
onDragHandleDragEnd,
|
|
4574
|
+
onItemPointerDown,
|
|
4575
|
+
onItemClick,
|
|
4522
4576
|
chromeGap = 6,
|
|
4523
4577
|
className
|
|
4524
4578
|
}) {
|
|
@@ -4526,7 +4580,8 @@ function ItemInteractionLayer({
|
|
|
4526
4580
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4527
4581
|
const isDragging = state === "dragging";
|
|
4528
4582
|
const showToolbar = isActive && toolbar;
|
|
4529
|
-
const showDragHandle = isActive
|
|
4583
|
+
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
4584
|
+
const itemDragEnabled = isActive && showHandle && !isDragging && !dragDisabled;
|
|
4530
4585
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4531
4586
|
"div",
|
|
4532
4587
|
{
|
|
@@ -4551,11 +4606,28 @@ function ItemInteractionLayer({
|
|
|
4551
4606
|
style: getChromeStyle(state)
|
|
4552
4607
|
}
|
|
4553
4608
|
),
|
|
4609
|
+
itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4610
|
+
"div",
|
|
4611
|
+
{
|
|
4612
|
+
"data-ohw-item-drag-surface": "",
|
|
4613
|
+
className: "pointer-events-auto absolute inset-0 cursor-grab rounded-lg active:cursor-grabbing",
|
|
4614
|
+
onPointerDown: (e) => {
|
|
4615
|
+
if (e.button !== 0) return;
|
|
4616
|
+
onItemPointerDown?.(e);
|
|
4617
|
+
},
|
|
4618
|
+
onClick: (e) => {
|
|
4619
|
+
e.preventDefault();
|
|
4620
|
+
e.stopPropagation();
|
|
4621
|
+
onItemClick?.(e.clientX, e.clientY);
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
),
|
|
4554
4625
|
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4555
4626
|
"div",
|
|
4556
4627
|
{
|
|
4557
4628
|
"data-ohw-drag-handle-container": "",
|
|
4558
|
-
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4629
|
+
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4630
|
+
style: isDragging ? { visibility: "hidden" } : void 0,
|
|
4559
4631
|
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4560
4632
|
DragHandle,
|
|
4561
4633
|
{
|
|
@@ -4778,15 +4850,12 @@ function MediaOverlay({
|
|
|
4778
4850
|
className: "flex items-center justify-center cursor-pointer",
|
|
4779
4851
|
style: {
|
|
4780
4852
|
...box,
|
|
4781
|
-
//
|
|
4782
|
-
//
|
|
4783
|
-
|
|
4784
|
-
// Replace still works.
|
|
4785
|
-
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4853
|
+
// Keep the full-size visual overlay click-through so carousel controls and editable
|
|
4854
|
+
// content underneath remain interactive. The Replace button opts back in below.
|
|
4855
|
+
pointerEvents: "none",
|
|
4786
4856
|
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4787
4857
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4788
4858
|
},
|
|
4789
|
-
onClick: () => onReplace(hover.key),
|
|
4790
4859
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4791
4860
|
Button,
|
|
4792
4861
|
{
|
|
@@ -4811,6 +4880,61 @@ function MediaOverlay({
|
|
|
4811
4880
|
] });
|
|
4812
4881
|
}
|
|
4813
4882
|
|
|
4883
|
+
// src/ui/CarouselOverlay.tsx
|
|
4884
|
+
var import_lucide_react4 = require("lucide-react");
|
|
4885
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4886
|
+
var OVERLAY_BUTTON_STYLE2 = {
|
|
4887
|
+
pointerEvents: "auto",
|
|
4888
|
+
fontFamily: "Inter, sans-serif",
|
|
4889
|
+
fontSize: 12,
|
|
4890
|
+
color: "#000"
|
|
4891
|
+
};
|
|
4892
|
+
function CarouselOverlay({
|
|
4893
|
+
hover,
|
|
4894
|
+
onEdit
|
|
4895
|
+
}) {
|
|
4896
|
+
const { rect } = hover;
|
|
4897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4898
|
+
"div",
|
|
4899
|
+
{
|
|
4900
|
+
"data-ohw-bridge": "",
|
|
4901
|
+
"data-ohw-carousel-overlay": "",
|
|
4902
|
+
className: "flex cursor-pointer items-center justify-center",
|
|
4903
|
+
style: {
|
|
4904
|
+
position: "fixed",
|
|
4905
|
+
top: rect.top,
|
|
4906
|
+
left: rect.left,
|
|
4907
|
+
width: rect.width,
|
|
4908
|
+
height: rect.height,
|
|
4909
|
+
zIndex: 2147483646,
|
|
4910
|
+
pointerEvents: "auto",
|
|
4911
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4912
|
+
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4913
|
+
},
|
|
4914
|
+
onClick: () => onEdit(hover.key),
|
|
4915
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4916
|
+
Button,
|
|
4917
|
+
{
|
|
4918
|
+
"data-ohw-carousel-overlay": "",
|
|
4919
|
+
variant: "outline",
|
|
4920
|
+
size: "sm",
|
|
4921
|
+
className: "cursor-pointer gap-1.5 hover:bg-background",
|
|
4922
|
+
style: OVERLAY_BUTTON_STYLE2,
|
|
4923
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4924
|
+
onClick: (e) => {
|
|
4925
|
+
e.stopPropagation();
|
|
4926
|
+
onEdit(hover.key);
|
|
4927
|
+
},
|
|
4928
|
+
children: [
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.GalleryHorizontal, { size: 14 }),
|
|
4930
|
+
"Edit gallery"
|
|
4931
|
+
]
|
|
4932
|
+
}
|
|
4933
|
+
)
|
|
4934
|
+
}
|
|
4935
|
+
);
|
|
4936
|
+
}
|
|
4937
|
+
|
|
4814
4938
|
// src/OhhwellsBridge.tsx
|
|
4815
4939
|
var import_react_dom3 = require("react-dom");
|
|
4816
4940
|
var import_navigation2 = require("next/navigation");
|
|
@@ -5096,23 +5220,23 @@ var import_react7 = require("react");
|
|
|
5096
5220
|
// src/ui/dialog.tsx
|
|
5097
5221
|
var React7 = __toESM(require("react"), 1);
|
|
5098
5222
|
var import_radix_ui5 = require("radix-ui");
|
|
5099
|
-
var
|
|
5100
|
-
var
|
|
5223
|
+
var import_lucide_react5 = require("lucide-react");
|
|
5224
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
5101
5225
|
function Dialog2({
|
|
5102
5226
|
...props
|
|
5103
5227
|
}) {
|
|
5104
|
-
return /* @__PURE__ */ (0,
|
|
5228
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
5105
5229
|
}
|
|
5106
5230
|
function DialogPortal({
|
|
5107
5231
|
...props
|
|
5108
5232
|
}) {
|
|
5109
|
-
return /* @__PURE__ */ (0,
|
|
5233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
|
|
5110
5234
|
}
|
|
5111
5235
|
function DialogOverlay({
|
|
5112
5236
|
className,
|
|
5113
5237
|
...props
|
|
5114
5238
|
}) {
|
|
5115
|
-
return /* @__PURE__ */ (0,
|
|
5239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5116
5240
|
import_radix_ui5.Dialog.Overlay,
|
|
5117
5241
|
{
|
|
5118
5242
|
"data-slot": "dialog-overlay",
|
|
@@ -5125,9 +5249,9 @@ function DialogOverlay({
|
|
|
5125
5249
|
var DialogContent = React7.forwardRef(
|
|
5126
5250
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5127
5251
|
const positionMode = container ? "absolute" : "fixed";
|
|
5128
|
-
return /* @__PURE__ */ (0,
|
|
5129
|
-
/* @__PURE__ */ (0,
|
|
5130
|
-
/* @__PURE__ */ (0,
|
|
5252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
5253
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5254
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
5131
5255
|
import_radix_ui5.Dialog.Content,
|
|
5132
5256
|
{
|
|
5133
5257
|
ref,
|
|
@@ -5143,13 +5267,13 @@ var DialogContent = React7.forwardRef(
|
|
|
5143
5267
|
...props,
|
|
5144
5268
|
children: [
|
|
5145
5269
|
children,
|
|
5146
|
-
showCloseButton ? /* @__PURE__ */ (0,
|
|
5270
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5147
5271
|
import_radix_ui5.Dialog.Close,
|
|
5148
5272
|
{
|
|
5149
5273
|
type: "button",
|
|
5150
5274
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5151
5275
|
"aria-label": "Close",
|
|
5152
|
-
children: /* @__PURE__ */ (0,
|
|
5276
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.X, { size: 16, "aria-hidden": true })
|
|
5153
5277
|
}
|
|
5154
5278
|
) : null
|
|
5155
5279
|
]
|
|
@@ -5163,13 +5287,13 @@ function DialogHeader({
|
|
|
5163
5287
|
className,
|
|
5164
5288
|
...props
|
|
5165
5289
|
}) {
|
|
5166
|
-
return /* @__PURE__ */ (0,
|
|
5290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5167
5291
|
}
|
|
5168
5292
|
function DialogFooter({
|
|
5169
5293
|
className,
|
|
5170
5294
|
...props
|
|
5171
5295
|
}) {
|
|
5172
|
-
return /* @__PURE__ */ (0,
|
|
5296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5173
5297
|
"div",
|
|
5174
5298
|
{
|
|
5175
5299
|
className: cn("flex items-center justify-end gap-2", className),
|
|
@@ -5177,7 +5301,7 @@ function DialogFooter({
|
|
|
5177
5301
|
}
|
|
5178
5302
|
);
|
|
5179
5303
|
}
|
|
5180
|
-
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
5304
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5181
5305
|
import_radix_ui5.Dialog.Title,
|
|
5182
5306
|
{
|
|
5183
5307
|
ref,
|
|
@@ -5189,7 +5313,7 @@ var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5189
5313
|
}
|
|
5190
5314
|
));
|
|
5191
5315
|
DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
|
|
5192
|
-
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
5316
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5193
5317
|
import_radix_ui5.Dialog.Description,
|
|
5194
5318
|
{
|
|
5195
5319
|
ref,
|
|
@@ -5201,63 +5325,63 @@ DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
|
|
|
5201
5325
|
var DialogClose = import_radix_ui5.Dialog.Close;
|
|
5202
5326
|
|
|
5203
5327
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5204
|
-
var
|
|
5328
|
+
var import_lucide_react9 = require("lucide-react");
|
|
5205
5329
|
|
|
5206
5330
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5207
|
-
var
|
|
5208
|
-
var
|
|
5331
|
+
var import_lucide_react6 = require("lucide-react");
|
|
5332
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5209
5333
|
function DestinationBreadcrumb({
|
|
5210
5334
|
pageTitle,
|
|
5211
5335
|
sectionLabel
|
|
5212
5336
|
}) {
|
|
5213
|
-
return /* @__PURE__ */ (0,
|
|
5214
|
-
/* @__PURE__ */ (0,
|
|
5215
|
-
/* @__PURE__ */ (0,
|
|
5216
|
-
/* @__PURE__ */ (0,
|
|
5217
|
-
/* @__PURE__ */ (0,
|
|
5218
|
-
/* @__PURE__ */ (0,
|
|
5337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5338
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5339
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5340
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5341
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react6.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5342
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5219
5343
|
] }),
|
|
5220
|
-
/* @__PURE__ */ (0,
|
|
5221
|
-
|
|
5344
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5345
|
+
import_lucide_react6.ArrowRight,
|
|
5222
5346
|
{
|
|
5223
5347
|
size: 16,
|
|
5224
5348
|
className: "shrink-0 text-muted-foreground",
|
|
5225
5349
|
"aria-hidden": true
|
|
5226
5350
|
}
|
|
5227
5351
|
),
|
|
5228
|
-
/* @__PURE__ */ (0,
|
|
5229
|
-
/* @__PURE__ */ (0,
|
|
5230
|
-
|
|
5352
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5353
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5354
|
+
import_lucide_react6.GalleryVertical,
|
|
5231
5355
|
{
|
|
5232
5356
|
size: 16,
|
|
5233
5357
|
className: "shrink-0 text-foreground",
|
|
5234
5358
|
"aria-hidden": true
|
|
5235
5359
|
}
|
|
5236
5360
|
),
|
|
5237
|
-
/* @__PURE__ */ (0,
|
|
5361
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5238
5362
|
] })
|
|
5239
5363
|
] })
|
|
5240
5364
|
] });
|
|
5241
5365
|
}
|
|
5242
5366
|
|
|
5243
5367
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5244
|
-
var
|
|
5245
|
-
var
|
|
5368
|
+
var import_lucide_react7 = require("lucide-react");
|
|
5369
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5246
5370
|
function SectionTreeItem({
|
|
5247
5371
|
section,
|
|
5248
5372
|
onSelect,
|
|
5249
5373
|
selected
|
|
5250
5374
|
}) {
|
|
5251
5375
|
const interactive = Boolean(onSelect);
|
|
5252
|
-
return /* @__PURE__ */ (0,
|
|
5253
|
-
/* @__PURE__ */ (0,
|
|
5376
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5377
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5254
5378
|
"div",
|
|
5255
5379
|
{
|
|
5256
5380
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
5257
5381
|
"aria-hidden": true
|
|
5258
5382
|
}
|
|
5259
5383
|
),
|
|
5260
|
-
/* @__PURE__ */ (0,
|
|
5384
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5261
5385
|
"div",
|
|
5262
5386
|
{
|
|
5263
5387
|
role: interactive ? "button" : void 0,
|
|
@@ -5275,15 +5399,15 @@ function SectionTreeItem({
|
|
|
5275
5399
|
interactive && selected && "border-primary"
|
|
5276
5400
|
),
|
|
5277
5401
|
children: [
|
|
5278
|
-
/* @__PURE__ */ (0,
|
|
5279
|
-
|
|
5402
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5403
|
+
import_lucide_react7.GalleryVertical,
|
|
5280
5404
|
{
|
|
5281
5405
|
size: 16,
|
|
5282
5406
|
className: "shrink-0 text-foreground",
|
|
5283
5407
|
"aria-hidden": true
|
|
5284
5408
|
}
|
|
5285
5409
|
),
|
|
5286
|
-
/* @__PURE__ */ (0,
|
|
5410
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5287
5411
|
]
|
|
5288
5412
|
}
|
|
5289
5413
|
)
|
|
@@ -5295,10 +5419,10 @@ var import_react4 = require("react");
|
|
|
5295
5419
|
|
|
5296
5420
|
// src/ui/input.tsx
|
|
5297
5421
|
var React8 = __toESM(require("react"), 1);
|
|
5298
|
-
var
|
|
5422
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5299
5423
|
var Input = React8.forwardRef(
|
|
5300
5424
|
({ className, type, ...props }, ref) => {
|
|
5301
|
-
return /* @__PURE__ */ (0,
|
|
5425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5302
5426
|
"input",
|
|
5303
5427
|
{
|
|
5304
5428
|
type,
|
|
@@ -5317,9 +5441,9 @@ Input.displayName = "Input";
|
|
|
5317
5441
|
|
|
5318
5442
|
// src/ui/label.tsx
|
|
5319
5443
|
var import_radix_ui6 = require("radix-ui");
|
|
5320
|
-
var
|
|
5444
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5321
5445
|
function Label({ className, ...props }) {
|
|
5322
|
-
return /* @__PURE__ */ (0,
|
|
5446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5323
5447
|
import_radix_ui6.Label.Root,
|
|
5324
5448
|
{
|
|
5325
5449
|
"data-slot": "label",
|
|
@@ -5330,12 +5454,12 @@ function Label({ className, ...props }) {
|
|
|
5330
5454
|
}
|
|
5331
5455
|
|
|
5332
5456
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5333
|
-
var
|
|
5334
|
-
var
|
|
5457
|
+
var import_lucide_react8 = require("lucide-react");
|
|
5458
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5335
5459
|
function FieldChevron({
|
|
5336
5460
|
onClick
|
|
5337
5461
|
}) {
|
|
5338
|
-
return /* @__PURE__ */ (0,
|
|
5462
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5339
5463
|
"button",
|
|
5340
5464
|
{
|
|
5341
5465
|
type: "button",
|
|
@@ -5343,7 +5467,7 @@ function FieldChevron({
|
|
|
5343
5467
|
onClick,
|
|
5344
5468
|
"aria-label": "Open page list",
|
|
5345
5469
|
tabIndex: -1,
|
|
5346
|
-
children: /* @__PURE__ */ (0,
|
|
5470
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.ChevronDown, { size: 16 })
|
|
5347
5471
|
}
|
|
5348
5472
|
);
|
|
5349
5473
|
}
|
|
@@ -5404,19 +5528,19 @@ function UrlOrPageInput({
|
|
|
5404
5528
|
"data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
5405
5529
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5406
5530
|
);
|
|
5407
|
-
return /* @__PURE__ */ (0,
|
|
5408
|
-
/* @__PURE__ */ (0,
|
|
5409
|
-
/* @__PURE__ */ (0,
|
|
5410
|
-
/* @__PURE__ */ (0,
|
|
5411
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
5412
|
-
|
|
5531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5532
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5533
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5534
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5535
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5536
|
+
import_lucide_react8.File,
|
|
5413
5537
|
{
|
|
5414
5538
|
size: 16,
|
|
5415
5539
|
className: "shrink-0 text-foreground",
|
|
5416
5540
|
"aria-hidden": true
|
|
5417
5541
|
}
|
|
5418
5542
|
) }) : null,
|
|
5419
|
-
readOnly ? /* @__PURE__ */ (0,
|
|
5543
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5420
5544
|
Input,
|
|
5421
5545
|
{
|
|
5422
5546
|
ref: inputRef,
|
|
@@ -5442,7 +5566,7 @@ function UrlOrPageInput({
|
|
|
5442
5566
|
)
|
|
5443
5567
|
}
|
|
5444
5568
|
),
|
|
5445
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
5569
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5446
5570
|
"button",
|
|
5447
5571
|
{
|
|
5448
5572
|
type: "button",
|
|
@@ -5450,26 +5574,26 @@ function UrlOrPageInput({
|
|
|
5450
5574
|
onMouseDown: clearSelection,
|
|
5451
5575
|
"aria-label": "Clear selected page",
|
|
5452
5576
|
tabIndex: -1,
|
|
5453
|
-
children: /* @__PURE__ */ (0,
|
|
5577
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
5454
5578
|
}
|
|
5455
5579
|
) : null,
|
|
5456
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
5580
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
5457
5581
|
] }),
|
|
5458
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
5582
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5459
5583
|
"div",
|
|
5460
5584
|
{
|
|
5461
5585
|
"data-ohw-link-page-dropdown": "",
|
|
5462
5586
|
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5463
5587
|
onMouseDown: (e) => e.preventDefault(),
|
|
5464
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
5588
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
5465
5589
|
"button",
|
|
5466
5590
|
{
|
|
5467
5591
|
type: "button",
|
|
5468
5592
|
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",
|
|
5469
5593
|
onClick: () => onPageSelect(page),
|
|
5470
5594
|
children: [
|
|
5471
|
-
/* @__PURE__ */ (0,
|
|
5472
|
-
/* @__PURE__ */ (0,
|
|
5595
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5596
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: page.title })
|
|
5473
5597
|
]
|
|
5474
5598
|
},
|
|
5475
5599
|
page.path
|
|
@@ -5477,34 +5601,34 @@ function UrlOrPageInput({
|
|
|
5477
5601
|
}
|
|
5478
5602
|
) : null
|
|
5479
5603
|
] }),
|
|
5480
|
-
urlError ? /* @__PURE__ */ (0,
|
|
5604
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
5481
5605
|
] });
|
|
5482
5606
|
}
|
|
5483
5607
|
|
|
5484
5608
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5485
|
-
var
|
|
5609
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5486
5610
|
function LinkEditorPanel({ state, onClose }) {
|
|
5487
5611
|
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5488
|
-
return /* @__PURE__ */ (0,
|
|
5489
|
-
/* @__PURE__ */ (0,
|
|
5612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5613
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5490
5614
|
"button",
|
|
5491
5615
|
{
|
|
5492
5616
|
type: "button",
|
|
5493
5617
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5494
5618
|
"aria-label": "Close",
|
|
5495
5619
|
onClick: onClose,
|
|
5496
|
-
children: /* @__PURE__ */ (0,
|
|
5620
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.X, { size: 16, "aria-hidden": true })
|
|
5497
5621
|
}
|
|
5498
5622
|
) }),
|
|
5499
|
-
/* @__PURE__ */ (0,
|
|
5500
|
-
/* @__PURE__ */ (0,
|
|
5501
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5623
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5624
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5625
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5502
5626
|
DestinationBreadcrumb,
|
|
5503
5627
|
{
|
|
5504
5628
|
pageTitle: state.selectedPage.title,
|
|
5505
5629
|
sectionLabel: state.selectedSection.label
|
|
5506
5630
|
}
|
|
5507
|
-
) : /* @__PURE__ */ (0,
|
|
5631
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5508
5632
|
UrlOrPageInput,
|
|
5509
5633
|
{
|
|
5510
5634
|
value: state.searchValue,
|
|
@@ -5517,8 +5641,8 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5517
5641
|
urlError: state.urlError
|
|
5518
5642
|
}
|
|
5519
5643
|
),
|
|
5520
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
5521
|
-
/* @__PURE__ */ (0,
|
|
5644
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5645
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5522
5646
|
Button,
|
|
5523
5647
|
{
|
|
5524
5648
|
type: "button",
|
|
@@ -5529,15 +5653,15 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5529
5653
|
children: "Choose a section"
|
|
5530
5654
|
}
|
|
5531
5655
|
),
|
|
5532
|
-
/* @__PURE__ */ (0,
|
|
5533
|
-
/* @__PURE__ */ (0,
|
|
5534
|
-
/* @__PURE__ */ (0,
|
|
5656
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5657
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5658
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5535
5659
|
] })
|
|
5536
5660
|
] }) : null,
|
|
5537
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5661
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5538
5662
|
] }),
|
|
5539
|
-
/* @__PURE__ */ (0,
|
|
5540
|
-
/* @__PURE__ */ (0,
|
|
5663
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5664
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5541
5665
|
Button,
|
|
5542
5666
|
{
|
|
5543
5667
|
type: "button",
|
|
@@ -5552,7 +5676,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5552
5676
|
children: state.secondaryLabel
|
|
5553
5677
|
}
|
|
5554
5678
|
),
|
|
5555
|
-
/* @__PURE__ */ (0,
|
|
5679
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5556
5680
|
Button,
|
|
5557
5681
|
{
|
|
5558
5682
|
type: "button",
|
|
@@ -5573,9 +5697,9 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5573
5697
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5574
5698
|
var import_react5 = require("react");
|
|
5575
5699
|
var import_react_dom = require("react-dom");
|
|
5576
|
-
var
|
|
5700
|
+
var import_lucide_react10 = require("lucide-react");
|
|
5577
5701
|
var import_navigation = require("next/navigation");
|
|
5578
|
-
var
|
|
5702
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5579
5703
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5580
5704
|
function rectsEqual(a, b) {
|
|
5581
5705
|
if (a.size !== b.size) return false;
|
|
@@ -5804,7 +5928,7 @@ function SectionPickerOverlay({
|
|
|
5804
5928
|
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5805
5929
|
if (!portalRoot) return null;
|
|
5806
5930
|
return (0, import_react_dom.createPortal)(
|
|
5807
|
-
/* @__PURE__ */ (0,
|
|
5931
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5808
5932
|
"div",
|
|
5809
5933
|
{
|
|
5810
5934
|
"data-ohw-section-picker": "",
|
|
@@ -5814,12 +5938,12 @@ function SectionPickerOverlay({
|
|
|
5814
5938
|
role: "dialog",
|
|
5815
5939
|
"aria-label": "Choose a section",
|
|
5816
5940
|
children: [
|
|
5817
|
-
/* @__PURE__ */ (0,
|
|
5941
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5818
5942
|
"div",
|
|
5819
5943
|
{
|
|
5820
5944
|
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5821
5945
|
style: { top: chromeClip.top + 20 },
|
|
5822
|
-
children: /* @__PURE__ */ (0,
|
|
5946
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5823
5947
|
Button,
|
|
5824
5948
|
{
|
|
5825
5949
|
type: "button",
|
|
@@ -5828,14 +5952,14 @@ function SectionPickerOverlay({
|
|
|
5828
5952
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5829
5953
|
onClick: onBack,
|
|
5830
5954
|
children: [
|
|
5831
|
-
/* @__PURE__ */ (0,
|
|
5955
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5832
5956
|
"Back"
|
|
5833
5957
|
]
|
|
5834
5958
|
}
|
|
5835
5959
|
)
|
|
5836
5960
|
}
|
|
5837
5961
|
),
|
|
5838
|
-
/* @__PURE__ */ (0,
|
|
5962
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5839
5963
|
"div",
|
|
5840
5964
|
{
|
|
5841
5965
|
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",
|
|
@@ -5848,7 +5972,7 @@ function SectionPickerOverlay({
|
|
|
5848
5972
|
children: "Click on section to select"
|
|
5849
5973
|
}
|
|
5850
5974
|
),
|
|
5851
|
-
!isOnTargetPage ? /* @__PURE__ */ (0,
|
|
5975
|
+
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5852
5976
|
"div",
|
|
5853
5977
|
{
|
|
5854
5978
|
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",
|
|
@@ -5856,14 +5980,14 @@ function SectionPickerOverlay({
|
|
|
5856
5980
|
children: "Loading page preview\u2026"
|
|
5857
5981
|
}
|
|
5858
5982
|
) : null,
|
|
5859
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0,
|
|
5983
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5860
5984
|
isOnTargetPage ? liveSections.map((section) => {
|
|
5861
5985
|
const rect = rects.get(section.id);
|
|
5862
5986
|
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5863
5987
|
const isSelected = selectedId === section.id;
|
|
5864
5988
|
const isHovered = hoveredId === section.id;
|
|
5865
5989
|
const isLit = isSelected || isHovered;
|
|
5866
|
-
return /* @__PURE__ */ (0,
|
|
5990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5867
5991
|
"button",
|
|
5868
5992
|
{
|
|
5869
5993
|
type: "button",
|
|
@@ -5878,7 +6002,7 @@ function SectionPickerOverlay({
|
|
|
5878
6002
|
"aria-label": `Select section ${section.label}`,
|
|
5879
6003
|
onClick: () => handleSelect(section),
|
|
5880
6004
|
children: [
|
|
5881
|
-
isLit ? /* @__PURE__ */ (0,
|
|
6005
|
+
isLit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5882
6006
|
"span",
|
|
5883
6007
|
{
|
|
5884
6008
|
className: "pointer-events-none absolute",
|
|
@@ -5891,13 +6015,13 @@ function SectionPickerOverlay({
|
|
|
5891
6015
|
"aria-hidden": true
|
|
5892
6016
|
}
|
|
5893
6017
|
) : null,
|
|
5894
|
-
isSelected ? /* @__PURE__ */ (0,
|
|
6018
|
+
isSelected ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5895
6019
|
"span",
|
|
5896
6020
|
{
|
|
5897
6021
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5898
6022
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5899
6023
|
"aria-hidden": true,
|
|
5900
|
-
children: /* @__PURE__ */ (0,
|
|
6024
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Check, { className: "size-5" })
|
|
5901
6025
|
}
|
|
5902
6026
|
) : null
|
|
5903
6027
|
]
|
|
@@ -6077,7 +6201,7 @@ function useLinkModalState({
|
|
|
6077
6201
|
}
|
|
6078
6202
|
|
|
6079
6203
|
// src/ui/link-modal/LinkPopover.tsx
|
|
6080
|
-
var
|
|
6204
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6081
6205
|
function postToParent(data) {
|
|
6082
6206
|
window.parent?.postMessage(data, "*");
|
|
6083
6207
|
}
|
|
@@ -6173,15 +6297,15 @@ function LinkPopover({
|
|
|
6173
6297
|
);
|
|
6174
6298
|
};
|
|
6175
6299
|
}, [open, sectionPickerActive]);
|
|
6176
|
-
return /* @__PURE__ */ (0,
|
|
6177
|
-
/* @__PURE__ */ (0,
|
|
6300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6301
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6178
6302
|
Dialog2,
|
|
6179
6303
|
{
|
|
6180
6304
|
open: open && !sectionPickerActive,
|
|
6181
6305
|
onOpenChange: (next) => {
|
|
6182
6306
|
if (!next) onClose?.();
|
|
6183
6307
|
},
|
|
6184
|
-
children: /* @__PURE__ */ (0,
|
|
6308
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6185
6309
|
DialogContent,
|
|
6186
6310
|
{
|
|
6187
6311
|
ref: panelRef,
|
|
@@ -6191,12 +6315,12 @@ function LinkPopover({
|
|
|
6191
6315
|
"data-ohw-bridge": "",
|
|
6192
6316
|
showCloseButton: false,
|
|
6193
6317
|
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6194
|
-
children: /* @__PURE__ */ (0,
|
|
6318
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LinkEditorPanel, { state, onClose })
|
|
6195
6319
|
}
|
|
6196
6320
|
)
|
|
6197
6321
|
}
|
|
6198
6322
|
),
|
|
6199
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0,
|
|
6323
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6200
6324
|
SectionPickerOverlay,
|
|
6201
6325
|
{
|
|
6202
6326
|
pagePath: state.selectedPage.path,
|
|
@@ -6502,15 +6626,412 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6502
6626
|
};
|
|
6503
6627
|
}
|
|
6504
6628
|
|
|
6629
|
+
// src/lib/footer-items.ts
|
|
6630
|
+
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6631
|
+
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6632
|
+
function parseFooterHrefKey(key) {
|
|
6633
|
+
if (!key) return null;
|
|
6634
|
+
const match = key.match(FOOTER_HREF_RE);
|
|
6635
|
+
if (!match) return null;
|
|
6636
|
+
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6637
|
+
}
|
|
6638
|
+
function isFooterHrefKey(key) {
|
|
6639
|
+
return parseFooterHrefKey(key) !== null;
|
|
6640
|
+
}
|
|
6641
|
+
function getFooterRoot() {
|
|
6642
|
+
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6643
|
+
}
|
|
6644
|
+
function getFooterLinksContainer() {
|
|
6645
|
+
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6646
|
+
}
|
|
6647
|
+
function isFooterLinkAnchor(el) {
|
|
6648
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6649
|
+
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6650
|
+
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6651
|
+
}
|
|
6652
|
+
function listFooterColumns() {
|
|
6653
|
+
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6654
|
+
if (!root) return [];
|
|
6655
|
+
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6656
|
+
if (explicit.length > 0) return explicit;
|
|
6657
|
+
return Array.from(root.children).filter((el) => {
|
|
6658
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
6659
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6660
|
+
isFooterLinkAnchor
|
|
6661
|
+
);
|
|
6662
|
+
});
|
|
6663
|
+
}
|
|
6664
|
+
function listFooterLinksInColumn(column) {
|
|
6665
|
+
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6666
|
+
isFooterLinkAnchor
|
|
6667
|
+
);
|
|
6668
|
+
}
|
|
6669
|
+
function findFooterColumnForLink(anchor) {
|
|
6670
|
+
const columns = listFooterColumns();
|
|
6671
|
+
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6672
|
+
}
|
|
6673
|
+
function getFooterOrderFromDom() {
|
|
6674
|
+
return listFooterColumns().map(
|
|
6675
|
+
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6676
|
+
);
|
|
6677
|
+
}
|
|
6678
|
+
function findFooterLinkByKey(hrefKey) {
|
|
6679
|
+
return document.querySelector(
|
|
6680
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6681
|
+
);
|
|
6682
|
+
}
|
|
6683
|
+
function syncFooterColumnIndices(columns) {
|
|
6684
|
+
columns.forEach((col, index) => {
|
|
6685
|
+
const next = String(index);
|
|
6686
|
+
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6687
|
+
col.setAttribute("data-ohw-footer-col", next);
|
|
6688
|
+
}
|
|
6689
|
+
});
|
|
6690
|
+
}
|
|
6691
|
+
function appendChildIfNeeded(parent, child) {
|
|
6692
|
+
if (parent.lastElementChild !== child) {
|
|
6693
|
+
parent.appendChild(child);
|
|
6694
|
+
}
|
|
6695
|
+
}
|
|
6696
|
+
function insertLinkBeforeNext(col, el, nextEl) {
|
|
6697
|
+
if (nextEl) {
|
|
6698
|
+
if (el.nextElementSibling !== nextEl) {
|
|
6699
|
+
col.insertBefore(el, nextEl);
|
|
6700
|
+
}
|
|
6701
|
+
return;
|
|
6702
|
+
}
|
|
6703
|
+
if (col.lastElementChild !== el) {
|
|
6704
|
+
col.appendChild(el);
|
|
6705
|
+
}
|
|
6706
|
+
}
|
|
6707
|
+
function applyFooterOrder(order) {
|
|
6708
|
+
const container = getFooterLinksContainer();
|
|
6709
|
+
if (!container) return;
|
|
6710
|
+
const columns = listFooterColumns();
|
|
6711
|
+
if (columns.length === 0) return;
|
|
6712
|
+
const currentOrder = getFooterOrderFromDom();
|
|
6713
|
+
if (ordersEqual(order, currentOrder)) {
|
|
6714
|
+
syncFooterColumnIndices(columns);
|
|
6715
|
+
return;
|
|
6716
|
+
}
|
|
6717
|
+
const colCount = Math.max(columns.length, order.length);
|
|
6718
|
+
const working = columns.slice(0, colCount);
|
|
6719
|
+
for (let i = 0; i < order.length && i < working.length; i++) {
|
|
6720
|
+
appendChildIfNeeded(container, working[i]);
|
|
6721
|
+
}
|
|
6722
|
+
for (let i = order.length; i < working.length; i++) {
|
|
6723
|
+
appendChildIfNeeded(container, working[i]);
|
|
6724
|
+
}
|
|
6725
|
+
const freshColumns = listFooterColumns();
|
|
6726
|
+
syncFooterColumnIndices(freshColumns);
|
|
6727
|
+
for (let c = 0; c < order.length; c++) {
|
|
6728
|
+
const col = freshColumns[c];
|
|
6729
|
+
if (!col) continue;
|
|
6730
|
+
const colOrder = order[c];
|
|
6731
|
+
for (let j = 0; j < colOrder.length; j++) {
|
|
6732
|
+
const hrefKey = colOrder[j];
|
|
6733
|
+
const el = findFooterLinkByKey(hrefKey);
|
|
6734
|
+
if (!el) continue;
|
|
6735
|
+
if (el.parentElement !== col) {
|
|
6736
|
+
col.appendChild(el);
|
|
6737
|
+
}
|
|
6738
|
+
const nextKey = colOrder[j + 1];
|
|
6739
|
+
const nextEl = nextKey ? findFooterLinkByKey(nextKey) : null;
|
|
6740
|
+
insertLinkBeforeNext(col, el, nextEl?.parentElement === col ? nextEl : null);
|
|
6741
|
+
}
|
|
6742
|
+
}
|
|
6743
|
+
}
|
|
6744
|
+
function ordersEqual(a, b) {
|
|
6745
|
+
if (a.length !== b.length) return false;
|
|
6746
|
+
for (let i = 0; i < a.length; i++) {
|
|
6747
|
+
const left = a[i];
|
|
6748
|
+
const right = b[i];
|
|
6749
|
+
if (left.length !== right.length) return false;
|
|
6750
|
+
for (let j = 0; j < left.length; j++) {
|
|
6751
|
+
if (left[j] !== right[j]) return false;
|
|
6752
|
+
}
|
|
6753
|
+
}
|
|
6754
|
+
return true;
|
|
6755
|
+
}
|
|
6756
|
+
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6757
|
+
const order = getFooterOrderFromDom();
|
|
6758
|
+
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6759
|
+
let fromCol = -1;
|
|
6760
|
+
let fromIdx = -1;
|
|
6761
|
+
for (let c = 0; c < order.length; c++) {
|
|
6762
|
+
const idx = order[c].indexOf(hrefKey);
|
|
6763
|
+
if (idx >= 0) {
|
|
6764
|
+
fromCol = c;
|
|
6765
|
+
fromIdx = idx;
|
|
6766
|
+
break;
|
|
6767
|
+
}
|
|
6768
|
+
}
|
|
6769
|
+
if (fromCol < 0) return null;
|
|
6770
|
+
const next = order.map((col) => [...col]);
|
|
6771
|
+
next[fromCol].splice(fromIdx, 1);
|
|
6772
|
+
let adjusted = insertIndex;
|
|
6773
|
+
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6774
|
+
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6775
|
+
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6776
|
+
if (ordersEqual(next, order)) return null;
|
|
6777
|
+
return next;
|
|
6778
|
+
}
|
|
6779
|
+
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6780
|
+
const order = getFooterOrderFromDom();
|
|
6781
|
+
const columns = listFooterColumns();
|
|
6782
|
+
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6783
|
+
return null;
|
|
6784
|
+
}
|
|
6785
|
+
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6786
|
+
const nextOrder = order.map((col) => [...col]);
|
|
6787
|
+
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6788
|
+
if (!movedOrder) return null;
|
|
6789
|
+
let adjusted = toIndex;
|
|
6790
|
+
if (fromIndex < toIndex) adjusted -= 1;
|
|
6791
|
+
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6792
|
+
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6793
|
+
if (ordersEqual(nextOrder, order)) return null;
|
|
6794
|
+
return nextOrder;
|
|
6795
|
+
}
|
|
6796
|
+
function parseFooterOrder(content) {
|
|
6797
|
+
const raw = content[FOOTER_ORDER_KEY];
|
|
6798
|
+
if (!raw) return null;
|
|
6799
|
+
try {
|
|
6800
|
+
const parsed = JSON.parse(raw);
|
|
6801
|
+
if (!Array.isArray(parsed)) return null;
|
|
6802
|
+
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6803
|
+
} catch {
|
|
6804
|
+
return null;
|
|
6805
|
+
}
|
|
6806
|
+
}
|
|
6807
|
+
function reconcileFooterOrderFromContent(content) {
|
|
6808
|
+
const order = parseFooterOrder(content);
|
|
6809
|
+
if (!order?.length) return;
|
|
6810
|
+
const current = getFooterOrderFromDom();
|
|
6811
|
+
if (ordersEqual(order, current)) {
|
|
6812
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
6813
|
+
return;
|
|
6814
|
+
}
|
|
6815
|
+
applyFooterOrder(order);
|
|
6816
|
+
}
|
|
6817
|
+
function buildLinkDropSlots(column, columnIndex) {
|
|
6818
|
+
const links = listFooterLinksInColumn(column);
|
|
6819
|
+
const colRect = column.getBoundingClientRect();
|
|
6820
|
+
const slots = [];
|
|
6821
|
+
const barThickness = 3;
|
|
6822
|
+
if (links.length === 0) {
|
|
6823
|
+
slots.push({
|
|
6824
|
+
insertIndex: 0,
|
|
6825
|
+
columnIndex,
|
|
6826
|
+
left: colRect.left,
|
|
6827
|
+
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6828
|
+
width: colRect.width,
|
|
6829
|
+
height: barThickness,
|
|
6830
|
+
direction: "horizontal"
|
|
6831
|
+
});
|
|
6832
|
+
return slots;
|
|
6833
|
+
}
|
|
6834
|
+
for (let i = 0; i <= links.length; i++) {
|
|
6835
|
+
let top;
|
|
6836
|
+
if (i === 0) {
|
|
6837
|
+
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6838
|
+
} else if (i === links.length) {
|
|
6839
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
6840
|
+
top = last.bottom - barThickness / 2;
|
|
6841
|
+
} else {
|
|
6842
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
6843
|
+
const next = links[i].getBoundingClientRect();
|
|
6844
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6845
|
+
}
|
|
6846
|
+
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6847
|
+
slots.push({
|
|
6848
|
+
insertIndex: i,
|
|
6849
|
+
columnIndex,
|
|
6850
|
+
left: widthRef.left,
|
|
6851
|
+
top,
|
|
6852
|
+
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6853
|
+
height: barThickness,
|
|
6854
|
+
direction: "horizontal"
|
|
6855
|
+
});
|
|
6856
|
+
}
|
|
6857
|
+
return slots;
|
|
6858
|
+
}
|
|
6859
|
+
function buildColumnDropSlots() {
|
|
6860
|
+
const columns = listFooterColumns();
|
|
6861
|
+
const slots = [];
|
|
6862
|
+
const barThickness = 3;
|
|
6863
|
+
if (columns.length === 0) return slots;
|
|
6864
|
+
for (let i = 0; i <= columns.length; i++) {
|
|
6865
|
+
let left;
|
|
6866
|
+
let height;
|
|
6867
|
+
let top;
|
|
6868
|
+
if (i === 0) {
|
|
6869
|
+
const first = columns[0].getBoundingClientRect();
|
|
6870
|
+
left = first.left - barThickness / 2;
|
|
6871
|
+
top = first.top;
|
|
6872
|
+
height = first.height;
|
|
6873
|
+
} else if (i === columns.length) {
|
|
6874
|
+
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
6875
|
+
left = last.right - barThickness / 2;
|
|
6876
|
+
top = last.top;
|
|
6877
|
+
height = last.height;
|
|
6878
|
+
} else {
|
|
6879
|
+
const prev = columns[i - 1].getBoundingClientRect();
|
|
6880
|
+
const next = columns[i].getBoundingClientRect();
|
|
6881
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
6882
|
+
top = Math.min(prev.top, next.top);
|
|
6883
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
6884
|
+
}
|
|
6885
|
+
slots.push({
|
|
6886
|
+
insertIndex: i,
|
|
6887
|
+
columnIndex: i,
|
|
6888
|
+
left,
|
|
6889
|
+
top,
|
|
6890
|
+
width: barThickness,
|
|
6891
|
+
height: Math.max(height, 24),
|
|
6892
|
+
direction: "vertical"
|
|
6893
|
+
});
|
|
6894
|
+
}
|
|
6895
|
+
return slots;
|
|
6896
|
+
}
|
|
6897
|
+
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
6898
|
+
const columns = listFooterColumns();
|
|
6899
|
+
let best = null;
|
|
6900
|
+
for (let c = 0; c < columns.length; c++) {
|
|
6901
|
+
const col = columns[c];
|
|
6902
|
+
const colRect = col.getBoundingClientRect();
|
|
6903
|
+
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
6904
|
+
if (!inColX) continue;
|
|
6905
|
+
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
6906
|
+
const links = listFooterLinksInColumn(col);
|
|
6907
|
+
const fromIdx = links.findIndex(
|
|
6908
|
+
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
6909
|
+
);
|
|
6910
|
+
if (fromIdx < 0) return true;
|
|
6911
|
+
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
6912
|
+
return true;
|
|
6913
|
+
}
|
|
6914
|
+
return true;
|
|
6915
|
+
});
|
|
6916
|
+
for (const slot of slots) {
|
|
6917
|
+
const cy = slot.top + slot.height / 2;
|
|
6918
|
+
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
6919
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
return best?.slot ?? null;
|
|
6923
|
+
}
|
|
6924
|
+
function findColumnIndexForKey(hrefKey) {
|
|
6925
|
+
const order = getFooterOrderFromDom();
|
|
6926
|
+
for (let c = 0; c < order.length; c++) {
|
|
6927
|
+
if (order[c].includes(hrefKey)) return c;
|
|
6928
|
+
}
|
|
6929
|
+
return -1;
|
|
6930
|
+
}
|
|
6931
|
+
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
6932
|
+
const slots = buildColumnDropSlots();
|
|
6933
|
+
let best = null;
|
|
6934
|
+
for (const slot of slots) {
|
|
6935
|
+
const cx2 = slot.left + slot.width / 2;
|
|
6936
|
+
const dist = Math.abs(clientX - cx2);
|
|
6937
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
6938
|
+
}
|
|
6939
|
+
return best?.slot ?? null;
|
|
6940
|
+
}
|
|
6941
|
+
|
|
6942
|
+
// src/lib/carousel.ts
|
|
6943
|
+
var import_react8 = require("react");
|
|
6944
|
+
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
6945
|
+
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
6946
|
+
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
6947
|
+
var CAROUSEL_EVENT = "ohw:carousel-change";
|
|
6948
|
+
function listCarouselKeys() {
|
|
6949
|
+
const keys = /* @__PURE__ */ new Set();
|
|
6950
|
+
document.querySelectorAll(`[${CAROUSEL_ATTR}]`).forEach((el) => {
|
|
6951
|
+
const key = el.getAttribute("data-ohw-key");
|
|
6952
|
+
if (key) keys.add(key);
|
|
6953
|
+
});
|
|
6954
|
+
return [...keys];
|
|
6955
|
+
}
|
|
6956
|
+
function containersForKey(key) {
|
|
6957
|
+
return Array.from(
|
|
6958
|
+
document.querySelectorAll(`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`)
|
|
6959
|
+
);
|
|
6960
|
+
}
|
|
6961
|
+
function isCarouselKey(key) {
|
|
6962
|
+
return containersForKey(key).length > 0;
|
|
6963
|
+
}
|
|
6964
|
+
function parseSlides(raw) {
|
|
6965
|
+
if (!raw) return [];
|
|
6966
|
+
try {
|
|
6967
|
+
const parsed = JSON.parse(raw);
|
|
6968
|
+
if (!Array.isArray(parsed)) return [];
|
|
6969
|
+
return parsed.filter((s) => Boolean(s) && typeof s === "object").map((s) => ({ src: String(s.src ?? ""), alt: String(s.alt ?? "") }));
|
|
6970
|
+
} catch {
|
|
6971
|
+
return [];
|
|
6972
|
+
}
|
|
6973
|
+
}
|
|
6974
|
+
function readCarouselValue(key) {
|
|
6975
|
+
const container = containersForKey(key)[0];
|
|
6976
|
+
if (!container) return [];
|
|
6977
|
+
const fromAttr = parseSlides(container.getAttribute(CAROUSEL_VALUE_ATTR));
|
|
6978
|
+
if (fromAttr.length > 0) return fromAttr;
|
|
6979
|
+
return Array.from(container.querySelectorAll(`[${CAROUSEL_SLIDE_ATTR}]`)).filter((slide) => slide.closest(`[${CAROUSEL_ATTR}]`) === container).sort((a, b) => slideIndex(a) - slideIndex(b)).map((slide) => {
|
|
6980
|
+
const img = slide instanceof HTMLImageElement ? slide : slide.querySelector("img");
|
|
6981
|
+
return { src: img?.src ?? "", alt: img?.alt ?? "" };
|
|
6982
|
+
});
|
|
6983
|
+
}
|
|
6984
|
+
function slideIndex(el) {
|
|
6985
|
+
const raw = el.getAttribute(CAROUSEL_SLIDE_ATTR);
|
|
6986
|
+
const n = raw ? parseInt(raw, 10) : NaN;
|
|
6987
|
+
return Number.isFinite(n) ? n : 0;
|
|
6988
|
+
}
|
|
6989
|
+
function applyCarouselValue(key, slides) {
|
|
6990
|
+
const value = JSON.stringify(slides);
|
|
6991
|
+
for (const container of containersForKey(key)) {
|
|
6992
|
+
if (container.getAttribute(CAROUSEL_VALUE_ATTR) === value) continue;
|
|
6993
|
+
container.setAttribute(CAROUSEL_VALUE_ATTR, value);
|
|
6994
|
+
container.dispatchEvent(
|
|
6995
|
+
new CustomEvent(CAROUSEL_EVENT, { detail: { images: slides } })
|
|
6996
|
+
);
|
|
6997
|
+
}
|
|
6998
|
+
}
|
|
6999
|
+
function applyCarouselNode(key, val) {
|
|
7000
|
+
if (!isCarouselKey(key)) return false;
|
|
7001
|
+
applyCarouselValue(key, parseSlides(val));
|
|
7002
|
+
return true;
|
|
7003
|
+
}
|
|
7004
|
+
function useOhwCarousel(key, initial) {
|
|
7005
|
+
const [images, setImages] = (0, import_react8.useState)(initial);
|
|
7006
|
+
(0, import_react8.useEffect)(() => {
|
|
7007
|
+
const el = document.querySelector(
|
|
7008
|
+
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
7009
|
+
);
|
|
7010
|
+
if (!el) return;
|
|
7011
|
+
const onChange = (e) => {
|
|
7012
|
+
const detail = e.detail;
|
|
7013
|
+
if (Array.isArray(detail?.images)) setImages(detail.images);
|
|
7014
|
+
};
|
|
7015
|
+
el.addEventListener(CAROUSEL_EVENT, onChange);
|
|
7016
|
+
return () => el.removeEventListener(CAROUSEL_EVENT, onChange);
|
|
7017
|
+
}, [key]);
|
|
7018
|
+
const bind = {
|
|
7019
|
+
[CAROUSEL_ATTR]: "",
|
|
7020
|
+
"data-ohw-key": key,
|
|
7021
|
+
[CAROUSEL_VALUE_ATTR]: JSON.stringify(images)
|
|
7022
|
+
};
|
|
7023
|
+
return { images, setImages, bind };
|
|
7024
|
+
}
|
|
7025
|
+
|
|
6505
7026
|
// src/ui/navbar-container-chrome.tsx
|
|
6506
|
-
var
|
|
6507
|
-
var
|
|
7027
|
+
var import_lucide_react11 = require("lucide-react");
|
|
7028
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6508
7029
|
function NavbarContainerChrome({
|
|
6509
7030
|
rect,
|
|
6510
7031
|
onAdd
|
|
6511
7032
|
}) {
|
|
6512
7033
|
const chromeGap = 6;
|
|
6513
|
-
return /* @__PURE__ */ (0,
|
|
7034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6514
7035
|
"div",
|
|
6515
7036
|
{
|
|
6516
7037
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -6522,7 +7043,7 @@ function NavbarContainerChrome({
|
|
|
6522
7043
|
width: rect.width + chromeGap * 2,
|
|
6523
7044
|
height: rect.height + chromeGap * 2
|
|
6524
7045
|
},
|
|
6525
|
-
children: /* @__PURE__ */ (0,
|
|
7046
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6526
7047
|
"button",
|
|
6527
7048
|
{
|
|
6528
7049
|
type: "button",
|
|
@@ -6539,15 +7060,57 @@ function NavbarContainerChrome({
|
|
|
6539
7060
|
e.stopPropagation();
|
|
6540
7061
|
onAdd();
|
|
6541
7062
|
},
|
|
6542
|
-
children: /* @__PURE__ */ (0,
|
|
7063
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6543
7064
|
}
|
|
6544
7065
|
)
|
|
6545
7066
|
}
|
|
6546
7067
|
);
|
|
6547
7068
|
}
|
|
6548
7069
|
|
|
7070
|
+
// src/ui/drop-indicator.tsx
|
|
7071
|
+
var React9 = __toESM(require("react"), 1);
|
|
7072
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7073
|
+
var dropIndicatorVariants = cva(
|
|
7074
|
+
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7075
|
+
{
|
|
7076
|
+
variants: {
|
|
7077
|
+
direction: {
|
|
7078
|
+
vertical: "h-6 w-[3px]",
|
|
7079
|
+
horizontal: "h-[3px] w-[200px]"
|
|
7080
|
+
},
|
|
7081
|
+
state: {
|
|
7082
|
+
default: "opacity-0",
|
|
7083
|
+
hover: "opacity-100",
|
|
7084
|
+
dragIdle: "opacity-40",
|
|
7085
|
+
dragActive: "opacity-100"
|
|
7086
|
+
}
|
|
7087
|
+
},
|
|
7088
|
+
defaultVariants: {
|
|
7089
|
+
direction: "vertical",
|
|
7090
|
+
state: "default"
|
|
7091
|
+
}
|
|
7092
|
+
}
|
|
7093
|
+
);
|
|
7094
|
+
var DropIndicator = React9.forwardRef(
|
|
7095
|
+
({ className, direction, state, ...props }, ref) => {
|
|
7096
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7097
|
+
"div",
|
|
7098
|
+
{
|
|
7099
|
+
ref,
|
|
7100
|
+
"data-slot": "drop-indicator",
|
|
7101
|
+
"data-direction": direction ?? "vertical",
|
|
7102
|
+
"data-state": state ?? "default",
|
|
7103
|
+
"aria-hidden": "true",
|
|
7104
|
+
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7105
|
+
...props
|
|
7106
|
+
}
|
|
7107
|
+
);
|
|
7108
|
+
}
|
|
7109
|
+
);
|
|
7110
|
+
DropIndicator.displayName = "DropIndicator";
|
|
7111
|
+
|
|
6549
7112
|
// src/ui/badge.tsx
|
|
6550
|
-
var
|
|
7113
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6551
7114
|
var badgeVariants = cva(
|
|
6552
7115
|
"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",
|
|
6553
7116
|
{
|
|
@@ -6565,12 +7128,12 @@ var badgeVariants = cva(
|
|
|
6565
7128
|
}
|
|
6566
7129
|
);
|
|
6567
7130
|
function Badge({ className, variant, ...props }) {
|
|
6568
|
-
return /* @__PURE__ */ (0,
|
|
7131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6569
7132
|
}
|
|
6570
7133
|
|
|
6571
7134
|
// src/OhhwellsBridge.tsx
|
|
6572
|
-
var
|
|
6573
|
-
var
|
|
7135
|
+
var import_lucide_react12 = require("lucide-react");
|
|
7136
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
6574
7137
|
var PRIMARY2 = "#0885FE";
|
|
6575
7138
|
var IMAGE_FADE_MS = 300;
|
|
6576
7139
|
function runOpacityFade(el, onDone) {
|
|
@@ -6749,7 +7312,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6749
7312
|
const root = (0, import_client.createRoot)(container);
|
|
6750
7313
|
(0, import_react_dom2.flushSync)(() => {
|
|
6751
7314
|
root.render(
|
|
6752
|
-
/* @__PURE__ */ (0,
|
|
7315
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6753
7316
|
SchedulingWidget,
|
|
6754
7317
|
{
|
|
6755
7318
|
notifyOnConnect,
|
|
@@ -6811,7 +7374,7 @@ function isDragHandleDisabled(el) {
|
|
|
6811
7374
|
return raw === "true" || raw === "";
|
|
6812
7375
|
});
|
|
6813
7376
|
}
|
|
6814
|
-
function collectEditableNodes() {
|
|
7377
|
+
function collectEditableNodes(extraContent) {
|
|
6815
7378
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
6816
7379
|
if (el.dataset.ohwEditable === "image") {
|
|
6817
7380
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6839,6 +7402,14 @@ function collectEditableNodes() {
|
|
|
6839
7402
|
if (!key) return;
|
|
6840
7403
|
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
6841
7404
|
});
|
|
7405
|
+
if (extraContent) {
|
|
7406
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
7407
|
+
const text = extraContent[key];
|
|
7408
|
+
if (typeof text === "string" && text.length > 0) {
|
|
7409
|
+
nodes.push({ key, type: "meta", text });
|
|
7410
|
+
}
|
|
7411
|
+
}
|
|
7412
|
+
}
|
|
6842
7413
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6843
7414
|
const key = el.dataset.ohwKey ?? "";
|
|
6844
7415
|
const video = getVideoEl(el);
|
|
@@ -6846,13 +7417,10 @@ function collectEditableNodes() {
|
|
|
6846
7417
|
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
6847
7418
|
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
6848
7419
|
});
|
|
6849
|
-
const
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
seen.add(node.key);
|
|
6854
|
-
return true;
|
|
6855
|
-
});
|
|
7420
|
+
for (const key of listCarouselKeys()) {
|
|
7421
|
+
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
7422
|
+
}
|
|
7423
|
+
return nodes;
|
|
6856
7424
|
}
|
|
6857
7425
|
function isMediaEditable(el) {
|
|
6858
7426
|
const t = el.dataset.ohwEditable;
|
|
@@ -6940,6 +7508,29 @@ function getHrefKeyFromElement(el) {
|
|
|
6940
7508
|
if (!key) return null;
|
|
6941
7509
|
return { anchor, key };
|
|
6942
7510
|
}
|
|
7511
|
+
function disableNativeHrefDrag(el) {
|
|
7512
|
+
if (el.draggable) el.draggable = false;
|
|
7513
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
7514
|
+
el.setAttribute("draggable", "false");
|
|
7515
|
+
}
|
|
7516
|
+
}
|
|
7517
|
+
function clearTextSelection() {
|
|
7518
|
+
const sel = window.getSelection();
|
|
7519
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7520
|
+
}
|
|
7521
|
+
function armFooterPressDrag() {
|
|
7522
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7523
|
+
}
|
|
7524
|
+
function lockFooterDuringDrag() {
|
|
7525
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7526
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7527
|
+
clearTextSelection();
|
|
7528
|
+
}
|
|
7529
|
+
function unlockFooterDragInteraction() {
|
|
7530
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7531
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7532
|
+
clearTextSelection();
|
|
7533
|
+
}
|
|
6943
7534
|
function isNavbarButton2(el) {
|
|
6944
7535
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
6945
7536
|
}
|
|
@@ -7002,7 +7593,7 @@ function isInferredFooterGroup(el) {
|
|
|
7002
7593
|
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
7003
7594
|
}
|
|
7004
7595
|
function isNavigationContainer(el) {
|
|
7005
|
-
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
7596
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
7006
7597
|
}
|
|
7007
7598
|
function isPointOverNavigation(x, y) {
|
|
7008
7599
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
@@ -7212,6 +7803,8 @@ var ICONS = {
|
|
|
7212
7803
|
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"/>',
|
|
7213
7804
|
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"/>'
|
|
7214
7805
|
};
|
|
7806
|
+
var TOOLBAR_PILL_PADDING = 2;
|
|
7807
|
+
var TOOLBAR_TOGGLE_GAP = 4;
|
|
7215
7808
|
var TOOLBAR_GROUPS = [
|
|
7216
7809
|
[
|
|
7217
7810
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -7236,7 +7829,7 @@ function EditGlowChrome({
|
|
|
7236
7829
|
dragDisabled = false
|
|
7237
7830
|
}) {
|
|
7238
7831
|
const GAP = 6;
|
|
7239
|
-
return /* @__PURE__ */ (0,
|
|
7832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
7240
7833
|
"div",
|
|
7241
7834
|
{
|
|
7242
7835
|
ref: elRef,
|
|
@@ -7251,7 +7844,7 @@ function EditGlowChrome({
|
|
|
7251
7844
|
zIndex: 2147483646
|
|
7252
7845
|
},
|
|
7253
7846
|
children: [
|
|
7254
|
-
/* @__PURE__ */ (0,
|
|
7847
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7255
7848
|
"div",
|
|
7256
7849
|
{
|
|
7257
7850
|
style: {
|
|
@@ -7264,7 +7857,7 @@ function EditGlowChrome({
|
|
|
7264
7857
|
}
|
|
7265
7858
|
}
|
|
7266
7859
|
),
|
|
7267
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
7860
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7268
7861
|
"div",
|
|
7269
7862
|
{
|
|
7270
7863
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7276,7 +7869,7 @@ function EditGlowChrome({
|
|
|
7276
7869
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7277
7870
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7278
7871
|
},
|
|
7279
|
-
children: /* @__PURE__ */ (0,
|
|
7872
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7280
7873
|
DragHandle,
|
|
7281
7874
|
{
|
|
7282
7875
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7380,7 +7973,7 @@ function FloatingToolbar({
|
|
|
7380
7973
|
onEditLink
|
|
7381
7974
|
}) {
|
|
7382
7975
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7383
|
-
return /* @__PURE__ */ (0,
|
|
7976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7384
7977
|
"div",
|
|
7385
7978
|
{
|
|
7386
7979
|
ref: elRef,
|
|
@@ -7390,14 +7983,23 @@ function FloatingToolbar({
|
|
|
7390
7983
|
left,
|
|
7391
7984
|
transform,
|
|
7392
7985
|
zIndex: 2147483647,
|
|
7986
|
+
background: "#fff",
|
|
7987
|
+
border: "1px solid #E7E5E4",
|
|
7988
|
+
borderRadius: 6,
|
|
7989
|
+
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
7990
|
+
display: "flex",
|
|
7991
|
+
alignItems: "center",
|
|
7992
|
+
padding: TOOLBAR_PILL_PADDING,
|
|
7993
|
+
gap: TOOLBAR_TOGGLE_GAP,
|
|
7994
|
+
fontFamily: "sans-serif",
|
|
7393
7995
|
pointerEvents: "auto"
|
|
7394
7996
|
},
|
|
7395
|
-
children: /* @__PURE__ */ (0,
|
|
7396
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
7397
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
7997
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CustomToolbar, { children: [
|
|
7998
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react9.default.Fragment, { children: [
|
|
7999
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CustomToolbarDivider, {}),
|
|
7398
8000
|
btns.map((btn) => {
|
|
7399
8001
|
const isActive = activeCommands.has(btn.cmd);
|
|
7400
|
-
return /* @__PURE__ */ (0,
|
|
8002
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7401
8003
|
CustomToolbarButton,
|
|
7402
8004
|
{
|
|
7403
8005
|
title: btn.title,
|
|
@@ -7406,7 +8008,7 @@ function FloatingToolbar({
|
|
|
7406
8008
|
e.preventDefault();
|
|
7407
8009
|
onCommand(btn.cmd);
|
|
7408
8010
|
},
|
|
7409
|
-
children: /* @__PURE__ */ (0,
|
|
8011
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7410
8012
|
"svg",
|
|
7411
8013
|
{
|
|
7412
8014
|
width: "16",
|
|
@@ -7427,7 +8029,7 @@ function FloatingToolbar({
|
|
|
7427
8029
|
);
|
|
7428
8030
|
})
|
|
7429
8031
|
] }, gi)),
|
|
7430
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
8032
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7431
8033
|
CustomToolbarButton,
|
|
7432
8034
|
{
|
|
7433
8035
|
type: "button",
|
|
@@ -7441,7 +8043,7 @@ function FloatingToolbar({
|
|
|
7441
8043
|
e.preventDefault();
|
|
7442
8044
|
e.stopPropagation();
|
|
7443
8045
|
},
|
|
7444
|
-
children: /* @__PURE__ */ (0,
|
|
8046
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7445
8047
|
}
|
|
7446
8048
|
) : null
|
|
7447
8049
|
] })
|
|
@@ -7458,7 +8060,7 @@ function StateToggle({
|
|
|
7458
8060
|
states,
|
|
7459
8061
|
onStateChange
|
|
7460
8062
|
}) {
|
|
7461
|
-
return /* @__PURE__ */ (0,
|
|
8063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7462
8064
|
ToggleGroup,
|
|
7463
8065
|
{
|
|
7464
8066
|
"data-ohw-state-toggle": "",
|
|
@@ -7472,7 +8074,7 @@ function StateToggle({
|
|
|
7472
8074
|
left: rect.right - 8,
|
|
7473
8075
|
transform: "translateX(-100%)"
|
|
7474
8076
|
},
|
|
7475
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
8077
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
7476
8078
|
}
|
|
7477
8079
|
);
|
|
7478
8080
|
}
|
|
@@ -7499,8 +8101,8 @@ function OhhwellsBridge() {
|
|
|
7499
8101
|
const router = (0, import_navigation2.useRouter)();
|
|
7500
8102
|
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
7501
8103
|
const isEditMode = isEditSessionActive();
|
|
7502
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
7503
|
-
(0,
|
|
8104
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react9.useState)(null);
|
|
8105
|
+
(0, import_react9.useEffect)(() => {
|
|
7504
8106
|
const figtreeFontId = "ohw-figtree-font";
|
|
7505
8107
|
if (!document.getElementById(figtreeFontId)) {
|
|
7506
8108
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -7528,91 +8130,101 @@ function OhhwellsBridge() {
|
|
|
7528
8130
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
7529
8131
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
7530
8132
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
7531
|
-
const postToParent2 = (0,
|
|
8133
|
+
const postToParent2 = (0, import_react9.useCallback)((data) => {
|
|
7532
8134
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
7533
8135
|
window.parent.postMessage(data, "*");
|
|
7534
8136
|
}
|
|
7535
8137
|
}, []);
|
|
7536
|
-
const [fetchState, setFetchState] = (0,
|
|
7537
|
-
const autoSaveTimers = (0,
|
|
7538
|
-
const activeElRef = (0,
|
|
7539
|
-
const selectedElRef = (0,
|
|
7540
|
-
const originalContentRef = (0,
|
|
7541
|
-
const activeStateElRef = (0,
|
|
7542
|
-
const parentScrollRef = (0,
|
|
7543
|
-
const visibleViewportRef = (0,
|
|
7544
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0,
|
|
7545
|
-
const attachVisibleViewport = (0,
|
|
8138
|
+
const [fetchState, setFetchState] = (0, import_react9.useState)("idle");
|
|
8139
|
+
const autoSaveTimers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
8140
|
+
const activeElRef = (0, import_react9.useRef)(null);
|
|
8141
|
+
const selectedElRef = (0, import_react9.useRef)(null);
|
|
8142
|
+
const originalContentRef = (0, import_react9.useRef)(null);
|
|
8143
|
+
const activeStateElRef = (0, import_react9.useRef)(null);
|
|
8144
|
+
const parentScrollRef = (0, import_react9.useRef)(null);
|
|
8145
|
+
const visibleViewportRef = (0, import_react9.useRef)(null);
|
|
8146
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react9.useState)(null);
|
|
8147
|
+
const attachVisibleViewport = (0, import_react9.useCallback)((node) => {
|
|
7546
8148
|
visibleViewportRef.current = node;
|
|
7547
8149
|
setDialogPortalContainer(node);
|
|
7548
8150
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
7549
8151
|
}, []);
|
|
7550
|
-
const toolbarElRef = (0,
|
|
7551
|
-
const glowElRef = (0,
|
|
7552
|
-
const hoveredImageRef = (0,
|
|
7553
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
7554
|
-
const dragOverElRef = (0,
|
|
7555
|
-
const [mediaHover, setMediaHover] = (0,
|
|
7556
|
-
const [
|
|
7557
|
-
const
|
|
7558
|
-
const
|
|
7559
|
-
const
|
|
7560
|
-
const
|
|
7561
|
-
const
|
|
8152
|
+
const toolbarElRef = (0, import_react9.useRef)(null);
|
|
8153
|
+
const glowElRef = (0, import_react9.useRef)(null);
|
|
8154
|
+
const hoveredImageRef = (0, import_react9.useRef)(null);
|
|
8155
|
+
const hoveredImageHasTextOverlapRef = (0, import_react9.useRef)(false);
|
|
8156
|
+
const dragOverElRef = (0, import_react9.useRef)(null);
|
|
8157
|
+
const [mediaHover, setMediaHover] = (0, import_react9.useState)(null);
|
|
8158
|
+
const [carouselHover, setCarouselHover] = (0, import_react9.useState)(null);
|
|
8159
|
+
const [uploadingRects, setUploadingRects] = (0, import_react9.useState)({});
|
|
8160
|
+
const pendingUploadRectRef = (0, import_react9.useRef)(null);
|
|
8161
|
+
const hoveredGapRef = (0, import_react9.useRef)(null);
|
|
8162
|
+
const imageUnhoverTimerRef = (0, import_react9.useRef)(null);
|
|
8163
|
+
const imageShowTimerRef = (0, import_react9.useRef)(null);
|
|
8164
|
+
const editStylesRef = (0, import_react9.useRef)(null);
|
|
8165
|
+
const activateRef = (0, import_react9.useRef)(() => {
|
|
7562
8166
|
});
|
|
7563
|
-
const deactivateRef = (0,
|
|
8167
|
+
const deactivateRef = (0, import_react9.useRef)(() => {
|
|
7564
8168
|
});
|
|
7565
|
-
const selectRef = (0,
|
|
8169
|
+
const selectRef = (0, import_react9.useRef)(() => {
|
|
7566
8170
|
});
|
|
7567
|
-
const selectFrameRef = (0,
|
|
8171
|
+
const selectFrameRef = (0, import_react9.useRef)(() => {
|
|
7568
8172
|
});
|
|
7569
|
-
const deselectRef = (0,
|
|
8173
|
+
const deselectRef = (0, import_react9.useRef)(() => {
|
|
7570
8174
|
});
|
|
7571
|
-
const reselectNavigationItemRef = (0,
|
|
8175
|
+
const reselectNavigationItemRef = (0, import_react9.useRef)(() => {
|
|
7572
8176
|
});
|
|
7573
|
-
const commitNavigationTextEditRef = (0,
|
|
8177
|
+
const commitNavigationTextEditRef = (0, import_react9.useRef)(() => {
|
|
7574
8178
|
});
|
|
7575
|
-
const refreshActiveCommandsRef = (0,
|
|
8179
|
+
const refreshActiveCommandsRef = (0, import_react9.useRef)(() => {
|
|
7576
8180
|
});
|
|
7577
|
-
const postToParentRef = (0,
|
|
8181
|
+
const postToParentRef = (0, import_react9.useRef)(postToParent2);
|
|
7578
8182
|
postToParentRef.current = postToParent2;
|
|
7579
|
-
const sectionsLoadedRef = (0,
|
|
7580
|
-
const pendingScheduleConfigRequests = (0,
|
|
7581
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
7582
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
7583
|
-
const toolbarVariantRef = (0,
|
|
8183
|
+
const sectionsLoadedRef = (0, import_react9.useRef)(false);
|
|
8184
|
+
const pendingScheduleConfigRequests = (0, import_react9.useRef)([]);
|
|
8185
|
+
const [toolbarRect, setToolbarRect] = (0, import_react9.useState)(null);
|
|
8186
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react9.useState)("none");
|
|
8187
|
+
const toolbarVariantRef = (0, import_react9.useRef)("none");
|
|
7584
8188
|
toolbarVariantRef.current = toolbarVariant;
|
|
7585
|
-
const [reorderHrefKey, setReorderHrefKey] = (0,
|
|
7586
|
-
const [reorderDragDisabled, setReorderDragDisabled] = (0,
|
|
7587
|
-
const [toggleState, setToggleState] = (0,
|
|
7588
|
-
const [maxBadge, setMaxBadge] = (0,
|
|
7589
|
-
const [activeCommands, setActiveCommands] = (0,
|
|
7590
|
-
const [sectionGap, setSectionGap] = (0,
|
|
7591
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] = (0,
|
|
7592
|
-
const hoveredNavContainerRef = (0,
|
|
7593
|
-
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0,
|
|
7594
|
-
const hoveredItemElRef = (0,
|
|
7595
|
-
const [hoveredItemRect, setHoveredItemRect] = (0,
|
|
7596
|
-
const siblingHintElRef = (0,
|
|
7597
|
-
const [siblingHintRect, setSiblingHintRect] = (0,
|
|
7598
|
-
const [
|
|
7599
|
-
const [
|
|
7600
|
-
const
|
|
7601
|
-
const
|
|
7602
|
-
const
|
|
7603
|
-
const [
|
|
7604
|
-
const [
|
|
7605
|
-
const
|
|
7606
|
-
const
|
|
7607
|
-
const
|
|
7608
|
-
const
|
|
7609
|
-
const
|
|
8189
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react9.useState)(null);
|
|
8190
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react9.useState)(false);
|
|
8191
|
+
const [toggleState, setToggleState] = (0, import_react9.useState)(null);
|
|
8192
|
+
const [maxBadge, setMaxBadge] = (0, import_react9.useState)(null);
|
|
8193
|
+
const [activeCommands, setActiveCommands] = (0, import_react9.useState)(/* @__PURE__ */ new Set());
|
|
8194
|
+
const [sectionGap, setSectionGap] = (0, import_react9.useState)(null);
|
|
8195
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react9.useState)(false);
|
|
8196
|
+
const hoveredNavContainerRef = (0, import_react9.useRef)(null);
|
|
8197
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react9.useState)(null);
|
|
8198
|
+
const hoveredItemElRef = (0, import_react9.useRef)(null);
|
|
8199
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react9.useState)(null);
|
|
8200
|
+
const siblingHintElRef = (0, import_react9.useRef)(null);
|
|
8201
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react9.useState)(null);
|
|
8202
|
+
const [siblingHintRects, setSiblingHintRects] = (0, import_react9.useState)([]);
|
|
8203
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react9.useState)(false);
|
|
8204
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react9.useState)(false);
|
|
8205
|
+
const footerDragRef = (0, import_react9.useRef)(null);
|
|
8206
|
+
const [footerDropSlots, setFooterDropSlots] = (0, import_react9.useState)([]);
|
|
8207
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react9.useState)(null);
|
|
8208
|
+
const [draggedItemRect, setDraggedItemRect] = (0, import_react9.useState)(null);
|
|
8209
|
+
const footerPointerDragRef = (0, import_react9.useRef)(null);
|
|
8210
|
+
const suppressNextClickRef = (0, import_react9.useRef)(false);
|
|
8211
|
+
const [linkPopover, setLinkPopover] = (0, import_react9.useState)(null);
|
|
8212
|
+
const linkPopoverSessionRef = (0, import_react9.useRef)(null);
|
|
8213
|
+
const addNavAfterAnchorRef = (0, import_react9.useRef)(null);
|
|
8214
|
+
const editContentRef = (0, import_react9.useRef)({});
|
|
8215
|
+
const [sitePages, setSitePages] = (0, import_react9.useState)([]);
|
|
8216
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react9.useState)({});
|
|
8217
|
+
const sectionsPrefetchGenRef = (0, import_react9.useRef)(0);
|
|
8218
|
+
const setLinkPopoverRef = (0, import_react9.useRef)(setLinkPopover);
|
|
8219
|
+
const linkPopoverPanelRef = (0, import_react9.useRef)(null);
|
|
8220
|
+
const linkPopoverOpenRef = (0, import_react9.useRef)(false);
|
|
8221
|
+
const linkPopoverGraceUntilRef = (0, import_react9.useRef)(0);
|
|
7610
8222
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7611
8223
|
linkPopoverSessionRef.current = linkPopover;
|
|
7612
8224
|
const bumpLinkPopoverGrace = () => {
|
|
7613
8225
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
7614
8226
|
};
|
|
7615
|
-
const runSectionsPrefetch = (0,
|
|
8227
|
+
const runSectionsPrefetch = (0, import_react9.useCallback)((pages) => {
|
|
7616
8228
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
7617
8229
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
7618
8230
|
const paths = pages.map((p) => p.path);
|
|
@@ -7631,10 +8243,14 @@ function OhhwellsBridge() {
|
|
|
7631
8243
|
);
|
|
7632
8244
|
});
|
|
7633
8245
|
}, [isEditMode, pathname]);
|
|
7634
|
-
const runSectionsPrefetchRef = (0,
|
|
8246
|
+
const runSectionsPrefetchRef = (0, import_react9.useRef)(runSectionsPrefetch);
|
|
7635
8247
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
7636
|
-
(0,
|
|
7637
|
-
if (!linkPopover)
|
|
8248
|
+
(0, import_react9.useEffect)(() => {
|
|
8249
|
+
if (!linkPopover) {
|
|
8250
|
+
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
8251
|
+
return;
|
|
8252
|
+
}
|
|
8253
|
+
document.documentElement.setAttribute("data-ohw-link-popover-open", "");
|
|
7638
8254
|
if (hoveredImageRef.current) {
|
|
7639
8255
|
hoveredImageRef.current = null;
|
|
7640
8256
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -7661,14 +8277,10 @@ function OhhwellsBridge() {
|
|
|
7661
8277
|
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
7662
8278
|
postToParent2({ type: "ow:image-unhover" });
|
|
7663
8279
|
return () => {
|
|
7664
|
-
|
|
7665
|
-
html.style.overflow = prevHtmlOverflow;
|
|
7666
|
-
body.style.overflow = prevBodyOverflow;
|
|
7667
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
7668
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
8280
|
+
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
7669
8281
|
};
|
|
7670
8282
|
}, [linkPopover, postToParent2]);
|
|
7671
|
-
(0,
|
|
8283
|
+
(0, import_react9.useEffect)(() => {
|
|
7672
8284
|
if (!isEditMode) return;
|
|
7673
8285
|
const useFixtures = shouldUseDevFixtures();
|
|
7674
8286
|
if (useFixtures) {
|
|
@@ -7692,14 +8304,14 @@ function OhhwellsBridge() {
|
|
|
7692
8304
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
7693
8305
|
return () => window.removeEventListener("message", onSitePages);
|
|
7694
8306
|
}, [isEditMode, postToParent2]);
|
|
7695
|
-
(0,
|
|
8307
|
+
(0, import_react9.useEffect)(() => {
|
|
7696
8308
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
7697
8309
|
void loadAllSectionsManifest().then((manifest) => {
|
|
7698
8310
|
if (Object.keys(manifest).length === 0) return;
|
|
7699
8311
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
7700
8312
|
});
|
|
7701
8313
|
}, [isEditMode]);
|
|
7702
|
-
(0,
|
|
8314
|
+
(0, import_react9.useEffect)(() => {
|
|
7703
8315
|
const update = () => {
|
|
7704
8316
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
7705
8317
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -7723,10 +8335,10 @@ function OhhwellsBridge() {
|
|
|
7723
8335
|
vvp.removeEventListener("resize", update);
|
|
7724
8336
|
};
|
|
7725
8337
|
}, []);
|
|
7726
|
-
const refreshStateRules = (0,
|
|
8338
|
+
const refreshStateRules = (0, import_react9.useCallback)(() => {
|
|
7727
8339
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
7728
8340
|
}, []);
|
|
7729
|
-
const processConfigRequest = (0,
|
|
8341
|
+
const processConfigRequest = (0, import_react9.useCallback)((insertAfterVal) => {
|
|
7730
8342
|
const tracker = getSectionsTracker();
|
|
7731
8343
|
let entries = [];
|
|
7732
8344
|
try {
|
|
@@ -7749,7 +8361,7 @@ function OhhwellsBridge() {
|
|
|
7749
8361
|
}
|
|
7750
8362
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
7751
8363
|
}, [isEditMode]);
|
|
7752
|
-
const deactivate = (0,
|
|
8364
|
+
const deactivate = (0, import_react9.useCallback)(() => {
|
|
7753
8365
|
const el = activeElRef.current;
|
|
7754
8366
|
if (!el) return;
|
|
7755
8367
|
const key = el.dataset.ohwKey;
|
|
@@ -7780,12 +8392,14 @@ function OhhwellsBridge() {
|
|
|
7780
8392
|
setToolbarShowEditLink(false);
|
|
7781
8393
|
postToParent2({ type: "ow:exit-edit" });
|
|
7782
8394
|
}, [postToParent2]);
|
|
7783
|
-
const deselect = (0,
|
|
8395
|
+
const deselect = (0, import_react9.useCallback)(() => {
|
|
7784
8396
|
selectedElRef.current = null;
|
|
7785
8397
|
setReorderHrefKey(null);
|
|
7786
8398
|
setReorderDragDisabled(false);
|
|
8399
|
+
setIsFooterFrameSelection(false);
|
|
7787
8400
|
siblingHintElRef.current = null;
|
|
7788
8401
|
setSiblingHintRect(null);
|
|
8402
|
+
setSiblingHintRects([]);
|
|
7789
8403
|
setIsItemDragging(false);
|
|
7790
8404
|
hoveredNavContainerRef.current = null;
|
|
7791
8405
|
setHoveredNavContainerRect(null);
|
|
@@ -7794,7 +8408,7 @@ function OhhwellsBridge() {
|
|
|
7794
8408
|
setToolbarVariant("none");
|
|
7795
8409
|
}
|
|
7796
8410
|
}, []);
|
|
7797
|
-
const reselectNavigationItem = (0,
|
|
8411
|
+
const reselectNavigationItem = (0, import_react9.useCallback)((navAnchor) => {
|
|
7798
8412
|
selectedElRef.current = navAnchor;
|
|
7799
8413
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
7800
8414
|
setReorderHrefKey(key);
|
|
@@ -7804,7 +8418,7 @@ function OhhwellsBridge() {
|
|
|
7804
8418
|
setToolbarShowEditLink(false);
|
|
7805
8419
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7806
8420
|
}, []);
|
|
7807
|
-
const commitNavigationTextEdit = (0,
|
|
8421
|
+
const commitNavigationTextEdit = (0, import_react9.useCallback)((navAnchor) => {
|
|
7808
8422
|
const el = activeElRef.current;
|
|
7809
8423
|
if (!el) return;
|
|
7810
8424
|
const key = el.dataset.ohwKey;
|
|
@@ -7830,7 +8444,7 @@ function OhhwellsBridge() {
|
|
|
7830
8444
|
postToParent2({ type: "ow:exit-edit" });
|
|
7831
8445
|
reselectNavigationItem(navAnchor);
|
|
7832
8446
|
}, [postToParent2, reselectNavigationItem]);
|
|
7833
|
-
const handleAddTopLevelNavItem = (0,
|
|
8447
|
+
const handleAddTopLevelNavItem = (0, import_react9.useCallback)(() => {
|
|
7834
8448
|
const items = listNavbarItems();
|
|
7835
8449
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7836
8450
|
deselectRef.current();
|
|
@@ -7842,96 +8456,393 @@ function OhhwellsBridge() {
|
|
|
7842
8456
|
intent: "add-nav"
|
|
7843
8457
|
});
|
|
7844
8458
|
}, []);
|
|
7845
|
-
const
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
8459
|
+
const clearFooterDragVisuals = (0, import_react9.useCallback)(() => {
|
|
8460
|
+
footerDragRef.current = null;
|
|
8461
|
+
setSiblingHintRects([]);
|
|
8462
|
+
setFooterDropSlots([]);
|
|
8463
|
+
setActiveFooterDropIndex(null);
|
|
8464
|
+
setDraggedItemRect(null);
|
|
7851
8465
|
setIsItemDragging(false);
|
|
8466
|
+
unlockFooterDragInteraction();
|
|
7852
8467
|
}, []);
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
if (
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
clearHrefKeyHover(anchor);
|
|
7860
|
-
hoveredNavContainerRef.current = null;
|
|
7861
|
-
setHoveredNavContainerRect(null);
|
|
7862
|
-
setHoveredItemRect(null);
|
|
7863
|
-
hoveredItemElRef.current = null;
|
|
7864
|
-
siblingHintElRef.current = null;
|
|
7865
|
-
setSiblingHintRect(null);
|
|
7866
|
-
setIsItemDragging(false);
|
|
7867
|
-
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
7868
|
-
setReorderHrefKey(key);
|
|
7869
|
-
setReorderDragDisabled(disabled);
|
|
7870
|
-
setToolbarVariant("link-action");
|
|
7871
|
-
setToolbarRect(anchor.getBoundingClientRect());
|
|
7872
|
-
setToolbarShowEditLink(false);
|
|
7873
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7874
|
-
}, [deactivate]);
|
|
7875
|
-
const selectFrame = (0, import_react8.useCallback)((el) => {
|
|
7876
|
-
if (!isNavigationContainer(el)) return;
|
|
7877
|
-
if (activeElRef.current) deactivate();
|
|
7878
|
-
selectedElRef.current = el;
|
|
7879
|
-
clearHrefKeyHover(el);
|
|
7880
|
-
hoveredNavContainerRef.current = null;
|
|
7881
|
-
setHoveredNavContainerRect(null);
|
|
7882
|
-
setHoveredItemRect(null);
|
|
7883
|
-
hoveredItemElRef.current = null;
|
|
7884
|
-
siblingHintElRef.current = null;
|
|
7885
|
-
setSiblingHintRect(null);
|
|
7886
|
-
setIsItemDragging(false);
|
|
7887
|
-
setReorderHrefKey(null);
|
|
7888
|
-
setReorderDragDisabled(false);
|
|
7889
|
-
setToolbarVariant("select-frame");
|
|
7890
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
7891
|
-
setToolbarShowEditLink(false);
|
|
7892
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7893
|
-
}, [deactivate]);
|
|
7894
|
-
const activate = (0, import_react8.useCallback)((el, options) => {
|
|
7895
|
-
if (activeElRef.current === el) return;
|
|
7896
|
-
selectedElRef.current = null;
|
|
7897
|
-
deactivate();
|
|
7898
|
-
if (hoveredImageRef.current) {
|
|
7899
|
-
hoveredImageRef.current = null;
|
|
7900
|
-
setMediaHover(null);
|
|
8468
|
+
const refreshFooterDragVisuals = (0, import_react9.useCallback)((session, activeSlot, clientX, clientY) => {
|
|
8469
|
+
const dragged = session.draggedEl;
|
|
8470
|
+
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
8471
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
8472
|
+
session.lastClientX = clientX;
|
|
8473
|
+
session.lastClientY = clientY;
|
|
7901
8474
|
}
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
8475
|
+
session.activeSlot = activeSlot;
|
|
8476
|
+
if (session.kind === "link") {
|
|
8477
|
+
const columns2 = listFooterColumns();
|
|
8478
|
+
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
8479
|
+
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
8480
|
+
const siblingRects = [];
|
|
8481
|
+
columns2.forEach((col, i) => {
|
|
8482
|
+
if (!focusCols.has(i)) return;
|
|
8483
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
8484
|
+
if (link === dragged) continue;
|
|
8485
|
+
siblingRects.push(link.getBoundingClientRect());
|
|
8486
|
+
}
|
|
8487
|
+
});
|
|
8488
|
+
setSiblingHintRects(siblingRects);
|
|
8489
|
+
const slots2 = [];
|
|
8490
|
+
columns2.forEach((col, i) => {
|
|
8491
|
+
slots2.push(...buildLinkDropSlots(col, i));
|
|
8492
|
+
});
|
|
8493
|
+
setFooterDropSlots(slots2);
|
|
8494
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8495
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
8496
|
+
return;
|
|
8497
|
+
}
|
|
8498
|
+
const columns = listFooterColumns();
|
|
8499
|
+
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
8500
|
+
const slots = buildColumnDropSlots();
|
|
8501
|
+
setFooterDropSlots(slots);
|
|
8502
|
+
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8503
|
+
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
8504
|
+
}, []);
|
|
8505
|
+
const refreshFooterDragVisualsRef = (0, import_react9.useRef)(refreshFooterDragVisuals);
|
|
8506
|
+
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
8507
|
+
const commitFooterDragRef = (0, import_react9.useRef)(() => {
|
|
8508
|
+
});
|
|
8509
|
+
const beginFooterDragRef = (0, import_react9.useRef)(() => {
|
|
8510
|
+
});
|
|
8511
|
+
const beginFooterDrag = (0, import_react9.useCallback)(
|
|
8512
|
+
(session) => {
|
|
8513
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
8514
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
8515
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
8516
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
8517
|
+
footerDragRef.current = session;
|
|
8518
|
+
setIsItemDragging(true);
|
|
8519
|
+
lockFooterDuringDrag();
|
|
8520
|
+
siblingHintElRef.current = null;
|
|
8521
|
+
setSiblingHintRect(null);
|
|
8522
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
8523
|
+
setToolbarRect(rect);
|
|
8524
|
+
}
|
|
8525
|
+
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
8526
|
+
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
8527
|
+
},
|
|
8528
|
+
[refreshFooterDragVisuals]
|
|
8529
|
+
);
|
|
8530
|
+
beginFooterDragRef.current = beginFooterDrag;
|
|
8531
|
+
const commitFooterDrag = (0, import_react9.useCallback)(
|
|
8532
|
+
(clientX, clientY) => {
|
|
8533
|
+
const session = footerDragRef.current;
|
|
8534
|
+
if (!session) {
|
|
8535
|
+
clearFooterDragVisuals();
|
|
8536
|
+
return;
|
|
8537
|
+
}
|
|
8538
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
8539
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
8540
|
+
let nextOrder = null;
|
|
8541
|
+
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
8542
|
+
if (session.kind === "link" && session.hrefKey && slot) {
|
|
8543
|
+
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
8544
|
+
} else if (session.kind === "column" && slot) {
|
|
8545
|
+
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
8546
|
+
}
|
|
8547
|
+
const wasSelected = session.wasSelected;
|
|
8548
|
+
const draggedEl = session.draggedEl;
|
|
8549
|
+
const hrefKey = session.hrefKey;
|
|
8550
|
+
let movedColumnIndex = null;
|
|
8551
|
+
if (session.kind === "column" && slot && nextOrder) {
|
|
8552
|
+
let adjusted = slot.insertIndex;
|
|
8553
|
+
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
8554
|
+
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
8555
|
+
}
|
|
8556
|
+
clearFooterDragVisuals();
|
|
8557
|
+
const applySelectionAfterDrop = () => {
|
|
8558
|
+
if (!wasSelected) {
|
|
8559
|
+
deselectRef.current();
|
|
8560
|
+
return;
|
|
8561
|
+
}
|
|
8562
|
+
if (hrefKey) {
|
|
8563
|
+
const link = document.querySelector(
|
|
8564
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
8565
|
+
);
|
|
8566
|
+
if (link && isNavigationItem(link)) {
|
|
8567
|
+
selectRef.current(link);
|
|
8568
|
+
return;
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
8571
|
+
if (movedColumnIndex !== null && nextOrder) {
|
|
8572
|
+
const colKeys = nextOrder[movedColumnIndex] ?? [];
|
|
8573
|
+
let column = null;
|
|
8574
|
+
for (const key of colKeys) {
|
|
8575
|
+
const link = document.querySelector(
|
|
8576
|
+
`footer [data-ohw-href-key="${CSS.escape(key)}"]`
|
|
8577
|
+
);
|
|
8578
|
+
if (link) {
|
|
8579
|
+
column = findFooterColumnForLink(link);
|
|
8580
|
+
if (column) break;
|
|
8581
|
+
}
|
|
8582
|
+
}
|
|
8583
|
+
if (!column) column = listFooterColumns()[movedColumnIndex] ?? null;
|
|
8584
|
+
if (column && isNavigationContainer(column)) {
|
|
8585
|
+
selectFrameRef.current(column);
|
|
8586
|
+
return;
|
|
8587
|
+
}
|
|
8588
|
+
}
|
|
8589
|
+
if (document.body.contains(draggedEl)) {
|
|
8590
|
+
if (isNavigationItem(draggedEl)) {
|
|
8591
|
+
selectRef.current(draggedEl);
|
|
8592
|
+
return;
|
|
8593
|
+
}
|
|
8594
|
+
if (isNavigationContainer(draggedEl)) {
|
|
8595
|
+
selectFrameRef.current(draggedEl);
|
|
8596
|
+
return;
|
|
8597
|
+
}
|
|
8598
|
+
}
|
|
8599
|
+
deselectRef.current();
|
|
8600
|
+
};
|
|
8601
|
+
if (!wasSelected) {
|
|
8602
|
+
deselectRef.current();
|
|
8603
|
+
}
|
|
8604
|
+
if (nextOrder) {
|
|
8605
|
+
const orderJson = JSON.stringify(nextOrder);
|
|
8606
|
+
editContentRef.current = {
|
|
8607
|
+
...editContentRef.current,
|
|
8608
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
8609
|
+
};
|
|
8610
|
+
applyFooterOrder(nextOrder);
|
|
8611
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8612
|
+
postToParentRef.current({
|
|
8613
|
+
type: "ow:change",
|
|
8614
|
+
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
8615
|
+
});
|
|
8616
|
+
requestAnimationFrame(() => {
|
|
8617
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
8618
|
+
applyFooterOrder(nextOrder);
|
|
8619
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8620
|
+
}
|
|
8621
|
+
requestAnimationFrame(applySelectionAfterDrop);
|
|
8622
|
+
});
|
|
8623
|
+
return;
|
|
8624
|
+
}
|
|
8625
|
+
applySelectionAfterDrop();
|
|
8626
|
+
},
|
|
8627
|
+
[clearFooterDragVisuals]
|
|
8628
|
+
);
|
|
8629
|
+
commitFooterDragRef.current = commitFooterDrag;
|
|
8630
|
+
const startFooterLinkDrag = (0, import_react9.useCallback)(
|
|
8631
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
8632
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
8633
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
8634
|
+
const column = findFooterColumnForLink(anchor);
|
|
8635
|
+
const columns = listFooterColumns();
|
|
8636
|
+
beginFooterDrag({
|
|
8637
|
+
kind: "link",
|
|
8638
|
+
hrefKey,
|
|
8639
|
+
columnEl: column,
|
|
8640
|
+
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
8641
|
+
wasSelected,
|
|
8642
|
+
draggedEl: anchor,
|
|
8643
|
+
lastClientX: clientX,
|
|
8644
|
+
lastClientY: clientY,
|
|
8645
|
+
activeSlot: null
|
|
8646
|
+
});
|
|
8647
|
+
return true;
|
|
8648
|
+
},
|
|
8649
|
+
[beginFooterDrag]
|
|
8650
|
+
);
|
|
8651
|
+
const startFooterColumnDrag = (0, import_react9.useCallback)(
|
|
8652
|
+
(columnEl, clientX, clientY, wasSelected) => {
|
|
8653
|
+
const columns = listFooterColumns();
|
|
8654
|
+
const idx = columns.indexOf(columnEl);
|
|
8655
|
+
if (idx < 0) return false;
|
|
8656
|
+
beginFooterDrag({
|
|
8657
|
+
kind: "column",
|
|
8658
|
+
hrefKey: null,
|
|
8659
|
+
columnEl,
|
|
8660
|
+
sourceColumnIndex: idx,
|
|
8661
|
+
wasSelected,
|
|
8662
|
+
draggedEl: columnEl,
|
|
8663
|
+
lastClientX: clientX,
|
|
8664
|
+
lastClientY: clientY,
|
|
8665
|
+
activeSlot: null
|
|
8666
|
+
});
|
|
8667
|
+
return true;
|
|
8668
|
+
},
|
|
8669
|
+
[beginFooterDrag]
|
|
8670
|
+
);
|
|
8671
|
+
const handleItemDragStart = (0, import_react9.useCallback)(
|
|
8672
|
+
(e) => {
|
|
8673
|
+
const selected = selectedElRef.current;
|
|
8674
|
+
if (!selected) {
|
|
8675
|
+
setIsItemDragging(true);
|
|
8676
|
+
return;
|
|
8677
|
+
}
|
|
8678
|
+
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
8679
|
+
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
8680
|
+
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
8681
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8682
|
+
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
8683
|
+
}
|
|
8684
|
+
siblingHintElRef.current = null;
|
|
8685
|
+
setSiblingHintRect(null);
|
|
8686
|
+
setIsItemDragging(true);
|
|
8687
|
+
},
|
|
8688
|
+
[startFooterColumnDrag, startFooterLinkDrag]
|
|
8689
|
+
);
|
|
8690
|
+
const handleItemDragEnd = (0, import_react9.useCallback)(
|
|
8691
|
+
(e) => {
|
|
8692
|
+
if (footerDragRef.current) {
|
|
8693
|
+
const x = e?.clientX;
|
|
8694
|
+
const y = e?.clientY;
|
|
8695
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
8696
|
+
commitFooterDrag(x, y);
|
|
8697
|
+
} else {
|
|
8698
|
+
commitFooterDrag();
|
|
8699
|
+
}
|
|
8700
|
+
return;
|
|
8701
|
+
}
|
|
8702
|
+
setIsItemDragging(false);
|
|
8703
|
+
},
|
|
8704
|
+
[commitFooterDrag]
|
|
8705
|
+
);
|
|
8706
|
+
const handleItemChromePointerDown = (0, import_react9.useCallback)((e) => {
|
|
8707
|
+
if (e.button !== 0) return;
|
|
8708
|
+
const selected = selectedElRef.current;
|
|
8709
|
+
if (!selected) return;
|
|
8710
|
+
armFooterPressDrag();
|
|
8711
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
8712
|
+
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
8713
|
+
footerPointerDragRef.current = {
|
|
8714
|
+
el: selected,
|
|
8715
|
+
kind: "link",
|
|
8716
|
+
startX: e.clientX,
|
|
8717
|
+
startY: e.clientY,
|
|
8718
|
+
pointerId: e.pointerId,
|
|
8719
|
+
wasSelected: true,
|
|
8720
|
+
started: false
|
|
8721
|
+
};
|
|
8722
|
+
return;
|
|
8723
|
+
}
|
|
8724
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8725
|
+
footerPointerDragRef.current = {
|
|
8726
|
+
el: selected,
|
|
8727
|
+
kind: "column",
|
|
8728
|
+
startX: e.clientX,
|
|
8729
|
+
startY: e.clientY,
|
|
8730
|
+
pointerId: e.pointerId,
|
|
8731
|
+
wasSelected: true,
|
|
8732
|
+
started: false
|
|
8733
|
+
};
|
|
8734
|
+
}
|
|
8735
|
+
}, []);
|
|
8736
|
+
const handleItemChromeClick = (0, import_react9.useCallback)((clientX, clientY) => {
|
|
8737
|
+
if (suppressNextClickRef.current) {
|
|
8738
|
+
suppressNextClickRef.current = false;
|
|
8739
|
+
return;
|
|
7914
8740
|
}
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
8741
|
+
const selected = selectedElRef.current;
|
|
8742
|
+
if (!selected || !isNavigationItem(selected)) return;
|
|
8743
|
+
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
8744
|
+
if (!editable) return;
|
|
8745
|
+
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
8746
|
+
}, []);
|
|
8747
|
+
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
8748
|
+
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
8749
|
+
const select = (0, import_react9.useCallback)(
|
|
8750
|
+
(anchor) => {
|
|
8751
|
+
if (!isNavigationItem(anchor)) return;
|
|
8752
|
+
if (activeElRef.current) deactivate();
|
|
8753
|
+
selectedElRef.current = anchor;
|
|
8754
|
+
clearHrefKeyHover(anchor);
|
|
8755
|
+
hoveredNavContainerRef.current = null;
|
|
8756
|
+
setHoveredNavContainerRect(null);
|
|
8757
|
+
setHoveredItemRect(null);
|
|
8758
|
+
hoveredItemElRef.current = null;
|
|
8759
|
+
siblingHintElRef.current = null;
|
|
8760
|
+
setSiblingHintRect(null);
|
|
8761
|
+
setSiblingHintRects([]);
|
|
8762
|
+
setIsItemDragging(false);
|
|
8763
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
8764
|
+
setReorderHrefKey(key);
|
|
8765
|
+
setReorderDragDisabled(disabled);
|
|
8766
|
+
setIsFooterFrameSelection(false);
|
|
8767
|
+
setToolbarVariant("link-action");
|
|
8768
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
8769
|
+
setToolbarShowEditLink(false);
|
|
8770
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8771
|
+
},
|
|
8772
|
+
[deactivate]
|
|
8773
|
+
);
|
|
8774
|
+
const selectFrame = (0, import_react9.useCallback)(
|
|
8775
|
+
(el) => {
|
|
8776
|
+
if (!isNavigationContainer(el)) return;
|
|
8777
|
+
if (activeElRef.current) deactivate();
|
|
8778
|
+
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
8779
|
+
selectedElRef.current = el;
|
|
8780
|
+
clearHrefKeyHover(el);
|
|
8781
|
+
hoveredNavContainerRef.current = null;
|
|
8782
|
+
setHoveredNavContainerRect(null);
|
|
8783
|
+
setHoveredItemRect(null);
|
|
8784
|
+
hoveredItemElRef.current = null;
|
|
8785
|
+
siblingHintElRef.current = null;
|
|
8786
|
+
setSiblingHintRect(null);
|
|
8787
|
+
setSiblingHintRects(
|
|
8788
|
+
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
8789
|
+
);
|
|
8790
|
+
setIsItemDragging(false);
|
|
7918
8791
|
setReorderHrefKey(null);
|
|
7919
8792
|
setReorderDragDisabled(false);
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
8793
|
+
setIsFooterFrameSelection(isFooterColumn);
|
|
8794
|
+
setToolbarVariant("select-frame");
|
|
8795
|
+
setToolbarRect(el.getBoundingClientRect());
|
|
8796
|
+
setToolbarShowEditLink(false);
|
|
8797
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8798
|
+
},
|
|
8799
|
+
[deactivate]
|
|
8800
|
+
);
|
|
8801
|
+
const activate = (0, import_react9.useCallback)(
|
|
8802
|
+
(el, options) => {
|
|
8803
|
+
if (activeElRef.current === el) return;
|
|
8804
|
+
selectedElRef.current = null;
|
|
8805
|
+
deactivate();
|
|
8806
|
+
if (hoveredImageRef.current) {
|
|
8807
|
+
hoveredImageRef.current = null;
|
|
8808
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8809
|
+
}
|
|
8810
|
+
setToolbarVariant("rich-text");
|
|
8811
|
+
siblingHintElRef.current = null;
|
|
8812
|
+
setSiblingHintRect(null);
|
|
8813
|
+
setSiblingHintRects([]);
|
|
8814
|
+
setIsItemDragging(false);
|
|
8815
|
+
el.setAttribute("contenteditable", "true");
|
|
8816
|
+
el.removeAttribute("data-ohw-hovered");
|
|
8817
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
8818
|
+
activeElRef.current = el;
|
|
8819
|
+
originalContentRef.current = el.innerHTML;
|
|
8820
|
+
el.focus();
|
|
8821
|
+
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8822
|
+
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
8823
|
+
}
|
|
8824
|
+
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
8825
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
8826
|
+
if (navAnchor) {
|
|
8827
|
+
setReorderHrefKey(null);
|
|
8828
|
+
setReorderDragDisabled(false);
|
|
8829
|
+
} else {
|
|
8830
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
8831
|
+
setReorderHrefKey(reorderKey);
|
|
8832
|
+
setReorderDragDisabled(reorderDisabled);
|
|
8833
|
+
}
|
|
8834
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
8835
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
8836
|
+
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
8837
|
+
},
|
|
8838
|
+
[deactivate, postToParent2]
|
|
8839
|
+
);
|
|
7929
8840
|
activateRef.current = activate;
|
|
7930
8841
|
deactivateRef.current = deactivate;
|
|
7931
8842
|
selectRef.current = select;
|
|
7932
8843
|
selectFrameRef.current = selectFrame;
|
|
7933
8844
|
deselectRef.current = deselect;
|
|
7934
|
-
(0,
|
|
8845
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
7935
8846
|
if (!subdomain || isEditMode) {
|
|
7936
8847
|
setFetchState("done");
|
|
7937
8848
|
return;
|
|
@@ -7941,6 +8852,7 @@ function OhhwellsBridge() {
|
|
|
7941
8852
|
for (const [key, val] of Object.entries(content)) {
|
|
7942
8853
|
if (key === "__ohw_sections") continue;
|
|
7943
8854
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8855
|
+
if (applyCarouselNode(key, val)) continue;
|
|
7944
8856
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7945
8857
|
if (el.dataset.ohwEditable === "image") {
|
|
7946
8858
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7972,6 +8884,7 @@ function OhhwellsBridge() {
|
|
|
7972
8884
|
applyLinkByKey(key, val);
|
|
7973
8885
|
}
|
|
7974
8886
|
reconcileNavbarItemsFromContent(content);
|
|
8887
|
+
reconcileFooterOrderFromContent(content);
|
|
7975
8888
|
enforceLinkHrefs();
|
|
7976
8889
|
initSectionsFromContent(content, true);
|
|
7977
8890
|
sectionsLoadedRef.current = true;
|
|
@@ -8000,7 +8913,7 @@ function OhhwellsBridge() {
|
|
|
8000
8913
|
cancelled = true;
|
|
8001
8914
|
};
|
|
8002
8915
|
}, [subdomain, isEditMode]);
|
|
8003
|
-
(0,
|
|
8916
|
+
(0, import_react9.useEffect)(() => {
|
|
8004
8917
|
if (!subdomain || isEditMode) return;
|
|
8005
8918
|
let debounceTimer = null;
|
|
8006
8919
|
let observer = null;
|
|
@@ -8013,6 +8926,7 @@ function OhhwellsBridge() {
|
|
|
8013
8926
|
for (const [key, val] of Object.entries(content)) {
|
|
8014
8927
|
if (key === "__ohw_sections") continue;
|
|
8015
8928
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8929
|
+
if (applyCarouselNode(key, val)) continue;
|
|
8016
8930
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8017
8931
|
if (el.dataset.ohwEditable === "image") {
|
|
8018
8932
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8032,6 +8946,7 @@ function OhhwellsBridge() {
|
|
|
8032
8946
|
applyLinkByKey(key, val);
|
|
8033
8947
|
}
|
|
8034
8948
|
reconcileNavbarItemsFromContent(content);
|
|
8949
|
+
reconcileFooterOrderFromContent(content);
|
|
8035
8950
|
} finally {
|
|
8036
8951
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8037
8952
|
}
|
|
@@ -8049,16 +8964,16 @@ function OhhwellsBridge() {
|
|
|
8049
8964
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
8050
8965
|
};
|
|
8051
8966
|
}, [subdomain, isEditMode, pathname]);
|
|
8052
|
-
(0,
|
|
8967
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
8053
8968
|
const el = document.getElementById("ohw-loader");
|
|
8054
8969
|
if (!el) return;
|
|
8055
8970
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
8056
8971
|
el.style.display = visible ? "flex" : "none";
|
|
8057
8972
|
}, [subdomain, fetchState]);
|
|
8058
|
-
(0,
|
|
8973
|
+
(0, import_react9.useEffect)(() => {
|
|
8059
8974
|
postToParent2({ type: "ow:navigation", path: pathname });
|
|
8060
8975
|
}, [pathname, postToParent2]);
|
|
8061
|
-
(0,
|
|
8976
|
+
(0, import_react9.useEffect)(() => {
|
|
8062
8977
|
if (!isEditMode) return;
|
|
8063
8978
|
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8064
8979
|
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -8066,23 +8981,50 @@ function OhhwellsBridge() {
|
|
|
8066
8981
|
deselectRef.current();
|
|
8067
8982
|
deactivateRef.current();
|
|
8068
8983
|
}, [pathname, isEditMode]);
|
|
8069
|
-
(0,
|
|
8984
|
+
(0, import_react9.useEffect)(() => {
|
|
8070
8985
|
const contentForNav = () => {
|
|
8071
8986
|
if (isEditMode) return editContentRef.current;
|
|
8072
8987
|
if (!subdomain) return {};
|
|
8073
8988
|
return contentCache.get(subdomain) ?? {};
|
|
8074
8989
|
};
|
|
8075
|
-
|
|
8990
|
+
let applying = false;
|
|
8991
|
+
let rafId = null;
|
|
8992
|
+
const run = () => {
|
|
8993
|
+
if (footerDragRef.current || applying) return;
|
|
8994
|
+
applying = true;
|
|
8995
|
+
try {
|
|
8996
|
+
const content = contentForNav();
|
|
8997
|
+
reconcileNavbarItemsFromContent(content);
|
|
8998
|
+
reconcileFooterOrderFromContent(content);
|
|
8999
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
9000
|
+
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9001
|
+
disableNativeHrefDrag(el);
|
|
9002
|
+
}
|
|
9003
|
+
});
|
|
9004
|
+
} finally {
|
|
9005
|
+
applying = false;
|
|
9006
|
+
}
|
|
9007
|
+
};
|
|
9008
|
+
const scheduleRun = () => {
|
|
9009
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
9010
|
+
rafId = requestAnimationFrame(() => {
|
|
9011
|
+
rafId = null;
|
|
9012
|
+
run();
|
|
9013
|
+
});
|
|
9014
|
+
};
|
|
8076
9015
|
run();
|
|
8077
9016
|
const nav = document.querySelector("nav");
|
|
8078
|
-
|
|
8079
|
-
const observer = new MutationObserver(
|
|
8080
|
-
|
|
8081
|
-
});
|
|
8082
|
-
|
|
8083
|
-
return () =>
|
|
9017
|
+
const footer = document.querySelector("footer");
|
|
9018
|
+
const observer = new MutationObserver(scheduleRun);
|
|
9019
|
+
if (nav) observer.observe(nav, { childList: true, subtree: true });
|
|
9020
|
+
if (footer) observer.observe(footer, { childList: true, subtree: true });
|
|
9021
|
+
if (!nav && !footer) return;
|
|
9022
|
+
return () => {
|
|
9023
|
+
observer.disconnect();
|
|
9024
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
9025
|
+
};
|
|
8084
9026
|
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8085
|
-
(0,
|
|
9027
|
+
(0, import_react9.useEffect)(() => {
|
|
8086
9028
|
if (!isEditMode) return;
|
|
8087
9029
|
const measure = () => {
|
|
8088
9030
|
const h = document.body.scrollHeight;
|
|
@@ -8106,7 +9048,7 @@ function OhhwellsBridge() {
|
|
|
8106
9048
|
window.removeEventListener("resize", handleResize);
|
|
8107
9049
|
};
|
|
8108
9050
|
}, [pathname, isEditMode, postToParent2]);
|
|
8109
|
-
(0,
|
|
9051
|
+
(0, import_react9.useEffect)(() => {
|
|
8110
9052
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8111
9053
|
const handleClick = (e) => {
|
|
8112
9054
|
const anchor = e.target.closest("a");
|
|
@@ -8122,7 +9064,7 @@ function OhhwellsBridge() {
|
|
|
8122
9064
|
document.addEventListener("click", handleClick, true);
|
|
8123
9065
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8124
9066
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8125
|
-
(0,
|
|
9067
|
+
(0, import_react9.useEffect)(() => {
|
|
8126
9068
|
if (!isEditMode) {
|
|
8127
9069
|
editStylesRef.current?.base.remove();
|
|
8128
9070
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -8145,6 +9087,32 @@ function OhhwellsBridge() {
|
|
|
8145
9087
|
[data-ohw-editable] {
|
|
8146
9088
|
display: block;
|
|
8147
9089
|
}
|
|
9090
|
+
/* Native <a> drag steals clicks \u2014 disable for edit links; reorder via press-to-drag / handle. */
|
|
9091
|
+
footer [data-ohw-href-key] {
|
|
9092
|
+
-webkit-user-drag: none !important;
|
|
9093
|
+
}
|
|
9094
|
+
footer [data-ohw-footer-col]:hover {
|
|
9095
|
+
outline: 1.5px dashed ${PRIMARY2} !important;
|
|
9096
|
+
outline-offset: 6px;
|
|
9097
|
+
border-radius: 8px;
|
|
9098
|
+
}
|
|
9099
|
+
html[data-ohw-link-popover-open] footer [data-ohw-footer-col]:hover {
|
|
9100
|
+
outline: none !important;
|
|
9101
|
+
}
|
|
9102
|
+
html[data-ohw-footer-press-drag] footer,
|
|
9103
|
+
html[data-ohw-footer-press-drag] footer * {
|
|
9104
|
+
user-select: none !important;
|
|
9105
|
+
-webkit-user-select: none !important;
|
|
9106
|
+
}
|
|
9107
|
+
html[data-ohw-item-dragging] footer,
|
|
9108
|
+
html[data-ohw-item-dragging] footer * {
|
|
9109
|
+
user-select: none !important;
|
|
9110
|
+
-webkit-user-select: none !important;
|
|
9111
|
+
pointer-events: none !important;
|
|
9112
|
+
}
|
|
9113
|
+
html[data-ohw-item-dragging] {
|
|
9114
|
+
cursor: grabbing !important;
|
|
9115
|
+
}
|
|
8148
9116
|
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
8149
9117
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8150
9118
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
@@ -8189,12 +9157,39 @@ function OhhwellsBridge() {
|
|
|
8189
9157
|
}
|
|
8190
9158
|
refreshStateRules();
|
|
8191
9159
|
const handleClick = (e) => {
|
|
9160
|
+
if (suppressNextClickRef.current) {
|
|
9161
|
+
suppressNextClickRef.current = false;
|
|
9162
|
+
e.preventDefault();
|
|
9163
|
+
e.stopPropagation();
|
|
9164
|
+
return;
|
|
9165
|
+
}
|
|
8192
9166
|
const target = e.target;
|
|
8193
9167
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8194
9168
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8195
9169
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8196
9170
|
if (isInsideLinkEditor(target)) return;
|
|
8197
9171
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9172
|
+
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
9173
|
+
e.preventDefault();
|
|
9174
|
+
e.stopPropagation();
|
|
9175
|
+
const selected = selectedElRef.current;
|
|
9176
|
+
if (selected && isNavigationItem(selected)) {
|
|
9177
|
+
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9178
|
+
if (editable2) {
|
|
9179
|
+
activateRef.current(editable2, {
|
|
9180
|
+
caretX: e.clientX,
|
|
9181
|
+
caretY: e.clientY
|
|
9182
|
+
});
|
|
9183
|
+
}
|
|
9184
|
+
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
9185
|
+
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
9186
|
+
const r2 = el.getBoundingClientRect();
|
|
9187
|
+
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
9188
|
+
});
|
|
9189
|
+
if (link) selectRef.current(link);
|
|
9190
|
+
}
|
|
9191
|
+
return;
|
|
9192
|
+
}
|
|
8198
9193
|
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8199
9194
|
if (navFromChrome) {
|
|
8200
9195
|
e.preventDefault();
|
|
@@ -8224,7 +9219,15 @@ function OhhwellsBridge() {
|
|
|
8224
9219
|
if (isMediaEditable(editable)) {
|
|
8225
9220
|
e.preventDefault();
|
|
8226
9221
|
e.stopPropagation();
|
|
8227
|
-
|
|
9222
|
+
const key = editable.dataset.ohwKey ?? "";
|
|
9223
|
+
const r2 = editable.getBoundingClientRect();
|
|
9224
|
+
if (key && r2.width > 1 && r2.height > 1) {
|
|
9225
|
+
pendingUploadRectRef.current = {
|
|
9226
|
+
key,
|
|
9227
|
+
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height }
|
|
9228
|
+
};
|
|
9229
|
+
}
|
|
9230
|
+
postToParentRef.current({ type: "ow:image-pick", key, elementType: editable.dataset.ohwEditable ?? "image" });
|
|
8228
9231
|
return;
|
|
8229
9232
|
}
|
|
8230
9233
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
@@ -8249,10 +9252,26 @@ function OhhwellsBridge() {
|
|
|
8249
9252
|
if (hrefAnchor) {
|
|
8250
9253
|
e.preventDefault();
|
|
8251
9254
|
e.stopPropagation();
|
|
8252
|
-
if (selectedElRef.current === hrefAnchor)
|
|
9255
|
+
if (selectedElRef.current === hrefAnchor) {
|
|
9256
|
+
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
9257
|
+
if (textEditable) {
|
|
9258
|
+
activateRef.current(textEditable, {
|
|
9259
|
+
caretX: e.clientX,
|
|
9260
|
+
caretY: e.clientY
|
|
9261
|
+
});
|
|
9262
|
+
}
|
|
9263
|
+
return;
|
|
9264
|
+
}
|
|
8253
9265
|
selectRef.current(hrefAnchor);
|
|
8254
9266
|
return;
|
|
8255
9267
|
}
|
|
9268
|
+
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
9269
|
+
if (footerColClick) {
|
|
9270
|
+
e.preventDefault();
|
|
9271
|
+
e.stopPropagation();
|
|
9272
|
+
selectFrameRef.current(footerColClick);
|
|
9273
|
+
return;
|
|
9274
|
+
}
|
|
8256
9275
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8257
9276
|
if (navContainerToSelect) {
|
|
8258
9277
|
e.preventDefault();
|
|
@@ -8319,6 +9338,13 @@ function OhhwellsBridge() {
|
|
|
8319
9338
|
const handleMouseOver = (e) => {
|
|
8320
9339
|
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
8321
9340
|
const target = e.target;
|
|
9341
|
+
if (linkPopoverOpenRef.current) {
|
|
9342
|
+
hoveredItemElRef.current = null;
|
|
9343
|
+
setHoveredItemRect(null);
|
|
9344
|
+
hoveredNavContainerRef.current = null;
|
|
9345
|
+
setHoveredNavContainerRect(null);
|
|
9346
|
+
return;
|
|
9347
|
+
}
|
|
8322
9348
|
if (toolbarVariantRef.current !== "select-frame") {
|
|
8323
9349
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8324
9350
|
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
@@ -8333,6 +9359,15 @@ function OhhwellsBridge() {
|
|
|
8333
9359
|
setHoveredNavContainerRect(null);
|
|
8334
9360
|
}
|
|
8335
9361
|
}
|
|
9362
|
+
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9363
|
+
if (footerCol) {
|
|
9364
|
+
hoveredNavContainerRef.current = null;
|
|
9365
|
+
setHoveredNavContainerRect(null);
|
|
9366
|
+
if (selectedElRef.current === footerCol) return;
|
|
9367
|
+
hoveredItemElRef.current = footerCol;
|
|
9368
|
+
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
9369
|
+
return;
|
|
9370
|
+
}
|
|
8336
9371
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8337
9372
|
if (navAnchor) {
|
|
8338
9373
|
hoveredNavContainerRef.current = null;
|
|
@@ -8369,6 +9404,15 @@ function OhhwellsBridge() {
|
|
|
8369
9404
|
hoveredNavContainerRef.current = null;
|
|
8370
9405
|
setHoveredNavContainerRect(null);
|
|
8371
9406
|
}
|
|
9407
|
+
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9408
|
+
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
9409
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9410
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
9411
|
+
if (related2?.closest("[data-ohw-footer-col]") === footerCol) return;
|
|
9412
|
+
hoveredItemElRef.current = null;
|
|
9413
|
+
setHoveredItemRect(null);
|
|
9414
|
+
return;
|
|
9415
|
+
}
|
|
8372
9416
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8373
9417
|
if (navAnchor) {
|
|
8374
9418
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -8480,12 +9524,12 @@ function OhhwellsBridge() {
|
|
|
8480
9524
|
const stickyPad = 48;
|
|
8481
9525
|
const withinPad = x >= pr.left - stickyPad && x <= pr.left + pr.width + stickyPad && y >= pr.top - stickyPad && y <= pr.top + pr.height + stickyPad;
|
|
8482
9526
|
if (withinPad) {
|
|
8483
|
-
|
|
9527
|
+
const yieldToSmaller = smallest !== pinned && candidatePool.includes(smallest) && (() => {
|
|
8484
9528
|
const sr = getVisibleRect(smallest);
|
|
8485
|
-
const
|
|
8486
|
-
|
|
8487
|
-
}
|
|
8488
|
-
return pinned;
|
|
9529
|
+
const pr2 = getVisibleRect(pinned);
|
|
9530
|
+
return sr.width * sr.height < pr2.width * pr2.height;
|
|
9531
|
+
})();
|
|
9532
|
+
if (!yieldToSmaller) return pinned;
|
|
8489
9533
|
}
|
|
8490
9534
|
}
|
|
8491
9535
|
return smallest;
|
|
@@ -8497,6 +9541,7 @@ function OhhwellsBridge() {
|
|
|
8497
9541
|
resumeAnimTracks();
|
|
8498
9542
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8499
9543
|
}
|
|
9544
|
+
clearImageHover();
|
|
8500
9545
|
};
|
|
8501
9546
|
const probeNavigationHoverAt = (x, y) => {
|
|
8502
9547
|
if (toolbarVariantRef.current === "select-frame") {
|
|
@@ -8599,7 +9644,7 @@ function OhhwellsBridge() {
|
|
|
8599
9644
|
return;
|
|
8600
9645
|
}
|
|
8601
9646
|
const topEl = document.elementFromPoint(x2, y2);
|
|
8602
|
-
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9647
|
+
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-media-chrome]')) {
|
|
8603
9648
|
if (hoveredImageRef.current) {
|
|
8604
9649
|
hoveredImageRef.current = null;
|
|
8605
9650
|
resumeAnimTracks();
|
|
@@ -8806,6 +9851,14 @@ function OhhwellsBridge() {
|
|
|
8806
9851
|
probeHoverCardsAt(clientX, clientY);
|
|
8807
9852
|
};
|
|
8808
9853
|
const handleDragOver = (e) => {
|
|
9854
|
+
const footerSession = footerDragRef.current;
|
|
9855
|
+
if (footerSession) {
|
|
9856
|
+
e.preventDefault();
|
|
9857
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
9858
|
+
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
9859
|
+
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
9860
|
+
return;
|
|
9861
|
+
}
|
|
8809
9862
|
e.preventDefault();
|
|
8810
9863
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
8811
9864
|
if (!el) {
|
|
@@ -8874,6 +9927,7 @@ function OhhwellsBridge() {
|
|
|
8874
9927
|
if (!entry || entry.fadingOut) return prev;
|
|
8875
9928
|
return { ...prev, [key]: { ...entry, fadingOut: true } };
|
|
8876
9929
|
});
|
|
9930
|
+
if (pendingUploadRectRef.current?.key === key) pendingUploadRectRef.current = null;
|
|
8877
9931
|
};
|
|
8878
9932
|
let found = false;
|
|
8879
9933
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -8988,6 +10042,7 @@ function OhhwellsBridge() {
|
|
|
8988
10042
|
continue;
|
|
8989
10043
|
}
|
|
8990
10044
|
if (applyVideoSettingNode(key, val)) continue;
|
|
10045
|
+
if (applyCarouselNode(key, val)) continue;
|
|
8991
10046
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8992
10047
|
if (el.dataset.ohwEditable === "image") {
|
|
8993
10048
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -9012,6 +10067,7 @@ function OhhwellsBridge() {
|
|
|
9012
10067
|
}
|
|
9013
10068
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9014
10069
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
10070
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
9015
10071
|
enforceLinkHrefs();
|
|
9016
10072
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9017
10073
|
};
|
|
@@ -9125,6 +10181,17 @@ function OhhwellsBridge() {
|
|
|
9125
10181
|
if (siblingHintElRef.current) {
|
|
9126
10182
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
9127
10183
|
}
|
|
10184
|
+
const selected = selectedElRef.current;
|
|
10185
|
+
if (selected && !footerDragRef.current && (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)))) {
|
|
10186
|
+
setSiblingHintRects(
|
|
10187
|
+
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
10188
|
+
);
|
|
10189
|
+
}
|
|
10190
|
+
if (footerDragRef.current) {
|
|
10191
|
+
const session = footerDragRef.current;
|
|
10192
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
10193
|
+
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
10194
|
+
}
|
|
9128
10195
|
if (hoveredImageRef.current) {
|
|
9129
10196
|
const el = hoveredImageRef.current;
|
|
9130
10197
|
const r2 = el.getBoundingClientRect();
|
|
@@ -9135,7 +10202,7 @@ function OhhwellsBridge() {
|
|
|
9135
10202
|
};
|
|
9136
10203
|
const handleSave = (e) => {
|
|
9137
10204
|
if (e.data?.type !== "ow:save") return;
|
|
9138
|
-
const nodes = collectEditableNodes();
|
|
10205
|
+
const nodes = collectEditableNodes(editContentRef.current);
|
|
9139
10206
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
9140
10207
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
9141
10208
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -9220,28 +10287,49 @@ function OhhwellsBridge() {
|
|
|
9220
10287
|
const handleDocMouseLeave = () => {
|
|
9221
10288
|
hoveredImageRef.current = null;
|
|
9222
10289
|
setMediaHover(null);
|
|
10290
|
+
setCarouselHover(null);
|
|
9223
10291
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
9224
10292
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
9225
10293
|
activeStateElRef.current = null;
|
|
9226
10294
|
setToggleState(null);
|
|
9227
10295
|
};
|
|
10296
|
+
const resolveUploadRects = (key) => {
|
|
10297
|
+
const matches = Array.from(document.querySelectorAll(`[data-ohw-key="${key}"]`));
|
|
10298
|
+
const rects = matches.map((el) => {
|
|
10299
|
+
const r2 = el.getBoundingClientRect();
|
|
10300
|
+
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
10301
|
+
}).filter((r2) => r2.width > 1 && r2.height > 1);
|
|
10302
|
+
if (rects.length > 0) return rects;
|
|
10303
|
+
const pending = pendingUploadRectRef.current;
|
|
10304
|
+
if (pending?.key === key && pending.rect.width > 1 && pending.rect.height > 1) {
|
|
10305
|
+
return [pending.rect];
|
|
10306
|
+
}
|
|
10307
|
+
const hovered = hoveredImageRef.current;
|
|
10308
|
+
if (hovered?.dataset.ohwKey === key) {
|
|
10309
|
+
const r2 = hovered.getBoundingClientRect();
|
|
10310
|
+
if (r2.width > 1 && r2.height > 1) {
|
|
10311
|
+
return [{ top: r2.top, left: r2.left, width: r2.width, height: r2.height }];
|
|
10312
|
+
}
|
|
10313
|
+
}
|
|
10314
|
+
return [];
|
|
10315
|
+
};
|
|
9228
10316
|
const handleImageUploading = (e) => {
|
|
9229
|
-
|
|
9230
|
-
|
|
10317
|
+
const type = e.data?.type;
|
|
10318
|
+
if (type !== "ow:image-uploading" && type !== "ow:anim-lock") return;
|
|
10319
|
+
const key = e.data.key;
|
|
10320
|
+
if (!key) return;
|
|
10321
|
+
const uploading = type === "ow:anim-lock" ? true : !!e.data.uploading;
|
|
9231
10322
|
setUploadingRects((prev) => {
|
|
9232
10323
|
if (!uploading) {
|
|
10324
|
+
if (pendingUploadRectRef.current?.key === key) pendingUploadRectRef.current = null;
|
|
9233
10325
|
if (!(key in prev)) return prev;
|
|
9234
10326
|
const next = { ...prev };
|
|
9235
10327
|
delete next[key];
|
|
9236
10328
|
return next;
|
|
9237
10329
|
}
|
|
9238
|
-
const
|
|
9239
|
-
if (
|
|
9240
|
-
|
|
9241
|
-
return {
|
|
9242
|
-
...prev,
|
|
9243
|
-
[key]: { rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
9244
|
-
};
|
|
10330
|
+
const rects = resolveUploadRects(key);
|
|
10331
|
+
if (rects.length === 0) return prev;
|
|
10332
|
+
return { ...prev, [key]: { rects } };
|
|
9245
10333
|
});
|
|
9246
10334
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9247
10335
|
const track = el.closest("[data-ohw-hover-pause]");
|
|
@@ -9259,6 +10347,48 @@ function OhhwellsBridge() {
|
|
|
9259
10347
|
if (e.data?.type !== "ow:canvas-height" || typeof e.data.height !== "number") return;
|
|
9260
10348
|
document.documentElement.style.setProperty("--ohw-canvas-h", `${e.data.height}px`);
|
|
9261
10349
|
};
|
|
10350
|
+
const handleCarouselChange = (e) => {
|
|
10351
|
+
if (e.data?.type !== "ow:carousel-change") return;
|
|
10352
|
+
const { key, images } = e.data;
|
|
10353
|
+
if (!key || !Array.isArray(images)) return;
|
|
10354
|
+
const text = JSON.stringify(images);
|
|
10355
|
+
applyCarouselValue(key, images);
|
|
10356
|
+
editContentRef.current = { ...editContentRef.current, [key]: text };
|
|
10357
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key, text }] });
|
|
10358
|
+
setCarouselHover(null);
|
|
10359
|
+
};
|
|
10360
|
+
const findCarouselAtPoint = (clientX, clientY) => {
|
|
10361
|
+
const containers = Array.from(document.querySelectorAll(`[${CAROUSEL_ATTR}]`));
|
|
10362
|
+
for (let i = containers.length - 1; i >= 0; i--) {
|
|
10363
|
+
const r2 = containers[i].getBoundingClientRect();
|
|
10364
|
+
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) {
|
|
10365
|
+
return containers[i];
|
|
10366
|
+
}
|
|
10367
|
+
}
|
|
10368
|
+
return null;
|
|
10369
|
+
};
|
|
10370
|
+
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
10371
|
+
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
10372
|
+
for (const el of editables) {
|
|
10373
|
+
const r2 = el.getBoundingClientRect();
|
|
10374
|
+
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
10375
|
+
}
|
|
10376
|
+
return false;
|
|
10377
|
+
};
|
|
10378
|
+
const handleCarouselHover = (e) => {
|
|
10379
|
+
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
10380
|
+
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
10381
|
+
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
10382
|
+
setCarouselHover((prev) => prev ? null : prev);
|
|
10383
|
+
return;
|
|
10384
|
+
}
|
|
10385
|
+
const key = container.getAttribute("data-ohw-key") ?? "";
|
|
10386
|
+
if (!key) return;
|
|
10387
|
+
const r2 = getVisibleRect(container);
|
|
10388
|
+
setCarouselHover(
|
|
10389
|
+
(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 } }
|
|
10390
|
+
);
|
|
10391
|
+
};
|
|
9262
10392
|
const applyToolbarPos = (rect) => {
|
|
9263
10393
|
const ps = parentScrollRef.current;
|
|
9264
10394
|
const approxW = 330;
|
|
@@ -9367,6 +10497,7 @@ function OhhwellsBridge() {
|
|
|
9367
10497
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
9368
10498
|
window.addEventListener("message", handleImageUrl);
|
|
9369
10499
|
window.addEventListener("message", handleImageUploading);
|
|
10500
|
+
window.addEventListener("message", handleCarouselChange);
|
|
9370
10501
|
window.addEventListener("message", handleCanvasHeight);
|
|
9371
10502
|
window.addEventListener("message", handleParentScroll);
|
|
9372
10503
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -9384,6 +10515,7 @@ function OhhwellsBridge() {
|
|
|
9384
10515
|
document.addEventListener("mouseover", handleMouseOver, true);
|
|
9385
10516
|
document.addEventListener("mouseout", handleMouseOut, true);
|
|
9386
10517
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
10518
|
+
document.addEventListener("mousemove", handleCarouselHover, true);
|
|
9387
10519
|
document.addEventListener("mouseleave", handleDocMouseLeave);
|
|
9388
10520
|
document.addEventListener("dragover", handleDragOver, true);
|
|
9389
10521
|
document.addEventListener("dragleave", handleDragLeave, true);
|
|
@@ -9399,6 +10531,7 @@ function OhhwellsBridge() {
|
|
|
9399
10531
|
document.removeEventListener("mouseover", handleMouseOver, true);
|
|
9400
10532
|
document.removeEventListener("mouseout", handleMouseOut, true);
|
|
9401
10533
|
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
10534
|
+
document.removeEventListener("mousemove", handleCarouselHover, true);
|
|
9402
10535
|
document.removeEventListener("mouseleave", handleDocMouseLeave);
|
|
9403
10536
|
document.removeEventListener("dragover", handleDragOver, true);
|
|
9404
10537
|
document.removeEventListener("dragleave", handleDragLeave, true);
|
|
@@ -9414,6 +10547,7 @@ function OhhwellsBridge() {
|
|
|
9414
10547
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
9415
10548
|
window.removeEventListener("message", handleImageUrl);
|
|
9416
10549
|
window.removeEventListener("message", handleImageUploading);
|
|
10550
|
+
window.removeEventListener("message", handleCarouselChange);
|
|
9417
10551
|
window.removeEventListener("message", handleCanvasHeight);
|
|
9418
10552
|
window.removeEventListener("message", handleParentScroll);
|
|
9419
10553
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -9428,7 +10562,158 @@ function OhhwellsBridge() {
|
|
|
9428
10562
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
9429
10563
|
};
|
|
9430
10564
|
}, [isEditMode, refreshStateRules]);
|
|
9431
|
-
(0,
|
|
10565
|
+
(0, import_react9.useEffect)(() => {
|
|
10566
|
+
if (!isEditMode) return;
|
|
10567
|
+
const THRESHOLD = 10;
|
|
10568
|
+
const resolveWasSelected = (el) => {
|
|
10569
|
+
if (selectedElRef.current === el) return true;
|
|
10570
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
10571
|
+
return activeAnchor === el;
|
|
10572
|
+
};
|
|
10573
|
+
const onPointerDown = (e) => {
|
|
10574
|
+
if (e.button !== 0) return;
|
|
10575
|
+
if (suppressNextClickRef.current && !footerDragRef.current && !footerPointerDragRef.current?.started) {
|
|
10576
|
+
suppressNextClickRef.current = false;
|
|
10577
|
+
}
|
|
10578
|
+
if (footerDragRef.current) return;
|
|
10579
|
+
const target = e.target;
|
|
10580
|
+
if (!target) return;
|
|
10581
|
+
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]')) {
|
|
10582
|
+
return;
|
|
10583
|
+
}
|
|
10584
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
10585
|
+
const anchor = getNavigationItemAnchor(target);
|
|
10586
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
10587
|
+
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
10588
|
+
armFooterPressDrag();
|
|
10589
|
+
footerPointerDragRef.current = {
|
|
10590
|
+
el: anchor,
|
|
10591
|
+
kind: "link",
|
|
10592
|
+
startX: e.clientX,
|
|
10593
|
+
startY: e.clientY,
|
|
10594
|
+
pointerId: e.pointerId,
|
|
10595
|
+
wasSelected: resolveWasSelected(anchor),
|
|
10596
|
+
started: false
|
|
10597
|
+
};
|
|
10598
|
+
return;
|
|
10599
|
+
}
|
|
10600
|
+
const col = target.closest("[data-ohw-footer-col]");
|
|
10601
|
+
if (col && !getNavigationItemAnchor(target)) {
|
|
10602
|
+
armFooterPressDrag();
|
|
10603
|
+
footerPointerDragRef.current = {
|
|
10604
|
+
el: col,
|
|
10605
|
+
kind: "column",
|
|
10606
|
+
startX: e.clientX,
|
|
10607
|
+
startY: e.clientY,
|
|
10608
|
+
pointerId: e.pointerId,
|
|
10609
|
+
wasSelected: resolveWasSelected(col),
|
|
10610
|
+
started: false
|
|
10611
|
+
};
|
|
10612
|
+
}
|
|
10613
|
+
};
|
|
10614
|
+
const onPointerMove = (e) => {
|
|
10615
|
+
const pending = footerPointerDragRef.current;
|
|
10616
|
+
if (!pending) return;
|
|
10617
|
+
if (pending.started) {
|
|
10618
|
+
e.preventDefault();
|
|
10619
|
+
clearTextSelection();
|
|
10620
|
+
const session = footerDragRef.current;
|
|
10621
|
+
if (!session) return;
|
|
10622
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10623
|
+
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
10624
|
+
return;
|
|
10625
|
+
}
|
|
10626
|
+
const dx = e.clientX - pending.startX;
|
|
10627
|
+
const dy = e.clientY - pending.startY;
|
|
10628
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
10629
|
+
e.preventDefault();
|
|
10630
|
+
pending.started = true;
|
|
10631
|
+
clearTextSelection();
|
|
10632
|
+
try {
|
|
10633
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
10634
|
+
} catch {
|
|
10635
|
+
}
|
|
10636
|
+
if (linkPopoverOpenRef.current) {
|
|
10637
|
+
setLinkPopoverRef.current(null);
|
|
10638
|
+
}
|
|
10639
|
+
if (activeElRef.current) {
|
|
10640
|
+
deactivateRef.current();
|
|
10641
|
+
}
|
|
10642
|
+
if (pending.kind === "link") {
|
|
10643
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
10644
|
+
if (!key) return;
|
|
10645
|
+
const column = findFooterColumnForLink(pending.el);
|
|
10646
|
+
const columns2 = listFooterColumns();
|
|
10647
|
+
beginFooterDragRef.current({
|
|
10648
|
+
kind: "link",
|
|
10649
|
+
hrefKey: key,
|
|
10650
|
+
columnEl: column,
|
|
10651
|
+
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
10652
|
+
wasSelected: pending.wasSelected,
|
|
10653
|
+
draggedEl: pending.el,
|
|
10654
|
+
lastClientX: e.clientX,
|
|
10655
|
+
lastClientY: e.clientY,
|
|
10656
|
+
activeSlot: null
|
|
10657
|
+
});
|
|
10658
|
+
return;
|
|
10659
|
+
}
|
|
10660
|
+
const columns = listFooterColumns();
|
|
10661
|
+
const idx = columns.indexOf(pending.el);
|
|
10662
|
+
if (idx < 0) return;
|
|
10663
|
+
beginFooterDragRef.current({
|
|
10664
|
+
kind: "column",
|
|
10665
|
+
hrefKey: null,
|
|
10666
|
+
columnEl: pending.el,
|
|
10667
|
+
sourceColumnIndex: idx,
|
|
10668
|
+
wasSelected: pending.wasSelected,
|
|
10669
|
+
draggedEl: pending.el,
|
|
10670
|
+
lastClientX: e.clientX,
|
|
10671
|
+
lastClientY: e.clientY,
|
|
10672
|
+
activeSlot: null
|
|
10673
|
+
});
|
|
10674
|
+
};
|
|
10675
|
+
const endPointerDrag = (e) => {
|
|
10676
|
+
const pending = footerPointerDragRef.current;
|
|
10677
|
+
footerPointerDragRef.current = null;
|
|
10678
|
+
try {
|
|
10679
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
10680
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
10681
|
+
}
|
|
10682
|
+
} catch {
|
|
10683
|
+
}
|
|
10684
|
+
if (!pending?.started) {
|
|
10685
|
+
unlockFooterDragInteraction();
|
|
10686
|
+
return;
|
|
10687
|
+
}
|
|
10688
|
+
suppressNextClickRef.current = true;
|
|
10689
|
+
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
10690
|
+
};
|
|
10691
|
+
const blockSelectStart = (e) => {
|
|
10692
|
+
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
10693
|
+
e.preventDefault();
|
|
10694
|
+
}
|
|
10695
|
+
};
|
|
10696
|
+
const onDragEnd = (_e) => {
|
|
10697
|
+
if (!footerDragRef.current) return;
|
|
10698
|
+
commitFooterDragRef.current();
|
|
10699
|
+
};
|
|
10700
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
10701
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
10702
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
10703
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
10704
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
10705
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
10706
|
+
return () => {
|
|
10707
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
10708
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
10709
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
10710
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
10711
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
10712
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
10713
|
+
unlockFooterDragInteraction();
|
|
10714
|
+
};
|
|
10715
|
+
}, [isEditMode]);
|
|
10716
|
+
(0, import_react9.useEffect)(() => {
|
|
9432
10717
|
const handler = (e) => {
|
|
9433
10718
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
9434
10719
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -9444,7 +10729,7 @@ function OhhwellsBridge() {
|
|
|
9444
10729
|
window.addEventListener("message", handler);
|
|
9445
10730
|
return () => window.removeEventListener("message", handler);
|
|
9446
10731
|
}, [processConfigRequest]);
|
|
9447
|
-
(0,
|
|
10732
|
+
(0, import_react9.useEffect)(() => {
|
|
9448
10733
|
if (!isEditMode) return;
|
|
9449
10734
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
9450
10735
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -9465,7 +10750,13 @@ function OhhwellsBridge() {
|
|
|
9465
10750
|
const next = { ...prev, [pathKey]: sections };
|
|
9466
10751
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
9467
10752
|
});
|
|
9468
|
-
postToParent2({
|
|
10753
|
+
postToParent2({
|
|
10754
|
+
type: "ow:ready",
|
|
10755
|
+
version: "1",
|
|
10756
|
+
path: pathname,
|
|
10757
|
+
nodes: collectEditableNodes(editContentRef.current),
|
|
10758
|
+
sections
|
|
10759
|
+
});
|
|
9469
10760
|
postToParent2({ type: "ow:request-site-pages" });
|
|
9470
10761
|
}, 150);
|
|
9471
10762
|
return () => {
|
|
@@ -9473,19 +10764,19 @@ function OhhwellsBridge() {
|
|
|
9473
10764
|
clearTimeout(timer);
|
|
9474
10765
|
};
|
|
9475
10766
|
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9476
|
-
(0,
|
|
10767
|
+
(0, import_react9.useEffect)(() => {
|
|
9477
10768
|
scrollToHashSectionWhenReady();
|
|
9478
10769
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
9479
10770
|
window.addEventListener("hashchange", onHashChange);
|
|
9480
10771
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
9481
10772
|
}, [pathname]);
|
|
9482
|
-
const handleCommand = (0,
|
|
10773
|
+
const handleCommand = (0, import_react9.useCallback)((cmd) => {
|
|
9483
10774
|
document.execCommand(cmd, false);
|
|
9484
10775
|
activeElRef.current?.focus();
|
|
9485
10776
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
9486
10777
|
refreshActiveCommandsRef.current();
|
|
9487
10778
|
}, []);
|
|
9488
|
-
const handleStateChange = (0,
|
|
10779
|
+
const handleStateChange = (0, import_react9.useCallback)((state) => {
|
|
9489
10780
|
if (!activeStateElRef.current) return;
|
|
9490
10781
|
const el = activeStateElRef.current;
|
|
9491
10782
|
if (state === "Default") {
|
|
@@ -9498,11 +10789,11 @@ function OhhwellsBridge() {
|
|
|
9498
10789
|
}
|
|
9499
10790
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
9500
10791
|
}, [deactivate]);
|
|
9501
|
-
const closeLinkPopover = (0,
|
|
10792
|
+
const closeLinkPopover = (0, import_react9.useCallback)(() => {
|
|
9502
10793
|
addNavAfterAnchorRef.current = null;
|
|
9503
10794
|
setLinkPopover(null);
|
|
9504
10795
|
}, []);
|
|
9505
|
-
const openLinkPopoverForActive = (0,
|
|
10796
|
+
const openLinkPopoverForActive = (0, import_react9.useCallback)(() => {
|
|
9506
10797
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
9507
10798
|
if (!hrefCtx) return;
|
|
9508
10799
|
bumpLinkPopoverGrace();
|
|
@@ -9513,7 +10804,7 @@ function OhhwellsBridge() {
|
|
|
9513
10804
|
});
|
|
9514
10805
|
deactivate();
|
|
9515
10806
|
}, [deactivate]);
|
|
9516
|
-
const openLinkPopoverForSelected = (0,
|
|
10807
|
+
const openLinkPopoverForSelected = (0, import_react9.useCallback)(() => {
|
|
9517
10808
|
const anchor = selectedElRef.current;
|
|
9518
10809
|
if (!anchor) return;
|
|
9519
10810
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -9526,7 +10817,7 @@ function OhhwellsBridge() {
|
|
|
9526
10817
|
});
|
|
9527
10818
|
deselect();
|
|
9528
10819
|
}, [deselect]);
|
|
9529
|
-
const handleLinkPopoverSubmit = (0,
|
|
10820
|
+
const handleLinkPopoverSubmit = (0, import_react9.useCallback)(
|
|
9530
10821
|
(target) => {
|
|
9531
10822
|
const session = linkPopoverSessionRef.current;
|
|
9532
10823
|
if (!session) return;
|
|
@@ -9582,16 +10873,22 @@ function OhhwellsBridge() {
|
|
|
9582
10873
|
},
|
|
9583
10874
|
[postToParent2, sitePages, sectionsByPath]
|
|
9584
10875
|
);
|
|
9585
|
-
const
|
|
9586
|
-
const currentSections = sectionsByPath[pathname] ?? [];
|
|
9587
|
-
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9588
|
-
const handleMediaReplace = (0, import_react8.useCallback)(
|
|
10876
|
+
const handleMediaReplace = (0, import_react9.useCallback)(
|
|
9589
10877
|
(key) => {
|
|
10878
|
+
if (mediaHover?.key === key) {
|
|
10879
|
+
pendingUploadRectRef.current = { key, rect: mediaHover.rect };
|
|
10880
|
+
}
|
|
9590
10881
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
9591
10882
|
},
|
|
9592
|
-
[postToParent2, mediaHover
|
|
10883
|
+
[postToParent2, mediaHover]
|
|
10884
|
+
);
|
|
10885
|
+
const handleEditCarousel = (0, import_react9.useCallback)(
|
|
10886
|
+
(key) => {
|
|
10887
|
+
postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
|
|
10888
|
+
},
|
|
10889
|
+
[postToParent2]
|
|
9593
10890
|
);
|
|
9594
|
-
const handleMediaFadeOutComplete = (0,
|
|
10891
|
+
const handleMediaFadeOutComplete = (0, import_react9.useCallback)((key) => {
|
|
9595
10892
|
setUploadingRects((prev) => {
|
|
9596
10893
|
if (!(key in prev)) return prev;
|
|
9597
10894
|
const next = { ...prev };
|
|
@@ -9599,7 +10896,7 @@ function OhhwellsBridge() {
|
|
|
9599
10896
|
return next;
|
|
9600
10897
|
});
|
|
9601
10898
|
}, []);
|
|
9602
|
-
const handleVideoSettingsChange = (0,
|
|
10899
|
+
const handleVideoSettingsChange = (0, import_react9.useCallback)(
|
|
9603
10900
|
(key, settings) => {
|
|
9604
10901
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9605
10902
|
const video = getVideoEl(el);
|
|
@@ -9621,21 +10918,26 @@ function OhhwellsBridge() {
|
|
|
9621
10918
|
},
|
|
9622
10919
|
[postToParent2]
|
|
9623
10920
|
);
|
|
10921
|
+
const showEditLink = toolbarShowEditLink;
|
|
10922
|
+
const currentSections = sectionsByPath[pathname] ?? [];
|
|
10923
|
+
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9624
10924
|
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
9625
|
-
/* @__PURE__ */ (0,
|
|
9626
|
-
/* @__PURE__ */ (0,
|
|
9627
|
-
Object.entries(uploadingRects).
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
10925
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
10926
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
10927
|
+
Object.entries(uploadingRects).flatMap(
|
|
10928
|
+
([key, { rects, fadingOut }]) => rects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10929
|
+
MediaOverlay,
|
|
10930
|
+
{
|
|
10931
|
+
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
10932
|
+
isUploading: true,
|
|
10933
|
+
fadingOut,
|
|
10934
|
+
onFadeOutComplete: handleMediaFadeOutComplete,
|
|
10935
|
+
onReplace: handleMediaReplace
|
|
10936
|
+
},
|
|
10937
|
+
`uploading-${key}-${i}`
|
|
10938
|
+
))
|
|
10939
|
+
),
|
|
10940
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9639
10941
|
MediaOverlay,
|
|
9640
10942
|
{
|
|
9641
10943
|
hover: mediaHover,
|
|
@@ -9644,62 +10946,33 @@ function OhhwellsBridge() {
|
|
|
9644
10946
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
9645
10947
|
}
|
|
9646
10948
|
),
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
onAdd: handleAddTopLevelNavItem
|
|
9654
|
-
}
|
|
9655
|
-
),
|
|
9656
|
-
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9657
|
-
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9658
|
-
ItemInteractionLayer,
|
|
10949
|
+
carouselHover && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
10950
|
+
siblingHintRect && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
10951
|
+
siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
10952
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
10953
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10954
|
+
"div",
|
|
9659
10955
|
{
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
}
|
|
9678
|
-
),
|
|
9679
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9680
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9681
|
-
EditGlowChrome,
|
|
9682
|
-
{
|
|
9683
|
-
rect: toolbarRect,
|
|
9684
|
-
elRef: glowElRef,
|
|
9685
|
-
reorderHrefKey,
|
|
9686
|
-
dragDisabled: reorderDragDisabled
|
|
9687
|
-
}
|
|
9688
|
-
),
|
|
9689
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9690
|
-
FloatingToolbar,
|
|
9691
|
-
{
|
|
9692
|
-
rect: toolbarRect,
|
|
9693
|
-
parentScroll: parentScrollRef.current,
|
|
9694
|
-
elRef: toolbarElRef,
|
|
9695
|
-
onCommand: handleCommand,
|
|
9696
|
-
activeCommands,
|
|
9697
|
-
showEditLink,
|
|
9698
|
-
onEditLink: openLinkPopoverForActive
|
|
9699
|
-
}
|
|
9700
|
-
)
|
|
10956
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
10957
|
+
style: {
|
|
10958
|
+
left: slot.left,
|
|
10959
|
+
top: slot.top,
|
|
10960
|
+
width: slot.width,
|
|
10961
|
+
height: slot.height
|
|
10962
|
+
},
|
|
10963
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropIndicator, { direction: slot.direction, state: activeFooterDropIndex === i ? "dragActive" : "dragIdle", className: slot.direction === "horizontal" ? "!h-full !w-full" : "!h-full !w-full" })
|
|
10964
|
+
},
|
|
10965
|
+
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
10966
|
+
)),
|
|
10967
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
10968
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
10969
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !siblingHintRect && siblingHintRects.length === 0 && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
10970
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: isItemDragging && draggedItemRect && footerDragRef.current?.wasSelected ? draggedItemRect : toolbarRect, elRef: glowElRef, state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current), showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection, dragDisabled: reorderDragDisabled, dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item", onDragHandleDragStart: handleItemDragStart, onDragHandleDragEnd: handleItemDragEnd, onItemPointerDown: handleItemChromePointerDown, onItemClick: handleItemChromeClick, toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemActionToolbar, { onEditLink: openLinkPopoverForSelected, addItemDisabled: true, editLinkDisabled: false, moreDisabled: true }) : void 0 }),
|
|
10971
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
10972
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EditGlowChrome, { rect: toolbarRect, elRef: glowElRef, reorderHrefKey, dragDisabled: reorderDragDisabled }),
|
|
10973
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FloatingToolbar, { rect: toolbarRect, parentScroll: parentScrollRef.current, elRef: toolbarElRef, onCommand: handleCommand, activeCommands, showEditLink, onEditLink: openLinkPopoverForActive })
|
|
9701
10974
|
] }),
|
|
9702
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
10975
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
9703
10976
|
"div",
|
|
9704
10977
|
{
|
|
9705
10978
|
"data-ohw-max-badge": "",
|
|
@@ -9725,57 +10998,29 @@ function OhhwellsBridge() {
|
|
|
9725
10998
|
]
|
|
9726
10999
|
}
|
|
9727
11000
|
),
|
|
9728
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
9729
|
-
|
|
9730
|
-
{
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9742
|
-
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9743
|
-
children: [
|
|
9744
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9745
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9746
|
-
Badge,
|
|
9747
|
-
{
|
|
9748
|
-
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",
|
|
9749
|
-
onClick: () => {
|
|
9750
|
-
window.parent.postMessage(
|
|
9751
|
-
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
9752
|
-
"*"
|
|
9753
|
-
);
|
|
11001
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StateToggle, { rect: toggleState.rect, activeState: toggleState.activeState, states: toggleState.states, onStateChange: handleStateChange }),
|
|
11002
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-ohw-section-insert-line": "", className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none", style: { top: sectionGap.y, transform: "translateY(-50%)" }, children: [
|
|
11003
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
11004
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11005
|
+
Badge,
|
|
11006
|
+
{
|
|
11007
|
+
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",
|
|
11008
|
+
onClick: () => {
|
|
11009
|
+
window.parent.postMessage(
|
|
11010
|
+
{
|
|
11011
|
+
type: "ow:add-section",
|
|
11012
|
+
insertAfter: sectionGap.insertAfter,
|
|
11013
|
+
insertBefore: sectionGap.insertBefore
|
|
9754
11014
|
},
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
{
|
|
9765
|
-
panelRef: linkPopoverPanelRef,
|
|
9766
|
-
portalContainer: dialogPortalContainer,
|
|
9767
|
-
open: true,
|
|
9768
|
-
mode: linkPopover.mode ?? "edit",
|
|
9769
|
-
pages: sitePages,
|
|
9770
|
-
sections: currentSections,
|
|
9771
|
-
sectionsByPath,
|
|
9772
|
-
initialTarget: linkPopover.target,
|
|
9773
|
-
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
9774
|
-
onClose: closeLinkPopover,
|
|
9775
|
-
onSubmit: handleLinkPopoverSubmit
|
|
9776
|
-
},
|
|
9777
|
-
linkPopover.key
|
|
9778
|
-
) : null
|
|
11015
|
+
"*"
|
|
11016
|
+
);
|
|
11017
|
+
},
|
|
11018
|
+
children: "Add Section"
|
|
11019
|
+
}
|
|
11020
|
+
),
|
|
11021
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
11022
|
+
] }),
|
|
11023
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(LinkPopover, { panelRef: linkPopoverPanelRef, portalContainer: dialogPortalContainer, open: true, mode: linkPopover.mode ?? "edit", pages: sitePages, sections: currentSections, sectionsByPath, initialTarget: linkPopover.target, existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [], onClose: closeLinkPopover, onSubmit: handleLinkPopoverSubmit }, linkPopover.key) : null
|
|
9779
11024
|
] }),
|
|
9780
11025
|
bridgeRoot
|
|
9781
11026
|
) : null;
|
|
@@ -9786,6 +11031,7 @@ function OhhwellsBridge() {
|
|
|
9786
11031
|
CustomToolbarButton,
|
|
9787
11032
|
CustomToolbarDivider,
|
|
9788
11033
|
DragHandle,
|
|
11034
|
+
DropIndicator,
|
|
9789
11035
|
ItemActionToolbar,
|
|
9790
11036
|
ItemInteractionLayer,
|
|
9791
11037
|
LinkEditorPanel,
|
|
@@ -9800,12 +11046,14 @@ function OhhwellsBridge() {
|
|
|
9800
11046
|
TooltipProvider,
|
|
9801
11047
|
TooltipTrigger,
|
|
9802
11048
|
buildTarget,
|
|
11049
|
+
dropIndicatorVariants,
|
|
9803
11050
|
filterAvailablePages,
|
|
9804
11051
|
getEditModeInitialState,
|
|
9805
11052
|
isEditSessionActive,
|
|
9806
11053
|
isValidUrl,
|
|
9807
11054
|
parseTarget,
|
|
9808
11055
|
toggleVariants,
|
|
11056
|
+
useOhwCarousel,
|
|
9809
11057
|
validateUrlInput
|
|
9810
11058
|
});
|
|
9811
11059
|
//# sourceMappingURL=index.cjs.map
|