@ohhwells/bridge 0.1.36-next.49 → 0.1.36-next.51
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/dist/index.cjs +1767 -670
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -3
- package/dist/index.d.ts +50 -3
- package/dist/index.js +1765 -668
- package/dist/index.js.map +1 -1
- package/dist/styles.css +156 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,15 +60,18 @@ __export(index_exports, {
|
|
|
60
60
|
module.exports = __toCommonJS(index_exports);
|
|
61
61
|
|
|
62
62
|
// src/OhhwellsBridge.tsx
|
|
63
|
-
var
|
|
63
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
64
64
|
var import_client = require("react-dom/client");
|
|
65
|
-
var
|
|
65
|
+
var import_react_dom2 = 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
|
+
}
|
|
72
75
|
function enforceLinkHrefs() {
|
|
73
76
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
74
77
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -4456,6 +4459,7 @@ function ItemActionToolbar({
|
|
|
4456
4459
|
onEditLink,
|
|
4457
4460
|
onAddItem,
|
|
4458
4461
|
onMore,
|
|
4462
|
+
editLinkDisabled = false,
|
|
4459
4463
|
addItemDisabled = true,
|
|
4460
4464
|
moreDisabled = true,
|
|
4461
4465
|
tooltipSide = "bottom"
|
|
@@ -4466,8 +4470,10 @@ function ItemActionToolbar({
|
|
|
4466
4470
|
{
|
|
4467
4471
|
label: "Edit link",
|
|
4468
4472
|
side: tooltipSide,
|
|
4473
|
+
disabled: editLinkDisabled,
|
|
4469
4474
|
buttonProps: {
|
|
4470
4475
|
onMouseDown: (e) => {
|
|
4476
|
+
if (editLinkDisabled) return;
|
|
4471
4477
|
e.preventDefault();
|
|
4472
4478
|
e.stopPropagation();
|
|
4473
4479
|
onEditLink?.();
|
|
@@ -4639,9 +4645,223 @@ function ItemInteractionLayer({
|
|
|
4639
4645
|
);
|
|
4640
4646
|
}
|
|
4641
4647
|
|
|
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
|
+
|
|
4642
4862
|
// src/OhhwellsBridge.tsx
|
|
4643
|
-
var
|
|
4644
|
-
var
|
|
4863
|
+
var import_react_dom3 = require("react-dom");
|
|
4864
|
+
var import_navigation2 = require("next/navigation");
|
|
4645
4865
|
|
|
4646
4866
|
// src/lib/session-search.ts
|
|
4647
4867
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -4917,62 +5137,30 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
4917
5137
|
tick();
|
|
4918
5138
|
}
|
|
4919
5139
|
|
|
4920
|
-
// src/ui/
|
|
4921
|
-
var
|
|
4922
|
-
var import_radix_ui4 = require("radix-ui");
|
|
4923
|
-
|
|
4924
|
-
// src/ui/icons.tsx
|
|
4925
|
-
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4926
|
-
function IconX({ className, ...props }) {
|
|
4927
|
-
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: [
|
|
4928
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M18 6 6 18" }),
|
|
4929
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 6 12 12" })
|
|
4930
|
-
] });
|
|
4931
|
-
}
|
|
4932
|
-
function IconChevronDown({ className, ...props }) {
|
|
4933
|
-
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" }) });
|
|
4934
|
-
}
|
|
4935
|
-
function IconFile({ className, ...props }) {
|
|
4936
|
-
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: [
|
|
4937
|
-
/* @__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" }),
|
|
4938
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4939
|
-
] });
|
|
4940
|
-
}
|
|
4941
|
-
function IconInfo({ className, ...props }) {
|
|
4942
|
-
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: [
|
|
4943
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4944
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 16v-4" }),
|
|
4945
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 8h.01" })
|
|
4946
|
-
] });
|
|
4947
|
-
}
|
|
4948
|
-
function IconArrowRight({ className, ...props }) {
|
|
4949
|
-
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: [
|
|
4950
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M5 12h14" }),
|
|
4951
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
4952
|
-
] });
|
|
4953
|
-
}
|
|
4954
|
-
function IconSection({ className, ...props }) {
|
|
4955
|
-
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: [
|
|
4956
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4957
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4958
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4959
|
-
] });
|
|
4960
|
-
}
|
|
5140
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5141
|
+
var import_react7 = require("react");
|
|
4961
5142
|
|
|
4962
5143
|
// src/ui/dialog.tsx
|
|
4963
|
-
var
|
|
4964
|
-
|
|
4965
|
-
|
|
5144
|
+
var React7 = __toESM(require("react"), 1);
|
|
5145
|
+
var import_radix_ui5 = require("radix-ui");
|
|
5146
|
+
var import_lucide_react4 = require("lucide-react");
|
|
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 });
|
|
4966
5152
|
}
|
|
4967
|
-
function DialogPortal({
|
|
4968
|
-
|
|
5153
|
+
function DialogPortal({
|
|
5154
|
+
...props
|
|
5155
|
+
}) {
|
|
5156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
|
|
4969
5157
|
}
|
|
4970
5158
|
function DialogOverlay({
|
|
4971
5159
|
className,
|
|
4972
5160
|
...props
|
|
4973
5161
|
}) {
|
|
4974
|
-
return /* @__PURE__ */ (0,
|
|
4975
|
-
|
|
5162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5163
|
+
import_radix_ui5.Dialog.Overlay,
|
|
4976
5164
|
{
|
|
4977
5165
|
"data-slot": "dialog-overlay",
|
|
4978
5166
|
"data-ohw-link-modal-root": "",
|
|
@@ -4981,120 +5169,118 @@ function DialogOverlay({
|
|
|
4981
5169
|
}
|
|
4982
5170
|
);
|
|
4983
5171
|
}
|
|
4984
|
-
var DialogContent =
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
/* @__PURE__ */ (0,
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
children
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
});
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5172
|
+
var DialogContent = React7.forwardRef(
|
|
5173
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5174
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
5176
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
5178
|
+
import_radix_ui5.Dialog.Content,
|
|
5179
|
+
{
|
|
5180
|
+
ref,
|
|
5181
|
+
"data-slot": "dialog-content",
|
|
5182
|
+
className: cn(
|
|
5183
|
+
positionMode,
|
|
5184
|
+
"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-visible",
|
|
5185
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5186
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
5187
|
+
className
|
|
5188
|
+
),
|
|
5189
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5190
|
+
...props,
|
|
5191
|
+
children: [
|
|
5192
|
+
children,
|
|
5193
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5194
|
+
import_radix_ui5.Dialog.Close,
|
|
5195
|
+
{
|
|
5196
|
+
type: "button",
|
|
5197
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5198
|
+
"aria-label": "Close",
|
|
5199
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.X, { size: 16, "aria-hidden": true })
|
|
5200
|
+
}
|
|
5201
|
+
) : null
|
|
5202
|
+
]
|
|
5203
|
+
}
|
|
5204
|
+
)
|
|
5205
|
+
] });
|
|
5206
|
+
}
|
|
5207
|
+
);
|
|
5208
|
+
DialogContent.displayName = import_radix_ui5.Dialog.Content.displayName;
|
|
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 });
|
|
5021
5214
|
}
|
|
5022
|
-
function DialogFooter({
|
|
5023
|
-
|
|
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
|
+
);
|
|
5024
5226
|
}
|
|
5025
|
-
var DialogTitle =
|
|
5026
|
-
|
|
5227
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5228
|
+
import_radix_ui5.Dialog.Title,
|
|
5027
5229
|
{
|
|
5028
5230
|
ref,
|
|
5029
|
-
className: cn(
|
|
5231
|
+
className: cn(
|
|
5232
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5233
|
+
className
|
|
5234
|
+
),
|
|
5030
5235
|
...props
|
|
5031
5236
|
}
|
|
5032
5237
|
));
|
|
5033
|
-
DialogTitle.displayName =
|
|
5034
|
-
var DialogDescription =
|
|
5035
|
-
|
|
5238
|
+
DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
|
|
5239
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5240
|
+
import_radix_ui5.Dialog.Description,
|
|
5036
5241
|
{
|
|
5037
5242
|
ref,
|
|
5038
5243
|
className: cn("text-sm text-muted-foreground", className),
|
|
5039
5244
|
...props
|
|
5040
5245
|
}
|
|
5041
5246
|
));
|
|
5042
|
-
DialogDescription.displayName =
|
|
5043
|
-
var DialogClose =
|
|
5247
|
+
DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
|
|
5248
|
+
var DialogClose = import_radix_ui5.Dialog.Close;
|
|
5044
5249
|
|
|
5045
|
-
// src/ui/
|
|
5046
|
-
var
|
|
5047
|
-
var import_radix_ui5 = require("radix-ui");
|
|
5048
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5049
|
-
var buttonVariants = cva(
|
|
5050
|
-
"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",
|
|
5051
|
-
{
|
|
5052
|
-
variants: {
|
|
5053
|
-
variant: {
|
|
5054
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
5055
|
-
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
5056
|
-
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
5057
|
-
},
|
|
5058
|
-
size: {
|
|
5059
|
-
default: "h-9",
|
|
5060
|
-
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
5061
|
-
}
|
|
5062
|
-
},
|
|
5063
|
-
defaultVariants: {
|
|
5064
|
-
variant: "default",
|
|
5065
|
-
size: "default"
|
|
5066
|
-
}
|
|
5067
|
-
}
|
|
5068
|
-
);
|
|
5069
|
-
var Button = React6.forwardRef(
|
|
5070
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
5071
|
-
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
5072
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5073
|
-
Comp,
|
|
5074
|
-
{
|
|
5075
|
-
ref,
|
|
5076
|
-
"data-slot": "button",
|
|
5077
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
5078
|
-
...props
|
|
5079
|
-
}
|
|
5080
|
-
);
|
|
5081
|
-
}
|
|
5082
|
-
);
|
|
5083
|
-
Button.displayName = "Button";
|
|
5250
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5251
|
+
var import_lucide_react8 = require("lucide-react");
|
|
5084
5252
|
|
|
5085
5253
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5254
|
+
var import_lucide_react5 = require("lucide-react");
|
|
5086
5255
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
5087
|
-
function DestinationBreadcrumb({
|
|
5256
|
+
function DestinationBreadcrumb({
|
|
5257
|
+
pageTitle,
|
|
5258
|
+
sectionLabel
|
|
5259
|
+
}) {
|
|
5088
5260
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5089
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5090
5262
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5091
5263
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5092
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5093
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5265
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5094
5266
|
] }),
|
|
5095
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
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
|
+
),
|
|
5096
5275
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5097
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
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
|
+
),
|
|
5098
5284
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5099
5285
|
] })
|
|
5100
5286
|
] })
|
|
@@ -5102,8 +5288,13 @@ function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
|
5102
5288
|
}
|
|
5103
5289
|
|
|
5104
5290
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5291
|
+
var import_lucide_react6 = require("lucide-react");
|
|
5105
5292
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5106
|
-
function SectionTreeItem({
|
|
5293
|
+
function SectionTreeItem({
|
|
5294
|
+
section,
|
|
5295
|
+
onSelect,
|
|
5296
|
+
selected
|
|
5297
|
+
}) {
|
|
5107
5298
|
const interactive = Boolean(onSelect);
|
|
5108
5299
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5109
5300
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
@@ -5131,30 +5322,28 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
5131
5322
|
interactive && selected && "border-primary"
|
|
5132
5323
|
),
|
|
5133
5324
|
children: [
|
|
5134
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
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
|
+
),
|
|
5135
5333
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5136
5334
|
]
|
|
5137
5335
|
}
|
|
5138
5336
|
)
|
|
5139
5337
|
] });
|
|
5140
5338
|
}
|
|
5141
|
-
function SectionPickerList({ sections, onSelect }) {
|
|
5142
|
-
if (sections.length === 0) {
|
|
5143
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5144
|
-
}
|
|
5145
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5146
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5147
|
-
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
5148
|
-
] });
|
|
5149
|
-
}
|
|
5150
5339
|
|
|
5151
5340
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5152
5341
|
var import_react4 = require("react");
|
|
5153
5342
|
|
|
5154
5343
|
// src/ui/input.tsx
|
|
5155
|
-
var
|
|
5344
|
+
var React8 = __toESM(require("react"), 1);
|
|
5156
5345
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5157
|
-
var Input =
|
|
5346
|
+
var Input = React8.forwardRef(
|
|
5158
5347
|
({ className, type, ...props }, ref) => {
|
|
5159
5348
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5160
5349
|
"input",
|
|
@@ -5188,8 +5377,11 @@ function Label({ className, ...props }) {
|
|
|
5188
5377
|
}
|
|
5189
5378
|
|
|
5190
5379
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5380
|
+
var import_lucide_react7 = require("lucide-react");
|
|
5191
5381
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5192
|
-
function FieldChevron({
|
|
5382
|
+
function FieldChevron({
|
|
5383
|
+
onClick
|
|
5384
|
+
}) {
|
|
5193
5385
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5194
5386
|
"button",
|
|
5195
5387
|
{
|
|
@@ -5198,7 +5390,7 @@ function FieldChevron({ onClick }) {
|
|
|
5198
5390
|
onClick,
|
|
5199
5391
|
"aria-label": "Open page list",
|
|
5200
5392
|
tabIndex: -1,
|
|
5201
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5393
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.ChevronDown, { size: 16 })
|
|
5202
5394
|
}
|
|
5203
5395
|
);
|
|
5204
5396
|
}
|
|
@@ -5216,7 +5408,29 @@ function UrlOrPageInput({
|
|
|
5216
5408
|
}) {
|
|
5217
5409
|
const inputId = (0, import_react4.useId)();
|
|
5218
5410
|
const inputRef = (0, import_react4.useRef)(null);
|
|
5411
|
+
const rootRef = (0, import_react4.useRef)(null);
|
|
5219
5412
|
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]);
|
|
5220
5434
|
const openDropdown = () => {
|
|
5221
5435
|
if (readOnly || filteredPages.length === 0) return;
|
|
5222
5436
|
onDropdownOpenChange(true);
|
|
@@ -5239,9 +5453,16 @@ function UrlOrPageInput({
|
|
|
5239
5453
|
);
|
|
5240
5454
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5241
5455
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5242
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative w-full", children: [
|
|
5456
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5243
5457
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5244
|
-
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
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,
|
|
5245
5466
|
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)(
|
|
5246
5467
|
Input,
|
|
5247
5468
|
{
|
|
@@ -5253,7 +5474,14 @@ function UrlOrPageInput({
|
|
|
5253
5474
|
setIsFocused(true);
|
|
5254
5475
|
if (!selectedPage) openDropdown();
|
|
5255
5476
|
},
|
|
5256
|
-
onBlur: () =>
|
|
5477
|
+
onBlur: () => {
|
|
5478
|
+
setIsFocused(false);
|
|
5479
|
+
requestAnimationFrame(() => {
|
|
5480
|
+
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5481
|
+
onDropdownOpenChange(false);
|
|
5482
|
+
}
|
|
5483
|
+
});
|
|
5484
|
+
},
|
|
5257
5485
|
placeholder,
|
|
5258
5486
|
className: cn(
|
|
5259
5487
|
"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",
|
|
@@ -5269,7 +5497,7 @@ function UrlOrPageInput({
|
|
|
5269
5497
|
onMouseDown: clearSelection,
|
|
5270
5498
|
"aria-label": "Clear selected page",
|
|
5271
5499
|
tabIndex: -1,
|
|
5272
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5500
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.X, { size: 16, "aria-hidden": true })
|
|
5273
5501
|
}
|
|
5274
5502
|
) : null,
|
|
5275
5503
|
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
@@ -5278,7 +5506,7 @@ function UrlOrPageInput({
|
|
|
5278
5506
|
"div",
|
|
5279
5507
|
{
|
|
5280
5508
|
"data-ohw-link-page-dropdown": "",
|
|
5281
|
-
className: "absolute left-0 right-0
|
|
5509
|
+
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5282
5510
|
onMouseDown: (e) => e.preventDefault(),
|
|
5283
5511
|
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5284
5512
|
"button",
|
|
@@ -5287,7 +5515,7 @@ function UrlOrPageInput({
|
|
|
5287
5515
|
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",
|
|
5288
5516
|
onClick: () => onPageSelect(page),
|
|
5289
5517
|
children: [
|
|
5290
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5518
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5291
5519
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: page.title })
|
|
5292
5520
|
]
|
|
5293
5521
|
},
|
|
@@ -5300,58 +5528,395 @@ function UrlOrPageInput({
|
|
|
5300
5528
|
] });
|
|
5301
5529
|
}
|
|
5302
5530
|
|
|
5303
|
-
// src/ui/link-modal/
|
|
5304
|
-
var
|
|
5305
|
-
function
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
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
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5872
|
+
var import_react6 = require("react");
|
|
5873
|
+
function useLinkModalState({
|
|
5874
|
+
open,
|
|
5875
|
+
mode,
|
|
5876
|
+
pages,
|
|
5877
|
+
sections: _sections,
|
|
5878
|
+
sectionsByPath,
|
|
5879
|
+
initialTarget,
|
|
5880
|
+
existingTargets: _existingTargets,
|
|
5881
|
+
onClose,
|
|
5882
|
+
onSubmit
|
|
5883
|
+
}) {
|
|
5884
|
+
const availablePages = (0, import_react6.useMemo)(() => pages, [pages]);
|
|
5885
|
+
const [searchValue, setSearchValue] = (0, import_react6.useState)("");
|
|
5886
|
+
const [selectedPage, setSelectedPage] = (0, import_react6.useState)(null);
|
|
5887
|
+
const [selectedSection, setSelectedSection] = (0, import_react6.useState)(null);
|
|
5888
|
+
const [step, setStep] = (0, import_react6.useState)("input");
|
|
5889
|
+
const [dropdownOpen, setDropdownOpen] = (0, import_react6.useState)(false);
|
|
5890
|
+
const [urlError, setUrlError] = (0, import_react6.useState)("");
|
|
5891
|
+
const reset = (0, import_react6.useCallback)(() => {
|
|
5892
|
+
setSearchValue("");
|
|
5893
|
+
setSelectedPage(null);
|
|
5894
|
+
setSelectedSection(null);
|
|
5895
|
+
setStep("input");
|
|
5896
|
+
setDropdownOpen(false);
|
|
5897
|
+
setUrlError("");
|
|
5898
|
+
}, []);
|
|
5899
|
+
(0, import_react6.useEffect)(() => {
|
|
5900
|
+
if (!open) return;
|
|
5901
|
+
if (mode === "edit" && initialTarget) {
|
|
5902
|
+
const { pageRoute } = parseTarget(initialTarget);
|
|
5903
|
+
const targetSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
5904
|
+
const init = getEditModeInitialState(initialTarget, pages, targetSections);
|
|
5905
|
+
setSearchValue(init.searchValue);
|
|
5906
|
+
setSelectedPage(init.selectedPage);
|
|
5907
|
+
setSelectedSection(init.selectedSection);
|
|
5908
|
+
setStep(init.step);
|
|
5909
|
+
} else {
|
|
5910
|
+
reset();
|
|
5911
|
+
}
|
|
5912
|
+
setDropdownOpen(false);
|
|
5913
|
+
setUrlError("");
|
|
5914
|
+
}, [open, mode, initialTarget, reset]);
|
|
5915
|
+
const filteredPages = (0, import_react6.useMemo)(() => {
|
|
5916
|
+
if (!searchValue.trim()) return availablePages;
|
|
5352
5917
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
5353
5918
|
}, [availablePages, searchValue]);
|
|
5354
|
-
const activeSections = (0,
|
|
5919
|
+
const activeSections = (0, import_react6.useMemo)(() => {
|
|
5355
5920
|
if (!selectedPage) return [];
|
|
5356
5921
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
5357
5922
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -5393,11 +5958,14 @@ function useLinkModalState({
|
|
|
5393
5958
|
const handleBackToSections = () => {
|
|
5394
5959
|
setStep("sectionPicker");
|
|
5395
5960
|
};
|
|
5961
|
+
const handleSectionPickerBack = () => {
|
|
5962
|
+
setStep("input");
|
|
5963
|
+
};
|
|
5396
5964
|
const handleClose = () => {
|
|
5397
5965
|
reset();
|
|
5398
5966
|
onClose();
|
|
5399
5967
|
};
|
|
5400
|
-
const isValid = (0,
|
|
5968
|
+
const isValid = (0, import_react6.useMemo)(() => {
|
|
5401
5969
|
if (urlError) return false;
|
|
5402
5970
|
if (showBreadcrumb) return true;
|
|
5403
5971
|
if (selectedPage) return true;
|
|
@@ -5430,7 +5998,7 @@ function useLinkModalState({
|
|
|
5430
5998
|
onSubmit(normalizeUrl(searchValue));
|
|
5431
5999
|
handleClose();
|
|
5432
6000
|
};
|
|
5433
|
-
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
6001
|
+
const submitLabel = showBreadcrumb ? "Save" : mode === "edit" ? "Save" : "Create";
|
|
5434
6002
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
5435
6003
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
5436
6004
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -5457,23 +6025,29 @@ function useLinkModalState({
|
|
|
5457
6025
|
handleChooseSection,
|
|
5458
6026
|
handleSectionSelect,
|
|
5459
6027
|
handleBackToSections,
|
|
6028
|
+
handleSectionPickerBack,
|
|
5460
6029
|
handleClose,
|
|
5461
6030
|
handleSecondary,
|
|
5462
6031
|
handleSubmit
|
|
5463
6032
|
};
|
|
5464
6033
|
}
|
|
5465
6034
|
|
|
5466
|
-
// src/ui/link-modal/
|
|
5467
|
-
var
|
|
5468
|
-
function
|
|
6035
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
6036
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
6037
|
+
function postToParent(data) {
|
|
6038
|
+
window.parent?.postMessage(data, "*");
|
|
6039
|
+
}
|
|
6040
|
+
function LinkPopover({
|
|
5469
6041
|
open = true,
|
|
6042
|
+
panelRef,
|
|
6043
|
+
portalContainer,
|
|
6044
|
+
onClose,
|
|
5470
6045
|
mode = "create",
|
|
5471
6046
|
pages,
|
|
5472
6047
|
sections = [],
|
|
5473
6048
|
sectionsByPath,
|
|
5474
6049
|
initialTarget,
|
|
5475
6050
|
existingTargets = [],
|
|
5476
|
-
onClose,
|
|
5477
6051
|
onSubmit
|
|
5478
6052
|
}) {
|
|
5479
6053
|
const state = useLinkModalState({
|
|
@@ -5487,175 +6061,440 @@ function LinkEditorPanel({
|
|
|
5487
6061
|
onClose,
|
|
5488
6062
|
onSubmit
|
|
5489
6063
|
});
|
|
5490
|
-
const
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
6064
|
+
const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
|
|
6065
|
+
(0, import_react7.useEffect)(() => {
|
|
6066
|
+
if (!open) return;
|
|
6067
|
+
if (sectionPickerActive) {
|
|
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,
|
|
5494
6126
|
{
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
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
|
+
)
|
|
5499
6144
|
}
|
|
5500
|
-
)
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
UrlOrPageInput,
|
|
5511
|
-
{
|
|
5512
|
-
value: state.searchValue,
|
|
5513
|
-
selectedPage: state.selectedPage,
|
|
5514
|
-
dropdownOpen: state.dropdownOpen,
|
|
5515
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5516
|
-
filteredPages: state.filteredPages,
|
|
5517
|
-
onInputChange: state.handleInputChange,
|
|
5518
|
-
onPageSelect: state.handlePageSelect,
|
|
5519
|
-
urlError: state.urlError
|
|
5520
|
-
}
|
|
5521
|
-
),
|
|
5522
|
-
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5523
|
-
/* @__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" }),
|
|
5524
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5525
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5526
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5527
|
-
] })
|
|
5528
|
-
] }) : null,
|
|
5529
|
-
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5530
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5531
|
-
] }),
|
|
5532
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5533
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5534
|
-
Button,
|
|
5535
|
-
{
|
|
5536
|
-
type: "button",
|
|
5537
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5538
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5539
|
-
style: isCancel ? {
|
|
5540
|
-
backgroundColor: "var(--ohw-background)",
|
|
5541
|
-
borderColor: "var(--ohw-border)",
|
|
5542
|
-
color: "var(--ohw-foreground)"
|
|
5543
|
-
} : void 0,
|
|
5544
|
-
onClick: state.handleSecondary,
|
|
5545
|
-
children: state.secondaryLabel
|
|
5546
|
-
}
|
|
5547
|
-
),
|
|
5548
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5549
|
-
Button,
|
|
5550
|
-
{
|
|
5551
|
-
type: "button",
|
|
5552
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5553
|
-
style: {
|
|
5554
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5555
|
-
color: "var(--ohw-primary-foreground)"
|
|
5556
|
-
},
|
|
5557
|
-
disabled: !state.isValid,
|
|
5558
|
-
onClick: state.handleSubmit,
|
|
5559
|
-
children: state.submitLabel
|
|
5560
|
-
}
|
|
5561
|
-
)
|
|
5562
|
-
] })
|
|
6145
|
+
),
|
|
6146
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6147
|
+
SectionPickerOverlay,
|
|
6148
|
+
{
|
|
6149
|
+
pagePath: state.selectedPage.path,
|
|
6150
|
+
sections: state.activeSections,
|
|
6151
|
+
onBack: state.handleSectionPickerBack,
|
|
6152
|
+
onSelect: state.handleSectionSelect
|
|
6153
|
+
}
|
|
6154
|
+
) : null
|
|
5563
6155
|
] });
|
|
5564
6156
|
}
|
|
5565
6157
|
|
|
5566
|
-
// src/ui/link-modal/
|
|
5567
|
-
var
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
6158
|
+
// src/ui/link-modal/devFixtures.ts
|
|
6159
|
+
var DEV_SITE_PAGES = [
|
|
6160
|
+
{ path: "/", title: "Home" },
|
|
6161
|
+
{ path: "/about", title: "About" },
|
|
6162
|
+
{ path: "/classes", title: "Classes" },
|
|
6163
|
+
{ path: "/pricing", title: "Pricing" },
|
|
6164
|
+
{ path: "/studio", title: "Studio" },
|
|
6165
|
+
{ path: "/instructors", title: "Instructors" },
|
|
6166
|
+
{ path: "/contact", title: "Contact" }
|
|
6167
|
+
];
|
|
6168
|
+
var DEV_SECTIONS_BY_PATH = {
|
|
6169
|
+
"/": [
|
|
6170
|
+
{ id: "hero", label: "Hero" },
|
|
6171
|
+
{ id: "lagree-intro", label: "Lagree Intro" },
|
|
6172
|
+
{ id: "classes-strip", label: "Classes" },
|
|
6173
|
+
{ id: "feel-split", label: "Feel Split" },
|
|
6174
|
+
{ id: "founder-teaser", label: "Founder" },
|
|
6175
|
+
{ id: "plan-form", label: "Plan Form" },
|
|
6176
|
+
{ id: "testimonials", label: "Testimonials" },
|
|
6177
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6178
|
+
{ id: "footer", label: "Footer" }
|
|
6179
|
+
],
|
|
6180
|
+
"/about": [
|
|
6181
|
+
{ id: "manifesto", label: "Manifesto" },
|
|
6182
|
+
{ id: "story-letter", label: "Our Story" },
|
|
6183
|
+
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
6184
|
+
{ 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" }
|
|
6191
|
+
],
|
|
6192
|
+
"/pricing": [
|
|
6193
|
+
{ id: "page-header", label: "Page Header" },
|
|
6194
|
+
{ id: "free-class-cta", label: "Free Class" },
|
|
6195
|
+
{ id: "benefits-marquee", label: "Benefits" },
|
|
6196
|
+
{ id: "monthly-memberships", label: "Memberships" },
|
|
6197
|
+
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
6198
|
+
{ id: "package-matcher", label: "Packages" },
|
|
6199
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6200
|
+
{ id: "footer", label: "Footer" }
|
|
6201
|
+
],
|
|
6202
|
+
"/studio": [
|
|
6203
|
+
{ id: "studio-intro", label: "Studio Intro" },
|
|
6204
|
+
{ id: "studio-features", label: "Studio Features" },
|
|
6205
|
+
{ 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" }
|
|
6212
|
+
],
|
|
6213
|
+
"/contact": [
|
|
6214
|
+
{ id: "hello-hero", label: "Hello" },
|
|
6215
|
+
{ id: "contact-form", label: "Contact Form" },
|
|
6216
|
+
{ id: "faq", label: "FAQ" },
|
|
6217
|
+
{ id: "footer", label: "Footer" }
|
|
6218
|
+
]
|
|
6219
|
+
};
|
|
6220
|
+
function shouldUseDevFixtures() {
|
|
6221
|
+
if (typeof window === "undefined") return false;
|
|
6222
|
+
const raw = readPreservedSearch();
|
|
6223
|
+
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
6224
|
+
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6225
|
+
}
|
|
6226
|
+
|
|
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
|
|
5574
6458
|
}) {
|
|
5575
|
-
|
|
5576
|
-
|
|
6459
|
+
const chromeGap = 6;
|
|
6460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6461
|
+
"div",
|
|
5577
6462
|
{
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
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
|
|
5581
6471
|
},
|
|
5582
|
-
children: /* @__PURE__ */ (0,
|
|
5583
|
-
|
|
6472
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6473
|
+
"button",
|
|
5584
6474
|
{
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
"
|
|
5588
|
-
|
|
5589
|
-
"
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
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 })
|
|
5593
6490
|
}
|
|
5594
6491
|
)
|
|
5595
6492
|
}
|
|
5596
6493
|
);
|
|
5597
6494
|
}
|
|
5598
6495
|
|
|
5599
|
-
// src/ui/link-modal/devFixtures.ts
|
|
5600
|
-
var DEV_SITE_PAGES = [
|
|
5601
|
-
{ path: "/", title: "Home" },
|
|
5602
|
-
{ path: "/about", title: "About" },
|
|
5603
|
-
{ path: "/classes", title: "Classes" },
|
|
5604
|
-
{ path: "/pricing", title: "Pricing" },
|
|
5605
|
-
{ path: "/studio", title: "Studio" },
|
|
5606
|
-
{ path: "/instructors", title: "Instructors" },
|
|
5607
|
-
{ path: "/contact", title: "Contact" }
|
|
5608
|
-
];
|
|
5609
|
-
var DEV_SECTIONS_BY_PATH = {
|
|
5610
|
-
"/": [
|
|
5611
|
-
{ id: "hero", label: "Hero" },
|
|
5612
|
-
{ id: "lagree-intro", label: "Lagree Intro" },
|
|
5613
|
-
{ id: "classes-strip", label: "Classes" },
|
|
5614
|
-
{ id: "feel-split", label: "Feel Split" },
|
|
5615
|
-
{ id: "founder-teaser", label: "Founder" },
|
|
5616
|
-
{ id: "plan-form", label: "Plan Form" },
|
|
5617
|
-
{ id: "testimonials", label: "Testimonials" },
|
|
5618
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
5619
|
-
],
|
|
5620
|
-
"/about": [
|
|
5621
|
-
{ id: "manifesto", label: "Manifesto" },
|
|
5622
|
-
{ id: "story-letter", label: "Our Story" },
|
|
5623
|
-
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
5624
|
-
{ id: "waitlist-cta", label: "Waitlist" },
|
|
5625
|
-
{ id: "personal-training", label: "Personal training" }
|
|
5626
|
-
],
|
|
5627
|
-
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5628
|
-
"/pricing": [
|
|
5629
|
-
{ id: "page-header", label: "Page Header" },
|
|
5630
|
-
{ id: "free-class-cta", label: "Free Class" },
|
|
5631
|
-
{ id: "benefits-marquee", label: "Benefits" },
|
|
5632
|
-
{ id: "monthly-memberships", label: "Memberships" },
|
|
5633
|
-
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5634
|
-
{ id: "package-matcher", label: "Packages" },
|
|
5635
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
5636
|
-
],
|
|
5637
|
-
"/studio": [
|
|
5638
|
-
{ id: "studio-intro", label: "Studio Intro" },
|
|
5639
|
-
{ id: "studio-features", label: "Studio Features" },
|
|
5640
|
-
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5641
|
-
{ id: "studio-visit", label: "Visit Studio" }
|
|
5642
|
-
],
|
|
5643
|
-
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5644
|
-
"/contact": [
|
|
5645
|
-
{ id: "hello-hero", label: "Hello" },
|
|
5646
|
-
{ id: "contact-form", label: "Contact Form" },
|
|
5647
|
-
{ id: "faq", label: "FAQ" }
|
|
5648
|
-
]
|
|
5649
|
-
};
|
|
5650
|
-
function shouldUseDevFixtures() {
|
|
5651
|
-
if (typeof window === "undefined") return false;
|
|
5652
|
-
const raw = readPreservedSearch();
|
|
5653
|
-
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
5654
|
-
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
5655
|
-
}
|
|
5656
|
-
|
|
5657
6496
|
// src/ui/badge.tsx
|
|
5658
|
-
var
|
|
6497
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5659
6498
|
var badgeVariants = cva(
|
|
5660
6499
|
"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",
|
|
5661
6500
|
{
|
|
@@ -5673,12 +6512,12 @@ var badgeVariants = cva(
|
|
|
5673
6512
|
}
|
|
5674
6513
|
);
|
|
5675
6514
|
function Badge({ className, variant, ...props }) {
|
|
5676
|
-
return /* @__PURE__ */ (0,
|
|
6515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5677
6516
|
}
|
|
5678
6517
|
|
|
5679
6518
|
// src/OhhwellsBridge.tsx
|
|
5680
|
-
var
|
|
5681
|
-
var
|
|
6519
|
+
var import_lucide_react11 = require("lucide-react");
|
|
6520
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5682
6521
|
var PRIMARY2 = "#0885FE";
|
|
5683
6522
|
var IMAGE_FADE_MS = 300;
|
|
5684
6523
|
function runOpacityFade(el, onDone) {
|
|
@@ -5850,9 +6689,9 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5850
6689
|
tail.insertAdjacentElement("afterend", container);
|
|
5851
6690
|
}
|
|
5852
6691
|
const root = (0, import_client.createRoot)(container);
|
|
5853
|
-
(0,
|
|
6692
|
+
(0, import_react_dom2.flushSync)(() => {
|
|
5854
6693
|
root.render(
|
|
5855
|
-
/* @__PURE__ */ (0,
|
|
6694
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5856
6695
|
SchedulingWidget,
|
|
5857
6696
|
{
|
|
5858
6697
|
notifyOnConnect,
|
|
@@ -5892,7 +6731,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
5892
6731
|
}
|
|
5893
6732
|
}
|
|
5894
6733
|
}
|
|
5895
|
-
function
|
|
6734
|
+
function getLinkHref2(el) {
|
|
5896
6735
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
5897
6736
|
return anchor?.getAttribute("href") ?? "";
|
|
5898
6737
|
}
|
|
@@ -5929,7 +6768,7 @@ function collectEditableNodes() {
|
|
|
5929
6768
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
5930
6769
|
}
|
|
5931
6770
|
if (el.dataset.ohwEditable === "link") {
|
|
5932
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6771
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
|
|
5933
6772
|
}
|
|
5934
6773
|
return {
|
|
5935
6774
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -5940,7 +6779,7 @@ function collectEditableNodes() {
|
|
|
5940
6779
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
5941
6780
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
5942
6781
|
if (!key) return;
|
|
5943
|
-
nodes.push({ key, type: "link", text:
|
|
6782
|
+
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
5944
6783
|
});
|
|
5945
6784
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
5946
6785
|
const key = el.dataset.ohwKey ?? "";
|
|
@@ -6010,7 +6849,7 @@ function applyLinkByKey(key, val) {
|
|
|
6010
6849
|
}
|
|
6011
6850
|
function isInsideLinkEditor(target) {
|
|
6012
6851
|
return Boolean(
|
|
6013
|
-
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"]')
|
|
6852
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
6014
6853
|
);
|
|
6015
6854
|
}
|
|
6016
6855
|
function getHrefKeyFromElement(el) {
|
|
@@ -6021,7 +6860,7 @@ function getHrefKeyFromElement(el) {
|
|
|
6021
6860
|
if (!key) return null;
|
|
6022
6861
|
return { anchor, key };
|
|
6023
6862
|
}
|
|
6024
|
-
function
|
|
6863
|
+
function isNavbarButton2(el) {
|
|
6025
6864
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
6026
6865
|
}
|
|
6027
6866
|
function getNavigationItemAnchor(el) {
|
|
@@ -6033,19 +6872,8 @@ function getNavigationItemAnchor(el) {
|
|
|
6033
6872
|
function isNavigationItem(el) {
|
|
6034
6873
|
return getNavigationItemAnchor(el) !== null;
|
|
6035
6874
|
}
|
|
6036
|
-
function getNavigationItemAddHintTarget(anchor) {
|
|
6037
|
-
const items = listNavigationItems();
|
|
6038
|
-
const idx = items.indexOf(anchor);
|
|
6039
|
-
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
6040
|
-
return anchor;
|
|
6041
|
-
}
|
|
6042
|
-
function listNavigationItems() {
|
|
6043
|
-
return Array.from(
|
|
6044
|
-
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
6045
|
-
).filter((el) => isNavigationItem(el));
|
|
6046
|
-
}
|
|
6047
6875
|
function getNavigationItemReorderState(anchor) {
|
|
6048
|
-
if (
|
|
6876
|
+
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
6049
6877
|
return getReorderHandleStateFromAnchor(anchor);
|
|
6050
6878
|
}
|
|
6051
6879
|
function getReorderHandleState(el) {
|
|
@@ -6096,6 +6924,39 @@ function isInferredFooterGroup(el) {
|
|
|
6096
6924
|
function isNavigationContainer(el) {
|
|
6097
6925
|
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
6098
6926
|
}
|
|
6927
|
+
function isPointOverNavigation(x, y) {
|
|
6928
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
6929
|
+
if (!navRoot) return false;
|
|
6930
|
+
const r2 = navRoot.getBoundingClientRect();
|
|
6931
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
6932
|
+
}
|
|
6933
|
+
function isPointOverNavItem(container, x, y) {
|
|
6934
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
6935
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
6936
|
+
const itemRect = el.getBoundingClientRect();
|
|
6937
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
6938
|
+
});
|
|
6939
|
+
}
|
|
6940
|
+
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
6941
|
+
if (getNavigationItemAnchor(target)) return null;
|
|
6942
|
+
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
6943
|
+
const plainLink = target.closest("a");
|
|
6944
|
+
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
6945
|
+
return null;
|
|
6946
|
+
}
|
|
6947
|
+
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
6948
|
+
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
6949
|
+
return fromClosest;
|
|
6950
|
+
}
|
|
6951
|
+
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
6952
|
+
if (!navRoot) return null;
|
|
6953
|
+
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
6954
|
+
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
6955
|
+
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
6956
|
+
return container;
|
|
6957
|
+
}
|
|
6958
|
+
return null;
|
|
6959
|
+
}
|
|
6099
6960
|
function getNavigationSelectionParent(el) {
|
|
6100
6961
|
if (isNavigationItem(el)) {
|
|
6101
6962
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
@@ -6297,7 +7158,7 @@ function EditGlowChrome({
|
|
|
6297
7158
|
dragDisabled = false
|
|
6298
7159
|
}) {
|
|
6299
7160
|
const GAP = 6;
|
|
6300
|
-
return /* @__PURE__ */ (0,
|
|
7161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
6301
7162
|
"div",
|
|
6302
7163
|
{
|
|
6303
7164
|
ref: elRef,
|
|
@@ -6312,7 +7173,7 @@ function EditGlowChrome({
|
|
|
6312
7173
|
zIndex: 2147483646
|
|
6313
7174
|
},
|
|
6314
7175
|
children: [
|
|
6315
|
-
/* @__PURE__ */ (0,
|
|
7176
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6316
7177
|
"div",
|
|
6317
7178
|
{
|
|
6318
7179
|
style: {
|
|
@@ -6325,7 +7186,7 @@ function EditGlowChrome({
|
|
|
6325
7186
|
}
|
|
6326
7187
|
}
|
|
6327
7188
|
),
|
|
6328
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
7189
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6329
7190
|
"div",
|
|
6330
7191
|
{
|
|
6331
7192
|
"data-ohw-drag-handle-container": "",
|
|
@@ -6337,7 +7198,7 @@ function EditGlowChrome({
|
|
|
6337
7198
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6338
7199
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6339
7200
|
},
|
|
6340
|
-
children: /* @__PURE__ */ (0,
|
|
7201
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6341
7202
|
DragHandle,
|
|
6342
7203
|
{
|
|
6343
7204
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -6441,7 +7302,7 @@ function FloatingToolbar({
|
|
|
6441
7302
|
onEditLink
|
|
6442
7303
|
}) {
|
|
6443
7304
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6444
|
-
return /* @__PURE__ */ (0,
|
|
7305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6445
7306
|
"div",
|
|
6446
7307
|
{
|
|
6447
7308
|
ref: elRef,
|
|
@@ -6462,12 +7323,12 @@ function FloatingToolbar({
|
|
|
6462
7323
|
fontFamily: "sans-serif",
|
|
6463
7324
|
pointerEvents: "auto"
|
|
6464
7325
|
},
|
|
6465
|
-
children: /* @__PURE__ */ (0,
|
|
6466
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
6467
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
7326
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CustomToolbar, { children: [
|
|
7327
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react8.default.Fragment, { children: [
|
|
7328
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CustomToolbarDivider, {}),
|
|
6468
7329
|
btns.map((btn) => {
|
|
6469
7330
|
const isActive = activeCommands.has(btn.cmd);
|
|
6470
|
-
return /* @__PURE__ */ (0,
|
|
7331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6471
7332
|
CustomToolbarButton,
|
|
6472
7333
|
{
|
|
6473
7334
|
title: btn.title,
|
|
@@ -6476,7 +7337,7 @@ function FloatingToolbar({
|
|
|
6476
7337
|
e.preventDefault();
|
|
6477
7338
|
onCommand(btn.cmd);
|
|
6478
7339
|
},
|
|
6479
|
-
children: /* @__PURE__ */ (0,
|
|
7340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6480
7341
|
"svg",
|
|
6481
7342
|
{
|
|
6482
7343
|
width: "16",
|
|
@@ -6497,7 +7358,7 @@ function FloatingToolbar({
|
|
|
6497
7358
|
);
|
|
6498
7359
|
})
|
|
6499
7360
|
] }, gi)),
|
|
6500
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
7361
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6501
7362
|
CustomToolbarButton,
|
|
6502
7363
|
{
|
|
6503
7364
|
type: "button",
|
|
@@ -6511,7 +7372,7 @@ function FloatingToolbar({
|
|
|
6511
7372
|
e.preventDefault();
|
|
6512
7373
|
e.stopPropagation();
|
|
6513
7374
|
},
|
|
6514
|
-
children: /* @__PURE__ */ (0,
|
|
7375
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6515
7376
|
}
|
|
6516
7377
|
) : null
|
|
6517
7378
|
] })
|
|
@@ -6528,7 +7389,7 @@ function StateToggle({
|
|
|
6528
7389
|
states,
|
|
6529
7390
|
onStateChange
|
|
6530
7391
|
}) {
|
|
6531
|
-
return /* @__PURE__ */ (0,
|
|
7392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6532
7393
|
ToggleGroup,
|
|
6533
7394
|
{
|
|
6534
7395
|
"data-ohw-state-toggle": "",
|
|
@@ -6542,7 +7403,7 @@ function StateToggle({
|
|
|
6542
7403
|
left: rect.right - 8,
|
|
6543
7404
|
transform: "translateX(-100%)"
|
|
6544
7405
|
},
|
|
6545
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
7406
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6546
7407
|
}
|
|
6547
7408
|
);
|
|
6548
7409
|
}
|
|
@@ -6565,12 +7426,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
6565
7426
|
return "";
|
|
6566
7427
|
}
|
|
6567
7428
|
function OhhwellsBridge() {
|
|
6568
|
-
const pathname = (0,
|
|
6569
|
-
const router = (0,
|
|
6570
|
-
const searchParams = (0,
|
|
7429
|
+
const pathname = (0, import_navigation2.usePathname)();
|
|
7430
|
+
const router = (0, import_navigation2.useRouter)();
|
|
7431
|
+
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
6571
7432
|
const isEditMode = isEditSessionActive();
|
|
6572
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
6573
|
-
(0,
|
|
7433
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react8.useState)(null);
|
|
7434
|
+
(0, import_react8.useEffect)(() => {
|
|
6574
7435
|
const figtreeFontId = "ohw-figtree-font";
|
|
6575
7436
|
if (!document.getElementById(figtreeFontId)) {
|
|
6576
7437
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -6578,7 +7439,10 @@ function OhhwellsBridge() {
|
|
|
6578
7439
|
const stylesheet = Object.assign(document.createElement("link"), {
|
|
6579
7440
|
id: figtreeFontId,
|
|
6580
7441
|
rel: "stylesheet",
|
|
6581
|
-
|
|
7442
|
+
// Inter is loaded alongside Figtree for the media overlay's Replace button. The bridge
|
|
7443
|
+
// renders inside the customer's document, so it cannot assume any font is present — an
|
|
7444
|
+
// unloaded family would silently fall back to whatever the template happens to use.
|
|
7445
|
+
href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Inter:wght@400;500;600&display=swap"
|
|
6582
7446
|
});
|
|
6583
7447
|
document.head.append(preconnect1, preconnect2, stylesheet);
|
|
6584
7448
|
}
|
|
@@ -6595,82 +7459,90 @@ function OhhwellsBridge() {
|
|
|
6595
7459
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
6596
7460
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
6597
7461
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
6598
|
-
const
|
|
7462
|
+
const postToParent2 = (0, import_react8.useCallback)((data) => {
|
|
6599
7463
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
6600
7464
|
window.parent.postMessage(data, "*");
|
|
6601
7465
|
}
|
|
6602
7466
|
}, []);
|
|
6603
|
-
const [fetchState, setFetchState] = (0,
|
|
6604
|
-
const autoSaveTimers = (0,
|
|
6605
|
-
const activeElRef = (0,
|
|
6606
|
-
const selectedElRef = (0,
|
|
6607
|
-
const originalContentRef = (0,
|
|
6608
|
-
const activeStateElRef = (0,
|
|
6609
|
-
const parentScrollRef = (0,
|
|
6610
|
-
const visibleViewportRef = (0,
|
|
6611
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0,
|
|
6612
|
-
const attachVisibleViewport = (0,
|
|
7467
|
+
const [fetchState, setFetchState] = (0, import_react8.useState)("idle");
|
|
7468
|
+
const autoSaveTimers = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
7469
|
+
const activeElRef = (0, import_react8.useRef)(null);
|
|
7470
|
+
const selectedElRef = (0, import_react8.useRef)(null);
|
|
7471
|
+
const originalContentRef = (0, import_react8.useRef)(null);
|
|
7472
|
+
const activeStateElRef = (0, import_react8.useRef)(null);
|
|
7473
|
+
const parentScrollRef = (0, import_react8.useRef)(null);
|
|
7474
|
+
const visibleViewportRef = (0, import_react8.useRef)(null);
|
|
7475
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react8.useState)(null);
|
|
7476
|
+
const attachVisibleViewport = (0, import_react8.useCallback)((node) => {
|
|
6613
7477
|
visibleViewportRef.current = node;
|
|
6614
7478
|
setDialogPortalContainer(node);
|
|
6615
7479
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6616
7480
|
}, []);
|
|
6617
|
-
const toolbarElRef = (0,
|
|
6618
|
-
const glowElRef = (0,
|
|
6619
|
-
const hoveredImageRef = (0,
|
|
6620
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
6621
|
-
const
|
|
6622
|
-
const
|
|
6623
|
-
const
|
|
6624
|
-
const
|
|
6625
|
-
const
|
|
7481
|
+
const toolbarElRef = (0, import_react8.useRef)(null);
|
|
7482
|
+
const glowElRef = (0, import_react8.useRef)(null);
|
|
7483
|
+
const hoveredImageRef = (0, import_react8.useRef)(null);
|
|
7484
|
+
const hoveredImageHasTextOverlapRef = (0, import_react8.useRef)(false);
|
|
7485
|
+
const [mediaHover, setMediaHover] = (0, import_react8.useState)(null);
|
|
7486
|
+
const [uploadingRects, setUploadingRects] = (0, import_react8.useState)({});
|
|
7487
|
+
const hoveredGapRef = (0, import_react8.useRef)(null);
|
|
7488
|
+
const imageUnhoverTimerRef = (0, import_react8.useRef)(null);
|
|
7489
|
+
const imageShowTimerRef = (0, import_react8.useRef)(null);
|
|
7490
|
+
const editStylesRef = (0, import_react8.useRef)(null);
|
|
7491
|
+
const activateRef = (0, import_react8.useRef)(() => {
|
|
6626
7492
|
});
|
|
6627
|
-
const deactivateRef = (0,
|
|
7493
|
+
const deactivateRef = (0, import_react8.useRef)(() => {
|
|
6628
7494
|
});
|
|
6629
|
-
const selectRef = (0,
|
|
7495
|
+
const selectRef = (0, import_react8.useRef)(() => {
|
|
6630
7496
|
});
|
|
6631
|
-
const selectFrameRef = (0,
|
|
7497
|
+
const selectFrameRef = (0, import_react8.useRef)(() => {
|
|
6632
7498
|
});
|
|
6633
|
-
const deselectRef = (0,
|
|
7499
|
+
const deselectRef = (0, import_react8.useRef)(() => {
|
|
6634
7500
|
});
|
|
6635
|
-
const reselectNavigationItemRef = (0,
|
|
7501
|
+
const reselectNavigationItemRef = (0, import_react8.useRef)(() => {
|
|
6636
7502
|
});
|
|
6637
|
-
const commitNavigationTextEditRef = (0,
|
|
7503
|
+
const commitNavigationTextEditRef = (0, import_react8.useRef)(() => {
|
|
6638
7504
|
});
|
|
6639
|
-
const refreshActiveCommandsRef = (0,
|
|
7505
|
+
const refreshActiveCommandsRef = (0, import_react8.useRef)(() => {
|
|
6640
7506
|
});
|
|
6641
|
-
const postToParentRef = (0,
|
|
6642
|
-
postToParentRef.current =
|
|
6643
|
-
const sectionsLoadedRef = (0,
|
|
6644
|
-
const pendingScheduleConfigRequests = (0,
|
|
6645
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
6646
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
6647
|
-
const toolbarVariantRef = (0,
|
|
7507
|
+
const postToParentRef = (0, import_react8.useRef)(postToParent2);
|
|
7508
|
+
postToParentRef.current = postToParent2;
|
|
7509
|
+
const sectionsLoadedRef = (0, import_react8.useRef)(false);
|
|
7510
|
+
const pendingScheduleConfigRequests = (0, import_react8.useRef)([]);
|
|
7511
|
+
const [toolbarRect, setToolbarRect] = (0, import_react8.useState)(null);
|
|
7512
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react8.useState)("none");
|
|
7513
|
+
const toolbarVariantRef = (0, import_react8.useRef)("none");
|
|
6648
7514
|
toolbarVariantRef.current = toolbarVariant;
|
|
6649
|
-
const [reorderHrefKey, setReorderHrefKey] = (0,
|
|
6650
|
-
const [reorderDragDisabled, setReorderDragDisabled] = (0,
|
|
6651
|
-
const [toggleState, setToggleState] = (0,
|
|
6652
|
-
const [maxBadge, setMaxBadge] = (0,
|
|
6653
|
-
const [activeCommands, setActiveCommands] = (0,
|
|
6654
|
-
const [sectionGap, setSectionGap] = (0,
|
|
6655
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] = (0,
|
|
6656
|
-
const
|
|
6657
|
-
const [
|
|
6658
|
-
const
|
|
6659
|
-
const [
|
|
6660
|
-
const
|
|
6661
|
-
const [
|
|
6662
|
-
const [
|
|
6663
|
-
const [
|
|
6664
|
-
const
|
|
6665
|
-
const
|
|
6666
|
-
const
|
|
6667
|
-
const
|
|
6668
|
-
const
|
|
7515
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react8.useState)(null);
|
|
7516
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react8.useState)(false);
|
|
7517
|
+
const [toggleState, setToggleState] = (0, import_react8.useState)(null);
|
|
7518
|
+
const [maxBadge, setMaxBadge] = (0, import_react8.useState)(null);
|
|
7519
|
+
const [activeCommands, setActiveCommands] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
|
|
7520
|
+
const [sectionGap, setSectionGap] = (0, import_react8.useState)(null);
|
|
7521
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react8.useState)(false);
|
|
7522
|
+
const hoveredNavContainerRef = (0, import_react8.useRef)(null);
|
|
7523
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react8.useState)(null);
|
|
7524
|
+
const hoveredItemElRef = (0, import_react8.useRef)(null);
|
|
7525
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react8.useState)(null);
|
|
7526
|
+
const siblingHintElRef = (0, import_react8.useRef)(null);
|
|
7527
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react8.useState)(null);
|
|
7528
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react8.useState)(false);
|
|
7529
|
+
const [linkPopover, setLinkPopover] = (0, import_react8.useState)(null);
|
|
7530
|
+
const linkPopoverSessionRef = (0, import_react8.useRef)(null);
|
|
7531
|
+
const addNavAfterAnchorRef = (0, import_react8.useRef)(null);
|
|
7532
|
+
const editContentRef = (0, import_react8.useRef)({});
|
|
7533
|
+
const [sitePages, setSitePages] = (0, import_react8.useState)([]);
|
|
7534
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react8.useState)({});
|
|
7535
|
+
const sectionsPrefetchGenRef = (0, import_react8.useRef)(0);
|
|
7536
|
+
const setLinkPopoverRef = (0, import_react8.useRef)(setLinkPopover);
|
|
7537
|
+
const linkPopoverPanelRef = (0, import_react8.useRef)(null);
|
|
7538
|
+
const linkPopoverOpenRef = (0, import_react8.useRef)(false);
|
|
7539
|
+
const linkPopoverGraceUntilRef = (0, import_react8.useRef)(0);
|
|
6669
7540
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7541
|
+
linkPopoverSessionRef.current = linkPopover;
|
|
6670
7542
|
const bumpLinkPopoverGrace = () => {
|
|
6671
7543
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
6672
7544
|
};
|
|
6673
|
-
const runSectionsPrefetch = (0,
|
|
7545
|
+
const runSectionsPrefetch = (0, import_react8.useCallback)((pages) => {
|
|
6674
7546
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
6675
7547
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
6676
7548
|
const paths = pages.map((p) => p.path);
|
|
@@ -6689,9 +7561,9 @@ function OhhwellsBridge() {
|
|
|
6689
7561
|
);
|
|
6690
7562
|
});
|
|
6691
7563
|
}, [isEditMode, pathname]);
|
|
6692
|
-
const runSectionsPrefetchRef = (0,
|
|
7564
|
+
const runSectionsPrefetchRef = (0, import_react8.useRef)(runSectionsPrefetch);
|
|
6693
7565
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
6694
|
-
(0,
|
|
7566
|
+
(0, import_react8.useEffect)(() => {
|
|
6695
7567
|
if (!linkPopover) return;
|
|
6696
7568
|
if (hoveredImageRef.current) {
|
|
6697
7569
|
hoveredImageRef.current = null;
|
|
@@ -6699,33 +7571,9 @@ function OhhwellsBridge() {
|
|
|
6699
7571
|
}
|
|
6700
7572
|
hoveredGapRef.current = null;
|
|
6701
7573
|
setSectionGap(null);
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
const body = document.body;
|
|
6706
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6707
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6708
|
-
html.style.overflow = "hidden";
|
|
6709
|
-
body.style.overflow = "hidden";
|
|
6710
|
-
const preventBackgroundScroll = (e) => {
|
|
6711
|
-
const target = e.target;
|
|
6712
|
-
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6713
|
-
return;
|
|
6714
|
-
}
|
|
6715
|
-
e.preventDefault();
|
|
6716
|
-
};
|
|
6717
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6718
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6719
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6720
|
-
return () => {
|
|
6721
|
-
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6722
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6723
|
-
body.style.overflow = prevBodyOverflow;
|
|
6724
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6725
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6726
|
-
};
|
|
6727
|
-
}, [linkPopover, postToParent]);
|
|
6728
|
-
(0, import_react6.useEffect)(() => {
|
|
7574
|
+
postToParent2({ type: "ow:image-unhover" });
|
|
7575
|
+
}, [linkPopover, postToParent2]);
|
|
7576
|
+
(0, import_react8.useEffect)(() => {
|
|
6729
7577
|
if (!isEditMode) return;
|
|
6730
7578
|
const useFixtures = shouldUseDevFixtures();
|
|
6731
7579
|
if (useFixtures) {
|
|
@@ -6746,17 +7594,17 @@ function OhhwellsBridge() {
|
|
|
6746
7594
|
runSectionsPrefetchRef.current(mapped);
|
|
6747
7595
|
};
|
|
6748
7596
|
window.addEventListener("message", onSitePages);
|
|
6749
|
-
if (!useFixtures)
|
|
7597
|
+
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
6750
7598
|
return () => window.removeEventListener("message", onSitePages);
|
|
6751
|
-
}, [isEditMode,
|
|
6752
|
-
(0,
|
|
7599
|
+
}, [isEditMode, postToParent2]);
|
|
7600
|
+
(0, import_react8.useEffect)(() => {
|
|
6753
7601
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
6754
7602
|
void loadAllSectionsManifest().then((manifest) => {
|
|
6755
7603
|
if (Object.keys(manifest).length === 0) return;
|
|
6756
7604
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
6757
7605
|
});
|
|
6758
7606
|
}, [isEditMode]);
|
|
6759
|
-
(0,
|
|
7607
|
+
(0, import_react8.useEffect)(() => {
|
|
6760
7608
|
const update = () => {
|
|
6761
7609
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6762
7610
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -6780,10 +7628,10 @@ function OhhwellsBridge() {
|
|
|
6780
7628
|
vvp.removeEventListener("resize", update);
|
|
6781
7629
|
};
|
|
6782
7630
|
}, []);
|
|
6783
|
-
const refreshStateRules = (0,
|
|
7631
|
+
const refreshStateRules = (0, import_react8.useCallback)(() => {
|
|
6784
7632
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
6785
7633
|
}, []);
|
|
6786
|
-
const processConfigRequest = (0,
|
|
7634
|
+
const processConfigRequest = (0, import_react8.useCallback)((insertAfterVal) => {
|
|
6787
7635
|
const tracker = getSectionsTracker();
|
|
6788
7636
|
let entries = [];
|
|
6789
7637
|
try {
|
|
@@ -6806,7 +7654,7 @@ function OhhwellsBridge() {
|
|
|
6806
7654
|
}
|
|
6807
7655
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
6808
7656
|
}, [isEditMode]);
|
|
6809
|
-
const deactivate = (0,
|
|
7657
|
+
const deactivate = (0, import_react8.useCallback)(() => {
|
|
6810
7658
|
const el = activeElRef.current;
|
|
6811
7659
|
if (!el) return;
|
|
6812
7660
|
const key = el.dataset.ohwKey;
|
|
@@ -6835,21 +7683,23 @@ function OhhwellsBridge() {
|
|
|
6835
7683
|
setMaxBadge(null);
|
|
6836
7684
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6837
7685
|
setToolbarShowEditLink(false);
|
|
6838
|
-
|
|
6839
|
-
}, [
|
|
6840
|
-
const deselect = (0,
|
|
7686
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
7687
|
+
}, [postToParent2]);
|
|
7688
|
+
const deselect = (0, import_react8.useCallback)(() => {
|
|
6841
7689
|
selectedElRef.current = null;
|
|
6842
7690
|
setReorderHrefKey(null);
|
|
6843
7691
|
setReorderDragDisabled(false);
|
|
6844
7692
|
siblingHintElRef.current = null;
|
|
6845
7693
|
setSiblingHintRect(null);
|
|
6846
7694
|
setIsItemDragging(false);
|
|
7695
|
+
hoveredNavContainerRef.current = null;
|
|
7696
|
+
setHoveredNavContainerRect(null);
|
|
6847
7697
|
if (!activeElRef.current) {
|
|
6848
7698
|
setToolbarRect(null);
|
|
6849
7699
|
setToolbarVariant("none");
|
|
6850
7700
|
}
|
|
6851
7701
|
}, []);
|
|
6852
|
-
const reselectNavigationItem = (0,
|
|
7702
|
+
const reselectNavigationItem = (0, import_react8.useCallback)((navAnchor) => {
|
|
6853
7703
|
selectedElRef.current = navAnchor;
|
|
6854
7704
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
6855
7705
|
setReorderHrefKey(key);
|
|
@@ -6859,7 +7709,7 @@ function OhhwellsBridge() {
|
|
|
6859
7709
|
setToolbarShowEditLink(false);
|
|
6860
7710
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6861
7711
|
}, []);
|
|
6862
|
-
const commitNavigationTextEdit = (0,
|
|
7712
|
+
const commitNavigationTextEdit = (0, import_react8.useCallback)((navAnchor) => {
|
|
6863
7713
|
const el = activeElRef.current;
|
|
6864
7714
|
if (!el) return;
|
|
6865
7715
|
const key = el.dataset.ohwKey;
|
|
@@ -6872,9 +7722,9 @@ function OhhwellsBridge() {
|
|
|
6872
7722
|
const html = sanitizeHtml(el.innerHTML);
|
|
6873
7723
|
const original = originalContentRef.current ?? "";
|
|
6874
7724
|
if (html !== sanitizeHtml(original)) {
|
|
6875
|
-
|
|
7725
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
6876
7726
|
const h = document.documentElement.scrollHeight;
|
|
6877
|
-
if (h > 50)
|
|
7727
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
6878
7728
|
}
|
|
6879
7729
|
}
|
|
6880
7730
|
el.removeAttribute("contenteditable");
|
|
@@ -6882,31 +7732,38 @@ function OhhwellsBridge() {
|
|
|
6882
7732
|
setMaxBadge(null);
|
|
6883
7733
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6884
7734
|
setToolbarShowEditLink(false);
|
|
6885
|
-
|
|
7735
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
6886
7736
|
reselectNavigationItem(navAnchor);
|
|
6887
|
-
}, [
|
|
6888
|
-
const
|
|
6889
|
-
const
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
7737
|
+
}, [postToParent2, reselectNavigationItem]);
|
|
7738
|
+
const handleAddTopLevelNavItem = (0, import_react8.useCallback)(() => {
|
|
7739
|
+
const items = listNavbarItems();
|
|
7740
|
+
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7741
|
+
deselectRef.current();
|
|
7742
|
+
deactivateRef.current();
|
|
7743
|
+
bumpLinkPopoverGrace();
|
|
7744
|
+
setLinkPopover({
|
|
7745
|
+
key: "__add-nav__",
|
|
7746
|
+
mode: "create",
|
|
7747
|
+
intent: "add-nav"
|
|
7748
|
+
});
|
|
6894
7749
|
}, []);
|
|
6895
|
-
const handleItemDragStart = (0,
|
|
7750
|
+
const handleItemDragStart = (0, import_react8.useCallback)(() => {
|
|
6896
7751
|
siblingHintElRef.current = null;
|
|
6897
7752
|
setSiblingHintRect(null);
|
|
6898
7753
|
setIsItemDragging(true);
|
|
6899
7754
|
}, []);
|
|
6900
|
-
const handleItemDragEnd = (0,
|
|
7755
|
+
const handleItemDragEnd = (0, import_react8.useCallback)(() => {
|
|
6901
7756
|
setIsItemDragging(false);
|
|
6902
7757
|
}, []);
|
|
6903
7758
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
6904
7759
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
6905
|
-
const select = (0,
|
|
7760
|
+
const select = (0, import_react8.useCallback)((anchor) => {
|
|
6906
7761
|
if (!isNavigationItem(anchor)) return;
|
|
6907
7762
|
if (activeElRef.current) deactivate();
|
|
6908
7763
|
selectedElRef.current = anchor;
|
|
6909
7764
|
clearHrefKeyHover(anchor);
|
|
7765
|
+
hoveredNavContainerRef.current = null;
|
|
7766
|
+
setHoveredNavContainerRect(null);
|
|
6910
7767
|
setHoveredItemRect(null);
|
|
6911
7768
|
hoveredItemElRef.current = null;
|
|
6912
7769
|
siblingHintElRef.current = null;
|
|
@@ -6920,11 +7777,13 @@ function OhhwellsBridge() {
|
|
|
6920
7777
|
setToolbarShowEditLink(false);
|
|
6921
7778
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6922
7779
|
}, [deactivate]);
|
|
6923
|
-
const selectFrame = (0,
|
|
7780
|
+
const selectFrame = (0, import_react8.useCallback)((el) => {
|
|
6924
7781
|
if (!isNavigationContainer(el)) return;
|
|
6925
7782
|
if (activeElRef.current) deactivate();
|
|
6926
7783
|
selectedElRef.current = el;
|
|
6927
7784
|
clearHrefKeyHover(el);
|
|
7785
|
+
hoveredNavContainerRef.current = null;
|
|
7786
|
+
setHoveredNavContainerRect(null);
|
|
6928
7787
|
setHoveredItemRect(null);
|
|
6929
7788
|
hoveredItemElRef.current = null;
|
|
6930
7789
|
siblingHintElRef.current = null;
|
|
@@ -6937,13 +7796,13 @@ function OhhwellsBridge() {
|
|
|
6937
7796
|
setToolbarShowEditLink(false);
|
|
6938
7797
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6939
7798
|
}, [deactivate]);
|
|
6940
|
-
const activate = (0,
|
|
7799
|
+
const activate = (0, import_react8.useCallback)((el, options) => {
|
|
6941
7800
|
if (activeElRef.current === el) return;
|
|
6942
7801
|
selectedElRef.current = null;
|
|
6943
7802
|
deactivate();
|
|
6944
7803
|
if (hoveredImageRef.current) {
|
|
6945
7804
|
hoveredImageRef.current = null;
|
|
6946
|
-
|
|
7805
|
+
setMediaHover(null);
|
|
6947
7806
|
}
|
|
6948
7807
|
setToolbarVariant("rich-text");
|
|
6949
7808
|
siblingHintElRef.current = null;
|
|
@@ -6969,15 +7828,15 @@ function OhhwellsBridge() {
|
|
|
6969
7828
|
setReorderDragDisabled(reorderDisabled);
|
|
6970
7829
|
}
|
|
6971
7830
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6972
|
-
|
|
7831
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6973
7832
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6974
|
-
}, [deactivate,
|
|
7833
|
+
}, [deactivate, postToParent2]);
|
|
6975
7834
|
activateRef.current = activate;
|
|
6976
7835
|
deactivateRef.current = deactivate;
|
|
6977
7836
|
selectRef.current = select;
|
|
6978
7837
|
selectFrameRef.current = selectFrame;
|
|
6979
7838
|
deselectRef.current = deselect;
|
|
6980
|
-
(0,
|
|
7839
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
6981
7840
|
if (!subdomain || isEditMode) {
|
|
6982
7841
|
setFetchState("done");
|
|
6983
7842
|
return;
|
|
@@ -7045,7 +7904,7 @@ function OhhwellsBridge() {
|
|
|
7045
7904
|
cancelled = true;
|
|
7046
7905
|
};
|
|
7047
7906
|
}, [subdomain, isEditMode]);
|
|
7048
|
-
(0,
|
|
7907
|
+
(0, import_react8.useEffect)(() => {
|
|
7049
7908
|
if (!subdomain || isEditMode) return;
|
|
7050
7909
|
let debounceTimer = null;
|
|
7051
7910
|
let observer = null;
|
|
@@ -7093,26 +7952,40 @@ function OhhwellsBridge() {
|
|
|
7093
7952
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
7094
7953
|
};
|
|
7095
7954
|
}, [subdomain, isEditMode, pathname]);
|
|
7096
|
-
(0,
|
|
7955
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
7097
7956
|
const el = document.getElementById("ohw-loader");
|
|
7098
7957
|
if (!el) return;
|
|
7099
7958
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
7100
7959
|
el.style.display = visible ? "flex" : "none";
|
|
7101
7960
|
}, [subdomain, fetchState]);
|
|
7102
|
-
(0,
|
|
7103
|
-
|
|
7104
|
-
}, [pathname,
|
|
7105
|
-
(0,
|
|
7961
|
+
(0, import_react8.useEffect)(() => {
|
|
7962
|
+
postToParent2({ type: "ow:navigation", path: pathname });
|
|
7963
|
+
}, [pathname, postToParent2]);
|
|
7964
|
+
(0, import_react8.useEffect)(() => {
|
|
7106
7965
|
if (!isEditMode) return;
|
|
7966
|
+
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
7967
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7107
7968
|
setLinkPopover(null);
|
|
7108
7969
|
deselectRef.current();
|
|
7109
7970
|
deactivateRef.current();
|
|
7110
7971
|
}, [pathname, isEditMode]);
|
|
7111
|
-
(0,
|
|
7972
|
+
(0, import_react8.useEffect)(() => {
|
|
7973
|
+
if (!isEditMode) return;
|
|
7974
|
+
const run = () => reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7975
|
+
run();
|
|
7976
|
+
const nav = document.querySelector("nav");
|
|
7977
|
+
if (!nav) return;
|
|
7978
|
+
const observer = new MutationObserver(() => {
|
|
7979
|
+
requestAnimationFrame(run);
|
|
7980
|
+
});
|
|
7981
|
+
observer.observe(nav, { childList: true, subtree: true });
|
|
7982
|
+
return () => observer.disconnect();
|
|
7983
|
+
}, [isEditMode, pathname]);
|
|
7984
|
+
(0, import_react8.useEffect)(() => {
|
|
7112
7985
|
if (!isEditMode) return;
|
|
7113
7986
|
const measure = () => {
|
|
7114
7987
|
const h = document.body.scrollHeight;
|
|
7115
|
-
if (h > 50)
|
|
7988
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
7116
7989
|
};
|
|
7117
7990
|
const t1 = setTimeout(measure, 50);
|
|
7118
7991
|
const t2 = setTimeout(measure, 500);
|
|
@@ -7131,8 +8004,8 @@ function OhhwellsBridge() {
|
|
|
7131
8004
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
7132
8005
|
window.removeEventListener("resize", handleResize);
|
|
7133
8006
|
};
|
|
7134
|
-
}, [pathname, isEditMode,
|
|
7135
|
-
(0,
|
|
8007
|
+
}, [pathname, isEditMode, postToParent2]);
|
|
8008
|
+
(0, import_react8.useEffect)(() => {
|
|
7136
8009
|
if (!subdomainFromQuery || isEditMode) return;
|
|
7137
8010
|
const handleClick = (e) => {
|
|
7138
8011
|
const anchor = e.target.closest("a");
|
|
@@ -7148,7 +8021,7 @@ function OhhwellsBridge() {
|
|
|
7148
8021
|
document.addEventListener("click", handleClick, true);
|
|
7149
8022
|
return () => document.removeEventListener("click", handleClick, true);
|
|
7150
8023
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
7151
|
-
(0,
|
|
8024
|
+
(0, import_react8.useEffect)(() => {
|
|
7152
8025
|
if (!isEditMode) {
|
|
7153
8026
|
editStylesRef.current?.base.remove();
|
|
7154
8027
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -7222,6 +8095,13 @@ function OhhwellsBridge() {
|
|
|
7222
8095
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7223
8096
|
if (isInsideLinkEditor(target)) return;
|
|
7224
8097
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8098
|
+
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8099
|
+
if (navFromChrome) {
|
|
8100
|
+
e.preventDefault();
|
|
8101
|
+
e.stopPropagation();
|
|
8102
|
+
selectFrameRef.current(navFromChrome);
|
|
8103
|
+
return;
|
|
8104
|
+
}
|
|
7225
8105
|
e.preventDefault();
|
|
7226
8106
|
e.stopPropagation();
|
|
7227
8107
|
return;
|
|
@@ -7236,14 +8116,15 @@ function OhhwellsBridge() {
|
|
|
7236
8116
|
bumpLinkPopoverGrace();
|
|
7237
8117
|
setLinkPopoverRef.current({
|
|
7238
8118
|
key: editable.dataset.ohwKey ?? "",
|
|
7239
|
-
|
|
8119
|
+
mode: "edit",
|
|
8120
|
+
target: getLinkHref2(editable)
|
|
7240
8121
|
});
|
|
7241
8122
|
return;
|
|
7242
8123
|
}
|
|
7243
8124
|
if (isMediaEditable(editable)) {
|
|
7244
8125
|
e.preventDefault();
|
|
7245
8126
|
e.stopPropagation();
|
|
7246
|
-
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
8127
|
+
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
7247
8128
|
return;
|
|
7248
8129
|
}
|
|
7249
8130
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
@@ -7272,6 +8153,13 @@ function OhhwellsBridge() {
|
|
|
7272
8153
|
selectRef.current(hrefAnchor);
|
|
7273
8154
|
return;
|
|
7274
8155
|
}
|
|
8156
|
+
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8157
|
+
if (navContainerToSelect) {
|
|
8158
|
+
e.preventDefault();
|
|
8159
|
+
e.stopPropagation();
|
|
8160
|
+
selectFrameRef.current(navContainerToSelect);
|
|
8161
|
+
return;
|
|
8162
|
+
}
|
|
7275
8163
|
const selectedContainer = selectedElRef.current;
|
|
7276
8164
|
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
7277
8165
|
const navItem = getNavigationItemAnchor(target);
|
|
@@ -7330,8 +8218,24 @@ function OhhwellsBridge() {
|
|
|
7330
8218
|
};
|
|
7331
8219
|
const handleMouseOver = (e) => {
|
|
7332
8220
|
const target = e.target;
|
|
8221
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
8222
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8223
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
8224
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8225
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8226
|
+
hoveredItemElRef.current = null;
|
|
8227
|
+
setHoveredItemRect(null);
|
|
8228
|
+
return;
|
|
8229
|
+
}
|
|
8230
|
+
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8231
|
+
hoveredNavContainerRef.current = null;
|
|
8232
|
+
setHoveredNavContainerRect(null);
|
|
8233
|
+
}
|
|
8234
|
+
}
|
|
7333
8235
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7334
8236
|
if (navAnchor) {
|
|
8237
|
+
hoveredNavContainerRef.current = null;
|
|
8238
|
+
setHoveredNavContainerRect(null);
|
|
7335
8239
|
const selected2 = selectedElRef.current;
|
|
7336
8240
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7337
8241
|
clearHrefKeyHover(navAnchor);
|
|
@@ -7356,6 +8260,14 @@ function OhhwellsBridge() {
|
|
|
7356
8260
|
};
|
|
7357
8261
|
const handleMouseOut = (e) => {
|
|
7358
8262
|
const target = e.target;
|
|
8263
|
+
if (target.closest("[data-ohw-nav-container]")) {
|
|
8264
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8265
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8266
|
+
return;
|
|
8267
|
+
}
|
|
8268
|
+
hoveredNavContainerRef.current = null;
|
|
8269
|
+
setHoveredNavContainerRect(null);
|
|
8270
|
+
}
|
|
7359
8271
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7360
8272
|
if (navAnchor) {
|
|
7361
8273
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -7417,25 +8329,23 @@ function OhhwellsBridge() {
|
|
|
7417
8329
|
}
|
|
7418
8330
|
return { top, left, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
|
|
7419
8331
|
};
|
|
7420
|
-
const
|
|
8332
|
+
const showImageHover = (imgEl, isDragOver = false, forceTextOverlap) => {
|
|
7421
8333
|
const r2 = getVisibleRect(imgEl);
|
|
7422
8334
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
7423
8335
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
7424
8336
|
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
|
|
7425
|
-
|
|
7426
|
-
type: "ow:image-hover",
|
|
8337
|
+
setMediaHover({
|
|
7427
8338
|
key: imgEl.dataset.ohwKey ?? "",
|
|
7428
|
-
// Lets the parent pick the file-picker `accept`, overlay label/icon and drop
|
|
7429
|
-
// mime-check without a parallel ow:video-* message channel.
|
|
7430
|
-
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7431
8339
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
8340
|
+
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7432
8341
|
hasTextOverlap,
|
|
7433
|
-
|
|
7434
|
-
...
|
|
8342
|
+
isDragOver,
|
|
8343
|
+
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
7435
8344
|
});
|
|
7436
8345
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
7437
8346
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
7438
8347
|
};
|
|
8348
|
+
const clearImageHover = () => setMediaHover(null);
|
|
7439
8349
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
7440
8350
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7441
8351
|
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
@@ -7479,47 +8389,91 @@ function OhhwellsBridge() {
|
|
|
7479
8389
|
}
|
|
7480
8390
|
return smallest;
|
|
7481
8391
|
};
|
|
8392
|
+
const dismissImageHover = () => {
|
|
8393
|
+
if (hoveredImageRef.current) {
|
|
8394
|
+
hoveredImageRef.current = null;
|
|
8395
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
8396
|
+
resumeAnimTracks();
|
|
8397
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8398
|
+
}
|
|
8399
|
+
clearImageHover();
|
|
8400
|
+
};
|
|
8401
|
+
const probeNavigationHoverAt = (x, y) => {
|
|
8402
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8403
|
+
hoveredNavContainerRef.current = null;
|
|
8404
|
+
setHoveredNavContainerRect(null);
|
|
8405
|
+
return;
|
|
8406
|
+
}
|
|
8407
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8408
|
+
if (!navContainer) {
|
|
8409
|
+
hoveredNavContainerRef.current = null;
|
|
8410
|
+
setHoveredNavContainerRect(null);
|
|
8411
|
+
return;
|
|
8412
|
+
}
|
|
8413
|
+
const containerRect = navContainer.getBoundingClientRect();
|
|
8414
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8415
|
+
if (!overContainer) {
|
|
8416
|
+
hoveredNavContainerRef.current = null;
|
|
8417
|
+
setHoveredNavContainerRect(null);
|
|
8418
|
+
return;
|
|
8419
|
+
}
|
|
8420
|
+
const navItemHit = Array.from(
|
|
8421
|
+
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8422
|
+
).find((el) => {
|
|
8423
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8424
|
+
const itemRect = el.getBoundingClientRect();
|
|
8425
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8426
|
+
});
|
|
8427
|
+
if (navItemHit) {
|
|
8428
|
+
hoveredNavContainerRef.current = null;
|
|
8429
|
+
setHoveredNavContainerRect(null);
|
|
8430
|
+
const selected = selectedElRef.current;
|
|
8431
|
+
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8432
|
+
clearHrefKeyHover(navItemHit);
|
|
8433
|
+
hoveredItemElRef.current = navItemHit;
|
|
8434
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
8435
|
+
}
|
|
8436
|
+
return;
|
|
8437
|
+
}
|
|
8438
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8439
|
+
setHoveredNavContainerRect(containerRect);
|
|
8440
|
+
hoveredItemElRef.current = null;
|
|
8441
|
+
setHoveredItemRect(null);
|
|
8442
|
+
};
|
|
7482
8443
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
7483
8444
|
if (linkPopoverOpenRef.current) {
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
8445
|
+
dismissImageHover();
|
|
8446
|
+
return;
|
|
8447
|
+
}
|
|
8448
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8449
|
+
if (isPointOverNavigation(x, y)) {
|
|
8450
|
+
dismissImageHover();
|
|
8451
|
+
probeNavigationHoverAt(x, y);
|
|
7490
8452
|
return;
|
|
7491
8453
|
}
|
|
8454
|
+
hoveredNavContainerRef.current = null;
|
|
8455
|
+
setHoveredNavContainerRect(null);
|
|
7492
8456
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7493
8457
|
if (toggleEl) {
|
|
7494
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7495
8458
|
const tr = toggleEl.getBoundingClientRect();
|
|
7496
8459
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
7497
|
-
|
|
7498
|
-
hoveredImageRef.current = null;
|
|
7499
|
-
resumeAnimTracks();
|
|
7500
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7501
|
-
}
|
|
8460
|
+
dismissImageHover();
|
|
7502
8461
|
return;
|
|
7503
8462
|
}
|
|
7504
8463
|
}
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
resumeAnimTracks();
|
|
7510
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7511
|
-
}
|
|
8464
|
+
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
8465
|
+
const activeEl = activeElRef.current;
|
|
8466
|
+
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
8467
|
+
dismissImageHover();
|
|
7512
8468
|
return;
|
|
7513
8469
|
}
|
|
7514
|
-
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
7515
8470
|
if (imgEl) {
|
|
7516
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7517
8471
|
const topEl = document.elementFromPoint(x, y);
|
|
7518
8472
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
7519
8473
|
if (hoveredImageRef.current) {
|
|
7520
8474
|
hoveredImageRef.current = null;
|
|
7521
8475
|
resumeAnimTracks();
|
|
7522
|
-
|
|
8476
|
+
clearImageHover();
|
|
7523
8477
|
}
|
|
7524
8478
|
return;
|
|
7525
8479
|
}
|
|
@@ -7528,7 +8482,7 @@ function OhhwellsBridge() {
|
|
|
7528
8482
|
hoveredImageRef.current = null;
|
|
7529
8483
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7530
8484
|
resumeAnimTracks();
|
|
7531
|
-
|
|
8485
|
+
clearImageHover();
|
|
7532
8486
|
}
|
|
7533
8487
|
return;
|
|
7534
8488
|
}
|
|
@@ -7553,14 +8507,14 @@ function OhhwellsBridge() {
|
|
|
7553
8507
|
hoveredImageRef.current = null;
|
|
7554
8508
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7555
8509
|
resumeAnimTracks();
|
|
7556
|
-
|
|
8510
|
+
clearImageHover();
|
|
7557
8511
|
}
|
|
7558
8512
|
return;
|
|
7559
8513
|
}
|
|
7560
8514
|
if (isStateCardImage) {
|
|
7561
8515
|
if (imgEl !== hoveredImageRef.current || !hoveredImageHasTextOverlapRef.current) {
|
|
7562
8516
|
hoveredImageRef.current = imgEl;
|
|
7563
|
-
|
|
8517
|
+
showImageHover(imgEl, isDragOver, true);
|
|
7564
8518
|
}
|
|
7565
8519
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7566
8520
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -7572,7 +8526,7 @@ function OhhwellsBridge() {
|
|
|
7572
8526
|
hoveredImageRef.current = null;
|
|
7573
8527
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7574
8528
|
resumeAnimTracks();
|
|
7575
|
-
|
|
8529
|
+
clearImageHover();
|
|
7576
8530
|
}
|
|
7577
8531
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7578
8532
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -7584,7 +8538,7 @@ function OhhwellsBridge() {
|
|
|
7584
8538
|
if (hoveredImageRef.current) {
|
|
7585
8539
|
hoveredImageRef.current = null;
|
|
7586
8540
|
resumeAnimTracks();
|
|
7587
|
-
|
|
8541
|
+
clearImageHover();
|
|
7588
8542
|
}
|
|
7589
8543
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7590
8544
|
return;
|
|
@@ -7592,9 +8546,9 @@ function OhhwellsBridge() {
|
|
|
7592
8546
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7593
8547
|
if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
|
|
7594
8548
|
hoveredImageRef.current = imgEl;
|
|
7595
|
-
|
|
8549
|
+
showImageHover(imgEl, isDragOver);
|
|
7596
8550
|
} else if (isDragOver) {
|
|
7597
|
-
|
|
8551
|
+
showImageHover(imgEl, true);
|
|
7598
8552
|
}
|
|
7599
8553
|
} else {
|
|
7600
8554
|
const inIframeView = clientX >= 0 && clientY >= 0 && clientX <= window.innerWidth && clientY <= window.innerHeight;
|
|
@@ -7611,14 +8565,14 @@ function OhhwellsBridge() {
|
|
|
7611
8565
|
hoveredImageRef.current = null;
|
|
7612
8566
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7613
8567
|
resumeAnimTracks();
|
|
7614
|
-
|
|
8568
|
+
clearImageHover();
|
|
7615
8569
|
}
|
|
7616
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8570
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7617
8571
|
const textEl = Array.from(
|
|
7618
8572
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7619
8573
|
).find((el) => {
|
|
7620
8574
|
const er = el.getBoundingClientRect();
|
|
7621
|
-
return
|
|
8575
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7622
8576
|
});
|
|
7623
8577
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7624
8578
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -7724,7 +8678,7 @@ function OhhwellsBridge() {
|
|
|
7724
8678
|
if (hoveredImageRef.current !== el) {
|
|
7725
8679
|
hoveredImageRef.current = el;
|
|
7726
8680
|
const isStateCard = !!el.closest("[data-ohw-editable-state]");
|
|
7727
|
-
|
|
8681
|
+
showImageHover(el, true, isStateCard ? true : void 0);
|
|
7728
8682
|
}
|
|
7729
8683
|
};
|
|
7730
8684
|
const handleDragLeave = (e) => {
|
|
@@ -7732,7 +8686,7 @@ function OhhwellsBridge() {
|
|
|
7732
8686
|
if (imgEl) return;
|
|
7733
8687
|
hoveredImageRef.current = null;
|
|
7734
8688
|
resumeAnimTracks();
|
|
7735
|
-
|
|
8689
|
+
clearImageHover();
|
|
7736
8690
|
};
|
|
7737
8691
|
const handleDrop = (e) => {
|
|
7738
8692
|
e.preventDefault();
|
|
@@ -7756,31 +8710,7 @@ function OhhwellsBridge() {
|
|
|
7756
8710
|
}
|
|
7757
8711
|
hoveredImageRef.current = null;
|
|
7758
8712
|
resumeAnimTracks();
|
|
7759
|
-
|
|
7760
|
-
};
|
|
7761
|
-
const handleVideoSettings = (e) => {
|
|
7762
|
-
if (e.data?.type !== "ow:video-settings") return;
|
|
7763
|
-
const { key, autoplay, muted } = e.data;
|
|
7764
|
-
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7765
|
-
const video = getVideoEl(el);
|
|
7766
|
-
if (!video) return;
|
|
7767
|
-
if (typeof autoplay === "boolean") video.autoplay = autoplay;
|
|
7768
|
-
if (typeof muted === "boolean") video.muted = muted;
|
|
7769
|
-
syncVideoPlayback(video);
|
|
7770
|
-
postToParentRef.current({
|
|
7771
|
-
type: "ow:change",
|
|
7772
|
-
nodes: [
|
|
7773
|
-
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
7774
|
-
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
7775
|
-
]
|
|
7776
|
-
});
|
|
7777
|
-
postToParentRef.current({
|
|
7778
|
-
type: "ow:video-settings-applied",
|
|
7779
|
-
key,
|
|
7780
|
-
autoplay: video.autoplay,
|
|
7781
|
-
muted: video.muted
|
|
7782
|
-
});
|
|
7783
|
-
});
|
|
8713
|
+
clearImageHover();
|
|
7784
8714
|
};
|
|
7785
8715
|
const handleImageUrl = (e) => {
|
|
7786
8716
|
if (e.data?.type !== "ow:image-url") return;
|
|
@@ -7798,7 +8728,11 @@ function OhhwellsBridge() {
|
|
|
7798
8728
|
}
|
|
7799
8729
|
});
|
|
7800
8730
|
hoveredImageRef.current = null;
|
|
7801
|
-
|
|
8731
|
+
setUploadingRects((prev) => {
|
|
8732
|
+
const entry = prev[key];
|
|
8733
|
+
if (!entry || entry.fadingOut) return prev;
|
|
8734
|
+
return { ...prev, [key]: { ...entry, fadingOut: true } };
|
|
8735
|
+
});
|
|
7802
8736
|
};
|
|
7803
8737
|
let found = false;
|
|
7804
8738
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -7935,6 +8869,8 @@ function OhhwellsBridge() {
|
|
|
7935
8869
|
sectionsLoadedRef.current = true;
|
|
7936
8870
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
7937
8871
|
}
|
|
8872
|
+
editContentRef.current = { ...editContentRef.current, ...content };
|
|
8873
|
+
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7938
8874
|
enforceLinkHrefs();
|
|
7939
8875
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
7940
8876
|
};
|
|
@@ -7942,6 +8878,7 @@ function OhhwellsBridge() {
|
|
|
7942
8878
|
const handleDeactivate = (e) => {
|
|
7943
8879
|
if (e.data?.type !== "ow:deactivate") return;
|
|
7944
8880
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
8881
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7945
8882
|
if (linkPopoverOpenRef.current) {
|
|
7946
8883
|
setLinkPopoverRef.current(null);
|
|
7947
8884
|
return;
|
|
@@ -7951,6 +8888,7 @@ function OhhwellsBridge() {
|
|
|
7951
8888
|
};
|
|
7952
8889
|
window.addEventListener("message", handleDeactivate);
|
|
7953
8890
|
const handleKeyDown = (e) => {
|
|
8891
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
7954
8892
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
7955
8893
|
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
7956
8894
|
if (navAnchor) {
|
|
@@ -7965,8 +8903,13 @@ function OhhwellsBridge() {
|
|
|
7965
8903
|
return;
|
|
7966
8904
|
}
|
|
7967
8905
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
8906
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8907
|
+
deselectRef.current();
|
|
8908
|
+
return;
|
|
8909
|
+
}
|
|
7968
8910
|
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
7969
8911
|
if (parent) {
|
|
8912
|
+
e.preventDefault();
|
|
7970
8913
|
selectFrameRef.current(parent);
|
|
7971
8914
|
} else {
|
|
7972
8915
|
deselectRef.current();
|
|
@@ -8028,18 +8971,18 @@ function OhhwellsBridge() {
|
|
|
8028
8971
|
if (hoveredItemElRef.current) {
|
|
8029
8972
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
8030
8973
|
}
|
|
8974
|
+
if (hoveredNavContainerRef.current) {
|
|
8975
|
+
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
8976
|
+
}
|
|
8031
8977
|
if (siblingHintElRef.current) {
|
|
8032
8978
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
8033
8979
|
}
|
|
8034
8980
|
if (hoveredImageRef.current) {
|
|
8035
8981
|
const el = hoveredImageRef.current;
|
|
8036
8982
|
const r2 = el.getBoundingClientRect();
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
8041
|
-
hasTextOverlap: hoveredImageHasTextOverlapRef.current
|
|
8042
|
-
});
|
|
8983
|
+
setMediaHover(
|
|
8984
|
+
(prev) => prev ? { ...prev, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } } : prev
|
|
8985
|
+
);
|
|
8043
8986
|
}
|
|
8044
8987
|
};
|
|
8045
8988
|
const handleSave = (e) => {
|
|
@@ -8128,19 +9071,39 @@ function OhhwellsBridge() {
|
|
|
8128
9071
|
refreshActiveCommandsRef.current = handleSelectionChange;
|
|
8129
9072
|
const handleDocMouseLeave = () => {
|
|
8130
9073
|
hoveredImageRef.current = null;
|
|
9074
|
+
setMediaHover(null);
|
|
8131
9075
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
8132
9076
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8133
9077
|
activeStateElRef.current = null;
|
|
8134
9078
|
setToggleState(null);
|
|
8135
9079
|
};
|
|
8136
|
-
const
|
|
8137
|
-
if (e.data?.type !== "ow:
|
|
8138
|
-
const { key } = e.data;
|
|
9080
|
+
const handleImageUploading = (e) => {
|
|
9081
|
+
if (e.data?.type !== "ow:image-uploading") return;
|
|
9082
|
+
const { key, uploading } = e.data;
|
|
9083
|
+
setUploadingRects((prev) => {
|
|
9084
|
+
if (!uploading) {
|
|
9085
|
+
if (!(key in prev)) return prev;
|
|
9086
|
+
const next = { ...prev };
|
|
9087
|
+
delete next[key];
|
|
9088
|
+
return next;
|
|
9089
|
+
}
|
|
9090
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
9091
|
+
if (!el) return prev;
|
|
9092
|
+
const r2 = getVisibleRect(el);
|
|
9093
|
+
return {
|
|
9094
|
+
...prev,
|
|
9095
|
+
[key]: { rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
9096
|
+
};
|
|
9097
|
+
});
|
|
8139
9098
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8140
9099
|
const track = el.closest("[data-ohw-hover-pause]");
|
|
8141
|
-
if (track)
|
|
9100
|
+
if (!track) return;
|
|
9101
|
+
if (uploading) {
|
|
8142
9102
|
uploadLockedTracks.add(track);
|
|
8143
9103
|
track.setAttribute("data-ohw-hover-paused", "");
|
|
9104
|
+
} else {
|
|
9105
|
+
uploadLockedTracks.delete(track);
|
|
9106
|
+
track.removeAttribute("data-ohw-hover-paused");
|
|
8144
9107
|
}
|
|
8145
9108
|
});
|
|
8146
9109
|
};
|
|
@@ -8197,7 +9160,7 @@ function OhhwellsBridge() {
|
|
|
8197
9160
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
8198
9161
|
});
|
|
8199
9162
|
if (stateCardImage) {
|
|
8200
|
-
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "" });
|
|
9163
|
+
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
8201
9164
|
return;
|
|
8202
9165
|
}
|
|
8203
9166
|
const textEditable = Array.from(
|
|
@@ -8220,6 +9183,32 @@ function OhhwellsBridge() {
|
|
|
8220
9183
|
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8221
9184
|
return;
|
|
8222
9185
|
}
|
|
9186
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9187
|
+
if (navContainer) {
|
|
9188
|
+
const r2 = navContainer.getBoundingClientRect();
|
|
9189
|
+
const pad = 8;
|
|
9190
|
+
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
9191
|
+
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9192
|
+
selectFrameRef.current(navContainer);
|
|
9193
|
+
return;
|
|
9194
|
+
}
|
|
9195
|
+
}
|
|
9196
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
9197
|
+
if (navRoot && navContainer) {
|
|
9198
|
+
const rr = navRoot.getBoundingClientRect();
|
|
9199
|
+
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9200
|
+
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
9201
|
+
if (book) {
|
|
9202
|
+
const br = book.getBoundingClientRect();
|
|
9203
|
+
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
9204
|
+
deactivateRef.current();
|
|
9205
|
+
return;
|
|
9206
|
+
}
|
|
9207
|
+
}
|
|
9208
|
+
selectFrameRef.current(navContainer);
|
|
9209
|
+
return;
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
8223
9212
|
deactivateRef.current();
|
|
8224
9213
|
};
|
|
8225
9214
|
window.addEventListener("message", handleSave);
|
|
@@ -8229,8 +9218,7 @@ function OhhwellsBridge() {
|
|
|
8229
9218
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
8230
9219
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
8231
9220
|
window.addEventListener("message", handleImageUrl);
|
|
8232
|
-
window.addEventListener("message",
|
|
8233
|
-
window.addEventListener("message", handleAnimLock);
|
|
9221
|
+
window.addEventListener("message", handleImageUploading);
|
|
8234
9222
|
window.addEventListener("message", handleCanvasHeight);
|
|
8235
9223
|
window.addEventListener("message", handleParentScroll);
|
|
8236
9224
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -8277,8 +9265,7 @@ function OhhwellsBridge() {
|
|
|
8277
9265
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
8278
9266
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
8279
9267
|
window.removeEventListener("message", handleImageUrl);
|
|
8280
|
-
window.removeEventListener("message",
|
|
8281
|
-
window.removeEventListener("message", handleAnimLock);
|
|
9268
|
+
window.removeEventListener("message", handleImageUploading);
|
|
8282
9269
|
window.removeEventListener("message", handleCanvasHeight);
|
|
8283
9270
|
window.removeEventListener("message", handleParentScroll);
|
|
8284
9271
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -8292,7 +9279,7 @@ function OhhwellsBridge() {
|
|
|
8292
9279
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
8293
9280
|
};
|
|
8294
9281
|
}, [isEditMode, refreshStateRules]);
|
|
8295
|
-
(0,
|
|
9282
|
+
(0, import_react8.useEffect)(() => {
|
|
8296
9283
|
const handler = (e) => {
|
|
8297
9284
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
8298
9285
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -8308,7 +9295,7 @@ function OhhwellsBridge() {
|
|
|
8308
9295
|
window.addEventListener("message", handler);
|
|
8309
9296
|
return () => window.removeEventListener("message", handler);
|
|
8310
9297
|
}, [processConfigRequest]);
|
|
8311
|
-
(0,
|
|
9298
|
+
(0, import_react8.useEffect)(() => {
|
|
8312
9299
|
if (!isEditMode) return;
|
|
8313
9300
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
8314
9301
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -8329,27 +9316,27 @@ function OhhwellsBridge() {
|
|
|
8329
9316
|
const next = { ...prev, [pathKey]: sections };
|
|
8330
9317
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
8331
9318
|
});
|
|
8332
|
-
|
|
8333
|
-
|
|
9319
|
+
postToParent2({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
9320
|
+
postToParent2({ type: "ow:request-site-pages" });
|
|
8334
9321
|
}, 150);
|
|
8335
9322
|
return () => {
|
|
8336
9323
|
cancelAnimationFrame(raf);
|
|
8337
9324
|
clearTimeout(timer);
|
|
8338
9325
|
};
|
|
8339
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
8340
|
-
(0,
|
|
9326
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9327
|
+
(0, import_react8.useEffect)(() => {
|
|
8341
9328
|
scrollToHashSectionWhenReady();
|
|
8342
9329
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
8343
9330
|
window.addEventListener("hashchange", onHashChange);
|
|
8344
9331
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
8345
9332
|
}, [pathname]);
|
|
8346
|
-
const handleCommand = (0,
|
|
9333
|
+
const handleCommand = (0, import_react8.useCallback)((cmd) => {
|
|
8347
9334
|
document.execCommand(cmd, false);
|
|
8348
9335
|
activeElRef.current?.focus();
|
|
8349
9336
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
8350
9337
|
refreshActiveCommandsRef.current();
|
|
8351
9338
|
}, []);
|
|
8352
|
-
const handleStateChange = (0,
|
|
9339
|
+
const handleStateChange = (0, import_react8.useCallback)((state) => {
|
|
8353
9340
|
if (!activeStateElRef.current) return;
|
|
8354
9341
|
const el = activeStateElRef.current;
|
|
8355
9342
|
if (state === "Default") {
|
|
@@ -8362,18 +9349,22 @@ function OhhwellsBridge() {
|
|
|
8362
9349
|
}
|
|
8363
9350
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
8364
9351
|
}, [deactivate]);
|
|
8365
|
-
const closeLinkPopover = (0,
|
|
8366
|
-
|
|
9352
|
+
const closeLinkPopover = (0, import_react8.useCallback)(() => {
|
|
9353
|
+
addNavAfterAnchorRef.current = null;
|
|
9354
|
+
setLinkPopover(null);
|
|
9355
|
+
}, []);
|
|
9356
|
+
const openLinkPopoverForActive = (0, import_react8.useCallback)(() => {
|
|
8367
9357
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
8368
9358
|
if (!hrefCtx) return;
|
|
8369
9359
|
bumpLinkPopoverGrace();
|
|
8370
9360
|
setLinkPopover({
|
|
8371
9361
|
key: hrefCtx.key,
|
|
8372
|
-
|
|
9362
|
+
mode: "edit",
|
|
9363
|
+
target: getLinkHref2(hrefCtx.anchor)
|
|
8373
9364
|
});
|
|
8374
9365
|
deactivate();
|
|
8375
9366
|
}, [deactivate]);
|
|
8376
|
-
const openLinkPopoverForSelected = (0,
|
|
9367
|
+
const openLinkPopoverForSelected = (0, import_react8.useCallback)(() => {
|
|
8377
9368
|
const anchor = selectedElRef.current;
|
|
8378
9369
|
if (!anchor) return;
|
|
8379
9370
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -8381,29 +9372,133 @@ function OhhwellsBridge() {
|
|
|
8381
9372
|
bumpLinkPopoverGrace();
|
|
8382
9373
|
setLinkPopover({
|
|
8383
9374
|
key,
|
|
8384
|
-
|
|
9375
|
+
mode: "edit",
|
|
9376
|
+
target: getLinkHref2(anchor)
|
|
8385
9377
|
});
|
|
8386
9378
|
deselect();
|
|
8387
9379
|
}, [deselect]);
|
|
8388
|
-
const handleLinkPopoverSubmit = (0,
|
|
9380
|
+
const handleLinkPopoverSubmit = (0, import_react8.useCallback)(
|
|
8389
9381
|
(target) => {
|
|
8390
|
-
|
|
8391
|
-
|
|
9382
|
+
const session = linkPopoverSessionRef.current;
|
|
9383
|
+
if (!session) return;
|
|
9384
|
+
if (session.intent === "add-nav") {
|
|
9385
|
+
const { pageRoute, sectionId } = parseTarget(target);
|
|
9386
|
+
const page = resolvePage(pageRoute, sitePages);
|
|
9387
|
+
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
9388
|
+
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
9389
|
+
const label = section?.label ?? page.title;
|
|
9390
|
+
const afterAnchor = addNavAfterAnchorRef.current;
|
|
9391
|
+
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(target, label, afterAnchor);
|
|
9392
|
+
applyLinkByKey(hrefKey, target);
|
|
9393
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
9394
|
+
el.textContent = label;
|
|
9395
|
+
});
|
|
9396
|
+
const navCount = String(index + 1);
|
|
9397
|
+
const orderJson = JSON.stringify(order);
|
|
9398
|
+
editContentRef.current = {
|
|
9399
|
+
...editContentRef.current,
|
|
9400
|
+
[hrefKey]: target,
|
|
9401
|
+
[labelKey]: label,
|
|
9402
|
+
[NAV_COUNT_KEY]: navCount,
|
|
9403
|
+
[NAV_ORDER_KEY]: orderJson
|
|
9404
|
+
};
|
|
9405
|
+
postToParent2({
|
|
9406
|
+
type: "ow:change",
|
|
9407
|
+
nodes: [
|
|
9408
|
+
{ key: hrefKey, text: target },
|
|
9409
|
+
{ key: labelKey, text: label },
|
|
9410
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
9411
|
+
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
9412
|
+
]
|
|
9413
|
+
});
|
|
9414
|
+
addNavAfterAnchorRef.current = null;
|
|
9415
|
+
setLinkPopover(null);
|
|
9416
|
+
enforceLinkHrefs();
|
|
9417
|
+
requestAnimationFrame(() => {
|
|
9418
|
+
selectRef.current(anchor);
|
|
9419
|
+
});
|
|
9420
|
+
return;
|
|
9421
|
+
}
|
|
9422
|
+
const { key } = session;
|
|
8392
9423
|
applyLinkByKey(key, target);
|
|
8393
|
-
|
|
9424
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
8394
9425
|
setLinkPopover(null);
|
|
8395
9426
|
},
|
|
8396
|
-
[
|
|
9427
|
+
[postToParent2, sitePages, sectionsByPath]
|
|
8397
9428
|
);
|
|
8398
9429
|
const showEditLink = toolbarShowEditLink;
|
|
8399
9430
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8400
9431
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
|
|
9432
|
+
const handleMediaReplace = (0, import_react8.useCallback)(
|
|
9433
|
+
(key) => {
|
|
9434
|
+
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
9435
|
+
},
|
|
9436
|
+
[postToParent2, mediaHover?.elementType]
|
|
9437
|
+
);
|
|
9438
|
+
const handleVideoSettingsChange = (0, import_react8.useCallback)(
|
|
9439
|
+
(key, settings) => {
|
|
9440
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9441
|
+
const video = getVideoEl(el);
|
|
9442
|
+
if (!video) return;
|
|
9443
|
+
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
9444
|
+
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
9445
|
+
syncVideoPlayback(video);
|
|
9446
|
+
postToParent2({
|
|
9447
|
+
type: "ow:change",
|
|
9448
|
+
nodes: [
|
|
9449
|
+
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
9450
|
+
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
9451
|
+
]
|
|
9452
|
+
});
|
|
9453
|
+
setMediaHover(
|
|
9454
|
+
(prev) => prev && prev.key === key ? { ...prev, videoAutoplay: video.autoplay, videoMuted: video.muted } : prev
|
|
9455
|
+
);
|
|
9456
|
+
});
|
|
9457
|
+
},
|
|
9458
|
+
[postToParent2]
|
|
9459
|
+
);
|
|
9460
|
+
const handleMediaFadeOutComplete = (0, import_react8.useCallback)((key) => {
|
|
9461
|
+
setUploadingRects((prev) => {
|
|
9462
|
+
if (!(key in prev)) return prev;
|
|
9463
|
+
const next = { ...prev };
|
|
9464
|
+
delete next[key];
|
|
9465
|
+
return next;
|
|
9466
|
+
});
|
|
9467
|
+
}, []);
|
|
9468
|
+
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
9469
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9470
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9471
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9472
|
+
MediaOverlay,
|
|
9473
|
+
{
|
|
9474
|
+
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
9475
|
+
isUploading: true,
|
|
9476
|
+
fadingOut,
|
|
9477
|
+
onFadeOutComplete: handleMediaFadeOutComplete,
|
|
9478
|
+
onReplace: handleMediaReplace
|
|
9479
|
+
},
|
|
9480
|
+
`uploading-${key}`
|
|
9481
|
+
)),
|
|
9482
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9483
|
+
MediaOverlay,
|
|
9484
|
+
{
|
|
9485
|
+
hover: mediaHover,
|
|
9486
|
+
isUploading: false,
|
|
9487
|
+
onReplace: handleMediaReplace,
|
|
9488
|
+
onVideoSettingsChange: handleVideoSettingsChange
|
|
9489
|
+
}
|
|
9490
|
+
),
|
|
9491
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9492
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9493
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9494
|
+
NavbarContainerChrome,
|
|
9495
|
+
{
|
|
9496
|
+
rect: toolbarRect,
|
|
9497
|
+
onAdd: handleAddTopLevelNavItem
|
|
9498
|
+
}
|
|
9499
|
+
),
|
|
9500
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9501
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8407
9502
|
ItemInteractionLayer,
|
|
8408
9503
|
{
|
|
8409
9504
|
rect: toolbarRect,
|
|
@@ -8414,18 +9509,19 @@ function OhhwellsBridge() {
|
|
|
8414
9509
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8415
9510
|
onDragHandleDragStart: handleItemDragStart,
|
|
8416
9511
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
8417
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0,
|
|
9512
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8418
9513
|
ItemActionToolbar,
|
|
8419
9514
|
{
|
|
8420
9515
|
onEditLink: openLinkPopoverForSelected,
|
|
8421
|
-
|
|
8422
|
-
|
|
9516
|
+
addItemDisabled: true,
|
|
9517
|
+
editLinkDisabled: false,
|
|
9518
|
+
moreDisabled: true
|
|
8423
9519
|
}
|
|
8424
9520
|
) : void 0
|
|
8425
9521
|
}
|
|
8426
9522
|
),
|
|
8427
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0,
|
|
8428
|
-
/* @__PURE__ */ (0,
|
|
9523
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9524
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8429
9525
|
EditGlowChrome,
|
|
8430
9526
|
{
|
|
8431
9527
|
rect: toolbarRect,
|
|
@@ -8434,7 +9530,7 @@ function OhhwellsBridge() {
|
|
|
8434
9530
|
dragDisabled: reorderDragDisabled
|
|
8435
9531
|
}
|
|
8436
9532
|
),
|
|
8437
|
-
/* @__PURE__ */ (0,
|
|
9533
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8438
9534
|
FloatingToolbar,
|
|
8439
9535
|
{
|
|
8440
9536
|
rect: toolbarRect,
|
|
@@ -8447,7 +9543,7 @@ function OhhwellsBridge() {
|
|
|
8447
9543
|
}
|
|
8448
9544
|
)
|
|
8449
9545
|
] }),
|
|
8450
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
9546
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8451
9547
|
"div",
|
|
8452
9548
|
{
|
|
8453
9549
|
"data-ohw-max-badge": "",
|
|
@@ -8473,7 +9569,7 @@ function OhhwellsBridge() {
|
|
|
8473
9569
|
]
|
|
8474
9570
|
}
|
|
8475
9571
|
),
|
|
8476
|
-
toggleState && /* @__PURE__ */ (0,
|
|
9572
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8477
9573
|
StateToggle,
|
|
8478
9574
|
{
|
|
8479
9575
|
rect: toggleState.rect,
|
|
@@ -8482,15 +9578,15 @@ function OhhwellsBridge() {
|
|
|
8482
9578
|
onStateChange: handleStateChange
|
|
8483
9579
|
}
|
|
8484
9580
|
),
|
|
8485
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
9581
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8486
9582
|
"div",
|
|
8487
9583
|
{
|
|
8488
9584
|
"data-ohw-section-insert-line": "",
|
|
8489
9585
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8490
9586
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8491
9587
|
children: [
|
|
8492
|
-
/* @__PURE__ */ (0,
|
|
8493
|
-
/* @__PURE__ */ (0,
|
|
9588
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9589
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8494
9590
|
Badge,
|
|
8495
9591
|
{
|
|
8496
9592
|
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",
|
|
@@ -8503,35 +9599,36 @@ function OhhwellsBridge() {
|
|
|
8503
9599
|
children: "Add Section"
|
|
8504
9600
|
}
|
|
8505
9601
|
),
|
|
8506
|
-
/* @__PURE__ */ (0,
|
|
9602
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8507
9603
|
]
|
|
8508
9604
|
}
|
|
8509
9605
|
),
|
|
8510
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
9606
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8511
9607
|
LinkPopover,
|
|
8512
9608
|
{
|
|
8513
9609
|
panelRef: linkPopoverPanelRef,
|
|
8514
9610
|
portalContainer: dialogPortalContainer,
|
|
8515
9611
|
open: true,
|
|
8516
|
-
mode: "edit",
|
|
9612
|
+
mode: linkPopover.mode ?? "edit",
|
|
8517
9613
|
pages: sitePages,
|
|
8518
9614
|
sections: currentSections,
|
|
8519
9615
|
sectionsByPath,
|
|
8520
9616
|
initialTarget: linkPopover.target,
|
|
9617
|
+
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
8521
9618
|
onClose: closeLinkPopover,
|
|
8522
9619
|
onSubmit: handleLinkPopoverSubmit
|
|
8523
9620
|
},
|
|
8524
|
-
|
|
9621
|
+
linkPopover.key
|
|
8525
9622
|
) : null,
|
|
8526
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
9623
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8527
9624
|
"div",
|
|
8528
9625
|
{
|
|
8529
9626
|
"data-ohw-section-insert-line": "",
|
|
8530
9627
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8531
9628
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8532
9629
|
children: [
|
|
8533
|
-
/* @__PURE__ */ (0,
|
|
8534
|
-
/* @__PURE__ */ (0,
|
|
9630
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9631
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8535
9632
|
Badge,
|
|
8536
9633
|
{
|
|
8537
9634
|
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",
|
|
@@ -8544,7 +9641,7 @@ function OhhwellsBridge() {
|
|
|
8544
9641
|
children: "Add Section"
|
|
8545
9642
|
}
|
|
8546
9643
|
),
|
|
8547
|
-
/* @__PURE__ */ (0,
|
|
9644
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8548
9645
|
]
|
|
8549
9646
|
}
|
|
8550
9647
|
)
|