@ohhwells/bridge 0.1.36-next.54 → 0.1.37
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 +0 -12
- package/dist/index.cjs +601 -2072
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -51
- package/dist/index.d.ts +4 -51
- package/dist/index.js +591 -2062
- package/dist/index.js.map +1 -1
- package/dist/styles.css +21 -156
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,18 +60,15 @@ __export(index_exports, {
|
|
|
60
60
|
module.exports = __toCommonJS(index_exports);
|
|
61
61
|
|
|
62
62
|
// src/OhhwellsBridge.tsx
|
|
63
|
-
var
|
|
63
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
64
64
|
var import_client = require("react-dom/client");
|
|
65
|
-
var
|
|
65
|
+
var import_react_dom = require("react-dom");
|
|
66
66
|
|
|
67
67
|
// src/linkHrefStore.ts
|
|
68
68
|
var linkHrefStore = /* @__PURE__ */ new Map();
|
|
69
69
|
function setStoredLinkHref(key, href) {
|
|
70
70
|
linkHrefStore.set(key, href);
|
|
71
71
|
}
|
|
72
|
-
function getStoredLinkHref(key) {
|
|
73
|
-
return linkHrefStore.get(key);
|
|
74
|
-
}
|
|
75
72
|
function enforceLinkHrefs() {
|
|
76
73
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
77
74
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -113,7 +110,6 @@ var import_react3 = require("react");
|
|
|
113
110
|
var import_react2 = require("react");
|
|
114
111
|
var import_radix_ui = require("radix-ui");
|
|
115
112
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
116
|
-
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
117
113
|
function Spinner() {
|
|
118
114
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
119
115
|
"svg",
|
|
@@ -147,17 +143,12 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
147
143
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
148
144
|
const isBook = title === "Confirm your spot";
|
|
149
145
|
const handleSubmit = async () => {
|
|
150
|
-
|
|
151
|
-
if (!trimmed) return;
|
|
152
|
-
if (!isValidEmail(trimmed)) {
|
|
153
|
-
setError("Please enter a valid email address.");
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
146
|
+
if (!email.trim()) return;
|
|
156
147
|
setLoading(true);
|
|
157
148
|
setError(null);
|
|
158
149
|
try {
|
|
159
|
-
await onSubmit(
|
|
160
|
-
setSubmittedEmail(
|
|
150
|
+
await onSubmit(email.trim());
|
|
151
|
+
setSubmittedEmail(email.trim());
|
|
161
152
|
setSuccess(true);
|
|
162
153
|
} catch (e) {
|
|
163
154
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -232,10 +223,7 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
232
223
|
{
|
|
233
224
|
type: "email",
|
|
234
225
|
value: email,
|
|
235
|
-
onChange: (e) =>
|
|
236
|
-
setEmail(e.target.value);
|
|
237
|
-
if (error) setError(null);
|
|
238
|
-
},
|
|
226
|
+
onChange: (e) => setEmail(e.target.value),
|
|
239
227
|
onKeyDown: handleKeyDown,
|
|
240
228
|
placeholder: "hello@gmail.com",
|
|
241
229
|
autoFocus: true,
|
|
@@ -292,20 +280,12 @@ function formatClassTime(cls) {
|
|
|
292
280
|
const em = endTotal % 60;
|
|
293
281
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
294
282
|
}
|
|
295
|
-
function formatBookingLabel(cls) {
|
|
296
|
-
const price = cls.price;
|
|
297
|
-
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
298
|
-
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
299
|
-
}
|
|
300
283
|
function getBookingsOnDate(cls, date) {
|
|
301
284
|
if (!cls.bookings?.length) return 0;
|
|
302
|
-
const
|
|
303
|
-
target.setHours(0, 0, 0, 0);
|
|
285
|
+
const ds = date.toISOString().split("T")[0];
|
|
304
286
|
return cls.bookings.filter((b) => {
|
|
305
287
|
try {
|
|
306
|
-
|
|
307
|
-
bookingDate.setHours(0, 0, 0, 0);
|
|
308
|
-
return bookingDate.getTime() === target.getTime();
|
|
288
|
+
return new Date(b.classDate).toISOString().split("T")[0] === ds;
|
|
309
289
|
} catch {
|
|
310
290
|
return false;
|
|
311
291
|
}
|
|
@@ -609,7 +589,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
609
589
|
if (!cls.id) return;
|
|
610
590
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
611
591
|
},
|
|
612
|
-
children: isFull ? "Join Waitlist" :
|
|
592
|
+
children: isFull ? "Join Waitlist" : "Book Now"
|
|
613
593
|
}
|
|
614
594
|
)
|
|
615
595
|
] })
|
|
@@ -651,17 +631,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
651
631
|
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
652
632
|
const [modalState, setModalState] = (0, import_react3.useState)(null);
|
|
653
633
|
const switchScheduleIdRef = (0, import_react3.useRef)(null);
|
|
654
|
-
const liveScheduleIdRef = (0, import_react3.useRef)(null);
|
|
655
|
-
const refetchLiveSchedule = (0, import_react3.useCallback)(async () => {
|
|
656
|
-
const id = liveScheduleIdRef.current;
|
|
657
|
-
if (!id) return;
|
|
658
|
-
try {
|
|
659
|
-
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
660
|
-
const data = await res.json();
|
|
661
|
-
if (data?.id) setSchedule(data);
|
|
662
|
-
} catch {
|
|
663
|
-
}
|
|
664
|
-
}, []);
|
|
665
634
|
const dates = (0, import_react3.useMemo)(() => {
|
|
666
635
|
const today = /* @__PURE__ */ new Date();
|
|
667
636
|
today.setHours(0, 0, 0, 0);
|
|
@@ -681,18 +650,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
681
650
|
}
|
|
682
651
|
}
|
|
683
652
|
}, [schedule, dates]);
|
|
684
|
-
(0, import_react3.useEffect)(() => {
|
|
685
|
-
if (typeof window === "undefined") return;
|
|
686
|
-
const onVisible = () => {
|
|
687
|
-
if (!document.hidden) void refetchLiveSchedule();
|
|
688
|
-
};
|
|
689
|
-
window.addEventListener("focus", refetchLiveSchedule);
|
|
690
|
-
document.addEventListener("visibilitychange", onVisible);
|
|
691
|
-
return () => {
|
|
692
|
-
window.removeEventListener("focus", refetchLiveSchedule);
|
|
693
|
-
document.removeEventListener("visibilitychange", onVisible);
|
|
694
|
-
};
|
|
695
|
-
}, [refetchLiveSchedule]);
|
|
696
653
|
(0, import_react3.useEffect)(() => {
|
|
697
654
|
if (typeof window === "undefined") return;
|
|
698
655
|
const isInEditor = window.self !== window.top;
|
|
@@ -754,7 +711,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
754
711
|
setLoading(false);
|
|
755
712
|
return;
|
|
756
713
|
}
|
|
757
|
-
|
|
714
|
+
;
|
|
758
715
|
(async () => {
|
|
759
716
|
try {
|
|
760
717
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -811,14 +768,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
811
768
|
const data = await res.json().catch(() => ({}));
|
|
812
769
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
813
770
|
}
|
|
814
|
-
await refetchLiveSchedule();
|
|
815
771
|
};
|
|
816
772
|
const handleReplaceSchedule = () => {
|
|
817
773
|
setIsHovered(false);
|
|
818
|
-
|
|
819
|
-
{
|
|
820
|
-
|
|
821
|
-
|
|
774
|
+
if (schedule) {
|
|
775
|
+
window.parent.postMessage({
|
|
776
|
+
type: "ow:schedule-connected",
|
|
777
|
+
schedule: { id: schedule.id, name: schedule.name },
|
|
778
|
+
insertAfter
|
|
779
|
+
}, "*");
|
|
780
|
+
} else {
|
|
781
|
+
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
782
|
+
}
|
|
822
783
|
};
|
|
823
784
|
if (!inEditor && !loading && !schedule) return null;
|
|
824
785
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -861,19 +822,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
861
822
|
),
|
|
862
823
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
863
824
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
864
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
865
|
-
"h2",
|
|
866
|
-
{
|
|
867
|
-
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
868
|
-
style: {
|
|
869
|
-
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
870
|
-
fontWeight: "var(--font-weight-heading, 400)",
|
|
871
|
-
lineHeight: 1.05,
|
|
872
|
-
letterSpacing: "-0.02em"
|
|
873
|
-
},
|
|
874
|
-
children: schedule?.name ?? "Book an appointment"
|
|
875
|
-
}
|
|
876
|
-
),
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "font-display text-4xl sm:text-5xl font-bold text-center m-0 text-(--color-dark,#200C02)", children: schedule?.name ?? "Book an appointment" }),
|
|
877
826
|
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 })
|
|
878
827
|
] }),
|
|
879
828
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4459,7 +4408,6 @@ function ItemActionToolbar({
|
|
|
4459
4408
|
onEditLink,
|
|
4460
4409
|
onAddItem,
|
|
4461
4410
|
onMore,
|
|
4462
|
-
editLinkDisabled = false,
|
|
4463
4411
|
addItemDisabled = true,
|
|
4464
4412
|
moreDisabled = true,
|
|
4465
4413
|
tooltipSide = "bottom"
|
|
@@ -4468,12 +4416,10 @@ function ItemActionToolbar({
|
|
|
4468
4416
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4469
4417
|
ToolbarActionTooltip,
|
|
4470
4418
|
{
|
|
4471
|
-
label: "
|
|
4419
|
+
label: "Add link",
|
|
4472
4420
|
side: tooltipSide,
|
|
4473
|
-
disabled: editLinkDisabled,
|
|
4474
4421
|
buttonProps: {
|
|
4475
4422
|
onMouseDown: (e) => {
|
|
4476
|
-
if (editLinkDisabled) return;
|
|
4477
4423
|
e.preventDefault();
|
|
4478
4424
|
e.stopPropagation();
|
|
4479
4425
|
onEditLink?.();
|
|
@@ -4645,223 +4591,9 @@ function ItemInteractionLayer({
|
|
|
4645
4591
|
);
|
|
4646
4592
|
}
|
|
4647
4593
|
|
|
4648
|
-
// src/ui/MediaOverlay.tsx
|
|
4649
|
-
var React6 = __toESM(require("react"), 1);
|
|
4650
|
-
var import_lucide_react3 = require("lucide-react");
|
|
4651
|
-
|
|
4652
|
-
// src/ui/button.tsx
|
|
4653
|
-
var React5 = __toESM(require("react"), 1);
|
|
4654
|
-
var import_radix_ui4 = require("radix-ui");
|
|
4655
|
-
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4656
|
-
var buttonVariants = cva(
|
|
4657
|
-
"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
|
|
4658
|
-
{
|
|
4659
|
-
variants: {
|
|
4660
|
-
variant: {
|
|
4661
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
4662
|
-
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
4663
|
-
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
4664
|
-
},
|
|
4665
|
-
size: {
|
|
4666
|
-
default: "h-9",
|
|
4667
|
-
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
4668
|
-
}
|
|
4669
|
-
},
|
|
4670
|
-
defaultVariants: {
|
|
4671
|
-
variant: "default",
|
|
4672
|
-
size: "default"
|
|
4673
|
-
}
|
|
4674
|
-
}
|
|
4675
|
-
);
|
|
4676
|
-
var Button = React5.forwardRef(
|
|
4677
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4678
|
-
const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
|
|
4679
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4680
|
-
Comp,
|
|
4681
|
-
{
|
|
4682
|
-
ref,
|
|
4683
|
-
"data-slot": "button",
|
|
4684
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
4685
|
-
...props
|
|
4686
|
-
}
|
|
4687
|
-
);
|
|
4688
|
-
}
|
|
4689
|
-
);
|
|
4690
|
-
Button.displayName = "Button";
|
|
4691
|
-
|
|
4692
|
-
// src/ui/MediaOverlay.tsx
|
|
4693
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4694
|
-
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
4695
|
-
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
4696
|
-
var OVERLAY_BUTTON_STYLE = {
|
|
4697
|
-
pointerEvents: "auto",
|
|
4698
|
-
fontFamily: "Inter, sans-serif",
|
|
4699
|
-
fontSize: 12,
|
|
4700
|
-
color: "#000"
|
|
4701
|
-
};
|
|
4702
|
-
var SKELETON_CSS = `
|
|
4703
|
-
@keyframes ohw-media-shimmer {
|
|
4704
|
-
0% { transform: translateX(-100%); }
|
|
4705
|
-
100% { transform: translateX(100%); }
|
|
4706
|
-
}
|
|
4707
|
-
[data-ohw-media-skeleton] {
|
|
4708
|
-
overflow: hidden;
|
|
4709
|
-
background-color: #d1d5db; /* tailwind gray-300 */
|
|
4710
|
-
}
|
|
4711
|
-
[data-ohw-media-skeleton]::after {
|
|
4712
|
-
content: "";
|
|
4713
|
-
position: absolute;
|
|
4714
|
-
inset: 0;
|
|
4715
|
-
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
|
|
4716
|
-
animation: ohw-media-shimmer 1.4s infinite;
|
|
4717
|
-
}
|
|
4718
|
-
`;
|
|
4719
|
-
function MediaOverlay({
|
|
4720
|
-
hover,
|
|
4721
|
-
isUploading,
|
|
4722
|
-
fadingOut = false,
|
|
4723
|
-
onFadeOutComplete,
|
|
4724
|
-
onReplace,
|
|
4725
|
-
onVideoSettingsChange
|
|
4726
|
-
}) {
|
|
4727
|
-
const { rect } = hover;
|
|
4728
|
-
const skeletonRef = React6.useRef(null);
|
|
4729
|
-
const isVideo = hover.elementType === "video";
|
|
4730
|
-
const autoplay = hover.videoAutoplay ?? true;
|
|
4731
|
-
const muted = hover.videoMuted ?? true;
|
|
4732
|
-
const box = {
|
|
4733
|
-
position: "fixed",
|
|
4734
|
-
top: rect.top,
|
|
4735
|
-
left: rect.left,
|
|
4736
|
-
width: rect.width,
|
|
4737
|
-
height: rect.height,
|
|
4738
|
-
zIndex: 2147483646
|
|
4739
|
-
};
|
|
4740
|
-
React6.useEffect(() => {
|
|
4741
|
-
if (!isUploading || !fadingOut || !skeletonRef.current) return;
|
|
4742
|
-
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
4743
|
-
duration: MEDIA_UPLOAD_FADE_MS,
|
|
4744
|
-
easing: "ease-out",
|
|
4745
|
-
fill: "forwards"
|
|
4746
|
-
});
|
|
4747
|
-
anim.finished.then(() => onFadeOutComplete?.(hover.key)).catch(() => onFadeOutComplete?.(hover.key));
|
|
4748
|
-
return () => anim.cancel();
|
|
4749
|
-
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
4750
|
-
if (isUploading) {
|
|
4751
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4752
|
-
"div",
|
|
4753
|
-
{
|
|
4754
|
-
ref: skeletonRef,
|
|
4755
|
-
"data-ohw-bridge": "",
|
|
4756
|
-
"data-ohw-media-overlay": "",
|
|
4757
|
-
"data-ohw-media-skeleton": "",
|
|
4758
|
-
"aria-hidden": true,
|
|
4759
|
-
style: { ...box, pointerEvents: "none" },
|
|
4760
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: SKELETON_CSS })
|
|
4761
|
-
}
|
|
4762
|
-
);
|
|
4763
|
-
}
|
|
4764
|
-
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4765
|
-
"div",
|
|
4766
|
-
{
|
|
4767
|
-
"data-ohw-bridge": "",
|
|
4768
|
-
"data-ohw-media-overlay": "",
|
|
4769
|
-
className: "flex items-center justify-center gap-1.5",
|
|
4770
|
-
style: {
|
|
4771
|
-
position: "fixed",
|
|
4772
|
-
top: rect.top + VIDEO_SETTINGS_BAR_INSET,
|
|
4773
|
-
left: rect.left,
|
|
4774
|
-
width: rect.width,
|
|
4775
|
-
zIndex: 2147483647,
|
|
4776
|
-
pointerEvents: "auto"
|
|
4777
|
-
},
|
|
4778
|
-
onClick: (e) => e.stopPropagation(),
|
|
4779
|
-
children: [
|
|
4780
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4781
|
-
Button,
|
|
4782
|
-
{
|
|
4783
|
-
"data-ohw-media-overlay": "",
|
|
4784
|
-
variant: "outline",
|
|
4785
|
-
size: "sm",
|
|
4786
|
-
className: "cursor-pointer hover:bg-background",
|
|
4787
|
-
style: { ...OVERLAY_BUTTON_STYLE, minWidth: 0, padding: "0 8px" },
|
|
4788
|
-
"aria-label": autoplay ? "Disable autoplay" : "Enable autoplay",
|
|
4789
|
-
title: autoplay ? "Autoplay on \u2014 click to disable" : "Autoplay off \u2014 click to enable",
|
|
4790
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
4791
|
-
onClick: (e) => {
|
|
4792
|
-
e.stopPropagation();
|
|
4793
|
-
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
4794
|
-
},
|
|
4795
|
-
children: autoplay ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Pause, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Play, { size: 14 })
|
|
4796
|
-
}
|
|
4797
|
-
),
|
|
4798
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4799
|
-
Button,
|
|
4800
|
-
{
|
|
4801
|
-
"data-ohw-media-overlay": "",
|
|
4802
|
-
variant: "outline",
|
|
4803
|
-
size: "sm",
|
|
4804
|
-
className: "cursor-pointer hover:bg-background",
|
|
4805
|
-
style: { ...OVERLAY_BUTTON_STYLE, minWidth: 0, padding: "0 8px" },
|
|
4806
|
-
"aria-label": muted ? "Unmute video" : "Mute video",
|
|
4807
|
-
title: muted ? "Muted \u2014 click to unmute" : "Sound on \u2014 click to mute",
|
|
4808
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
4809
|
-
onClick: (e) => {
|
|
4810
|
-
e.stopPropagation();
|
|
4811
|
-
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
4812
|
-
},
|
|
4813
|
-
children: muted ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.VolumeX, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Volume2, { size: 14 })
|
|
4814
|
-
}
|
|
4815
|
-
)
|
|
4816
|
-
]
|
|
4817
|
-
}
|
|
4818
|
-
) : null;
|
|
4819
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4820
|
-
settingsBar,
|
|
4821
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4822
|
-
"div",
|
|
4823
|
-
{
|
|
4824
|
-
"data-ohw-bridge": "",
|
|
4825
|
-
"data-ohw-media-overlay": "",
|
|
4826
|
-
className: "flex items-center justify-center cursor-pointer",
|
|
4827
|
-
style: {
|
|
4828
|
-
...box,
|
|
4829
|
-
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
4830
|
-
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
4831
|
-
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
4832
|
-
// Replace still works.
|
|
4833
|
-
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4834
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4835
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4836
|
-
},
|
|
4837
|
-
onClick: () => onReplace(hover.key),
|
|
4838
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4839
|
-
Button,
|
|
4840
|
-
{
|
|
4841
|
-
"data-ohw-media-overlay": "",
|
|
4842
|
-
variant: "outline",
|
|
4843
|
-
size: "sm",
|
|
4844
|
-
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4845
|
-
style: OVERLAY_BUTTON_STYLE,
|
|
4846
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
4847
|
-
onClick: (e) => {
|
|
4848
|
-
e.stopPropagation();
|
|
4849
|
-
onReplace(hover.key);
|
|
4850
|
-
},
|
|
4851
|
-
children: [
|
|
4852
|
-
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.ImageIcon, { size: 14 }),
|
|
4853
|
-
isVideo ? "Replace video" : "Replace image"
|
|
4854
|
-
]
|
|
4855
|
-
}
|
|
4856
|
-
)
|
|
4857
|
-
}
|
|
4858
|
-
)
|
|
4859
|
-
] });
|
|
4860
|
-
}
|
|
4861
|
-
|
|
4862
4594
|
// src/OhhwellsBridge.tsx
|
|
4863
|
-
var
|
|
4864
|
-
var
|
|
4595
|
+
var import_react_dom2 = require("react-dom");
|
|
4596
|
+
var import_navigation = require("next/navigation");
|
|
4865
4597
|
|
|
4866
4598
|
// src/lib/session-search.ts
|
|
4867
4599
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -5137,30 +4869,62 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5137
4869
|
tick();
|
|
5138
4870
|
}
|
|
5139
4871
|
|
|
5140
|
-
// src/ui/
|
|
5141
|
-
var
|
|
4872
|
+
// src/ui/dialog.tsx
|
|
4873
|
+
var React5 = __toESM(require("react"), 1);
|
|
4874
|
+
var import_radix_ui4 = require("radix-ui");
|
|
4875
|
+
|
|
4876
|
+
// src/ui/icons.tsx
|
|
4877
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4878
|
+
function IconX({ className, ...props }) {
|
|
4879
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4880
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M18 6 6 18" }),
|
|
4881
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 6 12 12" })
|
|
4882
|
+
] });
|
|
4883
|
+
}
|
|
4884
|
+
function IconChevronDown({ className, ...props }) {
|
|
4885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
4886
|
+
}
|
|
4887
|
+
function IconFile({ className, ...props }) {
|
|
4888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4889
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
4890
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4891
|
+
] });
|
|
4892
|
+
}
|
|
4893
|
+
function IconInfo({ className, ...props }) {
|
|
4894
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4895
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4896
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 16v-4" }),
|
|
4897
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 8h.01" })
|
|
4898
|
+
] });
|
|
4899
|
+
}
|
|
4900
|
+
function IconArrowRight({ className, ...props }) {
|
|
4901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4902
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M5 12h14" }),
|
|
4903
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
4904
|
+
] });
|
|
4905
|
+
}
|
|
4906
|
+
function IconSection({ className, ...props }) {
|
|
4907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4908
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4909
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4910
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4911
|
+
] });
|
|
4912
|
+
}
|
|
5142
4913
|
|
|
5143
4914
|
// src/ui/dialog.tsx
|
|
5144
|
-
var
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5148
|
-
function Dialog2({
|
|
5149
|
-
...props
|
|
5150
|
-
}) {
|
|
5151
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
4915
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4916
|
+
function Dialog2({ ...props }) {
|
|
4917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
5152
4918
|
}
|
|
5153
|
-
function DialogPortal({
|
|
5154
|
-
...props
|
|
5155
|
-
}) {
|
|
5156
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
|
|
4919
|
+
function DialogPortal({ ...props }) {
|
|
4920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Portal, { ...props });
|
|
5157
4921
|
}
|
|
5158
4922
|
function DialogOverlay({
|
|
5159
4923
|
className,
|
|
5160
4924
|
...props
|
|
5161
4925
|
}) {
|
|
5162
|
-
return /* @__PURE__ */ (0,
|
|
5163
|
-
|
|
4926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4927
|
+
import_radix_ui4.Dialog.Overlay,
|
|
5164
4928
|
{
|
|
5165
4929
|
"data-slot": "dialog-overlay",
|
|
5166
4930
|
"data-ohw-link-modal-root": "",
|
|
@@ -5169,118 +4933,120 @@ function DialogOverlay({
|
|
|
5169
4933
|
}
|
|
5170
4934
|
);
|
|
5171
4935
|
}
|
|
5172
|
-
var DialogContent =
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
children
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
)
|
|
5208
|
-
|
|
5209
|
-
function DialogHeader({
|
|
5210
|
-
className,
|
|
5211
|
-
...props
|
|
5212
|
-
}) {
|
|
5213
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
4936
|
+
var DialogContent = React5.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
4937
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
4938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
4939
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
4940
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4941
|
+
import_radix_ui4.Dialog.Content,
|
|
4942
|
+
{
|
|
4943
|
+
ref,
|
|
4944
|
+
"data-slot": "dialog-content",
|
|
4945
|
+
className: cn(
|
|
4946
|
+
positionMode,
|
|
4947
|
+
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[483px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden",
|
|
4948
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
4949
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
4950
|
+
className
|
|
4951
|
+
),
|
|
4952
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
4953
|
+
...props,
|
|
4954
|
+
children: [
|
|
4955
|
+
children,
|
|
4956
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4957
|
+
import_radix_ui4.Dialog.Close,
|
|
4958
|
+
{
|
|
4959
|
+
type: "button",
|
|
4960
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
4961
|
+
"aria-label": "Close",
|
|
4962
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconX, { "aria-hidden": true })
|
|
4963
|
+
}
|
|
4964
|
+
) : null
|
|
4965
|
+
]
|
|
4966
|
+
}
|
|
4967
|
+
)
|
|
4968
|
+
] });
|
|
4969
|
+
});
|
|
4970
|
+
DialogContent.displayName = import_radix_ui4.Dialog.Content.displayName;
|
|
4971
|
+
function DialogHeader({ className, ...props }) {
|
|
4972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5214
4973
|
}
|
|
5215
|
-
function DialogFooter({
|
|
5216
|
-
className,
|
|
5217
|
-
...props
|
|
5218
|
-
}) {
|
|
5219
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5220
|
-
"div",
|
|
5221
|
-
{
|
|
5222
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
5223
|
-
...props
|
|
5224
|
-
}
|
|
5225
|
-
);
|
|
4974
|
+
function DialogFooter({ className, ...props }) {
|
|
4975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
5226
4976
|
}
|
|
5227
|
-
var DialogTitle =
|
|
5228
|
-
|
|
4977
|
+
var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4978
|
+
import_radix_ui4.Dialog.Title,
|
|
5229
4979
|
{
|
|
5230
4980
|
ref,
|
|
5231
|
-
className: cn(
|
|
5232
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5233
|
-
className
|
|
5234
|
-
),
|
|
4981
|
+
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
5235
4982
|
...props
|
|
5236
4983
|
}
|
|
5237
4984
|
));
|
|
5238
|
-
DialogTitle.displayName =
|
|
5239
|
-
var DialogDescription =
|
|
5240
|
-
|
|
4985
|
+
DialogTitle.displayName = import_radix_ui4.Dialog.Title.displayName;
|
|
4986
|
+
var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4987
|
+
import_radix_ui4.Dialog.Description,
|
|
5241
4988
|
{
|
|
5242
4989
|
ref,
|
|
5243
4990
|
className: cn("text-sm text-muted-foreground", className),
|
|
5244
4991
|
...props
|
|
5245
4992
|
}
|
|
5246
4993
|
));
|
|
5247
|
-
DialogDescription.displayName =
|
|
5248
|
-
var DialogClose =
|
|
4994
|
+
DialogDescription.displayName = import_radix_ui4.Dialog.Description.displayName;
|
|
4995
|
+
var DialogClose = import_radix_ui4.Dialog.Close;
|
|
5249
4996
|
|
|
5250
|
-
// src/ui/
|
|
5251
|
-
var
|
|
4997
|
+
// src/ui/button.tsx
|
|
4998
|
+
var React6 = __toESM(require("react"), 1);
|
|
4999
|
+
var import_radix_ui5 = require("radix-ui");
|
|
5000
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5001
|
+
var buttonVariants = cva(
|
|
5002
|
+
"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
|
|
5003
|
+
{
|
|
5004
|
+
variants: {
|
|
5005
|
+
variant: {
|
|
5006
|
+
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
5007
|
+
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
5008
|
+
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
5009
|
+
},
|
|
5010
|
+
size: {
|
|
5011
|
+
default: "h-9",
|
|
5012
|
+
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
5013
|
+
}
|
|
5014
|
+
},
|
|
5015
|
+
defaultVariants: {
|
|
5016
|
+
variant: "default",
|
|
5017
|
+
size: "default"
|
|
5018
|
+
}
|
|
5019
|
+
}
|
|
5020
|
+
);
|
|
5021
|
+
var Button = React6.forwardRef(
|
|
5022
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
5023
|
+
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
5024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5025
|
+
Comp,
|
|
5026
|
+
{
|
|
5027
|
+
ref,
|
|
5028
|
+
"data-slot": "button",
|
|
5029
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
5030
|
+
...props
|
|
5031
|
+
}
|
|
5032
|
+
);
|
|
5033
|
+
}
|
|
5034
|
+
);
|
|
5035
|
+
Button.displayName = "Button";
|
|
5252
5036
|
|
|
5253
5037
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5254
|
-
var import_lucide_react5 = require("lucide-react");
|
|
5255
5038
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
5256
|
-
function DestinationBreadcrumb({
|
|
5257
|
-
pageTitle,
|
|
5258
|
-
sectionLabel
|
|
5259
|
-
}) {
|
|
5039
|
+
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
5260
5040
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5261
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium
|
|
5041
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5262
5042
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5263
5043
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5264
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5265
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground
|
|
5044
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5045
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5266
5046
|
] }),
|
|
5267
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5268
|
-
import_lucide_react5.ArrowRight,
|
|
5269
|
-
{
|
|
5270
|
-
size: 16,
|
|
5271
|
-
className: "shrink-0 text-muted-foreground",
|
|
5272
|
-
"aria-hidden": true
|
|
5273
|
-
}
|
|
5274
|
-
),
|
|
5047
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5275
5048
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5276
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5277
|
-
import_lucide_react5.GalleryVertical,
|
|
5278
|
-
{
|
|
5279
|
-
size: 16,
|
|
5280
|
-
className: "shrink-0 text-foreground",
|
|
5281
|
-
"aria-hidden": true
|
|
5282
|
-
}
|
|
5283
|
-
),
|
|
5049
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5284
5050
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5285
5051
|
] })
|
|
5286
5052
|
] })
|
|
@@ -5288,13 +5054,8 @@ function DestinationBreadcrumb({
|
|
|
5288
5054
|
}
|
|
5289
5055
|
|
|
5290
5056
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5291
|
-
var import_lucide_react6 = require("lucide-react");
|
|
5292
5057
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5293
|
-
function SectionTreeItem({
|
|
5294
|
-
section,
|
|
5295
|
-
onSelect,
|
|
5296
|
-
selected
|
|
5297
|
-
}) {
|
|
5058
|
+
function SectionTreeItem({ section, onSelect, selected }) {
|
|
5298
5059
|
const interactive = Boolean(onSelect);
|
|
5299
5060
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5300
5061
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
@@ -5322,28 +5083,30 @@ function SectionTreeItem({
|
|
|
5322
5083
|
interactive && selected && "border-primary"
|
|
5323
5084
|
),
|
|
5324
5085
|
children: [
|
|
5325
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5326
|
-
import_lucide_react6.GalleryVertical,
|
|
5327
|
-
{
|
|
5328
|
-
size: 16,
|
|
5329
|
-
className: "shrink-0 text-foreground",
|
|
5330
|
-
"aria-hidden": true
|
|
5331
|
-
}
|
|
5332
|
-
),
|
|
5086
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5333
5087
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5334
5088
|
]
|
|
5335
5089
|
}
|
|
5336
5090
|
)
|
|
5337
5091
|
] });
|
|
5338
5092
|
}
|
|
5093
|
+
function SectionPickerList({ sections, onSelect }) {
|
|
5094
|
+
if (sections.length === 0) {
|
|
5095
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5096
|
+
}
|
|
5097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5098
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5099
|
+
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
5100
|
+
] });
|
|
5101
|
+
}
|
|
5339
5102
|
|
|
5340
5103
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5341
5104
|
var import_react4 = require("react");
|
|
5342
5105
|
|
|
5343
5106
|
// src/ui/input.tsx
|
|
5344
|
-
var
|
|
5107
|
+
var React7 = __toESM(require("react"), 1);
|
|
5345
5108
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5346
|
-
var Input =
|
|
5109
|
+
var Input = React7.forwardRef(
|
|
5347
5110
|
({ className, type, ...props }, ref) => {
|
|
5348
5111
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5349
5112
|
"input",
|
|
@@ -5377,11 +5140,8 @@ function Label({ className, ...props }) {
|
|
|
5377
5140
|
}
|
|
5378
5141
|
|
|
5379
5142
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5380
|
-
var import_lucide_react7 = require("lucide-react");
|
|
5381
5143
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5382
|
-
function FieldChevron({
|
|
5383
|
-
onClick
|
|
5384
|
-
}) {
|
|
5144
|
+
function FieldChevron({ onClick }) {
|
|
5385
5145
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5386
5146
|
"button",
|
|
5387
5147
|
{
|
|
@@ -5390,7 +5150,7 @@ function FieldChevron({
|
|
|
5390
5150
|
onClick,
|
|
5391
5151
|
"aria-label": "Open page list",
|
|
5392
5152
|
tabIndex: -1,
|
|
5393
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5153
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconChevronDown, {})
|
|
5394
5154
|
}
|
|
5395
5155
|
);
|
|
5396
5156
|
}
|
|
@@ -5408,29 +5168,7 @@ function UrlOrPageInput({
|
|
|
5408
5168
|
}) {
|
|
5409
5169
|
const inputId = (0, import_react4.useId)();
|
|
5410
5170
|
const inputRef = (0, import_react4.useRef)(null);
|
|
5411
|
-
const rootRef = (0, import_react4.useRef)(null);
|
|
5412
5171
|
const [isFocused, setIsFocused] = (0, import_react4.useState)(false);
|
|
5413
|
-
(0, import_react4.useEffect)(() => {
|
|
5414
|
-
if (!dropdownOpen) return;
|
|
5415
|
-
const isOutside = (e) => {
|
|
5416
|
-
const root = rootRef.current;
|
|
5417
|
-
if (!root) return true;
|
|
5418
|
-
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5419
|
-
if (path.includes(root)) return false;
|
|
5420
|
-
const target = e.target;
|
|
5421
|
-
return !(target instanceof Node && root.contains(target));
|
|
5422
|
-
};
|
|
5423
|
-
const closeIfOutside = (e) => {
|
|
5424
|
-
if (!isOutside(e)) return;
|
|
5425
|
-
onDropdownOpenChange(false);
|
|
5426
|
-
};
|
|
5427
|
-
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5428
|
-
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5429
|
-
return () => {
|
|
5430
|
-
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5431
|
-
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5432
|
-
};
|
|
5433
|
-
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5434
5172
|
const openDropdown = () => {
|
|
5435
5173
|
if (readOnly || filteredPages.length === 0) return;
|
|
5436
5174
|
onDropdownOpenChange(true);
|
|
@@ -5453,16 +5191,9 @@ function UrlOrPageInput({
|
|
|
5453
5191
|
);
|
|
5454
5192
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5455
5193
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5456
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", {
|
|
5194
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative w-full", children: [
|
|
5457
5195
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5458
|
-
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5459
|
-
import_lucide_react7.File,
|
|
5460
|
-
{
|
|
5461
|
-
size: 16,
|
|
5462
|
-
className: "shrink-0 text-foreground",
|
|
5463
|
-
"aria-hidden": true
|
|
5464
|
-
}
|
|
5465
|
-
) }) : null,
|
|
5196
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5466
5197
|
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5467
5198
|
Input,
|
|
5468
5199
|
{
|
|
@@ -5474,14 +5205,7 @@ function UrlOrPageInput({
|
|
|
5474
5205
|
setIsFocused(true);
|
|
5475
5206
|
if (!selectedPage) openDropdown();
|
|
5476
5207
|
},
|
|
5477
|
-
onBlur: () =>
|
|
5478
|
-
setIsFocused(false);
|
|
5479
|
-
requestAnimationFrame(() => {
|
|
5480
|
-
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5481
|
-
onDropdownOpenChange(false);
|
|
5482
|
-
}
|
|
5483
|
-
});
|
|
5484
|
-
},
|
|
5208
|
+
onBlur: () => setIsFocused(false),
|
|
5485
5209
|
placeholder,
|
|
5486
5210
|
className: cn(
|
|
5487
5211
|
"min-w-0 flex-1 truncate border-0 bg-transparent p-0 text-sm font-normal leading-5 shadow-none outline-none ring-0 caret-foreground",
|
|
@@ -5497,7 +5221,7 @@ function UrlOrPageInput({
|
|
|
5497
5221
|
onMouseDown: clearSelection,
|
|
5498
5222
|
"aria-label": "Clear selected page",
|
|
5499
5223
|
tabIndex: -1,
|
|
5500
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5224
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconX, { "aria-hidden": true })
|
|
5501
5225
|
}
|
|
5502
5226
|
) : null,
|
|
5503
5227
|
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
@@ -5506,7 +5230,7 @@ function UrlOrPageInput({
|
|
|
5506
5230
|
"div",
|
|
5507
5231
|
{
|
|
5508
5232
|
"data-ohw-link-page-dropdown": "",
|
|
5509
|
-
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-
|
|
5233
|
+
className: "absolute left-0 right-0 h-20 top-[calc(100%+4px)] z-10 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5510
5234
|
onMouseDown: (e) => e.preventDefault(),
|
|
5511
5235
|
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5512
5236
|
"button",
|
|
@@ -5515,7 +5239,7 @@ function UrlOrPageInput({
|
|
|
5515
5239
|
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",
|
|
5516
5240
|
onClick: () => onPageSelect(page),
|
|
5517
5241
|
children: [
|
|
5518
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5242
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5519
5243
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: page.title })
|
|
5520
5244
|
]
|
|
5521
5245
|
},
|
|
@@ -5528,348 +5252,8 @@ function UrlOrPageInput({
|
|
|
5528
5252
|
] });
|
|
5529
5253
|
}
|
|
5530
5254
|
|
|
5531
|
-
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5532
|
-
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5533
|
-
function LinkEditorPanel({ state, onClose }) {
|
|
5534
|
-
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5535
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5536
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5537
|
-
"button",
|
|
5538
|
-
{
|
|
5539
|
-
type: "button",
|
|
5540
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5541
|
-
"aria-label": "Close",
|
|
5542
|
-
onClick: onClose,
|
|
5543
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
5544
|
-
}
|
|
5545
|
-
) }),
|
|
5546
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5547
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5548
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5549
|
-
DestinationBreadcrumb,
|
|
5550
|
-
{
|
|
5551
|
-
pageTitle: state.selectedPage.title,
|
|
5552
|
-
sectionLabel: state.selectedSection.label
|
|
5553
|
-
}
|
|
5554
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5555
|
-
UrlOrPageInput,
|
|
5556
|
-
{
|
|
5557
|
-
value: state.searchValue,
|
|
5558
|
-
selectedPage: state.selectedPage,
|
|
5559
|
-
dropdownOpen: state.dropdownOpen,
|
|
5560
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5561
|
-
filteredPages: state.filteredPages,
|
|
5562
|
-
onInputChange: state.handleInputChange,
|
|
5563
|
-
onPageSelect: state.handlePageSelect,
|
|
5564
|
-
urlError: state.urlError
|
|
5565
|
-
}
|
|
5566
|
-
),
|
|
5567
|
-
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5568
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5569
|
-
Button,
|
|
5570
|
-
{
|
|
5571
|
-
type: "button",
|
|
5572
|
-
variant: "outline",
|
|
5573
|
-
className: "w-fit cursor-pointer",
|
|
5574
|
-
size: "sm",
|
|
5575
|
-
onClick: state.handleChooseSection,
|
|
5576
|
-
children: "Choose a section"
|
|
5577
|
-
}
|
|
5578
|
-
),
|
|
5579
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5580
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5581
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5582
|
-
] })
|
|
5583
|
-
] }) : null,
|
|
5584
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5585
|
-
] }),
|
|
5586
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5587
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5588
|
-
Button,
|
|
5589
|
-
{
|
|
5590
|
-
type: "button",
|
|
5591
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5592
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5593
|
-
style: isCancel ? {
|
|
5594
|
-
backgroundColor: "var(--ohw-background)",
|
|
5595
|
-
borderColor: "var(--ohw-border)",
|
|
5596
|
-
color: "var(--ohw-foreground)"
|
|
5597
|
-
} : void 0,
|
|
5598
|
-
onClick: state.handleSecondary,
|
|
5599
|
-
children: state.secondaryLabel
|
|
5600
|
-
}
|
|
5601
|
-
),
|
|
5602
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5603
|
-
Button,
|
|
5604
|
-
{
|
|
5605
|
-
type: "button",
|
|
5606
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5607
|
-
style: {
|
|
5608
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5609
|
-
color: "var(--ohw-primary-foreground)"
|
|
5610
|
-
},
|
|
5611
|
-
disabled: !state.isValid,
|
|
5612
|
-
onClick: state.handleSubmit,
|
|
5613
|
-
children: state.submitLabel
|
|
5614
|
-
}
|
|
5615
|
-
)
|
|
5616
|
-
] })
|
|
5617
|
-
] });
|
|
5618
|
-
}
|
|
5619
|
-
|
|
5620
|
-
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5621
|
-
var import_react5 = require("react");
|
|
5622
|
-
var import_react_dom = require("react-dom");
|
|
5623
|
-
var import_lucide_react9 = require("lucide-react");
|
|
5624
|
-
var import_navigation = require("next/navigation");
|
|
5625
|
-
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5626
|
-
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5627
|
-
function rectsEqual(a, b) {
|
|
5628
|
-
if (a.size !== b.size) return false;
|
|
5629
|
-
for (const [id, rect] of a) {
|
|
5630
|
-
const other = b.get(id);
|
|
5631
|
-
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5632
|
-
return false;
|
|
5633
|
-
}
|
|
5634
|
-
}
|
|
5635
|
-
return true;
|
|
5636
|
-
}
|
|
5637
|
-
function useSectionRects(sectionIdsKey, enabled) {
|
|
5638
|
-
const [rects, setRects] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
|
|
5639
|
-
const sectionIds = (0, import_react5.useMemo)(
|
|
5640
|
-
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5641
|
-
[sectionIdsKey]
|
|
5642
|
-
);
|
|
5643
|
-
(0, import_react5.useEffect)(() => {
|
|
5644
|
-
if (!enabled || sectionIds.length === 0) {
|
|
5645
|
-
setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
5646
|
-
return;
|
|
5647
|
-
}
|
|
5648
|
-
const update = () => {
|
|
5649
|
-
const next = /* @__PURE__ */ new Map();
|
|
5650
|
-
for (const id of sectionIds) {
|
|
5651
|
-
const el = document.querySelector(
|
|
5652
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5653
|
-
);
|
|
5654
|
-
if (el) next.set(id, el.getBoundingClientRect());
|
|
5655
|
-
}
|
|
5656
|
-
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5657
|
-
};
|
|
5658
|
-
update();
|
|
5659
|
-
const opts = { capture: true, passive: true };
|
|
5660
|
-
window.addEventListener("scroll", update, opts);
|
|
5661
|
-
window.addEventListener("resize", update);
|
|
5662
|
-
const vv = window.visualViewport;
|
|
5663
|
-
vv?.addEventListener("resize", update);
|
|
5664
|
-
vv?.addEventListener("scroll", update);
|
|
5665
|
-
const ro = new ResizeObserver(update);
|
|
5666
|
-
for (const id of sectionIds) {
|
|
5667
|
-
const el = document.querySelector(
|
|
5668
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5669
|
-
);
|
|
5670
|
-
if (el) ro.observe(el);
|
|
5671
|
-
}
|
|
5672
|
-
return () => {
|
|
5673
|
-
window.removeEventListener("scroll", update, opts);
|
|
5674
|
-
window.removeEventListener("resize", update);
|
|
5675
|
-
vv?.removeEventListener("resize", update);
|
|
5676
|
-
vv?.removeEventListener("scroll", update);
|
|
5677
|
-
ro.disconnect();
|
|
5678
|
-
};
|
|
5679
|
-
}, [sectionIds, enabled]);
|
|
5680
|
-
return rects;
|
|
5681
|
-
}
|
|
5682
|
-
function SectionPickerOverlay({
|
|
5683
|
-
pagePath,
|
|
5684
|
-
sections,
|
|
5685
|
-
onBack,
|
|
5686
|
-
onSelect
|
|
5687
|
-
}) {
|
|
5688
|
-
const router = (0, import_navigation.useRouter)();
|
|
5689
|
-
const pathname = (0, import_navigation.usePathname)();
|
|
5690
|
-
const [selectedId, setSelectedId] = (0, import_react5.useState)(null);
|
|
5691
|
-
const [hoveredId, setHoveredId] = (0, import_react5.useState)(null);
|
|
5692
|
-
const [chromeClip, setChromeClip] = (0, import_react5.useState)(
|
|
5693
|
-
() => ({
|
|
5694
|
-
top: 0,
|
|
5695
|
-
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5696
|
-
})
|
|
5697
|
-
);
|
|
5698
|
-
const normalizedTarget = normalizePath(pagePath);
|
|
5699
|
-
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5700
|
-
(0, import_react5.useEffect)(() => {
|
|
5701
|
-
if (isOnTargetPage) return;
|
|
5702
|
-
const search = readPreservedSearch();
|
|
5703
|
-
router.push(`${normalizedTarget}${search}`);
|
|
5704
|
-
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5705
|
-
(0, import_react5.useEffect)(() => {
|
|
5706
|
-
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5707
|
-
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5708
|
-
el.removeAttribute("data-ohw-hovered");
|
|
5709
|
-
});
|
|
5710
|
-
return () => {
|
|
5711
|
-
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5712
|
-
};
|
|
5713
|
-
}, []);
|
|
5714
|
-
(0, import_react5.useEffect)(() => {
|
|
5715
|
-
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5716
|
-
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5717
|
-
const bottom = Math.min(
|
|
5718
|
-
window.innerHeight,
|
|
5719
|
-
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5720
|
-
);
|
|
5721
|
-
setChromeClip(
|
|
5722
|
-
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5723
|
-
);
|
|
5724
|
-
};
|
|
5725
|
-
const onParentScroll = (e) => {
|
|
5726
|
-
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5727
|
-
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5728
|
-
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5729
|
-
};
|
|
5730
|
-
const onResize = () => {
|
|
5731
|
-
setChromeClip((prev) => {
|
|
5732
|
-
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5733
|
-
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5734
|
-
});
|
|
5735
|
-
};
|
|
5736
|
-
window.addEventListener("message", onParentScroll);
|
|
5737
|
-
window.addEventListener("resize", onResize);
|
|
5738
|
-
return () => {
|
|
5739
|
-
window.removeEventListener("message", onParentScroll);
|
|
5740
|
-
window.removeEventListener("resize", onResize);
|
|
5741
|
-
};
|
|
5742
|
-
}, []);
|
|
5743
|
-
const liveSections = (0, import_react5.useMemo)(() => {
|
|
5744
|
-
if (!isOnTargetPage) return sections;
|
|
5745
|
-
const live = collectSectionsFromDom();
|
|
5746
|
-
if (live.length === 0) return sections;
|
|
5747
|
-
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5748
|
-
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5749
|
-
}, [isOnTargetPage, sections, pathname]);
|
|
5750
|
-
const sectionIdsKey = (0, import_react5.useMemo)(
|
|
5751
|
-
() => liveSections.map((s) => s.id).join("\0"),
|
|
5752
|
-
[liveSections]
|
|
5753
|
-
);
|
|
5754
|
-
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5755
|
-
const handleSelect = (0, import_react5.useCallback)(
|
|
5756
|
-
(section) => {
|
|
5757
|
-
if (selectedId) return;
|
|
5758
|
-
setSelectedId(section.id);
|
|
5759
|
-
onSelect(section);
|
|
5760
|
-
},
|
|
5761
|
-
[selectedId, onSelect]
|
|
5762
|
-
);
|
|
5763
|
-
(0, import_react5.useEffect)(() => {
|
|
5764
|
-
const onKeyDown = (e) => {
|
|
5765
|
-
if (e.key === "Escape") {
|
|
5766
|
-
e.preventDefault();
|
|
5767
|
-
e.stopPropagation();
|
|
5768
|
-
onBack();
|
|
5769
|
-
}
|
|
5770
|
-
};
|
|
5771
|
-
window.addEventListener("keydown", onKeyDown, true);
|
|
5772
|
-
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5773
|
-
}, [onBack]);
|
|
5774
|
-
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5775
|
-
if (!portalRoot) return null;
|
|
5776
|
-
return (0, import_react_dom.createPortal)(
|
|
5777
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5778
|
-
"div",
|
|
5779
|
-
{
|
|
5780
|
-
"data-ohw-section-picker": "",
|
|
5781
|
-
"data-ohw-bridge": "",
|
|
5782
|
-
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5783
|
-
"aria-modal": true,
|
|
5784
|
-
role: "dialog",
|
|
5785
|
-
"aria-label": "Choose a section",
|
|
5786
|
-
children: [
|
|
5787
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5788
|
-
"div",
|
|
5789
|
-
{
|
|
5790
|
-
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5791
|
-
style: { top: chromeClip.top + 20 },
|
|
5792
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5793
|
-
Button,
|
|
5794
|
-
{
|
|
5795
|
-
type: "button",
|
|
5796
|
-
variant: "outline",
|
|
5797
|
-
size: "sm",
|
|
5798
|
-
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5799
|
-
onClick: onBack,
|
|
5800
|
-
children: [
|
|
5801
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5802
|
-
"Back"
|
|
5803
|
-
]
|
|
5804
|
-
}
|
|
5805
|
-
)
|
|
5806
|
-
}
|
|
5807
|
-
),
|
|
5808
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5809
|
-
"div",
|
|
5810
|
-
{
|
|
5811
|
-
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",
|
|
5812
|
-
style: {
|
|
5813
|
-
top: chromeClip.bottom - 20,
|
|
5814
|
-
transform: "translate(-50%, -100%)",
|
|
5815
|
-
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5816
|
-
},
|
|
5817
|
-
"data-ohw-section-picker-hint": "",
|
|
5818
|
-
children: "Click on section to select"
|
|
5819
|
-
}
|
|
5820
|
-
),
|
|
5821
|
-
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5822
|
-
"div",
|
|
5823
|
-
{
|
|
5824
|
-
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",
|
|
5825
|
-
style: { top: chromeClip.top + 64 },
|
|
5826
|
-
children: "Loading page preview\u2026"
|
|
5827
|
-
}
|
|
5828
|
-
) : null,
|
|
5829
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5830
|
-
isOnTargetPage ? liveSections.map((section) => {
|
|
5831
|
-
const rect = rects.get(section.id);
|
|
5832
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5833
|
-
const isSelected = selectedId === section.id;
|
|
5834
|
-
const isLit = isSelected || hoveredId === section.id;
|
|
5835
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5836
|
-
"button",
|
|
5837
|
-
{
|
|
5838
|
-
type: "button",
|
|
5839
|
-
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5840
|
-
style: {
|
|
5841
|
-
top: rect.top,
|
|
5842
|
-
left: rect.left,
|
|
5843
|
-
width: rect.width,
|
|
5844
|
-
height: rect.height,
|
|
5845
|
-
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
5846
|
-
},
|
|
5847
|
-
"aria-label": `Select section ${section.label}`,
|
|
5848
|
-
onMouseEnter: () => setHoveredId(section.id),
|
|
5849
|
-
onMouseLeave: () => setHoveredId((prev) => prev === section.id ? null : prev),
|
|
5850
|
-
onClick: () => handleSelect(section),
|
|
5851
|
-
children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5852
|
-
"span",
|
|
5853
|
-
{
|
|
5854
|
-
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5855
|
-
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5856
|
-
"aria-hidden": true,
|
|
5857
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Check, { className: "size-5" })
|
|
5858
|
-
}
|
|
5859
|
-
) : null
|
|
5860
|
-
},
|
|
5861
|
-
section.id
|
|
5862
|
-
);
|
|
5863
|
-
}) : null
|
|
5864
|
-
]
|
|
5865
|
-
}
|
|
5866
|
-
),
|
|
5867
|
-
portalRoot
|
|
5868
|
-
);
|
|
5869
|
-
}
|
|
5870
|
-
|
|
5871
5255
|
// src/ui/link-modal/useLinkModalState.ts
|
|
5872
|
-
var
|
|
5256
|
+
var import_react5 = require("react");
|
|
5873
5257
|
function useLinkModalState({
|
|
5874
5258
|
open,
|
|
5875
5259
|
mode,
|
|
@@ -5877,18 +5261,21 @@ function useLinkModalState({
|
|
|
5877
5261
|
sections: _sections,
|
|
5878
5262
|
sectionsByPath,
|
|
5879
5263
|
initialTarget,
|
|
5880
|
-
existingTargets
|
|
5264
|
+
existingTargets,
|
|
5881
5265
|
onClose,
|
|
5882
5266
|
onSubmit
|
|
5883
5267
|
}) {
|
|
5884
|
-
const availablePages = (0,
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
const [
|
|
5889
|
-
const [
|
|
5890
|
-
const [
|
|
5891
|
-
const
|
|
5268
|
+
const availablePages = (0, import_react5.useMemo)(
|
|
5269
|
+
() => mode === "create" ? filterAvailablePages(pages, existingTargets) : pages,
|
|
5270
|
+
[mode, pages, existingTargets]
|
|
5271
|
+
);
|
|
5272
|
+
const [searchValue, setSearchValue] = (0, import_react5.useState)("");
|
|
5273
|
+
const [selectedPage, setSelectedPage] = (0, import_react5.useState)(null);
|
|
5274
|
+
const [selectedSection, setSelectedSection] = (0, import_react5.useState)(null);
|
|
5275
|
+
const [step, setStep] = (0, import_react5.useState)("input");
|
|
5276
|
+
const [dropdownOpen, setDropdownOpen] = (0, import_react5.useState)(false);
|
|
5277
|
+
const [urlError, setUrlError] = (0, import_react5.useState)("");
|
|
5278
|
+
const reset = (0, import_react5.useCallback)(() => {
|
|
5892
5279
|
setSearchValue("");
|
|
5893
5280
|
setSelectedPage(null);
|
|
5894
5281
|
setSelectedSection(null);
|
|
@@ -5896,7 +5283,7 @@ function useLinkModalState({
|
|
|
5896
5283
|
setDropdownOpen(false);
|
|
5897
5284
|
setUrlError("");
|
|
5898
5285
|
}, []);
|
|
5899
|
-
(0,
|
|
5286
|
+
(0, import_react5.useEffect)(() => {
|
|
5900
5287
|
if (!open) return;
|
|
5901
5288
|
if (mode === "edit" && initialTarget) {
|
|
5902
5289
|
const { pageRoute } = parseTarget(initialTarget);
|
|
@@ -5911,12 +5298,12 @@ function useLinkModalState({
|
|
|
5911
5298
|
}
|
|
5912
5299
|
setDropdownOpen(false);
|
|
5913
5300
|
setUrlError("");
|
|
5914
|
-
}, [open, mode, initialTarget, reset]);
|
|
5915
|
-
const filteredPages = (0,
|
|
5301
|
+
}, [open, mode, initialTarget, pages, sectionsByPath, reset]);
|
|
5302
|
+
const filteredPages = (0, import_react5.useMemo)(() => {
|
|
5916
5303
|
if (!searchValue.trim()) return availablePages;
|
|
5917
5304
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
5918
5305
|
}, [availablePages, searchValue]);
|
|
5919
|
-
const activeSections = (0,
|
|
5306
|
+
const activeSections = (0, import_react5.useMemo)(() => {
|
|
5920
5307
|
if (!selectedPage) return [];
|
|
5921
5308
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
5922
5309
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -5958,14 +5345,11 @@ function useLinkModalState({
|
|
|
5958
5345
|
const handleBackToSections = () => {
|
|
5959
5346
|
setStep("sectionPicker");
|
|
5960
5347
|
};
|
|
5961
|
-
const handleSectionPickerBack = () => {
|
|
5962
|
-
setStep("input");
|
|
5963
|
-
};
|
|
5964
5348
|
const handleClose = () => {
|
|
5965
5349
|
reset();
|
|
5966
5350
|
onClose();
|
|
5967
5351
|
};
|
|
5968
|
-
const isValid = (0,
|
|
5352
|
+
const isValid = (0, import_react5.useMemo)(() => {
|
|
5969
5353
|
if (urlError) return false;
|
|
5970
5354
|
if (showBreadcrumb) return true;
|
|
5971
5355
|
if (selectedPage) return true;
|
|
@@ -5998,7 +5382,7 @@ function useLinkModalState({
|
|
|
5998
5382
|
onSubmit(normalizeUrl(searchValue));
|
|
5999
5383
|
handleClose();
|
|
6000
5384
|
};
|
|
6001
|
-
const submitLabel =
|
|
5385
|
+
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
6002
5386
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
6003
5387
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
6004
5388
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -6025,29 +5409,23 @@ function useLinkModalState({
|
|
|
6025
5409
|
handleChooseSection,
|
|
6026
5410
|
handleSectionSelect,
|
|
6027
5411
|
handleBackToSections,
|
|
6028
|
-
handleSectionPickerBack,
|
|
6029
5412
|
handleClose,
|
|
6030
5413
|
handleSecondary,
|
|
6031
5414
|
handleSubmit
|
|
6032
5415
|
};
|
|
6033
5416
|
}
|
|
6034
5417
|
|
|
6035
|
-
// src/ui/link-modal/
|
|
6036
|
-
var
|
|
6037
|
-
function
|
|
6038
|
-
window.parent?.postMessage(data, "*");
|
|
6039
|
-
}
|
|
6040
|
-
function LinkPopover({
|
|
5418
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5419
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5420
|
+
function LinkEditorPanel({
|
|
6041
5421
|
open = true,
|
|
6042
|
-
panelRef,
|
|
6043
|
-
portalContainer,
|
|
6044
|
-
onClose,
|
|
6045
5422
|
mode = "create",
|
|
6046
5423
|
pages,
|
|
6047
5424
|
sections = [],
|
|
6048
5425
|
sectionsByPath,
|
|
6049
5426
|
initialTarget,
|
|
6050
5427
|
existingTargets = [],
|
|
5428
|
+
onClose,
|
|
6051
5429
|
onSubmit
|
|
6052
5430
|
}) {
|
|
6053
5431
|
const state = useLinkModalState({
|
|
@@ -6061,100 +5439,115 @@ function LinkPopover({
|
|
|
6061
5439
|
onClose,
|
|
6062
5440
|
onSubmit
|
|
6063
5441
|
});
|
|
6064
|
-
const
|
|
6065
|
-
(0,
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6069
|
-
postToParent({ type: "ow:section-picker", active: true });
|
|
6070
|
-
document.documentElement.style.overflow = "";
|
|
6071
|
-
document.body.style.overflow = "";
|
|
6072
|
-
return () => {
|
|
6073
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6074
|
-
};
|
|
6075
|
-
}
|
|
6076
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6077
|
-
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6078
|
-
const html = document.documentElement;
|
|
6079
|
-
const body = document.body;
|
|
6080
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6081
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6082
|
-
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6083
|
-
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6084
|
-
html.style.overflow = "hidden";
|
|
6085
|
-
body.style.overflow = "hidden";
|
|
6086
|
-
html.style.overscrollBehavior = "none";
|
|
6087
|
-
body.style.overscrollBehavior = "none";
|
|
6088
|
-
const canScrollElement = (el, deltaY) => {
|
|
6089
|
-
const { overflowY } = getComputedStyle(el);
|
|
6090
|
-
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6091
|
-
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6092
|
-
if (deltaY < 0) return el.scrollTop > 0;
|
|
6093
|
-
if (deltaY > 0) return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6094
|
-
return true;
|
|
6095
|
-
};
|
|
6096
|
-
const allowsInternalScroll = (e) => {
|
|
6097
|
-
const target = e.target;
|
|
6098
|
-
if (!(target instanceof Element)) return false;
|
|
6099
|
-
const scrollRoot = target.closest(
|
|
6100
|
-
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6101
|
-
);
|
|
6102
|
-
if (!scrollRoot) return false;
|
|
6103
|
-
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6104
|
-
return canScrollElement(scrollRoot, deltaY);
|
|
6105
|
-
};
|
|
6106
|
-
const preventBackgroundScroll = (e) => {
|
|
6107
|
-
if (allowsInternalScroll(e)) return;
|
|
6108
|
-
e.preventDefault();
|
|
6109
|
-
};
|
|
6110
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6111
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6112
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6113
|
-
return () => {
|
|
6114
|
-
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6115
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6116
|
-
body.style.overflow = prevBodyOverflow;
|
|
6117
|
-
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6118
|
-
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6119
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6120
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6121
|
-
};
|
|
6122
|
-
}, [open, sectionPickerActive]);
|
|
6123
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
6124
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6125
|
-
Dialog2,
|
|
6126
|
-
{
|
|
6127
|
-
open: open && !sectionPickerActive,
|
|
6128
|
-
onOpenChange: (next) => {
|
|
6129
|
-
if (!next) onClose?.();
|
|
6130
|
-
},
|
|
6131
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6132
|
-
DialogContent,
|
|
6133
|
-
{
|
|
6134
|
-
ref: panelRef,
|
|
6135
|
-
container: portalContainer,
|
|
6136
|
-
"data-ohw-link-popover-root": "",
|
|
6137
|
-
"data-ohw-link-modal-root": "",
|
|
6138
|
-
"data-ohw-bridge": "",
|
|
6139
|
-
showCloseButton: false,
|
|
6140
|
-
className: "gap-0 p-0 w-full md:w-md pointer-events-auto z-[2147483646] overflow-visible",
|
|
6141
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkEditorPanel, { state, onClose })
|
|
6142
|
-
}
|
|
6143
|
-
)
|
|
6144
|
-
}
|
|
6145
|
-
),
|
|
6146
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6147
|
-
SectionPickerOverlay,
|
|
5442
|
+
const isCancel = state.secondaryLabel === "Cancel";
|
|
5443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5444
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5445
|
+
"button",
|
|
6148
5446
|
{
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
5447
|
+
type: "button",
|
|
5448
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5449
|
+
"aria-label": "Close",
|
|
5450
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconX, { "aria-hidden": true })
|
|
6153
5451
|
}
|
|
6154
|
-
)
|
|
5452
|
+
) }),
|
|
5453
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5454
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5455
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5456
|
+
DestinationBreadcrumb,
|
|
5457
|
+
{
|
|
5458
|
+
pageTitle: state.selectedPage.title,
|
|
5459
|
+
sectionLabel: state.selectedSection.label
|
|
5460
|
+
}
|
|
5461
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5462
|
+
UrlOrPageInput,
|
|
5463
|
+
{
|
|
5464
|
+
value: state.searchValue,
|
|
5465
|
+
selectedPage: state.selectedPage,
|
|
5466
|
+
dropdownOpen: state.dropdownOpen,
|
|
5467
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5468
|
+
filteredPages: state.filteredPages,
|
|
5469
|
+
onInputChange: state.handleInputChange,
|
|
5470
|
+
onPageSelect: state.handlePageSelect,
|
|
5471
|
+
urlError: state.urlError
|
|
5472
|
+
}
|
|
5473
|
+
),
|
|
5474
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5475
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5476
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5477
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5478
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5479
|
+
] })
|
|
5480
|
+
] }) : null,
|
|
5481
|
+
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5482
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5483
|
+
] }),
|
|
5484
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5485
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5486
|
+
Button,
|
|
5487
|
+
{
|
|
5488
|
+
type: "button",
|
|
5489
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5490
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5491
|
+
style: isCancel ? {
|
|
5492
|
+
backgroundColor: "var(--ohw-background)",
|
|
5493
|
+
borderColor: "var(--ohw-border)",
|
|
5494
|
+
color: "var(--ohw-foreground)"
|
|
5495
|
+
} : void 0,
|
|
5496
|
+
onClick: state.handleSecondary,
|
|
5497
|
+
children: state.secondaryLabel
|
|
5498
|
+
}
|
|
5499
|
+
),
|
|
5500
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5501
|
+
Button,
|
|
5502
|
+
{
|
|
5503
|
+
type: "button",
|
|
5504
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5505
|
+
style: {
|
|
5506
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5507
|
+
color: "var(--ohw-primary-foreground)"
|
|
5508
|
+
},
|
|
5509
|
+
disabled: !state.isValid,
|
|
5510
|
+
onClick: state.handleSubmit,
|
|
5511
|
+
children: state.submitLabel
|
|
5512
|
+
}
|
|
5513
|
+
)
|
|
5514
|
+
] })
|
|
6155
5515
|
] });
|
|
6156
5516
|
}
|
|
6157
5517
|
|
|
5518
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5519
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5520
|
+
function LinkPopover({
|
|
5521
|
+
open = true,
|
|
5522
|
+
panelRef,
|
|
5523
|
+
portalContainer,
|
|
5524
|
+
onClose,
|
|
5525
|
+
...editorProps
|
|
5526
|
+
}) {
|
|
5527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5528
|
+
Dialog2,
|
|
5529
|
+
{
|
|
5530
|
+
open,
|
|
5531
|
+
onOpenChange: (next) => {
|
|
5532
|
+
if (!next) onClose?.();
|
|
5533
|
+
},
|
|
5534
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5535
|
+
DialogContent,
|
|
5536
|
+
{
|
|
5537
|
+
ref: panelRef,
|
|
5538
|
+
container: portalContainer,
|
|
5539
|
+
"data-ohw-link-popover-root": "",
|
|
5540
|
+
"data-ohw-link-modal-root": "",
|
|
5541
|
+
"data-ohw-bridge": "",
|
|
5542
|
+
showCloseButton: false,
|
|
5543
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5544
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5545
|
+
}
|
|
5546
|
+
)
|
|
5547
|
+
}
|
|
5548
|
+
);
|
|
5549
|
+
}
|
|
5550
|
+
|
|
6158
5551
|
// src/ui/link-modal/devFixtures.ts
|
|
6159
5552
|
var DEV_SITE_PAGES = [
|
|
6160
5553
|
{ path: "/", title: "Home" },
|
|
@@ -6174,21 +5567,16 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
6174
5567
|
{ id: "founder-teaser", label: "Founder" },
|
|
6175
5568
|
{ id: "plan-form", label: "Plan Form" },
|
|
6176
5569
|
{ id: "testimonials", label: "Testimonials" },
|
|
6177
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6178
|
-
{ id: "footer", label: "Footer" }
|
|
5570
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
6179
5571
|
],
|
|
6180
5572
|
"/about": [
|
|
6181
5573
|
{ id: "manifesto", label: "Manifesto" },
|
|
6182
5574
|
{ id: "story-letter", label: "Our Story" },
|
|
6183
5575
|
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
6184
5576
|
{ id: "waitlist-cta", label: "Waitlist" },
|
|
6185
|
-
{ id: "personal-training", label: "Personal training" }
|
|
6186
|
-
{ id: "footer", label: "Footer" }
|
|
6187
|
-
],
|
|
6188
|
-
"/classes": [
|
|
6189
|
-
{ id: "class-library", label: "Class Library" },
|
|
6190
|
-
{ id: "footer", label: "Footer" }
|
|
5577
|
+
{ id: "personal-training", label: "Personal training" }
|
|
6191
5578
|
],
|
|
5579
|
+
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
6192
5580
|
"/pricing": [
|
|
6193
5581
|
{ id: "page-header", label: "Page Header" },
|
|
6194
5582
|
{ id: "free-class-cta", label: "Free Class" },
|
|
@@ -6196,25 +5584,19 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
6196
5584
|
{ id: "monthly-memberships", label: "Memberships" },
|
|
6197
5585
|
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
6198
5586
|
{ id: "package-matcher", label: "Packages" },
|
|
6199
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6200
|
-
{ id: "footer", label: "Footer" }
|
|
5587
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
6201
5588
|
],
|
|
6202
5589
|
"/studio": [
|
|
6203
5590
|
{ id: "studio-intro", label: "Studio Intro" },
|
|
6204
5591
|
{ id: "studio-features", label: "Studio Features" },
|
|
6205
5592
|
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
6206
|
-
{ id: "studio-visit", label: "Visit Studio" }
|
|
6207
|
-
{ id: "footer", label: "Footer" }
|
|
6208
|
-
],
|
|
6209
|
-
"/instructors": [
|
|
6210
|
-
{ id: "instructor-grid", label: "Instructors" },
|
|
6211
|
-
{ id: "footer", label: "Footer" }
|
|
5593
|
+
{ id: "studio-visit", label: "Visit Studio" }
|
|
6212
5594
|
],
|
|
5595
|
+
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
6213
5596
|
"/contact": [
|
|
6214
5597
|
{ id: "hello-hero", label: "Hello" },
|
|
6215
5598
|
{ id: "contact-form", label: "Contact Form" },
|
|
6216
|
-
{ id: "faq", label: "FAQ" }
|
|
6217
|
-
{ id: "footer", label: "Footer" }
|
|
5599
|
+
{ id: "faq", label: "FAQ" }
|
|
6218
5600
|
]
|
|
6219
5601
|
};
|
|
6220
5602
|
function shouldUseDevFixtures() {
|
|
@@ -6224,277 +5606,8 @@ function shouldUseDevFixtures() {
|
|
|
6224
5606
|
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6225
5607
|
}
|
|
6226
5608
|
|
|
6227
|
-
// src/lib/nav-items.ts
|
|
6228
|
-
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6229
|
-
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6230
|
-
function getLinkHref(el) {
|
|
6231
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6232
|
-
if (key) {
|
|
6233
|
-
const stored = getStoredLinkHref(key);
|
|
6234
|
-
if (stored !== void 0) return stored;
|
|
6235
|
-
}
|
|
6236
|
-
return el.getAttribute("href") ?? "";
|
|
6237
|
-
}
|
|
6238
|
-
function isNavbarButton(el) {
|
|
6239
|
-
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6240
|
-
}
|
|
6241
|
-
function isNavbarLinkItem(el) {
|
|
6242
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6243
|
-
if (isNavbarButton(el)) return false;
|
|
6244
|
-
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6245
|
-
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6246
|
-
}
|
|
6247
|
-
function getNavbarDesktopContainer() {
|
|
6248
|
-
return document.querySelector("[data-ohw-nav-container]");
|
|
6249
|
-
}
|
|
6250
|
-
function getNavbarDrawerContainer() {
|
|
6251
|
-
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6252
|
-
}
|
|
6253
|
-
function listNavbarItems() {
|
|
6254
|
-
const desktop = getNavbarDesktopContainer();
|
|
6255
|
-
if (desktop) {
|
|
6256
|
-
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6257
|
-
}
|
|
6258
|
-
const drawer = getNavbarDrawerContainer();
|
|
6259
|
-
if (drawer) {
|
|
6260
|
-
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6261
|
-
}
|
|
6262
|
-
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6263
|
-
}
|
|
6264
|
-
function parseNavIndexFromKey(key) {
|
|
6265
|
-
if (!key) return null;
|
|
6266
|
-
const match = key.match(/^nav-(\d+)-href$/);
|
|
6267
|
-
if (!match) return null;
|
|
6268
|
-
return parseInt(match[1], 10);
|
|
6269
|
-
}
|
|
6270
|
-
function getNavbarIndicesInDom() {
|
|
6271
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6272
|
-
for (const item of listNavbarItems()) {
|
|
6273
|
-
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6274
|
-
if (idx !== null) indices.add(idx);
|
|
6275
|
-
}
|
|
6276
|
-
return [...indices].sort((a, b) => a - b);
|
|
6277
|
-
}
|
|
6278
|
-
function getNextNavbarIndex() {
|
|
6279
|
-
const indices = getNavbarIndicesInDom();
|
|
6280
|
-
if (indices.length === 0) return 0;
|
|
6281
|
-
return Math.max(...indices) + 1;
|
|
6282
|
-
}
|
|
6283
|
-
function getNavbarExistingTargets() {
|
|
6284
|
-
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6285
|
-
}
|
|
6286
|
-
function getNavOrderFromDom() {
|
|
6287
|
-
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6288
|
-
}
|
|
6289
|
-
function parseNavOrder(content) {
|
|
6290
|
-
const raw = content[NAV_ORDER_KEY];
|
|
6291
|
-
if (!raw) return null;
|
|
6292
|
-
try {
|
|
6293
|
-
const parsed = JSON.parse(raw);
|
|
6294
|
-
if (!Array.isArray(parsed)) return null;
|
|
6295
|
-
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6296
|
-
} catch {
|
|
6297
|
-
return null;
|
|
6298
|
-
}
|
|
6299
|
-
}
|
|
6300
|
-
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6301
|
-
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6302
|
-
}
|
|
6303
|
-
function cloneNavLinkShell(template) {
|
|
6304
|
-
const anchor = document.createElement("a");
|
|
6305
|
-
if (template) {
|
|
6306
|
-
anchor.style.cssText = template.style.cssText;
|
|
6307
|
-
if (template.className) anchor.className = template.className;
|
|
6308
|
-
}
|
|
6309
|
-
anchor.style.cursor = "pointer";
|
|
6310
|
-
anchor.style.textDecoration = "none";
|
|
6311
|
-
return anchor;
|
|
6312
|
-
}
|
|
6313
|
-
function buildNavLink(index, href, label, template) {
|
|
6314
|
-
const anchor = cloneNavLinkShell(template);
|
|
6315
|
-
anchor.href = href;
|
|
6316
|
-
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6317
|
-
const span = document.createElement("span");
|
|
6318
|
-
span.setAttribute("data-ohw-editable", "text");
|
|
6319
|
-
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6320
|
-
span.textContent = label;
|
|
6321
|
-
anchor.appendChild(span);
|
|
6322
|
-
return anchor;
|
|
6323
|
-
}
|
|
6324
|
-
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6325
|
-
if (!afterHrefKey) {
|
|
6326
|
-
container.appendChild(anchor);
|
|
6327
|
-
return;
|
|
6328
|
-
}
|
|
6329
|
-
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6330
|
-
if (afterEl?.parentElement === container) {
|
|
6331
|
-
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6332
|
-
return;
|
|
6333
|
-
}
|
|
6334
|
-
container.appendChild(anchor);
|
|
6335
|
-
}
|
|
6336
|
-
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6337
|
-
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6338
|
-
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6339
|
-
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6340
|
-
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6341
|
-
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6342
|
-
let primary = null;
|
|
6343
|
-
const desktopContainer = getNavbarDesktopContainer();
|
|
6344
|
-
if (desktopContainer) {
|
|
6345
|
-
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6346
|
-
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6347
|
-
primary = desktopAnchor;
|
|
6348
|
-
}
|
|
6349
|
-
const drawerContainer = getNavbarDrawerContainer();
|
|
6350
|
-
if (drawerContainer) {
|
|
6351
|
-
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6352
|
-
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6353
|
-
if (!primary) primary = drawerAnchor;
|
|
6354
|
-
}
|
|
6355
|
-
if (!primary) {
|
|
6356
|
-
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6357
|
-
const nav = document.querySelector("nav");
|
|
6358
|
-
nav?.appendChild(fallback);
|
|
6359
|
-
primary = fallback;
|
|
6360
|
-
}
|
|
6361
|
-
return primary;
|
|
6362
|
-
}
|
|
6363
|
-
function applyNavOrderToContainer(container, order) {
|
|
6364
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6365
|
-
for (const hrefKey of order) {
|
|
6366
|
-
if (seen.has(hrefKey)) continue;
|
|
6367
|
-
seen.add(hrefKey);
|
|
6368
|
-
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6369
|
-
if (el) container.appendChild(el);
|
|
6370
|
-
}
|
|
6371
|
-
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6372
|
-
if (!isNavbarLinkItem(el)) continue;
|
|
6373
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6374
|
-
if (!key || seen.has(key)) continue;
|
|
6375
|
-
container.appendChild(el);
|
|
6376
|
-
}
|
|
6377
|
-
}
|
|
6378
|
-
function applyNavOrder(order) {
|
|
6379
|
-
const desktop = getNavbarDesktopContainer();
|
|
6380
|
-
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6381
|
-
const drawer = getNavbarDrawerContainer();
|
|
6382
|
-
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6383
|
-
}
|
|
6384
|
-
function collectNavbarIndicesFromContent(content) {
|
|
6385
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6386
|
-
for (const key of Object.keys(content)) {
|
|
6387
|
-
const idx = parseNavIndexFromKey(key);
|
|
6388
|
-
if (idx !== null) indices.add(idx);
|
|
6389
|
-
}
|
|
6390
|
-
const countRaw = content[NAV_COUNT_KEY];
|
|
6391
|
-
if (countRaw) {
|
|
6392
|
-
const count = parseInt(countRaw, 10);
|
|
6393
|
-
if (Number.isFinite(count) && count > 0) {
|
|
6394
|
-
for (let i = 0; i < count; i++) indices.add(i);
|
|
6395
|
-
}
|
|
6396
|
-
}
|
|
6397
|
-
return [...indices].sort((a, b) => a - b);
|
|
6398
|
-
}
|
|
6399
|
-
function navbarIndexExistsInDom(index) {
|
|
6400
|
-
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6401
|
-
}
|
|
6402
|
-
function reconcileNavbarItemsFromContent(content) {
|
|
6403
|
-
const indices = collectNavbarIndicesFromContent(content);
|
|
6404
|
-
for (const index of indices) {
|
|
6405
|
-
if (navbarIndexExistsInDom(index)) continue;
|
|
6406
|
-
const href = content[`nav-${index}-href`];
|
|
6407
|
-
const label = content[`nav-${index}-label`];
|
|
6408
|
-
if (!href && !label) continue;
|
|
6409
|
-
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6410
|
-
}
|
|
6411
|
-
const order = parseNavOrder(content);
|
|
6412
|
-
if (order?.length) applyNavOrder(order);
|
|
6413
|
-
}
|
|
6414
|
-
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6415
|
-
const order = getNavOrderFromDom();
|
|
6416
|
-
if (!afterAnchor) {
|
|
6417
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6418
|
-
return order;
|
|
6419
|
-
}
|
|
6420
|
-
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6421
|
-
if (!afterKey) {
|
|
6422
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6423
|
-
return order;
|
|
6424
|
-
}
|
|
6425
|
-
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6426
|
-
const pos = withoutNew.indexOf(afterKey);
|
|
6427
|
-
if (pos >= 0) {
|
|
6428
|
-
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6429
|
-
return withoutNew;
|
|
6430
|
-
}
|
|
6431
|
-
withoutNew.push(newHrefKey);
|
|
6432
|
-
return withoutNew;
|
|
6433
|
-
}
|
|
6434
|
-
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6435
|
-
const index = getNextNavbarIndex();
|
|
6436
|
-
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6437
|
-
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6438
|
-
const hrefKey = `nav-${index}-href`;
|
|
6439
|
-
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6440
|
-
applyNavOrder(order);
|
|
6441
|
-
return {
|
|
6442
|
-
anchor,
|
|
6443
|
-
index,
|
|
6444
|
-
hrefKey,
|
|
6445
|
-
labelKey: `nav-${index}-label`,
|
|
6446
|
-
href,
|
|
6447
|
-
label,
|
|
6448
|
-
order
|
|
6449
|
-
};
|
|
6450
|
-
}
|
|
6451
|
-
|
|
6452
|
-
// src/ui/navbar-container-chrome.tsx
|
|
6453
|
-
var import_lucide_react10 = require("lucide-react");
|
|
6454
|
-
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6455
|
-
function NavbarContainerChrome({
|
|
6456
|
-
rect,
|
|
6457
|
-
onAdd
|
|
6458
|
-
}) {
|
|
6459
|
-
const chromeGap = 6;
|
|
6460
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6461
|
-
"div",
|
|
6462
|
-
{
|
|
6463
|
-
"data-ohw-navbar-container-chrome": "",
|
|
6464
|
-
"data-ohw-bridge": "",
|
|
6465
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
6466
|
-
style: {
|
|
6467
|
-
top: rect.top - chromeGap,
|
|
6468
|
-
left: rect.left - chromeGap,
|
|
6469
|
-
width: rect.width + chromeGap * 2,
|
|
6470
|
-
height: rect.height + chromeGap * 2
|
|
6471
|
-
},
|
|
6472
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6473
|
-
"button",
|
|
6474
|
-
{
|
|
6475
|
-
type: "button",
|
|
6476
|
-
"data-ohw-navbar-add-button": "",
|
|
6477
|
-
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
6478
|
-
style: { top: "70%" },
|
|
6479
|
-
"aria-label": "Add item",
|
|
6480
|
-
onMouseDown: (e) => {
|
|
6481
|
-
e.preventDefault();
|
|
6482
|
-
e.stopPropagation();
|
|
6483
|
-
},
|
|
6484
|
-
onClick: (e) => {
|
|
6485
|
-
e.preventDefault();
|
|
6486
|
-
e.stopPropagation();
|
|
6487
|
-
onAdd();
|
|
6488
|
-
},
|
|
6489
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6490
|
-
}
|
|
6491
|
-
)
|
|
6492
|
-
}
|
|
6493
|
-
);
|
|
6494
|
-
}
|
|
6495
|
-
|
|
6496
5609
|
// src/ui/badge.tsx
|
|
6497
|
-
var
|
|
5610
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
6498
5611
|
var badgeVariants = cva(
|
|
6499
5612
|
"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",
|
|
6500
5613
|
{
|
|
@@ -6512,12 +5625,12 @@ var badgeVariants = cva(
|
|
|
6512
5625
|
}
|
|
6513
5626
|
);
|
|
6514
5627
|
function Badge({ className, variant, ...props }) {
|
|
6515
|
-
return /* @__PURE__ */ (0,
|
|
5628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6516
5629
|
}
|
|
6517
5630
|
|
|
6518
5631
|
// src/OhhwellsBridge.tsx
|
|
6519
|
-
var
|
|
6520
|
-
var
|
|
5632
|
+
var import_lucide_react3 = require("lucide-react");
|
|
5633
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6521
5634
|
var PRIMARY2 = "#0885FE";
|
|
6522
5635
|
var IMAGE_FADE_MS = 300;
|
|
6523
5636
|
function runOpacityFade(el, onDone) {
|
|
@@ -6694,9 +5807,9 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6694
5807
|
tail.insertAdjacentElement("afterend", container);
|
|
6695
5808
|
}
|
|
6696
5809
|
const root = (0, import_client.createRoot)(container);
|
|
6697
|
-
(0,
|
|
5810
|
+
(0, import_react_dom.flushSync)(() => {
|
|
6698
5811
|
root.render(
|
|
6699
|
-
/* @__PURE__ */ (0,
|
|
5812
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6700
5813
|
SchedulingWidget,
|
|
6701
5814
|
{
|
|
6702
5815
|
notifyOnConnect,
|
|
@@ -6736,7 +5849,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
6736
5849
|
}
|
|
6737
5850
|
}
|
|
6738
5851
|
}
|
|
6739
|
-
function
|
|
5852
|
+
function getLinkHref(el) {
|
|
6740
5853
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
6741
5854
|
return anchor?.getAttribute("href") ?? "";
|
|
6742
5855
|
}
|
|
@@ -6769,11 +5882,8 @@ function collectEditableNodes() {
|
|
|
6769
5882
|
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
6770
5883
|
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
6771
5884
|
}
|
|
6772
|
-
if (el.dataset.ohwEditable === "video") {
|
|
6773
|
-
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
6774
|
-
}
|
|
6775
5885
|
if (el.dataset.ohwEditable === "link") {
|
|
6776
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
5886
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
6777
5887
|
}
|
|
6778
5888
|
return {
|
|
6779
5889
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -6782,65 +5892,11 @@ function collectEditableNodes() {
|
|
|
6782
5892
|
};
|
|
6783
5893
|
});
|
|
6784
5894
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
6785
|
-
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
6786
|
-
if (!key) return;
|
|
6787
|
-
nodes.push({ key, type: "link", text:
|
|
6788
|
-
});
|
|
6789
|
-
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6790
|
-
const key = el.dataset.ohwKey ?? "";
|
|
6791
|
-
const video = getVideoEl(el);
|
|
6792
|
-
if (!key || !video) return;
|
|
6793
|
-
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
6794
|
-
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
6795
|
-
});
|
|
6796
|
-
return nodes;
|
|
6797
|
-
}
|
|
6798
|
-
function isMediaEditable(el) {
|
|
6799
|
-
const t = el.dataset.ohwEditable;
|
|
6800
|
-
return t === "image" || t === "bg-image" || t === "video";
|
|
6801
|
-
}
|
|
6802
|
-
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
6803
|
-
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
6804
|
-
function getVideoEl(el) {
|
|
6805
|
-
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
6806
|
-
}
|
|
6807
|
-
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
6808
|
-
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
6809
|
-
function isBackgroundVideo(video) {
|
|
6810
|
-
return video.autoplay && video.muted;
|
|
6811
|
-
}
|
|
6812
|
-
function syncVideoPlayback(video) {
|
|
6813
|
-
const background = isBackgroundVideo(video);
|
|
6814
|
-
video.controls = !background;
|
|
6815
|
-
if (video.autoplay) void video.play().catch(() => {
|
|
6816
|
-
});
|
|
6817
|
-
else video.pause();
|
|
6818
|
-
}
|
|
6819
|
-
function applyVideoSrc(video, url) {
|
|
6820
|
-
const { autoplay, muted } = video;
|
|
6821
|
-
video.src = url;
|
|
6822
|
-
video.loop = true;
|
|
6823
|
-
video.playsInline = true;
|
|
6824
|
-
video.autoplay = autoplay;
|
|
6825
|
-
video.muted = muted;
|
|
6826
|
-
video.load();
|
|
6827
|
-
syncVideoPlayback(video);
|
|
6828
|
-
}
|
|
6829
|
-
function applyVideoSettingNode(key, val) {
|
|
6830
|
-
const isAutoplay = key.endsWith(VIDEO_AUTOPLAY_SUFFIX);
|
|
6831
|
-
const isMuted = key.endsWith(VIDEO_MUTED_SUFFIX);
|
|
6832
|
-
if (!isAutoplay && !isMuted) return false;
|
|
6833
|
-
const suffixLen = (isAutoplay ? VIDEO_AUTOPLAY_SUFFIX : VIDEO_MUTED_SUFFIX).length;
|
|
6834
|
-
const baseKey = key.slice(0, key.length - suffixLen);
|
|
6835
|
-
const on = val === "true";
|
|
6836
|
-
document.querySelectorAll(`[data-ohw-key="${baseKey}"]`).forEach((el) => {
|
|
6837
|
-
const video = getVideoEl(el);
|
|
6838
|
-
if (!video) return;
|
|
6839
|
-
if (isAutoplay) video.autoplay = on;
|
|
6840
|
-
else video.muted = on;
|
|
6841
|
-
syncVideoPlayback(video);
|
|
5895
|
+
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
5896
|
+
if (!key) return;
|
|
5897
|
+
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
6842
5898
|
});
|
|
6843
|
-
return
|
|
5899
|
+
return nodes;
|
|
6844
5900
|
}
|
|
6845
5901
|
function applyLinkByKey(key, val) {
|
|
6846
5902
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -6854,7 +5910,7 @@ function applyLinkByKey(key, val) {
|
|
|
6854
5910
|
}
|
|
6855
5911
|
function isInsideLinkEditor(target) {
|
|
6856
5912
|
return Boolean(
|
|
6857
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest(
|
|
5913
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
6858
5914
|
);
|
|
6859
5915
|
}
|
|
6860
5916
|
function getHrefKeyFromElement(el) {
|
|
@@ -6865,7 +5921,7 @@ function getHrefKeyFromElement(el) {
|
|
|
6865
5921
|
if (!key) return null;
|
|
6866
5922
|
return { anchor, key };
|
|
6867
5923
|
}
|
|
6868
|
-
function
|
|
5924
|
+
function isNavbarButton(el) {
|
|
6869
5925
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
6870
5926
|
}
|
|
6871
5927
|
function getNavigationItemAnchor(el) {
|
|
@@ -6877,8 +5933,19 @@ function getNavigationItemAnchor(el) {
|
|
|
6877
5933
|
function isNavigationItem(el) {
|
|
6878
5934
|
return getNavigationItemAnchor(el) !== null;
|
|
6879
5935
|
}
|
|
5936
|
+
function getNavigationItemAddHintTarget(anchor) {
|
|
5937
|
+
const items = listNavigationItems();
|
|
5938
|
+
const idx = items.indexOf(anchor);
|
|
5939
|
+
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
5940
|
+
return anchor;
|
|
5941
|
+
}
|
|
5942
|
+
function listNavigationItems() {
|
|
5943
|
+
return Array.from(
|
|
5944
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
5945
|
+
).filter((el) => isNavigationItem(el));
|
|
5946
|
+
}
|
|
6880
5947
|
function getNavigationItemReorderState(anchor) {
|
|
6881
|
-
if (
|
|
5948
|
+
if (isNavbarButton(anchor)) return { key: null, disabled: false };
|
|
6882
5949
|
return getReorderHandleStateFromAnchor(anchor);
|
|
6883
5950
|
}
|
|
6884
5951
|
function getReorderHandleState(el) {
|
|
@@ -6900,120 +5967,6 @@ function clearHrefKeyHover(anchor) {
|
|
|
6900
5967
|
function isInsideNavigationItem(el) {
|
|
6901
5968
|
return getNavigationItemAnchor(el) !== null;
|
|
6902
5969
|
}
|
|
6903
|
-
function getNavigationRoot(el) {
|
|
6904
|
-
const explicit = el.closest("[data-ohw-nav-root]");
|
|
6905
|
-
if (explicit) return explicit;
|
|
6906
|
-
return el.closest("nav, footer, aside");
|
|
6907
|
-
}
|
|
6908
|
-
function findFooterItemGroup(item) {
|
|
6909
|
-
const footer = item.closest("footer");
|
|
6910
|
-
if (!footer) return null;
|
|
6911
|
-
let node = item.parentElement;
|
|
6912
|
-
while (node && node !== footer) {
|
|
6913
|
-
const hasDirectNavItems = Array.from(
|
|
6914
|
-
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
6915
|
-
).some(isNavigationItem);
|
|
6916
|
-
if (hasDirectNavItems) return node;
|
|
6917
|
-
node = node.parentElement;
|
|
6918
|
-
}
|
|
6919
|
-
return null;
|
|
6920
|
-
}
|
|
6921
|
-
function isNavigationRoot(el) {
|
|
6922
|
-
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
6923
|
-
}
|
|
6924
|
-
function isInferredFooterGroup(el) {
|
|
6925
|
-
const footer = el.closest("footer");
|
|
6926
|
-
if (!footer || el === footer) return false;
|
|
6927
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
6928
|
-
}
|
|
6929
|
-
function isNavigationContainer(el) {
|
|
6930
|
-
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
6931
|
-
}
|
|
6932
|
-
function isPointOverNavigation(x, y) {
|
|
6933
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
6934
|
-
if (!navRoot) return false;
|
|
6935
|
-
const r2 = navRoot.getBoundingClientRect();
|
|
6936
|
-
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
6937
|
-
}
|
|
6938
|
-
function isPointOverNavItem(container, x, y) {
|
|
6939
|
-
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
6940
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
6941
|
-
const itemRect = el.getBoundingClientRect();
|
|
6942
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
6943
|
-
});
|
|
6944
|
-
}
|
|
6945
|
-
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
6946
|
-
if (getNavigationItemAnchor(target)) return null;
|
|
6947
|
-
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
6948
|
-
const plainLink = target.closest("a");
|
|
6949
|
-
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
6950
|
-
return null;
|
|
6951
|
-
}
|
|
6952
|
-
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
6953
|
-
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
6954
|
-
return fromClosest;
|
|
6955
|
-
}
|
|
6956
|
-
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
6957
|
-
if (!navRoot) return null;
|
|
6958
|
-
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
6959
|
-
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
6960
|
-
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
6961
|
-
return container;
|
|
6962
|
-
}
|
|
6963
|
-
return null;
|
|
6964
|
-
}
|
|
6965
|
-
function getNavigationSelectionParent(el) {
|
|
6966
|
-
if (isNavigationItem(el)) {
|
|
6967
|
-
const explicit = el.closest("[data-ohw-nav-container]");
|
|
6968
|
-
if (explicit) return explicit;
|
|
6969
|
-
const footerGroup = findFooterItemGroup(el);
|
|
6970
|
-
if (footerGroup) return footerGroup;
|
|
6971
|
-
return getNavigationRoot(el);
|
|
6972
|
-
}
|
|
6973
|
-
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
6974
|
-
return getNavigationRoot(el);
|
|
6975
|
-
}
|
|
6976
|
-
return null;
|
|
6977
|
-
}
|
|
6978
|
-
function placeCaretAtPoint(el, x, y) {
|
|
6979
|
-
const selection = window.getSelection();
|
|
6980
|
-
if (!selection) return;
|
|
6981
|
-
if (typeof document.caretRangeFromPoint === "function") {
|
|
6982
|
-
const range = document.caretRangeFromPoint(x, y);
|
|
6983
|
-
if (range && el.contains(range.startContainer)) {
|
|
6984
|
-
selection.removeAllRanges();
|
|
6985
|
-
selection.addRange(range);
|
|
6986
|
-
return;
|
|
6987
|
-
}
|
|
6988
|
-
}
|
|
6989
|
-
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
6990
|
-
if (typeof caretPositionFromPoint === "function") {
|
|
6991
|
-
const position = caretPositionFromPoint(x, y);
|
|
6992
|
-
if (position && el.contains(position.offsetNode)) {
|
|
6993
|
-
const range = document.createRange();
|
|
6994
|
-
range.setStart(position.offsetNode, position.offset);
|
|
6995
|
-
range.collapse(true);
|
|
6996
|
-
selection.removeAllRanges();
|
|
6997
|
-
selection.addRange(range);
|
|
6998
|
-
}
|
|
6999
|
-
}
|
|
7000
|
-
}
|
|
7001
|
-
function selectAllTextInEditable(el) {
|
|
7002
|
-
const selection = window.getSelection();
|
|
7003
|
-
if (!selection) return;
|
|
7004
|
-
const range = document.createRange();
|
|
7005
|
-
range.selectNodeContents(el);
|
|
7006
|
-
selection.removeAllRanges();
|
|
7007
|
-
selection.addRange(range);
|
|
7008
|
-
}
|
|
7009
|
-
function getNavigationLabelEditable(target) {
|
|
7010
|
-
const editable = target.closest('[data-ohw-editable="text"]');
|
|
7011
|
-
if (!editable) return null;
|
|
7012
|
-
const hrefCtx = getHrefKeyFromElement(editable);
|
|
7013
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7014
|
-
if (!navAnchor) return null;
|
|
7015
|
-
return { editable, navAnchor };
|
|
7016
|
-
}
|
|
7017
5970
|
function collectSections() {
|
|
7018
5971
|
return collectSectionsFromDom();
|
|
7019
5972
|
}
|
|
@@ -7137,8 +6090,6 @@ var ICONS = {
|
|
|
7137
6090
|
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"/>',
|
|
7138
6091
|
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"/>'
|
|
7139
6092
|
};
|
|
7140
|
-
var TOOLBAR_PILL_PADDING = 2;
|
|
7141
|
-
var TOOLBAR_TOGGLE_GAP = 4;
|
|
7142
6093
|
var TOOLBAR_GROUPS = [
|
|
7143
6094
|
[
|
|
7144
6095
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -7163,7 +6114,7 @@ function EditGlowChrome({
|
|
|
7163
6114
|
dragDisabled = false
|
|
7164
6115
|
}) {
|
|
7165
6116
|
const GAP = 6;
|
|
7166
|
-
return /* @__PURE__ */ (0,
|
|
6117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7167
6118
|
"div",
|
|
7168
6119
|
{
|
|
7169
6120
|
ref: elRef,
|
|
@@ -7178,7 +6129,7 @@ function EditGlowChrome({
|
|
|
7178
6129
|
zIndex: 2147483646
|
|
7179
6130
|
},
|
|
7180
6131
|
children: [
|
|
7181
|
-
/* @__PURE__ */ (0,
|
|
6132
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7182
6133
|
"div",
|
|
7183
6134
|
{
|
|
7184
6135
|
style: {
|
|
@@ -7191,7 +6142,7 @@ function EditGlowChrome({
|
|
|
7191
6142
|
}
|
|
7192
6143
|
}
|
|
7193
6144
|
),
|
|
7194
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
6145
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7195
6146
|
"div",
|
|
7196
6147
|
{
|
|
7197
6148
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7203,7 +6154,7 @@ function EditGlowChrome({
|
|
|
7203
6154
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7204
6155
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7205
6156
|
},
|
|
7206
|
-
children: /* @__PURE__ */ (0,
|
|
6157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7207
6158
|
DragHandle,
|
|
7208
6159
|
{
|
|
7209
6160
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7307,7 +6258,7 @@ function FloatingToolbar({
|
|
|
7307
6258
|
onEditLink
|
|
7308
6259
|
}) {
|
|
7309
6260
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7310
|
-
return /* @__PURE__ */ (0,
|
|
6261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7311
6262
|
"div",
|
|
7312
6263
|
{
|
|
7313
6264
|
ref: elRef,
|
|
@@ -7317,23 +6268,14 @@ function FloatingToolbar({
|
|
|
7317
6268
|
left,
|
|
7318
6269
|
transform,
|
|
7319
6270
|
zIndex: 2147483647,
|
|
7320
|
-
background: "#fff",
|
|
7321
|
-
border: "1px solid #E7E5E4",
|
|
7322
|
-
borderRadius: 6,
|
|
7323
|
-
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
7324
|
-
display: "flex",
|
|
7325
|
-
alignItems: "center",
|
|
7326
|
-
padding: TOOLBAR_PILL_PADDING,
|
|
7327
|
-
gap: TOOLBAR_TOGGLE_GAP,
|
|
7328
|
-
fontFamily: "sans-serif",
|
|
7329
6271
|
pointerEvents: "auto"
|
|
7330
6272
|
},
|
|
7331
|
-
children: /* @__PURE__ */ (0,
|
|
7332
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
7333
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
6273
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CustomToolbar, { children: [
|
|
6274
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react6.default.Fragment, { children: [
|
|
6275
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarDivider, {}),
|
|
7334
6276
|
btns.map((btn) => {
|
|
7335
6277
|
const isActive = activeCommands.has(btn.cmd);
|
|
7336
|
-
return /* @__PURE__ */ (0,
|
|
6278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7337
6279
|
CustomToolbarButton,
|
|
7338
6280
|
{
|
|
7339
6281
|
title: btn.title,
|
|
@@ -7342,7 +6284,7 @@ function FloatingToolbar({
|
|
|
7342
6284
|
e.preventDefault();
|
|
7343
6285
|
onCommand(btn.cmd);
|
|
7344
6286
|
},
|
|
7345
|
-
children: /* @__PURE__ */ (0,
|
|
6287
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7346
6288
|
"svg",
|
|
7347
6289
|
{
|
|
7348
6290
|
width: "16",
|
|
@@ -7363,7 +6305,7 @@ function FloatingToolbar({
|
|
|
7363
6305
|
);
|
|
7364
6306
|
})
|
|
7365
6307
|
] }, gi)),
|
|
7366
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
6308
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7367
6309
|
CustomToolbarButton,
|
|
7368
6310
|
{
|
|
7369
6311
|
type: "button",
|
|
@@ -7377,7 +6319,7 @@ function FloatingToolbar({
|
|
|
7377
6319
|
e.preventDefault();
|
|
7378
6320
|
e.stopPropagation();
|
|
7379
6321
|
},
|
|
7380
|
-
children: /* @__PURE__ */ (0,
|
|
6322
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react3.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7381
6323
|
}
|
|
7382
6324
|
) : null
|
|
7383
6325
|
] })
|
|
@@ -7394,7 +6336,7 @@ function StateToggle({
|
|
|
7394
6336
|
states,
|
|
7395
6337
|
onStateChange
|
|
7396
6338
|
}) {
|
|
7397
|
-
return /* @__PURE__ */ (0,
|
|
6339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7398
6340
|
ToggleGroup,
|
|
7399
6341
|
{
|
|
7400
6342
|
"data-ohw-state-toggle": "",
|
|
@@ -7408,7 +6350,7 @@ function StateToggle({
|
|
|
7408
6350
|
left: rect.right - 8,
|
|
7409
6351
|
transform: "translateX(-100%)"
|
|
7410
6352
|
},
|
|
7411
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
6353
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
7412
6354
|
}
|
|
7413
6355
|
);
|
|
7414
6356
|
}
|
|
@@ -7431,12 +6373,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
7431
6373
|
return "";
|
|
7432
6374
|
}
|
|
7433
6375
|
function OhhwellsBridge() {
|
|
7434
|
-
const pathname = (0,
|
|
7435
|
-
const router = (0,
|
|
7436
|
-
const searchParams = (0,
|
|
6376
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
6377
|
+
const router = (0, import_navigation.useRouter)();
|
|
6378
|
+
const searchParams = (0, import_navigation.useSearchParams)();
|
|
7437
6379
|
const isEditMode = isEditSessionActive();
|
|
7438
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
7439
|
-
(0,
|
|
6380
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react6.useState)(null);
|
|
6381
|
+
(0, import_react6.useEffect)(() => {
|
|
7440
6382
|
const figtreeFontId = "ohw-figtree-font";
|
|
7441
6383
|
if (!document.getElementById(figtreeFontId)) {
|
|
7442
6384
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -7444,10 +6386,7 @@ function OhhwellsBridge() {
|
|
|
7444
6386
|
const stylesheet = Object.assign(document.createElement("link"), {
|
|
7445
6387
|
id: figtreeFontId,
|
|
7446
6388
|
rel: "stylesheet",
|
|
7447
|
-
|
|
7448
|
-
// renders inside the customer's document, so it cannot assume any font is present — an
|
|
7449
|
-
// unloaded family would silently fall back to whatever the template happens to use.
|
|
7450
|
-
href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Inter:wght@400;500;600&display=swap"
|
|
6389
|
+
href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&display=swap"
|
|
7451
6390
|
});
|
|
7452
6391
|
document.head.append(preconnect1, preconnect2, stylesheet);
|
|
7453
6392
|
}
|
|
@@ -7464,90 +6403,80 @@ function OhhwellsBridge() {
|
|
|
7464
6403
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
7465
6404
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
7466
6405
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
7467
|
-
const
|
|
6406
|
+
const postToParent = (0, import_react6.useCallback)((data) => {
|
|
7468
6407
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
7469
6408
|
window.parent.postMessage(data, "*");
|
|
7470
6409
|
}
|
|
7471
6410
|
}, []);
|
|
7472
|
-
const [fetchState, setFetchState] = (0,
|
|
7473
|
-
const autoSaveTimers = (0,
|
|
7474
|
-
const activeElRef = (0,
|
|
7475
|
-
const selectedElRef = (0,
|
|
7476
|
-
const originalContentRef = (0,
|
|
7477
|
-
const activeStateElRef = (0,
|
|
7478
|
-
const parentScrollRef = (0,
|
|
7479
|
-
const visibleViewportRef = (0,
|
|
7480
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0,
|
|
7481
|
-
const attachVisibleViewport = (0,
|
|
6411
|
+
const [fetchState, setFetchState] = (0, import_react6.useState)("idle");
|
|
6412
|
+
const autoSaveTimers = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
6413
|
+
const activeElRef = (0, import_react6.useRef)(null);
|
|
6414
|
+
const selectedElRef = (0, import_react6.useRef)(null);
|
|
6415
|
+
const originalContentRef = (0, import_react6.useRef)(null);
|
|
6416
|
+
const activeStateElRef = (0, import_react6.useRef)(null);
|
|
6417
|
+
const parentScrollRef = (0, import_react6.useRef)(null);
|
|
6418
|
+
const visibleViewportRef = (0, import_react6.useRef)(null);
|
|
6419
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react6.useState)(null);
|
|
6420
|
+
const attachVisibleViewport = (0, import_react6.useCallback)((node) => {
|
|
7482
6421
|
visibleViewportRef.current = node;
|
|
7483
6422
|
setDialogPortalContainer(node);
|
|
7484
6423
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
7485
6424
|
}, []);
|
|
7486
|
-
const toolbarElRef = (0,
|
|
7487
|
-
const glowElRef = (0,
|
|
7488
|
-
const hoveredImageRef = (0,
|
|
7489
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
7490
|
-
const
|
|
7491
|
-
const
|
|
7492
|
-
const
|
|
7493
|
-
const
|
|
7494
|
-
const
|
|
7495
|
-
const editStylesRef = (0, import_react8.useRef)(null);
|
|
7496
|
-
const activateRef = (0, import_react8.useRef)(() => {
|
|
7497
|
-
});
|
|
7498
|
-
const deactivateRef = (0, import_react8.useRef)(() => {
|
|
6425
|
+
const toolbarElRef = (0, import_react6.useRef)(null);
|
|
6426
|
+
const glowElRef = (0, import_react6.useRef)(null);
|
|
6427
|
+
const hoveredImageRef = (0, import_react6.useRef)(null);
|
|
6428
|
+
const hoveredImageHasTextOverlapRef = (0, import_react6.useRef)(false);
|
|
6429
|
+
const hoveredGapRef = (0, import_react6.useRef)(null);
|
|
6430
|
+
const imageUnhoverTimerRef = (0, import_react6.useRef)(null);
|
|
6431
|
+
const imageShowTimerRef = (0, import_react6.useRef)(null);
|
|
6432
|
+
const editStylesRef = (0, import_react6.useRef)(null);
|
|
6433
|
+
const activateRef = (0, import_react6.useRef)(() => {
|
|
7499
6434
|
});
|
|
7500
|
-
const
|
|
6435
|
+
const deactivateRef = (0, import_react6.useRef)(() => {
|
|
7501
6436
|
});
|
|
7502
|
-
const
|
|
6437
|
+
const selectRef = (0, import_react6.useRef)(() => {
|
|
7503
6438
|
});
|
|
7504
|
-
const deselectRef = (0,
|
|
6439
|
+
const deselectRef = (0, import_react6.useRef)(() => {
|
|
7505
6440
|
});
|
|
7506
|
-
const reselectNavigationItemRef = (0,
|
|
6441
|
+
const reselectNavigationItemRef = (0, import_react6.useRef)(() => {
|
|
7507
6442
|
});
|
|
7508
|
-
const commitNavigationTextEditRef = (0,
|
|
6443
|
+
const commitNavigationTextEditRef = (0, import_react6.useRef)(() => {
|
|
7509
6444
|
});
|
|
7510
|
-
const refreshActiveCommandsRef = (0,
|
|
6445
|
+
const refreshActiveCommandsRef = (0, import_react6.useRef)(() => {
|
|
7511
6446
|
});
|
|
7512
|
-
const postToParentRef = (0,
|
|
7513
|
-
postToParentRef.current =
|
|
7514
|
-
const sectionsLoadedRef = (0,
|
|
7515
|
-
const pendingScheduleConfigRequests = (0,
|
|
7516
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
7517
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
7518
|
-
const toolbarVariantRef = (0,
|
|
6447
|
+
const postToParentRef = (0, import_react6.useRef)(postToParent);
|
|
6448
|
+
postToParentRef.current = postToParent;
|
|
6449
|
+
const sectionsLoadedRef = (0, import_react6.useRef)(false);
|
|
6450
|
+
const pendingScheduleConfigRequests = (0, import_react6.useRef)([]);
|
|
6451
|
+
const [toolbarRect, setToolbarRect] = (0, import_react6.useState)(null);
|
|
6452
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react6.useState)("none");
|
|
6453
|
+
const toolbarVariantRef = (0, import_react6.useRef)("none");
|
|
7519
6454
|
toolbarVariantRef.current = toolbarVariant;
|
|
7520
|
-
const [reorderHrefKey, setReorderHrefKey] = (0,
|
|
7521
|
-
const [reorderDragDisabled, setReorderDragDisabled] = (0,
|
|
7522
|
-
const [toggleState, setToggleState] = (0,
|
|
7523
|
-
const [maxBadge, setMaxBadge] = (0,
|
|
7524
|
-
const [activeCommands, setActiveCommands] = (0,
|
|
7525
|
-
const [sectionGap, setSectionGap] = (0,
|
|
7526
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] = (0,
|
|
7527
|
-
const
|
|
7528
|
-
const [
|
|
7529
|
-
const
|
|
7530
|
-
const [
|
|
7531
|
-
const
|
|
7532
|
-
const [
|
|
7533
|
-
const [
|
|
7534
|
-
const [
|
|
7535
|
-
const
|
|
7536
|
-
const
|
|
7537
|
-
const
|
|
7538
|
-
const
|
|
7539
|
-
const
|
|
7540
|
-
const sectionsPrefetchGenRef = (0, import_react8.useRef)(0);
|
|
7541
|
-
const setLinkPopoverRef = (0, import_react8.useRef)(setLinkPopover);
|
|
7542
|
-
const linkPopoverPanelRef = (0, import_react8.useRef)(null);
|
|
7543
|
-
const linkPopoverOpenRef = (0, import_react8.useRef)(false);
|
|
7544
|
-
const linkPopoverGraceUntilRef = (0, import_react8.useRef)(0);
|
|
6455
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react6.useState)(null);
|
|
6456
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react6.useState)(false);
|
|
6457
|
+
const [toggleState, setToggleState] = (0, import_react6.useState)(null);
|
|
6458
|
+
const [maxBadge, setMaxBadge] = (0, import_react6.useState)(null);
|
|
6459
|
+
const [activeCommands, setActiveCommands] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
6460
|
+
const [sectionGap, setSectionGap] = (0, import_react6.useState)(null);
|
|
6461
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react6.useState)(false);
|
|
6462
|
+
const hoveredItemElRef = (0, import_react6.useRef)(null);
|
|
6463
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react6.useState)(null);
|
|
6464
|
+
const siblingHintElRef = (0, import_react6.useRef)(null);
|
|
6465
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react6.useState)(null);
|
|
6466
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react6.useState)(false);
|
|
6467
|
+
const [linkPopover, setLinkPopover] = (0, import_react6.useState)(null);
|
|
6468
|
+
const [sitePages, setSitePages] = (0, import_react6.useState)([]);
|
|
6469
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react6.useState)({});
|
|
6470
|
+
const sectionsPrefetchGenRef = (0, import_react6.useRef)(0);
|
|
6471
|
+
const setLinkPopoverRef = (0, import_react6.useRef)(setLinkPopover);
|
|
6472
|
+
const linkPopoverPanelRef = (0, import_react6.useRef)(null);
|
|
6473
|
+
const linkPopoverOpenRef = (0, import_react6.useRef)(false);
|
|
6474
|
+
const linkPopoverGraceUntilRef = (0, import_react6.useRef)(0);
|
|
7545
6475
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7546
|
-
linkPopoverSessionRef.current = linkPopover;
|
|
7547
6476
|
const bumpLinkPopoverGrace = () => {
|
|
7548
6477
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
7549
6478
|
};
|
|
7550
|
-
const runSectionsPrefetch = (0,
|
|
6479
|
+
const runSectionsPrefetch = (0, import_react6.useCallback)((pages) => {
|
|
7551
6480
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
7552
6481
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
7553
6482
|
const paths = pages.map((p) => p.path);
|
|
@@ -7566,9 +6495,9 @@ function OhhwellsBridge() {
|
|
|
7566
6495
|
);
|
|
7567
6496
|
});
|
|
7568
6497
|
}, [isEditMode, pathname]);
|
|
7569
|
-
const runSectionsPrefetchRef = (0,
|
|
6498
|
+
const runSectionsPrefetchRef = (0, import_react6.useRef)(runSectionsPrefetch);
|
|
7570
6499
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
7571
|
-
(0,
|
|
6500
|
+
(0, import_react6.useEffect)(() => {
|
|
7572
6501
|
if (!linkPopover) return;
|
|
7573
6502
|
if (hoveredImageRef.current) {
|
|
7574
6503
|
hoveredImageRef.current = null;
|
|
@@ -7576,9 +6505,33 @@ function OhhwellsBridge() {
|
|
|
7576
6505
|
}
|
|
7577
6506
|
hoveredGapRef.current = null;
|
|
7578
6507
|
setSectionGap(null);
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
6508
|
+
postToParent({ type: "ow:image-unhover" });
|
|
6509
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6510
|
+
const html = document.documentElement;
|
|
6511
|
+
const body = document.body;
|
|
6512
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6513
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6514
|
+
html.style.overflow = "hidden";
|
|
6515
|
+
body.style.overflow = "hidden";
|
|
6516
|
+
const preventBackgroundScroll = (e) => {
|
|
6517
|
+
const target = e.target;
|
|
6518
|
+
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6519
|
+
return;
|
|
6520
|
+
}
|
|
6521
|
+
e.preventDefault();
|
|
6522
|
+
};
|
|
6523
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6524
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6525
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6526
|
+
return () => {
|
|
6527
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6528
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6529
|
+
body.style.overflow = prevBodyOverflow;
|
|
6530
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6531
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6532
|
+
};
|
|
6533
|
+
}, [linkPopover, postToParent]);
|
|
6534
|
+
(0, import_react6.useEffect)(() => {
|
|
7582
6535
|
if (!isEditMode) return;
|
|
7583
6536
|
const useFixtures = shouldUseDevFixtures();
|
|
7584
6537
|
if (useFixtures) {
|
|
@@ -7599,17 +6552,17 @@ function OhhwellsBridge() {
|
|
|
7599
6552
|
runSectionsPrefetchRef.current(mapped);
|
|
7600
6553
|
};
|
|
7601
6554
|
window.addEventListener("message", onSitePages);
|
|
7602
|
-
if (!useFixtures)
|
|
6555
|
+
if (!useFixtures) postToParent({ type: "ow:request-site-pages" });
|
|
7603
6556
|
return () => window.removeEventListener("message", onSitePages);
|
|
7604
|
-
}, [isEditMode,
|
|
7605
|
-
(0,
|
|
6557
|
+
}, [isEditMode, postToParent]);
|
|
6558
|
+
(0, import_react6.useEffect)(() => {
|
|
7606
6559
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
7607
6560
|
void loadAllSectionsManifest().then((manifest) => {
|
|
7608
6561
|
if (Object.keys(manifest).length === 0) return;
|
|
7609
6562
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
7610
6563
|
});
|
|
7611
6564
|
}, [isEditMode]);
|
|
7612
|
-
(0,
|
|
6565
|
+
(0, import_react6.useEffect)(() => {
|
|
7613
6566
|
const update = () => {
|
|
7614
6567
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
7615
6568
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -7633,10 +6586,10 @@ function OhhwellsBridge() {
|
|
|
7633
6586
|
vvp.removeEventListener("resize", update);
|
|
7634
6587
|
};
|
|
7635
6588
|
}, []);
|
|
7636
|
-
const refreshStateRules = (0,
|
|
6589
|
+
const refreshStateRules = (0, import_react6.useCallback)(() => {
|
|
7637
6590
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
7638
6591
|
}, []);
|
|
7639
|
-
const processConfigRequest = (0,
|
|
6592
|
+
const processConfigRequest = (0, import_react6.useCallback)((insertAfterVal) => {
|
|
7640
6593
|
const tracker = getSectionsTracker();
|
|
7641
6594
|
let entries = [];
|
|
7642
6595
|
try {
|
|
@@ -7659,7 +6612,7 @@ function OhhwellsBridge() {
|
|
|
7659
6612
|
}
|
|
7660
6613
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
7661
6614
|
}, [isEditMode]);
|
|
7662
|
-
const deactivate = (0,
|
|
6615
|
+
const deactivate = (0, import_react6.useCallback)(() => {
|
|
7663
6616
|
const el = activeElRef.current;
|
|
7664
6617
|
if (!el) return;
|
|
7665
6618
|
const key = el.dataset.ohwKey;
|
|
@@ -7688,23 +6641,21 @@ function OhhwellsBridge() {
|
|
|
7688
6641
|
setMaxBadge(null);
|
|
7689
6642
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7690
6643
|
setToolbarShowEditLink(false);
|
|
7691
|
-
|
|
7692
|
-
}, [
|
|
7693
|
-
const deselect = (0,
|
|
6644
|
+
postToParent({ type: "ow:exit-edit" });
|
|
6645
|
+
}, [postToParent]);
|
|
6646
|
+
const deselect = (0, import_react6.useCallback)(() => {
|
|
7694
6647
|
selectedElRef.current = null;
|
|
7695
6648
|
setReorderHrefKey(null);
|
|
7696
6649
|
setReorderDragDisabled(false);
|
|
7697
6650
|
siblingHintElRef.current = null;
|
|
7698
6651
|
setSiblingHintRect(null);
|
|
7699
6652
|
setIsItemDragging(false);
|
|
7700
|
-
hoveredNavContainerRef.current = null;
|
|
7701
|
-
setHoveredNavContainerRect(null);
|
|
7702
6653
|
if (!activeElRef.current) {
|
|
7703
6654
|
setToolbarRect(null);
|
|
7704
6655
|
setToolbarVariant("none");
|
|
7705
6656
|
}
|
|
7706
6657
|
}, []);
|
|
7707
|
-
const reselectNavigationItem = (0,
|
|
6658
|
+
const reselectNavigationItem = (0, import_react6.useCallback)((navAnchor) => {
|
|
7708
6659
|
selectedElRef.current = navAnchor;
|
|
7709
6660
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
7710
6661
|
setReorderHrefKey(key);
|
|
@@ -7714,7 +6665,7 @@ function OhhwellsBridge() {
|
|
|
7714
6665
|
setToolbarShowEditLink(false);
|
|
7715
6666
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7716
6667
|
}, []);
|
|
7717
|
-
const commitNavigationTextEdit = (0,
|
|
6668
|
+
const commitNavigationTextEdit = (0, import_react6.useCallback)((navAnchor) => {
|
|
7718
6669
|
const el = activeElRef.current;
|
|
7719
6670
|
if (!el) return;
|
|
7720
6671
|
const key = el.dataset.ohwKey;
|
|
@@ -7727,9 +6678,9 @@ function OhhwellsBridge() {
|
|
|
7727
6678
|
const html = sanitizeHtml(el.innerHTML);
|
|
7728
6679
|
const original = originalContentRef.current ?? "";
|
|
7729
6680
|
if (html !== sanitizeHtml(original)) {
|
|
7730
|
-
|
|
6681
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
7731
6682
|
const h = document.documentElement.scrollHeight;
|
|
7732
|
-
if (h > 50)
|
|
6683
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
7733
6684
|
}
|
|
7734
6685
|
}
|
|
7735
6686
|
el.removeAttribute("contenteditable");
|
|
@@ -7737,38 +6688,31 @@ function OhhwellsBridge() {
|
|
|
7737
6688
|
setMaxBadge(null);
|
|
7738
6689
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7739
6690
|
setToolbarShowEditLink(false);
|
|
7740
|
-
|
|
6691
|
+
postToParent({ type: "ow:exit-edit" });
|
|
7741
6692
|
reselectNavigationItem(navAnchor);
|
|
7742
|
-
}, [
|
|
7743
|
-
const
|
|
7744
|
-
const
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
setLinkPopover({
|
|
7750
|
-
key: "__add-nav__",
|
|
7751
|
-
mode: "create",
|
|
7752
|
-
intent: "add-nav"
|
|
7753
|
-
});
|
|
6693
|
+
}, [postToParent, reselectNavigationItem]);
|
|
6694
|
+
const handleAddNavigationItem = (0, import_react6.useCallback)(() => {
|
|
6695
|
+
const selected = selectedElRef.current;
|
|
6696
|
+
if (!selected) return;
|
|
6697
|
+
const target = getNavigationItemAddHintTarget(selected);
|
|
6698
|
+
siblingHintElRef.current = target;
|
|
6699
|
+
setSiblingHintRect(target.getBoundingClientRect());
|
|
7754
6700
|
}, []);
|
|
7755
|
-
const handleItemDragStart = (0,
|
|
6701
|
+
const handleItemDragStart = (0, import_react6.useCallback)(() => {
|
|
7756
6702
|
siblingHintElRef.current = null;
|
|
7757
6703
|
setSiblingHintRect(null);
|
|
7758
6704
|
setIsItemDragging(true);
|
|
7759
6705
|
}, []);
|
|
7760
|
-
const handleItemDragEnd = (0,
|
|
6706
|
+
const handleItemDragEnd = (0, import_react6.useCallback)(() => {
|
|
7761
6707
|
setIsItemDragging(false);
|
|
7762
6708
|
}, []);
|
|
7763
6709
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
7764
6710
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
7765
|
-
const select = (0,
|
|
6711
|
+
const select = (0, import_react6.useCallback)((anchor) => {
|
|
7766
6712
|
if (!isNavigationItem(anchor)) return;
|
|
7767
6713
|
if (activeElRef.current) deactivate();
|
|
7768
6714
|
selectedElRef.current = anchor;
|
|
7769
6715
|
clearHrefKeyHover(anchor);
|
|
7770
|
-
hoveredNavContainerRef.current = null;
|
|
7771
|
-
setHoveredNavContainerRect(null);
|
|
7772
6716
|
setHoveredItemRect(null);
|
|
7773
6717
|
hoveredItemElRef.current = null;
|
|
7774
6718
|
siblingHintElRef.current = null;
|
|
@@ -7782,32 +6726,13 @@ function OhhwellsBridge() {
|
|
|
7782
6726
|
setToolbarShowEditLink(false);
|
|
7783
6727
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7784
6728
|
}, [deactivate]);
|
|
7785
|
-
const
|
|
7786
|
-
if (!isNavigationContainer(el)) return;
|
|
7787
|
-
if (activeElRef.current) deactivate();
|
|
7788
|
-
selectedElRef.current = el;
|
|
7789
|
-
clearHrefKeyHover(el);
|
|
7790
|
-
hoveredNavContainerRef.current = null;
|
|
7791
|
-
setHoveredNavContainerRect(null);
|
|
7792
|
-
setHoveredItemRect(null);
|
|
7793
|
-
hoveredItemElRef.current = null;
|
|
7794
|
-
siblingHintElRef.current = null;
|
|
7795
|
-
setSiblingHintRect(null);
|
|
7796
|
-
setIsItemDragging(false);
|
|
7797
|
-
setReorderHrefKey(null);
|
|
7798
|
-
setReorderDragDisabled(false);
|
|
7799
|
-
setToolbarVariant("select-frame");
|
|
7800
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
7801
|
-
setToolbarShowEditLink(false);
|
|
7802
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7803
|
-
}, [deactivate]);
|
|
7804
|
-
const activate = (0, import_react8.useCallback)((el, options) => {
|
|
6729
|
+
const activate = (0, import_react6.useCallback)((el) => {
|
|
7805
6730
|
if (activeElRef.current === el) return;
|
|
7806
6731
|
selectedElRef.current = null;
|
|
7807
6732
|
deactivate();
|
|
7808
6733
|
if (hoveredImageRef.current) {
|
|
7809
6734
|
hoveredImageRef.current = null;
|
|
7810
|
-
|
|
6735
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7811
6736
|
}
|
|
7812
6737
|
setToolbarVariant("rich-text");
|
|
7813
6738
|
siblingHintElRef.current = null;
|
|
@@ -7819,9 +6744,6 @@ function OhhwellsBridge() {
|
|
|
7819
6744
|
activeElRef.current = el;
|
|
7820
6745
|
originalContentRef.current = el.innerHTML;
|
|
7821
6746
|
el.focus();
|
|
7822
|
-
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
7823
|
-
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
7824
|
-
}
|
|
7825
6747
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
7826
6748
|
const navAnchor = getNavigationItemAnchor(el);
|
|
7827
6749
|
if (navAnchor) {
|
|
@@ -7833,15 +6755,14 @@ function OhhwellsBridge() {
|
|
|
7833
6755
|
setReorderDragDisabled(reorderDisabled);
|
|
7834
6756
|
}
|
|
7835
6757
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
7836
|
-
|
|
6758
|
+
postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
7837
6759
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
7838
|
-
}, [deactivate,
|
|
6760
|
+
}, [deactivate, postToParent]);
|
|
7839
6761
|
activateRef.current = activate;
|
|
7840
6762
|
deactivateRef.current = deactivate;
|
|
7841
6763
|
selectRef.current = select;
|
|
7842
|
-
selectFrameRef.current = selectFrame;
|
|
7843
6764
|
deselectRef.current = deselect;
|
|
7844
|
-
(0,
|
|
6765
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
7845
6766
|
if (!subdomain || isEditMode) {
|
|
7846
6767
|
setFetchState("done");
|
|
7847
6768
|
return;
|
|
@@ -7850,7 +6771,6 @@ function OhhwellsBridge() {
|
|
|
7850
6771
|
const imageLoads = [];
|
|
7851
6772
|
for (const [key, val] of Object.entries(content)) {
|
|
7852
6773
|
if (key === "__ohw_sections") continue;
|
|
7853
|
-
if (applyVideoSettingNode(key, val)) continue;
|
|
7854
6774
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7855
6775
|
if (el.dataset.ohwEditable === "image") {
|
|
7856
6776
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7864,15 +6784,6 @@ function OhhwellsBridge() {
|
|
|
7864
6784
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
7865
6785
|
const next = `url('${val}')`;
|
|
7866
6786
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7867
|
-
} else if (el.dataset.ohwEditable === "video") {
|
|
7868
|
-
const video = getVideoEl(el);
|
|
7869
|
-
if (video && video.src !== val) {
|
|
7870
|
-
applyVideoSrc(video, val);
|
|
7871
|
-
imageLoads.push(new Promise((resolve) => {
|
|
7872
|
-
video.onloadeddata = () => resolve();
|
|
7873
|
-
video.onerror = () => resolve();
|
|
7874
|
-
}));
|
|
7875
|
-
}
|
|
7876
6787
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7877
6788
|
applyLinkHref(el, val);
|
|
7878
6789
|
} else if (el.innerHTML !== val) {
|
|
@@ -7881,7 +6792,6 @@ function OhhwellsBridge() {
|
|
|
7881
6792
|
});
|
|
7882
6793
|
applyLinkByKey(key, val);
|
|
7883
6794
|
}
|
|
7884
|
-
reconcileNavbarItemsFromContent(content);
|
|
7885
6795
|
enforceLinkHrefs();
|
|
7886
6796
|
initSectionsFromContent(content, true);
|
|
7887
6797
|
sectionsLoadedRef.current = true;
|
|
@@ -7910,7 +6820,7 @@ function OhhwellsBridge() {
|
|
|
7910
6820
|
cancelled = true;
|
|
7911
6821
|
};
|
|
7912
6822
|
}, [subdomain, isEditMode]);
|
|
7913
|
-
(0,
|
|
6823
|
+
(0, import_react6.useEffect)(() => {
|
|
7914
6824
|
if (!subdomain || isEditMode) return;
|
|
7915
6825
|
let debounceTimer = null;
|
|
7916
6826
|
let observer = null;
|
|
@@ -7922,7 +6832,6 @@ function OhhwellsBridge() {
|
|
|
7922
6832
|
try {
|
|
7923
6833
|
for (const [key, val] of Object.entries(content)) {
|
|
7924
6834
|
if (key === "__ohw_sections") continue;
|
|
7925
|
-
if (applyVideoSettingNode(key, val)) continue;
|
|
7926
6835
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7927
6836
|
if (el.dataset.ohwEditable === "image") {
|
|
7928
6837
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7930,9 +6839,6 @@ function OhhwellsBridge() {
|
|
|
7930
6839
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
7931
6840
|
const next = `url('${val}')`;
|
|
7932
6841
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7933
|
-
} else if (el.dataset.ohwEditable === "video") {
|
|
7934
|
-
const video = getVideoEl(el);
|
|
7935
|
-
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
7936
6842
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7937
6843
|
applyLinkHref(el, val);
|
|
7938
6844
|
} else if (el.innerHTML !== val) {
|
|
@@ -7941,7 +6847,6 @@ function OhhwellsBridge() {
|
|
|
7941
6847
|
});
|
|
7942
6848
|
applyLinkByKey(key, val);
|
|
7943
6849
|
}
|
|
7944
|
-
reconcileNavbarItemsFromContent(content);
|
|
7945
6850
|
} finally {
|
|
7946
6851
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
7947
6852
|
}
|
|
@@ -7959,44 +6864,26 @@ function OhhwellsBridge() {
|
|
|
7959
6864
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
7960
6865
|
};
|
|
7961
6866
|
}, [subdomain, isEditMode, pathname]);
|
|
7962
|
-
(0,
|
|
6867
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
7963
6868
|
const el = document.getElementById("ohw-loader");
|
|
7964
6869
|
if (!el) return;
|
|
7965
6870
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
7966
6871
|
el.style.display = visible ? "flex" : "none";
|
|
7967
6872
|
}, [subdomain, fetchState]);
|
|
7968
|
-
(0,
|
|
7969
|
-
|
|
7970
|
-
}, [pathname,
|
|
7971
|
-
(0,
|
|
6873
|
+
(0, import_react6.useEffect)(() => {
|
|
6874
|
+
postToParent({ type: "ow:navigation", path: pathname });
|
|
6875
|
+
}, [pathname, postToParent]);
|
|
6876
|
+
(0, import_react6.useEffect)(() => {
|
|
7972
6877
|
if (!isEditMode) return;
|
|
7973
|
-
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
7974
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7975
6878
|
setLinkPopover(null);
|
|
7976
6879
|
deselectRef.current();
|
|
7977
6880
|
deactivateRef.current();
|
|
7978
6881
|
}, [pathname, isEditMode]);
|
|
7979
|
-
(0,
|
|
7980
|
-
const contentForNav = () => {
|
|
7981
|
-
if (isEditMode) return editContentRef.current;
|
|
7982
|
-
if (!subdomain) return {};
|
|
7983
|
-
return contentCache.get(subdomain) ?? {};
|
|
7984
|
-
};
|
|
7985
|
-
const run = () => reconcileNavbarItemsFromContent(contentForNav());
|
|
7986
|
-
run();
|
|
7987
|
-
const nav = document.querySelector("nav");
|
|
7988
|
-
if (!nav) return;
|
|
7989
|
-
const observer = new MutationObserver(() => {
|
|
7990
|
-
requestAnimationFrame(run);
|
|
7991
|
-
});
|
|
7992
|
-
observer.observe(nav, { childList: true, subtree: true });
|
|
7993
|
-
return () => observer.disconnect();
|
|
7994
|
-
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
7995
|
-
(0, import_react8.useEffect)(() => {
|
|
6882
|
+
(0, import_react6.useEffect)(() => {
|
|
7996
6883
|
if (!isEditMode) return;
|
|
7997
6884
|
const measure = () => {
|
|
7998
6885
|
const h = document.body.scrollHeight;
|
|
7999
|
-
if (h > 50)
|
|
6886
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8000
6887
|
};
|
|
8001
6888
|
const t1 = setTimeout(measure, 50);
|
|
8002
6889
|
const t2 = setTimeout(measure, 500);
|
|
@@ -8015,8 +6902,8 @@ function OhhwellsBridge() {
|
|
|
8015
6902
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
8016
6903
|
window.removeEventListener("resize", handleResize);
|
|
8017
6904
|
};
|
|
8018
|
-
}, [pathname, isEditMode,
|
|
8019
|
-
(0,
|
|
6905
|
+
}, [pathname, isEditMode, postToParent]);
|
|
6906
|
+
(0, import_react6.useEffect)(() => {
|
|
8020
6907
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8021
6908
|
const handleClick = (e) => {
|
|
8022
6909
|
const anchor = e.target.closest("a");
|
|
@@ -8032,7 +6919,7 @@ function OhhwellsBridge() {
|
|
|
8032
6919
|
document.addEventListener("click", handleClick, true);
|
|
8033
6920
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8034
6921
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8035
|
-
(0,
|
|
6922
|
+
(0, import_react6.useEffect)(() => {
|
|
8036
6923
|
if (!isEditMode) {
|
|
8037
6924
|
editStylesRef.current?.base.remove();
|
|
8038
6925
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -8055,9 +6942,8 @@ function OhhwellsBridge() {
|
|
|
8055
6942
|
[data-ohw-editable] {
|
|
8056
6943
|
display: block;
|
|
8057
6944
|
}
|
|
8058
|
-
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])
|
|
6945
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]) { cursor: text !important; }
|
|
8059
6946
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8060
|
-
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
8061
6947
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
8062
6948
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
8063
6949
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
@@ -8106,13 +6992,6 @@ function OhhwellsBridge() {
|
|
|
8106
6992
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8107
6993
|
if (isInsideLinkEditor(target)) return;
|
|
8108
6994
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8109
|
-
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8110
|
-
if (navFromChrome) {
|
|
8111
|
-
e.preventDefault();
|
|
8112
|
-
e.stopPropagation();
|
|
8113
|
-
selectFrameRef.current(navFromChrome);
|
|
8114
|
-
return;
|
|
8115
|
-
}
|
|
8116
6995
|
e.preventDefault();
|
|
8117
6996
|
e.stopPropagation();
|
|
8118
6997
|
return;
|
|
@@ -8127,15 +7006,14 @@ function OhhwellsBridge() {
|
|
|
8127
7006
|
bumpLinkPopoverGrace();
|
|
8128
7007
|
setLinkPopoverRef.current({
|
|
8129
7008
|
key: editable.dataset.ohwKey ?? "",
|
|
8130
|
-
|
|
8131
|
-
target: getLinkHref2(editable)
|
|
7009
|
+
target: getLinkHref(editable)
|
|
8132
7010
|
});
|
|
8133
7011
|
return;
|
|
8134
7012
|
}
|
|
8135
|
-
if (
|
|
7013
|
+
if (editable.dataset.ohwEditable === "image" || editable.dataset.ohwEditable === "bg-image") {
|
|
8136
7014
|
e.preventDefault();
|
|
8137
7015
|
e.stopPropagation();
|
|
8138
|
-
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? ""
|
|
7016
|
+
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
8139
7017
|
return;
|
|
8140
7018
|
}
|
|
8141
7019
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
@@ -8144,8 +7022,7 @@ function OhhwellsBridge() {
|
|
|
8144
7022
|
e.preventDefault();
|
|
8145
7023
|
e.stopPropagation();
|
|
8146
7024
|
if (selectedElRef.current === navAnchor) {
|
|
8147
|
-
|
|
8148
|
-
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
7025
|
+
activateRef.current(editable);
|
|
8149
7026
|
return;
|
|
8150
7027
|
}
|
|
8151
7028
|
selectRef.current(navAnchor);
|
|
@@ -8164,22 +7041,6 @@ function OhhwellsBridge() {
|
|
|
8164
7041
|
selectRef.current(hrefAnchor);
|
|
8165
7042
|
return;
|
|
8166
7043
|
}
|
|
8167
|
-
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8168
|
-
if (navContainerToSelect) {
|
|
8169
|
-
e.preventDefault();
|
|
8170
|
-
e.stopPropagation();
|
|
8171
|
-
selectFrameRef.current(navContainerToSelect);
|
|
8172
|
-
return;
|
|
8173
|
-
}
|
|
8174
|
-
const selectedContainer = selectedElRef.current;
|
|
8175
|
-
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
8176
|
-
const navItem = getNavigationItemAnchor(target);
|
|
8177
|
-
if (!navItem && (selectedContainer === target || selectedContainer.contains(target))) {
|
|
8178
|
-
e.preventDefault();
|
|
8179
|
-
e.stopPropagation();
|
|
8180
|
-
return;
|
|
8181
|
-
}
|
|
8182
|
-
}
|
|
8183
7044
|
if (activeElRef.current) {
|
|
8184
7045
|
const sel = window.getSelection();
|
|
8185
7046
|
if (sel && !sel.isCollapsed) {
|
|
@@ -8205,48 +7066,10 @@ function OhhwellsBridge() {
|
|
|
8205
7066
|
deselectRef.current();
|
|
8206
7067
|
deactivateRef.current();
|
|
8207
7068
|
};
|
|
8208
|
-
const handleDblClick = (e) => {
|
|
8209
|
-
const target = e.target;
|
|
8210
|
-
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8211
|
-
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8212
|
-
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8213
|
-
if (isInsideLinkEditor(target)) return;
|
|
8214
|
-
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8215
|
-
return;
|
|
8216
|
-
}
|
|
8217
|
-
const navLabel = getNavigationLabelEditable(target);
|
|
8218
|
-
if (!navLabel) return;
|
|
8219
|
-
const { editable } = navLabel;
|
|
8220
|
-
e.preventDefault();
|
|
8221
|
-
e.stopPropagation();
|
|
8222
|
-
if (activeElRef.current !== editable) {
|
|
8223
|
-
activateRef.current(editable);
|
|
8224
|
-
}
|
|
8225
|
-
requestAnimationFrame(() => {
|
|
8226
|
-
selectAllTextInEditable(editable);
|
|
8227
|
-
refreshActiveCommandsRef.current();
|
|
8228
|
-
});
|
|
8229
|
-
};
|
|
8230
7069
|
const handleMouseOver = (e) => {
|
|
8231
7070
|
const target = e.target;
|
|
8232
|
-
if (toolbarVariantRef.current !== "select-frame") {
|
|
8233
|
-
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8234
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
8235
|
-
hoveredNavContainerRef.current = navContainer;
|
|
8236
|
-
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8237
|
-
hoveredItemElRef.current = null;
|
|
8238
|
-
setHoveredItemRect(null);
|
|
8239
|
-
return;
|
|
8240
|
-
}
|
|
8241
|
-
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8242
|
-
hoveredNavContainerRef.current = null;
|
|
8243
|
-
setHoveredNavContainerRect(null);
|
|
8244
|
-
}
|
|
8245
|
-
}
|
|
8246
7071
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8247
7072
|
if (navAnchor) {
|
|
8248
|
-
hoveredNavContainerRef.current = null;
|
|
8249
|
-
setHoveredNavContainerRect(null);
|
|
8250
7073
|
const selected2 = selectedElRef.current;
|
|
8251
7074
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
8252
7075
|
clearHrefKeyHover(navAnchor);
|
|
@@ -8258,7 +7081,7 @@ function OhhwellsBridge() {
|
|
|
8258
7081
|
if (!editable) return;
|
|
8259
7082
|
const selected = selectedElRef.current;
|
|
8260
7083
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
8261
|
-
if (
|
|
7084
|
+
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
|
|
8262
7085
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
8263
7086
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
8264
7087
|
clearHrefKeyHover(hoverTarget);
|
|
@@ -8271,14 +7094,6 @@ function OhhwellsBridge() {
|
|
|
8271
7094
|
};
|
|
8272
7095
|
const handleMouseOut = (e) => {
|
|
8273
7096
|
const target = e.target;
|
|
8274
|
-
if (target.closest("[data-ohw-nav-container]")) {
|
|
8275
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8276
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8277
|
-
return;
|
|
8278
|
-
}
|
|
8279
|
-
hoveredNavContainerRef.current = null;
|
|
8280
|
-
setHoveredNavContainerRect(null);
|
|
8281
|
-
}
|
|
8282
7097
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8283
7098
|
if (navAnchor) {
|
|
8284
7099
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -8294,7 +7109,7 @@ function OhhwellsBridge() {
|
|
|
8294
7109
|
if (!editable) return;
|
|
8295
7110
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8296
7111
|
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
8297
|
-
if (
|
|
7112
|
+
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
|
|
8298
7113
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
8299
7114
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
8300
7115
|
if (!related?.closest("[data-ohw-href-key]")) {
|
|
@@ -8340,26 +7155,23 @@ function OhhwellsBridge() {
|
|
|
8340
7155
|
}
|
|
8341
7156
|
return { top, left, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
|
|
8342
7157
|
};
|
|
8343
|
-
const
|
|
7158
|
+
const postImageHover = (imgEl, isDragOver = false, forceTextOverlap) => {
|
|
8344
7159
|
const r2 = getVisibleRect(imgEl);
|
|
8345
7160
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
8346
7161
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
8347
|
-
|
|
8348
|
-
|
|
7162
|
+
postToParentRef.current({
|
|
7163
|
+
type: "ow:image-hover",
|
|
8349
7164
|
key: imgEl.dataset.ohwKey ?? "",
|
|
8350
7165
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
8351
|
-
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
8352
7166
|
hasTextOverlap,
|
|
8353
|
-
isDragOver
|
|
8354
|
-
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
7167
|
+
...isDragOver ? { isDragOver: true } : {}
|
|
8355
7168
|
});
|
|
8356
7169
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
8357
7170
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
8358
7171
|
};
|
|
8359
|
-
const clearImageHover = () => setMediaHover(null);
|
|
8360
7172
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
8361
7173
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8362
|
-
const images = Array.from(document.querySelectorAll(
|
|
7174
|
+
const images = Array.from(document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]'));
|
|
8363
7175
|
const matches = [];
|
|
8364
7176
|
for (let i = images.length - 1; i >= 0; i--) {
|
|
8365
7177
|
const el = images[i];
|
|
@@ -8375,9 +7187,7 @@ function OhhwellsBridge() {
|
|
|
8375
7187
|
if (x >= r2.left && x <= r2.left + r2.width && y >= r2.top && y <= r2.top + r2.height) matches.push(el);
|
|
8376
7188
|
}
|
|
8377
7189
|
if (matches.length === 0) return null;
|
|
8378
|
-
const imageTypeMatches = matches.filter(
|
|
8379
|
-
(el) => el.dataset.ohwEditable === "image" || el.dataset.ohwEditable === "video"
|
|
8380
|
-
);
|
|
7190
|
+
const imageTypeMatches = matches.filter((el) => el.dataset.ohwEditable === "image");
|
|
8381
7191
|
const candidatePool = imageTypeMatches.length > 0 ? imageTypeMatches : matches;
|
|
8382
7192
|
const smallest = candidatePool.reduce((best, el) => {
|
|
8383
7193
|
const br = getVisibleRect(best);
|
|
@@ -8400,91 +7210,47 @@ function OhhwellsBridge() {
|
|
|
8400
7210
|
}
|
|
8401
7211
|
return smallest;
|
|
8402
7212
|
};
|
|
8403
|
-
const dismissImageHover = () => {
|
|
8404
|
-
if (hoveredImageRef.current) {
|
|
8405
|
-
hoveredImageRef.current = null;
|
|
8406
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
8407
|
-
resumeAnimTracks();
|
|
8408
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8409
|
-
}
|
|
8410
|
-
clearImageHover();
|
|
8411
|
-
};
|
|
8412
|
-
const probeNavigationHoverAt = (x, y) => {
|
|
8413
|
-
if (toolbarVariantRef.current === "select-frame") {
|
|
8414
|
-
hoveredNavContainerRef.current = null;
|
|
8415
|
-
setHoveredNavContainerRect(null);
|
|
8416
|
-
return;
|
|
8417
|
-
}
|
|
8418
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8419
|
-
if (!navContainer) {
|
|
8420
|
-
hoveredNavContainerRef.current = null;
|
|
8421
|
-
setHoveredNavContainerRect(null);
|
|
8422
|
-
return;
|
|
8423
|
-
}
|
|
8424
|
-
const containerRect = navContainer.getBoundingClientRect();
|
|
8425
|
-
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8426
|
-
if (!overContainer) {
|
|
8427
|
-
hoveredNavContainerRef.current = null;
|
|
8428
|
-
setHoveredNavContainerRect(null);
|
|
8429
|
-
return;
|
|
8430
|
-
}
|
|
8431
|
-
const navItemHit = Array.from(
|
|
8432
|
-
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8433
|
-
).find((el) => {
|
|
8434
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8435
|
-
const itemRect = el.getBoundingClientRect();
|
|
8436
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8437
|
-
});
|
|
8438
|
-
if (navItemHit) {
|
|
8439
|
-
hoveredNavContainerRef.current = null;
|
|
8440
|
-
setHoveredNavContainerRect(null);
|
|
8441
|
-
const selected = selectedElRef.current;
|
|
8442
|
-
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8443
|
-
clearHrefKeyHover(navItemHit);
|
|
8444
|
-
hoveredItemElRef.current = navItemHit;
|
|
8445
|
-
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
8446
|
-
}
|
|
8447
|
-
return;
|
|
8448
|
-
}
|
|
8449
|
-
hoveredNavContainerRef.current = navContainer;
|
|
8450
|
-
setHoveredNavContainerRect(containerRect);
|
|
8451
|
-
hoveredItemElRef.current = null;
|
|
8452
|
-
setHoveredItemRect(null);
|
|
8453
|
-
};
|
|
8454
7213
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
8455
7214
|
if (linkPopoverOpenRef.current) {
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
probeNavigationHoverAt(x, y);
|
|
7215
|
+
if (hoveredImageRef.current) {
|
|
7216
|
+
hoveredImageRef.current = null;
|
|
7217
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7218
|
+
resumeAnimTracks();
|
|
7219
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7220
|
+
}
|
|
8463
7221
|
return;
|
|
8464
7222
|
}
|
|
8465
|
-
hoveredNavContainerRef.current = null;
|
|
8466
|
-
setHoveredNavContainerRect(null);
|
|
8467
7223
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
8468
7224
|
if (toggleEl) {
|
|
7225
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8469
7226
|
const tr = toggleEl.getBoundingClientRect();
|
|
8470
7227
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
8471
|
-
|
|
7228
|
+
if (hoveredImageRef.current) {
|
|
7229
|
+
hoveredImageRef.current = null;
|
|
7230
|
+
resumeAnimTracks();
|
|
7231
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7232
|
+
}
|
|
8472
7233
|
return;
|
|
8473
7234
|
}
|
|
8474
7235
|
}
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
7236
|
+
if (activeElRef.current) {
|
|
7237
|
+
if (hoveredImageRef.current) {
|
|
7238
|
+
hoveredImageRef.current = null;
|
|
7239
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7240
|
+
resumeAnimTracks();
|
|
7241
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7242
|
+
}
|
|
8479
7243
|
return;
|
|
8480
7244
|
}
|
|
7245
|
+
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
8481
7246
|
if (imgEl) {
|
|
7247
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8482
7248
|
const topEl = document.elementFromPoint(x, y);
|
|
8483
7249
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8484
7250
|
if (hoveredImageRef.current) {
|
|
8485
7251
|
hoveredImageRef.current = null;
|
|
8486
7252
|
resumeAnimTracks();
|
|
8487
|
-
|
|
7253
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8488
7254
|
}
|
|
8489
7255
|
return;
|
|
8490
7256
|
}
|
|
@@ -8493,13 +7259,13 @@ function OhhwellsBridge() {
|
|
|
8493
7259
|
hoveredImageRef.current = null;
|
|
8494
7260
|
hoveredImageHasTextOverlapRef.current = false;
|
|
8495
7261
|
resumeAnimTracks();
|
|
8496
|
-
|
|
7262
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8497
7263
|
}
|
|
8498
7264
|
return;
|
|
8499
7265
|
}
|
|
8500
7266
|
const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
|
|
8501
7267
|
const textEditable = Array.from(
|
|
8502
|
-
document.querySelectorAll(
|
|
7268
|
+
document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
|
|
8503
7269
|
).find((el) => {
|
|
8504
7270
|
const er = el.getBoundingClientRect();
|
|
8505
7271
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -8518,14 +7284,14 @@ function OhhwellsBridge() {
|
|
|
8518
7284
|
hoveredImageRef.current = null;
|
|
8519
7285
|
hoveredImageHasTextOverlapRef.current = false;
|
|
8520
7286
|
resumeAnimTracks();
|
|
8521
|
-
|
|
7287
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8522
7288
|
}
|
|
8523
7289
|
return;
|
|
8524
7290
|
}
|
|
8525
7291
|
if (isStateCardImage) {
|
|
8526
7292
|
if (imgEl !== hoveredImageRef.current || !hoveredImageHasTextOverlapRef.current) {
|
|
8527
7293
|
hoveredImageRef.current = imgEl;
|
|
8528
|
-
|
|
7294
|
+
postImageHover(imgEl, isDragOver, true);
|
|
8529
7295
|
}
|
|
8530
7296
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8531
7297
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -8537,7 +7303,7 @@ function OhhwellsBridge() {
|
|
|
8537
7303
|
hoveredImageRef.current = null;
|
|
8538
7304
|
hoveredImageHasTextOverlapRef.current = false;
|
|
8539
7305
|
resumeAnimTracks();
|
|
8540
|
-
|
|
7306
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8541
7307
|
}
|
|
8542
7308
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8543
7309
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -8549,7 +7315,7 @@ function OhhwellsBridge() {
|
|
|
8549
7315
|
if (hoveredImageRef.current) {
|
|
8550
7316
|
hoveredImageRef.current = null;
|
|
8551
7317
|
resumeAnimTracks();
|
|
8552
|
-
|
|
7318
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8553
7319
|
}
|
|
8554
7320
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8555
7321
|
return;
|
|
@@ -8557,9 +7323,9 @@ function OhhwellsBridge() {
|
|
|
8557
7323
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8558
7324
|
if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
|
|
8559
7325
|
hoveredImageRef.current = imgEl;
|
|
8560
|
-
|
|
7326
|
+
postImageHover(imgEl, isDragOver);
|
|
8561
7327
|
} else if (isDragOver) {
|
|
8562
|
-
|
|
7328
|
+
postImageHover(imgEl, true);
|
|
8563
7329
|
}
|
|
8564
7330
|
} else {
|
|
8565
7331
|
const inIframeView = clientX >= 0 && clientY >= 0 && clientX <= window.innerWidth && clientY <= window.innerHeight;
|
|
@@ -8576,14 +7342,14 @@ function OhhwellsBridge() {
|
|
|
8576
7342
|
hoveredImageRef.current = null;
|
|
8577
7343
|
hoveredImageHasTextOverlapRef.current = false;
|
|
8578
7344
|
resumeAnimTracks();
|
|
8579
|
-
|
|
7345
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8580
7346
|
}
|
|
8581
|
-
const { x
|
|
7347
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8582
7348
|
const textEl = Array.from(
|
|
8583
|
-
document.querySelectorAll(
|
|
7349
|
+
document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
|
|
8584
7350
|
).find((el) => {
|
|
8585
7351
|
const er = el.getBoundingClientRect();
|
|
8586
|
-
return
|
|
7352
|
+
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
8587
7353
|
});
|
|
8588
7354
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8589
7355
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -8689,7 +7455,7 @@ function OhhwellsBridge() {
|
|
|
8689
7455
|
if (hoveredImageRef.current !== el) {
|
|
8690
7456
|
hoveredImageRef.current = el;
|
|
8691
7457
|
const isStateCard = !!el.closest("[data-ohw-editable-state]");
|
|
8692
|
-
|
|
7458
|
+
postImageHover(el, true, isStateCard ? true : void 0);
|
|
8693
7459
|
}
|
|
8694
7460
|
};
|
|
8695
7461
|
const handleDragLeave = (e) => {
|
|
@@ -8697,7 +7463,7 @@ function OhhwellsBridge() {
|
|
|
8697
7463
|
if (imgEl) return;
|
|
8698
7464
|
hoveredImageRef.current = null;
|
|
8699
7465
|
resumeAnimTracks();
|
|
8700
|
-
|
|
7466
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8701
7467
|
};
|
|
8702
7468
|
const handleDrop = (e) => {
|
|
8703
7469
|
e.preventDefault();
|
|
@@ -8705,9 +7471,7 @@ function OhhwellsBridge() {
|
|
|
8705
7471
|
if (!el) return;
|
|
8706
7472
|
const file = e.dataTransfer?.files?.[0];
|
|
8707
7473
|
if (file) {
|
|
8708
|
-
|
|
8709
|
-
const accepted = wantsVideo ? file.type.startsWith("video/") : file.type.startsWith("image/");
|
|
8710
|
-
if (accepted) {
|
|
7474
|
+
if (file.type.startsWith("image/")) {
|
|
8711
7475
|
const key = el.dataset.ohwKey ?? "";
|
|
8712
7476
|
const { name, type: mimeType } = file;
|
|
8713
7477
|
const r2 = el.getBoundingClientRect();
|
|
@@ -8721,7 +7485,7 @@ function OhhwellsBridge() {
|
|
|
8721
7485
|
}
|
|
8722
7486
|
hoveredImageRef.current = null;
|
|
8723
7487
|
resumeAnimTracks();
|
|
8724
|
-
|
|
7488
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8725
7489
|
};
|
|
8726
7490
|
const handleImageUrl = (e) => {
|
|
8727
7491
|
if (e.data?.type !== "ow:image-url") return;
|
|
@@ -8739,11 +7503,7 @@ function OhhwellsBridge() {
|
|
|
8739
7503
|
}
|
|
8740
7504
|
});
|
|
8741
7505
|
hoveredImageRef.current = null;
|
|
8742
|
-
|
|
8743
|
-
const entry = prev[key];
|
|
8744
|
-
if (!entry || entry.fadingOut) return prev;
|
|
8745
|
-
return { ...prev, [key]: { ...entry, fadingOut: true } };
|
|
8746
|
-
});
|
|
7506
|
+
postToParentRef.current({ type: "ow:image-loaded", key });
|
|
8747
7507
|
};
|
|
8748
7508
|
let found = false;
|
|
8749
7509
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -8778,19 +7538,6 @@ function OhhwellsBridge() {
|
|
|
8778
7538
|
requestAnimationFrame(() => onReady());
|
|
8779
7539
|
}
|
|
8780
7540
|
}
|
|
8781
|
-
} else if (el.dataset.ohwEditable === "video") {
|
|
8782
|
-
const video = getVideoEl(el);
|
|
8783
|
-
if (video) {
|
|
8784
|
-
found = true;
|
|
8785
|
-
const onReady = () => {
|
|
8786
|
-
video.onloadeddata = null;
|
|
8787
|
-
video.onerror = null;
|
|
8788
|
-
notify();
|
|
8789
|
-
};
|
|
8790
|
-
video.onloadeddata = onReady;
|
|
8791
|
-
video.onerror = onReady;
|
|
8792
|
-
applyVideoSrc(video, url);
|
|
8793
|
-
}
|
|
8794
7541
|
}
|
|
8795
7542
|
});
|
|
8796
7543
|
if (!found) notify();
|
|
@@ -8857,16 +7604,12 @@ function OhhwellsBridge() {
|
|
|
8857
7604
|
sectionsJson = val;
|
|
8858
7605
|
continue;
|
|
8859
7606
|
}
|
|
8860
|
-
if (applyVideoSettingNode(key, val)) continue;
|
|
8861
7607
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8862
7608
|
if (el.dataset.ohwEditable === "image") {
|
|
8863
7609
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
8864
7610
|
if (img) applyEditableImageSrc(img, val);
|
|
8865
7611
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
8866
7612
|
el.style.backgroundImage = `url('${val}')`;
|
|
8867
|
-
} else if (el.dataset.ohwEditable === "video") {
|
|
8868
|
-
const video = getVideoEl(el);
|
|
8869
|
-
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
8870
7613
|
} else if (el.dataset.ohwEditable === "link") {
|
|
8871
7614
|
applyLinkHref(el, val);
|
|
8872
7615
|
} else {
|
|
@@ -8880,8 +7623,6 @@ function OhhwellsBridge() {
|
|
|
8880
7623
|
sectionsLoadedRef.current = true;
|
|
8881
7624
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
8882
7625
|
}
|
|
8883
|
-
editContentRef.current = { ...editContentRef.current, ...content };
|
|
8884
|
-
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
8885
7626
|
enforceLinkHrefs();
|
|
8886
7627
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
8887
7628
|
};
|
|
@@ -8889,7 +7630,6 @@ function OhhwellsBridge() {
|
|
|
8889
7630
|
const handleDeactivate = (e) => {
|
|
8890
7631
|
if (e.data?.type !== "ow:deactivate") return;
|
|
8891
7632
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
8892
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
8893
7633
|
if (linkPopoverOpenRef.current) {
|
|
8894
7634
|
setLinkPopoverRef.current(null);
|
|
8895
7635
|
return;
|
|
@@ -8899,32 +7639,12 @@ function OhhwellsBridge() {
|
|
|
8899
7639
|
};
|
|
8900
7640
|
window.addEventListener("message", handleDeactivate);
|
|
8901
7641
|
const handleKeyDown = (e) => {
|
|
8902
|
-
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
8903
|
-
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
8904
|
-
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
8905
|
-
if (navAnchor) {
|
|
8906
|
-
e.preventDefault();
|
|
8907
|
-
selectAllTextInEditable(activeElRef.current);
|
|
8908
|
-
refreshActiveCommandsRef.current();
|
|
8909
|
-
return;
|
|
8910
|
-
}
|
|
8911
|
-
}
|
|
8912
7642
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
8913
7643
|
setLinkPopoverRef.current(null);
|
|
8914
7644
|
return;
|
|
8915
7645
|
}
|
|
8916
7646
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
8917
|
-
|
|
8918
|
-
deselectRef.current();
|
|
8919
|
-
return;
|
|
8920
|
-
}
|
|
8921
|
-
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
8922
|
-
if (parent) {
|
|
8923
|
-
e.preventDefault();
|
|
8924
|
-
selectFrameRef.current(parent);
|
|
8925
|
-
} else {
|
|
8926
|
-
deselectRef.current();
|
|
8927
|
-
}
|
|
7647
|
+
deselectRef.current();
|
|
8928
7648
|
return;
|
|
8929
7649
|
}
|
|
8930
7650
|
if (e.key === "Escape" && activeElRef.current) {
|
|
@@ -8982,18 +7702,18 @@ function OhhwellsBridge() {
|
|
|
8982
7702
|
if (hoveredItemElRef.current) {
|
|
8983
7703
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
8984
7704
|
}
|
|
8985
|
-
if (hoveredNavContainerRef.current) {
|
|
8986
|
-
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
8987
|
-
}
|
|
8988
7705
|
if (siblingHintElRef.current) {
|
|
8989
7706
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
8990
7707
|
}
|
|
8991
7708
|
if (hoveredImageRef.current) {
|
|
8992
7709
|
const el = hoveredImageRef.current;
|
|
8993
7710
|
const r2 = el.getBoundingClientRect();
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
7711
|
+
postToParentRef.current({
|
|
7712
|
+
type: "ow:image-hover",
|
|
7713
|
+
key: el.dataset.ohwKey ?? "",
|
|
7714
|
+
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
7715
|
+
hasTextOverlap: hoveredImageHasTextOverlapRef.current
|
|
7716
|
+
});
|
|
8997
7717
|
}
|
|
8998
7718
|
};
|
|
8999
7719
|
const handleSave = (e) => {
|
|
@@ -9082,39 +7802,19 @@ function OhhwellsBridge() {
|
|
|
9082
7802
|
refreshActiveCommandsRef.current = handleSelectionChange;
|
|
9083
7803
|
const handleDocMouseLeave = () => {
|
|
9084
7804
|
hoveredImageRef.current = null;
|
|
9085
|
-
setMediaHover(null);
|
|
9086
7805
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
9087
7806
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
9088
7807
|
activeStateElRef.current = null;
|
|
9089
7808
|
setToggleState(null);
|
|
9090
7809
|
};
|
|
9091
|
-
const
|
|
9092
|
-
if (e.data?.type !== "ow:
|
|
9093
|
-
const { key
|
|
9094
|
-
setUploadingRects((prev) => {
|
|
9095
|
-
if (!uploading) {
|
|
9096
|
-
if (!(key in prev)) return prev;
|
|
9097
|
-
const next = { ...prev };
|
|
9098
|
-
delete next[key];
|
|
9099
|
-
return next;
|
|
9100
|
-
}
|
|
9101
|
-
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
9102
|
-
if (!el) return prev;
|
|
9103
|
-
const r2 = getVisibleRect(el);
|
|
9104
|
-
return {
|
|
9105
|
-
...prev,
|
|
9106
|
-
[key]: { rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
9107
|
-
};
|
|
9108
|
-
});
|
|
7810
|
+
const handleAnimLock = (e) => {
|
|
7811
|
+
if (e.data?.type !== "ow:anim-lock") return;
|
|
7812
|
+
const { key } = e.data;
|
|
9109
7813
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9110
7814
|
const track = el.closest("[data-ohw-hover-pause]");
|
|
9111
|
-
if (
|
|
9112
|
-
if (uploading) {
|
|
7815
|
+
if (track) {
|
|
9113
7816
|
uploadLockedTracks.add(track);
|
|
9114
7817
|
track.setAttribute("data-ohw-hover-paused", "");
|
|
9115
|
-
} else {
|
|
9116
|
-
uploadLockedTracks.delete(track);
|
|
9117
|
-
track.removeAttribute("data-ohw-hover-paused");
|
|
9118
7818
|
}
|
|
9119
7819
|
});
|
|
9120
7820
|
};
|
|
@@ -9156,7 +7856,7 @@ function OhhwellsBridge() {
|
|
|
9156
7856
|
if (e.data?.type !== "ow:click-at") return;
|
|
9157
7857
|
const { clientX, clientY } = e.data;
|
|
9158
7858
|
const allImages = Array.from(
|
|
9159
|
-
document.querySelectorAll(
|
|
7859
|
+
document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]')
|
|
9160
7860
|
).filter((el) => !!el.closest("[data-ohw-editable-state]"));
|
|
9161
7861
|
const stateCardImage = allImages.find((el) => {
|
|
9162
7862
|
const ownerCard = el.closest("[data-ohw-editable-state]");
|
|
@@ -9171,55 +7871,21 @@ function OhhwellsBridge() {
|
|
|
9171
7871
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
9172
7872
|
});
|
|
9173
7873
|
if (stateCardImage) {
|
|
9174
|
-
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? ""
|
|
7874
|
+
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "" });
|
|
9175
7875
|
return;
|
|
9176
7876
|
}
|
|
9177
7877
|
const textEditable = Array.from(
|
|
9178
|
-
document.querySelectorAll(
|
|
7878
|
+
document.querySelectorAll(
|
|
7879
|
+
'[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
|
|
7880
|
+
)
|
|
9179
7881
|
).find((el) => {
|
|
9180
7882
|
const r2 = el.getBoundingClientRect();
|
|
9181
7883
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
9182
7884
|
});
|
|
9183
7885
|
if (textEditable) {
|
|
9184
|
-
|
|
9185
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
9186
|
-
if (navAnchor) {
|
|
9187
|
-
if (selectedElRef.current === navAnchor) {
|
|
9188
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
9189
|
-
} else {
|
|
9190
|
-
selectRef.current(navAnchor);
|
|
9191
|
-
}
|
|
9192
|
-
return;
|
|
9193
|
-
}
|
|
9194
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
7886
|
+
activateRef.current(textEditable);
|
|
9195
7887
|
return;
|
|
9196
7888
|
}
|
|
9197
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9198
|
-
if (navContainer) {
|
|
9199
|
-
const r2 = navContainer.getBoundingClientRect();
|
|
9200
|
-
const pad = 8;
|
|
9201
|
-
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
9202
|
-
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9203
|
-
selectFrameRef.current(navContainer);
|
|
9204
|
-
return;
|
|
9205
|
-
}
|
|
9206
|
-
}
|
|
9207
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
9208
|
-
if (navRoot && navContainer) {
|
|
9209
|
-
const rr = navRoot.getBoundingClientRect();
|
|
9210
|
-
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9211
|
-
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
9212
|
-
if (book) {
|
|
9213
|
-
const br = book.getBoundingClientRect();
|
|
9214
|
-
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
9215
|
-
deactivateRef.current();
|
|
9216
|
-
return;
|
|
9217
|
-
}
|
|
9218
|
-
}
|
|
9219
|
-
selectFrameRef.current(navContainer);
|
|
9220
|
-
return;
|
|
9221
|
-
}
|
|
9222
|
-
}
|
|
9223
7889
|
deactivateRef.current();
|
|
9224
7890
|
};
|
|
9225
7891
|
window.addEventListener("message", handleSave);
|
|
@@ -9229,7 +7895,7 @@ function OhhwellsBridge() {
|
|
|
9229
7895
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
9230
7896
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
9231
7897
|
window.addEventListener("message", handleImageUrl);
|
|
9232
|
-
window.addEventListener("message",
|
|
7898
|
+
window.addEventListener("message", handleAnimLock);
|
|
9233
7899
|
window.addEventListener("message", handleCanvasHeight);
|
|
9234
7900
|
window.addEventListener("message", handleParentScroll);
|
|
9235
7901
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -9241,7 +7907,6 @@ function OhhwellsBridge() {
|
|
|
9241
7907
|
};
|
|
9242
7908
|
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
9243
7909
|
document.addEventListener("click", handleClick, true);
|
|
9244
|
-
document.addEventListener("dblclick", handleDblClick, true);
|
|
9245
7910
|
document.addEventListener("paste", handlePaste, true);
|
|
9246
7911
|
document.addEventListener("input", handleInput, true);
|
|
9247
7912
|
document.addEventListener("mouseover", handleMouseOver, true);
|
|
@@ -9256,7 +7921,6 @@ function OhhwellsBridge() {
|
|
|
9256
7921
|
window.addEventListener("scroll", handleScroll, true);
|
|
9257
7922
|
return () => {
|
|
9258
7923
|
document.removeEventListener("click", handleClick, true);
|
|
9259
|
-
document.removeEventListener("dblclick", handleDblClick, true);
|
|
9260
7924
|
document.removeEventListener("paste", handlePaste, true);
|
|
9261
7925
|
document.removeEventListener("input", handleInput, true);
|
|
9262
7926
|
document.removeEventListener("mouseover", handleMouseOver, true);
|
|
@@ -9276,7 +7940,7 @@ function OhhwellsBridge() {
|
|
|
9276
7940
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
9277
7941
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
9278
7942
|
window.removeEventListener("message", handleImageUrl);
|
|
9279
|
-
window.removeEventListener("message",
|
|
7943
|
+
window.removeEventListener("message", handleAnimLock);
|
|
9280
7944
|
window.removeEventListener("message", handleCanvasHeight);
|
|
9281
7945
|
window.removeEventListener("message", handleParentScroll);
|
|
9282
7946
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -9290,7 +7954,7 @@ function OhhwellsBridge() {
|
|
|
9290
7954
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
9291
7955
|
};
|
|
9292
7956
|
}, [isEditMode, refreshStateRules]);
|
|
9293
|
-
(0,
|
|
7957
|
+
(0, import_react6.useEffect)(() => {
|
|
9294
7958
|
const handler = (e) => {
|
|
9295
7959
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
9296
7960
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -9306,7 +7970,7 @@ function OhhwellsBridge() {
|
|
|
9306
7970
|
window.addEventListener("message", handler);
|
|
9307
7971
|
return () => window.removeEventListener("message", handler);
|
|
9308
7972
|
}, [processConfigRequest]);
|
|
9309
|
-
(0,
|
|
7973
|
+
(0, import_react6.useEffect)(() => {
|
|
9310
7974
|
if (!isEditMode) return;
|
|
9311
7975
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
9312
7976
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -9327,27 +7991,27 @@ function OhhwellsBridge() {
|
|
|
9327
7991
|
const next = { ...prev, [pathKey]: sections };
|
|
9328
7992
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
9329
7993
|
});
|
|
9330
|
-
|
|
9331
|
-
|
|
7994
|
+
postToParent({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
7995
|
+
postToParent({ type: "ow:request-site-pages" });
|
|
9332
7996
|
}, 150);
|
|
9333
7997
|
return () => {
|
|
9334
7998
|
cancelAnimationFrame(raf);
|
|
9335
7999
|
clearTimeout(timer);
|
|
9336
8000
|
};
|
|
9337
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
9338
|
-
(0,
|
|
8001
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent]);
|
|
8002
|
+
(0, import_react6.useEffect)(() => {
|
|
9339
8003
|
scrollToHashSectionWhenReady();
|
|
9340
8004
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
9341
8005
|
window.addEventListener("hashchange", onHashChange);
|
|
9342
8006
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
9343
8007
|
}, [pathname]);
|
|
9344
|
-
const handleCommand = (0,
|
|
8008
|
+
const handleCommand = (0, import_react6.useCallback)((cmd) => {
|
|
9345
8009
|
document.execCommand(cmd, false);
|
|
9346
8010
|
activeElRef.current?.focus();
|
|
9347
8011
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
9348
8012
|
refreshActiveCommandsRef.current();
|
|
9349
8013
|
}, []);
|
|
9350
|
-
const handleStateChange = (0,
|
|
8014
|
+
const handleStateChange = (0, import_react6.useCallback)((state) => {
|
|
9351
8015
|
if (!activeStateElRef.current) return;
|
|
9352
8016
|
const el = activeStateElRef.current;
|
|
9353
8017
|
if (state === "Default") {
|
|
@@ -9360,22 +8024,18 @@ function OhhwellsBridge() {
|
|
|
9360
8024
|
}
|
|
9361
8025
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
9362
8026
|
}, [deactivate]);
|
|
9363
|
-
const closeLinkPopover = (0,
|
|
9364
|
-
|
|
9365
|
-
setLinkPopover(null);
|
|
9366
|
-
}, []);
|
|
9367
|
-
const openLinkPopoverForActive = (0, import_react8.useCallback)(() => {
|
|
8027
|
+
const closeLinkPopover = (0, import_react6.useCallback)(() => setLinkPopover(null), []);
|
|
8028
|
+
const openLinkPopoverForActive = (0, import_react6.useCallback)(() => {
|
|
9368
8029
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
9369
8030
|
if (!hrefCtx) return;
|
|
9370
8031
|
bumpLinkPopoverGrace();
|
|
9371
8032
|
setLinkPopover({
|
|
9372
8033
|
key: hrefCtx.key,
|
|
9373
|
-
|
|
9374
|
-
target: getLinkHref2(hrefCtx.anchor)
|
|
8034
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
9375
8035
|
});
|
|
9376
8036
|
deactivate();
|
|
9377
8037
|
}, [deactivate]);
|
|
9378
|
-
const openLinkPopoverForSelected = (0,
|
|
8038
|
+
const openLinkPopoverForSelected = (0, import_react6.useCallback)(() => {
|
|
9379
8039
|
const anchor = selectedElRef.current;
|
|
9380
8040
|
if (!anchor) return;
|
|
9381
8041
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -9383,156 +8043,51 @@ function OhhwellsBridge() {
|
|
|
9383
8043
|
bumpLinkPopoverGrace();
|
|
9384
8044
|
setLinkPopover({
|
|
9385
8045
|
key,
|
|
9386
|
-
|
|
9387
|
-
target: getLinkHref2(anchor)
|
|
8046
|
+
target: getLinkHref(anchor)
|
|
9388
8047
|
});
|
|
9389
8048
|
deselect();
|
|
9390
8049
|
}, [deselect]);
|
|
9391
|
-
const handleLinkPopoverSubmit = (0,
|
|
8050
|
+
const handleLinkPopoverSubmit = (0, import_react6.useCallback)(
|
|
9392
8051
|
(target) => {
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
if (session.intent === "add-nav") {
|
|
9396
|
-
const { pageRoute, sectionId } = parseTarget(target);
|
|
9397
|
-
const page = resolvePage(pageRoute, sitePages);
|
|
9398
|
-
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
9399
|
-
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
9400
|
-
const label = section?.label ?? page.title;
|
|
9401
|
-
const afterAnchor = addNavAfterAnchorRef.current;
|
|
9402
|
-
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(target, label, afterAnchor);
|
|
9403
|
-
applyLinkByKey(hrefKey, target);
|
|
9404
|
-
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
9405
|
-
el.textContent = label;
|
|
9406
|
-
});
|
|
9407
|
-
const navCount = String(index + 1);
|
|
9408
|
-
const orderJson = JSON.stringify(order);
|
|
9409
|
-
editContentRef.current = {
|
|
9410
|
-
...editContentRef.current,
|
|
9411
|
-
[hrefKey]: target,
|
|
9412
|
-
[labelKey]: label,
|
|
9413
|
-
[NAV_COUNT_KEY]: navCount,
|
|
9414
|
-
[NAV_ORDER_KEY]: orderJson
|
|
9415
|
-
};
|
|
9416
|
-
postToParent2({
|
|
9417
|
-
type: "ow:change",
|
|
9418
|
-
nodes: [
|
|
9419
|
-
{ key: hrefKey, text: target },
|
|
9420
|
-
{ key: labelKey, text: label },
|
|
9421
|
-
{ key: NAV_COUNT_KEY, text: navCount },
|
|
9422
|
-
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
9423
|
-
]
|
|
9424
|
-
});
|
|
9425
|
-
addNavAfterAnchorRef.current = null;
|
|
9426
|
-
setLinkPopover(null);
|
|
9427
|
-
enforceLinkHrefs();
|
|
9428
|
-
requestAnimationFrame(() => {
|
|
9429
|
-
selectRef.current(anchor);
|
|
9430
|
-
});
|
|
9431
|
-
return;
|
|
9432
|
-
}
|
|
9433
|
-
const { key } = session;
|
|
8052
|
+
if (!linkPopover) return;
|
|
8053
|
+
const { key } = linkPopover;
|
|
9434
8054
|
applyLinkByKey(key, target);
|
|
9435
|
-
|
|
8055
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
9436
8056
|
setLinkPopover(null);
|
|
9437
8057
|
},
|
|
9438
|
-
[
|
|
8058
|
+
[linkPopover, postToParent]
|
|
9439
8059
|
);
|
|
9440
8060
|
const showEditLink = toolbarShowEditLink;
|
|
9441
8061
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
9442
8062
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9443
|
-
|
|
9444
|
-
(
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
const handleVideoSettingsChange = (0, import_react8.useCallback)(
|
|
9450
|
-
(key, settings) => {
|
|
9451
|
-
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9452
|
-
const video = getVideoEl(el);
|
|
9453
|
-
if (!video) return;
|
|
9454
|
-
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
9455
|
-
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
9456
|
-
syncVideoPlayback(video);
|
|
9457
|
-
postToParent2({
|
|
9458
|
-
type: "ow:change",
|
|
9459
|
-
nodes: [
|
|
9460
|
-
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
9461
|
-
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
9462
|
-
]
|
|
9463
|
-
});
|
|
9464
|
-
setMediaHover(
|
|
9465
|
-
(prev) => prev && prev.key === key ? { ...prev, videoAutoplay: video.autoplay, videoMuted: video.muted } : prev
|
|
9466
|
-
);
|
|
9467
|
-
});
|
|
9468
|
-
},
|
|
9469
|
-
[postToParent2]
|
|
9470
|
-
);
|
|
9471
|
-
const handleMediaFadeOutComplete = (0, import_react8.useCallback)((key) => {
|
|
9472
|
-
setUploadingRects((prev) => {
|
|
9473
|
-
if (!(key in prev)) return prev;
|
|
9474
|
-
const next = { ...prev };
|
|
9475
|
-
delete next[key];
|
|
9476
|
-
return next;
|
|
9477
|
-
});
|
|
9478
|
-
}, []);
|
|
9479
|
-
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
9480
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9481
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9482
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9483
|
-
MediaOverlay,
|
|
9484
|
-
{
|
|
9485
|
-
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
9486
|
-
isUploading: true,
|
|
9487
|
-
fadingOut,
|
|
9488
|
-
onFadeOutComplete: handleMediaFadeOutComplete,
|
|
9489
|
-
onReplace: handleMediaReplace
|
|
9490
|
-
},
|
|
9491
|
-
`uploading-${key}`
|
|
9492
|
-
)),
|
|
9493
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9494
|
-
MediaOverlay,
|
|
9495
|
-
{
|
|
9496
|
-
hover: mediaHover,
|
|
9497
|
-
isUploading: false,
|
|
9498
|
-
onReplace: handleMediaReplace,
|
|
9499
|
-
onVideoSettingsChange: handleVideoSettingsChange
|
|
9500
|
-
}
|
|
9501
|
-
),
|
|
9502
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9503
|
-
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9504
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9505
|
-
NavbarContainerChrome,
|
|
9506
|
-
{
|
|
9507
|
-
rect: toolbarRect,
|
|
9508
|
-
onAdd: handleAddTopLevelNavItem
|
|
9509
|
-
}
|
|
9510
|
-
),
|
|
9511
|
-
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9512
|
-
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8063
|
+
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
8064
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
8065
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8066
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8067
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8068
|
+
toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9513
8069
|
ItemInteractionLayer,
|
|
9514
8070
|
{
|
|
9515
8071
|
rect: toolbarRect,
|
|
9516
8072
|
elRef: glowElRef,
|
|
9517
8073
|
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
9518
|
-
showHandle:
|
|
8074
|
+
showHandle: Boolean(reorderHrefKey),
|
|
9519
8075
|
dragDisabled: reorderDragDisabled,
|
|
9520
8076
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
9521
8077
|
onDragHandleDragStart: handleItemDragStart,
|
|
9522
8078
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
9523
|
-
toolbar:
|
|
8079
|
+
toolbar: isItemDragging ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9524
8080
|
ItemActionToolbar,
|
|
9525
8081
|
{
|
|
9526
8082
|
onEditLink: openLinkPopoverForSelected,
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
moreDisabled: true
|
|
8083
|
+
onAddItem: handleAddNavigationItem,
|
|
8084
|
+
addItemDisabled: false
|
|
9530
8085
|
}
|
|
9531
|
-
)
|
|
8086
|
+
)
|
|
9532
8087
|
}
|
|
9533
8088
|
),
|
|
9534
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0,
|
|
9535
|
-
/* @__PURE__ */ (0,
|
|
8089
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
8090
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9536
8091
|
EditGlowChrome,
|
|
9537
8092
|
{
|
|
9538
8093
|
rect: toolbarRect,
|
|
@@ -9541,7 +8096,7 @@ function OhhwellsBridge() {
|
|
|
9541
8096
|
dragDisabled: reorderDragDisabled
|
|
9542
8097
|
}
|
|
9543
8098
|
),
|
|
9544
|
-
/* @__PURE__ */ (0,
|
|
8099
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9545
8100
|
FloatingToolbar,
|
|
9546
8101
|
{
|
|
9547
8102
|
rect: toolbarRect,
|
|
@@ -9554,7 +8109,7 @@ function OhhwellsBridge() {
|
|
|
9554
8109
|
}
|
|
9555
8110
|
)
|
|
9556
8111
|
] }),
|
|
9557
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
8112
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
9558
8113
|
"div",
|
|
9559
8114
|
{
|
|
9560
8115
|
"data-ohw-max-badge": "",
|
|
@@ -9580,7 +8135,7 @@ function OhhwellsBridge() {
|
|
|
9580
8135
|
]
|
|
9581
8136
|
}
|
|
9582
8137
|
),
|
|
9583
|
-
toggleState &&
|
|
8138
|
+
toggleState && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9584
8139
|
StateToggle,
|
|
9585
8140
|
{
|
|
9586
8141
|
rect: toggleState.rect,
|
|
@@ -9589,15 +8144,15 @@ function OhhwellsBridge() {
|
|
|
9589
8144
|
onStateChange: handleStateChange
|
|
9590
8145
|
}
|
|
9591
8146
|
),
|
|
9592
|
-
sectionGap &&
|
|
8147
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
9593
8148
|
"div",
|
|
9594
8149
|
{
|
|
9595
8150
|
"data-ohw-section-insert-line": "",
|
|
9596
8151
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9597
8152
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9598
8153
|
children: [
|
|
9599
|
-
/* @__PURE__ */ (0,
|
|
9600
|
-
/* @__PURE__ */ (0,
|
|
8154
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8155
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9601
8156
|
Badge,
|
|
9602
8157
|
{
|
|
9603
8158
|
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",
|
|
@@ -9610,52 +8165,26 @@ function OhhwellsBridge() {
|
|
|
9610
8165
|
children: "Add Section"
|
|
9611
8166
|
}
|
|
9612
8167
|
),
|
|
9613
|
-
/* @__PURE__ */ (0,
|
|
8168
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
9614
8169
|
]
|
|
9615
8170
|
}
|
|
9616
8171
|
),
|
|
9617
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
8172
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
9618
8173
|
LinkPopover,
|
|
9619
8174
|
{
|
|
9620
8175
|
panelRef: linkPopoverPanelRef,
|
|
9621
8176
|
portalContainer: dialogPortalContainer,
|
|
9622
8177
|
open: true,
|
|
9623
|
-
mode:
|
|
8178
|
+
mode: "edit",
|
|
9624
8179
|
pages: sitePages,
|
|
9625
8180
|
sections: currentSections,
|
|
9626
8181
|
sectionsByPath,
|
|
9627
8182
|
initialTarget: linkPopover.target,
|
|
9628
|
-
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
9629
8183
|
onClose: closeLinkPopover,
|
|
9630
8184
|
onSubmit: handleLinkPopoverSubmit
|
|
9631
8185
|
},
|
|
9632
|
-
linkPopover.key
|
|
9633
|
-
) : null
|
|
9634
|
-
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
9635
|
-
"div",
|
|
9636
|
-
{
|
|
9637
|
-
"data-ohw-section-insert-line": "",
|
|
9638
|
-
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9639
|
-
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9640
|
-
children: [
|
|
9641
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9642
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9643
|
-
Badge,
|
|
9644
|
-
{
|
|
9645
|
-
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",
|
|
9646
|
-
onClick: () => {
|
|
9647
|
-
window.parent.postMessage(
|
|
9648
|
-
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
9649
|
-
"*"
|
|
9650
|
-
);
|
|
9651
|
-
},
|
|
9652
|
-
children: "Add Section"
|
|
9653
|
-
}
|
|
9654
|
-
),
|
|
9655
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
9656
|
-
]
|
|
9657
|
-
}
|
|
9658
|
-
)
|
|
8186
|
+
`${linkPopover.key}-${pathname}`
|
|
8187
|
+
) : null
|
|
9659
8188
|
] }),
|
|
9660
8189
|
bridgeRoot
|
|
9661
8190
|
) : null;
|