@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.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import
|
|
4
|
+
import React9, { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState6 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -10,6 +10,9 @@ var linkHrefStore = /* @__PURE__ */ new Map();
|
|
|
10
10
|
function setStoredLinkHref(key, href) {
|
|
11
11
|
linkHrefStore.set(key, href);
|
|
12
12
|
}
|
|
13
|
+
function getStoredLinkHref(key) {
|
|
14
|
+
return linkHrefStore.get(key);
|
|
15
|
+
}
|
|
13
16
|
function enforceLinkHrefs() {
|
|
14
17
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
15
18
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -4397,6 +4400,7 @@ function ItemActionToolbar({
|
|
|
4397
4400
|
onEditLink,
|
|
4398
4401
|
onAddItem,
|
|
4399
4402
|
onMore,
|
|
4403
|
+
editLinkDisabled = false,
|
|
4400
4404
|
addItemDisabled = true,
|
|
4401
4405
|
moreDisabled = true,
|
|
4402
4406
|
tooltipSide = "bottom"
|
|
@@ -4407,8 +4411,10 @@ function ItemActionToolbar({
|
|
|
4407
4411
|
{
|
|
4408
4412
|
label: "Edit link",
|
|
4409
4413
|
side: tooltipSide,
|
|
4414
|
+
disabled: editLinkDisabled,
|
|
4410
4415
|
buttonProps: {
|
|
4411
4416
|
onMouseDown: (e) => {
|
|
4417
|
+
if (editLinkDisabled) return;
|
|
4412
4418
|
e.preventDefault();
|
|
4413
4419
|
e.stopPropagation();
|
|
4414
4420
|
onEditLink?.();
|
|
@@ -4580,9 +4586,223 @@ function ItemInteractionLayer({
|
|
|
4580
4586
|
);
|
|
4581
4587
|
}
|
|
4582
4588
|
|
|
4589
|
+
// src/ui/MediaOverlay.tsx
|
|
4590
|
+
import * as React6 from "react";
|
|
4591
|
+
import { Film, ImageIcon, Pause, Play, Volume2, VolumeX } from "lucide-react";
|
|
4592
|
+
|
|
4593
|
+
// src/ui/button.tsx
|
|
4594
|
+
import * as React5 from "react";
|
|
4595
|
+
import { Slot } from "radix-ui";
|
|
4596
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
4597
|
+
var buttonVariants = cva(
|
|
4598
|
+
"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",
|
|
4599
|
+
{
|
|
4600
|
+
variants: {
|
|
4601
|
+
variant: {
|
|
4602
|
+
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
4603
|
+
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
4604
|
+
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
4605
|
+
},
|
|
4606
|
+
size: {
|
|
4607
|
+
default: "h-9",
|
|
4608
|
+
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
4609
|
+
}
|
|
4610
|
+
},
|
|
4611
|
+
defaultVariants: {
|
|
4612
|
+
variant: "default",
|
|
4613
|
+
size: "default"
|
|
4614
|
+
}
|
|
4615
|
+
}
|
|
4616
|
+
);
|
|
4617
|
+
var Button = React5.forwardRef(
|
|
4618
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4619
|
+
const Comp = asChild ? Slot.Root : "button";
|
|
4620
|
+
return /* @__PURE__ */ jsx10(
|
|
4621
|
+
Comp,
|
|
4622
|
+
{
|
|
4623
|
+
ref,
|
|
4624
|
+
"data-slot": "button",
|
|
4625
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
4626
|
+
...props
|
|
4627
|
+
}
|
|
4628
|
+
);
|
|
4629
|
+
}
|
|
4630
|
+
);
|
|
4631
|
+
Button.displayName = "Button";
|
|
4632
|
+
|
|
4633
|
+
// src/ui/MediaOverlay.tsx
|
|
4634
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4635
|
+
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
4636
|
+
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
4637
|
+
var OVERLAY_BUTTON_STYLE = {
|
|
4638
|
+
pointerEvents: "auto",
|
|
4639
|
+
fontFamily: "Inter, sans-serif",
|
|
4640
|
+
fontSize: 12,
|
|
4641
|
+
color: "#000"
|
|
4642
|
+
};
|
|
4643
|
+
var SKELETON_CSS = `
|
|
4644
|
+
@keyframes ohw-media-shimmer {
|
|
4645
|
+
0% { transform: translateX(-100%); }
|
|
4646
|
+
100% { transform: translateX(100%); }
|
|
4647
|
+
}
|
|
4648
|
+
[data-ohw-media-skeleton] {
|
|
4649
|
+
overflow: hidden;
|
|
4650
|
+
background-color: #d1d5db; /* tailwind gray-300 */
|
|
4651
|
+
}
|
|
4652
|
+
[data-ohw-media-skeleton]::after {
|
|
4653
|
+
content: "";
|
|
4654
|
+
position: absolute;
|
|
4655
|
+
inset: 0;
|
|
4656
|
+
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
|
|
4657
|
+
animation: ohw-media-shimmer 1.4s infinite;
|
|
4658
|
+
}
|
|
4659
|
+
`;
|
|
4660
|
+
function MediaOverlay({
|
|
4661
|
+
hover,
|
|
4662
|
+
isUploading,
|
|
4663
|
+
fadingOut = false,
|
|
4664
|
+
onFadeOutComplete,
|
|
4665
|
+
onReplace,
|
|
4666
|
+
onVideoSettingsChange
|
|
4667
|
+
}) {
|
|
4668
|
+
const { rect } = hover;
|
|
4669
|
+
const skeletonRef = React6.useRef(null);
|
|
4670
|
+
const isVideo = hover.elementType === "video";
|
|
4671
|
+
const autoplay = hover.videoAutoplay ?? true;
|
|
4672
|
+
const muted = hover.videoMuted ?? true;
|
|
4673
|
+
const box = {
|
|
4674
|
+
position: "fixed",
|
|
4675
|
+
top: rect.top,
|
|
4676
|
+
left: rect.left,
|
|
4677
|
+
width: rect.width,
|
|
4678
|
+
height: rect.height,
|
|
4679
|
+
zIndex: 2147483646
|
|
4680
|
+
};
|
|
4681
|
+
React6.useEffect(() => {
|
|
4682
|
+
if (!isUploading || !fadingOut || !skeletonRef.current) return;
|
|
4683
|
+
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
4684
|
+
duration: MEDIA_UPLOAD_FADE_MS,
|
|
4685
|
+
easing: "ease-out",
|
|
4686
|
+
fill: "forwards"
|
|
4687
|
+
});
|
|
4688
|
+
anim.finished.then(() => onFadeOutComplete?.(hover.key)).catch(() => onFadeOutComplete?.(hover.key));
|
|
4689
|
+
return () => anim.cancel();
|
|
4690
|
+
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
4691
|
+
if (isUploading) {
|
|
4692
|
+
return /* @__PURE__ */ jsx11(
|
|
4693
|
+
"div",
|
|
4694
|
+
{
|
|
4695
|
+
ref: skeletonRef,
|
|
4696
|
+
"data-ohw-bridge": "",
|
|
4697
|
+
"data-ohw-media-overlay": "",
|
|
4698
|
+
"data-ohw-media-skeleton": "",
|
|
4699
|
+
"aria-hidden": true,
|
|
4700
|
+
style: { ...box, pointerEvents: "none" },
|
|
4701
|
+
children: /* @__PURE__ */ jsx11("style", { children: SKELETON_CSS })
|
|
4702
|
+
}
|
|
4703
|
+
);
|
|
4704
|
+
}
|
|
4705
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ jsxs5(
|
|
4706
|
+
"div",
|
|
4707
|
+
{
|
|
4708
|
+
"data-ohw-bridge": "",
|
|
4709
|
+
"data-ohw-media-overlay": "",
|
|
4710
|
+
className: "flex items-center justify-center gap-1.5",
|
|
4711
|
+
style: {
|
|
4712
|
+
position: "fixed",
|
|
4713
|
+
top: rect.top + VIDEO_SETTINGS_BAR_INSET,
|
|
4714
|
+
left: rect.left,
|
|
4715
|
+
width: rect.width,
|
|
4716
|
+
zIndex: 2147483647,
|
|
4717
|
+
pointerEvents: "auto"
|
|
4718
|
+
},
|
|
4719
|
+
onClick: (e) => e.stopPropagation(),
|
|
4720
|
+
children: [
|
|
4721
|
+
/* @__PURE__ */ jsx11(
|
|
4722
|
+
Button,
|
|
4723
|
+
{
|
|
4724
|
+
"data-ohw-media-overlay": "",
|
|
4725
|
+
variant: "outline",
|
|
4726
|
+
size: "sm",
|
|
4727
|
+
className: "cursor-pointer hover:bg-background",
|
|
4728
|
+
style: { ...OVERLAY_BUTTON_STYLE, minWidth: 0, padding: "0 8px" },
|
|
4729
|
+
"aria-label": autoplay ? "Disable autoplay" : "Enable autoplay",
|
|
4730
|
+
title: autoplay ? "Autoplay on \u2014 click to disable" : "Autoplay off \u2014 click to enable",
|
|
4731
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4732
|
+
onClick: (e) => {
|
|
4733
|
+
e.stopPropagation();
|
|
4734
|
+
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
4735
|
+
},
|
|
4736
|
+
children: autoplay ? /* @__PURE__ */ jsx11(Pause, { size: 14 }) : /* @__PURE__ */ jsx11(Play, { size: 14 })
|
|
4737
|
+
}
|
|
4738
|
+
),
|
|
4739
|
+
/* @__PURE__ */ jsx11(
|
|
4740
|
+
Button,
|
|
4741
|
+
{
|
|
4742
|
+
"data-ohw-media-overlay": "",
|
|
4743
|
+
variant: "outline",
|
|
4744
|
+
size: "sm",
|
|
4745
|
+
className: "cursor-pointer hover:bg-background",
|
|
4746
|
+
style: { ...OVERLAY_BUTTON_STYLE, minWidth: 0, padding: "0 8px" },
|
|
4747
|
+
"aria-label": muted ? "Unmute video" : "Mute video",
|
|
4748
|
+
title: muted ? "Muted \u2014 click to unmute" : "Sound on \u2014 click to mute",
|
|
4749
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4750
|
+
onClick: (e) => {
|
|
4751
|
+
e.stopPropagation();
|
|
4752
|
+
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
4753
|
+
},
|
|
4754
|
+
children: muted ? /* @__PURE__ */ jsx11(VolumeX, { size: 14 }) : /* @__PURE__ */ jsx11(Volume2, { size: 14 })
|
|
4755
|
+
}
|
|
4756
|
+
)
|
|
4757
|
+
]
|
|
4758
|
+
}
|
|
4759
|
+
) : null;
|
|
4760
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
4761
|
+
settingsBar,
|
|
4762
|
+
/* @__PURE__ */ jsx11(
|
|
4763
|
+
"div",
|
|
4764
|
+
{
|
|
4765
|
+
"data-ohw-bridge": "",
|
|
4766
|
+
"data-ohw-media-overlay": "",
|
|
4767
|
+
className: "flex items-center justify-center cursor-pointer",
|
|
4768
|
+
style: {
|
|
4769
|
+
...box,
|
|
4770
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
4771
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
4772
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
4773
|
+
// Replace still works.
|
|
4774
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4775
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4776
|
+
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4777
|
+
},
|
|
4778
|
+
onClick: () => onReplace(hover.key),
|
|
4779
|
+
children: /* @__PURE__ */ jsxs5(
|
|
4780
|
+
Button,
|
|
4781
|
+
{
|
|
4782
|
+
"data-ohw-media-overlay": "",
|
|
4783
|
+
variant: "outline",
|
|
4784
|
+
size: "sm",
|
|
4785
|
+
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4786
|
+
style: OVERLAY_BUTTON_STYLE,
|
|
4787
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4788
|
+
onClick: (e) => {
|
|
4789
|
+
e.stopPropagation();
|
|
4790
|
+
onReplace(hover.key);
|
|
4791
|
+
},
|
|
4792
|
+
children: [
|
|
4793
|
+
isVideo ? /* @__PURE__ */ jsx11(Film, { size: 14 }) : /* @__PURE__ */ jsx11(ImageIcon, { size: 14 }),
|
|
4794
|
+
isVideo ? "Replace video" : "Replace image"
|
|
4795
|
+
]
|
|
4796
|
+
}
|
|
4797
|
+
)
|
|
4798
|
+
}
|
|
4799
|
+
)
|
|
4800
|
+
] });
|
|
4801
|
+
}
|
|
4802
|
+
|
|
4583
4803
|
// src/OhhwellsBridge.tsx
|
|
4584
|
-
import { createPortal } from "react-dom";
|
|
4585
|
-
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
4804
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
4805
|
+
import { usePathname as usePathname2, useRouter as useRouter2, useSearchParams } from "next/navigation";
|
|
4586
4806
|
|
|
4587
4807
|
// src/lib/session-search.ts
|
|
4588
4808
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -4858,61 +5078,29 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
4858
5078
|
tick();
|
|
4859
5079
|
}
|
|
4860
5080
|
|
|
4861
|
-
// src/ui/
|
|
4862
|
-
import
|
|
4863
|
-
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
4864
|
-
|
|
4865
|
-
// src/ui/icons.tsx
|
|
4866
|
-
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4867
|
-
function IconX({ className, ...props }) {
|
|
4868
|
-
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4869
|
-
/* @__PURE__ */ jsx10("path", { d: "M18 6 6 18" }),
|
|
4870
|
-
/* @__PURE__ */ jsx10("path", { d: "m6 6 12 12" })
|
|
4871
|
-
] });
|
|
4872
|
-
}
|
|
4873
|
-
function IconChevronDown({ className, ...props }) {
|
|
4874
|
-
return /* @__PURE__ */ jsx10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ jsx10("path", { d: "m6 9 6 6 6-6" }) });
|
|
4875
|
-
}
|
|
4876
|
-
function IconFile({ className, ...props }) {
|
|
4877
|
-
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4878
|
-
/* @__PURE__ */ jsx10("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
4879
|
-
/* @__PURE__ */ jsx10("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4880
|
-
] });
|
|
4881
|
-
}
|
|
4882
|
-
function IconInfo({ className, ...props }) {
|
|
4883
|
-
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4884
|
-
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4885
|
-
/* @__PURE__ */ jsx10("path", { d: "M12 16v-4" }),
|
|
4886
|
-
/* @__PURE__ */ jsx10("path", { d: "M12 8h.01" })
|
|
4887
|
-
] });
|
|
4888
|
-
}
|
|
4889
|
-
function IconArrowRight({ className, ...props }) {
|
|
4890
|
-
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4891
|
-
/* @__PURE__ */ jsx10("path", { d: "M5 12h14" }),
|
|
4892
|
-
/* @__PURE__ */ jsx10("path", { d: "m12 5 7 7-7 7" })
|
|
4893
|
-
] });
|
|
4894
|
-
}
|
|
4895
|
-
function IconSection({ className, ...props }) {
|
|
4896
|
-
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4897
|
-
/* @__PURE__ */ jsx10("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4898
|
-
/* @__PURE__ */ jsx10("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4899
|
-
/* @__PURE__ */ jsx10("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4900
|
-
] });
|
|
4901
|
-
}
|
|
5081
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5082
|
+
import { useEffect as useEffect6 } from "react";
|
|
4902
5083
|
|
|
4903
5084
|
// src/ui/dialog.tsx
|
|
4904
|
-
import
|
|
4905
|
-
|
|
4906
|
-
|
|
5085
|
+
import * as React7 from "react";
|
|
5086
|
+
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
5087
|
+
import { X } from "lucide-react";
|
|
5088
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5089
|
+
function Dialog2({
|
|
5090
|
+
...props
|
|
5091
|
+
}) {
|
|
5092
|
+
return /* @__PURE__ */ jsx12(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
4907
5093
|
}
|
|
4908
|
-
function DialogPortal({
|
|
4909
|
-
|
|
5094
|
+
function DialogPortal({
|
|
5095
|
+
...props
|
|
5096
|
+
}) {
|
|
5097
|
+
return /* @__PURE__ */ jsx12(DialogPrimitive.Portal, { ...props });
|
|
4910
5098
|
}
|
|
4911
5099
|
function DialogOverlay({
|
|
4912
5100
|
className,
|
|
4913
5101
|
...props
|
|
4914
5102
|
}) {
|
|
4915
|
-
return /* @__PURE__ */
|
|
5103
|
+
return /* @__PURE__ */ jsx12(
|
|
4916
5104
|
DialogPrimitive.Overlay,
|
|
4917
5105
|
{
|
|
4918
5106
|
"data-slot": "dialog-overlay",
|
|
@@ -4922,57 +5110,74 @@ function DialogOverlay({
|
|
|
4922
5110
|
}
|
|
4923
5111
|
);
|
|
4924
5112
|
}
|
|
4925
|
-
var DialogContent =
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
/* @__PURE__ */
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
children
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
});
|
|
5113
|
+
var DialogContent = React7.forwardRef(
|
|
5114
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5115
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5116
|
+
return /* @__PURE__ */ jsxs6(DialogPortal, { container: container ?? void 0, children: [
|
|
5117
|
+
/* @__PURE__ */ jsx12(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5118
|
+
/* @__PURE__ */ jsxs6(
|
|
5119
|
+
DialogPrimitive.Content,
|
|
5120
|
+
{
|
|
5121
|
+
ref,
|
|
5122
|
+
"data-slot": "dialog-content",
|
|
5123
|
+
className: cn(
|
|
5124
|
+
positionMode,
|
|
5125
|
+
"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",
|
|
5126
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5127
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
5128
|
+
className
|
|
5129
|
+
),
|
|
5130
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5131
|
+
...props,
|
|
5132
|
+
children: [
|
|
5133
|
+
children,
|
|
5134
|
+
showCloseButton ? /* @__PURE__ */ jsx12(
|
|
5135
|
+
DialogPrimitive.Close,
|
|
5136
|
+
{
|
|
5137
|
+
type: "button",
|
|
5138
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5139
|
+
"aria-label": "Close",
|
|
5140
|
+
children: /* @__PURE__ */ jsx12(X, { size: 16, "aria-hidden": true })
|
|
5141
|
+
}
|
|
5142
|
+
) : null
|
|
5143
|
+
]
|
|
5144
|
+
}
|
|
5145
|
+
)
|
|
5146
|
+
] });
|
|
5147
|
+
}
|
|
5148
|
+
);
|
|
4959
5149
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
4960
|
-
function DialogHeader({
|
|
4961
|
-
|
|
5150
|
+
function DialogHeader({
|
|
5151
|
+
className,
|
|
5152
|
+
...props
|
|
5153
|
+
}) {
|
|
5154
|
+
return /* @__PURE__ */ jsx12("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
4962
5155
|
}
|
|
4963
|
-
function DialogFooter({
|
|
4964
|
-
|
|
5156
|
+
function DialogFooter({
|
|
5157
|
+
className,
|
|
5158
|
+
...props
|
|
5159
|
+
}) {
|
|
5160
|
+
return /* @__PURE__ */ jsx12(
|
|
5161
|
+
"div",
|
|
5162
|
+
{
|
|
5163
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
5164
|
+
...props
|
|
5165
|
+
}
|
|
5166
|
+
);
|
|
4965
5167
|
}
|
|
4966
|
-
var DialogTitle =
|
|
5168
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
4967
5169
|
DialogPrimitive.Title,
|
|
4968
5170
|
{
|
|
4969
5171
|
ref,
|
|
4970
|
-
className: cn(
|
|
5172
|
+
className: cn(
|
|
5173
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5174
|
+
className
|
|
5175
|
+
),
|
|
4971
5176
|
...props
|
|
4972
5177
|
}
|
|
4973
5178
|
));
|
|
4974
5179
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
4975
|
-
var DialogDescription =
|
|
5180
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
4976
5181
|
DialogPrimitive.Description,
|
|
4977
5182
|
{
|
|
4978
5183
|
ref,
|
|
@@ -4983,59 +5188,40 @@ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
4983
5188
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
4984
5189
|
var DialogClose = DialogPrimitive.Close;
|
|
4985
5190
|
|
|
4986
|
-
// src/ui/
|
|
4987
|
-
import
|
|
4988
|
-
import { Slot } from "radix-ui";
|
|
4989
|
-
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
4990
|
-
var buttonVariants = cva(
|
|
4991
|
-
"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",
|
|
4992
|
-
{
|
|
4993
|
-
variants: {
|
|
4994
|
-
variant: {
|
|
4995
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
4996
|
-
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
4997
|
-
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
4998
|
-
},
|
|
4999
|
-
size: {
|
|
5000
|
-
default: "h-9",
|
|
5001
|
-
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
5002
|
-
}
|
|
5003
|
-
},
|
|
5004
|
-
defaultVariants: {
|
|
5005
|
-
variant: "default",
|
|
5006
|
-
size: "default"
|
|
5007
|
-
}
|
|
5008
|
-
}
|
|
5009
|
-
);
|
|
5010
|
-
var Button = React6.forwardRef(
|
|
5011
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
5012
|
-
const Comp = asChild ? Slot.Root : "button";
|
|
5013
|
-
return /* @__PURE__ */ jsx12(
|
|
5014
|
-
Comp,
|
|
5015
|
-
{
|
|
5016
|
-
ref,
|
|
5017
|
-
"data-slot": "button",
|
|
5018
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
5019
|
-
...props
|
|
5020
|
-
}
|
|
5021
|
-
);
|
|
5022
|
-
}
|
|
5023
|
-
);
|
|
5024
|
-
Button.displayName = "Button";
|
|
5191
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5192
|
+
import { Info, X as X3 } from "lucide-react";
|
|
5025
5193
|
|
|
5026
5194
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5195
|
+
import { ArrowRight, File, GalleryVertical } from "lucide-react";
|
|
5027
5196
|
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5028
|
-
function DestinationBreadcrumb({
|
|
5197
|
+
function DestinationBreadcrumb({
|
|
5198
|
+
pageTitle,
|
|
5199
|
+
sectionLabel
|
|
5200
|
+
}) {
|
|
5029
5201
|
return /* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5030
|
-
/* @__PURE__ */ jsx13("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5202
|
+
/* @__PURE__ */ jsx13("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5031
5203
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
5032
5204
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
5033
|
-
/* @__PURE__ */ jsx13(
|
|
5034
|
-
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5205
|
+
/* @__PURE__ */ jsx13(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5206
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5035
5207
|
] }),
|
|
5036
|
-
/* @__PURE__ */ jsx13(
|
|
5208
|
+
/* @__PURE__ */ jsx13(
|
|
5209
|
+
ArrowRight,
|
|
5210
|
+
{
|
|
5211
|
+
size: 16,
|
|
5212
|
+
className: "shrink-0 text-muted-foreground",
|
|
5213
|
+
"aria-hidden": true
|
|
5214
|
+
}
|
|
5215
|
+
),
|
|
5037
5216
|
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5038
|
-
/* @__PURE__ */ jsx13(
|
|
5217
|
+
/* @__PURE__ */ jsx13(
|
|
5218
|
+
GalleryVertical,
|
|
5219
|
+
{
|
|
5220
|
+
size: 16,
|
|
5221
|
+
className: "shrink-0 text-foreground",
|
|
5222
|
+
"aria-hidden": true
|
|
5223
|
+
}
|
|
5224
|
+
),
|
|
5039
5225
|
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5040
5226
|
] })
|
|
5041
5227
|
] })
|
|
@@ -5043,8 +5229,13 @@ function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
|
5043
5229
|
}
|
|
5044
5230
|
|
|
5045
5231
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5232
|
+
import { GalleryVertical as GalleryVertical2 } from "lucide-react";
|
|
5046
5233
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5047
|
-
function SectionTreeItem({
|
|
5234
|
+
function SectionTreeItem({
|
|
5235
|
+
section,
|
|
5236
|
+
onSelect,
|
|
5237
|
+
selected
|
|
5238
|
+
}) {
|
|
5048
5239
|
const interactive = Boolean(onSelect);
|
|
5049
5240
|
return /* @__PURE__ */ jsxs8("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5050
5241
|
/* @__PURE__ */ jsx14(
|
|
@@ -5072,30 +5263,28 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
5072
5263
|
interactive && selected && "border-primary"
|
|
5073
5264
|
),
|
|
5074
5265
|
children: [
|
|
5075
|
-
/* @__PURE__ */ jsx14(
|
|
5266
|
+
/* @__PURE__ */ jsx14(
|
|
5267
|
+
GalleryVertical2,
|
|
5268
|
+
{
|
|
5269
|
+
size: 16,
|
|
5270
|
+
className: "shrink-0 text-foreground",
|
|
5271
|
+
"aria-hidden": true
|
|
5272
|
+
}
|
|
5273
|
+
),
|
|
5076
5274
|
/* @__PURE__ */ jsx14("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5077
5275
|
]
|
|
5078
5276
|
}
|
|
5079
5277
|
)
|
|
5080
5278
|
] });
|
|
5081
5279
|
}
|
|
5082
|
-
function SectionPickerList({ sections, onSelect }) {
|
|
5083
|
-
if (sections.length === 0) {
|
|
5084
|
-
return /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5085
|
-
}
|
|
5086
|
-
return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1", children: [
|
|
5087
|
-
/* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5088
|
-
sections.map((section) => /* @__PURE__ */ jsx14(SectionTreeItem, { section, onSelect }, section.id))
|
|
5089
|
-
] });
|
|
5090
|
-
}
|
|
5091
5280
|
|
|
5092
5281
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5093
|
-
import { useId as useId2, useRef as
|
|
5282
|
+
import { useEffect as useEffect3, useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
5094
5283
|
|
|
5095
5284
|
// src/ui/input.tsx
|
|
5096
|
-
import * as
|
|
5285
|
+
import * as React8 from "react";
|
|
5097
5286
|
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
5098
|
-
var Input =
|
|
5287
|
+
var Input = React8.forwardRef(
|
|
5099
5288
|
({ className, type, ...props }, ref) => {
|
|
5100
5289
|
return /* @__PURE__ */ jsx15(
|
|
5101
5290
|
"input",
|
|
@@ -5129,8 +5318,11 @@ function Label({ className, ...props }) {
|
|
|
5129
5318
|
}
|
|
5130
5319
|
|
|
5131
5320
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5321
|
+
import { ChevronDown, File as File2, X as X2 } from "lucide-react";
|
|
5132
5322
|
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5133
|
-
function FieldChevron({
|
|
5323
|
+
function FieldChevron({
|
|
5324
|
+
onClick
|
|
5325
|
+
}) {
|
|
5134
5326
|
return /* @__PURE__ */ jsx17(
|
|
5135
5327
|
"button",
|
|
5136
5328
|
{
|
|
@@ -5139,7 +5331,7 @@ function FieldChevron({ onClick }) {
|
|
|
5139
5331
|
onClick,
|
|
5140
5332
|
"aria-label": "Open page list",
|
|
5141
5333
|
tabIndex: -1,
|
|
5142
|
-
children: /* @__PURE__ */ jsx17(
|
|
5334
|
+
children: /* @__PURE__ */ jsx17(ChevronDown, { size: 16 })
|
|
5143
5335
|
}
|
|
5144
5336
|
);
|
|
5145
5337
|
}
|
|
@@ -5156,8 +5348,30 @@ function UrlOrPageInput({
|
|
|
5156
5348
|
urlError
|
|
5157
5349
|
}) {
|
|
5158
5350
|
const inputId = useId2();
|
|
5159
|
-
const inputRef =
|
|
5351
|
+
const inputRef = useRef3(null);
|
|
5352
|
+
const rootRef = useRef3(null);
|
|
5160
5353
|
const [isFocused, setIsFocused] = useState3(false);
|
|
5354
|
+
useEffect3(() => {
|
|
5355
|
+
if (!dropdownOpen) return;
|
|
5356
|
+
const isOutside = (e) => {
|
|
5357
|
+
const root = rootRef.current;
|
|
5358
|
+
if (!root) return true;
|
|
5359
|
+
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5360
|
+
if (path.includes(root)) return false;
|
|
5361
|
+
const target = e.target;
|
|
5362
|
+
return !(target instanceof Node && root.contains(target));
|
|
5363
|
+
};
|
|
5364
|
+
const closeIfOutside = (e) => {
|
|
5365
|
+
if (!isOutside(e)) return;
|
|
5366
|
+
onDropdownOpenChange(false);
|
|
5367
|
+
};
|
|
5368
|
+
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5369
|
+
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5370
|
+
return () => {
|
|
5371
|
+
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5372
|
+
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5373
|
+
};
|
|
5374
|
+
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5161
5375
|
const openDropdown = () => {
|
|
5162
5376
|
if (readOnly || filteredPages.length === 0) return;
|
|
5163
5377
|
onDropdownOpenChange(true);
|
|
@@ -5180,9 +5394,16 @@ function UrlOrPageInput({
|
|
|
5180
5394
|
);
|
|
5181
5395
|
return /* @__PURE__ */ jsxs9("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5182
5396
|
/* @__PURE__ */ jsx17(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5183
|
-
/* @__PURE__ */ jsxs9("div", { className: "relative w-full", children: [
|
|
5397
|
+
/* @__PURE__ */ jsxs9("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5184
5398
|
/* @__PURE__ */ jsxs9("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5185
|
-
selectedPage ? /* @__PURE__ */ jsx17("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx17(
|
|
5399
|
+
selectedPage ? /* @__PURE__ */ jsx17("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx17(
|
|
5400
|
+
File2,
|
|
5401
|
+
{
|
|
5402
|
+
size: 16,
|
|
5403
|
+
className: "shrink-0 text-foreground",
|
|
5404
|
+
"aria-hidden": true
|
|
5405
|
+
}
|
|
5406
|
+
) }) : null,
|
|
5186
5407
|
readOnly ? /* @__PURE__ */ jsx17("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx17(
|
|
5187
5408
|
Input,
|
|
5188
5409
|
{
|
|
@@ -5194,7 +5415,14 @@ function UrlOrPageInput({
|
|
|
5194
5415
|
setIsFocused(true);
|
|
5195
5416
|
if (!selectedPage) openDropdown();
|
|
5196
5417
|
},
|
|
5197
|
-
onBlur: () =>
|
|
5418
|
+
onBlur: () => {
|
|
5419
|
+
setIsFocused(false);
|
|
5420
|
+
requestAnimationFrame(() => {
|
|
5421
|
+
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5422
|
+
onDropdownOpenChange(false);
|
|
5423
|
+
}
|
|
5424
|
+
});
|
|
5425
|
+
},
|
|
5198
5426
|
placeholder,
|
|
5199
5427
|
className: cn(
|
|
5200
5428
|
"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",
|
|
@@ -5210,7 +5438,7 @@ function UrlOrPageInput({
|
|
|
5210
5438
|
onMouseDown: clearSelection,
|
|
5211
5439
|
"aria-label": "Clear selected page",
|
|
5212
5440
|
tabIndex: -1,
|
|
5213
|
-
children: /* @__PURE__ */ jsx17(
|
|
5441
|
+
children: /* @__PURE__ */ jsx17(X2, { size: 16, "aria-hidden": true })
|
|
5214
5442
|
}
|
|
5215
5443
|
) : null,
|
|
5216
5444
|
!readOnly ? /* @__PURE__ */ jsx17(FieldChevron, { onClick: toggleDropdown }) : null
|
|
@@ -5219,7 +5447,7 @@ function UrlOrPageInput({
|
|
|
5219
5447
|
"div",
|
|
5220
5448
|
{
|
|
5221
5449
|
"data-ohw-link-page-dropdown": "",
|
|
5222
|
-
className: "absolute left-0 right-0
|
|
5450
|
+
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",
|
|
5223
5451
|
onMouseDown: (e) => e.preventDefault(),
|
|
5224
5452
|
children: filteredPages.map((page) => /* @__PURE__ */ jsxs9(
|
|
5225
5453
|
"button",
|
|
@@ -5228,7 +5456,7 @@ function UrlOrPageInput({
|
|
|
5228
5456
|
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",
|
|
5229
5457
|
onClick: () => onPageSelect(page),
|
|
5230
5458
|
children: [
|
|
5231
|
-
/* @__PURE__ */ jsx17(
|
|
5459
|
+
/* @__PURE__ */ jsx17(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5232
5460
|
/* @__PURE__ */ jsx17("span", { className: "truncate", children: page.title })
|
|
5233
5461
|
]
|
|
5234
5462
|
},
|
|
@@ -5241,65 +5469,402 @@ function UrlOrPageInput({
|
|
|
5241
5469
|
] });
|
|
5242
5470
|
}
|
|
5243
5471
|
|
|
5244
|
-
// src/ui/link-modal/
|
|
5245
|
-
import {
|
|
5246
|
-
function
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
})
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5472
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5473
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5474
|
+
function LinkEditorPanel({ state, onClose }) {
|
|
5475
|
+
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5476
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
5477
|
+
/* @__PURE__ */ jsx18(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx18(
|
|
5478
|
+
"button",
|
|
5479
|
+
{
|
|
5480
|
+
type: "button",
|
|
5481
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5482
|
+
"aria-label": "Close",
|
|
5483
|
+
onClick: onClose,
|
|
5484
|
+
children: /* @__PURE__ */ jsx18(X3, { size: 16, "aria-hidden": true })
|
|
5485
|
+
}
|
|
5486
|
+
) }),
|
|
5487
|
+
/* @__PURE__ */ jsx18(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx18(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5488
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5489
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx18(
|
|
5490
|
+
DestinationBreadcrumb,
|
|
5491
|
+
{
|
|
5492
|
+
pageTitle: state.selectedPage.title,
|
|
5493
|
+
sectionLabel: state.selectedSection.label
|
|
5494
|
+
}
|
|
5495
|
+
) : /* @__PURE__ */ jsx18(
|
|
5496
|
+
UrlOrPageInput,
|
|
5497
|
+
{
|
|
5498
|
+
value: state.searchValue,
|
|
5499
|
+
selectedPage: state.selectedPage,
|
|
5500
|
+
dropdownOpen: state.dropdownOpen,
|
|
5501
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5502
|
+
filteredPages: state.filteredPages,
|
|
5503
|
+
onInputChange: state.handleInputChange,
|
|
5504
|
+
onPageSelect: state.handlePageSelect,
|
|
5505
|
+
urlError: state.urlError
|
|
5506
|
+
}
|
|
5507
|
+
),
|
|
5508
|
+
state.showChooseSection ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5509
|
+
/* @__PURE__ */ jsx18(
|
|
5510
|
+
Button,
|
|
5511
|
+
{
|
|
5512
|
+
type: "button",
|
|
5513
|
+
variant: "outline",
|
|
5514
|
+
className: "w-fit cursor-pointer",
|
|
5515
|
+
size: "sm",
|
|
5516
|
+
onClick: state.handleChooseSection,
|
|
5517
|
+
children: "Choose a section"
|
|
5518
|
+
}
|
|
5519
|
+
),
|
|
5520
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5521
|
+
/* @__PURE__ */ jsx18(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5522
|
+
/* @__PURE__ */ jsx18("span", { children: "Pick a section this link should scroll to." })
|
|
5523
|
+
] })
|
|
5524
|
+
] }) : null,
|
|
5525
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx18(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5526
|
+
] }),
|
|
5527
|
+
/* @__PURE__ */ jsxs10(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5528
|
+
/* @__PURE__ */ jsx18(
|
|
5529
|
+
Button,
|
|
5530
|
+
{
|
|
5531
|
+
type: "button",
|
|
5532
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5533
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5534
|
+
style: isCancel ? {
|
|
5535
|
+
backgroundColor: "var(--ohw-background)",
|
|
5536
|
+
borderColor: "var(--ohw-border)",
|
|
5537
|
+
color: "var(--ohw-foreground)"
|
|
5538
|
+
} : void 0,
|
|
5539
|
+
onClick: state.handleSecondary,
|
|
5540
|
+
children: state.secondaryLabel
|
|
5541
|
+
}
|
|
5542
|
+
),
|
|
5543
|
+
/* @__PURE__ */ jsx18(
|
|
5544
|
+
Button,
|
|
5545
|
+
{
|
|
5546
|
+
type: "button",
|
|
5547
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5548
|
+
style: {
|
|
5549
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5550
|
+
color: "var(--ohw-primary-foreground)"
|
|
5551
|
+
},
|
|
5552
|
+
disabled: !state.isValid,
|
|
5553
|
+
onClick: state.handleSubmit,
|
|
5554
|
+
children: state.submitLabel
|
|
5555
|
+
}
|
|
5556
|
+
)
|
|
5557
|
+
] })
|
|
5558
|
+
] });
|
|
5559
|
+
}
|
|
5560
|
+
|
|
5561
|
+
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5562
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useState as useState4 } from "react";
|
|
5563
|
+
import { createPortal } from "react-dom";
|
|
5564
|
+
import { ArrowLeft, Check } from "lucide-react";
|
|
5565
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
5566
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5567
|
+
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5568
|
+
function rectsEqual(a, b) {
|
|
5569
|
+
if (a.size !== b.size) return false;
|
|
5570
|
+
for (const [id, rect] of a) {
|
|
5571
|
+
const other = b.get(id);
|
|
5572
|
+
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5573
|
+
return false;
|
|
5574
|
+
}
|
|
5575
|
+
}
|
|
5576
|
+
return true;
|
|
5577
|
+
}
|
|
5578
|
+
function useSectionRects(sectionIdsKey, enabled) {
|
|
5579
|
+
const [rects, setRects] = useState4(/* @__PURE__ */ new Map());
|
|
5580
|
+
const sectionIds = useMemo2(
|
|
5581
|
+
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5582
|
+
[sectionIdsKey]
|
|
5583
|
+
);
|
|
5584
|
+
useEffect4(() => {
|
|
5585
|
+
if (!enabled || sectionIds.length === 0) {
|
|
5586
|
+
setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5589
|
+
const update = () => {
|
|
5590
|
+
const next = /* @__PURE__ */ new Map();
|
|
5591
|
+
for (const id of sectionIds) {
|
|
5592
|
+
const el = document.querySelector(
|
|
5593
|
+
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5594
|
+
);
|
|
5595
|
+
if (el) next.set(id, el.getBoundingClientRect());
|
|
5596
|
+
}
|
|
5597
|
+
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5598
|
+
};
|
|
5599
|
+
update();
|
|
5600
|
+
const opts = { capture: true, passive: true };
|
|
5601
|
+
window.addEventListener("scroll", update, opts);
|
|
5602
|
+
window.addEventListener("resize", update);
|
|
5603
|
+
const vv = window.visualViewport;
|
|
5604
|
+
vv?.addEventListener("resize", update);
|
|
5605
|
+
vv?.addEventListener("scroll", update);
|
|
5606
|
+
const ro = new ResizeObserver(update);
|
|
5607
|
+
for (const id of sectionIds) {
|
|
5608
|
+
const el = document.querySelector(
|
|
5609
|
+
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5610
|
+
);
|
|
5611
|
+
if (el) ro.observe(el);
|
|
5612
|
+
}
|
|
5613
|
+
return () => {
|
|
5614
|
+
window.removeEventListener("scroll", update, opts);
|
|
5615
|
+
window.removeEventListener("resize", update);
|
|
5616
|
+
vv?.removeEventListener("resize", update);
|
|
5617
|
+
vv?.removeEventListener("scroll", update);
|
|
5618
|
+
ro.disconnect();
|
|
5619
|
+
};
|
|
5620
|
+
}, [sectionIds, enabled]);
|
|
5621
|
+
return rects;
|
|
5622
|
+
}
|
|
5623
|
+
function SectionPickerOverlay({
|
|
5624
|
+
pagePath,
|
|
5625
|
+
sections,
|
|
5626
|
+
onBack,
|
|
5627
|
+
onSelect
|
|
5628
|
+
}) {
|
|
5629
|
+
const router = useRouter();
|
|
5630
|
+
const pathname = usePathname();
|
|
5631
|
+
const [selectedId, setSelectedId] = useState4(null);
|
|
5632
|
+
const [hoveredId, setHoveredId] = useState4(null);
|
|
5633
|
+
const [chromeClip, setChromeClip] = useState4(
|
|
5634
|
+
() => ({
|
|
5635
|
+
top: 0,
|
|
5636
|
+
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5637
|
+
})
|
|
5638
|
+
);
|
|
5639
|
+
const normalizedTarget = normalizePath(pagePath);
|
|
5640
|
+
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5641
|
+
useEffect4(() => {
|
|
5642
|
+
if (isOnTargetPage) return;
|
|
5643
|
+
const search = readPreservedSearch();
|
|
5644
|
+
router.push(`${normalizedTarget}${search}`);
|
|
5645
|
+
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5646
|
+
useEffect4(() => {
|
|
5647
|
+
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5648
|
+
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5649
|
+
el.removeAttribute("data-ohw-hovered");
|
|
5650
|
+
});
|
|
5651
|
+
return () => {
|
|
5652
|
+
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5653
|
+
};
|
|
5654
|
+
}, []);
|
|
5655
|
+
useEffect4(() => {
|
|
5656
|
+
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5657
|
+
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5658
|
+
const bottom = Math.min(
|
|
5659
|
+
window.innerHeight,
|
|
5660
|
+
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5661
|
+
);
|
|
5662
|
+
setChromeClip(
|
|
5663
|
+
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5664
|
+
);
|
|
5665
|
+
};
|
|
5666
|
+
const onParentScroll = (e) => {
|
|
5667
|
+
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5668
|
+
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5669
|
+
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5670
|
+
};
|
|
5671
|
+
const onResize = () => {
|
|
5672
|
+
setChromeClip((prev) => {
|
|
5673
|
+
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5674
|
+
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5675
|
+
});
|
|
5676
|
+
};
|
|
5677
|
+
window.addEventListener("message", onParentScroll);
|
|
5678
|
+
window.addEventListener("resize", onResize);
|
|
5679
|
+
return () => {
|
|
5680
|
+
window.removeEventListener("message", onParentScroll);
|
|
5681
|
+
window.removeEventListener("resize", onResize);
|
|
5682
|
+
};
|
|
5683
|
+
}, []);
|
|
5684
|
+
const liveSections = useMemo2(() => {
|
|
5685
|
+
if (!isOnTargetPage) return sections;
|
|
5686
|
+
const live = collectSectionsFromDom();
|
|
5687
|
+
if (live.length === 0) return sections;
|
|
5688
|
+
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5689
|
+
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5690
|
+
}, [isOnTargetPage, sections, pathname]);
|
|
5691
|
+
const sectionIdsKey = useMemo2(
|
|
5692
|
+
() => liveSections.map((s) => s.id).join("\0"),
|
|
5693
|
+
[liveSections]
|
|
5694
|
+
);
|
|
5695
|
+
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5696
|
+
const handleSelect = useCallback2(
|
|
5697
|
+
(section) => {
|
|
5698
|
+
if (selectedId) return;
|
|
5699
|
+
setSelectedId(section.id);
|
|
5700
|
+
onSelect(section);
|
|
5701
|
+
},
|
|
5702
|
+
[selectedId, onSelect]
|
|
5703
|
+
);
|
|
5704
|
+
useEffect4(() => {
|
|
5705
|
+
const onKeyDown = (e) => {
|
|
5706
|
+
if (e.key === "Escape") {
|
|
5707
|
+
e.preventDefault();
|
|
5708
|
+
e.stopPropagation();
|
|
5709
|
+
onBack();
|
|
5710
|
+
}
|
|
5711
|
+
};
|
|
5712
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
5713
|
+
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5714
|
+
}, [onBack]);
|
|
5715
|
+
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5716
|
+
if (!portalRoot) return null;
|
|
5717
|
+
return createPortal(
|
|
5718
|
+
/* @__PURE__ */ jsxs11(
|
|
5719
|
+
"div",
|
|
5720
|
+
{
|
|
5721
|
+
"data-ohw-section-picker": "",
|
|
5722
|
+
"data-ohw-bridge": "",
|
|
5723
|
+
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5724
|
+
"aria-modal": true,
|
|
5725
|
+
role: "dialog",
|
|
5726
|
+
"aria-label": "Choose a section",
|
|
5727
|
+
children: [
|
|
5728
|
+
/* @__PURE__ */ jsx19(
|
|
5729
|
+
"div",
|
|
5730
|
+
{
|
|
5731
|
+
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5732
|
+
style: { top: chromeClip.top + 20 },
|
|
5733
|
+
children: /* @__PURE__ */ jsxs11(
|
|
5734
|
+
Button,
|
|
5735
|
+
{
|
|
5736
|
+
type: "button",
|
|
5737
|
+
variant: "outline",
|
|
5738
|
+
size: "sm",
|
|
5739
|
+
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5740
|
+
onClick: onBack,
|
|
5741
|
+
children: [
|
|
5742
|
+
/* @__PURE__ */ jsx19(ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5743
|
+
"Back"
|
|
5744
|
+
]
|
|
5745
|
+
}
|
|
5746
|
+
)
|
|
5747
|
+
}
|
|
5748
|
+
),
|
|
5749
|
+
/* @__PURE__ */ jsx19(
|
|
5750
|
+
"div",
|
|
5751
|
+
{
|
|
5752
|
+
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",
|
|
5753
|
+
style: {
|
|
5754
|
+
top: chromeClip.bottom - 20,
|
|
5755
|
+
transform: "translate(-50%, -100%)",
|
|
5756
|
+
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5757
|
+
},
|
|
5758
|
+
"data-ohw-section-picker-hint": "",
|
|
5759
|
+
children: "Click on section to select"
|
|
5760
|
+
}
|
|
5761
|
+
),
|
|
5762
|
+
!isOnTargetPage ? /* @__PURE__ */ jsx19(
|
|
5763
|
+
"div",
|
|
5764
|
+
{
|
|
5765
|
+
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",
|
|
5766
|
+
style: { top: chromeClip.top + 64 },
|
|
5767
|
+
children: "Loading page preview\u2026"
|
|
5768
|
+
}
|
|
5769
|
+
) : null,
|
|
5770
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx19("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5771
|
+
isOnTargetPage ? liveSections.map((section) => {
|
|
5772
|
+
const rect = rects.get(section.id);
|
|
5773
|
+
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5774
|
+
const isSelected = selectedId === section.id;
|
|
5775
|
+
const isLit = isSelected || hoveredId === section.id;
|
|
5776
|
+
return /* @__PURE__ */ jsx19(
|
|
5777
|
+
"button",
|
|
5778
|
+
{
|
|
5779
|
+
type: "button",
|
|
5780
|
+
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5781
|
+
style: {
|
|
5782
|
+
top: rect.top,
|
|
5783
|
+
left: rect.left,
|
|
5784
|
+
width: rect.width,
|
|
5785
|
+
height: rect.height,
|
|
5786
|
+
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
5787
|
+
},
|
|
5788
|
+
"aria-label": `Select section ${section.label}`,
|
|
5789
|
+
onMouseEnter: () => setHoveredId(section.id),
|
|
5790
|
+
onMouseLeave: () => setHoveredId((prev) => prev === section.id ? null : prev),
|
|
5791
|
+
onClick: () => handleSelect(section),
|
|
5792
|
+
children: isSelected ? /* @__PURE__ */ jsx19(
|
|
5793
|
+
"span",
|
|
5794
|
+
{
|
|
5795
|
+
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5796
|
+
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5797
|
+
"aria-hidden": true,
|
|
5798
|
+
children: /* @__PURE__ */ jsx19(Check, { className: "size-5" })
|
|
5799
|
+
}
|
|
5800
|
+
) : null
|
|
5801
|
+
},
|
|
5802
|
+
section.id
|
|
5803
|
+
);
|
|
5804
|
+
}) : null
|
|
5805
|
+
]
|
|
5806
|
+
}
|
|
5807
|
+
),
|
|
5808
|
+
portalRoot
|
|
5809
|
+
);
|
|
5810
|
+
}
|
|
5811
|
+
|
|
5812
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5813
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
5814
|
+
function useLinkModalState({
|
|
5815
|
+
open,
|
|
5816
|
+
mode,
|
|
5817
|
+
pages,
|
|
5818
|
+
sections: _sections,
|
|
5819
|
+
sectionsByPath,
|
|
5820
|
+
initialTarget,
|
|
5821
|
+
existingTargets: _existingTargets,
|
|
5822
|
+
onClose,
|
|
5823
|
+
onSubmit
|
|
5824
|
+
}) {
|
|
5825
|
+
const availablePages = useMemo3(() => pages, [pages]);
|
|
5826
|
+
const [searchValue, setSearchValue] = useState5("");
|
|
5827
|
+
const [selectedPage, setSelectedPage] = useState5(null);
|
|
5828
|
+
const [selectedSection, setSelectedSection] = useState5(null);
|
|
5829
|
+
const [step, setStep] = useState5("input");
|
|
5830
|
+
const [dropdownOpen, setDropdownOpen] = useState5(false);
|
|
5831
|
+
const [urlError, setUrlError] = useState5("");
|
|
5832
|
+
const reset = useCallback3(() => {
|
|
5833
|
+
setSearchValue("");
|
|
5834
|
+
setSelectedPage(null);
|
|
5835
|
+
setSelectedSection(null);
|
|
5836
|
+
setStep("input");
|
|
5837
|
+
setDropdownOpen(false);
|
|
5838
|
+
setUrlError("");
|
|
5839
|
+
}, []);
|
|
5840
|
+
useEffect5(() => {
|
|
5841
|
+
if (!open) return;
|
|
5842
|
+
if (mode === "edit" && initialTarget) {
|
|
5843
|
+
const { pageRoute } = parseTarget(initialTarget);
|
|
5844
|
+
const targetSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
5845
|
+
const init = getEditModeInitialState(initialTarget, pages, targetSections);
|
|
5846
|
+
setSearchValue(init.searchValue);
|
|
5847
|
+
setSelectedPage(init.selectedPage);
|
|
5848
|
+
setSelectedSection(init.selectedSection);
|
|
5849
|
+
setStep(init.step);
|
|
5850
|
+
} else {
|
|
5851
|
+
reset();
|
|
5852
|
+
}
|
|
5853
|
+
setDropdownOpen(false);
|
|
5854
|
+
setUrlError("");
|
|
5855
|
+
}, [open, mode, initialTarget, reset]);
|
|
5856
|
+
const filteredPages = useMemo3(() => {
|
|
5857
|
+
if (!searchValue.trim()) return availablePages;
|
|
5858
|
+
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
5859
|
+
}, [availablePages, searchValue]);
|
|
5860
|
+
const activeSections = useMemo3(() => {
|
|
5861
|
+
if (!selectedPage) return [];
|
|
5862
|
+
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
5863
|
+
}, [selectedPage, sectionsByPath]);
|
|
5864
|
+
const showBreadcrumb = step === "confirmed" && selectedPage && selectedSection;
|
|
5865
|
+
const showSectionPicker = step === "sectionPicker" && selectedPage;
|
|
5866
|
+
const showSectionRow = mode === "edit" && selectedPage && selectedSection && step === "input";
|
|
5867
|
+
const showChooseSection = step === "input" && selectedPage && !selectedSection && !showSectionRow && activeSections.length > 0;
|
|
5303
5868
|
const handleInputChange = (value) => {
|
|
5304
5869
|
setSearchValue(value);
|
|
5305
5870
|
setSelectedPage(null);
|
|
@@ -5334,11 +5899,14 @@ function useLinkModalState({
|
|
|
5334
5899
|
const handleBackToSections = () => {
|
|
5335
5900
|
setStep("sectionPicker");
|
|
5336
5901
|
};
|
|
5902
|
+
const handleSectionPickerBack = () => {
|
|
5903
|
+
setStep("input");
|
|
5904
|
+
};
|
|
5337
5905
|
const handleClose = () => {
|
|
5338
5906
|
reset();
|
|
5339
5907
|
onClose();
|
|
5340
5908
|
};
|
|
5341
|
-
const isValid =
|
|
5909
|
+
const isValid = useMemo3(() => {
|
|
5342
5910
|
if (urlError) return false;
|
|
5343
5911
|
if (showBreadcrumb) return true;
|
|
5344
5912
|
if (selectedPage) return true;
|
|
@@ -5371,7 +5939,7 @@ function useLinkModalState({
|
|
|
5371
5939
|
onSubmit(normalizeUrl(searchValue));
|
|
5372
5940
|
handleClose();
|
|
5373
5941
|
};
|
|
5374
|
-
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
5942
|
+
const submitLabel = showBreadcrumb ? "Save" : mode === "edit" ? "Save" : "Create";
|
|
5375
5943
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
5376
5944
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
5377
5945
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -5398,23 +5966,29 @@ function useLinkModalState({
|
|
|
5398
5966
|
handleChooseSection,
|
|
5399
5967
|
handleSectionSelect,
|
|
5400
5968
|
handleBackToSections,
|
|
5969
|
+
handleSectionPickerBack,
|
|
5401
5970
|
handleClose,
|
|
5402
5971
|
handleSecondary,
|
|
5403
5972
|
handleSubmit
|
|
5404
5973
|
};
|
|
5405
5974
|
}
|
|
5406
5975
|
|
|
5407
|
-
// src/ui/link-modal/
|
|
5408
|
-
import { Fragment as
|
|
5409
|
-
function
|
|
5976
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5977
|
+
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5978
|
+
function postToParent(data) {
|
|
5979
|
+
window.parent?.postMessage(data, "*");
|
|
5980
|
+
}
|
|
5981
|
+
function LinkPopover({
|
|
5410
5982
|
open = true,
|
|
5983
|
+
panelRef,
|
|
5984
|
+
portalContainer,
|
|
5985
|
+
onClose,
|
|
5411
5986
|
mode = "create",
|
|
5412
5987
|
pages,
|
|
5413
5988
|
sections = [],
|
|
5414
5989
|
sectionsByPath,
|
|
5415
5990
|
initialTarget,
|
|
5416
5991
|
existingTargets = [],
|
|
5417
|
-
onClose,
|
|
5418
5992
|
onSubmit
|
|
5419
5993
|
}) {
|
|
5420
5994
|
const state = useLinkModalState({
|
|
@@ -5428,175 +6002,440 @@ function LinkEditorPanel({
|
|
|
5428
6002
|
onClose,
|
|
5429
6003
|
onSubmit
|
|
5430
6004
|
});
|
|
5431
|
-
const
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
6005
|
+
const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
|
|
6006
|
+
useEffect6(() => {
|
|
6007
|
+
if (!open) return;
|
|
6008
|
+
if (sectionPickerActive) {
|
|
6009
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6010
|
+
postToParent({ type: "ow:section-picker", active: true });
|
|
6011
|
+
document.documentElement.style.overflow = "";
|
|
6012
|
+
document.body.style.overflow = "";
|
|
6013
|
+
return () => {
|
|
6014
|
+
postToParent({ type: "ow:section-picker", active: false });
|
|
6015
|
+
};
|
|
6016
|
+
}
|
|
6017
|
+
postToParent({ type: "ow:section-picker", active: false });
|
|
6018
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6019
|
+
const html = document.documentElement;
|
|
6020
|
+
const body = document.body;
|
|
6021
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6022
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6023
|
+
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6024
|
+
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6025
|
+
html.style.overflow = "hidden";
|
|
6026
|
+
body.style.overflow = "hidden";
|
|
6027
|
+
html.style.overscrollBehavior = "none";
|
|
6028
|
+
body.style.overscrollBehavior = "none";
|
|
6029
|
+
const canScrollElement = (el, deltaY) => {
|
|
6030
|
+
const { overflowY } = getComputedStyle(el);
|
|
6031
|
+
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6032
|
+
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6033
|
+
if (deltaY < 0) return el.scrollTop > 0;
|
|
6034
|
+
if (deltaY > 0) return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6035
|
+
return true;
|
|
6036
|
+
};
|
|
6037
|
+
const allowsInternalScroll = (e) => {
|
|
6038
|
+
const target = e.target;
|
|
6039
|
+
if (!(target instanceof Element)) return false;
|
|
6040
|
+
const scrollRoot = target.closest(
|
|
6041
|
+
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6042
|
+
);
|
|
6043
|
+
if (!scrollRoot) return false;
|
|
6044
|
+
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6045
|
+
return canScrollElement(scrollRoot, deltaY);
|
|
6046
|
+
};
|
|
6047
|
+
const preventBackgroundScroll = (e) => {
|
|
6048
|
+
if (allowsInternalScroll(e)) return;
|
|
6049
|
+
e.preventDefault();
|
|
6050
|
+
};
|
|
6051
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6052
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6053
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6054
|
+
return () => {
|
|
6055
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6056
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6057
|
+
body.style.overflow = prevBodyOverflow;
|
|
6058
|
+
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6059
|
+
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6060
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6061
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6062
|
+
};
|
|
6063
|
+
}, [open, sectionPickerActive]);
|
|
6064
|
+
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
6065
|
+
/* @__PURE__ */ jsx20(
|
|
6066
|
+
Dialog2,
|
|
5435
6067
|
{
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
6068
|
+
open: open && !sectionPickerActive,
|
|
6069
|
+
onOpenChange: (next) => {
|
|
6070
|
+
if (!next) onClose?.();
|
|
6071
|
+
},
|
|
6072
|
+
children: /* @__PURE__ */ jsx20(
|
|
6073
|
+
DialogContent,
|
|
6074
|
+
{
|
|
6075
|
+
ref: panelRef,
|
|
6076
|
+
container: portalContainer,
|
|
6077
|
+
"data-ohw-link-popover-root": "",
|
|
6078
|
+
"data-ohw-link-modal-root": "",
|
|
6079
|
+
"data-ohw-bridge": "",
|
|
6080
|
+
showCloseButton: false,
|
|
6081
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto z-[2147483646] overflow-visible",
|
|
6082
|
+
children: /* @__PURE__ */ jsx20(LinkEditorPanel, { state, onClose })
|
|
6083
|
+
}
|
|
6084
|
+
)
|
|
5440
6085
|
}
|
|
5441
|
-
)
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
UrlOrPageInput,
|
|
5452
|
-
{
|
|
5453
|
-
value: state.searchValue,
|
|
5454
|
-
selectedPage: state.selectedPage,
|
|
5455
|
-
dropdownOpen: state.dropdownOpen,
|
|
5456
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5457
|
-
filteredPages: state.filteredPages,
|
|
5458
|
-
onInputChange: state.handleInputChange,
|
|
5459
|
-
onPageSelect: state.handlePageSelect,
|
|
5460
|
-
urlError: state.urlError
|
|
5461
|
-
}
|
|
5462
|
-
),
|
|
5463
|
-
state.showChooseSection ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5464
|
-
/* @__PURE__ */ jsx18(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5465
|
-
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5466
|
-
/* @__PURE__ */ jsx18(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5467
|
-
/* @__PURE__ */ jsx18("span", { children: "Pick a section this link should scroll to." })
|
|
5468
|
-
] })
|
|
5469
|
-
] }) : null,
|
|
5470
|
-
state.showSectionPicker ? /* @__PURE__ */ jsx18(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5471
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx18(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5472
|
-
] }),
|
|
5473
|
-
/* @__PURE__ */ jsxs10(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5474
|
-
/* @__PURE__ */ jsx18(
|
|
5475
|
-
Button,
|
|
5476
|
-
{
|
|
5477
|
-
type: "button",
|
|
5478
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5479
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5480
|
-
style: isCancel ? {
|
|
5481
|
-
backgroundColor: "var(--ohw-background)",
|
|
5482
|
-
borderColor: "var(--ohw-border)",
|
|
5483
|
-
color: "var(--ohw-foreground)"
|
|
5484
|
-
} : void 0,
|
|
5485
|
-
onClick: state.handleSecondary,
|
|
5486
|
-
children: state.secondaryLabel
|
|
5487
|
-
}
|
|
5488
|
-
),
|
|
5489
|
-
/* @__PURE__ */ jsx18(
|
|
5490
|
-
Button,
|
|
5491
|
-
{
|
|
5492
|
-
type: "button",
|
|
5493
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5494
|
-
style: {
|
|
5495
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5496
|
-
color: "var(--ohw-primary-foreground)"
|
|
5497
|
-
},
|
|
5498
|
-
disabled: !state.isValid,
|
|
5499
|
-
onClick: state.handleSubmit,
|
|
5500
|
-
children: state.submitLabel
|
|
5501
|
-
}
|
|
5502
|
-
)
|
|
5503
|
-
] })
|
|
6086
|
+
),
|
|
6087
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx20(
|
|
6088
|
+
SectionPickerOverlay,
|
|
6089
|
+
{
|
|
6090
|
+
pagePath: state.selectedPage.path,
|
|
6091
|
+
sections: state.activeSections,
|
|
6092
|
+
onBack: state.handleSectionPickerBack,
|
|
6093
|
+
onSelect: state.handleSectionSelect
|
|
6094
|
+
}
|
|
6095
|
+
) : null
|
|
5504
6096
|
] });
|
|
5505
6097
|
}
|
|
5506
6098
|
|
|
5507
|
-
// src/ui/link-modal/
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
6099
|
+
// src/ui/link-modal/devFixtures.ts
|
|
6100
|
+
var DEV_SITE_PAGES = [
|
|
6101
|
+
{ path: "/", title: "Home" },
|
|
6102
|
+
{ path: "/about", title: "About" },
|
|
6103
|
+
{ path: "/classes", title: "Classes" },
|
|
6104
|
+
{ path: "/pricing", title: "Pricing" },
|
|
6105
|
+
{ path: "/studio", title: "Studio" },
|
|
6106
|
+
{ path: "/instructors", title: "Instructors" },
|
|
6107
|
+
{ path: "/contact", title: "Contact" }
|
|
6108
|
+
];
|
|
6109
|
+
var DEV_SECTIONS_BY_PATH = {
|
|
6110
|
+
"/": [
|
|
6111
|
+
{ id: "hero", label: "Hero" },
|
|
6112
|
+
{ id: "lagree-intro", label: "Lagree Intro" },
|
|
6113
|
+
{ id: "classes-strip", label: "Classes" },
|
|
6114
|
+
{ id: "feel-split", label: "Feel Split" },
|
|
6115
|
+
{ id: "founder-teaser", label: "Founder" },
|
|
6116
|
+
{ id: "plan-form", label: "Plan Form" },
|
|
6117
|
+
{ id: "testimonials", label: "Testimonials" },
|
|
6118
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6119
|
+
{ id: "footer", label: "Footer" }
|
|
6120
|
+
],
|
|
6121
|
+
"/about": [
|
|
6122
|
+
{ id: "manifesto", label: "Manifesto" },
|
|
6123
|
+
{ id: "story-letter", label: "Our Story" },
|
|
6124
|
+
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
6125
|
+
{ id: "waitlist-cta", label: "Waitlist" },
|
|
6126
|
+
{ id: "personal-training", label: "Personal training" },
|
|
6127
|
+
{ id: "footer", label: "Footer" }
|
|
6128
|
+
],
|
|
6129
|
+
"/classes": [
|
|
6130
|
+
{ id: "class-library", label: "Class Library" },
|
|
6131
|
+
{ id: "footer", label: "Footer" }
|
|
6132
|
+
],
|
|
6133
|
+
"/pricing": [
|
|
6134
|
+
{ id: "page-header", label: "Page Header" },
|
|
6135
|
+
{ id: "free-class-cta", label: "Free Class" },
|
|
6136
|
+
{ id: "benefits-marquee", label: "Benefits" },
|
|
6137
|
+
{ id: "monthly-memberships", label: "Memberships" },
|
|
6138
|
+
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
6139
|
+
{ id: "package-matcher", label: "Packages" },
|
|
6140
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6141
|
+
{ id: "footer", label: "Footer" }
|
|
6142
|
+
],
|
|
6143
|
+
"/studio": [
|
|
6144
|
+
{ id: "studio-intro", label: "Studio Intro" },
|
|
6145
|
+
{ id: "studio-features", label: "Studio Features" },
|
|
6146
|
+
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
6147
|
+
{ id: "studio-visit", label: "Visit Studio" },
|
|
6148
|
+
{ id: "footer", label: "Footer" }
|
|
6149
|
+
],
|
|
6150
|
+
"/instructors": [
|
|
6151
|
+
{ id: "instructor-grid", label: "Instructors" },
|
|
6152
|
+
{ id: "footer", label: "Footer" }
|
|
6153
|
+
],
|
|
6154
|
+
"/contact": [
|
|
6155
|
+
{ id: "hello-hero", label: "Hello" },
|
|
6156
|
+
{ id: "contact-form", label: "Contact Form" },
|
|
6157
|
+
{ id: "faq", label: "FAQ" },
|
|
6158
|
+
{ id: "footer", label: "Footer" }
|
|
6159
|
+
]
|
|
6160
|
+
};
|
|
6161
|
+
function shouldUseDevFixtures() {
|
|
6162
|
+
if (typeof window === "undefined") return false;
|
|
6163
|
+
const raw = readPreservedSearch();
|
|
6164
|
+
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
6165
|
+
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6166
|
+
}
|
|
6167
|
+
|
|
6168
|
+
// src/lib/nav-items.ts
|
|
6169
|
+
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6170
|
+
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6171
|
+
function getLinkHref(el) {
|
|
6172
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
6173
|
+
if (key) {
|
|
6174
|
+
const stored = getStoredLinkHref(key);
|
|
6175
|
+
if (stored !== void 0) return stored;
|
|
6176
|
+
}
|
|
6177
|
+
return el.getAttribute("href") ?? "";
|
|
6178
|
+
}
|
|
6179
|
+
function isNavbarButton(el) {
|
|
6180
|
+
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6181
|
+
}
|
|
6182
|
+
function isNavbarLinkItem(el) {
|
|
6183
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6184
|
+
if (isNavbarButton(el)) return false;
|
|
6185
|
+
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6186
|
+
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6187
|
+
}
|
|
6188
|
+
function getNavbarDesktopContainer() {
|
|
6189
|
+
return document.querySelector("[data-ohw-nav-container]");
|
|
6190
|
+
}
|
|
6191
|
+
function getNavbarDrawerContainer() {
|
|
6192
|
+
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6193
|
+
}
|
|
6194
|
+
function listNavbarItems() {
|
|
6195
|
+
const desktop = getNavbarDesktopContainer();
|
|
6196
|
+
if (desktop) {
|
|
6197
|
+
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6198
|
+
}
|
|
6199
|
+
const drawer = getNavbarDrawerContainer();
|
|
6200
|
+
if (drawer) {
|
|
6201
|
+
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6202
|
+
}
|
|
6203
|
+
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6204
|
+
}
|
|
6205
|
+
function parseNavIndexFromKey(key) {
|
|
6206
|
+
if (!key) return null;
|
|
6207
|
+
const match = key.match(/^nav-(\d+)-href$/);
|
|
6208
|
+
if (!match) return null;
|
|
6209
|
+
return parseInt(match[1], 10);
|
|
6210
|
+
}
|
|
6211
|
+
function getNavbarIndicesInDom() {
|
|
6212
|
+
const indices = /* @__PURE__ */ new Set();
|
|
6213
|
+
for (const item of listNavbarItems()) {
|
|
6214
|
+
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6215
|
+
if (idx !== null) indices.add(idx);
|
|
6216
|
+
}
|
|
6217
|
+
return [...indices].sort((a, b) => a - b);
|
|
6218
|
+
}
|
|
6219
|
+
function getNextNavbarIndex() {
|
|
6220
|
+
const indices = getNavbarIndicesInDom();
|
|
6221
|
+
if (indices.length === 0) return 0;
|
|
6222
|
+
return Math.max(...indices) + 1;
|
|
6223
|
+
}
|
|
6224
|
+
function getNavbarExistingTargets() {
|
|
6225
|
+
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6226
|
+
}
|
|
6227
|
+
function getNavOrderFromDom() {
|
|
6228
|
+
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6229
|
+
}
|
|
6230
|
+
function parseNavOrder(content) {
|
|
6231
|
+
const raw = content[NAV_ORDER_KEY];
|
|
6232
|
+
if (!raw) return null;
|
|
6233
|
+
try {
|
|
6234
|
+
const parsed = JSON.parse(raw);
|
|
6235
|
+
if (!Array.isArray(parsed)) return null;
|
|
6236
|
+
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6237
|
+
} catch {
|
|
6238
|
+
return null;
|
|
6239
|
+
}
|
|
6240
|
+
}
|
|
6241
|
+
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6242
|
+
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6243
|
+
}
|
|
6244
|
+
function cloneNavLinkShell(template) {
|
|
6245
|
+
const anchor = document.createElement("a");
|
|
6246
|
+
if (template) {
|
|
6247
|
+
anchor.style.cssText = template.style.cssText;
|
|
6248
|
+
if (template.className) anchor.className = template.className;
|
|
6249
|
+
}
|
|
6250
|
+
anchor.style.cursor = "pointer";
|
|
6251
|
+
anchor.style.textDecoration = "none";
|
|
6252
|
+
return anchor;
|
|
6253
|
+
}
|
|
6254
|
+
function buildNavLink(index, href, label, template) {
|
|
6255
|
+
const anchor = cloneNavLinkShell(template);
|
|
6256
|
+
anchor.href = href;
|
|
6257
|
+
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6258
|
+
const span = document.createElement("span");
|
|
6259
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
6260
|
+
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6261
|
+
span.textContent = label;
|
|
6262
|
+
anchor.appendChild(span);
|
|
6263
|
+
return anchor;
|
|
6264
|
+
}
|
|
6265
|
+
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6266
|
+
if (!afterHrefKey) {
|
|
6267
|
+
container.appendChild(anchor);
|
|
6268
|
+
return;
|
|
6269
|
+
}
|
|
6270
|
+
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6271
|
+
if (afterEl?.parentElement === container) {
|
|
6272
|
+
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6273
|
+
return;
|
|
6274
|
+
}
|
|
6275
|
+
container.appendChild(anchor);
|
|
6276
|
+
}
|
|
6277
|
+
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6278
|
+
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6279
|
+
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6280
|
+
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6281
|
+
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6282
|
+
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6283
|
+
let primary = null;
|
|
6284
|
+
const desktopContainer = getNavbarDesktopContainer();
|
|
6285
|
+
if (desktopContainer) {
|
|
6286
|
+
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6287
|
+
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6288
|
+
primary = desktopAnchor;
|
|
6289
|
+
}
|
|
6290
|
+
const drawerContainer = getNavbarDrawerContainer();
|
|
6291
|
+
if (drawerContainer) {
|
|
6292
|
+
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6293
|
+
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6294
|
+
if (!primary) primary = drawerAnchor;
|
|
6295
|
+
}
|
|
6296
|
+
if (!primary) {
|
|
6297
|
+
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6298
|
+
const nav = document.querySelector("nav");
|
|
6299
|
+
nav?.appendChild(fallback);
|
|
6300
|
+
primary = fallback;
|
|
6301
|
+
}
|
|
6302
|
+
return primary;
|
|
6303
|
+
}
|
|
6304
|
+
function applyNavOrderToContainer(container, order) {
|
|
6305
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6306
|
+
for (const hrefKey of order) {
|
|
6307
|
+
if (seen.has(hrefKey)) continue;
|
|
6308
|
+
seen.add(hrefKey);
|
|
6309
|
+
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6310
|
+
if (el) container.appendChild(el);
|
|
6311
|
+
}
|
|
6312
|
+
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6313
|
+
if (!isNavbarLinkItem(el)) continue;
|
|
6314
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
6315
|
+
if (!key || seen.has(key)) continue;
|
|
6316
|
+
container.appendChild(el);
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6319
|
+
function applyNavOrder(order) {
|
|
6320
|
+
const desktop = getNavbarDesktopContainer();
|
|
6321
|
+
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6322
|
+
const drawer = getNavbarDrawerContainer();
|
|
6323
|
+
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6324
|
+
}
|
|
6325
|
+
function collectNavbarIndicesFromContent(content) {
|
|
6326
|
+
const indices = /* @__PURE__ */ new Set();
|
|
6327
|
+
for (const key of Object.keys(content)) {
|
|
6328
|
+
const idx = parseNavIndexFromKey(key);
|
|
6329
|
+
if (idx !== null) indices.add(idx);
|
|
6330
|
+
}
|
|
6331
|
+
const countRaw = content[NAV_COUNT_KEY];
|
|
6332
|
+
if (countRaw) {
|
|
6333
|
+
const count = parseInt(countRaw, 10);
|
|
6334
|
+
if (Number.isFinite(count) && count > 0) {
|
|
6335
|
+
for (let i = 0; i < count; i++) indices.add(i);
|
|
6336
|
+
}
|
|
6337
|
+
}
|
|
6338
|
+
return [...indices].sort((a, b) => a - b);
|
|
6339
|
+
}
|
|
6340
|
+
function navbarIndexExistsInDom(index) {
|
|
6341
|
+
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6342
|
+
}
|
|
6343
|
+
function reconcileNavbarItemsFromContent(content) {
|
|
6344
|
+
const indices = collectNavbarIndicesFromContent(content);
|
|
6345
|
+
for (const index of indices) {
|
|
6346
|
+
if (navbarIndexExistsInDom(index)) continue;
|
|
6347
|
+
const href = content[`nav-${index}-href`];
|
|
6348
|
+
const label = content[`nav-${index}-label`];
|
|
6349
|
+
if (!href && !label) continue;
|
|
6350
|
+
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6351
|
+
}
|
|
6352
|
+
const order = parseNavOrder(content);
|
|
6353
|
+
if (order?.length) applyNavOrder(order);
|
|
6354
|
+
}
|
|
6355
|
+
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6356
|
+
const order = getNavOrderFromDom();
|
|
6357
|
+
if (!afterAnchor) {
|
|
6358
|
+
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6359
|
+
return order;
|
|
6360
|
+
}
|
|
6361
|
+
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6362
|
+
if (!afterKey) {
|
|
6363
|
+
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6364
|
+
return order;
|
|
6365
|
+
}
|
|
6366
|
+
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6367
|
+
const pos = withoutNew.indexOf(afterKey);
|
|
6368
|
+
if (pos >= 0) {
|
|
6369
|
+
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6370
|
+
return withoutNew;
|
|
6371
|
+
}
|
|
6372
|
+
withoutNew.push(newHrefKey);
|
|
6373
|
+
return withoutNew;
|
|
6374
|
+
}
|
|
6375
|
+
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6376
|
+
const index = getNextNavbarIndex();
|
|
6377
|
+
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6378
|
+
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6379
|
+
const hrefKey = `nav-${index}-href`;
|
|
6380
|
+
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6381
|
+
applyNavOrder(order);
|
|
6382
|
+
return {
|
|
6383
|
+
anchor,
|
|
6384
|
+
index,
|
|
6385
|
+
hrefKey,
|
|
6386
|
+
labelKey: `nav-${index}-label`,
|
|
6387
|
+
href,
|
|
6388
|
+
label,
|
|
6389
|
+
order
|
|
6390
|
+
};
|
|
6391
|
+
}
|
|
6392
|
+
|
|
6393
|
+
// src/ui/navbar-container-chrome.tsx
|
|
6394
|
+
import { Plus as Plus2 } from "lucide-react";
|
|
6395
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
6396
|
+
function NavbarContainerChrome({
|
|
6397
|
+
rect,
|
|
6398
|
+
onAdd
|
|
5515
6399
|
}) {
|
|
5516
|
-
|
|
5517
|
-
|
|
6400
|
+
const chromeGap = 6;
|
|
6401
|
+
return /* @__PURE__ */ jsx21(
|
|
6402
|
+
"div",
|
|
5518
6403
|
{
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
6404
|
+
"data-ohw-navbar-container-chrome": "",
|
|
6405
|
+
"data-ohw-bridge": "",
|
|
6406
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
6407
|
+
style: {
|
|
6408
|
+
top: rect.top - chromeGap,
|
|
6409
|
+
left: rect.left - chromeGap,
|
|
6410
|
+
width: rect.width + chromeGap * 2,
|
|
6411
|
+
height: rect.height + chromeGap * 2
|
|
5522
6412
|
},
|
|
5523
|
-
children: /* @__PURE__ */
|
|
5524
|
-
|
|
6413
|
+
children: /* @__PURE__ */ jsx21(
|
|
6414
|
+
"button",
|
|
5525
6415
|
{
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
"
|
|
5529
|
-
|
|
5530
|
-
"
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
6416
|
+
type: "button",
|
|
6417
|
+
"data-ohw-navbar-add-button": "",
|
|
6418
|
+
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",
|
|
6419
|
+
style: { top: "70%" },
|
|
6420
|
+
"aria-label": "Add item",
|
|
6421
|
+
onMouseDown: (e) => {
|
|
6422
|
+
e.preventDefault();
|
|
6423
|
+
e.stopPropagation();
|
|
6424
|
+
},
|
|
6425
|
+
onClick: (e) => {
|
|
6426
|
+
e.preventDefault();
|
|
6427
|
+
e.stopPropagation();
|
|
6428
|
+
onAdd();
|
|
6429
|
+
},
|
|
6430
|
+
children: /* @__PURE__ */ jsx21(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
5534
6431
|
}
|
|
5535
6432
|
)
|
|
5536
6433
|
}
|
|
5537
6434
|
);
|
|
5538
6435
|
}
|
|
5539
6436
|
|
|
5540
|
-
// src/ui/link-modal/devFixtures.ts
|
|
5541
|
-
var DEV_SITE_PAGES = [
|
|
5542
|
-
{ path: "/", title: "Home" },
|
|
5543
|
-
{ path: "/about", title: "About" },
|
|
5544
|
-
{ path: "/classes", title: "Classes" },
|
|
5545
|
-
{ path: "/pricing", title: "Pricing" },
|
|
5546
|
-
{ path: "/studio", title: "Studio" },
|
|
5547
|
-
{ path: "/instructors", title: "Instructors" },
|
|
5548
|
-
{ path: "/contact", title: "Contact" }
|
|
5549
|
-
];
|
|
5550
|
-
var DEV_SECTIONS_BY_PATH = {
|
|
5551
|
-
"/": [
|
|
5552
|
-
{ id: "hero", label: "Hero" },
|
|
5553
|
-
{ id: "lagree-intro", label: "Lagree Intro" },
|
|
5554
|
-
{ id: "classes-strip", label: "Classes" },
|
|
5555
|
-
{ id: "feel-split", label: "Feel Split" },
|
|
5556
|
-
{ id: "founder-teaser", label: "Founder" },
|
|
5557
|
-
{ id: "plan-form", label: "Plan Form" },
|
|
5558
|
-
{ id: "testimonials", label: "Testimonials" },
|
|
5559
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
5560
|
-
],
|
|
5561
|
-
"/about": [
|
|
5562
|
-
{ id: "manifesto", label: "Manifesto" },
|
|
5563
|
-
{ id: "story-letter", label: "Our Story" },
|
|
5564
|
-
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
5565
|
-
{ id: "waitlist-cta", label: "Waitlist" },
|
|
5566
|
-
{ id: "personal-training", label: "Personal training" }
|
|
5567
|
-
],
|
|
5568
|
-
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5569
|
-
"/pricing": [
|
|
5570
|
-
{ id: "page-header", label: "Page Header" },
|
|
5571
|
-
{ id: "free-class-cta", label: "Free Class" },
|
|
5572
|
-
{ id: "benefits-marquee", label: "Benefits" },
|
|
5573
|
-
{ id: "monthly-memberships", label: "Memberships" },
|
|
5574
|
-
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5575
|
-
{ id: "package-matcher", label: "Packages" },
|
|
5576
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
5577
|
-
],
|
|
5578
|
-
"/studio": [
|
|
5579
|
-
{ id: "studio-intro", label: "Studio Intro" },
|
|
5580
|
-
{ id: "studio-features", label: "Studio Features" },
|
|
5581
|
-
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5582
|
-
{ id: "studio-visit", label: "Visit Studio" }
|
|
5583
|
-
],
|
|
5584
|
-
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5585
|
-
"/contact": [
|
|
5586
|
-
{ id: "hello-hero", label: "Hello" },
|
|
5587
|
-
{ id: "contact-form", label: "Contact Form" },
|
|
5588
|
-
{ id: "faq", label: "FAQ" }
|
|
5589
|
-
]
|
|
5590
|
-
};
|
|
5591
|
-
function shouldUseDevFixtures() {
|
|
5592
|
-
if (typeof window === "undefined") return false;
|
|
5593
|
-
const raw = readPreservedSearch();
|
|
5594
|
-
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
5595
|
-
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
5596
|
-
}
|
|
5597
|
-
|
|
5598
6437
|
// src/ui/badge.tsx
|
|
5599
|
-
import { jsx as
|
|
6438
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
5600
6439
|
var badgeVariants = cva(
|
|
5601
6440
|
"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",
|
|
5602
6441
|
{
|
|
@@ -5614,12 +6453,12 @@ var badgeVariants = cva(
|
|
|
5614
6453
|
}
|
|
5615
6454
|
);
|
|
5616
6455
|
function Badge({ className, variant, ...props }) {
|
|
5617
|
-
return /* @__PURE__ */
|
|
6456
|
+
return /* @__PURE__ */ jsx22("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5618
6457
|
}
|
|
5619
6458
|
|
|
5620
6459
|
// src/OhhwellsBridge.tsx
|
|
5621
6460
|
import { Link as Link2 } from "lucide-react";
|
|
5622
|
-
import { Fragment as
|
|
6461
|
+
import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5623
6462
|
var PRIMARY2 = "#0885FE";
|
|
5624
6463
|
var IMAGE_FADE_MS = 300;
|
|
5625
6464
|
function runOpacityFade(el, onDone) {
|
|
@@ -5793,7 +6632,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5793
6632
|
const root = createRoot(container);
|
|
5794
6633
|
flushSync(() => {
|
|
5795
6634
|
root.render(
|
|
5796
|
-
/* @__PURE__ */
|
|
6635
|
+
/* @__PURE__ */ jsx23(
|
|
5797
6636
|
SchedulingWidget,
|
|
5798
6637
|
{
|
|
5799
6638
|
notifyOnConnect,
|
|
@@ -5833,7 +6672,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
5833
6672
|
}
|
|
5834
6673
|
}
|
|
5835
6674
|
}
|
|
5836
|
-
function
|
|
6675
|
+
function getLinkHref2(el) {
|
|
5837
6676
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
5838
6677
|
return anchor?.getAttribute("href") ?? "";
|
|
5839
6678
|
}
|
|
@@ -5870,7 +6709,7 @@ function collectEditableNodes() {
|
|
|
5870
6709
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
5871
6710
|
}
|
|
5872
6711
|
if (el.dataset.ohwEditable === "link") {
|
|
5873
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6712
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
|
|
5874
6713
|
}
|
|
5875
6714
|
return {
|
|
5876
6715
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -5881,7 +6720,7 @@ function collectEditableNodes() {
|
|
|
5881
6720
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
5882
6721
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
5883
6722
|
if (!key) return;
|
|
5884
|
-
nodes.push({ key, type: "link", text:
|
|
6723
|
+
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
5885
6724
|
});
|
|
5886
6725
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
5887
6726
|
const key = el.dataset.ohwKey ?? "";
|
|
@@ -5951,7 +6790,7 @@ function applyLinkByKey(key, val) {
|
|
|
5951
6790
|
}
|
|
5952
6791
|
function isInsideLinkEditor(target) {
|
|
5953
6792
|
return Boolean(
|
|
5954
|
-
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"]')
|
|
6793
|
+
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"]')
|
|
5955
6794
|
);
|
|
5956
6795
|
}
|
|
5957
6796
|
function getHrefKeyFromElement(el) {
|
|
@@ -5962,7 +6801,7 @@ function getHrefKeyFromElement(el) {
|
|
|
5962
6801
|
if (!key) return null;
|
|
5963
6802
|
return { anchor, key };
|
|
5964
6803
|
}
|
|
5965
|
-
function
|
|
6804
|
+
function isNavbarButton2(el) {
|
|
5966
6805
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
5967
6806
|
}
|
|
5968
6807
|
function getNavigationItemAnchor(el) {
|
|
@@ -5974,19 +6813,8 @@ function getNavigationItemAnchor(el) {
|
|
|
5974
6813
|
function isNavigationItem(el) {
|
|
5975
6814
|
return getNavigationItemAnchor(el) !== null;
|
|
5976
6815
|
}
|
|
5977
|
-
function getNavigationItemAddHintTarget(anchor) {
|
|
5978
|
-
const items = listNavigationItems();
|
|
5979
|
-
const idx = items.indexOf(anchor);
|
|
5980
|
-
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
5981
|
-
return anchor;
|
|
5982
|
-
}
|
|
5983
|
-
function listNavigationItems() {
|
|
5984
|
-
return Array.from(
|
|
5985
|
-
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
5986
|
-
).filter((el) => isNavigationItem(el));
|
|
5987
|
-
}
|
|
5988
6816
|
function getNavigationItemReorderState(anchor) {
|
|
5989
|
-
if (
|
|
6817
|
+
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
5990
6818
|
return getReorderHandleStateFromAnchor(anchor);
|
|
5991
6819
|
}
|
|
5992
6820
|
function getReorderHandleState(el) {
|
|
@@ -6037,6 +6865,39 @@ function isInferredFooterGroup(el) {
|
|
|
6037
6865
|
function isNavigationContainer(el) {
|
|
6038
6866
|
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
6039
6867
|
}
|
|
6868
|
+
function isPointOverNavigation(x, y) {
|
|
6869
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
6870
|
+
if (!navRoot) return false;
|
|
6871
|
+
const r2 = navRoot.getBoundingClientRect();
|
|
6872
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
6873
|
+
}
|
|
6874
|
+
function isPointOverNavItem(container, x, y) {
|
|
6875
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
6876
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
6877
|
+
const itemRect = el.getBoundingClientRect();
|
|
6878
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
6879
|
+
});
|
|
6880
|
+
}
|
|
6881
|
+
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
6882
|
+
if (getNavigationItemAnchor(target)) return null;
|
|
6883
|
+
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
6884
|
+
const plainLink = target.closest("a");
|
|
6885
|
+
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
6886
|
+
return null;
|
|
6887
|
+
}
|
|
6888
|
+
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
6889
|
+
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
6890
|
+
return fromClosest;
|
|
6891
|
+
}
|
|
6892
|
+
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
6893
|
+
if (!navRoot) return null;
|
|
6894
|
+
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
6895
|
+
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
6896
|
+
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
6897
|
+
return container;
|
|
6898
|
+
}
|
|
6899
|
+
return null;
|
|
6900
|
+
}
|
|
6040
6901
|
function getNavigationSelectionParent(el) {
|
|
6041
6902
|
if (isNavigationItem(el)) {
|
|
6042
6903
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
@@ -6238,7 +7099,7 @@ function EditGlowChrome({
|
|
|
6238
7099
|
dragDisabled = false
|
|
6239
7100
|
}) {
|
|
6240
7101
|
const GAP = 6;
|
|
6241
|
-
return /* @__PURE__ */
|
|
7102
|
+
return /* @__PURE__ */ jsxs13(
|
|
6242
7103
|
"div",
|
|
6243
7104
|
{
|
|
6244
7105
|
ref: elRef,
|
|
@@ -6253,7 +7114,7 @@ function EditGlowChrome({
|
|
|
6253
7114
|
zIndex: 2147483646
|
|
6254
7115
|
},
|
|
6255
7116
|
children: [
|
|
6256
|
-
/* @__PURE__ */
|
|
7117
|
+
/* @__PURE__ */ jsx23(
|
|
6257
7118
|
"div",
|
|
6258
7119
|
{
|
|
6259
7120
|
style: {
|
|
@@ -6266,7 +7127,7 @@ function EditGlowChrome({
|
|
|
6266
7127
|
}
|
|
6267
7128
|
}
|
|
6268
7129
|
),
|
|
6269
|
-
reorderHrefKey && /* @__PURE__ */
|
|
7130
|
+
reorderHrefKey && /* @__PURE__ */ jsx23(
|
|
6270
7131
|
"div",
|
|
6271
7132
|
{
|
|
6272
7133
|
"data-ohw-drag-handle-container": "",
|
|
@@ -6278,7 +7139,7 @@ function EditGlowChrome({
|
|
|
6278
7139
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6279
7140
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6280
7141
|
},
|
|
6281
|
-
children: /* @__PURE__ */
|
|
7142
|
+
children: /* @__PURE__ */ jsx23(
|
|
6282
7143
|
DragHandle,
|
|
6283
7144
|
{
|
|
6284
7145
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -6382,7 +7243,7 @@ function FloatingToolbar({
|
|
|
6382
7243
|
onEditLink
|
|
6383
7244
|
}) {
|
|
6384
7245
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6385
|
-
return /* @__PURE__ */
|
|
7246
|
+
return /* @__PURE__ */ jsx23(
|
|
6386
7247
|
"div",
|
|
6387
7248
|
{
|
|
6388
7249
|
ref: elRef,
|
|
@@ -6403,12 +7264,12 @@ function FloatingToolbar({
|
|
|
6403
7264
|
fontFamily: "sans-serif",
|
|
6404
7265
|
pointerEvents: "auto"
|
|
6405
7266
|
},
|
|
6406
|
-
children: /* @__PURE__ */
|
|
6407
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
6408
|
-
gi > 0 && /* @__PURE__ */
|
|
7267
|
+
children: /* @__PURE__ */ jsxs13(CustomToolbar, { children: [
|
|
7268
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs13(React9.Fragment, { children: [
|
|
7269
|
+
gi > 0 && /* @__PURE__ */ jsx23(CustomToolbarDivider, {}),
|
|
6409
7270
|
btns.map((btn) => {
|
|
6410
7271
|
const isActive = activeCommands.has(btn.cmd);
|
|
6411
|
-
return /* @__PURE__ */
|
|
7272
|
+
return /* @__PURE__ */ jsx23(
|
|
6412
7273
|
CustomToolbarButton,
|
|
6413
7274
|
{
|
|
6414
7275
|
title: btn.title,
|
|
@@ -6417,7 +7278,7 @@ function FloatingToolbar({
|
|
|
6417
7278
|
e.preventDefault();
|
|
6418
7279
|
onCommand(btn.cmd);
|
|
6419
7280
|
},
|
|
6420
|
-
children: /* @__PURE__ */
|
|
7281
|
+
children: /* @__PURE__ */ jsx23(
|
|
6421
7282
|
"svg",
|
|
6422
7283
|
{
|
|
6423
7284
|
width: "16",
|
|
@@ -6438,7 +7299,7 @@ function FloatingToolbar({
|
|
|
6438
7299
|
);
|
|
6439
7300
|
})
|
|
6440
7301
|
] }, gi)),
|
|
6441
|
-
showEditLink ? /* @__PURE__ */
|
|
7302
|
+
showEditLink ? /* @__PURE__ */ jsx23(
|
|
6442
7303
|
CustomToolbarButton,
|
|
6443
7304
|
{
|
|
6444
7305
|
type: "button",
|
|
@@ -6452,7 +7313,7 @@ function FloatingToolbar({
|
|
|
6452
7313
|
e.preventDefault();
|
|
6453
7314
|
e.stopPropagation();
|
|
6454
7315
|
},
|
|
6455
|
-
children: /* @__PURE__ */
|
|
7316
|
+
children: /* @__PURE__ */ jsx23(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6456
7317
|
}
|
|
6457
7318
|
) : null
|
|
6458
7319
|
] })
|
|
@@ -6469,7 +7330,7 @@ function StateToggle({
|
|
|
6469
7330
|
states,
|
|
6470
7331
|
onStateChange
|
|
6471
7332
|
}) {
|
|
6472
|
-
return /* @__PURE__ */
|
|
7333
|
+
return /* @__PURE__ */ jsx23(
|
|
6473
7334
|
ToggleGroup,
|
|
6474
7335
|
{
|
|
6475
7336
|
"data-ohw-state-toggle": "",
|
|
@@ -6483,7 +7344,7 @@ function StateToggle({
|
|
|
6483
7344
|
left: rect.right - 8,
|
|
6484
7345
|
transform: "translateX(-100%)"
|
|
6485
7346
|
},
|
|
6486
|
-
children: states.map((state) => /* @__PURE__ */
|
|
7347
|
+
children: states.map((state) => /* @__PURE__ */ jsx23(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6487
7348
|
}
|
|
6488
7349
|
);
|
|
6489
7350
|
}
|
|
@@ -6506,12 +7367,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
6506
7367
|
return "";
|
|
6507
7368
|
}
|
|
6508
7369
|
function OhhwellsBridge() {
|
|
6509
|
-
const pathname =
|
|
6510
|
-
const router =
|
|
7370
|
+
const pathname = usePathname2();
|
|
7371
|
+
const router = useRouter2();
|
|
6511
7372
|
const searchParams = useSearchParams();
|
|
6512
7373
|
const isEditMode = isEditSessionActive();
|
|
6513
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
6514
|
-
|
|
7374
|
+
const [bridgeRoot, setBridgeRoot] = useState6(null);
|
|
7375
|
+
useEffect7(() => {
|
|
6515
7376
|
const figtreeFontId = "ohw-figtree-font";
|
|
6516
7377
|
if (!document.getElementById(figtreeFontId)) {
|
|
6517
7378
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -6519,7 +7380,10 @@ function OhhwellsBridge() {
|
|
|
6519
7380
|
const stylesheet = Object.assign(document.createElement("link"), {
|
|
6520
7381
|
id: figtreeFontId,
|
|
6521
7382
|
rel: "stylesheet",
|
|
6522
|
-
|
|
7383
|
+
// Inter is loaded alongside Figtree for the media overlay's Replace button. The bridge
|
|
7384
|
+
// renders inside the customer's document, so it cannot assume any font is present — an
|
|
7385
|
+
// unloaded family would silently fall back to whatever the template happens to use.
|
|
7386
|
+
href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Inter:wght@400;500;600&display=swap"
|
|
6523
7387
|
});
|
|
6524
7388
|
document.head.append(preconnect1, preconnect2, stylesheet);
|
|
6525
7389
|
}
|
|
@@ -6536,82 +7400,90 @@ function OhhwellsBridge() {
|
|
|
6536
7400
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
6537
7401
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
6538
7402
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
6539
|
-
const
|
|
7403
|
+
const postToParent2 = useCallback4((data) => {
|
|
6540
7404
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
6541
7405
|
window.parent.postMessage(data, "*");
|
|
6542
7406
|
}
|
|
6543
7407
|
}, []);
|
|
6544
|
-
const [fetchState, setFetchState] =
|
|
6545
|
-
const autoSaveTimers =
|
|
6546
|
-
const activeElRef =
|
|
6547
|
-
const selectedElRef =
|
|
6548
|
-
const originalContentRef =
|
|
6549
|
-
const activeStateElRef =
|
|
6550
|
-
const parentScrollRef =
|
|
6551
|
-
const visibleViewportRef =
|
|
6552
|
-
const [dialogPortalContainer, setDialogPortalContainer] =
|
|
6553
|
-
const attachVisibleViewport =
|
|
7408
|
+
const [fetchState, setFetchState] = useState6("idle");
|
|
7409
|
+
const autoSaveTimers = useRef4(/* @__PURE__ */ new Map());
|
|
7410
|
+
const activeElRef = useRef4(null);
|
|
7411
|
+
const selectedElRef = useRef4(null);
|
|
7412
|
+
const originalContentRef = useRef4(null);
|
|
7413
|
+
const activeStateElRef = useRef4(null);
|
|
7414
|
+
const parentScrollRef = useRef4(null);
|
|
7415
|
+
const visibleViewportRef = useRef4(null);
|
|
7416
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState6(null);
|
|
7417
|
+
const attachVisibleViewport = useCallback4((node) => {
|
|
6554
7418
|
visibleViewportRef.current = node;
|
|
6555
7419
|
setDialogPortalContainer(node);
|
|
6556
7420
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6557
7421
|
}, []);
|
|
6558
|
-
const toolbarElRef =
|
|
6559
|
-
const glowElRef =
|
|
6560
|
-
const hoveredImageRef =
|
|
6561
|
-
const hoveredImageHasTextOverlapRef =
|
|
6562
|
-
const
|
|
6563
|
-
const
|
|
6564
|
-
const
|
|
6565
|
-
const
|
|
6566
|
-
const
|
|
7422
|
+
const toolbarElRef = useRef4(null);
|
|
7423
|
+
const glowElRef = useRef4(null);
|
|
7424
|
+
const hoveredImageRef = useRef4(null);
|
|
7425
|
+
const hoveredImageHasTextOverlapRef = useRef4(false);
|
|
7426
|
+
const [mediaHover, setMediaHover] = useState6(null);
|
|
7427
|
+
const [uploadingRects, setUploadingRects] = useState6({});
|
|
7428
|
+
const hoveredGapRef = useRef4(null);
|
|
7429
|
+
const imageUnhoverTimerRef = useRef4(null);
|
|
7430
|
+
const imageShowTimerRef = useRef4(null);
|
|
7431
|
+
const editStylesRef = useRef4(null);
|
|
7432
|
+
const activateRef = useRef4(() => {
|
|
6567
7433
|
});
|
|
6568
|
-
const deactivateRef =
|
|
7434
|
+
const deactivateRef = useRef4(() => {
|
|
6569
7435
|
});
|
|
6570
|
-
const selectRef =
|
|
7436
|
+
const selectRef = useRef4(() => {
|
|
6571
7437
|
});
|
|
6572
|
-
const selectFrameRef =
|
|
7438
|
+
const selectFrameRef = useRef4(() => {
|
|
6573
7439
|
});
|
|
6574
|
-
const deselectRef =
|
|
7440
|
+
const deselectRef = useRef4(() => {
|
|
6575
7441
|
});
|
|
6576
|
-
const reselectNavigationItemRef =
|
|
7442
|
+
const reselectNavigationItemRef = useRef4(() => {
|
|
6577
7443
|
});
|
|
6578
|
-
const commitNavigationTextEditRef =
|
|
7444
|
+
const commitNavigationTextEditRef = useRef4(() => {
|
|
6579
7445
|
});
|
|
6580
|
-
const refreshActiveCommandsRef =
|
|
7446
|
+
const refreshActiveCommandsRef = useRef4(() => {
|
|
6581
7447
|
});
|
|
6582
|
-
const postToParentRef =
|
|
6583
|
-
postToParentRef.current =
|
|
6584
|
-
const sectionsLoadedRef =
|
|
6585
|
-
const pendingScheduleConfigRequests =
|
|
6586
|
-
const [toolbarRect, setToolbarRect] =
|
|
6587
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
6588
|
-
const toolbarVariantRef =
|
|
7448
|
+
const postToParentRef = useRef4(postToParent2);
|
|
7449
|
+
postToParentRef.current = postToParent2;
|
|
7450
|
+
const sectionsLoadedRef = useRef4(false);
|
|
7451
|
+
const pendingScheduleConfigRequests = useRef4([]);
|
|
7452
|
+
const [toolbarRect, setToolbarRect] = useState6(null);
|
|
7453
|
+
const [toolbarVariant, setToolbarVariant] = useState6("none");
|
|
7454
|
+
const toolbarVariantRef = useRef4("none");
|
|
6589
7455
|
toolbarVariantRef.current = toolbarVariant;
|
|
6590
|
-
const [reorderHrefKey, setReorderHrefKey] =
|
|
6591
|
-
const [reorderDragDisabled, setReorderDragDisabled] =
|
|
6592
|
-
const [toggleState, setToggleState] =
|
|
6593
|
-
const [maxBadge, setMaxBadge] =
|
|
6594
|
-
const [activeCommands, setActiveCommands] =
|
|
6595
|
-
const [sectionGap, setSectionGap] =
|
|
6596
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] =
|
|
6597
|
-
const
|
|
6598
|
-
const [
|
|
6599
|
-
const
|
|
6600
|
-
const [
|
|
6601
|
-
const
|
|
6602
|
-
const [
|
|
6603
|
-
const [
|
|
6604
|
-
const [
|
|
6605
|
-
const
|
|
6606
|
-
const
|
|
6607
|
-
const
|
|
6608
|
-
const
|
|
6609
|
-
const
|
|
7456
|
+
const [reorderHrefKey, setReorderHrefKey] = useState6(null);
|
|
7457
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState6(false);
|
|
7458
|
+
const [toggleState, setToggleState] = useState6(null);
|
|
7459
|
+
const [maxBadge, setMaxBadge] = useState6(null);
|
|
7460
|
+
const [activeCommands, setActiveCommands] = useState6(/* @__PURE__ */ new Set());
|
|
7461
|
+
const [sectionGap, setSectionGap] = useState6(null);
|
|
7462
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState6(false);
|
|
7463
|
+
const hoveredNavContainerRef = useRef4(null);
|
|
7464
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState6(null);
|
|
7465
|
+
const hoveredItemElRef = useRef4(null);
|
|
7466
|
+
const [hoveredItemRect, setHoveredItemRect] = useState6(null);
|
|
7467
|
+
const siblingHintElRef = useRef4(null);
|
|
7468
|
+
const [siblingHintRect, setSiblingHintRect] = useState6(null);
|
|
7469
|
+
const [isItemDragging, setIsItemDragging] = useState6(false);
|
|
7470
|
+
const [linkPopover, setLinkPopover] = useState6(null);
|
|
7471
|
+
const linkPopoverSessionRef = useRef4(null);
|
|
7472
|
+
const addNavAfterAnchorRef = useRef4(null);
|
|
7473
|
+
const editContentRef = useRef4({});
|
|
7474
|
+
const [sitePages, setSitePages] = useState6([]);
|
|
7475
|
+
const [sectionsByPath, setSectionsByPath] = useState6({});
|
|
7476
|
+
const sectionsPrefetchGenRef = useRef4(0);
|
|
7477
|
+
const setLinkPopoverRef = useRef4(setLinkPopover);
|
|
7478
|
+
const linkPopoverPanelRef = useRef4(null);
|
|
7479
|
+
const linkPopoverOpenRef = useRef4(false);
|
|
7480
|
+
const linkPopoverGraceUntilRef = useRef4(0);
|
|
6610
7481
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7482
|
+
linkPopoverSessionRef.current = linkPopover;
|
|
6611
7483
|
const bumpLinkPopoverGrace = () => {
|
|
6612
7484
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
6613
7485
|
};
|
|
6614
|
-
const runSectionsPrefetch =
|
|
7486
|
+
const runSectionsPrefetch = useCallback4((pages) => {
|
|
6615
7487
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
6616
7488
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
6617
7489
|
const paths = pages.map((p) => p.path);
|
|
@@ -6630,9 +7502,9 @@ function OhhwellsBridge() {
|
|
|
6630
7502
|
);
|
|
6631
7503
|
});
|
|
6632
7504
|
}, [isEditMode, pathname]);
|
|
6633
|
-
const runSectionsPrefetchRef =
|
|
7505
|
+
const runSectionsPrefetchRef = useRef4(runSectionsPrefetch);
|
|
6634
7506
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
6635
|
-
|
|
7507
|
+
useEffect7(() => {
|
|
6636
7508
|
if (!linkPopover) return;
|
|
6637
7509
|
if (hoveredImageRef.current) {
|
|
6638
7510
|
hoveredImageRef.current = null;
|
|
@@ -6640,33 +7512,9 @@ function OhhwellsBridge() {
|
|
|
6640
7512
|
}
|
|
6641
7513
|
hoveredGapRef.current = null;
|
|
6642
7514
|
setSectionGap(null);
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
const body = document.body;
|
|
6647
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6648
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6649
|
-
html.style.overflow = "hidden";
|
|
6650
|
-
body.style.overflow = "hidden";
|
|
6651
|
-
const preventBackgroundScroll = (e) => {
|
|
6652
|
-
const target = e.target;
|
|
6653
|
-
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6654
|
-
return;
|
|
6655
|
-
}
|
|
6656
|
-
e.preventDefault();
|
|
6657
|
-
};
|
|
6658
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6659
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6660
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6661
|
-
return () => {
|
|
6662
|
-
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6663
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6664
|
-
body.style.overflow = prevBodyOverflow;
|
|
6665
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6666
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6667
|
-
};
|
|
6668
|
-
}, [linkPopover, postToParent]);
|
|
6669
|
-
useEffect3(() => {
|
|
7515
|
+
postToParent2({ type: "ow:image-unhover" });
|
|
7516
|
+
}, [linkPopover, postToParent2]);
|
|
7517
|
+
useEffect7(() => {
|
|
6670
7518
|
if (!isEditMode) return;
|
|
6671
7519
|
const useFixtures = shouldUseDevFixtures();
|
|
6672
7520
|
if (useFixtures) {
|
|
@@ -6687,17 +7535,17 @@ function OhhwellsBridge() {
|
|
|
6687
7535
|
runSectionsPrefetchRef.current(mapped);
|
|
6688
7536
|
};
|
|
6689
7537
|
window.addEventListener("message", onSitePages);
|
|
6690
|
-
if (!useFixtures)
|
|
7538
|
+
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
6691
7539
|
return () => window.removeEventListener("message", onSitePages);
|
|
6692
|
-
}, [isEditMode,
|
|
6693
|
-
|
|
7540
|
+
}, [isEditMode, postToParent2]);
|
|
7541
|
+
useEffect7(() => {
|
|
6694
7542
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
6695
7543
|
void loadAllSectionsManifest().then((manifest) => {
|
|
6696
7544
|
if (Object.keys(manifest).length === 0) return;
|
|
6697
7545
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
6698
7546
|
});
|
|
6699
7547
|
}, [isEditMode]);
|
|
6700
|
-
|
|
7548
|
+
useEffect7(() => {
|
|
6701
7549
|
const update = () => {
|
|
6702
7550
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6703
7551
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -6721,10 +7569,10 @@ function OhhwellsBridge() {
|
|
|
6721
7569
|
vvp.removeEventListener("resize", update);
|
|
6722
7570
|
};
|
|
6723
7571
|
}, []);
|
|
6724
|
-
const refreshStateRules =
|
|
7572
|
+
const refreshStateRules = useCallback4(() => {
|
|
6725
7573
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
6726
7574
|
}, []);
|
|
6727
|
-
const processConfigRequest =
|
|
7575
|
+
const processConfigRequest = useCallback4((insertAfterVal) => {
|
|
6728
7576
|
const tracker = getSectionsTracker();
|
|
6729
7577
|
let entries = [];
|
|
6730
7578
|
try {
|
|
@@ -6747,7 +7595,7 @@ function OhhwellsBridge() {
|
|
|
6747
7595
|
}
|
|
6748
7596
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
6749
7597
|
}, [isEditMode]);
|
|
6750
|
-
const deactivate =
|
|
7598
|
+
const deactivate = useCallback4(() => {
|
|
6751
7599
|
const el = activeElRef.current;
|
|
6752
7600
|
if (!el) return;
|
|
6753
7601
|
const key = el.dataset.ohwKey;
|
|
@@ -6776,21 +7624,23 @@ function OhhwellsBridge() {
|
|
|
6776
7624
|
setMaxBadge(null);
|
|
6777
7625
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6778
7626
|
setToolbarShowEditLink(false);
|
|
6779
|
-
|
|
6780
|
-
}, [
|
|
6781
|
-
const deselect =
|
|
7627
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
7628
|
+
}, [postToParent2]);
|
|
7629
|
+
const deselect = useCallback4(() => {
|
|
6782
7630
|
selectedElRef.current = null;
|
|
6783
7631
|
setReorderHrefKey(null);
|
|
6784
7632
|
setReorderDragDisabled(false);
|
|
6785
7633
|
siblingHintElRef.current = null;
|
|
6786
7634
|
setSiblingHintRect(null);
|
|
6787
7635
|
setIsItemDragging(false);
|
|
7636
|
+
hoveredNavContainerRef.current = null;
|
|
7637
|
+
setHoveredNavContainerRect(null);
|
|
6788
7638
|
if (!activeElRef.current) {
|
|
6789
7639
|
setToolbarRect(null);
|
|
6790
7640
|
setToolbarVariant("none");
|
|
6791
7641
|
}
|
|
6792
7642
|
}, []);
|
|
6793
|
-
const reselectNavigationItem =
|
|
7643
|
+
const reselectNavigationItem = useCallback4((navAnchor) => {
|
|
6794
7644
|
selectedElRef.current = navAnchor;
|
|
6795
7645
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
6796
7646
|
setReorderHrefKey(key);
|
|
@@ -6800,7 +7650,7 @@ function OhhwellsBridge() {
|
|
|
6800
7650
|
setToolbarShowEditLink(false);
|
|
6801
7651
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6802
7652
|
}, []);
|
|
6803
|
-
const commitNavigationTextEdit =
|
|
7653
|
+
const commitNavigationTextEdit = useCallback4((navAnchor) => {
|
|
6804
7654
|
const el = activeElRef.current;
|
|
6805
7655
|
if (!el) return;
|
|
6806
7656
|
const key = el.dataset.ohwKey;
|
|
@@ -6813,9 +7663,9 @@ function OhhwellsBridge() {
|
|
|
6813
7663
|
const html = sanitizeHtml(el.innerHTML);
|
|
6814
7664
|
const original = originalContentRef.current ?? "";
|
|
6815
7665
|
if (html !== sanitizeHtml(original)) {
|
|
6816
|
-
|
|
7666
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
6817
7667
|
const h = document.documentElement.scrollHeight;
|
|
6818
|
-
if (h > 50)
|
|
7668
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
6819
7669
|
}
|
|
6820
7670
|
}
|
|
6821
7671
|
el.removeAttribute("contenteditable");
|
|
@@ -6823,31 +7673,38 @@ function OhhwellsBridge() {
|
|
|
6823
7673
|
setMaxBadge(null);
|
|
6824
7674
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6825
7675
|
setToolbarShowEditLink(false);
|
|
6826
|
-
|
|
7676
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
6827
7677
|
reselectNavigationItem(navAnchor);
|
|
6828
|
-
}, [
|
|
6829
|
-
const
|
|
6830
|
-
const
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
7678
|
+
}, [postToParent2, reselectNavigationItem]);
|
|
7679
|
+
const handleAddTopLevelNavItem = useCallback4(() => {
|
|
7680
|
+
const items = listNavbarItems();
|
|
7681
|
+
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7682
|
+
deselectRef.current();
|
|
7683
|
+
deactivateRef.current();
|
|
7684
|
+
bumpLinkPopoverGrace();
|
|
7685
|
+
setLinkPopover({
|
|
7686
|
+
key: "__add-nav__",
|
|
7687
|
+
mode: "create",
|
|
7688
|
+
intent: "add-nav"
|
|
7689
|
+
});
|
|
6835
7690
|
}, []);
|
|
6836
|
-
const handleItemDragStart =
|
|
7691
|
+
const handleItemDragStart = useCallback4(() => {
|
|
6837
7692
|
siblingHintElRef.current = null;
|
|
6838
7693
|
setSiblingHintRect(null);
|
|
6839
7694
|
setIsItemDragging(true);
|
|
6840
7695
|
}, []);
|
|
6841
|
-
const handleItemDragEnd =
|
|
7696
|
+
const handleItemDragEnd = useCallback4(() => {
|
|
6842
7697
|
setIsItemDragging(false);
|
|
6843
7698
|
}, []);
|
|
6844
7699
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
6845
7700
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
6846
|
-
const select =
|
|
7701
|
+
const select = useCallback4((anchor) => {
|
|
6847
7702
|
if (!isNavigationItem(anchor)) return;
|
|
6848
7703
|
if (activeElRef.current) deactivate();
|
|
6849
7704
|
selectedElRef.current = anchor;
|
|
6850
7705
|
clearHrefKeyHover(anchor);
|
|
7706
|
+
hoveredNavContainerRef.current = null;
|
|
7707
|
+
setHoveredNavContainerRect(null);
|
|
6851
7708
|
setHoveredItemRect(null);
|
|
6852
7709
|
hoveredItemElRef.current = null;
|
|
6853
7710
|
siblingHintElRef.current = null;
|
|
@@ -6861,11 +7718,13 @@ function OhhwellsBridge() {
|
|
|
6861
7718
|
setToolbarShowEditLink(false);
|
|
6862
7719
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6863
7720
|
}, [deactivate]);
|
|
6864
|
-
const selectFrame =
|
|
7721
|
+
const selectFrame = useCallback4((el) => {
|
|
6865
7722
|
if (!isNavigationContainer(el)) return;
|
|
6866
7723
|
if (activeElRef.current) deactivate();
|
|
6867
7724
|
selectedElRef.current = el;
|
|
6868
7725
|
clearHrefKeyHover(el);
|
|
7726
|
+
hoveredNavContainerRef.current = null;
|
|
7727
|
+
setHoveredNavContainerRect(null);
|
|
6869
7728
|
setHoveredItemRect(null);
|
|
6870
7729
|
hoveredItemElRef.current = null;
|
|
6871
7730
|
siblingHintElRef.current = null;
|
|
@@ -6878,13 +7737,13 @@ function OhhwellsBridge() {
|
|
|
6878
7737
|
setToolbarShowEditLink(false);
|
|
6879
7738
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6880
7739
|
}, [deactivate]);
|
|
6881
|
-
const activate =
|
|
7740
|
+
const activate = useCallback4((el, options) => {
|
|
6882
7741
|
if (activeElRef.current === el) return;
|
|
6883
7742
|
selectedElRef.current = null;
|
|
6884
7743
|
deactivate();
|
|
6885
7744
|
if (hoveredImageRef.current) {
|
|
6886
7745
|
hoveredImageRef.current = null;
|
|
6887
|
-
|
|
7746
|
+
setMediaHover(null);
|
|
6888
7747
|
}
|
|
6889
7748
|
setToolbarVariant("rich-text");
|
|
6890
7749
|
siblingHintElRef.current = null;
|
|
@@ -6910,9 +7769,9 @@ function OhhwellsBridge() {
|
|
|
6910
7769
|
setReorderDragDisabled(reorderDisabled);
|
|
6911
7770
|
}
|
|
6912
7771
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6913
|
-
|
|
7772
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6914
7773
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6915
|
-
}, [deactivate,
|
|
7774
|
+
}, [deactivate, postToParent2]);
|
|
6916
7775
|
activateRef.current = activate;
|
|
6917
7776
|
deactivateRef.current = deactivate;
|
|
6918
7777
|
selectRef.current = select;
|
|
@@ -6986,7 +7845,7 @@ function OhhwellsBridge() {
|
|
|
6986
7845
|
cancelled = true;
|
|
6987
7846
|
};
|
|
6988
7847
|
}, [subdomain, isEditMode]);
|
|
6989
|
-
|
|
7848
|
+
useEffect7(() => {
|
|
6990
7849
|
if (!subdomain || isEditMode) return;
|
|
6991
7850
|
let debounceTimer = null;
|
|
6992
7851
|
let observer = null;
|
|
@@ -7040,20 +7899,34 @@ function OhhwellsBridge() {
|
|
|
7040
7899
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
7041
7900
|
el.style.display = visible ? "flex" : "none";
|
|
7042
7901
|
}, [subdomain, fetchState]);
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
}, [pathname,
|
|
7046
|
-
|
|
7902
|
+
useEffect7(() => {
|
|
7903
|
+
postToParent2({ type: "ow:navigation", path: pathname });
|
|
7904
|
+
}, [pathname, postToParent2]);
|
|
7905
|
+
useEffect7(() => {
|
|
7047
7906
|
if (!isEditMode) return;
|
|
7907
|
+
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
7908
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7048
7909
|
setLinkPopover(null);
|
|
7049
7910
|
deselectRef.current();
|
|
7050
7911
|
deactivateRef.current();
|
|
7051
7912
|
}, [pathname, isEditMode]);
|
|
7052
|
-
|
|
7913
|
+
useEffect7(() => {
|
|
7914
|
+
if (!isEditMode) return;
|
|
7915
|
+
const run = () => reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7916
|
+
run();
|
|
7917
|
+
const nav = document.querySelector("nav");
|
|
7918
|
+
if (!nav) return;
|
|
7919
|
+
const observer = new MutationObserver(() => {
|
|
7920
|
+
requestAnimationFrame(run);
|
|
7921
|
+
});
|
|
7922
|
+
observer.observe(nav, { childList: true, subtree: true });
|
|
7923
|
+
return () => observer.disconnect();
|
|
7924
|
+
}, [isEditMode, pathname]);
|
|
7925
|
+
useEffect7(() => {
|
|
7053
7926
|
if (!isEditMode) return;
|
|
7054
7927
|
const measure = () => {
|
|
7055
7928
|
const h = document.body.scrollHeight;
|
|
7056
|
-
if (h > 50)
|
|
7929
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
7057
7930
|
};
|
|
7058
7931
|
const t1 = setTimeout(measure, 50);
|
|
7059
7932
|
const t2 = setTimeout(measure, 500);
|
|
@@ -7072,8 +7945,8 @@ function OhhwellsBridge() {
|
|
|
7072
7945
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
7073
7946
|
window.removeEventListener("resize", handleResize);
|
|
7074
7947
|
};
|
|
7075
|
-
}, [pathname, isEditMode,
|
|
7076
|
-
|
|
7948
|
+
}, [pathname, isEditMode, postToParent2]);
|
|
7949
|
+
useEffect7(() => {
|
|
7077
7950
|
if (!subdomainFromQuery || isEditMode) return;
|
|
7078
7951
|
const handleClick = (e) => {
|
|
7079
7952
|
const anchor = e.target.closest("a");
|
|
@@ -7089,7 +7962,7 @@ function OhhwellsBridge() {
|
|
|
7089
7962
|
document.addEventListener("click", handleClick, true);
|
|
7090
7963
|
return () => document.removeEventListener("click", handleClick, true);
|
|
7091
7964
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
7092
|
-
|
|
7965
|
+
useEffect7(() => {
|
|
7093
7966
|
if (!isEditMode) {
|
|
7094
7967
|
editStylesRef.current?.base.remove();
|
|
7095
7968
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -7163,6 +8036,13 @@ function OhhwellsBridge() {
|
|
|
7163
8036
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7164
8037
|
if (isInsideLinkEditor(target)) return;
|
|
7165
8038
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8039
|
+
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8040
|
+
if (navFromChrome) {
|
|
8041
|
+
e.preventDefault();
|
|
8042
|
+
e.stopPropagation();
|
|
8043
|
+
selectFrameRef.current(navFromChrome);
|
|
8044
|
+
return;
|
|
8045
|
+
}
|
|
7166
8046
|
e.preventDefault();
|
|
7167
8047
|
e.stopPropagation();
|
|
7168
8048
|
return;
|
|
@@ -7177,14 +8057,15 @@ function OhhwellsBridge() {
|
|
|
7177
8057
|
bumpLinkPopoverGrace();
|
|
7178
8058
|
setLinkPopoverRef.current({
|
|
7179
8059
|
key: editable.dataset.ohwKey ?? "",
|
|
7180
|
-
|
|
8060
|
+
mode: "edit",
|
|
8061
|
+
target: getLinkHref2(editable)
|
|
7181
8062
|
});
|
|
7182
8063
|
return;
|
|
7183
8064
|
}
|
|
7184
8065
|
if (isMediaEditable(editable)) {
|
|
7185
8066
|
e.preventDefault();
|
|
7186
8067
|
e.stopPropagation();
|
|
7187
|
-
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
8068
|
+
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
7188
8069
|
return;
|
|
7189
8070
|
}
|
|
7190
8071
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
@@ -7213,6 +8094,13 @@ function OhhwellsBridge() {
|
|
|
7213
8094
|
selectRef.current(hrefAnchor);
|
|
7214
8095
|
return;
|
|
7215
8096
|
}
|
|
8097
|
+
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8098
|
+
if (navContainerToSelect) {
|
|
8099
|
+
e.preventDefault();
|
|
8100
|
+
e.stopPropagation();
|
|
8101
|
+
selectFrameRef.current(navContainerToSelect);
|
|
8102
|
+
return;
|
|
8103
|
+
}
|
|
7216
8104
|
const selectedContainer = selectedElRef.current;
|
|
7217
8105
|
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
7218
8106
|
const navItem = getNavigationItemAnchor(target);
|
|
@@ -7271,8 +8159,24 @@ function OhhwellsBridge() {
|
|
|
7271
8159
|
};
|
|
7272
8160
|
const handleMouseOver = (e) => {
|
|
7273
8161
|
const target = e.target;
|
|
8162
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
8163
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8164
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
8165
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8166
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8167
|
+
hoveredItemElRef.current = null;
|
|
8168
|
+
setHoveredItemRect(null);
|
|
8169
|
+
return;
|
|
8170
|
+
}
|
|
8171
|
+
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8172
|
+
hoveredNavContainerRef.current = null;
|
|
8173
|
+
setHoveredNavContainerRect(null);
|
|
8174
|
+
}
|
|
8175
|
+
}
|
|
7274
8176
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7275
8177
|
if (navAnchor) {
|
|
8178
|
+
hoveredNavContainerRef.current = null;
|
|
8179
|
+
setHoveredNavContainerRect(null);
|
|
7276
8180
|
const selected2 = selectedElRef.current;
|
|
7277
8181
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7278
8182
|
clearHrefKeyHover(navAnchor);
|
|
@@ -7297,6 +8201,14 @@ function OhhwellsBridge() {
|
|
|
7297
8201
|
};
|
|
7298
8202
|
const handleMouseOut = (e) => {
|
|
7299
8203
|
const target = e.target;
|
|
8204
|
+
if (target.closest("[data-ohw-nav-container]")) {
|
|
8205
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8206
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8207
|
+
return;
|
|
8208
|
+
}
|
|
8209
|
+
hoveredNavContainerRef.current = null;
|
|
8210
|
+
setHoveredNavContainerRect(null);
|
|
8211
|
+
}
|
|
7300
8212
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7301
8213
|
if (navAnchor) {
|
|
7302
8214
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -7358,25 +8270,23 @@ function OhhwellsBridge() {
|
|
|
7358
8270
|
}
|
|
7359
8271
|
return { top, left, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
|
|
7360
8272
|
};
|
|
7361
|
-
const
|
|
8273
|
+
const showImageHover = (imgEl, isDragOver = false, forceTextOverlap) => {
|
|
7362
8274
|
const r2 = getVisibleRect(imgEl);
|
|
7363
8275
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
7364
8276
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
7365
8277
|
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
|
|
7366
|
-
|
|
7367
|
-
type: "ow:image-hover",
|
|
8278
|
+
setMediaHover({
|
|
7368
8279
|
key: imgEl.dataset.ohwKey ?? "",
|
|
7369
|
-
// Lets the parent pick the file-picker `accept`, overlay label/icon and drop
|
|
7370
|
-
// mime-check without a parallel ow:video-* message channel.
|
|
7371
|
-
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7372
8280
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
8281
|
+
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7373
8282
|
hasTextOverlap,
|
|
7374
|
-
|
|
7375
|
-
...
|
|
8283
|
+
isDragOver,
|
|
8284
|
+
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
7376
8285
|
});
|
|
7377
8286
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
7378
8287
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
7379
8288
|
};
|
|
8289
|
+
const clearImageHover = () => setMediaHover(null);
|
|
7380
8290
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
7381
8291
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7382
8292
|
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
@@ -7420,47 +8330,91 @@ function OhhwellsBridge() {
|
|
|
7420
8330
|
}
|
|
7421
8331
|
return smallest;
|
|
7422
8332
|
};
|
|
8333
|
+
const dismissImageHover = () => {
|
|
8334
|
+
if (hoveredImageRef.current) {
|
|
8335
|
+
hoveredImageRef.current = null;
|
|
8336
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
8337
|
+
resumeAnimTracks();
|
|
8338
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8339
|
+
}
|
|
8340
|
+
clearImageHover();
|
|
8341
|
+
};
|
|
8342
|
+
const probeNavigationHoverAt = (x, y) => {
|
|
8343
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8344
|
+
hoveredNavContainerRef.current = null;
|
|
8345
|
+
setHoveredNavContainerRect(null);
|
|
8346
|
+
return;
|
|
8347
|
+
}
|
|
8348
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8349
|
+
if (!navContainer) {
|
|
8350
|
+
hoveredNavContainerRef.current = null;
|
|
8351
|
+
setHoveredNavContainerRect(null);
|
|
8352
|
+
return;
|
|
8353
|
+
}
|
|
8354
|
+
const containerRect = navContainer.getBoundingClientRect();
|
|
8355
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8356
|
+
if (!overContainer) {
|
|
8357
|
+
hoveredNavContainerRef.current = null;
|
|
8358
|
+
setHoveredNavContainerRect(null);
|
|
8359
|
+
return;
|
|
8360
|
+
}
|
|
8361
|
+
const navItemHit = Array.from(
|
|
8362
|
+
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8363
|
+
).find((el) => {
|
|
8364
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8365
|
+
const itemRect = el.getBoundingClientRect();
|
|
8366
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8367
|
+
});
|
|
8368
|
+
if (navItemHit) {
|
|
8369
|
+
hoveredNavContainerRef.current = null;
|
|
8370
|
+
setHoveredNavContainerRect(null);
|
|
8371
|
+
const selected = selectedElRef.current;
|
|
8372
|
+
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8373
|
+
clearHrefKeyHover(navItemHit);
|
|
8374
|
+
hoveredItemElRef.current = navItemHit;
|
|
8375
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
8376
|
+
}
|
|
8377
|
+
return;
|
|
8378
|
+
}
|
|
8379
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8380
|
+
setHoveredNavContainerRect(containerRect);
|
|
8381
|
+
hoveredItemElRef.current = null;
|
|
8382
|
+
setHoveredItemRect(null);
|
|
8383
|
+
};
|
|
7423
8384
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
7424
8385
|
if (linkPopoverOpenRef.current) {
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
8386
|
+
dismissImageHover();
|
|
8387
|
+
return;
|
|
8388
|
+
}
|
|
8389
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8390
|
+
if (isPointOverNavigation(x, y)) {
|
|
8391
|
+
dismissImageHover();
|
|
8392
|
+
probeNavigationHoverAt(x, y);
|
|
7431
8393
|
return;
|
|
7432
8394
|
}
|
|
8395
|
+
hoveredNavContainerRef.current = null;
|
|
8396
|
+
setHoveredNavContainerRect(null);
|
|
7433
8397
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7434
8398
|
if (toggleEl) {
|
|
7435
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7436
8399
|
const tr = toggleEl.getBoundingClientRect();
|
|
7437
8400
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
7438
|
-
|
|
7439
|
-
hoveredImageRef.current = null;
|
|
7440
|
-
resumeAnimTracks();
|
|
7441
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7442
|
-
}
|
|
8401
|
+
dismissImageHover();
|
|
7443
8402
|
return;
|
|
7444
8403
|
}
|
|
7445
8404
|
}
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
resumeAnimTracks();
|
|
7451
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7452
|
-
}
|
|
8405
|
+
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
8406
|
+
const activeEl = activeElRef.current;
|
|
8407
|
+
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
8408
|
+
dismissImageHover();
|
|
7453
8409
|
return;
|
|
7454
8410
|
}
|
|
7455
|
-
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
7456
8411
|
if (imgEl) {
|
|
7457
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7458
8412
|
const topEl = document.elementFromPoint(x, y);
|
|
7459
8413
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
7460
8414
|
if (hoveredImageRef.current) {
|
|
7461
8415
|
hoveredImageRef.current = null;
|
|
7462
8416
|
resumeAnimTracks();
|
|
7463
|
-
|
|
8417
|
+
clearImageHover();
|
|
7464
8418
|
}
|
|
7465
8419
|
return;
|
|
7466
8420
|
}
|
|
@@ -7469,7 +8423,7 @@ function OhhwellsBridge() {
|
|
|
7469
8423
|
hoveredImageRef.current = null;
|
|
7470
8424
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7471
8425
|
resumeAnimTracks();
|
|
7472
|
-
|
|
8426
|
+
clearImageHover();
|
|
7473
8427
|
}
|
|
7474
8428
|
return;
|
|
7475
8429
|
}
|
|
@@ -7494,14 +8448,14 @@ function OhhwellsBridge() {
|
|
|
7494
8448
|
hoveredImageRef.current = null;
|
|
7495
8449
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7496
8450
|
resumeAnimTracks();
|
|
7497
|
-
|
|
8451
|
+
clearImageHover();
|
|
7498
8452
|
}
|
|
7499
8453
|
return;
|
|
7500
8454
|
}
|
|
7501
8455
|
if (isStateCardImage) {
|
|
7502
8456
|
if (imgEl !== hoveredImageRef.current || !hoveredImageHasTextOverlapRef.current) {
|
|
7503
8457
|
hoveredImageRef.current = imgEl;
|
|
7504
|
-
|
|
8458
|
+
showImageHover(imgEl, isDragOver, true);
|
|
7505
8459
|
}
|
|
7506
8460
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7507
8461
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -7513,7 +8467,7 @@ function OhhwellsBridge() {
|
|
|
7513
8467
|
hoveredImageRef.current = null;
|
|
7514
8468
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7515
8469
|
resumeAnimTracks();
|
|
7516
|
-
|
|
8470
|
+
clearImageHover();
|
|
7517
8471
|
}
|
|
7518
8472
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7519
8473
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -7525,7 +8479,7 @@ function OhhwellsBridge() {
|
|
|
7525
8479
|
if (hoveredImageRef.current) {
|
|
7526
8480
|
hoveredImageRef.current = null;
|
|
7527
8481
|
resumeAnimTracks();
|
|
7528
|
-
|
|
8482
|
+
clearImageHover();
|
|
7529
8483
|
}
|
|
7530
8484
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7531
8485
|
return;
|
|
@@ -7533,9 +8487,9 @@ function OhhwellsBridge() {
|
|
|
7533
8487
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7534
8488
|
if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
|
|
7535
8489
|
hoveredImageRef.current = imgEl;
|
|
7536
|
-
|
|
8490
|
+
showImageHover(imgEl, isDragOver);
|
|
7537
8491
|
} else if (isDragOver) {
|
|
7538
|
-
|
|
8492
|
+
showImageHover(imgEl, true);
|
|
7539
8493
|
}
|
|
7540
8494
|
} else {
|
|
7541
8495
|
const inIframeView = clientX >= 0 && clientY >= 0 && clientX <= window.innerWidth && clientY <= window.innerHeight;
|
|
@@ -7552,14 +8506,14 @@ function OhhwellsBridge() {
|
|
|
7552
8506
|
hoveredImageRef.current = null;
|
|
7553
8507
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7554
8508
|
resumeAnimTracks();
|
|
7555
|
-
|
|
8509
|
+
clearImageHover();
|
|
7556
8510
|
}
|
|
7557
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8511
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7558
8512
|
const textEl = Array.from(
|
|
7559
8513
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7560
8514
|
).find((el) => {
|
|
7561
8515
|
const er = el.getBoundingClientRect();
|
|
7562
|
-
return
|
|
8516
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7563
8517
|
});
|
|
7564
8518
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7565
8519
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -7665,7 +8619,7 @@ function OhhwellsBridge() {
|
|
|
7665
8619
|
if (hoveredImageRef.current !== el) {
|
|
7666
8620
|
hoveredImageRef.current = el;
|
|
7667
8621
|
const isStateCard = !!el.closest("[data-ohw-editable-state]");
|
|
7668
|
-
|
|
8622
|
+
showImageHover(el, true, isStateCard ? true : void 0);
|
|
7669
8623
|
}
|
|
7670
8624
|
};
|
|
7671
8625
|
const handleDragLeave = (e) => {
|
|
@@ -7673,7 +8627,7 @@ function OhhwellsBridge() {
|
|
|
7673
8627
|
if (imgEl) return;
|
|
7674
8628
|
hoveredImageRef.current = null;
|
|
7675
8629
|
resumeAnimTracks();
|
|
7676
|
-
|
|
8630
|
+
clearImageHover();
|
|
7677
8631
|
};
|
|
7678
8632
|
const handleDrop = (e) => {
|
|
7679
8633
|
e.preventDefault();
|
|
@@ -7697,31 +8651,7 @@ function OhhwellsBridge() {
|
|
|
7697
8651
|
}
|
|
7698
8652
|
hoveredImageRef.current = null;
|
|
7699
8653
|
resumeAnimTracks();
|
|
7700
|
-
|
|
7701
|
-
};
|
|
7702
|
-
const handleVideoSettings = (e) => {
|
|
7703
|
-
if (e.data?.type !== "ow:video-settings") return;
|
|
7704
|
-
const { key, autoplay, muted } = e.data;
|
|
7705
|
-
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7706
|
-
const video = getVideoEl(el);
|
|
7707
|
-
if (!video) return;
|
|
7708
|
-
if (typeof autoplay === "boolean") video.autoplay = autoplay;
|
|
7709
|
-
if (typeof muted === "boolean") video.muted = muted;
|
|
7710
|
-
syncVideoPlayback(video);
|
|
7711
|
-
postToParentRef.current({
|
|
7712
|
-
type: "ow:change",
|
|
7713
|
-
nodes: [
|
|
7714
|
-
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
7715
|
-
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
7716
|
-
]
|
|
7717
|
-
});
|
|
7718
|
-
postToParentRef.current({
|
|
7719
|
-
type: "ow:video-settings-applied",
|
|
7720
|
-
key,
|
|
7721
|
-
autoplay: video.autoplay,
|
|
7722
|
-
muted: video.muted
|
|
7723
|
-
});
|
|
7724
|
-
});
|
|
8654
|
+
clearImageHover();
|
|
7725
8655
|
};
|
|
7726
8656
|
const handleImageUrl = (e) => {
|
|
7727
8657
|
if (e.data?.type !== "ow:image-url") return;
|
|
@@ -7739,7 +8669,11 @@ function OhhwellsBridge() {
|
|
|
7739
8669
|
}
|
|
7740
8670
|
});
|
|
7741
8671
|
hoveredImageRef.current = null;
|
|
7742
|
-
|
|
8672
|
+
setUploadingRects((prev) => {
|
|
8673
|
+
const entry = prev[key];
|
|
8674
|
+
if (!entry || entry.fadingOut) return prev;
|
|
8675
|
+
return { ...prev, [key]: { ...entry, fadingOut: true } };
|
|
8676
|
+
});
|
|
7743
8677
|
};
|
|
7744
8678
|
let found = false;
|
|
7745
8679
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -7876,6 +8810,8 @@ function OhhwellsBridge() {
|
|
|
7876
8810
|
sectionsLoadedRef.current = true;
|
|
7877
8811
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
7878
8812
|
}
|
|
8813
|
+
editContentRef.current = { ...editContentRef.current, ...content };
|
|
8814
|
+
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7879
8815
|
enforceLinkHrefs();
|
|
7880
8816
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
7881
8817
|
};
|
|
@@ -7883,6 +8819,7 @@ function OhhwellsBridge() {
|
|
|
7883
8819
|
const handleDeactivate = (e) => {
|
|
7884
8820
|
if (e.data?.type !== "ow:deactivate") return;
|
|
7885
8821
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
8822
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7886
8823
|
if (linkPopoverOpenRef.current) {
|
|
7887
8824
|
setLinkPopoverRef.current(null);
|
|
7888
8825
|
return;
|
|
@@ -7892,6 +8829,7 @@ function OhhwellsBridge() {
|
|
|
7892
8829
|
};
|
|
7893
8830
|
window.addEventListener("message", handleDeactivate);
|
|
7894
8831
|
const handleKeyDown = (e) => {
|
|
8832
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
7895
8833
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
7896
8834
|
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
7897
8835
|
if (navAnchor) {
|
|
@@ -7906,8 +8844,13 @@ function OhhwellsBridge() {
|
|
|
7906
8844
|
return;
|
|
7907
8845
|
}
|
|
7908
8846
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
8847
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8848
|
+
deselectRef.current();
|
|
8849
|
+
return;
|
|
8850
|
+
}
|
|
7909
8851
|
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
7910
8852
|
if (parent) {
|
|
8853
|
+
e.preventDefault();
|
|
7911
8854
|
selectFrameRef.current(parent);
|
|
7912
8855
|
} else {
|
|
7913
8856
|
deselectRef.current();
|
|
@@ -7969,18 +8912,18 @@ function OhhwellsBridge() {
|
|
|
7969
8912
|
if (hoveredItemElRef.current) {
|
|
7970
8913
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
7971
8914
|
}
|
|
8915
|
+
if (hoveredNavContainerRef.current) {
|
|
8916
|
+
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
8917
|
+
}
|
|
7972
8918
|
if (siblingHintElRef.current) {
|
|
7973
8919
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
7974
8920
|
}
|
|
7975
8921
|
if (hoveredImageRef.current) {
|
|
7976
8922
|
const el = hoveredImageRef.current;
|
|
7977
8923
|
const r2 = el.getBoundingClientRect();
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
7982
|
-
hasTextOverlap: hoveredImageHasTextOverlapRef.current
|
|
7983
|
-
});
|
|
8924
|
+
setMediaHover(
|
|
8925
|
+
(prev) => prev ? { ...prev, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } } : prev
|
|
8926
|
+
);
|
|
7984
8927
|
}
|
|
7985
8928
|
};
|
|
7986
8929
|
const handleSave = (e) => {
|
|
@@ -8069,19 +9012,39 @@ function OhhwellsBridge() {
|
|
|
8069
9012
|
refreshActiveCommandsRef.current = handleSelectionChange;
|
|
8070
9013
|
const handleDocMouseLeave = () => {
|
|
8071
9014
|
hoveredImageRef.current = null;
|
|
9015
|
+
setMediaHover(null);
|
|
8072
9016
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
8073
9017
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8074
9018
|
activeStateElRef.current = null;
|
|
8075
9019
|
setToggleState(null);
|
|
8076
9020
|
};
|
|
8077
|
-
const
|
|
8078
|
-
if (e.data?.type !== "ow:
|
|
8079
|
-
const { key } = e.data;
|
|
9021
|
+
const handleImageUploading = (e) => {
|
|
9022
|
+
if (e.data?.type !== "ow:image-uploading") return;
|
|
9023
|
+
const { key, uploading } = e.data;
|
|
9024
|
+
setUploadingRects((prev) => {
|
|
9025
|
+
if (!uploading) {
|
|
9026
|
+
if (!(key in prev)) return prev;
|
|
9027
|
+
const next = { ...prev };
|
|
9028
|
+
delete next[key];
|
|
9029
|
+
return next;
|
|
9030
|
+
}
|
|
9031
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
9032
|
+
if (!el) return prev;
|
|
9033
|
+
const r2 = getVisibleRect(el);
|
|
9034
|
+
return {
|
|
9035
|
+
...prev,
|
|
9036
|
+
[key]: { rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
9037
|
+
};
|
|
9038
|
+
});
|
|
8080
9039
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8081
9040
|
const track = el.closest("[data-ohw-hover-pause]");
|
|
8082
|
-
if (track)
|
|
9041
|
+
if (!track) return;
|
|
9042
|
+
if (uploading) {
|
|
8083
9043
|
uploadLockedTracks.add(track);
|
|
8084
9044
|
track.setAttribute("data-ohw-hover-paused", "");
|
|
9045
|
+
} else {
|
|
9046
|
+
uploadLockedTracks.delete(track);
|
|
9047
|
+
track.removeAttribute("data-ohw-hover-paused");
|
|
8085
9048
|
}
|
|
8086
9049
|
});
|
|
8087
9050
|
};
|
|
@@ -8138,7 +9101,7 @@ function OhhwellsBridge() {
|
|
|
8138
9101
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
8139
9102
|
});
|
|
8140
9103
|
if (stateCardImage) {
|
|
8141
|
-
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "" });
|
|
9104
|
+
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
8142
9105
|
return;
|
|
8143
9106
|
}
|
|
8144
9107
|
const textEditable = Array.from(
|
|
@@ -8161,6 +9124,32 @@ function OhhwellsBridge() {
|
|
|
8161
9124
|
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8162
9125
|
return;
|
|
8163
9126
|
}
|
|
9127
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9128
|
+
if (navContainer) {
|
|
9129
|
+
const r2 = navContainer.getBoundingClientRect();
|
|
9130
|
+
const pad = 8;
|
|
9131
|
+
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
9132
|
+
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9133
|
+
selectFrameRef.current(navContainer);
|
|
9134
|
+
return;
|
|
9135
|
+
}
|
|
9136
|
+
}
|
|
9137
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
9138
|
+
if (navRoot && navContainer) {
|
|
9139
|
+
const rr = navRoot.getBoundingClientRect();
|
|
9140
|
+
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9141
|
+
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
9142
|
+
if (book) {
|
|
9143
|
+
const br = book.getBoundingClientRect();
|
|
9144
|
+
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
9145
|
+
deactivateRef.current();
|
|
9146
|
+
return;
|
|
9147
|
+
}
|
|
9148
|
+
}
|
|
9149
|
+
selectFrameRef.current(navContainer);
|
|
9150
|
+
return;
|
|
9151
|
+
}
|
|
9152
|
+
}
|
|
8164
9153
|
deactivateRef.current();
|
|
8165
9154
|
};
|
|
8166
9155
|
window.addEventListener("message", handleSave);
|
|
@@ -8170,8 +9159,7 @@ function OhhwellsBridge() {
|
|
|
8170
9159
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
8171
9160
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
8172
9161
|
window.addEventListener("message", handleImageUrl);
|
|
8173
|
-
window.addEventListener("message",
|
|
8174
|
-
window.addEventListener("message", handleAnimLock);
|
|
9162
|
+
window.addEventListener("message", handleImageUploading);
|
|
8175
9163
|
window.addEventListener("message", handleCanvasHeight);
|
|
8176
9164
|
window.addEventListener("message", handleParentScroll);
|
|
8177
9165
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -8218,8 +9206,7 @@ function OhhwellsBridge() {
|
|
|
8218
9206
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
8219
9207
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
8220
9208
|
window.removeEventListener("message", handleImageUrl);
|
|
8221
|
-
window.removeEventListener("message",
|
|
8222
|
-
window.removeEventListener("message", handleAnimLock);
|
|
9209
|
+
window.removeEventListener("message", handleImageUploading);
|
|
8223
9210
|
window.removeEventListener("message", handleCanvasHeight);
|
|
8224
9211
|
window.removeEventListener("message", handleParentScroll);
|
|
8225
9212
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -8233,7 +9220,7 @@ function OhhwellsBridge() {
|
|
|
8233
9220
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
8234
9221
|
};
|
|
8235
9222
|
}, [isEditMode, refreshStateRules]);
|
|
8236
|
-
|
|
9223
|
+
useEffect7(() => {
|
|
8237
9224
|
const handler = (e) => {
|
|
8238
9225
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
8239
9226
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -8249,7 +9236,7 @@ function OhhwellsBridge() {
|
|
|
8249
9236
|
window.addEventListener("message", handler);
|
|
8250
9237
|
return () => window.removeEventListener("message", handler);
|
|
8251
9238
|
}, [processConfigRequest]);
|
|
8252
|
-
|
|
9239
|
+
useEffect7(() => {
|
|
8253
9240
|
if (!isEditMode) return;
|
|
8254
9241
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
8255
9242
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -8270,27 +9257,27 @@ function OhhwellsBridge() {
|
|
|
8270
9257
|
const next = { ...prev, [pathKey]: sections };
|
|
8271
9258
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
8272
9259
|
});
|
|
8273
|
-
|
|
8274
|
-
|
|
9260
|
+
postToParent2({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
9261
|
+
postToParent2({ type: "ow:request-site-pages" });
|
|
8275
9262
|
}, 150);
|
|
8276
9263
|
return () => {
|
|
8277
9264
|
cancelAnimationFrame(raf);
|
|
8278
9265
|
clearTimeout(timer);
|
|
8279
9266
|
};
|
|
8280
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
8281
|
-
|
|
9267
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9268
|
+
useEffect7(() => {
|
|
8282
9269
|
scrollToHashSectionWhenReady();
|
|
8283
9270
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
8284
9271
|
window.addEventListener("hashchange", onHashChange);
|
|
8285
9272
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
8286
9273
|
}, [pathname]);
|
|
8287
|
-
const handleCommand =
|
|
9274
|
+
const handleCommand = useCallback4((cmd) => {
|
|
8288
9275
|
document.execCommand(cmd, false);
|
|
8289
9276
|
activeElRef.current?.focus();
|
|
8290
9277
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
8291
9278
|
refreshActiveCommandsRef.current();
|
|
8292
9279
|
}, []);
|
|
8293
|
-
const handleStateChange =
|
|
9280
|
+
const handleStateChange = useCallback4((state) => {
|
|
8294
9281
|
if (!activeStateElRef.current) return;
|
|
8295
9282
|
const el = activeStateElRef.current;
|
|
8296
9283
|
if (state === "Default") {
|
|
@@ -8303,18 +9290,22 @@ function OhhwellsBridge() {
|
|
|
8303
9290
|
}
|
|
8304
9291
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
8305
9292
|
}, [deactivate]);
|
|
8306
|
-
const closeLinkPopover =
|
|
8307
|
-
|
|
9293
|
+
const closeLinkPopover = useCallback4(() => {
|
|
9294
|
+
addNavAfterAnchorRef.current = null;
|
|
9295
|
+
setLinkPopover(null);
|
|
9296
|
+
}, []);
|
|
9297
|
+
const openLinkPopoverForActive = useCallback4(() => {
|
|
8308
9298
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
8309
9299
|
if (!hrefCtx) return;
|
|
8310
9300
|
bumpLinkPopoverGrace();
|
|
8311
9301
|
setLinkPopover({
|
|
8312
9302
|
key: hrefCtx.key,
|
|
8313
|
-
|
|
9303
|
+
mode: "edit",
|
|
9304
|
+
target: getLinkHref2(hrefCtx.anchor)
|
|
8314
9305
|
});
|
|
8315
9306
|
deactivate();
|
|
8316
9307
|
}, [deactivate]);
|
|
8317
|
-
const openLinkPopoverForSelected =
|
|
9308
|
+
const openLinkPopoverForSelected = useCallback4(() => {
|
|
8318
9309
|
const anchor = selectedElRef.current;
|
|
8319
9310
|
if (!anchor) return;
|
|
8320
9311
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -8322,29 +9313,133 @@ function OhhwellsBridge() {
|
|
|
8322
9313
|
bumpLinkPopoverGrace();
|
|
8323
9314
|
setLinkPopover({
|
|
8324
9315
|
key,
|
|
8325
|
-
|
|
9316
|
+
mode: "edit",
|
|
9317
|
+
target: getLinkHref2(anchor)
|
|
8326
9318
|
});
|
|
8327
9319
|
deselect();
|
|
8328
9320
|
}, [deselect]);
|
|
8329
|
-
const handleLinkPopoverSubmit =
|
|
9321
|
+
const handleLinkPopoverSubmit = useCallback4(
|
|
8330
9322
|
(target) => {
|
|
8331
|
-
|
|
8332
|
-
|
|
9323
|
+
const session = linkPopoverSessionRef.current;
|
|
9324
|
+
if (!session) return;
|
|
9325
|
+
if (session.intent === "add-nav") {
|
|
9326
|
+
const { pageRoute, sectionId } = parseTarget(target);
|
|
9327
|
+
const page = resolvePage(pageRoute, sitePages);
|
|
9328
|
+
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
9329
|
+
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
9330
|
+
const label = section?.label ?? page.title;
|
|
9331
|
+
const afterAnchor = addNavAfterAnchorRef.current;
|
|
9332
|
+
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(target, label, afterAnchor);
|
|
9333
|
+
applyLinkByKey(hrefKey, target);
|
|
9334
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
9335
|
+
el.textContent = label;
|
|
9336
|
+
});
|
|
9337
|
+
const navCount = String(index + 1);
|
|
9338
|
+
const orderJson = JSON.stringify(order);
|
|
9339
|
+
editContentRef.current = {
|
|
9340
|
+
...editContentRef.current,
|
|
9341
|
+
[hrefKey]: target,
|
|
9342
|
+
[labelKey]: label,
|
|
9343
|
+
[NAV_COUNT_KEY]: navCount,
|
|
9344
|
+
[NAV_ORDER_KEY]: orderJson
|
|
9345
|
+
};
|
|
9346
|
+
postToParent2({
|
|
9347
|
+
type: "ow:change",
|
|
9348
|
+
nodes: [
|
|
9349
|
+
{ key: hrefKey, text: target },
|
|
9350
|
+
{ key: labelKey, text: label },
|
|
9351
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
9352
|
+
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
9353
|
+
]
|
|
9354
|
+
});
|
|
9355
|
+
addNavAfterAnchorRef.current = null;
|
|
9356
|
+
setLinkPopover(null);
|
|
9357
|
+
enforceLinkHrefs();
|
|
9358
|
+
requestAnimationFrame(() => {
|
|
9359
|
+
selectRef.current(anchor);
|
|
9360
|
+
});
|
|
9361
|
+
return;
|
|
9362
|
+
}
|
|
9363
|
+
const { key } = session;
|
|
8333
9364
|
applyLinkByKey(key, target);
|
|
8334
|
-
|
|
9365
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
8335
9366
|
setLinkPopover(null);
|
|
8336
9367
|
},
|
|
8337
|
-
[
|
|
9368
|
+
[postToParent2, sitePages, sectionsByPath]
|
|
8338
9369
|
);
|
|
8339
9370
|
const showEditLink = toolbarShowEditLink;
|
|
8340
9371
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8341
9372
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
9373
|
+
const handleMediaReplace = useCallback4(
|
|
9374
|
+
(key) => {
|
|
9375
|
+
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
9376
|
+
},
|
|
9377
|
+
[postToParent2, mediaHover?.elementType]
|
|
9378
|
+
);
|
|
9379
|
+
const handleVideoSettingsChange = useCallback4(
|
|
9380
|
+
(key, settings) => {
|
|
9381
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9382
|
+
const video = getVideoEl(el);
|
|
9383
|
+
if (!video) return;
|
|
9384
|
+
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
9385
|
+
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
9386
|
+
syncVideoPlayback(video);
|
|
9387
|
+
postToParent2({
|
|
9388
|
+
type: "ow:change",
|
|
9389
|
+
nodes: [
|
|
9390
|
+
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
9391
|
+
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
9392
|
+
]
|
|
9393
|
+
});
|
|
9394
|
+
setMediaHover(
|
|
9395
|
+
(prev) => prev && prev.key === key ? { ...prev, videoAutoplay: video.autoplay, videoMuted: video.muted } : prev
|
|
9396
|
+
);
|
|
9397
|
+
});
|
|
9398
|
+
},
|
|
9399
|
+
[postToParent2]
|
|
9400
|
+
);
|
|
9401
|
+
const handleMediaFadeOutComplete = useCallback4((key) => {
|
|
9402
|
+
setUploadingRects((prev) => {
|
|
9403
|
+
if (!(key in prev)) return prev;
|
|
9404
|
+
const next = { ...prev };
|
|
9405
|
+
delete next[key];
|
|
9406
|
+
return next;
|
|
9407
|
+
});
|
|
9408
|
+
}, []);
|
|
9409
|
+
return bridgeRoot ? createPortal2(
|
|
9410
|
+
/* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
9411
|
+
/* @__PURE__ */ jsx23("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9412
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx23(
|
|
9413
|
+
MediaOverlay,
|
|
9414
|
+
{
|
|
9415
|
+
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
9416
|
+
isUploading: true,
|
|
9417
|
+
fadingOut,
|
|
9418
|
+
onFadeOutComplete: handleMediaFadeOutComplete,
|
|
9419
|
+
onReplace: handleMediaReplace
|
|
9420
|
+
},
|
|
9421
|
+
`uploading-${key}`
|
|
9422
|
+
)),
|
|
9423
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx23(
|
|
9424
|
+
MediaOverlay,
|
|
9425
|
+
{
|
|
9426
|
+
hover: mediaHover,
|
|
9427
|
+
isUploading: false,
|
|
9428
|
+
onReplace: handleMediaReplace,
|
|
9429
|
+
onVideoSettingsChange: handleVideoSettingsChange
|
|
9430
|
+
}
|
|
9431
|
+
),
|
|
9432
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9433
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9434
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx23(
|
|
9435
|
+
NavbarContainerChrome,
|
|
9436
|
+
{
|
|
9437
|
+
rect: toolbarRect,
|
|
9438
|
+
onAdd: handleAddTopLevelNavItem
|
|
9439
|
+
}
|
|
9440
|
+
),
|
|
9441
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9442
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx23(
|
|
8348
9443
|
ItemInteractionLayer,
|
|
8349
9444
|
{
|
|
8350
9445
|
rect: toolbarRect,
|
|
@@ -8355,18 +9450,19 @@ function OhhwellsBridge() {
|
|
|
8355
9450
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8356
9451
|
onDragHandleDragStart: handleItemDragStart,
|
|
8357
9452
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
8358
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */
|
|
9453
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ jsx23(
|
|
8359
9454
|
ItemActionToolbar,
|
|
8360
9455
|
{
|
|
8361
9456
|
onEditLink: openLinkPopoverForSelected,
|
|
8362
|
-
|
|
8363
|
-
|
|
9457
|
+
addItemDisabled: true,
|
|
9458
|
+
editLinkDisabled: false,
|
|
9459
|
+
moreDisabled: true
|
|
8364
9460
|
}
|
|
8365
9461
|
) : void 0
|
|
8366
9462
|
}
|
|
8367
9463
|
),
|
|
8368
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */
|
|
8369
|
-
/* @__PURE__ */
|
|
9464
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
9465
|
+
/* @__PURE__ */ jsx23(
|
|
8370
9466
|
EditGlowChrome,
|
|
8371
9467
|
{
|
|
8372
9468
|
rect: toolbarRect,
|
|
@@ -8375,7 +9471,7 @@ function OhhwellsBridge() {
|
|
|
8375
9471
|
dragDisabled: reorderDragDisabled
|
|
8376
9472
|
}
|
|
8377
9473
|
),
|
|
8378
|
-
/* @__PURE__ */
|
|
9474
|
+
/* @__PURE__ */ jsx23(
|
|
8379
9475
|
FloatingToolbar,
|
|
8380
9476
|
{
|
|
8381
9477
|
rect: toolbarRect,
|
|
@@ -8388,7 +9484,7 @@ function OhhwellsBridge() {
|
|
|
8388
9484
|
}
|
|
8389
9485
|
)
|
|
8390
9486
|
] }),
|
|
8391
|
-
maxBadge && /* @__PURE__ */
|
|
9487
|
+
maxBadge && /* @__PURE__ */ jsxs13(
|
|
8392
9488
|
"div",
|
|
8393
9489
|
{
|
|
8394
9490
|
"data-ohw-max-badge": "",
|
|
@@ -8414,7 +9510,7 @@ function OhhwellsBridge() {
|
|
|
8414
9510
|
]
|
|
8415
9511
|
}
|
|
8416
9512
|
),
|
|
8417
|
-
toggleState && /* @__PURE__ */
|
|
9513
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx23(
|
|
8418
9514
|
StateToggle,
|
|
8419
9515
|
{
|
|
8420
9516
|
rect: toggleState.rect,
|
|
@@ -8423,15 +9519,15 @@ function OhhwellsBridge() {
|
|
|
8423
9519
|
onStateChange: handleStateChange
|
|
8424
9520
|
}
|
|
8425
9521
|
),
|
|
8426
|
-
sectionGap && /* @__PURE__ */
|
|
9522
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs13(
|
|
8427
9523
|
"div",
|
|
8428
9524
|
{
|
|
8429
9525
|
"data-ohw-section-insert-line": "",
|
|
8430
9526
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8431
9527
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8432
9528
|
children: [
|
|
8433
|
-
/* @__PURE__ */
|
|
8434
|
-
/* @__PURE__ */
|
|
9529
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9530
|
+
/* @__PURE__ */ jsx23(
|
|
8435
9531
|
Badge,
|
|
8436
9532
|
{
|
|
8437
9533
|
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",
|
|
@@ -8444,35 +9540,36 @@ function OhhwellsBridge() {
|
|
|
8444
9540
|
children: "Add Section"
|
|
8445
9541
|
}
|
|
8446
9542
|
),
|
|
8447
|
-
/* @__PURE__ */
|
|
9543
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8448
9544
|
]
|
|
8449
9545
|
}
|
|
8450
9546
|
),
|
|
8451
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
9547
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx23(
|
|
8452
9548
|
LinkPopover,
|
|
8453
9549
|
{
|
|
8454
9550
|
panelRef: linkPopoverPanelRef,
|
|
8455
9551
|
portalContainer: dialogPortalContainer,
|
|
8456
9552
|
open: true,
|
|
8457
|
-
mode: "edit",
|
|
9553
|
+
mode: linkPopover.mode ?? "edit",
|
|
8458
9554
|
pages: sitePages,
|
|
8459
9555
|
sections: currentSections,
|
|
8460
9556
|
sectionsByPath,
|
|
8461
9557
|
initialTarget: linkPopover.target,
|
|
9558
|
+
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
8462
9559
|
onClose: closeLinkPopover,
|
|
8463
9560
|
onSubmit: handleLinkPopoverSubmit
|
|
8464
9561
|
},
|
|
8465
|
-
|
|
9562
|
+
linkPopover.key
|
|
8466
9563
|
) : null,
|
|
8467
|
-
sectionGap && /* @__PURE__ */
|
|
9564
|
+
sectionGap && /* @__PURE__ */ jsxs13(
|
|
8468
9565
|
"div",
|
|
8469
9566
|
{
|
|
8470
9567
|
"data-ohw-section-insert-line": "",
|
|
8471
9568
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8472
9569
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8473
9570
|
children: [
|
|
8474
|
-
/* @__PURE__ */
|
|
8475
|
-
/* @__PURE__ */
|
|
9571
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9572
|
+
/* @__PURE__ */ jsx23(
|
|
8476
9573
|
Badge,
|
|
8477
9574
|
{
|
|
8478
9575
|
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",
|
|
@@ -8485,7 +9582,7 @@ function OhhwellsBridge() {
|
|
|
8485
9582
|
children: "Add Section"
|
|
8486
9583
|
}
|
|
8487
9584
|
),
|
|
8488
|
-
/* @__PURE__ */
|
|
9585
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8489
9586
|
]
|
|
8490
9587
|
}
|
|
8491
9588
|
)
|