@ohhwells/bridge 0.1.49 → 0.1.50
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 +12 -0
- package/dist/index.cjs +77 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +129 -73
- package/dist/index.js.map +1 -1
- package/dist/styles.css +0 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React11, { useCallback as
|
|
4
|
+
import React11, { useCallback as useCallback5, useEffect as useEffect9, useLayoutEffect as useLayoutEffect3, useRef as useRef7, useState as useState8 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -48,12 +48,13 @@ function useLinkHrefGuardian(...deps) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// src/ui/SchedulingWidget.tsx
|
|
51
|
-
import { useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
51
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
52
52
|
|
|
53
53
|
// src/ui/EmailCaptureModal.tsx
|
|
54
54
|
import { useState } from "react";
|
|
55
55
|
import { Dialog } from "radix-ui";
|
|
56
56
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
57
|
+
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
57
58
|
function Spinner() {
|
|
58
59
|
return /* @__PURE__ */ jsxs(
|
|
59
60
|
"svg",
|
|
@@ -87,12 +88,17 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
87
88
|
const [error, setError] = useState(null);
|
|
88
89
|
const isBook = title === "Confirm your spot";
|
|
89
90
|
const handleSubmit = async () => {
|
|
90
|
-
|
|
91
|
+
const trimmed = email.trim();
|
|
92
|
+
if (!trimmed) return;
|
|
93
|
+
if (!isValidEmail(trimmed)) {
|
|
94
|
+
setError("Please enter a valid email address.");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
91
97
|
setLoading(true);
|
|
92
98
|
setError(null);
|
|
93
99
|
try {
|
|
94
|
-
await onSubmit(
|
|
95
|
-
setSubmittedEmail(
|
|
100
|
+
await onSubmit(trimmed);
|
|
101
|
+
setSubmittedEmail(trimmed);
|
|
96
102
|
setSuccess(true);
|
|
97
103
|
} catch (e) {
|
|
98
104
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -167,7 +173,10 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
167
173
|
{
|
|
168
174
|
type: "email",
|
|
169
175
|
value: email,
|
|
170
|
-
onChange: (e) =>
|
|
176
|
+
onChange: (e) => {
|
|
177
|
+
setEmail(e.target.value);
|
|
178
|
+
if (error) setError(null);
|
|
179
|
+
},
|
|
171
180
|
onKeyDown: handleKeyDown,
|
|
172
181
|
placeholder: "hello@gmail.com",
|
|
173
182
|
autoFocus: true,
|
|
@@ -224,12 +233,20 @@ function formatClassTime(cls) {
|
|
|
224
233
|
const em = endTotal % 60;
|
|
225
234
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
226
235
|
}
|
|
236
|
+
function formatBookingLabel(cls) {
|
|
237
|
+
const price = cls.price;
|
|
238
|
+
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
239
|
+
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
240
|
+
}
|
|
227
241
|
function getBookingsOnDate(cls, date) {
|
|
228
242
|
if (!cls.bookings?.length) return 0;
|
|
229
|
-
const
|
|
243
|
+
const target = new Date(date);
|
|
244
|
+
target.setHours(0, 0, 0, 0);
|
|
230
245
|
return cls.bookings.filter((b) => {
|
|
231
246
|
try {
|
|
232
|
-
|
|
247
|
+
const bookingDate = new Date(b.classDate);
|
|
248
|
+
bookingDate.setHours(0, 0, 0, 0);
|
|
249
|
+
return bookingDate.getTime() === target.getTime();
|
|
233
250
|
} catch {
|
|
234
251
|
return false;
|
|
235
252
|
}
|
|
@@ -494,7 +511,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
494
511
|
}
|
|
495
512
|
)
|
|
496
513
|
] }),
|
|
497
|
-
/* @__PURE__ */ jsx2("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
514
|
+
cls.showAvailability !== false && /* @__PURE__ */ jsx2("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
498
515
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
499
516
|
available,
|
|
500
517
|
"/",
|
|
@@ -506,9 +523,17 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
506
523
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
507
524
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
508
525
|
/* @__PURE__ */ jsx2("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
509
|
-
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
526
|
+
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName }),
|
|
527
|
+
cls.description && /* @__PURE__ */ jsx2(
|
|
528
|
+
"span",
|
|
529
|
+
{
|
|
530
|
+
className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block",
|
|
531
|
+
style: { wordBreak: "break-word" },
|
|
532
|
+
children: cls.description
|
|
533
|
+
}
|
|
534
|
+
)
|
|
510
535
|
] }),
|
|
511
|
-
/* @__PURE__ */ jsx2("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
536
|
+
cls.showAvailability !== false && /* @__PURE__ */ jsx2("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
512
537
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
513
538
|
available,
|
|
514
539
|
"/",
|
|
@@ -533,7 +558,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
533
558
|
if (!cls.id) return;
|
|
534
559
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
535
560
|
},
|
|
536
|
-
children: isFull ? "Join Waitlist" :
|
|
561
|
+
children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
|
|
537
562
|
}
|
|
538
563
|
)
|
|
539
564
|
] })
|
|
@@ -575,6 +600,17 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
575
600
|
const [isHovered, setIsHovered] = useState2(false);
|
|
576
601
|
const [modalState, setModalState] = useState2(null);
|
|
577
602
|
const switchScheduleIdRef = useRef(null);
|
|
603
|
+
const liveScheduleIdRef = useRef(null);
|
|
604
|
+
const refetchLiveSchedule = useCallback(async () => {
|
|
605
|
+
const id = liveScheduleIdRef.current;
|
|
606
|
+
if (!id) return;
|
|
607
|
+
try {
|
|
608
|
+
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
609
|
+
const data = await res.json();
|
|
610
|
+
if (data?.id) setSchedule(data);
|
|
611
|
+
} catch {
|
|
612
|
+
}
|
|
613
|
+
}, []);
|
|
578
614
|
const dates = useMemo(() => {
|
|
579
615
|
const today = /* @__PURE__ */ new Date();
|
|
580
616
|
today.setHours(0, 0, 0, 0);
|
|
@@ -594,6 +630,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
594
630
|
}
|
|
595
631
|
}
|
|
596
632
|
}, [schedule, dates]);
|
|
633
|
+
useEffect(() => {
|
|
634
|
+
if (typeof window === "undefined") return;
|
|
635
|
+
const onVisible = () => {
|
|
636
|
+
if (!document.hidden) void refetchLiveSchedule();
|
|
637
|
+
};
|
|
638
|
+
window.addEventListener("focus", refetchLiveSchedule);
|
|
639
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
640
|
+
return () => {
|
|
641
|
+
window.removeEventListener("focus", refetchLiveSchedule);
|
|
642
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
643
|
+
};
|
|
644
|
+
}, [refetchLiveSchedule]);
|
|
597
645
|
useEffect(() => {
|
|
598
646
|
if (typeof window === "undefined") return;
|
|
599
647
|
const isInEditor = window.self !== window.top;
|
|
@@ -655,7 +703,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
655
703
|
setLoading(false);
|
|
656
704
|
return;
|
|
657
705
|
}
|
|
658
|
-
;
|
|
706
|
+
liveScheduleIdRef.current = effectiveId;
|
|
659
707
|
(async () => {
|
|
660
708
|
try {
|
|
661
709
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -712,18 +760,14 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
712
760
|
const data = await res.json().catch(() => ({}));
|
|
713
761
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
714
762
|
}
|
|
763
|
+
await refetchLiveSchedule();
|
|
715
764
|
};
|
|
716
765
|
const handleReplaceSchedule = () => {
|
|
717
766
|
setIsHovered(false);
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
insertAfter
|
|
723
|
-
}, "*");
|
|
724
|
-
} else {
|
|
725
|
-
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
726
|
-
}
|
|
767
|
+
window.parent.postMessage(
|
|
768
|
+
{ type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
|
|
769
|
+
"*"
|
|
770
|
+
);
|
|
727
771
|
};
|
|
728
772
|
if (!inEditor && !loading && !schedule) return null;
|
|
729
773
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -766,7 +810,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
766
810
|
),
|
|
767
811
|
/* @__PURE__ */ jsxs2("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
768
812
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center gap-4", children: [
|
|
769
|
-
/* @__PURE__ */ jsx2(
|
|
813
|
+
/* @__PURE__ */ jsx2(
|
|
814
|
+
"h2",
|
|
815
|
+
{
|
|
816
|
+
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
817
|
+
style: {
|
|
818
|
+
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
819
|
+
fontWeight: "var(--font-weight-heading, 400)",
|
|
820
|
+
lineHeight: 1.05,
|
|
821
|
+
letterSpacing: "-0.02em"
|
|
822
|
+
},
|
|
823
|
+
children: schedule?.name ?? "Book an appointment"
|
|
824
|
+
}
|
|
825
|
+
),
|
|
770
826
|
schedule?.description && /* @__PURE__ */ jsx2("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
771
827
|
] }),
|
|
772
828
|
/* @__PURE__ */ jsxs2("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -5658,7 +5714,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5658
5714
|
}
|
|
5659
5715
|
|
|
5660
5716
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5661
|
-
import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
|
|
5717
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
|
|
5662
5718
|
import { createPortal } from "react-dom";
|
|
5663
5719
|
import { ArrowLeft, Check } from "lucide-react";
|
|
5664
5720
|
import { usePathname, useRouter } from "next/navigation";
|
|
@@ -5789,7 +5845,7 @@ function SectionPickerOverlay({
|
|
|
5789
5845
|
);
|
|
5790
5846
|
sectionIdsRef.current = sectionIds;
|
|
5791
5847
|
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5792
|
-
const applyHoverAt =
|
|
5848
|
+
const applyHoverAt = useCallback2(
|
|
5793
5849
|
(x, y, liveRects) => {
|
|
5794
5850
|
const ids = sectionIdsRef.current;
|
|
5795
5851
|
const map = liveRects ?? readSectionRects(ids);
|
|
@@ -5869,7 +5925,7 @@ function SectionPickerOverlay({
|
|
|
5869
5925
|
window.removeEventListener("message", onPointerSync);
|
|
5870
5926
|
};
|
|
5871
5927
|
}, [rects, applyHoverAt]);
|
|
5872
|
-
const handleSelect =
|
|
5928
|
+
const handleSelect = useCallback2(
|
|
5873
5929
|
(section) => {
|
|
5874
5930
|
if (selectedId) return;
|
|
5875
5931
|
setSelectedId(section.id);
|
|
@@ -6000,7 +6056,7 @@ function SectionPickerOverlay({
|
|
|
6000
6056
|
}
|
|
6001
6057
|
|
|
6002
6058
|
// src/ui/link-modal/useLinkModalState.ts
|
|
6003
|
-
import { useCallback as
|
|
6059
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
6004
6060
|
function useLinkModalState({
|
|
6005
6061
|
open,
|
|
6006
6062
|
mode,
|
|
@@ -6019,7 +6075,7 @@ function useLinkModalState({
|
|
|
6019
6075
|
const [step, setStep] = useState5("input");
|
|
6020
6076
|
const [dropdownOpen, setDropdownOpen] = useState5(false);
|
|
6021
6077
|
const [urlError, setUrlError] = useState5("");
|
|
6022
|
-
const reset =
|
|
6078
|
+
const reset = useCallback3(() => {
|
|
6023
6079
|
setSearchValue("");
|
|
6024
6080
|
setSelectedPage(null);
|
|
6025
6081
|
setSelectedSection(null);
|
|
@@ -7367,7 +7423,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7367
7423
|
}
|
|
7368
7424
|
|
|
7369
7425
|
// src/useNavItemDrag.ts
|
|
7370
|
-
import { useCallback as
|
|
7426
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef6, useState as useState6 } from "react";
|
|
7371
7427
|
function useNavItemDrag({
|
|
7372
7428
|
isEditMode,
|
|
7373
7429
|
editContentRef,
|
|
@@ -7396,7 +7452,7 @@ function useNavItemDrag({
|
|
|
7396
7452
|
const [navDropSlots, setNavDropSlots] = useState6([]);
|
|
7397
7453
|
const [activeNavDropIndex, setActiveNavDropIndex] = useState6(null);
|
|
7398
7454
|
const navPointerDragRef = useRef6(null);
|
|
7399
|
-
const clearNavDragVisuals =
|
|
7455
|
+
const clearNavDragVisuals = useCallback4(() => {
|
|
7400
7456
|
navDragRef.current = null;
|
|
7401
7457
|
setNavDropSlots([]);
|
|
7402
7458
|
setActiveNavDropIndex(null);
|
|
@@ -7405,7 +7461,7 @@ function useNavItemDrag({
|
|
|
7405
7461
|
setIsItemDragging(false);
|
|
7406
7462
|
unlockItemDragInteraction();
|
|
7407
7463
|
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
7408
|
-
const refreshNavDragVisuals =
|
|
7464
|
+
const refreshNavDragVisuals = useCallback4(
|
|
7409
7465
|
(session, activeSlot, clientX, clientY) => {
|
|
7410
7466
|
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
7411
7467
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -7429,7 +7485,7 @@ function useNavItemDrag({
|
|
|
7429
7485
|
});
|
|
7430
7486
|
const beginNavDragRef = useRef6(() => {
|
|
7431
7487
|
});
|
|
7432
|
-
const beginNavDrag =
|
|
7488
|
+
const beginNavDrag = useCallback4(
|
|
7433
7489
|
(session) => {
|
|
7434
7490
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
7435
7491
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -7456,7 +7512,7 @@ function useNavItemDrag({
|
|
|
7456
7512
|
]
|
|
7457
7513
|
);
|
|
7458
7514
|
beginNavDragRef.current = beginNavDrag;
|
|
7459
|
-
const commitNavDrag =
|
|
7515
|
+
const commitNavDrag = useCallback4(
|
|
7460
7516
|
(clientX, clientY) => {
|
|
7461
7517
|
const session = navDragRef.current;
|
|
7462
7518
|
if (!session) {
|
|
@@ -7517,7 +7573,7 @@ function useNavItemDrag({
|
|
|
7517
7573
|
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
7518
7574
|
);
|
|
7519
7575
|
commitNavDragRef.current = commitNavDrag;
|
|
7520
|
-
const startNavLinkDrag =
|
|
7576
|
+
const startNavLinkDrag = useCallback4(
|
|
7521
7577
|
(anchor, clientX, clientY, wasSelected) => {
|
|
7522
7578
|
if (footerDragRef.current) return false;
|
|
7523
7579
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -7535,7 +7591,7 @@ function useNavItemDrag({
|
|
|
7535
7591
|
},
|
|
7536
7592
|
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
|
|
7537
7593
|
);
|
|
7538
|
-
const onNavDragOver =
|
|
7594
|
+
const onNavDragOver = useCallback4(
|
|
7539
7595
|
(e) => {
|
|
7540
7596
|
const session = navDragRef.current;
|
|
7541
7597
|
if (!session) return false;
|
|
@@ -7672,7 +7728,7 @@ function useNavItemDrag({
|
|
|
7672
7728
|
setLinkPopover,
|
|
7673
7729
|
suppressNextClickRef
|
|
7674
7730
|
]);
|
|
7675
|
-
const armNavPressFromChrome =
|
|
7731
|
+
const armNavPressFromChrome = useCallback4(
|
|
7676
7732
|
(selected, clientX, clientY, pointerId) => {
|
|
7677
7733
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7678
7734
|
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
@@ -9062,7 +9118,7 @@ function OhhwellsBridge() {
|
|
|
9062
9118
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
9063
9119
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
9064
9120
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
9065
|
-
const postToParent2 =
|
|
9121
|
+
const postToParent2 = useCallback5((data) => {
|
|
9066
9122
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
9067
9123
|
window.parent.postMessage(data, "*");
|
|
9068
9124
|
}
|
|
@@ -9079,7 +9135,7 @@ function OhhwellsBridge() {
|
|
|
9079
9135
|
const parentScrollRef = useRef7(null);
|
|
9080
9136
|
const visibleViewportRef = useRef7(null);
|
|
9081
9137
|
const [dialogPortalContainer, setDialogPortalContainer] = useState8(null);
|
|
9082
|
-
const attachVisibleViewport =
|
|
9138
|
+
const attachVisibleViewport = useCallback5((node) => {
|
|
9083
9139
|
visibleViewportRef.current = node;
|
|
9084
9140
|
setDialogPortalContainer(node);
|
|
9085
9141
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
@@ -9193,7 +9249,7 @@ function OhhwellsBridge() {
|
|
|
9193
9249
|
const bumpLinkPopoverGrace = () => {
|
|
9194
9250
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
9195
9251
|
};
|
|
9196
|
-
const runSectionsPrefetch =
|
|
9252
|
+
const runSectionsPrefetch = useCallback5((pages) => {
|
|
9197
9253
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
9198
9254
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
9199
9255
|
const paths = pages.map((p) => p.path);
|
|
@@ -9319,10 +9375,10 @@ function OhhwellsBridge() {
|
|
|
9319
9375
|
vvp.removeEventListener("resize", update);
|
|
9320
9376
|
};
|
|
9321
9377
|
}, []);
|
|
9322
|
-
const refreshStateRules =
|
|
9378
|
+
const refreshStateRules = useCallback5(() => {
|
|
9323
9379
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
9324
9380
|
}, []);
|
|
9325
|
-
const processConfigRequest =
|
|
9381
|
+
const processConfigRequest = useCallback5((insertAfterVal) => {
|
|
9326
9382
|
const tracker = getSectionsTracker();
|
|
9327
9383
|
let entries = [];
|
|
9328
9384
|
try {
|
|
@@ -9345,7 +9401,7 @@ function OhhwellsBridge() {
|
|
|
9345
9401
|
}
|
|
9346
9402
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
9347
9403
|
}, [isEditMode]);
|
|
9348
|
-
const deactivate =
|
|
9404
|
+
const deactivate = useCallback5(() => {
|
|
9349
9405
|
const el = activeElRef.current;
|
|
9350
9406
|
if (!el) return;
|
|
9351
9407
|
const key = el.dataset.ohwKey;
|
|
@@ -9377,12 +9433,12 @@ function OhhwellsBridge() {
|
|
|
9377
9433
|
setToolbarShowEditLink(false);
|
|
9378
9434
|
postToParent2({ type: "ow:exit-edit" });
|
|
9379
9435
|
}, [postToParent2]);
|
|
9380
|
-
const clearSelectedAttr =
|
|
9436
|
+
const clearSelectedAttr = useCallback5(() => {
|
|
9381
9437
|
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
9382
9438
|
el.removeAttribute("data-ohw-selected");
|
|
9383
9439
|
});
|
|
9384
9440
|
}, []);
|
|
9385
|
-
const deselect =
|
|
9441
|
+
const deselect = useCallback5(() => {
|
|
9386
9442
|
clearSelectedAttr();
|
|
9387
9443
|
selectedElRef.current = null;
|
|
9388
9444
|
selectedHrefKeyRef.current = null;
|
|
@@ -9402,11 +9458,11 @@ function OhhwellsBridge() {
|
|
|
9402
9458
|
setToolbarVariant("none");
|
|
9403
9459
|
}
|
|
9404
9460
|
}, [clearSelectedAttr]);
|
|
9405
|
-
const markSelected =
|
|
9461
|
+
const markSelected = useCallback5((el) => {
|
|
9406
9462
|
clearSelectedAttr();
|
|
9407
9463
|
el.setAttribute("data-ohw-selected", "");
|
|
9408
9464
|
}, [clearSelectedAttr]);
|
|
9409
|
-
const resolveHrefKeyElement =
|
|
9465
|
+
const resolveHrefKeyElement = useCallback5((hrefKey) => {
|
|
9410
9466
|
if (isFooterHrefKey(hrefKey)) {
|
|
9411
9467
|
return document.querySelector(
|
|
9412
9468
|
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
@@ -9421,7 +9477,7 @@ function OhhwellsBridge() {
|
|
|
9421
9477
|
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9422
9478
|
);
|
|
9423
9479
|
}, []);
|
|
9424
|
-
const resyncSelectedNavigationItem =
|
|
9480
|
+
const resyncSelectedNavigationItem = useCallback5(() => {
|
|
9425
9481
|
const hrefKey = selectedHrefKeyRef.current;
|
|
9426
9482
|
if (hrefKey) {
|
|
9427
9483
|
const link = resolveHrefKeyElement(hrefKey);
|
|
@@ -9449,7 +9505,7 @@ function OhhwellsBridge() {
|
|
|
9449
9505
|
);
|
|
9450
9506
|
}
|
|
9451
9507
|
}, [resolveHrefKeyElement]);
|
|
9452
|
-
const reselectNavigationItem =
|
|
9508
|
+
const reselectNavigationItem = useCallback5((navAnchor) => {
|
|
9453
9509
|
selectedElRef.current = navAnchor;
|
|
9454
9510
|
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
9455
9511
|
selectedFooterColAttrRef.current = null;
|
|
@@ -9464,7 +9520,7 @@ function OhhwellsBridge() {
|
|
|
9464
9520
|
setToolbarShowEditLink(false);
|
|
9465
9521
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9466
9522
|
}, [markSelected]);
|
|
9467
|
-
const commitNavigationTextEdit =
|
|
9523
|
+
const commitNavigationTextEdit = useCallback5((navAnchor) => {
|
|
9468
9524
|
const el = activeElRef.current;
|
|
9469
9525
|
if (!el) return;
|
|
9470
9526
|
const key = el.dataset.ohwKey;
|
|
@@ -9491,7 +9547,7 @@ function OhhwellsBridge() {
|
|
|
9491
9547
|
postToParent2({ type: "ow:exit-edit" });
|
|
9492
9548
|
reselectNavigationItem(navAnchor);
|
|
9493
9549
|
}, [postToParent2, reselectNavigationItem]);
|
|
9494
|
-
const handleAddTopLevelNavItem =
|
|
9550
|
+
const handleAddTopLevelNavItem = useCallback5(() => {
|
|
9495
9551
|
const items = listNavbarItems();
|
|
9496
9552
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
9497
9553
|
deselectRef.current();
|
|
@@ -9503,7 +9559,7 @@ function OhhwellsBridge() {
|
|
|
9503
9559
|
intent: "add-nav"
|
|
9504
9560
|
});
|
|
9505
9561
|
}, []);
|
|
9506
|
-
const clearFooterDragVisuals =
|
|
9562
|
+
const clearFooterDragVisuals = useCallback5(() => {
|
|
9507
9563
|
footerDragRef.current = null;
|
|
9508
9564
|
setSiblingHintRects([]);
|
|
9509
9565
|
setFooterDropSlots([]);
|
|
@@ -9512,7 +9568,7 @@ function OhhwellsBridge() {
|
|
|
9512
9568
|
setIsItemDragging(false);
|
|
9513
9569
|
unlockFooterDragInteraction();
|
|
9514
9570
|
}, []);
|
|
9515
|
-
const refreshFooterDragVisuals =
|
|
9571
|
+
const refreshFooterDragVisuals = useCallback5((session, activeSlot, clientX, clientY) => {
|
|
9516
9572
|
const dragged = session.draggedEl;
|
|
9517
9573
|
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
9518
9574
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -9543,7 +9599,7 @@ function OhhwellsBridge() {
|
|
|
9543
9599
|
});
|
|
9544
9600
|
const beginFooterDragRef = useRef7(() => {
|
|
9545
9601
|
});
|
|
9546
|
-
const beginFooterDrag =
|
|
9602
|
+
const beginFooterDrag = useCallback5(
|
|
9547
9603
|
(session) => {
|
|
9548
9604
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
9549
9605
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -9563,7 +9619,7 @@ function OhhwellsBridge() {
|
|
|
9563
9619
|
[refreshFooterDragVisuals]
|
|
9564
9620
|
);
|
|
9565
9621
|
beginFooterDragRef.current = beginFooterDrag;
|
|
9566
|
-
const commitFooterDrag =
|
|
9622
|
+
const commitFooterDrag = useCallback5(
|
|
9567
9623
|
(clientX, clientY) => {
|
|
9568
9624
|
const session = footerDragRef.current;
|
|
9569
9625
|
if (!session) {
|
|
@@ -9667,7 +9723,7 @@ function OhhwellsBridge() {
|
|
|
9667
9723
|
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
9668
9724
|
);
|
|
9669
9725
|
commitFooterDragRef.current = commitFooterDrag;
|
|
9670
|
-
const startFooterLinkDrag =
|
|
9726
|
+
const startFooterLinkDrag = useCallback5(
|
|
9671
9727
|
(anchor, clientX, clientY, wasSelected) => {
|
|
9672
9728
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
9673
9729
|
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
@@ -9688,7 +9744,7 @@ function OhhwellsBridge() {
|
|
|
9688
9744
|
},
|
|
9689
9745
|
[beginFooterDrag]
|
|
9690
9746
|
);
|
|
9691
|
-
const startFooterColumnDrag =
|
|
9747
|
+
const startFooterColumnDrag = useCallback5(
|
|
9692
9748
|
(columnEl, clientX, clientY, wasSelected) => {
|
|
9693
9749
|
const columns = listFooterColumns();
|
|
9694
9750
|
const idx = columns.indexOf(columnEl);
|
|
@@ -9708,7 +9764,7 @@ function OhhwellsBridge() {
|
|
|
9708
9764
|
},
|
|
9709
9765
|
[beginFooterDrag]
|
|
9710
9766
|
);
|
|
9711
|
-
const handleItemDragStart =
|
|
9767
|
+
const handleItemDragStart = useCallback5(
|
|
9712
9768
|
(e) => {
|
|
9713
9769
|
const selected = selectedElRef.current;
|
|
9714
9770
|
if (!selected) {
|
|
@@ -9728,7 +9784,7 @@ function OhhwellsBridge() {
|
|
|
9728
9784
|
},
|
|
9729
9785
|
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
9730
9786
|
);
|
|
9731
|
-
const handleItemDragEnd =
|
|
9787
|
+
const handleItemDragEnd = useCallback5(
|
|
9732
9788
|
(e) => {
|
|
9733
9789
|
if (footerDragRef.current) {
|
|
9734
9790
|
const x = e?.clientX;
|
|
@@ -9754,7 +9810,7 @@ function OhhwellsBridge() {
|
|
|
9754
9810
|
},
|
|
9755
9811
|
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
9756
9812
|
);
|
|
9757
|
-
const handleItemChromePointerDown =
|
|
9813
|
+
const handleItemChromePointerDown = useCallback5((e) => {
|
|
9758
9814
|
if (e.button !== 0) return;
|
|
9759
9815
|
const selected = selectedElRef.current;
|
|
9760
9816
|
if (!selected) return;
|
|
@@ -9785,7 +9841,7 @@ function OhhwellsBridge() {
|
|
|
9785
9841
|
}
|
|
9786
9842
|
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
9787
9843
|
}, [armNavPressFromChrome]);
|
|
9788
|
-
const handleItemChromeClick =
|
|
9844
|
+
const handleItemChromeClick = useCallback5((clientX, clientY) => {
|
|
9789
9845
|
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
9790
9846
|
suppressNextClickRef.current = false;
|
|
9791
9847
|
return;
|
|
@@ -9798,7 +9854,7 @@ function OhhwellsBridge() {
|
|
|
9798
9854
|
}, []);
|
|
9799
9855
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
9800
9856
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
9801
|
-
const select =
|
|
9857
|
+
const select = useCallback5((anchor) => {
|
|
9802
9858
|
if (!isNavigationItem(anchor)) return;
|
|
9803
9859
|
if (activeElRef.current) deactivate();
|
|
9804
9860
|
selectedElRef.current = anchor;
|
|
@@ -9824,7 +9880,7 @@ function OhhwellsBridge() {
|
|
|
9824
9880
|
setToolbarShowEditLink(false);
|
|
9825
9881
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9826
9882
|
}, [deactivate, markSelected]);
|
|
9827
|
-
const selectFrame =
|
|
9883
|
+
const selectFrame = useCallback5((el) => {
|
|
9828
9884
|
if (!isNavigationContainer(el)) return;
|
|
9829
9885
|
if (activeElRef.current) deactivate();
|
|
9830
9886
|
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
@@ -9852,7 +9908,7 @@ function OhhwellsBridge() {
|
|
|
9852
9908
|
setToolbarShowEditLink(false);
|
|
9853
9909
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9854
9910
|
}, [deactivate, markSelected]);
|
|
9855
|
-
const activate =
|
|
9911
|
+
const activate = useCallback5((el, options) => {
|
|
9856
9912
|
if (activeElRef.current === el) return;
|
|
9857
9913
|
clearSelectedAttr();
|
|
9858
9914
|
selectedElRef.current = null;
|
|
@@ -11995,7 +12051,7 @@ function OhhwellsBridge() {
|
|
|
11995
12051
|
window.addEventListener("hashchange", onHashChange);
|
|
11996
12052
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
11997
12053
|
}, [pathname]);
|
|
11998
|
-
const handleCommand =
|
|
12054
|
+
const handleCommand = useCallback5((cmd) => {
|
|
11999
12055
|
const el = activeElRef.current;
|
|
12000
12056
|
const selBefore = window.getSelection();
|
|
12001
12057
|
let savedOffsets = null;
|
|
@@ -12031,7 +12087,7 @@ function OhhwellsBridge() {
|
|
|
12031
12087
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
12032
12088
|
refreshActiveCommandsRef.current();
|
|
12033
12089
|
}, []);
|
|
12034
|
-
const handleStateChange =
|
|
12090
|
+
const handleStateChange = useCallback5((state) => {
|
|
12035
12091
|
if (!activeStateElRef.current) return;
|
|
12036
12092
|
const el = activeStateElRef.current;
|
|
12037
12093
|
if (state === "Default") {
|
|
@@ -12044,11 +12100,11 @@ function OhhwellsBridge() {
|
|
|
12044
12100
|
}
|
|
12045
12101
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
12046
12102
|
}, [deactivate]);
|
|
12047
|
-
const closeLinkPopover =
|
|
12103
|
+
const closeLinkPopover = useCallback5(() => {
|
|
12048
12104
|
addNavAfterAnchorRef.current = null;
|
|
12049
12105
|
setLinkPopover(null);
|
|
12050
12106
|
}, []);
|
|
12051
|
-
const openLinkPopoverForActive =
|
|
12107
|
+
const openLinkPopoverForActive = useCallback5(() => {
|
|
12052
12108
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
12053
12109
|
if (!hrefCtx) return;
|
|
12054
12110
|
bumpLinkPopoverGrace();
|
|
@@ -12059,7 +12115,7 @@ function OhhwellsBridge() {
|
|
|
12059
12115
|
});
|
|
12060
12116
|
deactivate();
|
|
12061
12117
|
}, [deactivate]);
|
|
12062
|
-
const openLinkPopoverForSelected =
|
|
12118
|
+
const openLinkPopoverForSelected = useCallback5(() => {
|
|
12063
12119
|
const anchor = selectedElRef.current;
|
|
12064
12120
|
if (!anchor) return;
|
|
12065
12121
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -12072,7 +12128,7 @@ function OhhwellsBridge() {
|
|
|
12072
12128
|
});
|
|
12073
12129
|
deselect();
|
|
12074
12130
|
}, [deselect]);
|
|
12075
|
-
const handleLinkPopoverSubmit =
|
|
12131
|
+
const handleLinkPopoverSubmit = useCallback5(
|
|
12076
12132
|
(target) => {
|
|
12077
12133
|
const session = linkPopoverSessionRef.current;
|
|
12078
12134
|
if (!session) return;
|
|
@@ -12131,19 +12187,19 @@ function OhhwellsBridge() {
|
|
|
12131
12187
|
const showEditLink = toolbarShowEditLink;
|
|
12132
12188
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
12133
12189
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
12134
|
-
const handleMediaReplace =
|
|
12190
|
+
const handleMediaReplace = useCallback5(
|
|
12135
12191
|
(key) => {
|
|
12136
12192
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
12137
12193
|
},
|
|
12138
12194
|
[postToParent2, mediaHover?.elementType]
|
|
12139
12195
|
);
|
|
12140
|
-
const handleEditCarousel =
|
|
12196
|
+
const handleEditCarousel = useCallback5(
|
|
12141
12197
|
(key) => {
|
|
12142
12198
|
postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
|
|
12143
12199
|
},
|
|
12144
12200
|
[postToParent2]
|
|
12145
12201
|
);
|
|
12146
|
-
const handleMediaFadeOutComplete =
|
|
12202
|
+
const handleMediaFadeOutComplete = useCallback5((key) => {
|
|
12147
12203
|
setUploadingRects((prev) => {
|
|
12148
12204
|
if (!(key in prev)) return prev;
|
|
12149
12205
|
const next = { ...prev };
|
|
@@ -12151,7 +12207,7 @@ function OhhwellsBridge() {
|
|
|
12151
12207
|
return next;
|
|
12152
12208
|
});
|
|
12153
12209
|
}, []);
|
|
12154
|
-
const handleVideoSettingsChange =
|
|
12210
|
+
const handleVideoSettingsChange = useCallback5(
|
|
12155
12211
|
(key, settings) => {
|
|
12156
12212
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
12157
12213
|
const video = getVideoEl(el);
|