@ohhwells/bridge 0.1.121 → 0.1.122
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 +2411 -402
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +2407 -398
- package/dist/index.js.map +1 -1
- package/dist/styles.css +79 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -525,9 +525,9 @@ function styleSheetCss() {
|
|
|
525
525
|
);
|
|
526
526
|
}
|
|
527
527
|
const pad = { tight: 40, balanced: 64, airy: 96 };
|
|
528
|
-
for (const [spacing,
|
|
528
|
+
for (const [spacing, px2] of Object.entries(pad)) {
|
|
529
529
|
rules.push(
|
|
530
|
-
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${
|
|
530
|
+
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px2}px !important; padding-bottom: ${px2}px !important; }`
|
|
531
531
|
);
|
|
532
532
|
}
|
|
533
533
|
rules.push(
|
|
@@ -3094,12 +3094,12 @@ function deriveTemplateButtonStyle() {
|
|
|
3094
3094
|
cs.borderBottomLeftRadius
|
|
3095
3095
|
].map((v) => v || "0px");
|
|
3096
3096
|
const radius = corners.every((v) => v === corners[0]) ? corners[0] : corners.join(" ");
|
|
3097
|
-
const
|
|
3098
|
-
const lineHeight =
|
|
3099
|
-
const contentH = btn.getBoundingClientRect().height -
|
|
3097
|
+
const px2 = (v) => parseFloat(v) || 0;
|
|
3098
|
+
const lineHeight = px2(cs.lineHeight) || px2(cs.fontSize) * 1.2;
|
|
3099
|
+
const contentH = btn.getBoundingClientRect().height - px2(cs.borderTopWidth) - px2(cs.borderBottomWidth);
|
|
3100
3100
|
const impliedY = Math.round(Math.max(0, (contentH - lineHeight) / 2));
|
|
3101
|
-
const padY = Math.max(
|
|
3102
|
-
const padX = Math.max(
|
|
3101
|
+
const padY = Math.max(px2(cs.paddingTop), px2(cs.paddingBottom), impliedY);
|
|
3102
|
+
const padX = Math.max(px2(cs.paddingLeft), px2(cs.paddingRight));
|
|
3103
3103
|
return {
|
|
3104
3104
|
radius: radius || "10px",
|
|
3105
3105
|
padding: `${padY}px ${padX}px`,
|
|
@@ -8016,6 +8016,14 @@ function ItemActionToolbar({
|
|
|
8016
8016
|
e.preventDefault();
|
|
8017
8017
|
e.stopPropagation();
|
|
8018
8018
|
onStyle?.();
|
|
8019
|
+
},
|
|
8020
|
+
// Same as Edit link: mousedown opens the panel and remounts this toolbar
|
|
8021
|
+
// (styleActive flips). Without stopping click, the gesture lands on whatever
|
|
8022
|
+
// is now under the cursor — navbar CTAs park the toolbar below the button, so
|
|
8023
|
+
// that miss deselects and the panel closes as soon as it opens.
|
|
8024
|
+
onClick: (e) => {
|
|
8025
|
+
e.preventDefault();
|
|
8026
|
+
e.stopPropagation();
|
|
8019
8027
|
}
|
|
8020
8028
|
},
|
|
8021
8029
|
children: /* @__PURE__ */ jsx11(Brush, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
@@ -8338,20 +8346,32 @@ function ItemInteractionLayer({
|
|
|
8338
8346
|
itemDragSurface = true,
|
|
8339
8347
|
chromeGap,
|
|
8340
8348
|
toolbarAlign = "center",
|
|
8349
|
+
hidden = false,
|
|
8341
8350
|
className
|
|
8342
8351
|
}) {
|
|
8352
|
+
const localRef = useRef2(null);
|
|
8353
|
+
useLayoutEffect2(() => {
|
|
8354
|
+
const node = localRef.current;
|
|
8355
|
+
if (!node) return;
|
|
8356
|
+
node.style.display = hidden ? "none" : "block";
|
|
8357
|
+
}, [hidden, rect.top, rect.left, rect.width, rect.height, state]);
|
|
8343
8358
|
if (state === "default") return null;
|
|
8344
8359
|
const gap = chromeGap ?? (state === "hover" ? HOVER_CHROME_GAP : SELECTION_CHROME_GAP);
|
|
8345
8360
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
8346
8361
|
const isDragging = state === "dragging";
|
|
8347
8362
|
const showToolbar = isActive && toolbar;
|
|
8348
8363
|
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
8349
|
-
const itemDragEnabled = itemDragSurface && isActive &&
|
|
8364
|
+
const itemDragEnabled = itemDragSurface && isActive && !isDragging && !dragDisabled && Boolean(showHandle || onItemPointerDown);
|
|
8350
8365
|
const useDetachedBelowToolbar = Boolean(showToolbar && state === "active-bottom" && toolbarBelowRect);
|
|
8366
|
+
const setRootRef = (node) => {
|
|
8367
|
+
localRef.current = node;
|
|
8368
|
+
if (typeof elRef === "function") elRef(node);
|
|
8369
|
+
else if (elRef) elRef.current = node;
|
|
8370
|
+
};
|
|
8351
8371
|
return /* @__PURE__ */ jsxs5(
|
|
8352
8372
|
"div",
|
|
8353
8373
|
{
|
|
8354
|
-
ref:
|
|
8374
|
+
ref: setRootRef,
|
|
8355
8375
|
"data-ohw-item-interaction": "",
|
|
8356
8376
|
"data-ohw-item-interaction-state": state,
|
|
8357
8377
|
className: cn("pointer-events-none", className),
|
|
@@ -8361,7 +8381,8 @@ function ItemInteractionLayer({
|
|
|
8361
8381
|
left: rect.left - gap,
|
|
8362
8382
|
width: rect.width + gap * 2,
|
|
8363
8383
|
height: rect.height + gap * 2,
|
|
8364
|
-
zIndex: getChromeZIndex(state)
|
|
8384
|
+
zIndex: getChromeZIndex(state),
|
|
8385
|
+
display: hidden ? "none" : "block"
|
|
8365
8386
|
},
|
|
8366
8387
|
children: [
|
|
8367
8388
|
/* @__PURE__ */ jsx12(
|
|
@@ -11182,6 +11203,13 @@ function findButtonAtPoint(x, y, media) {
|
|
|
11182
11203
|
if (hits.length === 0) return null;
|
|
11183
11204
|
return hits.reduce((best, el) => best.contains(el) ? el : best);
|
|
11184
11205
|
}
|
|
11206
|
+
function findNavbarCtaAtPoint(x, y) {
|
|
11207
|
+
const hits = Array.from(
|
|
11208
|
+
document.querySelectorAll('[data-ohw-role="navbar-button"]')
|
|
11209
|
+
).filter((el) => containsPoint(el, x, y) && !el.closest("[data-ohw-bridge]"));
|
|
11210
|
+
if (hits.length === 0) return null;
|
|
11211
|
+
return hits.reduce((best, el) => best.contains(el) ? el : best);
|
|
11212
|
+
}
|
|
11185
11213
|
|
|
11186
11214
|
// src/lib/session-search.ts
|
|
11187
11215
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -11917,6 +11945,26 @@ import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMem
|
|
|
11917
11945
|
import { createPortal as createPortal2 } from "react-dom";
|
|
11918
11946
|
import { ArrowLeft as ArrowLeft2, Check as Check2 } from "lucide-react";
|
|
11919
11947
|
import { usePathname, useRouter as useRouter2 } from "next/navigation";
|
|
11948
|
+
|
|
11949
|
+
// src/lib/parent-scroll.ts
|
|
11950
|
+
function visibleBand(parentScroll) {
|
|
11951
|
+
const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
|
|
11952
|
+
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
11953
|
+
const bottom = Math.min(window.innerHeight, visibleCanvasTop + canvasH - iframeOffsetTop);
|
|
11954
|
+
return { top, bottom: Math.max(top, bottom) };
|
|
11955
|
+
}
|
|
11956
|
+
function getIframeVisibleClip(parentScroll) {
|
|
11957
|
+
if (!parentScroll) return null;
|
|
11958
|
+
return visibleBand(parentScroll);
|
|
11959
|
+
}
|
|
11960
|
+
function getIframeChromeClip(parentScroll) {
|
|
11961
|
+
if (!parentScroll) return null;
|
|
11962
|
+
const band = visibleBand(parentScroll);
|
|
11963
|
+
const promptBarH = Math.max(0, parentScroll.promptBarH ?? 0);
|
|
11964
|
+
return { top: band.top, bottom: Math.max(band.top, band.bottom - promptBarH) };
|
|
11965
|
+
}
|
|
11966
|
+
|
|
11967
|
+
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
11920
11968
|
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11921
11969
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
11922
11970
|
function rectsEqual(a, b) {
|
|
@@ -12054,20 +12102,22 @@ function SectionPickerOverlay({
|
|
|
12054
12102
|
[]
|
|
12055
12103
|
);
|
|
12056
12104
|
useEffect8(() => {
|
|
12057
|
-
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
12058
|
-
const
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12105
|
+
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
|
|
12106
|
+
const next = getIframeVisibleClip({
|
|
12107
|
+
iframeOffsetTop,
|
|
12108
|
+
headerH: visibleCanvasTop,
|
|
12109
|
+
canvasH,
|
|
12110
|
+
promptBarH
|
|
12111
|
+
});
|
|
12112
|
+
if (!next) return;
|
|
12063
12113
|
setChromeClip(
|
|
12064
|
-
(prev) => prev.top === top && prev.bottom === bottom ? prev :
|
|
12114
|
+
(prev) => prev.top === next.top && prev.bottom === next.bottom ? prev : next
|
|
12065
12115
|
);
|
|
12066
12116
|
};
|
|
12067
12117
|
const onParentScroll = (e) => {
|
|
12068
12118
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
12069
|
-
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
12070
|
-
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
12119
|
+
const { iframeOffsetTop, headerH, canvasH, promptBarH = 0 } = e.data;
|
|
12120
|
+
applyClip(iframeOffsetTop, headerH, canvasH, promptBarH);
|
|
12071
12121
|
iframeOffsetTopRef.current = iframeOffsetTop;
|
|
12072
12122
|
if (!pointerScreenRef.current && pointerRef.current) {
|
|
12073
12123
|
pointerScreenRef.current = {
|
|
@@ -15737,36 +15787,50 @@ import { X as X5 } from "lucide-react";
|
|
|
15737
15787
|
import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
15738
15788
|
var PANEL_WIDTH = 256;
|
|
15739
15789
|
var EDGE_MARGIN = 16;
|
|
15790
|
+
var HEADER_MIN = 56;
|
|
15740
15791
|
function getVisibleClip(parentScroll) {
|
|
15741
15792
|
const left = 0;
|
|
15742
15793
|
const right = window.innerWidth;
|
|
15743
|
-
|
|
15794
|
+
const band = getIframeChromeClip(parentScroll);
|
|
15795
|
+
if (!band) {
|
|
15744
15796
|
return { top: 0, bottom: window.innerHeight, left, right };
|
|
15745
15797
|
}
|
|
15746
|
-
|
|
15747
|
-
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
15748
|
-
const bottom = Math.min(window.innerHeight, visibleCanvasTop + canvasH - iframeOffsetTop);
|
|
15749
|
-
return { top, bottom: Math.max(top, bottom), left, right };
|
|
15798
|
+
return { ...band, left, right };
|
|
15750
15799
|
}
|
|
15751
|
-
function defaultFloatingPanelPosition(parentScroll,
|
|
15800
|
+
function defaultFloatingPanelPosition(parentScroll, _panelHeight = 280) {
|
|
15752
15801
|
const clip = getVisibleClip(parentScroll);
|
|
15753
15802
|
return {
|
|
15754
15803
|
x: Math.max(EDGE_MARGIN, clip.right - PANEL_WIDTH - EDGE_MARGIN),
|
|
15755
|
-
y:
|
|
15756
|
-
Math.max(clip.top + EDGE_MARGIN, EDGE_MARGIN),
|
|
15757
|
-
Math.max(clip.top + EDGE_MARGIN, clip.bottom - panelHeight - EDGE_MARGIN)
|
|
15758
|
-
)
|
|
15804
|
+
y: clip.top + EDGE_MARGIN
|
|
15759
15805
|
};
|
|
15760
15806
|
}
|
|
15761
|
-
function
|
|
15807
|
+
function clampX(x, panelW) {
|
|
15808
|
+
const left = EDGE_MARGIN;
|
|
15809
|
+
const maxX = Math.max(left, window.innerWidth - panelW - EDGE_MARGIN);
|
|
15810
|
+
return Math.min(Math.max(x, left), maxX);
|
|
15811
|
+
}
|
|
15812
|
+
function clampDragPosition(pos, parentScroll, panelW) {
|
|
15762
15813
|
const clip = getVisibleClip(parentScroll);
|
|
15763
|
-
const
|
|
15764
|
-
const maxY = Math.max(
|
|
15814
|
+
const minY = clip.top + EDGE_MARGIN;
|
|
15815
|
+
const maxY = Math.max(minY, clip.bottom - EDGE_MARGIN - HEADER_MIN);
|
|
15765
15816
|
return {
|
|
15766
|
-
x:
|
|
15767
|
-
y: Math.min(Math.max(pos.y,
|
|
15817
|
+
x: clampX(pos.x, panelW),
|
|
15818
|
+
y: Math.min(Math.max(pos.y, minY), maxY)
|
|
15768
15819
|
};
|
|
15769
15820
|
}
|
|
15821
|
+
function fitPanelInClip(homeY, parentScroll, preferredHeight) {
|
|
15822
|
+
const clip = getVisibleClip(parentScroll);
|
|
15823
|
+
const minY = clip.top + EDGE_MARGIN;
|
|
15824
|
+
const maxBottom = clip.bottom - EDGE_MARGIN;
|
|
15825
|
+
const band = Math.max(HEADER_MIN, maxBottom - minY);
|
|
15826
|
+
let y = Math.max(homeY, minY);
|
|
15827
|
+
const want = Math.min(Math.max(preferredHeight, HEADER_MIN), band);
|
|
15828
|
+
if (y + want > maxBottom) {
|
|
15829
|
+
y = Math.max(minY, maxBottom - want);
|
|
15830
|
+
}
|
|
15831
|
+
const maxHeight = Math.max(HEADER_MIN, Math.floor(maxBottom - y));
|
|
15832
|
+
return { y, maxHeight };
|
|
15833
|
+
}
|
|
15770
15834
|
function FloatingPanel({
|
|
15771
15835
|
open,
|
|
15772
15836
|
title,
|
|
@@ -15783,19 +15847,54 @@ function FloatingPanel({
|
|
|
15783
15847
|
const panelRef = useRef9(null);
|
|
15784
15848
|
const [measured, setMeasured] = useState12({ w: PANEL_WIDTH, h: 280 });
|
|
15785
15849
|
const dragRef = useRef9(null);
|
|
15786
|
-
const
|
|
15787
|
-
|
|
15850
|
+
const homeRef = useRef9(null);
|
|
15851
|
+
if (!open) {
|
|
15852
|
+
homeRef.current = null;
|
|
15853
|
+
} else if (position) {
|
|
15854
|
+
homeRef.current = position;
|
|
15855
|
+
} else if (homeRef.current == null) {
|
|
15856
|
+
homeRef.current = defaultFloatingPanelPosition(parentScroll);
|
|
15857
|
+
}
|
|
15858
|
+
const [liveScroll, setLiveScroll] = useState12(parentScroll);
|
|
15859
|
+
const home = position ?? homeRef.current ?? defaultFloatingPanelPosition(parentScroll);
|
|
15860
|
+
const { y: fittedY, maxHeight } = fitPanelInClip(home.y, liveScroll, measured.h);
|
|
15861
|
+
const clamped = {
|
|
15862
|
+
x: clampX(home.x, measured.w),
|
|
15863
|
+
y: fittedY
|
|
15864
|
+
};
|
|
15865
|
+
useEffect11(() => {
|
|
15866
|
+
setLiveScroll(parentScroll);
|
|
15867
|
+
}, [parentScroll]);
|
|
15868
|
+
useEffect11(() => {
|
|
15869
|
+
if (!open) return;
|
|
15870
|
+
const onParentScroll = (e) => {
|
|
15871
|
+
if (e.data?.type !== "ow:parent-scroll") return;
|
|
15872
|
+
const { iframeOffsetTop, headerH, canvasH, promptBarH = 0 } = e.data;
|
|
15873
|
+
setLiveScroll({ iframeOffsetTop, headerH, canvasH, promptBarH });
|
|
15874
|
+
};
|
|
15875
|
+
window.addEventListener("message", onParentScroll);
|
|
15876
|
+
return () => window.removeEventListener("message", onParentScroll);
|
|
15877
|
+
}, [open]);
|
|
15878
|
+
const positionRef = useRef9(position);
|
|
15879
|
+
useLayoutEffect4(() => {
|
|
15880
|
+
if (!open) {
|
|
15881
|
+
positionRef.current = position;
|
|
15882
|
+
return;
|
|
15883
|
+
}
|
|
15884
|
+
if (position == null && positionRef.current != null) {
|
|
15885
|
+
homeRef.current = defaultFloatingPanelPosition(liveScroll ?? parentScroll);
|
|
15886
|
+
}
|
|
15887
|
+
positionRef.current = position;
|
|
15888
|
+
}, [open, position, liveScroll, parentScroll]);
|
|
15788
15889
|
useLayoutEffect4(() => {
|
|
15789
15890
|
if (!open || !panelRef.current) return;
|
|
15790
15891
|
const el = panelRef.current;
|
|
15791
|
-
const
|
|
15892
|
+
const header = el.querySelector("[data-ohw-floating-panel-header]");
|
|
15893
|
+
const body = el.querySelector("[data-ohw-floating-panel-body]");
|
|
15894
|
+
const contentH = (header?.offsetHeight ?? 0) + (body?.scrollHeight ?? 0) || el.scrollHeight || 280;
|
|
15895
|
+
const next = { w: el.offsetWidth || PANEL_WIDTH, h: contentH };
|
|
15792
15896
|
setMeasured((prev) => prev.w === next.w && prev.h === next.h ? prev : next);
|
|
15793
15897
|
}, [open, children, title, context]);
|
|
15794
|
-
useEffect11(() => {
|
|
15795
|
-
if (!open || !position || !onPositionChange) return;
|
|
15796
|
-
const next = clampPosition(position, parentScroll, measured.w, measured.h);
|
|
15797
|
-
if (next.x !== position.x || next.y !== position.y) onPositionChange(next);
|
|
15798
|
-
}, [open, parentScroll, measured.w, measured.h, position, onPositionChange]);
|
|
15799
15898
|
const onHeaderPointerDown = useCallback7(
|
|
15800
15899
|
(e) => {
|
|
15801
15900
|
if (e.button !== 0) return;
|
|
@@ -15829,18 +15928,17 @@ function FloatingPanel({
|
|
|
15829
15928
|
return;
|
|
15830
15929
|
}
|
|
15831
15930
|
e.preventDefault();
|
|
15832
|
-
const next =
|
|
15931
|
+
const next = clampDragPosition(
|
|
15833
15932
|
{
|
|
15834
15933
|
x: drag.originX + (e.clientX - drag.startX),
|
|
15835
15934
|
y: drag.originY + (e.clientY - drag.startY)
|
|
15836
15935
|
},
|
|
15837
|
-
|
|
15838
|
-
measured.w
|
|
15839
|
-
measured.h
|
|
15936
|
+
liveScroll,
|
|
15937
|
+
measured.w
|
|
15840
15938
|
);
|
|
15841
15939
|
onPositionChange?.(next);
|
|
15842
15940
|
},
|
|
15843
|
-
[measured.
|
|
15941
|
+
[measured.w, onPositionChange, liveScroll]
|
|
15844
15942
|
);
|
|
15845
15943
|
const endDrag = useCallback7((e) => {
|
|
15846
15944
|
const drag = dragRef.current;
|
|
@@ -15870,7 +15968,7 @@ function FloatingPanel({
|
|
|
15870
15968
|
"fixed z-[2147483647] flex w-64 flex-col overflow-hidden rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
15871
15969
|
className
|
|
15872
15970
|
),
|
|
15873
|
-
style: { left: clamped.x, top: clamped.y },
|
|
15971
|
+
style: { left: clamped.x, top: clamped.y, maxHeight },
|
|
15874
15972
|
onMouseDown: (e) => e.stopPropagation(),
|
|
15875
15973
|
onPointerDown: (e) => e.stopPropagation(),
|
|
15876
15974
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -15879,7 +15977,7 @@ function FloatingPanel({
|
|
|
15879
15977
|
"div",
|
|
15880
15978
|
{
|
|
15881
15979
|
"data-ohw-floating-panel-header": "",
|
|
15882
|
-
className: "relative flex cursor-grab items-start gap-2 border-b border-border py-
|
|
15980
|
+
className: "relative flex shrink-0 cursor-grab items-start gap-2 border-b border-border py-4! pl-5! pr-11! active:cursor-grabbing",
|
|
15883
15981
|
onPointerDown: onHeaderPointerDown,
|
|
15884
15982
|
onPointerMove: onHeaderPointerMove,
|
|
15885
15983
|
onPointerUp: endDrag,
|
|
@@ -15914,7 +16012,11 @@ function FloatingPanel({
|
|
|
15914
16012
|
"div",
|
|
15915
16013
|
{
|
|
15916
16014
|
"data-ohw-floating-panel-body": "",
|
|
15917
|
-
className: cn(
|
|
16015
|
+
className: cn(
|
|
16016
|
+
"flex min-h-0 w-full flex-1 flex-col gap-4 overflow-y-auto overscroll-contain p-4",
|
|
16017
|
+
bodyClassName
|
|
16018
|
+
),
|
|
16019
|
+
style: { WebkitOverflowScrolling: "touch" },
|
|
15918
16020
|
children
|
|
15919
16021
|
}
|
|
15920
16022
|
)
|
|
@@ -15992,199 +16094,1633 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
15992
16094
|
] });
|
|
15993
16095
|
}
|
|
15994
16096
|
|
|
15995
|
-
// src/
|
|
15996
|
-
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16097
|
+
// src/ui/button-style-panel.tsx
|
|
16098
|
+
import { Check as Check3 } from "lucide-react";
|
|
16099
|
+
|
|
16100
|
+
// src/lib/button-styles.ts
|
|
16101
|
+
var BUTTON_VARIANTS_KEY = "__ohw_button_variants";
|
|
16102
|
+
var BUTTON_SIZES_KEY = "__ohw_button_sizes";
|
|
16103
|
+
var BUTTON_ASSIGNMENTS_KEY = "__ohw_button_assignments";
|
|
16104
|
+
var BUTTON_VARIANT_IDS = ["primary", "secondary", "ghost"];
|
|
16105
|
+
var BUTTON_SIZE_IDS = ["s", "m", "l"];
|
|
16106
|
+
var TRANSPARENT = "rgba(0, 0, 0, 0)";
|
|
16107
|
+
var REFERENCE_SIZES = {
|
|
16108
|
+
s: { height: 40, paddingTop: 8, paddingRight: 16, paddingBottom: 8, paddingLeft: 16, fontSize: 15, borderRadius: 8, gap: 8 },
|
|
16109
|
+
m: { height: 48, paddingTop: 12, paddingRight: 24, paddingBottom: 12, paddingLeft: 24, fontSize: 15, borderRadius: 8, gap: 8 },
|
|
16110
|
+
l: { height: 56, paddingTop: 16, paddingRight: 32, paddingBottom: 16, paddingLeft: 32, fontSize: 15, borderRadius: 8, gap: 8 }
|
|
16111
|
+
};
|
|
16112
|
+
function buttonStyleContext(_el) {
|
|
16113
|
+
return "Button";
|
|
16114
|
+
}
|
|
16115
|
+
function previewSlotBackground(el) {
|
|
16116
|
+
let node = el.parentElement;
|
|
16117
|
+
while (node && node !== el.ownerDocument.documentElement) {
|
|
16118
|
+
if (node.closest("[data-ohw-bridge], [data-ohw-bridge-root]")) {
|
|
16119
|
+
node = node.parentElement;
|
|
16120
|
+
continue;
|
|
16121
|
+
}
|
|
16122
|
+
const bg = getComputedStyle(node).backgroundColor;
|
|
16123
|
+
const parsed = parseColor(bg);
|
|
16124
|
+
if (parsed && !isTransparent(parsed)) return bg;
|
|
16125
|
+
node = node.parentElement;
|
|
16000
16126
|
}
|
|
16127
|
+
const root = el.ownerDocument.documentElement;
|
|
16128
|
+
const style = getComputedStyle(root);
|
|
16129
|
+
for (const name of ["--brand-surface", "--brand-background", "--ohw-brand-light", "--color-light"]) {
|
|
16130
|
+
const value = style.getPropertyValue(name).trim();
|
|
16131
|
+
if (value) return value;
|
|
16132
|
+
}
|
|
16133
|
+
return "var(--brand-background, var(--ohw-brand-light, var(--color-light, #ffffff)))";
|
|
16001
16134
|
}
|
|
16002
|
-
function
|
|
16003
|
-
|
|
16004
|
-
|
|
16135
|
+
function buttonId(el) {
|
|
16136
|
+
if (!el) return null;
|
|
16137
|
+
const button = el.matches(CTA_BUTTON_SELECTOR) ? el : el.closest(CTA_BUTTON_SELECTOR);
|
|
16138
|
+
const id = button?.getAttribute("data-ohw-href-key")?.trim();
|
|
16139
|
+
return id || null;
|
|
16005
16140
|
}
|
|
16006
|
-
function
|
|
16007
|
-
|
|
16141
|
+
function isButtonVariantId(value) {
|
|
16142
|
+
return BUTTON_VARIANT_IDS.includes(value);
|
|
16008
16143
|
}
|
|
16009
|
-
function
|
|
16010
|
-
|
|
16011
|
-
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
16012
|
-
clearTextSelection();
|
|
16144
|
+
function isButtonSizeId(value) {
|
|
16145
|
+
return BUTTON_SIZE_IDS.includes(value);
|
|
16013
16146
|
}
|
|
16014
|
-
function
|
|
16015
|
-
const
|
|
16016
|
-
|
|
16017
|
-
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
16018
|
-
if (wasDragging) clearTextSelection();
|
|
16147
|
+
function px(value) {
|
|
16148
|
+
const rounded = Math.round(value * 100) / 100;
|
|
16149
|
+
return `${rounded}px`;
|
|
16019
16150
|
}
|
|
16020
|
-
|
|
16021
|
-
|
|
16022
|
-
|
|
16023
|
-
|
|
16024
|
-
|
|
16025
|
-
|
|
16026
|
-
return listActiveNavbarItems(draggedEl).filter((el) => {
|
|
16027
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
16028
|
-
return isNavbarHrefKey(key) && !isNestedNavChild(el);
|
|
16029
|
-
});
|
|
16151
|
+
function parsePx(value, rootFont = 16) {
|
|
16152
|
+
if (!value) return 0;
|
|
16153
|
+
const n = parseFloat(value);
|
|
16154
|
+
if (!Number.isFinite(n)) return 0;
|
|
16155
|
+
if (value.trim().endsWith("rem") || value.trim().endsWith("em")) return n * rootFont;
|
|
16156
|
+
return n;
|
|
16030
16157
|
}
|
|
16031
|
-
function
|
|
16032
|
-
|
|
16033
|
-
|
|
16034
|
-
|
|
16035
|
-
const trigger = group.querySelector(":scope > [data-ohw-href-key]") ?? Array.from(group.querySelectorAll("[data-ohw-href-key]")).find(
|
|
16036
|
-
(el) => !el.closest("[data-ohw-nav-children]")
|
|
16037
|
-
) ?? null;
|
|
16038
|
-
const key = trigger?.getAttribute("data-ohw-href-key");
|
|
16039
|
-
return key && isNavbarHrefKey(key) ? key : null;
|
|
16158
|
+
function classifyHeight(height) {
|
|
16159
|
+
if (height < 44) return "s";
|
|
16160
|
+
if (height < 52) return "m";
|
|
16161
|
+
return "l";
|
|
16040
16162
|
}
|
|
16041
|
-
function
|
|
16042
|
-
|
|
16043
|
-
|
|
16044
|
-
|
|
16045
|
-
|
|
16046
|
-
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
(
|
|
16050
|
-
|
|
16163
|
+
function scaleGeometry(geometry, scale = 0.75) {
|
|
16164
|
+
return {
|
|
16165
|
+
paddingTop: px(parsePx(geometry.paddingTop) * scale),
|
|
16166
|
+
paddingRight: px(parsePx(geometry.paddingRight) * scale),
|
|
16167
|
+
paddingBottom: px(parsePx(geometry.paddingBottom) * scale),
|
|
16168
|
+
paddingLeft: px(parsePx(geometry.paddingLeft) * scale),
|
|
16169
|
+
fontSize: px(parsePx(geometry.fontSize) * scale),
|
|
16170
|
+
borderRadius: px(parsePx(geometry.borderRadius) * scale),
|
|
16171
|
+
gap: px(parsePx(geometry.gap) * scale),
|
|
16172
|
+
height: Math.round(geometry.height * scale)
|
|
16173
|
+
};
|
|
16051
16174
|
}
|
|
16052
|
-
function
|
|
16053
|
-
const
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
const horizontalGap = b.left - a.right;
|
|
16059
|
-
return verticalGap > horizontalGap;
|
|
16060
|
-
}
|
|
16061
|
-
const container = getActiveNavbarListContainer(draggedEl);
|
|
16062
|
-
if (!container) return false;
|
|
16063
|
-
const style = window.getComputedStyle(container);
|
|
16064
|
-
return style.flexDirection === "column" || style.flexDirection === "column-reverse";
|
|
16175
|
+
function relativeLuminance(color) {
|
|
16176
|
+
const channel = (value) => {
|
|
16177
|
+
const s = value / 255;
|
|
16178
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
16179
|
+
};
|
|
16180
|
+
return 0.2126 * channel(color.r) + 0.7152 * channel(color.g) + 0.0722 * channel(color.b);
|
|
16065
16181
|
}
|
|
16066
|
-
function
|
|
16067
|
-
const
|
|
16068
|
-
const
|
|
16069
|
-
|
|
16070
|
-
|
|
16071
|
-
|
|
16072
|
-
|
|
16073
|
-
|
|
16074
|
-
|
|
16075
|
-
|
|
16076
|
-
|
|
16077
|
-
|
|
16078
|
-
|
|
16079
|
-
|
|
16080
|
-
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
const
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
16088
|
-
|
|
16089
|
-
|
|
16090
|
-
|
|
16091
|
-
|
|
16092
|
-
|
|
16093
|
-
|
|
16094
|
-
|
|
16095
|
-
|
|
16096
|
-
|
|
16097
|
-
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16102
|
-
|
|
16103
|
-
|
|
16104
|
-
|
|
16105
|
-
}
|
|
16106
|
-
|
|
16107
|
-
|
|
16108
|
-
|
|
16109
|
-
|
|
16110
|
-
|
|
16182
|
+
function contrastRatio(a, b) {
|
|
16183
|
+
const lighter = Math.max(relativeLuminance(a), relativeLuminance(b));
|
|
16184
|
+
const darker = Math.min(relativeLuminance(a), relativeLuminance(b));
|
|
16185
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
16186
|
+
}
|
|
16187
|
+
function compositeOver(fg, bg) {
|
|
16188
|
+
const a = fg.a + bg.a * (1 - fg.a);
|
|
16189
|
+
if (a < 1e-3) return { ...bg, a: 0 };
|
|
16190
|
+
return {
|
|
16191
|
+
r: (fg.r * fg.a + bg.r * bg.a * (1 - fg.a)) / a,
|
|
16192
|
+
g: (fg.g * fg.a + bg.g * bg.a * (1 - fg.a)) / a,
|
|
16193
|
+
b: (fg.b * fg.a + bg.b * bg.a * (1 - fg.a)) / a,
|
|
16194
|
+
a
|
|
16195
|
+
};
|
|
16196
|
+
}
|
|
16197
|
+
function previewSlotForChrome(chrome, slotBackground) {
|
|
16198
|
+
const text = parseColor(chrome.color);
|
|
16199
|
+
if (!text || text.a < 0.2) return slotBackground;
|
|
16200
|
+
const slot = parseColor(slotBackground) ?? { r: 250, g: 250, b: 249, a: 1 };
|
|
16201
|
+
const fill = parseColor(chrome.background);
|
|
16202
|
+
const effective = fill && !isTransparent(fill) ? compositeOver(fill, slot) : slot;
|
|
16203
|
+
if (contrastRatio(text, effective) >= 3) return slotBackground;
|
|
16204
|
+
return relativeLuminance(text) > 0.55 ? "#2c2c2c" : "#f4f4f5";
|
|
16205
|
+
}
|
|
16206
|
+
function parseColor(input) {
|
|
16207
|
+
if (!input) return null;
|
|
16208
|
+
const value = input.trim().toLowerCase();
|
|
16209
|
+
if (value === "transparent") return { r: 0, g: 0, b: 0, a: 0 };
|
|
16210
|
+
const hex = value.match(/^#([0-9a-f]{3,8})$/);
|
|
16211
|
+
if (hex) {
|
|
16212
|
+
const raw = hex[1];
|
|
16213
|
+
const expand = (pair) => parseInt(pair.length === 1 ? pair + pair : pair, 16);
|
|
16214
|
+
if (raw.length === 3 || raw.length === 4) {
|
|
16215
|
+
return {
|
|
16216
|
+
r: expand(raw[0]),
|
|
16217
|
+
g: expand(raw[1]),
|
|
16218
|
+
b: expand(raw[2]),
|
|
16219
|
+
a: raw.length === 4 ? expand(raw[3]) / 255 : 1
|
|
16220
|
+
};
|
|
16221
|
+
}
|
|
16222
|
+
if (raw.length === 6 || raw.length === 8) {
|
|
16223
|
+
return {
|
|
16224
|
+
r: expand(raw.slice(0, 2)),
|
|
16225
|
+
g: expand(raw.slice(2, 4)),
|
|
16226
|
+
b: expand(raw.slice(4, 6)),
|
|
16227
|
+
a: raw.length === 8 ? expand(raw.slice(6, 8)) / 255 : 1
|
|
16228
|
+
};
|
|
16111
16229
|
}
|
|
16112
|
-
slots.push({
|
|
16113
|
-
insertIndex: i,
|
|
16114
|
-
parentId: null,
|
|
16115
|
-
left,
|
|
16116
|
-
top,
|
|
16117
|
-
width: Math.max(width, 40),
|
|
16118
|
-
height: barThickness,
|
|
16119
|
-
direction: "horizontal"
|
|
16120
|
-
});
|
|
16121
16230
|
}
|
|
16122
|
-
|
|
16123
|
-
|
|
16124
|
-
|
|
16125
|
-
|
|
16126
|
-
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
if (!container) return slots;
|
|
16130
|
-
const rect = container.getBoundingClientRect();
|
|
16131
|
-
slots.push({
|
|
16132
|
-
insertIndex: 0,
|
|
16133
|
-
parentId: null,
|
|
16134
|
-
left: rect.left + rect.width / 2 - barThickness / 2,
|
|
16135
|
-
top: rect.top,
|
|
16136
|
-
width: barThickness,
|
|
16137
|
-
height: Math.max(rect.height, 24),
|
|
16138
|
-
direction: "vertical"
|
|
16139
|
-
});
|
|
16140
|
-
return slots;
|
|
16231
|
+
const rgb = value.match(
|
|
16232
|
+
/^rgba?\(\s*([\d.]+)[%\s,]+([\d.]+)[%\s,]+([\d.]+)(?:%?\s*[,/]\s*([\d.]+%?))?\s*\)$/
|
|
16233
|
+
);
|
|
16234
|
+
if (rgb) {
|
|
16235
|
+
const alphaRaw = rgb[4];
|
|
16236
|
+
const alpha = alphaRaw == null ? 1 : alphaRaw.endsWith("%") ? parseFloat(alphaRaw) / 100 : parseFloat(alphaRaw);
|
|
16237
|
+
return { r: Number(rgb[1]), g: Number(rgb[2]), b: Number(rgb[3]), a: alpha };
|
|
16141
16238
|
}
|
|
16142
|
-
const
|
|
16143
|
-
|
|
16144
|
-
|
|
16145
|
-
|
|
16146
|
-
|
|
16147
|
-
|
|
16148
|
-
|
|
16149
|
-
|
|
16150
|
-
|
|
16151
|
-
|
|
16152
|
-
if (i === 0) {
|
|
16153
|
-
const first = items[0].getBoundingClientRect();
|
|
16154
|
-
left = first.left - edgeGap / 2 - barThickness / 2;
|
|
16155
|
-
top = first.top;
|
|
16156
|
-
height = first.height;
|
|
16157
|
-
} else if (i === items.length) {
|
|
16158
|
-
const last = items[items.length - 1].getBoundingClientRect();
|
|
16159
|
-
const lastGap = items.length >= 2 ? Math.max(0, last.left - items[items.length - 2].getBoundingClientRect().right) : edgeGap;
|
|
16160
|
-
left = last.right + lastGap / 2 - barThickness / 2;
|
|
16161
|
-
top = last.top;
|
|
16162
|
-
height = last.height;
|
|
16163
|
-
} else {
|
|
16164
|
-
const prev = items[i - 1].getBoundingClientRect();
|
|
16165
|
-
const next = items[i].getBoundingClientRect();
|
|
16166
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
16167
|
-
top = Math.min(prev.top, next.top);
|
|
16168
|
-
height = Math.max(prev.bottom, next.bottom) - top;
|
|
16169
|
-
}
|
|
16170
|
-
slots.push({
|
|
16171
|
-
insertIndex: i,
|
|
16172
|
-
parentId: null,
|
|
16173
|
-
left,
|
|
16174
|
-
top,
|
|
16175
|
-
width: barThickness,
|
|
16176
|
-
height: Math.max(height, 24),
|
|
16177
|
-
direction: "vertical"
|
|
16178
|
-
});
|
|
16239
|
+
const oklch = value.match(
|
|
16240
|
+
/^oklch\(\s*([\d.]+%?)\s+([\d.]+)\s+([\d.]+)(?:deg)?(?:\s*\/\s*([\d.]+%?))?\s*\)$/
|
|
16241
|
+
);
|
|
16242
|
+
if (oklch) {
|
|
16243
|
+
const Lraw = oklch[1];
|
|
16244
|
+
const L = Lraw.endsWith("%") ? parseFloat(Lraw) / 100 : parseFloat(Lraw);
|
|
16245
|
+
const gray = Math.max(0, Math.min(1, L)) * 255;
|
|
16246
|
+
const alphaRaw = oklch[4];
|
|
16247
|
+
const alpha = alphaRaw == null ? 1 : alphaRaw.endsWith("%") ? parseFloat(alphaRaw) / 100 : parseFloat(alphaRaw);
|
|
16248
|
+
return { r: gray, g: gray, b: gray, a: alpha };
|
|
16179
16249
|
}
|
|
16180
|
-
return
|
|
16250
|
+
return null;
|
|
16181
16251
|
}
|
|
16182
|
-
function
|
|
16183
|
-
|
|
16184
|
-
|
|
16185
|
-
|
|
16252
|
+
function isTransparent(color) {
|
|
16253
|
+
return !color || color.a < 0.05;
|
|
16254
|
+
}
|
|
16255
|
+
function hasOpaqueBackground(background) {
|
|
16256
|
+
if (!background) return false;
|
|
16257
|
+
const value = background.trim().toLowerCase();
|
|
16258
|
+
if (!value || value === "transparent" || value === "rgba(0, 0, 0, 0)" || value === "rgb(0, 0, 0, 0)") {
|
|
16259
|
+
return false;
|
|
16186
16260
|
}
|
|
16187
|
-
|
|
16261
|
+
const parsed = parseColor(background);
|
|
16262
|
+
if (parsed) return !isTransparent(parsed);
|
|
16263
|
+
return true;
|
|
16264
|
+
}
|
|
16265
|
+
function toCss(color) {
|
|
16266
|
+
const r2 = Math.round(color.r);
|
|
16267
|
+
const g = Math.round(color.g);
|
|
16268
|
+
const b = Math.round(color.b);
|
|
16269
|
+
if (color.a >= 0.995) return `rgb(${r2}, ${g}, ${b})`;
|
|
16270
|
+
return `rgba(${r2}, ${g}, ${b}, ${Math.round(color.a * 100) / 100})`;
|
|
16271
|
+
}
|
|
16272
|
+
function colorKey(input) {
|
|
16273
|
+
const parsed = parseColor(input);
|
|
16274
|
+
if (!parsed || isTransparent(parsed)) return "transparent";
|
|
16275
|
+
return `${Math.round(parsed.r / 8)}-${Math.round(parsed.g / 8)}-${Math.round(parsed.b / 8)}-${Math.round(parsed.a * 4)}`;
|
|
16276
|
+
}
|
|
16277
|
+
function declaredVariant(className) {
|
|
16278
|
+
const match = className.match(/\bbtn--(primary|secondary|ghost)\b/);
|
|
16279
|
+
return match && isButtonVariantId(match[1]) ? match[1] : null;
|
|
16280
|
+
}
|
|
16281
|
+
function fillSlot(sample) {
|
|
16282
|
+
const width = parseFloat(sample.borderWidth);
|
|
16283
|
+
const border = parseColor(sample.borderColor);
|
|
16284
|
+
if (width > 0 && !isTransparent(border)) return "secondary";
|
|
16285
|
+
if (hasOpaqueBackground(sample.background)) return "primary";
|
|
16286
|
+
return "ghost";
|
|
16287
|
+
}
|
|
16288
|
+
function sampleSlot(sample) {
|
|
16289
|
+
return declaredVariant(sample.className) ?? fillSlot(sample);
|
|
16290
|
+
}
|
|
16291
|
+
function fingerprint(sample) {
|
|
16292
|
+
const width = parseFloat(sample.borderWidth);
|
|
16293
|
+
const border = width > 0 ? colorKey(sample.borderColor) : "none";
|
|
16294
|
+
return `${colorKey(sample.background)}|${border}|${colorKey(sample.color)}|${sampleSlot(sample)}`;
|
|
16295
|
+
}
|
|
16296
|
+
function paintColor(chrome) {
|
|
16297
|
+
if (hasOpaqueBackground(chrome.background)) {
|
|
16298
|
+
const parsed = parseColor(chrome.background);
|
|
16299
|
+
return parsed ? toCss({ ...parsed, a: 1 }) : chrome.background;
|
|
16300
|
+
}
|
|
16301
|
+
const width = parseFloat(chrome.borderWidth);
|
|
16302
|
+
if (width > 0 && hasOpaqueBackground(chrome.borderColor)) {
|
|
16303
|
+
const parsed = parseColor(chrome.borderColor);
|
|
16304
|
+
return parsed ? toCss({ ...parsed, a: 1 }) : chrome.borderColor;
|
|
16305
|
+
}
|
|
16306
|
+
const text = parseColor(chrome.color);
|
|
16307
|
+
return text ? toCss({ ...text, a: 1 }) : chrome.color;
|
|
16308
|
+
}
|
|
16309
|
+
function accentColor(chrome) {
|
|
16310
|
+
const bg = parseColor(chrome.background);
|
|
16311
|
+
if (bg && !isTransparent(bg) && relativeLuminance(bg) < 0.55) {
|
|
16312
|
+
return toCss({ ...bg, a: 1 });
|
|
16313
|
+
}
|
|
16314
|
+
const text = parseColor(chrome.color);
|
|
16315
|
+
if (text && !isTransparent(text)) return toCss({ ...text, a: 1 });
|
|
16316
|
+
return paintColor(chrome);
|
|
16317
|
+
}
|
|
16318
|
+
function chromeFrom(sample) {
|
|
16319
|
+
return {
|
|
16320
|
+
background: sample.background || TRANSPARENT,
|
|
16321
|
+
color: sample.color || "currentColor",
|
|
16322
|
+
borderColor: sample.borderColor || TRANSPARENT,
|
|
16323
|
+
borderWidth: sample.borderWidth || "0px"
|
|
16324
|
+
};
|
|
16325
|
+
}
|
|
16326
|
+
function filledPrimary(seed) {
|
|
16327
|
+
const paint = parseColor(paintColor(seed)) ?? { r: 15, g: 15, b: 15, a: 1 };
|
|
16328
|
+
const luminance = relativeLuminance(paint);
|
|
16329
|
+
return {
|
|
16330
|
+
background: toCss({ ...paint, a: 1 }),
|
|
16331
|
+
color: luminance > 0.55 ? "rgb(15, 15, 15)" : "rgb(255, 255, 255)",
|
|
16332
|
+
borderColor: TRANSPARENT,
|
|
16333
|
+
borderWidth: "0px"
|
|
16334
|
+
};
|
|
16335
|
+
}
|
|
16336
|
+
function generatedSecondary(primary) {
|
|
16337
|
+
const paint = accentColor(primary);
|
|
16338
|
+
return {
|
|
16339
|
+
background: TRANSPARENT,
|
|
16340
|
+
color: paint,
|
|
16341
|
+
borderColor: paint,
|
|
16342
|
+
borderWidth: "1px"
|
|
16343
|
+
};
|
|
16344
|
+
}
|
|
16345
|
+
function generatedGhost(primary) {
|
|
16346
|
+
return {
|
|
16347
|
+
background: TRANSPARENT,
|
|
16348
|
+
color: accentColor(primary),
|
|
16349
|
+
borderColor: TRANSPARENT,
|
|
16350
|
+
borderWidth: "0px"
|
|
16351
|
+
};
|
|
16352
|
+
}
|
|
16353
|
+
function normalizeOutlineChrome(outline, primary) {
|
|
16354
|
+
const paint = accentColor(primary);
|
|
16355
|
+
const text = parseColor(outline.color);
|
|
16356
|
+
const paintRgb = parseColor(paint);
|
|
16357
|
+
const primaryLabel = parseColor(primary.color);
|
|
16358
|
+
const matchesOnPrimary = Boolean(text && primaryLabel) && colorKey(outline.color) === colorKey(primary.color);
|
|
16359
|
+
const textTooLight = text ? relativeLuminance(text) > 0.7 : false;
|
|
16360
|
+
const paintIsDarker = paintRgb ? relativeLuminance(paintRgb) < 0.65 : hasOpaqueBackground(primary.background);
|
|
16361
|
+
if (!(matchesOnPrimary || textTooLight) || !paintIsDarker) return outline;
|
|
16362
|
+
const hasBorder = parseFloat(outline.borderWidth) > 0;
|
|
16363
|
+
return {
|
|
16364
|
+
...outline,
|
|
16365
|
+
color: paint,
|
|
16366
|
+
borderColor: hasBorder ? paint : outline.borderColor
|
|
16367
|
+
};
|
|
16368
|
+
}
|
|
16369
|
+
function generateButtonVariants(samples) {
|
|
16370
|
+
if (samples.length === 0) return { status: "unresolved" };
|
|
16371
|
+
const groups = /* @__PURE__ */ new Map();
|
|
16372
|
+
for (const sample of samples) {
|
|
16373
|
+
const key = fingerprint(sample);
|
|
16374
|
+
const list = groups.get(key) ?? [];
|
|
16375
|
+
list.push(sample);
|
|
16376
|
+
groups.set(key, list);
|
|
16377
|
+
}
|
|
16378
|
+
if (groups.size > 3) return { status: "unresolved" };
|
|
16379
|
+
const bySlot = /* @__PURE__ */ new Map();
|
|
16380
|
+
for (const group of groups.values()) {
|
|
16381
|
+
const sample = group[0];
|
|
16382
|
+
const slot = sampleSlot(sample);
|
|
16383
|
+
if (bySlot.has(slot)) return { status: "unresolved" };
|
|
16384
|
+
bySlot.set(slot, sample);
|
|
16385
|
+
}
|
|
16386
|
+
const primarySample = bySlot.get("primary");
|
|
16387
|
+
const seed = chromeFrom(primarySample ?? samples[0]);
|
|
16388
|
+
const primary = primarySample ? seed : filledPrimary(seed);
|
|
16389
|
+
const secondary = normalizeOutlineChrome(
|
|
16390
|
+
bySlot.has("secondary") ? chromeFrom(bySlot.get("secondary")) : generatedSecondary(primary),
|
|
16391
|
+
primary
|
|
16392
|
+
);
|
|
16393
|
+
const ghost = normalizeOutlineChrome(
|
|
16394
|
+
bySlot.has("ghost") ? chromeFrom(bySlot.get("ghost")) : generatedGhost(primary),
|
|
16395
|
+
primary
|
|
16396
|
+
);
|
|
16397
|
+
return {
|
|
16398
|
+
status: "ready",
|
|
16399
|
+
tokens: { primary, secondary, ghost }
|
|
16400
|
+
};
|
|
16401
|
+
}
|
|
16402
|
+
function geometryFromSample(sample) {
|
|
16403
|
+
return {
|
|
16404
|
+
paddingTop: px(sample.paddingTop),
|
|
16405
|
+
paddingRight: px(sample.paddingRight),
|
|
16406
|
+
paddingBottom: px(sample.paddingBottom),
|
|
16407
|
+
paddingLeft: px(sample.paddingLeft),
|
|
16408
|
+
fontSize: px(sample.fontSize),
|
|
16409
|
+
borderRadius: px(sample.borderRadius),
|
|
16410
|
+
gap: px(sample.gap),
|
|
16411
|
+
height: Math.round(sample.height)
|
|
16412
|
+
};
|
|
16413
|
+
}
|
|
16414
|
+
function shiftSample(base, steps) {
|
|
16415
|
+
return {
|
|
16416
|
+
height: Math.max(24, base.height + steps * 8),
|
|
16417
|
+
paddingTop: Math.max(0, base.paddingTop + steps * 4),
|
|
16418
|
+
paddingBottom: Math.max(0, base.paddingBottom + steps * 4),
|
|
16419
|
+
paddingLeft: Math.max(0, base.paddingLeft + steps * 8),
|
|
16420
|
+
paddingRight: Math.max(0, base.paddingRight + steps * 8),
|
|
16421
|
+
fontSize: base.fontSize,
|
|
16422
|
+
borderRadius: base.borderRadius,
|
|
16423
|
+
gap: base.gap
|
|
16424
|
+
};
|
|
16425
|
+
}
|
|
16426
|
+
function clusterSizes(samples) {
|
|
16427
|
+
const sorted = [...samples].sort((a, b) => a.height - b.height);
|
|
16428
|
+
const clusters = [];
|
|
16429
|
+
for (const sample of sorted) {
|
|
16430
|
+
const current = clusters[clusters.length - 1];
|
|
16431
|
+
const head = current?.[0];
|
|
16432
|
+
if (!current || !head || Math.abs(sample.height - head.height) > 2) clusters.push([sample]);
|
|
16433
|
+
else current.push(sample);
|
|
16434
|
+
}
|
|
16435
|
+
return clusters.map((group) => {
|
|
16436
|
+
const pick = (key) => group.reduce((sum, item) => sum + item[key], 0) / group.length;
|
|
16437
|
+
return {
|
|
16438
|
+
height: pick("height"),
|
|
16439
|
+
paddingTop: pick("paddingTop"),
|
|
16440
|
+
paddingRight: pick("paddingRight"),
|
|
16441
|
+
paddingBottom: pick("paddingBottom"),
|
|
16442
|
+
paddingLeft: pick("paddingLeft"),
|
|
16443
|
+
fontSize: pick("fontSize"),
|
|
16444
|
+
borderRadius: pick("borderRadius"),
|
|
16445
|
+
gap: pick("gap")
|
|
16446
|
+
};
|
|
16447
|
+
});
|
|
16448
|
+
}
|
|
16449
|
+
function tokensFromSamples(bySlot, radius, gap) {
|
|
16450
|
+
const fill = (id) => {
|
|
16451
|
+
const sample = bySlot[id] ?? REFERENCE_SIZES[id];
|
|
16452
|
+
return geometryFromSample({ ...sample, borderRadius: radius, gap });
|
|
16453
|
+
};
|
|
16454
|
+
return { s: fill("s"), m: fill("m"), l: fill("l") };
|
|
16455
|
+
}
|
|
16456
|
+
function interpolateSizes(known) {
|
|
16457
|
+
const order = BUTTON_SIZE_IDS;
|
|
16458
|
+
const indexOf = (id) => order.indexOf(id);
|
|
16459
|
+
const sorted = [...known].sort((a, b) => indexOf(a.id) - indexOf(b.id));
|
|
16460
|
+
const left = sorted[0];
|
|
16461
|
+
const right = sorted[1];
|
|
16462
|
+
const span = indexOf(right.id) - indexOf(left.id);
|
|
16463
|
+
const step = (key) => (right.sample[key] - left.sample[key]) / span;
|
|
16464
|
+
const at = (index) => {
|
|
16465
|
+
const steps = index - indexOf(left.id);
|
|
16466
|
+
return {
|
|
16467
|
+
height: left.sample.height + step("height") * steps,
|
|
16468
|
+
paddingTop: Math.max(0, left.sample.paddingTop + step("paddingTop") * steps),
|
|
16469
|
+
paddingBottom: Math.max(0, left.sample.paddingBottom + step("paddingBottom") * steps),
|
|
16470
|
+
paddingLeft: Math.max(0, left.sample.paddingLeft + step("paddingLeft") * steps),
|
|
16471
|
+
paddingRight: Math.max(0, left.sample.paddingRight + step("paddingRight") * steps),
|
|
16472
|
+
fontSize: Math.max(10, left.sample.fontSize + step("fontSize") * steps),
|
|
16473
|
+
borderRadius: left.sample.borderRadius,
|
|
16474
|
+
gap: left.sample.gap
|
|
16475
|
+
};
|
|
16476
|
+
};
|
|
16477
|
+
const bySlot = {
|
|
16478
|
+
[left.id]: left.sample,
|
|
16479
|
+
[right.id]: { ...right.sample, borderRadius: left.sample.borderRadius, gap: left.sample.gap }
|
|
16480
|
+
};
|
|
16481
|
+
for (const id of order) {
|
|
16482
|
+
if (!bySlot[id]) bySlot[id] = at(indexOf(id));
|
|
16483
|
+
}
|
|
16484
|
+
return tokensFromSamples(bySlot, left.sample.borderRadius, left.sample.gap);
|
|
16485
|
+
}
|
|
16486
|
+
function generateButtonSizes(samples) {
|
|
16487
|
+
const clusters = clusterSizes(samples.filter((sample) => sample.height > 0));
|
|
16488
|
+
if (clusters.length === 0) {
|
|
16489
|
+
return { status: "ready", tokens: tokensFromSamples(REFERENCE_SIZES, 8, 8) };
|
|
16490
|
+
}
|
|
16491
|
+
if (clusters.length > 3) return { status: "unresolved" };
|
|
16492
|
+
if (clusters.length === 3) {
|
|
16493
|
+
const sorted = [...clusters].sort((a, b) => a.height - b.height);
|
|
16494
|
+
const radius = sorted[1].borderRadius;
|
|
16495
|
+
const gap = sorted[1].gap;
|
|
16496
|
+
return {
|
|
16497
|
+
status: "ready",
|
|
16498
|
+
tokens: {
|
|
16499
|
+
s: geometryFromSample({ ...sorted[0], borderRadius: radius, gap }),
|
|
16500
|
+
m: geometryFromSample({ ...sorted[1], borderRadius: radius, gap }),
|
|
16501
|
+
l: geometryFromSample({ ...sorted[2], borderRadius: radius, gap })
|
|
16502
|
+
}
|
|
16503
|
+
};
|
|
16504
|
+
}
|
|
16505
|
+
if (clusters.length === 1) {
|
|
16506
|
+
const known = clusters[0];
|
|
16507
|
+
const slot = classifyHeight(known.height);
|
|
16508
|
+
const offset = BUTTON_SIZE_IDS.indexOf(slot);
|
|
16509
|
+
const bySlot = Object.fromEntries(
|
|
16510
|
+
BUTTON_SIZE_IDS.map((id, index) => [id, shiftSample(known, index - offset)])
|
|
16511
|
+
);
|
|
16512
|
+
bySlot[slot] = known;
|
|
16513
|
+
return { status: "ready", tokens: tokensFromSamples(bySlot, known.borderRadius, known.gap) };
|
|
16514
|
+
}
|
|
16515
|
+
const mapped = clusters.map((sample) => ({ id: classifyHeight(sample.height), sample }));
|
|
16516
|
+
if (mapped[0].id === mapped[1].id) {
|
|
16517
|
+
const larger = clusters.slice().sort((a, b) => b.height - a.height)[0];
|
|
16518
|
+
return generateButtonSizes([larger]);
|
|
16519
|
+
}
|
|
16520
|
+
return { status: "ready", tokens: interpolateSizes(mapped) };
|
|
16521
|
+
}
|
|
16522
|
+
function parseJson(raw) {
|
|
16523
|
+
if (!raw) return null;
|
|
16524
|
+
try {
|
|
16525
|
+
return JSON.parse(raw);
|
|
16526
|
+
} catch {
|
|
16527
|
+
return null;
|
|
16528
|
+
}
|
|
16529
|
+
}
|
|
16530
|
+
function isChrome(value) {
|
|
16531
|
+
if (!value || typeof value !== "object") return false;
|
|
16532
|
+
const chrome = value;
|
|
16533
|
+
return typeof chrome.background === "string" && typeof chrome.color === "string";
|
|
16534
|
+
}
|
|
16535
|
+
function isGeometry(value) {
|
|
16536
|
+
if (!value || typeof value !== "object") return false;
|
|
16537
|
+
const geometry = value;
|
|
16538
|
+
return typeof geometry.paddingTop === "string" && typeof geometry.height === "number";
|
|
16539
|
+
}
|
|
16540
|
+
function readVariantTokens(content) {
|
|
16541
|
+
const parsed = parseJson(content[BUTTON_VARIANTS_KEY]);
|
|
16542
|
+
if (!parsed) return null;
|
|
16543
|
+
if (!BUTTON_VARIANT_IDS.every((id) => isChrome(parsed[id]))) return null;
|
|
16544
|
+
return parsed;
|
|
16545
|
+
}
|
|
16546
|
+
function readSizeTokens(content) {
|
|
16547
|
+
const parsed = parseJson(content[BUTTON_SIZES_KEY]);
|
|
16548
|
+
if (!parsed) return null;
|
|
16549
|
+
if (!BUTTON_SIZE_IDS.every((id) => isGeometry(parsed[id]))) return null;
|
|
16550
|
+
return parsed;
|
|
16551
|
+
}
|
|
16552
|
+
function readAssignments(content) {
|
|
16553
|
+
const parsed = parseJson(content[BUTTON_ASSIGNMENTS_KEY]);
|
|
16554
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
16555
|
+
const next = {};
|
|
16556
|
+
for (const [id, value] of Object.entries(parsed)) {
|
|
16557
|
+
if (!value || !isButtonVariantId(value.variant) || !isButtonSizeId(value.size)) continue;
|
|
16558
|
+
next[id] = { variant: value.variant, size: value.size };
|
|
16559
|
+
}
|
|
16560
|
+
return next;
|
|
16561
|
+
}
|
|
16562
|
+
function cssLength(style, prop) {
|
|
16563
|
+
return style.getPropertyValue(prop) || "0px";
|
|
16564
|
+
}
|
|
16565
|
+
function readVariantSample(el) {
|
|
16566
|
+
const style = getComputedStyle(el);
|
|
16567
|
+
return {
|
|
16568
|
+
background: style.backgroundColor,
|
|
16569
|
+
color: style.color,
|
|
16570
|
+
borderColor: style.borderTopColor,
|
|
16571
|
+
borderWidth: style.borderTopWidth,
|
|
16572
|
+
className: el.className || ""
|
|
16573
|
+
};
|
|
16574
|
+
}
|
|
16575
|
+
function readSizeSample(el) {
|
|
16576
|
+
const style = getComputedStyle(el);
|
|
16577
|
+
const rootFont = parsePx(getComputedStyle(el.ownerDocument.documentElement).fontSize) || 16;
|
|
16578
|
+
const rect = el.getBoundingClientRect();
|
|
16579
|
+
return {
|
|
16580
|
+
height: rect.height,
|
|
16581
|
+
paddingTop: parsePx(cssLength(style, "padding-top"), rootFont),
|
|
16582
|
+
paddingRight: parsePx(cssLength(style, "padding-right"), rootFont),
|
|
16583
|
+
paddingBottom: parsePx(cssLength(style, "padding-bottom"), rootFont),
|
|
16584
|
+
paddingLeft: parsePx(cssLength(style, "padding-left"), rootFont),
|
|
16585
|
+
fontSize: parsePx(style.fontSize, rootFont),
|
|
16586
|
+
borderRadius: parsePx(style.borderTopLeftRadius, rootFont),
|
|
16587
|
+
gap: parsePx(style.columnGap || style.gap, rootFont)
|
|
16588
|
+
};
|
|
16589
|
+
}
|
|
16590
|
+
function readTypography(el) {
|
|
16591
|
+
const style = getComputedStyle(el);
|
|
16592
|
+
return {
|
|
16593
|
+
fontFamily: style.fontFamily,
|
|
16594
|
+
fontWeight: style.fontWeight,
|
|
16595
|
+
letterSpacing: style.letterSpacing,
|
|
16596
|
+
textTransform: style.textTransform,
|
|
16597
|
+
textDecoration: style.textDecorationLine || style.textDecoration || "none"
|
|
16598
|
+
};
|
|
16599
|
+
}
|
|
16600
|
+
var buttonOriginByEl = /* @__PURE__ */ new WeakMap();
|
|
16601
|
+
var ORIGIN_ATTR = "data-ohw-btn-origin";
|
|
16602
|
+
function parseOriginAttr(raw) {
|
|
16603
|
+
if (!raw) return null;
|
|
16604
|
+
try {
|
|
16605
|
+
const value = JSON.parse(raw);
|
|
16606
|
+
if (!value?.variant || !value.size || !value.typography) return null;
|
|
16607
|
+
return value;
|
|
16608
|
+
} catch {
|
|
16609
|
+
return null;
|
|
16610
|
+
}
|
|
16611
|
+
}
|
|
16612
|
+
function measureLiveOrigin(el) {
|
|
16613
|
+
return {
|
|
16614
|
+
variant: readVariantSample(el),
|
|
16615
|
+
size: readSizeSample(el),
|
|
16616
|
+
typography: readTypography(el)
|
|
16617
|
+
};
|
|
16618
|
+
}
|
|
16619
|
+
function captureButtonOrigin(el) {
|
|
16620
|
+
const cached = buttonOriginByEl.get(el);
|
|
16621
|
+
if (cached) return cached;
|
|
16622
|
+
const fromAttr = parseOriginAttr(el.getAttribute(ORIGIN_ATTR));
|
|
16623
|
+
if (fromAttr) {
|
|
16624
|
+
buttonOriginByEl.set(el, fromAttr);
|
|
16625
|
+
return fromAttr;
|
|
16626
|
+
}
|
|
16627
|
+
const origin = measureLiveOrigin(el);
|
|
16628
|
+
buttonOriginByEl.set(el, origin);
|
|
16629
|
+
try {
|
|
16630
|
+
el.setAttribute(ORIGIN_ATTR, JSON.stringify(origin));
|
|
16631
|
+
} catch {
|
|
16632
|
+
}
|
|
16633
|
+
return origin;
|
|
16634
|
+
}
|
|
16635
|
+
function listStyleButtons(doc) {
|
|
16636
|
+
return Array.from(doc.querySelectorAll(CTA_BUTTON_SELECTOR)).filter((el) => {
|
|
16637
|
+
if (el.closest("[data-ohw-bridge], [data-ohw-bridge-root]")) return false;
|
|
16638
|
+
const rect = el.getBoundingClientRect();
|
|
16639
|
+
return rect.width > 0 && rect.height > 0;
|
|
16640
|
+
});
|
|
16641
|
+
}
|
|
16642
|
+
function generateTokensFromButtons(buttons) {
|
|
16643
|
+
const variants = generateButtonVariants(buttons.map(readVariantSample));
|
|
16644
|
+
const sizes = generateButtonSizes(buttons.map(readSizeSample));
|
|
16645
|
+
if (variants.status !== "ready" || sizes.status !== "ready") return { status: "unresolved" };
|
|
16646
|
+
return { status: "ready", tokens: { variants: variants.tokens, sizes: sizes.tokens } };
|
|
16647
|
+
}
|
|
16648
|
+
function tokensFromButton(el) {
|
|
16649
|
+
const origin = captureButtonOrigin(el);
|
|
16650
|
+
const sample = origin.variant;
|
|
16651
|
+
const variants = generateButtonVariants([sample]);
|
|
16652
|
+
const sizes = generateButtonSizes([origin.size]);
|
|
16653
|
+
const primary = chromeFrom(sample);
|
|
16654
|
+
return {
|
|
16655
|
+
variants: variants.status === "ready" ? variants.tokens : { primary, secondary: generatedSecondary(primary), ghost: generatedGhost(primary) },
|
|
16656
|
+
sizes: sizes.status === "ready" ? sizes.tokens : tokensFromSamples(REFERENCE_SIZES, 8, 8)
|
|
16657
|
+
};
|
|
16658
|
+
}
|
|
16659
|
+
function readStoredStyleTokens(content) {
|
|
16660
|
+
const variants = readVariantTokens(content);
|
|
16661
|
+
const sizes = readSizeTokens(content);
|
|
16662
|
+
if (!variants || !sizes) return null;
|
|
16663
|
+
return { variants, sizes };
|
|
16664
|
+
}
|
|
16665
|
+
function styleTokenNodes(tokens) {
|
|
16666
|
+
return [
|
|
16667
|
+
{ key: BUTTON_VARIANTS_KEY, text: JSON.stringify(tokens.variants) },
|
|
16668
|
+
{ key: BUTTON_SIZES_KEY, text: JSON.stringify(tokens.sizes) }
|
|
16669
|
+
];
|
|
16670
|
+
}
|
|
16671
|
+
function ensureButtonStyleTokens(doc, content) {
|
|
16672
|
+
const stored = readStoredStyleTokens(content);
|
|
16673
|
+
if (stored) return { tokens: stored, nodes: [] };
|
|
16674
|
+
const generated = generateTokensFromButtons(listStyleButtons(doc));
|
|
16675
|
+
if (generated.status !== "ready") return { tokens: null, nodes: [] };
|
|
16676
|
+
return { tokens: generated.tokens, nodes: styleTokenNodes(generated.tokens) };
|
|
16677
|
+
}
|
|
16678
|
+
function detectVariant(el, tokens) {
|
|
16679
|
+
const declared = declaredVariant(el.className || "");
|
|
16680
|
+
if (declared) return declared;
|
|
16681
|
+
const stamped = el.getAttribute("data-ohw-btn-variant");
|
|
16682
|
+
if (stamped && isButtonVariantId(stamped)) return stamped;
|
|
16683
|
+
const sample = readVariantSample(el);
|
|
16684
|
+
if (!tokens) return sampleSlot(sample);
|
|
16685
|
+
const key = fingerprint(sample);
|
|
16686
|
+
for (const id of BUTTON_VARIANT_IDS) {
|
|
16687
|
+
const chrome = tokens[id];
|
|
16688
|
+
const tokenKey = fingerprint({
|
|
16689
|
+
background: chrome.background,
|
|
16690
|
+
color: chrome.color,
|
|
16691
|
+
borderColor: chrome.borderColor,
|
|
16692
|
+
borderWidth: chrome.borderWidth,
|
|
16693
|
+
className: `btn btn--${id}`
|
|
16694
|
+
});
|
|
16695
|
+
if (tokenKey === key) return id;
|
|
16696
|
+
}
|
|
16697
|
+
return sampleSlot(sample);
|
|
16698
|
+
}
|
|
16699
|
+
function detectSize(el, tokens) {
|
|
16700
|
+
const stamped = el.getAttribute("data-ohw-btn-size");
|
|
16701
|
+
if (stamped && isButtonSizeId(stamped)) return stamped;
|
|
16702
|
+
const height = el.getBoundingClientRect().height;
|
|
16703
|
+
if (!tokens) return classifyHeight(height);
|
|
16704
|
+
let best = "m";
|
|
16705
|
+
let bestDelta = Number.POSITIVE_INFINITY;
|
|
16706
|
+
for (const id of BUTTON_SIZE_IDS) {
|
|
16707
|
+
const delta = Math.abs(tokens[id].height - height);
|
|
16708
|
+
if (delta < bestDelta) {
|
|
16709
|
+
best = id;
|
|
16710
|
+
bestDelta = delta;
|
|
16711
|
+
}
|
|
16712
|
+
}
|
|
16713
|
+
return best;
|
|
16714
|
+
}
|
|
16715
|
+
function assignmentFor(el, content, tokens) {
|
|
16716
|
+
const id = buttonId(el);
|
|
16717
|
+
const stored = id ? readAssignments(content)[id] : void 0;
|
|
16718
|
+
if (stored) return stored;
|
|
16719
|
+
return {
|
|
16720
|
+
variant: detectVariant(el, tokens?.variants ?? null),
|
|
16721
|
+
size: detectSize(el, tokens?.sizes ?? null)
|
|
16722
|
+
};
|
|
16723
|
+
}
|
|
16724
|
+
function labelElement(el) {
|
|
16725
|
+
return el.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? (el.matches('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ? el : null);
|
|
16726
|
+
}
|
|
16727
|
+
var paintLockByEl = /* @__PURE__ */ new WeakMap();
|
|
16728
|
+
var paintObserverByEl = /* @__PURE__ */ new WeakMap();
|
|
16729
|
+
var paintingButton = false;
|
|
16730
|
+
function paintButtonChrome(el, assignment, tokens) {
|
|
16731
|
+
const origin = captureButtonOrigin(el);
|
|
16732
|
+
const chrome = tokens.variants[assignment.variant];
|
|
16733
|
+
const originSlot = classifyHeight(origin.size.height);
|
|
16734
|
+
const geometry = assignment.size === originSlot ? geometryFromSample({ ...origin.size, borderRadius: origin.size.borderRadius, gap: origin.size.gap }) : tokens.sizes[assignment.size];
|
|
16735
|
+
const { typography } = origin;
|
|
16736
|
+
el.setAttribute("data-ohw-btn-variant", assignment.variant);
|
|
16737
|
+
el.setAttribute("data-ohw-btn-size", assignment.size);
|
|
16738
|
+
el.style.transition = "none";
|
|
16739
|
+
el.style.boxSizing = "border-box";
|
|
16740
|
+
el.style.display = "inline-flex";
|
|
16741
|
+
el.style.alignItems = "center";
|
|
16742
|
+
el.style.justifyContent = "center";
|
|
16743
|
+
el.style.background = chrome.background;
|
|
16744
|
+
el.style.color = chrome.color;
|
|
16745
|
+
el.style.borderStyle = parseFloat(chrome.borderWidth) > 0 ? "solid" : "none";
|
|
16746
|
+
el.style.borderColor = chrome.borderColor;
|
|
16747
|
+
el.style.borderWidth = chrome.borderWidth;
|
|
16748
|
+
el.style.padding = `${geometry.paddingTop} ${geometry.paddingRight} ${geometry.paddingBottom} ${geometry.paddingLeft}`;
|
|
16749
|
+
el.style.fontSize = geometry.fontSize;
|
|
16750
|
+
el.style.borderRadius = px(origin.size.borderRadius);
|
|
16751
|
+
el.style.gap = geometry.gap;
|
|
16752
|
+
el.style.height = px(geometry.height);
|
|
16753
|
+
el.style.fontFamily = typography.fontFamily;
|
|
16754
|
+
el.style.fontWeight = typography.fontWeight;
|
|
16755
|
+
el.style.letterSpacing = typography.letterSpacing;
|
|
16756
|
+
el.style.textTransform = typography.textTransform;
|
|
16757
|
+
if (typography.textDecoration && typography.textDecoration !== "none") {
|
|
16758
|
+
el.style.textDecoration = typography.textDecoration;
|
|
16759
|
+
} else {
|
|
16760
|
+
el.style.textDecoration = "none";
|
|
16761
|
+
}
|
|
16762
|
+
const label = labelElement(el);
|
|
16763
|
+
if (label && label !== el) label.style.color = chrome.color;
|
|
16764
|
+
}
|
|
16765
|
+
function guardTemplateHover(el) {
|
|
16766
|
+
if (paintObserverByEl.has(el)) return;
|
|
16767
|
+
const observer = new MutationObserver(() => {
|
|
16768
|
+
if (paintingButton) return;
|
|
16769
|
+
const lock = paintLockByEl.get(el);
|
|
16770
|
+
if (!lock) return;
|
|
16771
|
+
paintingButton = true;
|
|
16772
|
+
paintButtonChrome(el, lock.assignment, lock.tokens);
|
|
16773
|
+
paintingButton = false;
|
|
16774
|
+
});
|
|
16775
|
+
observer.observe(el, { attributes: true, attributeFilter: ["style", "class"] });
|
|
16776
|
+
paintObserverByEl.set(el, observer);
|
|
16777
|
+
}
|
|
16778
|
+
function applyButtonStyle(el, assignment, tokens) {
|
|
16779
|
+
paintLockByEl.set(el, { assignment, tokens });
|
|
16780
|
+
paintingButton = true;
|
|
16781
|
+
paintButtonChrome(el, assignment, tokens);
|
|
16782
|
+
paintingButton = false;
|
|
16783
|
+
guardTemplateHover(el);
|
|
16784
|
+
}
|
|
16785
|
+
function applyButtonStylesFromContent(doc, content) {
|
|
16786
|
+
const assignments = readAssignments(content);
|
|
16787
|
+
for (const [id, assignment] of Object.entries(assignments)) {
|
|
16788
|
+
const el = doc.querySelector(`[data-ohw-href-key="${CSS.escape(id)}"]`);
|
|
16789
|
+
if (!el) continue;
|
|
16790
|
+
applyButtonStyle(el, assignment, tokensFromButton(el));
|
|
16791
|
+
}
|
|
16792
|
+
}
|
|
16793
|
+
function withAssignment(content, id, assignment) {
|
|
16794
|
+
return { ...readAssignments(content), [id]: assignment };
|
|
16795
|
+
}
|
|
16796
|
+
|
|
16797
|
+
// src/ui/button-style-panel.tsx
|
|
16798
|
+
import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
16799
|
+
var SIZE_LABEL = { s: "S", m: "M", l: "L" };
|
|
16800
|
+
function ButtonStylePanel({
|
|
16801
|
+
variants,
|
|
16802
|
+
sizes,
|
|
16803
|
+
variant,
|
|
16804
|
+
size,
|
|
16805
|
+
onVariant,
|
|
16806
|
+
onSize,
|
|
16807
|
+
previewLabel = "Book Now",
|
|
16808
|
+
slotBackground = "var(--brand-background, var(--ohw-brand-light, var(--color-light, #ffffff)))"
|
|
16809
|
+
}) {
|
|
16810
|
+
const preview = scaleGeometry(sizes.m, 0.75);
|
|
16811
|
+
const label = previewLabel.trim() || "Book Now";
|
|
16812
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex w-full flex-col gap-5", children: [
|
|
16813
|
+
/* @__PURE__ */ jsxs21("section", { className: "flex w-full flex-col gap-2.5", children: [
|
|
16814
|
+
/* @__PURE__ */ jsx31("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
|
|
16815
|
+
/* @__PURE__ */ jsx31("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
|
|
16816
|
+
const chrome = variants[id];
|
|
16817
|
+
const selected = id === variant;
|
|
16818
|
+
const hasBorder = parseFloat(chrome.borderWidth) > 0;
|
|
16819
|
+
const cardSlot = previewSlotForChrome(chrome, slotBackground);
|
|
16820
|
+
return /* @__PURE__ */ jsxs21(
|
|
16821
|
+
"button",
|
|
16822
|
+
{
|
|
16823
|
+
type: "button",
|
|
16824
|
+
"aria-pressed": selected,
|
|
16825
|
+
"aria-label": id,
|
|
16826
|
+
onMouseDown: (e) => {
|
|
16827
|
+
e.preventDefault();
|
|
16828
|
+
e.stopPropagation();
|
|
16829
|
+
},
|
|
16830
|
+
onClick: () => onVariant(id),
|
|
16831
|
+
className: cn(
|
|
16832
|
+
"relative w-full overflow-hidden rounded-xl border-solid text-left",
|
|
16833
|
+
selected ? "border-2 border-primary" : "border border-border"
|
|
16834
|
+
),
|
|
16835
|
+
children: [
|
|
16836
|
+
/* @__PURE__ */ jsx31(
|
|
16837
|
+
"div",
|
|
16838
|
+
{
|
|
16839
|
+
className: "flex w-full items-center justify-center py-4",
|
|
16840
|
+
style: { background: cardSlot },
|
|
16841
|
+
children: /* @__PURE__ */ jsx31(
|
|
16842
|
+
"span",
|
|
16843
|
+
{
|
|
16844
|
+
className: "inline-flex items-center justify-center whitespace-nowrap font-semibold uppercase leading-none",
|
|
16845
|
+
style: {
|
|
16846
|
+
background: chrome.background,
|
|
16847
|
+
color: chrome.color,
|
|
16848
|
+
borderColor: chrome.borderColor,
|
|
16849
|
+
borderWidth: hasBorder ? chrome.borderWidth : "0px",
|
|
16850
|
+
borderStyle: hasBorder ? "solid" : "none",
|
|
16851
|
+
padding: `${preview.paddingTop} ${preview.paddingRight} ${preview.paddingBottom} ${preview.paddingLeft}`,
|
|
16852
|
+
fontSize: preview.fontSize,
|
|
16853
|
+
borderRadius: preview.borderRadius,
|
|
16854
|
+
height: preview.height,
|
|
16855
|
+
boxSizing: "border-box",
|
|
16856
|
+
letterSpacing: "0.12em"
|
|
16857
|
+
},
|
|
16858
|
+
children: label
|
|
16859
|
+
}
|
|
16860
|
+
)
|
|
16861
|
+
}
|
|
16862
|
+
),
|
|
16863
|
+
selected ? /* @__PURE__ */ jsx31(
|
|
16864
|
+
"span",
|
|
16865
|
+
{
|
|
16866
|
+
className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
16867
|
+
"aria-hidden": true,
|
|
16868
|
+
children: /* @__PURE__ */ jsx31(Check3, { className: "size-3", strokeWidth: 3 })
|
|
16869
|
+
}
|
|
16870
|
+
) : null
|
|
16871
|
+
]
|
|
16872
|
+
},
|
|
16873
|
+
id
|
|
16874
|
+
);
|
|
16875
|
+
}) })
|
|
16876
|
+
] }),
|
|
16877
|
+
/* @__PURE__ */ jsxs21("section", { className: "flex w-full flex-col gap-2.5", children: [
|
|
16878
|
+
/* @__PURE__ */ jsx31("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
|
|
16879
|
+
/* @__PURE__ */ jsx31(
|
|
16880
|
+
"div",
|
|
16881
|
+
{
|
|
16882
|
+
className: "flex w-full items-start rounded-lg bg-stone-100 p-1",
|
|
16883
|
+
role: "radiogroup",
|
|
16884
|
+
"aria-label": "Size",
|
|
16885
|
+
children: BUTTON_SIZE_IDS.map((id) => {
|
|
16886
|
+
const selected = id === size;
|
|
16887
|
+
return /* @__PURE__ */ jsx31(
|
|
16888
|
+
"button",
|
|
16889
|
+
{
|
|
16890
|
+
type: "button",
|
|
16891
|
+
role: "radio",
|
|
16892
|
+
"aria-checked": selected,
|
|
16893
|
+
onMouseDown: (e) => {
|
|
16894
|
+
e.preventDefault();
|
|
16895
|
+
e.stopPropagation();
|
|
16896
|
+
},
|
|
16897
|
+
onClick: () => onSize(id),
|
|
16898
|
+
className: cn(
|
|
16899
|
+
"flex min-w-14 flex-1 items-center justify-center rounded-md px-3 py-1.5 text-sm font-medium leading-5",
|
|
16900
|
+
selected ? "bg-white text-stone-950 shadow-sm" : "bg-transparent text-stone-500"
|
|
16901
|
+
),
|
|
16902
|
+
children: SIZE_LABEL[id]
|
|
16903
|
+
},
|
|
16904
|
+
id
|
|
16905
|
+
);
|
|
16906
|
+
})
|
|
16907
|
+
}
|
|
16908
|
+
)
|
|
16909
|
+
] })
|
|
16910
|
+
] });
|
|
16911
|
+
}
|
|
16912
|
+
|
|
16913
|
+
// src/lib/button-collections.ts
|
|
16914
|
+
var BUTTON_COLLECTIONS_KEY = "__ohw_button_collections";
|
|
16915
|
+
var BUTTON_SNAPSHOTS_KEY = "__ohw_button_snapshots";
|
|
16916
|
+
var BUTTON_HIDDEN_KEY = "__ohw_button_hidden";
|
|
16917
|
+
var COLLECTION_ATTR = "data-ohw-button-collection";
|
|
16918
|
+
function parseJson2(raw) {
|
|
16919
|
+
if (!raw) return null;
|
|
16920
|
+
try {
|
|
16921
|
+
return JSON.parse(raw);
|
|
16922
|
+
} catch {
|
|
16923
|
+
return null;
|
|
16924
|
+
}
|
|
16925
|
+
}
|
|
16926
|
+
function readCollections(content) {
|
|
16927
|
+
const parsed = parseJson2(content[BUTTON_COLLECTIONS_KEY]);
|
|
16928
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
16929
|
+
const next = {};
|
|
16930
|
+
for (const [id, value] of Object.entries(parsed)) {
|
|
16931
|
+
if (!value || !Array.isArray(value.members)) continue;
|
|
16932
|
+
next[id] = {
|
|
16933
|
+
id,
|
|
16934
|
+
members: value.members.filter((member) => typeof member === "string" && member),
|
|
16935
|
+
gap: typeof value.gap === "string" ? value.gap : "12px"
|
|
16936
|
+
};
|
|
16937
|
+
}
|
|
16938
|
+
return next;
|
|
16939
|
+
}
|
|
16940
|
+
function readSnapshots(content) {
|
|
16941
|
+
const parsed = parseJson2(content[BUTTON_SNAPSHOTS_KEY]);
|
|
16942
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
16943
|
+
const next = {};
|
|
16944
|
+
for (const [id, value] of Object.entries(parsed)) {
|
|
16945
|
+
if (!value || typeof value.html !== "string") continue;
|
|
16946
|
+
next[id] = value;
|
|
16947
|
+
}
|
|
16948
|
+
return next;
|
|
16949
|
+
}
|
|
16950
|
+
function readHiddenButtons(content) {
|
|
16951
|
+
const parsed = parseJson2(content[BUTTON_HIDDEN_KEY]);
|
|
16952
|
+
if (!Array.isArray(parsed)) return [];
|
|
16953
|
+
return parsed.filter((id) => typeof id === "string" && id);
|
|
16954
|
+
}
|
|
16955
|
+
function buttonCollectionOf(el) {
|
|
16956
|
+
return el?.closest(`[${COLLECTION_ATTR}]`) ?? null;
|
|
16957
|
+
}
|
|
16958
|
+
function isNavbarCta(el) {
|
|
16959
|
+
return el.getAttribute("data-ohw-role") === "navbar-button" || Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
16960
|
+
}
|
|
16961
|
+
function navbarScope(el) {
|
|
16962
|
+
return el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]") ?? el.ownerDocument;
|
|
16963
|
+
}
|
|
16964
|
+
function isLastNavbarButton(el) {
|
|
16965
|
+
if (!isNavbarCta(el)) return false;
|
|
16966
|
+
const buttons = Array.from(navbarScope(el).querySelectorAll(CTA_BUTTON_SELECTOR)).filter(
|
|
16967
|
+
(button) => isNavbarCta(button) && buttonId(button)
|
|
16968
|
+
);
|
|
16969
|
+
return buttons.length <= 1;
|
|
16970
|
+
}
|
|
16971
|
+
function canDeleteButton(el) {
|
|
16972
|
+
return !isLastNavbarButton(el);
|
|
16973
|
+
}
|
|
16974
|
+
function canDuplicateButton(el) {
|
|
16975
|
+
return isNavbarCta(el);
|
|
16976
|
+
}
|
|
16977
|
+
function labelElement2(el) {
|
|
16978
|
+
return el.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? el.querySelector("[data-ohw-key]");
|
|
16979
|
+
}
|
|
16980
|
+
function buttonLabel(el) {
|
|
16981
|
+
return (labelElement2(el)?.textContent ?? el.textContent ?? "").trim();
|
|
16982
|
+
}
|
|
16983
|
+
function buttonHref(el) {
|
|
16984
|
+
return el.getAttribute("href") ?? "";
|
|
16985
|
+
}
|
|
16986
|
+
function hrefKeyBase(hrefKey) {
|
|
16987
|
+
return hrefKey.replace(/-href$/, "").replace(/-copy-\d+$/, "");
|
|
16988
|
+
}
|
|
16989
|
+
function labelKeyForHrefKey(hrefKey) {
|
|
16990
|
+
return `${hrefKey.replace(/-href$/, "")}-label`;
|
|
16991
|
+
}
|
|
16992
|
+
function cleanClone(el) {
|
|
16993
|
+
const copy = el.cloneNode(true);
|
|
16994
|
+
copy.querySelectorAll("[data-ohw-selected], [data-ohw-hovered], [data-ohw-editing]").forEach((node) => {
|
|
16995
|
+
node.removeAttribute("data-ohw-selected");
|
|
16996
|
+
node.removeAttribute("data-ohw-hovered");
|
|
16997
|
+
node.removeAttribute("data-ohw-editing");
|
|
16998
|
+
node.removeAttribute("contenteditable");
|
|
16999
|
+
});
|
|
17000
|
+
copy.removeAttribute("data-ohw-selected");
|
|
17001
|
+
copy.removeAttribute("data-ohw-hovered");
|
|
17002
|
+
copy.removeAttribute("data-ohw-editing");
|
|
17003
|
+
copy.removeAttribute("contenteditable");
|
|
17004
|
+
copy.removeAttribute("data-ohw-drag-disabled");
|
|
17005
|
+
return copy;
|
|
17006
|
+
}
|
|
17007
|
+
function nextCopyId(sourceId, content, doc) {
|
|
17008
|
+
const used = /* @__PURE__ */ new Set([
|
|
17009
|
+
...Object.keys(readSnapshots(content)),
|
|
17010
|
+
...Object.keys(readAssignments(content)),
|
|
17011
|
+
...Array.from(doc.querySelectorAll("[data-ohw-href-key]")).map(
|
|
17012
|
+
(el) => el.getAttribute("data-ohw-href-key") ?? ""
|
|
17013
|
+
)
|
|
17014
|
+
]);
|
|
17015
|
+
const base = hrefKeyBase(sourceId);
|
|
17016
|
+
let n = 2;
|
|
17017
|
+
while (used.has(`${base}-copy-${n}-href`)) n += 1;
|
|
17018
|
+
return `${base}-copy-${n}-href`;
|
|
17019
|
+
}
|
|
17020
|
+
function nextCollectionId(content, doc) {
|
|
17021
|
+
const used = /* @__PURE__ */ new Set([
|
|
17022
|
+
...Object.keys(readCollections(content)),
|
|
17023
|
+
...Array.from(doc.querySelectorAll(`[${COLLECTION_ATTR}]`)).map(
|
|
17024
|
+
(el) => el.getAttribute(COLLECTION_ATTR) ?? ""
|
|
17025
|
+
)
|
|
17026
|
+
]);
|
|
17027
|
+
let n = 1;
|
|
17028
|
+
while (used.has(`bc-${n}`)) n += 1;
|
|
17029
|
+
return `bc-${n}`;
|
|
17030
|
+
}
|
|
17031
|
+
var COLLECTION_GAP_MAX_PX = 12;
|
|
17032
|
+
var COLLECTION_GAP_DEFAULT = "12px";
|
|
17033
|
+
function usableGap(value) {
|
|
17034
|
+
if (!value || value === "normal") return null;
|
|
17035
|
+
const n = parseFloat(value);
|
|
17036
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
17037
|
+
if (n > COLLECTION_GAP_MAX_PX) return COLLECTION_GAP_DEFAULT;
|
|
17038
|
+
return `${Math.round(n * 100) / 100}px`;
|
|
17039
|
+
}
|
|
17040
|
+
function collectionGap(el, tokens) {
|
|
17041
|
+
const fromCollection = usableGap(buttonCollectionOf(el)?.style.gap);
|
|
17042
|
+
if (fromCollection) return fromCollection;
|
|
17043
|
+
const parent = el.parentElement;
|
|
17044
|
+
if (parent) {
|
|
17045
|
+
const style = getComputedStyle(parent);
|
|
17046
|
+
const fromParent = usableGap(style.columnGap) ?? usableGap(style.gap);
|
|
17047
|
+
if (fromParent) return fromParent;
|
|
17048
|
+
}
|
|
17049
|
+
const fromTokens = usableGap(tokens?.sizes.m.gap);
|
|
17050
|
+
if (fromTokens) return fromTokens;
|
|
17051
|
+
return COLLECTION_GAP_DEFAULT;
|
|
17052
|
+
}
|
|
17053
|
+
function styleCollection(collection, gap) {
|
|
17054
|
+
collection.style.display = "inline-flex";
|
|
17055
|
+
collection.style.alignItems = "center";
|
|
17056
|
+
collection.style.flexWrap = "wrap";
|
|
17057
|
+
collection.style.gap = gap;
|
|
17058
|
+
collection.style.maxWidth = "100%";
|
|
17059
|
+
}
|
|
17060
|
+
function createCollection(doc, id, gap) {
|
|
17061
|
+
const collection = doc.createElement("div");
|
|
17062
|
+
collection.setAttribute(COLLECTION_ATTR, id);
|
|
17063
|
+
styleCollection(collection, gap);
|
|
17064
|
+
return collection;
|
|
17065
|
+
}
|
|
17066
|
+
function setButtonDragAttr(el) {
|
|
17067
|
+
if (isNavbarCta(el) && buttonCollectionOf(el)) el.removeAttribute("data-ohw-drag-disabled");
|
|
17068
|
+
else el.setAttribute("data-ohw-drag-disabled", "true");
|
|
17069
|
+
}
|
|
17070
|
+
function rekeyCopy(copy, id) {
|
|
17071
|
+
copy.setAttribute("data-ohw-href-key", id);
|
|
17072
|
+
const label = labelElement2(copy);
|
|
17073
|
+
const labelKey = labelKeyForHrefKey(id);
|
|
17074
|
+
if (label) label.setAttribute("data-ohw-key", labelKey);
|
|
17075
|
+
setButtonDragAttr(copy);
|
|
17076
|
+
return { labelKey };
|
|
17077
|
+
}
|
|
17078
|
+
function stampVariantClass(el, variant) {
|
|
17079
|
+
const raw = typeof el.className === "string" ? el.className : el.getAttribute("class") || "";
|
|
17080
|
+
const without = raw.replace(/\bbtn--(?:primary|secondary|ghost)\b/g, "").replace(/\s+/g, " ").trim();
|
|
17081
|
+
el.className = without ? `${without} btn--${variant}` : `btn btn--${variant}`;
|
|
17082
|
+
}
|
|
17083
|
+
function snapshotOf(el) {
|
|
17084
|
+
const id = buttonId(el) ?? "";
|
|
17085
|
+
const label = labelElement2(el);
|
|
17086
|
+
return {
|
|
17087
|
+
id,
|
|
17088
|
+
href: buttonHref(el),
|
|
17089
|
+
label: buttonLabel(el),
|
|
17090
|
+
labelKey: label?.getAttribute("data-ohw-key") ?? labelKeyForHrefKey(id),
|
|
17091
|
+
html: cleanClone(el).outerHTML
|
|
17092
|
+
};
|
|
17093
|
+
}
|
|
17094
|
+
function htmlToElement(doc, html) {
|
|
17095
|
+
const wrap = doc.createElement("div");
|
|
17096
|
+
wrap.innerHTML = html;
|
|
17097
|
+
const el = wrap.firstElementChild;
|
|
17098
|
+
return el instanceof HTMLElement ? el : null;
|
|
17099
|
+
}
|
|
17100
|
+
function findButton(doc, id) {
|
|
17101
|
+
return doc.querySelector(`[data-ohw-href-key="${CSS.escape(id)}"]`);
|
|
17102
|
+
}
|
|
17103
|
+
function duplicateButton(source, content) {
|
|
17104
|
+
if (!canDuplicateButton(source)) return null;
|
|
17105
|
+
const sourceId = buttonId(source);
|
|
17106
|
+
if (!sourceId) return null;
|
|
17107
|
+
const doc = source.ownerDocument;
|
|
17108
|
+
const tokens = tokensFromButton(source);
|
|
17109
|
+
const copyId = nextCopyId(sourceId, content, doc);
|
|
17110
|
+
const copy = cleanClone(source);
|
|
17111
|
+
const { labelKey } = rekeyCopy(copy, copyId);
|
|
17112
|
+
const href = buttonHref(source);
|
|
17113
|
+
const label = buttonLabel(source);
|
|
17114
|
+
if (href) copy.setAttribute("href", href);
|
|
17115
|
+
const sourceAssignment = readAssignments(content)[sourceId] ?? assignmentFor(source, content, tokens);
|
|
17116
|
+
const copyAssignment = {
|
|
17117
|
+
variant: "secondary",
|
|
17118
|
+
size: sourceAssignment.size
|
|
17119
|
+
};
|
|
17120
|
+
stampVariantClass(copy, "secondary");
|
|
17121
|
+
applyButtonStyle(copy, copyAssignment, tokens);
|
|
17122
|
+
const copyLabelEl = labelElement2(copy);
|
|
17123
|
+
if (copyLabelEl) copyLabelEl.textContent = label;
|
|
17124
|
+
let collection = buttonCollectionOf(source);
|
|
17125
|
+
const collections = readCollections(content);
|
|
17126
|
+
let collectionId = collection?.getAttribute(COLLECTION_ATTR) ?? "";
|
|
17127
|
+
let members = collectionId && collections[collectionId] ? [...collections[collectionId].members] : [];
|
|
17128
|
+
const gap = collectionGap(source, tokens);
|
|
17129
|
+
if (!collection) {
|
|
17130
|
+
collectionId = nextCollectionId(content, doc);
|
|
17131
|
+
collection = createCollection(doc, collectionId, gap);
|
|
17132
|
+
source.parentElement?.insertBefore(collection, source);
|
|
17133
|
+
collection.append(source, copy);
|
|
17134
|
+
setButtonDragAttr(source);
|
|
17135
|
+
setButtonDragAttr(copy);
|
|
17136
|
+
members = [sourceId, copyId];
|
|
17137
|
+
} else {
|
|
17138
|
+
styleCollection(collection, gap);
|
|
17139
|
+
source.after(copy);
|
|
17140
|
+
setButtonDragAttr(copy);
|
|
17141
|
+
if (!members.includes(sourceId)) members = listCollectionMembers(collection);
|
|
17142
|
+
const at = members.indexOf(sourceId);
|
|
17143
|
+
members.splice(at >= 0 ? at + 1 : members.length, 0, copyId);
|
|
17144
|
+
}
|
|
17145
|
+
const sourceLabelKey = labelElement2(source)?.getAttribute("data-ohw-key");
|
|
17146
|
+
const snapshots = {
|
|
17147
|
+
...readSnapshots(content),
|
|
17148
|
+
[sourceId]: snapshotOf(source),
|
|
17149
|
+
[copyId]: snapshotOf(copy)
|
|
17150
|
+
};
|
|
17151
|
+
const nextCollections = {
|
|
17152
|
+
...collections,
|
|
17153
|
+
[collectionId]: { id: collectionId, members, gap }
|
|
17154
|
+
};
|
|
17155
|
+
const assignments = withAssignment(content, copyId, copyAssignment);
|
|
17156
|
+
const nextContent = {
|
|
17157
|
+
...content,
|
|
17158
|
+
[copyId]: href,
|
|
17159
|
+
[labelKey]: label,
|
|
17160
|
+
[BUTTON_COLLECTIONS_KEY]: JSON.stringify(nextCollections),
|
|
17161
|
+
[BUTTON_SNAPSHOTS_KEY]: JSON.stringify(snapshots),
|
|
17162
|
+
[BUTTON_ASSIGNMENTS_KEY]: JSON.stringify(assignments)
|
|
17163
|
+
};
|
|
17164
|
+
if (sourceLabelKey && nextContent[sourceLabelKey] === void 0) {
|
|
17165
|
+
nextContent[sourceLabelKey] = label;
|
|
17166
|
+
}
|
|
17167
|
+
const nodeKeys = [
|
|
17168
|
+
copyId,
|
|
17169
|
+
labelKey,
|
|
17170
|
+
BUTTON_COLLECTIONS_KEY,
|
|
17171
|
+
BUTTON_SNAPSHOTS_KEY,
|
|
17172
|
+
BUTTON_ASSIGNMENTS_KEY
|
|
17173
|
+
];
|
|
17174
|
+
if (sourceLabelKey) nodeKeys.push(sourceLabelKey);
|
|
17175
|
+
return {
|
|
17176
|
+
copy,
|
|
17177
|
+
content: nextContent,
|
|
17178
|
+
nodes: contentNodes(nextContent, nodeKeys)
|
|
17179
|
+
};
|
|
17180
|
+
}
|
|
17181
|
+
function listCollectionMembers(collection) {
|
|
17182
|
+
return Array.from(collection.querySelectorAll(CTA_BUTTON_SELECTOR)).map((el) => buttonId(el)).filter((id) => Boolean(id));
|
|
17183
|
+
}
|
|
17184
|
+
function contentNodes(content, keys) {
|
|
17185
|
+
return keys.filter((key) => content[key] !== void 0).map((key) => ({ key, text: content[key] }));
|
|
17186
|
+
}
|
|
17187
|
+
function deleteButton(source, content) {
|
|
17188
|
+
if (!canDeleteButton(source)) return null;
|
|
17189
|
+
const id = buttonId(source);
|
|
17190
|
+
if (!id) return null;
|
|
17191
|
+
const parent = source.parentElement;
|
|
17192
|
+
const nextSibling = source.nextSibling;
|
|
17193
|
+
const removed = source;
|
|
17194
|
+
const collection = buttonCollectionOf(source);
|
|
17195
|
+
const collectionId = collection?.getAttribute(COLLECTION_ATTR) ?? "";
|
|
17196
|
+
const previousCollections = readCollections(content);
|
|
17197
|
+
const previousHidden = readHiddenButtons(content);
|
|
17198
|
+
const snapshots = { ...readSnapshots(content) };
|
|
17199
|
+
const assignments = { ...readAssignments(content) };
|
|
17200
|
+
delete assignments[id];
|
|
17201
|
+
const remainingBeforeUnwrap = collection ? listCollectionMembers(collection).filter((member) => member !== id) : [];
|
|
17202
|
+
removed.remove();
|
|
17203
|
+
let nextCollections = { ...previousCollections };
|
|
17204
|
+
let unwrapped = null;
|
|
17205
|
+
if (collection && collectionId) {
|
|
17206
|
+
const members = listCollectionMembers(collection);
|
|
17207
|
+
if (members.length <= 1) {
|
|
17208
|
+
unwrapped = collection;
|
|
17209
|
+
unwrapCollection(collection);
|
|
17210
|
+
delete nextCollections[collectionId];
|
|
17211
|
+
} else {
|
|
17212
|
+
nextCollections[collectionId] = {
|
|
17213
|
+
id: collectionId,
|
|
17214
|
+
members,
|
|
17215
|
+
gap: collection.style.gap || previousCollections[collectionId]?.gap || "12px"
|
|
17216
|
+
};
|
|
17217
|
+
}
|
|
17218
|
+
}
|
|
17219
|
+
const hidden = previousHidden.includes(id) ? previousHidden : [...previousHidden, id];
|
|
17220
|
+
const nextContent = {
|
|
17221
|
+
...content,
|
|
17222
|
+
[id]: "",
|
|
17223
|
+
[BUTTON_COLLECTIONS_KEY]: JSON.stringify(nextCollections),
|
|
17224
|
+
[BUTTON_HIDDEN_KEY]: JSON.stringify(hidden),
|
|
17225
|
+
[BUTTON_SNAPSHOTS_KEY]: JSON.stringify(snapshots),
|
|
17226
|
+
[BUTTON_ASSIGNMENTS_KEY]: JSON.stringify(assignments)
|
|
17227
|
+
};
|
|
17228
|
+
return {
|
|
17229
|
+
content: nextContent,
|
|
17230
|
+
nodes: contentNodes(nextContent, [id, BUTTON_COLLECTIONS_KEY, BUTTON_HIDDEN_KEY, BUTTON_SNAPSHOTS_KEY, BUTTON_ASSIGNMENTS_KEY]),
|
|
17231
|
+
undo: () => {
|
|
17232
|
+
if (unwrapped && remainingBeforeUnwrap.length === 1) {
|
|
17233
|
+
const remaining = findButton(removed.ownerDocument, remainingBeforeUnwrap[0]);
|
|
17234
|
+
const host = remaining?.parentElement;
|
|
17235
|
+
if (remaining && host) {
|
|
17236
|
+
const restoredCollection = createCollection(
|
|
17237
|
+
removed.ownerDocument,
|
|
17238
|
+
collectionId,
|
|
17239
|
+
previousCollections[collectionId]?.gap || "12px"
|
|
17240
|
+
);
|
|
17241
|
+
host.insertBefore(restoredCollection, remaining);
|
|
17242
|
+
restoredCollection.append(remaining, removed);
|
|
17243
|
+
return;
|
|
17244
|
+
}
|
|
17245
|
+
}
|
|
17246
|
+
if (nextSibling && nextSibling.parentNode === parent) parent?.insertBefore(removed, nextSibling);
|
|
17247
|
+
else parent?.appendChild(removed);
|
|
17248
|
+
}
|
|
17249
|
+
};
|
|
17250
|
+
}
|
|
17251
|
+
function unwrapCollection(collection) {
|
|
17252
|
+
const parent = collection.parentElement;
|
|
17253
|
+
if (!parent) return;
|
|
17254
|
+
while (collection.firstChild) parent.insertBefore(collection.firstChild, collection);
|
|
17255
|
+
collection.remove();
|
|
17256
|
+
}
|
|
17257
|
+
function reorderButtonInCollection(button, clientX) {
|
|
17258
|
+
const collection = buttonCollectionOf(button);
|
|
17259
|
+
const id = buttonId(button);
|
|
17260
|
+
if (!collection || !id) return null;
|
|
17261
|
+
const siblings = Array.from(collection.querySelectorAll(CTA_BUTTON_SELECTOR)).filter((el) => el !== button);
|
|
17262
|
+
let placed = false;
|
|
17263
|
+
for (const sibling of siblings) {
|
|
17264
|
+
const rect = sibling.getBoundingClientRect();
|
|
17265
|
+
if (clientX < rect.left + rect.width / 2) {
|
|
17266
|
+
sibling.before(button);
|
|
17267
|
+
placed = true;
|
|
17268
|
+
break;
|
|
17269
|
+
}
|
|
17270
|
+
}
|
|
17271
|
+
if (!placed) collection.append(button);
|
|
17272
|
+
return listCollectionMembers(collection);
|
|
17273
|
+
}
|
|
17274
|
+
function listVisibleCollectionButtons(collection) {
|
|
17275
|
+
return Array.from(collection.querySelectorAll(CTA_BUTTON_SELECTOR)).filter((el) => {
|
|
17276
|
+
if (!buttonId(el)) return false;
|
|
17277
|
+
return el.getClientRects().length > 0;
|
|
17278
|
+
});
|
|
17279
|
+
}
|
|
17280
|
+
function isVerticalButtonLayout(items, collection) {
|
|
17281
|
+
if (items.length >= 2) {
|
|
17282
|
+
const a = items[0].getBoundingClientRect();
|
|
17283
|
+
const b = items[1].getBoundingClientRect();
|
|
17284
|
+
return b.top - a.bottom > b.left - a.right;
|
|
17285
|
+
}
|
|
17286
|
+
const style = window.getComputedStyle(collection);
|
|
17287
|
+
return style.flexDirection === "column" || style.flexDirection === "column-reverse";
|
|
17288
|
+
}
|
|
17289
|
+
function buildButtonCollectionDropSlots(collection) {
|
|
17290
|
+
const items = listVisibleCollectionButtons(collection);
|
|
17291
|
+
const barThickness = 3;
|
|
17292
|
+
const slots = [];
|
|
17293
|
+
if (items.length === 0) {
|
|
17294
|
+
const rect = collection.getBoundingClientRect();
|
|
17295
|
+
slots.push({
|
|
17296
|
+
insertIndex: 0,
|
|
17297
|
+
left: rect.left + rect.width / 2 - barThickness / 2,
|
|
17298
|
+
top: rect.top,
|
|
17299
|
+
width: barThickness,
|
|
17300
|
+
height: Math.max(rect.height, 24),
|
|
17301
|
+
direction: "vertical"
|
|
17302
|
+
});
|
|
17303
|
+
return slots;
|
|
17304
|
+
}
|
|
17305
|
+
if (isVerticalButtonLayout(items, collection)) {
|
|
17306
|
+
const edgeGap2 = items.length >= 2 ? Math.max(0, items[1].getBoundingClientRect().top - items[0].getBoundingClientRect().bottom) : 16;
|
|
17307
|
+
for (let i = 0; i <= items.length; i++) {
|
|
17308
|
+
let top;
|
|
17309
|
+
let left;
|
|
17310
|
+
let width;
|
|
17311
|
+
if (i === 0) {
|
|
17312
|
+
const first = items[0].getBoundingClientRect();
|
|
17313
|
+
top = first.top - edgeGap2 / 2 - barThickness / 2;
|
|
17314
|
+
left = first.left;
|
|
17315
|
+
width = first.width;
|
|
17316
|
+
} else if (i === items.length) {
|
|
17317
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
17318
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.top - items[items.length - 2].getBoundingClientRect().bottom) : edgeGap2;
|
|
17319
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
17320
|
+
left = last.left;
|
|
17321
|
+
width = last.width;
|
|
17322
|
+
} else {
|
|
17323
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
17324
|
+
const next = items[i].getBoundingClientRect();
|
|
17325
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
17326
|
+
left = Math.min(prev.left, next.left);
|
|
17327
|
+
width = Math.max(prev.right, next.right) - left;
|
|
17328
|
+
}
|
|
17329
|
+
slots.push({
|
|
17330
|
+
insertIndex: i,
|
|
17331
|
+
left,
|
|
17332
|
+
top,
|
|
17333
|
+
width: Math.max(width, 40),
|
|
17334
|
+
height: barThickness,
|
|
17335
|
+
direction: "horizontal"
|
|
17336
|
+
});
|
|
17337
|
+
}
|
|
17338
|
+
return slots;
|
|
17339
|
+
}
|
|
17340
|
+
const edgeGap = items.length >= 2 ? Math.max(0, items[1].getBoundingClientRect().left - items[0].getBoundingClientRect().right) : 12;
|
|
17341
|
+
for (let i = 0; i <= items.length; i++) {
|
|
17342
|
+
let left;
|
|
17343
|
+
let top;
|
|
17344
|
+
let height;
|
|
17345
|
+
if (i === 0) {
|
|
17346
|
+
const first = items[0].getBoundingClientRect();
|
|
17347
|
+
left = first.left - edgeGap / 2 - barThickness / 2;
|
|
17348
|
+
top = first.top;
|
|
17349
|
+
height = first.height;
|
|
17350
|
+
} else if (i === items.length) {
|
|
17351
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
17352
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.left - items[items.length - 2].getBoundingClientRect().right) : edgeGap;
|
|
17353
|
+
left = last.right + lastGap / 2 - barThickness / 2;
|
|
17354
|
+
top = last.top;
|
|
17355
|
+
height = last.height;
|
|
17356
|
+
} else {
|
|
17357
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
17358
|
+
const next = items[i].getBoundingClientRect();
|
|
17359
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
17360
|
+
top = Math.min(prev.top, next.top);
|
|
17361
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
17362
|
+
}
|
|
17363
|
+
slots.push({
|
|
17364
|
+
insertIndex: i,
|
|
17365
|
+
left,
|
|
17366
|
+
top,
|
|
17367
|
+
width: barThickness,
|
|
17368
|
+
height: Math.max(height, 24),
|
|
17369
|
+
direction: "vertical"
|
|
17370
|
+
});
|
|
17371
|
+
}
|
|
17372
|
+
return slots;
|
|
17373
|
+
}
|
|
17374
|
+
function hitTestButtonCollectionDropSlot(collection, clientX, clientY) {
|
|
17375
|
+
const slots = buildButtonCollectionDropSlots(collection);
|
|
17376
|
+
let best = null;
|
|
17377
|
+
for (const slot of slots) {
|
|
17378
|
+
const cx2 = slot.left + slot.width / 2;
|
|
17379
|
+
const cy = slot.top + slot.height / 2;
|
|
17380
|
+
const dist = slot.direction === "vertical" ? Math.abs(clientX - cx2) + Math.abs(clientY - cy) * 0.25 : Math.abs(clientY - cy) + Math.abs(clientX - cx2) * 0.25;
|
|
17381
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
17382
|
+
}
|
|
17383
|
+
return best?.slot ?? null;
|
|
17384
|
+
}
|
|
17385
|
+
function insertButtonAtCollectionIndex(button, insertIndex) {
|
|
17386
|
+
const collection = buttonCollectionOf(button);
|
|
17387
|
+
if (!collection) return null;
|
|
17388
|
+
const items = listVisibleCollectionButtons(collection);
|
|
17389
|
+
const from = items.indexOf(button);
|
|
17390
|
+
if (from < 0) return null;
|
|
17391
|
+
const others = items.filter((el) => el !== button);
|
|
17392
|
+
let index = insertIndex;
|
|
17393
|
+
if (from < insertIndex) index -= 1;
|
|
17394
|
+
if (index <= 0) {
|
|
17395
|
+
const first = others[0];
|
|
17396
|
+
if (first) first.before(button);
|
|
17397
|
+
else collection.append(button);
|
|
17398
|
+
} else if (index >= others.length) {
|
|
17399
|
+
collection.append(button);
|
|
17400
|
+
} else {
|
|
17401
|
+
others[index].before(button);
|
|
17402
|
+
}
|
|
17403
|
+
return listCollectionMembers(collection);
|
|
17404
|
+
}
|
|
17405
|
+
function persistCollectionOrder(collection, content) {
|
|
17406
|
+
const id = collection.getAttribute(COLLECTION_ATTR);
|
|
17407
|
+
if (!id) return null;
|
|
17408
|
+
const collections = readCollections(content);
|
|
17409
|
+
const current = collections[id];
|
|
17410
|
+
const members = listCollectionMembers(collection);
|
|
17411
|
+
const next = {
|
|
17412
|
+
...collections,
|
|
17413
|
+
[id]: { id, members, gap: collection.style.gap || current?.gap || "12px" }
|
|
17414
|
+
};
|
|
17415
|
+
const nextContent = { ...content, [BUTTON_COLLECTIONS_KEY]: JSON.stringify(next) };
|
|
17416
|
+
return { content: nextContent, nodes: [{ key: BUTTON_COLLECTIONS_KEY, text: nextContent[BUTTON_COLLECTIONS_KEY] }] };
|
|
17417
|
+
}
|
|
17418
|
+
function hideButton(el) {
|
|
17419
|
+
if (el.getAttribute("data-ohw-button-hidden") === "") return;
|
|
17420
|
+
el.setAttribute("data-ohw-button-hidden", "");
|
|
17421
|
+
el.style.display = "none";
|
|
17422
|
+
}
|
|
17423
|
+
function syncButtonsFromContent(doc, content) {
|
|
17424
|
+
reconcileButtonCollections(doc, content);
|
|
17425
|
+
applyButtonContentFromContent(doc, content);
|
|
17426
|
+
applyButtonStylesFromContent(doc, content);
|
|
17427
|
+
}
|
|
17428
|
+
function applyButtonContentFromContent(doc, content) {
|
|
17429
|
+
const snapshots = readSnapshots(content);
|
|
17430
|
+
for (const snapshot of Object.values(snapshots)) {
|
|
17431
|
+
const el = findButton(doc, snapshot.id);
|
|
17432
|
+
if (!el) continue;
|
|
17433
|
+
applySnapshotContent(el, snapshot, content);
|
|
17434
|
+
}
|
|
17435
|
+
}
|
|
17436
|
+
function applySnapshotContent(el, snapshot, content) {
|
|
17437
|
+
const href = content[snapshot.id] ?? snapshot.href;
|
|
17438
|
+
if (href) el.setAttribute("href", href);
|
|
17439
|
+
const labelKey = snapshot.labelKey || labelKeyForHrefKey(snapshot.id);
|
|
17440
|
+
if (labelKey && !el.querySelector(`[data-ohw-key="${CSS.escape(labelKey)}"]`)) {
|
|
17441
|
+
const label2 = labelElement2(el);
|
|
17442
|
+
if (label2) label2.setAttribute("data-ohw-key", labelKey);
|
|
17443
|
+
}
|
|
17444
|
+
const text = content[labelKey];
|
|
17445
|
+
if (text === void 0) return;
|
|
17446
|
+
const label = labelElement2(el);
|
|
17447
|
+
if (label) {
|
|
17448
|
+
if (label.getAttribute("data-ohw-key") !== labelKey) label.setAttribute("data-ohw-key", labelKey);
|
|
17449
|
+
if (label.textContent !== text) label.textContent = text;
|
|
17450
|
+
}
|
|
17451
|
+
}
|
|
17452
|
+
function reconcileButtonCollections(doc, content) {
|
|
17453
|
+
const hidden = new Set(readHiddenButtons(content));
|
|
17454
|
+
for (const id of hidden) {
|
|
17455
|
+
const el = findButton(doc, id);
|
|
17456
|
+
if (el) hideButton(el);
|
|
17457
|
+
}
|
|
17458
|
+
const snapshots = readSnapshots(content);
|
|
17459
|
+
const collections = readCollections(content);
|
|
17460
|
+
for (const collectionState of Object.values(collections)) {
|
|
17461
|
+
const live = collectionState.members.map((id) => findButton(doc, id) ?? restoreSnapshot(doc, snapshots[id], content)).filter((el) => Boolean(el && !hidden.has(buttonId(el) ?? "")));
|
|
17462
|
+
if (live.length === 0) continue;
|
|
17463
|
+
if (live.length === 1) {
|
|
17464
|
+
const existing = buttonCollectionOf(live[0]);
|
|
17465
|
+
if (existing) unwrapCollection(existing);
|
|
17466
|
+
continue;
|
|
17467
|
+
}
|
|
17468
|
+
const anchor = live.find((el) => el.isConnected) ?? live[0];
|
|
17469
|
+
let collection = live.map((el) => buttonCollectionOf(el)).find((el) => el?.getAttribute(COLLECTION_ATTR) === collectionState.id) ?? null;
|
|
17470
|
+
if (!collection) {
|
|
17471
|
+
if (!anchor.parentElement) continue;
|
|
17472
|
+
collection = createCollection(doc, collectionState.id, collectionState.gap);
|
|
17473
|
+
anchor.parentElement.insertBefore(collection, anchor);
|
|
17474
|
+
}
|
|
17475
|
+
styleCollection(collection, collectionState.gap);
|
|
17476
|
+
const current = listCollectionMembers(collection);
|
|
17477
|
+
const sameOrder = current.length === live.length && current.every((id, index) => id === buttonId(live[index]));
|
|
17478
|
+
if (!sameOrder) {
|
|
17479
|
+
for (const member of live) collection.append(member);
|
|
17480
|
+
}
|
|
17481
|
+
for (const member of live) setButtonDragAttr(member);
|
|
17482
|
+
}
|
|
17483
|
+
}
|
|
17484
|
+
function restoreSnapshot(doc, snapshot, content) {
|
|
17485
|
+
if (!snapshot) return null;
|
|
17486
|
+
const existing = findButton(doc, snapshot.id);
|
|
17487
|
+
if (existing) {
|
|
17488
|
+
applySnapshotContent(existing, snapshot, content);
|
|
17489
|
+
return existing;
|
|
17490
|
+
}
|
|
17491
|
+
const el = htmlToElement(doc, snapshot.html);
|
|
17492
|
+
if (!el) return null;
|
|
17493
|
+
el.setAttribute("data-ohw-href-key", snapshot.id);
|
|
17494
|
+
const label = labelElement2(el);
|
|
17495
|
+
const labelKey = snapshot.labelKey || labelKeyForHrefKey(snapshot.id);
|
|
17496
|
+
if (label) label.setAttribute("data-ohw-key", labelKey);
|
|
17497
|
+
applySnapshotContent(el, snapshot, content);
|
|
17498
|
+
setButtonDragAttr(el);
|
|
17499
|
+
return el;
|
|
17500
|
+
}
|
|
17501
|
+
function navbarCtasInScope(el) {
|
|
17502
|
+
const scope = el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer]") ?? el.parentElement;
|
|
17503
|
+
if (!scope) return [];
|
|
17504
|
+
return Array.from(scope.querySelectorAll(CTA_BUTTON_SELECTOR)).filter(
|
|
17505
|
+
(button) => isNavbarCta(button) && buttonId(button)
|
|
17506
|
+
);
|
|
17507
|
+
}
|
|
17508
|
+
function ensureNavbarButtonCollection(button, content) {
|
|
17509
|
+
const existing = buttonCollectionOf(button);
|
|
17510
|
+
if (existing) return existing;
|
|
17511
|
+
if (!isNavbarCta(button) || !buttonId(button)) return null;
|
|
17512
|
+
const parent = button.parentElement;
|
|
17513
|
+
if (!parent) return null;
|
|
17514
|
+
const siblings = navbarCtasInScope(button).filter((el) => el.parentElement === parent);
|
|
17515
|
+
if (siblings.length < 2) return null;
|
|
17516
|
+
const id = nextCollectionId(content, button.ownerDocument);
|
|
17517
|
+
const collection = createCollection(button.ownerDocument, id, collectionGap(button, tokensFromButton(button)));
|
|
17518
|
+
siblings[0].before(collection);
|
|
17519
|
+
for (const member of siblings) {
|
|
17520
|
+
collection.append(member);
|
|
17521
|
+
setButtonDragAttr(member);
|
|
17522
|
+
}
|
|
17523
|
+
return collection;
|
|
17524
|
+
}
|
|
17525
|
+
function collectionDragEnabled(el) {
|
|
17526
|
+
if (!isNavbarCta(el) || !buttonId(el)) return false;
|
|
17527
|
+
if (buttonCollectionOf(el)) return true;
|
|
17528
|
+
return navbarCtasInScope(el).length >= 2;
|
|
17529
|
+
}
|
|
17530
|
+
|
|
17531
|
+
// src/lib/item-drag-interaction.ts
|
|
17532
|
+
function disableNativeHrefDrag(el) {
|
|
17533
|
+
if (el.draggable) el.draggable = false;
|
|
17534
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
17535
|
+
el.setAttribute("draggable", "false");
|
|
17536
|
+
}
|
|
17537
|
+
}
|
|
17538
|
+
function clearTextSelection() {
|
|
17539
|
+
const sel = window.getSelection();
|
|
17540
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
17541
|
+
}
|
|
17542
|
+
function armItemPressDrag() {
|
|
17543
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
17544
|
+
}
|
|
17545
|
+
function lockItemDuringDrag() {
|
|
17546
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
17547
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
17548
|
+
clearTextSelection();
|
|
17549
|
+
}
|
|
17550
|
+
function unlockItemDragInteraction() {
|
|
17551
|
+
const wasDragging = document.documentElement.hasAttribute("data-ohw-item-dragging");
|
|
17552
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
17553
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
17554
|
+
if (wasDragging) clearTextSelection();
|
|
17555
|
+
}
|
|
17556
|
+
var armFooterPressDrag = armItemPressDrag;
|
|
17557
|
+
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
17558
|
+
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
17559
|
+
|
|
17560
|
+
// src/lib/nav-dnd.ts
|
|
17561
|
+
function listReorderableNavItems(draggedEl) {
|
|
17562
|
+
return listActiveNavbarItems(draggedEl).filter((el) => {
|
|
17563
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
17564
|
+
return isNavbarHrefKey(key) && !isNestedNavChild(el);
|
|
17565
|
+
});
|
|
17566
|
+
}
|
|
17567
|
+
function resolveParentNavHrefKey(child) {
|
|
17568
|
+
const childrenRoot = child.closest("[data-ohw-nav-children]");
|
|
17569
|
+
const group = childrenRoot?.closest("[data-ohw-nav-group]");
|
|
17570
|
+
if (!group) return null;
|
|
17571
|
+
const trigger = group.querySelector(":scope > [data-ohw-href-key]") ?? Array.from(group.querySelectorAll("[data-ohw-href-key]")).find(
|
|
17572
|
+
(el) => !el.closest("[data-ohw-nav-children]")
|
|
17573
|
+
) ?? null;
|
|
17574
|
+
const key = trigger?.getAttribute("data-ohw-href-key");
|
|
17575
|
+
return key && isNavbarHrefKey(key) ? key : null;
|
|
17576
|
+
}
|
|
17577
|
+
function listNavChildren(parentHrefKey, draggedEl) {
|
|
17578
|
+
const items = listActiveNavbarItems(draggedEl);
|
|
17579
|
+
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
17580
|
+
if (!parent) return [];
|
|
17581
|
+
const group = parent.closest("[data-ohw-nav-group]");
|
|
17582
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
17583
|
+
if (!childrenRoot) return [];
|
|
17584
|
+
return Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
17585
|
+
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
17586
|
+
);
|
|
17587
|
+
}
|
|
17588
|
+
function isVerticalNavLayout(items, draggedEl) {
|
|
17589
|
+
const visible = items.filter((el) => el.getClientRects().length > 0);
|
|
17590
|
+
if (visible.length >= 2) {
|
|
17591
|
+
const a = visible[0].getBoundingClientRect();
|
|
17592
|
+
const b = visible[1].getBoundingClientRect();
|
|
17593
|
+
const verticalGap = b.top - a.bottom;
|
|
17594
|
+
const horizontalGap = b.left - a.right;
|
|
17595
|
+
return verticalGap > horizontalGap;
|
|
17596
|
+
}
|
|
17597
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
17598
|
+
if (!container) return false;
|
|
17599
|
+
const style = window.getComputedStyle(container);
|
|
17600
|
+
return style.flexDirection === "column" || style.flexDirection === "column-reverse";
|
|
17601
|
+
}
|
|
17602
|
+
function buildVerticalRootNavDropSlots(items, draggedEl) {
|
|
17603
|
+
const slots = [];
|
|
17604
|
+
const barThickness = 3;
|
|
17605
|
+
if (items.length === 0) {
|
|
17606
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
17607
|
+
if (!container) return slots;
|
|
17608
|
+
const rect = container.getBoundingClientRect();
|
|
17609
|
+
slots.push({
|
|
17610
|
+
insertIndex: 0,
|
|
17611
|
+
parentId: null,
|
|
17612
|
+
left: rect.left,
|
|
17613
|
+
top: rect.top + rect.height / 2 - barThickness / 2,
|
|
17614
|
+
width: Math.max(rect.width, 40),
|
|
17615
|
+
height: barThickness,
|
|
17616
|
+
direction: "horizontal"
|
|
17617
|
+
});
|
|
17618
|
+
return slots;
|
|
17619
|
+
}
|
|
17620
|
+
const edgeGap = (() => {
|
|
17621
|
+
if (items.length < 2) return 16;
|
|
17622
|
+
const a = items[0].getBoundingClientRect();
|
|
17623
|
+
const b = items[1].getBoundingClientRect();
|
|
17624
|
+
return Math.max(0, b.top - a.bottom);
|
|
17625
|
+
})();
|
|
17626
|
+
for (let i = 0; i <= items.length; i++) {
|
|
17627
|
+
let top;
|
|
17628
|
+
let width;
|
|
17629
|
+
let left;
|
|
17630
|
+
if (i === 0) {
|
|
17631
|
+
const first = items[0].getBoundingClientRect();
|
|
17632
|
+
top = first.top - edgeGap / 2 - barThickness / 2;
|
|
17633
|
+
left = first.left;
|
|
17634
|
+
width = first.width;
|
|
17635
|
+
} else if (i === items.length) {
|
|
17636
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
17637
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.top - items[items.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
17638
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
17639
|
+
left = last.left;
|
|
17640
|
+
width = last.width;
|
|
17641
|
+
} else {
|
|
17642
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
17643
|
+
const next = items[i].getBoundingClientRect();
|
|
17644
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
17645
|
+
left = Math.min(prev.left, next.left);
|
|
17646
|
+
width = Math.max(prev.right, next.right) - left;
|
|
17647
|
+
}
|
|
17648
|
+
slots.push({
|
|
17649
|
+
insertIndex: i,
|
|
17650
|
+
parentId: null,
|
|
17651
|
+
left,
|
|
17652
|
+
top,
|
|
17653
|
+
width: Math.max(width, 40),
|
|
17654
|
+
height: barThickness,
|
|
17655
|
+
direction: "horizontal"
|
|
17656
|
+
});
|
|
17657
|
+
}
|
|
17658
|
+
return slots;
|
|
17659
|
+
}
|
|
17660
|
+
function buildHorizontalRootNavDropSlots(items, draggedEl) {
|
|
17661
|
+
const slots = [];
|
|
17662
|
+
const barThickness = 3;
|
|
17663
|
+
if (items.length === 0) {
|
|
17664
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
17665
|
+
if (!container) return slots;
|
|
17666
|
+
const rect = container.getBoundingClientRect();
|
|
17667
|
+
slots.push({
|
|
17668
|
+
insertIndex: 0,
|
|
17669
|
+
parentId: null,
|
|
17670
|
+
left: rect.left + rect.width / 2 - barThickness / 2,
|
|
17671
|
+
top: rect.top,
|
|
17672
|
+
width: barThickness,
|
|
17673
|
+
height: Math.max(rect.height, 24),
|
|
17674
|
+
direction: "vertical"
|
|
17675
|
+
});
|
|
17676
|
+
return slots;
|
|
17677
|
+
}
|
|
17678
|
+
const edgeGap = (() => {
|
|
17679
|
+
if (items.length < 2) return 32;
|
|
17680
|
+
const a = items[0].getBoundingClientRect();
|
|
17681
|
+
const b = items[1].getBoundingClientRect();
|
|
17682
|
+
return Math.max(0, b.left - a.right);
|
|
17683
|
+
})();
|
|
17684
|
+
for (let i = 0; i <= items.length; i++) {
|
|
17685
|
+
let left;
|
|
17686
|
+
let top;
|
|
17687
|
+
let height;
|
|
17688
|
+
if (i === 0) {
|
|
17689
|
+
const first = items[0].getBoundingClientRect();
|
|
17690
|
+
left = first.left - edgeGap / 2 - barThickness / 2;
|
|
17691
|
+
top = first.top;
|
|
17692
|
+
height = first.height;
|
|
17693
|
+
} else if (i === items.length) {
|
|
17694
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
17695
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.left - items[items.length - 2].getBoundingClientRect().right) : edgeGap;
|
|
17696
|
+
left = last.right + lastGap / 2 - barThickness / 2;
|
|
17697
|
+
top = last.top;
|
|
17698
|
+
height = last.height;
|
|
17699
|
+
} else {
|
|
17700
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
17701
|
+
const next = items[i].getBoundingClientRect();
|
|
17702
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
17703
|
+
top = Math.min(prev.top, next.top);
|
|
17704
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
17705
|
+
}
|
|
17706
|
+
slots.push({
|
|
17707
|
+
insertIndex: i,
|
|
17708
|
+
parentId: null,
|
|
17709
|
+
left,
|
|
17710
|
+
top,
|
|
17711
|
+
width: barThickness,
|
|
17712
|
+
height: Math.max(height, 24),
|
|
17713
|
+
direction: "vertical"
|
|
17714
|
+
});
|
|
17715
|
+
}
|
|
17716
|
+
return slots;
|
|
17717
|
+
}
|
|
17718
|
+
function buildRootNavDropSlots(draggedEl) {
|
|
17719
|
+
const items = listReorderableNavItems(draggedEl);
|
|
17720
|
+
if (isVerticalNavLayout(items, draggedEl)) {
|
|
17721
|
+
return buildVerticalRootNavDropSlots(items, draggedEl);
|
|
17722
|
+
}
|
|
17723
|
+
return buildHorizontalRootNavDropSlots(items, draggedEl);
|
|
16188
17724
|
}
|
|
16189
17725
|
function buildChildNavDropSlots(parentHrefKey, draggedEl) {
|
|
16190
17726
|
const children = listNavChildren(parentHrefKey, draggedEl);
|
|
@@ -16421,7 +17957,7 @@ function useNavItemDrag({
|
|
|
16421
17957
|
document.querySelectorAll(
|
|
16422
17958
|
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
16423
17959
|
).forEach((el) => {
|
|
16424
|
-
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
17960
|
+
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key")) || isCtaButton(el)) {
|
|
16425
17961
|
disableNativeHrefDrag(el);
|
|
16426
17962
|
}
|
|
16427
17963
|
});
|
|
@@ -16730,12 +18266,6 @@ var SECTION_DRAG_EXCLUDED_SELECTOR = [
|
|
|
16730
18266
|
"[data-ohw-media-overlay]",
|
|
16731
18267
|
"[data-ohw-media-skeleton]"
|
|
16732
18268
|
].join(", ");
|
|
16733
|
-
function visibleClip(ps) {
|
|
16734
|
-
if (!ps) return null;
|
|
16735
|
-
const top = Math.max(0, ps.headerH - ps.iframeOffsetTop);
|
|
16736
|
-
const bottom = Math.min(window.innerHeight, ps.headerH + ps.canvasH - ps.iframeOffsetTop);
|
|
16737
|
-
return { top, bottom: Math.max(top, bottom) };
|
|
16738
|
-
}
|
|
16739
18269
|
function useSectionDrag({
|
|
16740
18270
|
isEditMode,
|
|
16741
18271
|
editContentRef,
|
|
@@ -16772,7 +18302,7 @@ function useSectionDrag({
|
|
|
16772
18302
|
}, [postToParentRef, stopAutoScroll]);
|
|
16773
18303
|
const updateAutoScroll = useCallback9(
|
|
16774
18304
|
(clientY) => {
|
|
16775
|
-
const clip =
|
|
18305
|
+
const clip = getIframeChromeClip(parentScrollRef.current);
|
|
16776
18306
|
let delta = 0;
|
|
16777
18307
|
if (clip) {
|
|
16778
18308
|
const distTop = clientY - clip.top;
|
|
@@ -16979,7 +18509,7 @@ function useSectionDrag({
|
|
|
16979
18509
|
|
|
16980
18510
|
// src/ui/footer-container-chrome.tsx
|
|
16981
18511
|
import { Plus as Plus2 } from "lucide-react";
|
|
16982
|
-
import { jsx as
|
|
18512
|
+
import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
16983
18513
|
function FooterContainerChrome({
|
|
16984
18514
|
rect,
|
|
16985
18515
|
onAdd,
|
|
@@ -16987,7 +18517,7 @@ function FooterContainerChrome({
|
|
|
16987
18517
|
}) {
|
|
16988
18518
|
const chromeGap = 6;
|
|
16989
18519
|
const buttonMargin = 7;
|
|
16990
|
-
return /* @__PURE__ */
|
|
18520
|
+
return /* @__PURE__ */ jsx32(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx32(
|
|
16991
18521
|
"div",
|
|
16992
18522
|
{
|
|
16993
18523
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -16999,8 +18529,8 @@ function FooterContainerChrome({
|
|
|
16999
18529
|
width: rect.width + chromeGap * 2,
|
|
17000
18530
|
height: rect.height + chromeGap * 2
|
|
17001
18531
|
},
|
|
17002
|
-
children: /* @__PURE__ */
|
|
17003
|
-
/* @__PURE__ */
|
|
18532
|
+
children: /* @__PURE__ */ jsxs22(Tooltip, { children: [
|
|
18533
|
+
/* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(
|
|
17004
18534
|
"button",
|
|
17005
18535
|
{
|
|
17006
18536
|
type: "button",
|
|
@@ -17019,10 +18549,10 @@ function FooterContainerChrome({
|
|
|
17019
18549
|
if (addDisabled) return;
|
|
17020
18550
|
onAdd();
|
|
17021
18551
|
},
|
|
17022
|
-
children: /* @__PURE__ */
|
|
18552
|
+
children: /* @__PURE__ */ jsx32(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
17023
18553
|
}
|
|
17024
18554
|
) }),
|
|
17025
|
-
/* @__PURE__ */
|
|
18555
|
+
/* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
17026
18556
|
] })
|
|
17027
18557
|
}
|
|
17028
18558
|
) });
|
|
@@ -17184,7 +18714,14 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
17184
18714
|
// so collecting the DOM alone left them behind: the draft knew the row was showing icons and
|
|
17185
18715
|
// had gained an item, and the published page went back to the template's own (OHH-736).
|
|
17186
18716
|
SOCIALS_ORDER_KEY,
|
|
17187
|
-
SOCIALS_DISPLAY_KEY
|
|
18717
|
+
SOCIALS_DISPLAY_KEY,
|
|
18718
|
+
// Button variant/size tokens and per-CTA assignments — JSON in editContent, applied on hydrate.
|
|
18719
|
+
BUTTON_VARIANTS_KEY,
|
|
18720
|
+
BUTTON_SIZES_KEY,
|
|
18721
|
+
BUTTON_ASSIGNMENTS_KEY,
|
|
18722
|
+
BUTTON_COLLECTIONS_KEY,
|
|
18723
|
+
BUTTON_SNAPSHOTS_KEY,
|
|
18724
|
+
BUTTON_HIDDEN_KEY
|
|
17188
18725
|
]) {
|
|
17189
18726
|
const text = extraContent[key];
|
|
17190
18727
|
if (typeof text === "string" && text.length > 0) {
|
|
@@ -17505,13 +19042,13 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
17505
19042
|
|
|
17506
19043
|
// src/ui/navbar-container-chrome.tsx
|
|
17507
19044
|
import { Plus as Plus3 } from "lucide-react";
|
|
17508
|
-
import { jsx as
|
|
19045
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
17509
19046
|
function NavbarContainerChrome({
|
|
17510
19047
|
rect,
|
|
17511
19048
|
onAdd
|
|
17512
19049
|
}) {
|
|
17513
19050
|
const chromeGap = 6;
|
|
17514
|
-
return /* @__PURE__ */
|
|
19051
|
+
return /* @__PURE__ */ jsx33(
|
|
17515
19052
|
"div",
|
|
17516
19053
|
{
|
|
17517
19054
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -17523,7 +19060,7 @@ function NavbarContainerChrome({
|
|
|
17523
19060
|
width: rect.width + chromeGap * 2,
|
|
17524
19061
|
height: rect.height + chromeGap * 2
|
|
17525
19062
|
},
|
|
17526
|
-
children: /* @__PURE__ */
|
|
19063
|
+
children: /* @__PURE__ */ jsx33(
|
|
17527
19064
|
"button",
|
|
17528
19065
|
{
|
|
17529
19066
|
type: "button",
|
|
@@ -17540,7 +19077,7 @@ function NavbarContainerChrome({
|
|
|
17540
19077
|
e.stopPropagation();
|
|
17541
19078
|
onAdd();
|
|
17542
19079
|
},
|
|
17543
|
-
children: /* @__PURE__ */
|
|
19080
|
+
children: /* @__PURE__ */ jsx33(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
17544
19081
|
}
|
|
17545
19082
|
)
|
|
17546
19083
|
}
|
|
@@ -17549,7 +19086,7 @@ function NavbarContainerChrome({
|
|
|
17549
19086
|
|
|
17550
19087
|
// src/ui/drop-indicator.tsx
|
|
17551
19088
|
import * as React11 from "react";
|
|
17552
|
-
import { jsx as
|
|
19089
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
17553
19090
|
var dropIndicatorVariants = cva(
|
|
17554
19091
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
17555
19092
|
{
|
|
@@ -17573,7 +19110,7 @@ var dropIndicatorVariants = cva(
|
|
|
17573
19110
|
);
|
|
17574
19111
|
var DropIndicator = React11.forwardRef(
|
|
17575
19112
|
({ className, direction, state, ...props }, ref) => {
|
|
17576
|
-
return /* @__PURE__ */
|
|
19113
|
+
return /* @__PURE__ */ jsx34(
|
|
17577
19114
|
"div",
|
|
17578
19115
|
{
|
|
17579
19116
|
ref,
|
|
@@ -17590,7 +19127,7 @@ var DropIndicator = React11.forwardRef(
|
|
|
17590
19127
|
DropIndicator.displayName = "DropIndicator";
|
|
17591
19128
|
|
|
17592
19129
|
// src/ui/badge.tsx
|
|
17593
|
-
import { jsx as
|
|
19130
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
17594
19131
|
var badgeVariants = cva(
|
|
17595
19132
|
"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",
|
|
17596
19133
|
{
|
|
@@ -17608,12 +19145,12 @@ var badgeVariants = cva(
|
|
|
17608
19145
|
}
|
|
17609
19146
|
);
|
|
17610
19147
|
function Badge({ className, variant, ...props }) {
|
|
17611
|
-
return /* @__PURE__ */
|
|
19148
|
+
return /* @__PURE__ */ jsx35("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
17612
19149
|
}
|
|
17613
19150
|
|
|
17614
19151
|
// src/OhhwellsBridge.tsx
|
|
17615
|
-
import { Link as Link2, Plus as Plus4, Settings } from "lucide-react";
|
|
17616
|
-
import { Fragment as Fragment10, jsx as
|
|
19152
|
+
import { Brush as Brush2, Link as Link2, Plus as Plus4, Settings } from "lucide-react";
|
|
19153
|
+
import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
17617
19154
|
var PRIMARY5 = "#0885FE";
|
|
17618
19155
|
var IMAGE_FADE_MS = 300;
|
|
17619
19156
|
var MEDIA_SETTLE_TIMEOUT_MS = 2500;
|
|
@@ -17735,7 +19272,7 @@ function duplicateSchedulingWidget(instanceId, scheduleId) {
|
|
|
17735
19272
|
schedulingRoots.set(container, root);
|
|
17736
19273
|
flushSync2(() => {
|
|
17737
19274
|
root.render(
|
|
17738
|
-
/* @__PURE__ */
|
|
19275
|
+
/* @__PURE__ */ jsx36(
|
|
17739
19276
|
SchedulingWidget,
|
|
17740
19277
|
{
|
|
17741
19278
|
notifyOnConnect: false,
|
|
@@ -17873,7 +19410,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
17873
19410
|
schedulingRoots.set(container, root);
|
|
17874
19411
|
flushSync2(() => {
|
|
17875
19412
|
root.render(
|
|
17876
|
-
/* @__PURE__ */
|
|
19413
|
+
/* @__PURE__ */ jsx36(
|
|
17877
19414
|
SchedulingWidget,
|
|
17878
19415
|
{
|
|
17879
19416
|
notifyOnConnect,
|
|
@@ -18036,8 +19573,8 @@ function lockVideoBox(video) {
|
|
|
18036
19573
|
}
|
|
18037
19574
|
const fit = video.style.objectFit || getComputedStyle(video).objectFit;
|
|
18038
19575
|
const bg = getComputedStyle(video).backgroundColor;
|
|
18039
|
-
const
|
|
18040
|
-
if (fit === "contain" &&
|
|
19576
|
+
const isTransparent2 = bg === "rgba(0, 0, 0, 0)" || bg === "transparent" || !bg;
|
|
19577
|
+
if (fit === "contain" && isTransparent2) {
|
|
18041
19578
|
video.style.backgroundColor = "var(--color-dark, #000)";
|
|
18042
19579
|
}
|
|
18043
19580
|
}
|
|
@@ -18187,7 +19724,10 @@ function listNavigationItems() {
|
|
|
18187
19724
|
).filter((el) => isNavigationItem2(el));
|
|
18188
19725
|
}
|
|
18189
19726
|
function getNavigationItemReorderState(anchor) {
|
|
18190
|
-
if (isCtaButton(anchor))
|
|
19727
|
+
if (isCtaButton(anchor)) {
|
|
19728
|
+
if (!collectionDragEnabled(anchor)) return { key: null, disabled: true };
|
|
19729
|
+
return { key: buttonId(anchor), disabled: false };
|
|
19730
|
+
}
|
|
18191
19731
|
return getReorderHandleStateFromAnchor(anchor);
|
|
18192
19732
|
}
|
|
18193
19733
|
function getReorderHandleState(el) {
|
|
@@ -18286,6 +19826,12 @@ function isPointOverNavigation(x, y) {
|
|
|
18286
19826
|
const r2 = panel.getBoundingClientRect();
|
|
18287
19827
|
if (x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom) return true;
|
|
18288
19828
|
}
|
|
19829
|
+
for (const el of document.querySelectorAll('[data-ohw-role="navbar-button"]')) {
|
|
19830
|
+
const r2 = el.getBoundingClientRect();
|
|
19831
|
+
if (r2.width > 0 && r2.height > 0 && x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom) {
|
|
19832
|
+
return true;
|
|
19833
|
+
}
|
|
19834
|
+
}
|
|
18289
19835
|
return false;
|
|
18290
19836
|
}
|
|
18291
19837
|
function findHoveredNavOrFooterContainer(x, y) {
|
|
@@ -18619,7 +20165,7 @@ function EditGlowChrome({
|
|
|
18619
20165
|
hideHandle = false
|
|
18620
20166
|
}) {
|
|
18621
20167
|
const GAP = SELECTION_CHROME_GAP2;
|
|
18622
|
-
return /* @__PURE__ */
|
|
20168
|
+
return /* @__PURE__ */ jsxs23(
|
|
18623
20169
|
"div",
|
|
18624
20170
|
{
|
|
18625
20171
|
ref: elRef,
|
|
@@ -18634,7 +20180,7 @@ function EditGlowChrome({
|
|
|
18634
20180
|
zIndex: 2147483646
|
|
18635
20181
|
},
|
|
18636
20182
|
children: [
|
|
18637
|
-
/* @__PURE__ */
|
|
20183
|
+
/* @__PURE__ */ jsx36(
|
|
18638
20184
|
"div",
|
|
18639
20185
|
{
|
|
18640
20186
|
style: {
|
|
@@ -18648,7 +20194,7 @@ function EditGlowChrome({
|
|
|
18648
20194
|
}
|
|
18649
20195
|
}
|
|
18650
20196
|
),
|
|
18651
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
20197
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx36(
|
|
18652
20198
|
"div",
|
|
18653
20199
|
{
|
|
18654
20200
|
"data-ohw-drag-handle-container": "",
|
|
@@ -18660,7 +20206,7 @@ function EditGlowChrome({
|
|
|
18660
20206
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
18661
20207
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
18662
20208
|
},
|
|
18663
|
-
children: /* @__PURE__ */
|
|
20209
|
+
children: /* @__PURE__ */ jsx36(
|
|
18664
20210
|
DragHandle,
|
|
18665
20211
|
{
|
|
18666
20212
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -18674,22 +20220,12 @@ function EditGlowChrome({
|
|
|
18674
20220
|
}
|
|
18675
20221
|
);
|
|
18676
20222
|
}
|
|
18677
|
-
function getIframeVisibleClip(parentScroll) {
|
|
18678
|
-
if (!parentScroll) return null;
|
|
18679
|
-
const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
|
|
18680
|
-
const clipTop = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
18681
|
-
const clipBottom = Math.min(
|
|
18682
|
-
window.innerHeight,
|
|
18683
|
-
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
18684
|
-
);
|
|
18685
|
-
return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
|
|
18686
|
-
}
|
|
18687
20223
|
function isRectOutsideClip(rect, clip) {
|
|
18688
20224
|
if (!clip) return false;
|
|
18689
20225
|
return rect.bottom < clip.top || rect.top > clip.bottom;
|
|
18690
20226
|
}
|
|
18691
20227
|
function applyVisibleViewport(el, parentScroll) {
|
|
18692
|
-
const clip =
|
|
20228
|
+
const clip = getIframeChromeClip(parentScroll);
|
|
18693
20229
|
const top = clip?.top ?? 0;
|
|
18694
20230
|
const height = clip ? clip.bottom - clip.top : window.innerHeight;
|
|
18695
20231
|
el.style.top = `${top}px`;
|
|
@@ -18729,7 +20265,7 @@ function clampToolbarLeft(centerX, toolbarWidth) {
|
|
|
18729
20265
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
18730
20266
|
const GAP = TOOLBAR_OFFSET_FROM_ELEMENT;
|
|
18731
20267
|
const APPROX_H = 32;
|
|
18732
|
-
const clip =
|
|
20268
|
+
const clip = getIframeChromeClip(parentScroll);
|
|
18733
20269
|
const clipTop = clip?.top ?? 0;
|
|
18734
20270
|
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
18735
20271
|
const visibleTop = rect.top - canvasTopInIframe;
|
|
@@ -18874,7 +20410,7 @@ function FloatingToolbar({
|
|
|
18874
20410
|
return () => ro.disconnect();
|
|
18875
20411
|
}, [showEditLink, activeCommands]);
|
|
18876
20412
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
18877
|
-
return /* @__PURE__ */
|
|
20413
|
+
return /* @__PURE__ */ jsx36(
|
|
18878
20414
|
"div",
|
|
18879
20415
|
{
|
|
18880
20416
|
ref: setRefs,
|
|
@@ -18886,12 +20422,12 @@ function FloatingToolbar({
|
|
|
18886
20422
|
zIndex: 2147483647,
|
|
18887
20423
|
pointerEvents: "auto"
|
|
18888
20424
|
},
|
|
18889
|
-
children: /* @__PURE__ */
|
|
18890
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
18891
|
-
gi > 0 && /* @__PURE__ */
|
|
20425
|
+
children: /* @__PURE__ */ jsxs23(CustomToolbar, { children: [
|
|
20426
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs23(React12.Fragment, { children: [
|
|
20427
|
+
gi > 0 && /* @__PURE__ */ jsx36(CustomToolbarDivider, {}),
|
|
18892
20428
|
btns.map((btn) => {
|
|
18893
20429
|
const isActive = activeCommands.has(btn.cmd);
|
|
18894
|
-
return /* @__PURE__ */
|
|
20430
|
+
return /* @__PURE__ */ jsx36(
|
|
18895
20431
|
CustomToolbarButton,
|
|
18896
20432
|
{
|
|
18897
20433
|
title: btn.title,
|
|
@@ -18900,7 +20436,7 @@ function FloatingToolbar({
|
|
|
18900
20436
|
e.preventDefault();
|
|
18901
20437
|
onCommand(btn.cmd);
|
|
18902
20438
|
},
|
|
18903
|
-
children: /* @__PURE__ */
|
|
20439
|
+
children: /* @__PURE__ */ jsx36(
|
|
18904
20440
|
"svg",
|
|
18905
20441
|
{
|
|
18906
20442
|
width: "16",
|
|
@@ -18921,7 +20457,7 @@ function FloatingToolbar({
|
|
|
18921
20457
|
);
|
|
18922
20458
|
})
|
|
18923
20459
|
] }, gi)),
|
|
18924
|
-
showEditLink ? /* @__PURE__ */
|
|
20460
|
+
showEditLink ? /* @__PURE__ */ jsx36(
|
|
18925
20461
|
CustomToolbarButton,
|
|
18926
20462
|
{
|
|
18927
20463
|
type: "button",
|
|
@@ -18935,7 +20471,7 @@ function FloatingToolbar({
|
|
|
18935
20471
|
e.preventDefault();
|
|
18936
20472
|
e.stopPropagation();
|
|
18937
20473
|
},
|
|
18938
|
-
children: /* @__PURE__ */
|
|
20474
|
+
children: /* @__PURE__ */ jsx36(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
18939
20475
|
}
|
|
18940
20476
|
) : null
|
|
18941
20477
|
] })
|
|
@@ -18952,7 +20488,7 @@ function StateToggle({
|
|
|
18952
20488
|
states,
|
|
18953
20489
|
onStateChange
|
|
18954
20490
|
}) {
|
|
18955
|
-
return /* @__PURE__ */
|
|
20491
|
+
return /* @__PURE__ */ jsx36(
|
|
18956
20492
|
ToggleGroup,
|
|
18957
20493
|
{
|
|
18958
20494
|
"data-ohw-state-toggle": "",
|
|
@@ -18966,7 +20502,7 @@ function StateToggle({
|
|
|
18966
20502
|
left: rect.right - 8,
|
|
18967
20503
|
transform: "translateX(-100%)"
|
|
18968
20504
|
},
|
|
18969
|
-
children: states.map((state) => /* @__PURE__ */
|
|
20505
|
+
children: states.map((state) => /* @__PURE__ */ jsx36(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
18970
20506
|
}
|
|
18971
20507
|
);
|
|
18972
20508
|
}
|
|
@@ -18982,9 +20518,9 @@ var OHW_LOADER_STYLE = {
|
|
|
18982
20518
|
justifyContent: "center"
|
|
18983
20519
|
};
|
|
18984
20520
|
function OhwLoaderSpinner() {
|
|
18985
|
-
return /* @__PURE__ */
|
|
18986
|
-
/* @__PURE__ */
|
|
18987
|
-
/* @__PURE__ */
|
|
20521
|
+
return /* @__PURE__ */ jsxs23("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
|
|
20522
|
+
/* @__PURE__ */ jsx36("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
|
|
20523
|
+
/* @__PURE__ */ jsx36(
|
|
18988
20524
|
"circle",
|
|
18989
20525
|
{
|
|
18990
20526
|
cx: "14",
|
|
@@ -18994,7 +20530,7 @@ function OhwLoaderSpinner() {
|
|
|
18994
20530
|
strokeWidth: "3",
|
|
18995
20531
|
strokeDasharray: "17 52",
|
|
18996
20532
|
strokeLinecap: "round",
|
|
18997
|
-
children: /* @__PURE__ */
|
|
20533
|
+
children: /* @__PURE__ */ jsx36(
|
|
18998
20534
|
"animateTransform",
|
|
18999
20535
|
{
|
|
19000
20536
|
attributeName: "transform",
|
|
@@ -19010,7 +20546,7 @@ function OhwLoaderSpinner() {
|
|
|
19010
20546
|
] });
|
|
19011
20547
|
}
|
|
19012
20548
|
function OhwBrandMark() {
|
|
19013
|
-
return /* @__PURE__ */
|
|
20549
|
+
return /* @__PURE__ */ jsxs23(
|
|
19014
20550
|
"svg",
|
|
19015
20551
|
{
|
|
19016
20552
|
width: "16",
|
|
@@ -19021,7 +20557,7 @@ function OhwBrandMark() {
|
|
|
19021
20557
|
style: { display: "block", flexShrink: 0 },
|
|
19022
20558
|
xmlns: "http://www.w3.org/2000/svg",
|
|
19023
20559
|
children: [
|
|
19024
|
-
/* @__PURE__ */
|
|
20560
|
+
/* @__PURE__ */ jsx36(
|
|
19025
20561
|
"mask",
|
|
19026
20562
|
{
|
|
19027
20563
|
id: "ohw-badge-mark",
|
|
@@ -19031,15 +20567,15 @@ function OhwBrandMark() {
|
|
|
19031
20567
|
y: "0",
|
|
19032
20568
|
width: "48",
|
|
19033
20569
|
height: "48",
|
|
19034
|
-
children: /* @__PURE__ */
|
|
20570
|
+
children: /* @__PURE__ */ jsx36("path", { d: "M23.8741 48C37.0594 48 47.7481 37.2548 47.7481 24C47.7481 10.7452 37.0594 0 23.8741 0C10.6888 0 0 10.7452 0 24C0 37.2548 10.6888 48 23.8741 48Z", fill: "white" })
|
|
19035
20571
|
}
|
|
19036
20572
|
),
|
|
19037
|
-
/* @__PURE__ */
|
|
19038
|
-
/* @__PURE__ */
|
|
19039
|
-
/* @__PURE__ */
|
|
19040
|
-
/* @__PURE__ */
|
|
19041
|
-
/* @__PURE__ */
|
|
19042
|
-
/* @__PURE__ */
|
|
20573
|
+
/* @__PURE__ */ jsxs23("g", { mask: "url(#ohw-badge-mark)", children: [
|
|
20574
|
+
/* @__PURE__ */ jsx36("path", { d: "M23.8731 48.0497C37.0584 48.0497 47.7472 37.3046 47.7472 24.0497C47.7472 10.7949 37.0584 0.0497208 23.8731 0.0497208C10.6878 0.0497208 -0.000976562 10.7949 -0.000976562 24.0497C-0.000976562 37.3046 10.6878 48.0497 23.8731 48.0497Z", fill: "#0078E5" }),
|
|
20575
|
+
/* @__PURE__ */ jsx36("path", { d: "M17.1307 14.7172C13.1687 14.7172 9.38102 18.1154 8.65114 22.34C8.38885 23.8488 8.5598 25.2581 9.06929 26.4451C6.20005 29.1677 1.77216 27.8721 -1.40212 26.1536C-2.73618 25.4317 -3.92695 27.4745 -2.59037 28.1981C1.33389 30.3226 6.86037 31.6621 10.4402 28.4188C11.4718 29.3859 12.867 29.9621 14.4894 29.9621C18.4161 29.9621 22.2038 26.5318 22.9337 22.34C23.6636 18.1162 21.0566 14.7172 17.1298 14.7172H17.1307ZM19.9798 22.34C19.5281 25.0399 17.2689 27.231 14.9754 27.231C12.6466 27.231 11.1877 25.0399 11.6394 22.34C12.1262 19.6401 14.3151 17.4482 16.6438 17.4482C18.9374 17.4482 20.4667 19.6401 19.9798 22.34Z", fill: "white" }),
|
|
20576
|
+
/* @__PURE__ */ jsx36("path", { d: "M40.0017 27.0262C39.1797 27.081 38.2721 26.995 37.4668 26.7415C37.3344 26.6993 37.28 26.5401 37.3529 26.4205C37.5959 26.0212 37.8255 25.6152 38.009 25.1889C38.1071 24.9918 38.2018 24.793 38.2897 24.5908C38.3274 24.5041 38.4163 24.451 38.5101 24.4619C38.63 24.4754 38.7054 24.4821 38.8881 24.4821L39.1529 24.4796L39.8283 24.4543C45.9229 24.0492 50.4765 20.4319 54.8466 16.9014C56.0172 15.9554 57.6932 17.6208 56.5116 18.5752C51.7687 22.4065 47.1966 26.5081 40.9319 26.9689", fill: "white" }),
|
|
20577
|
+
/* @__PURE__ */ jsx36("path", { d: "M37.9687 24.27C38.4472 23.1319 38.7656 21.9045 38.9609 20.6991C39.5927 16.76 38.5058 14.2193 36.1553 14.2193C34.1835 14.2193 33.1469 17.2427 32.9199 18.8694C32.743 19.9872 32.5914 22.1219 33.6028 23.9524C33.7553 24.259 34.15 24.7712 34.471 25.1259C34.5447 25.2067 34.6746 25.2 34.7349 25.1082C34.9528 24.7788 35.1615 24.4039 35.3584 24.0257C35.5444 23.6677 35.5888 23.6138 35.8587 23.0207C35.8838 22.966 35.8813 22.9002 35.8478 22.8505C35.5888 22.4597 35.2168 21.9787 35.1204 21.4614C34.9184 20.4455 34.9436 19.2257 35.2218 18.1078C35.4413 17.3118 35.7195 16.7844 35.9039 16.5106C35.9466 16.4466 36.0279 16.4129 36.0975 16.4449C36.369 16.5671 36.5827 16.8838 36.7385 17.396C37.0167 18.2089 37.0167 19.3782 36.814 20.6999C36.6991 21.5271 36.4771 22.3729 36.1746 23.1673C36.1293 23.308 36.0757 23.4461 36.0187 23.5826C36.0187 23.5868 36.0187 23.591 36.0187 23.5961C35.9911 23.6946 35.9207 23.8067 35.8846 23.901C35.5536 24.5497 35.2344 25.1697 34.8439 25.7838C34.8388 25.7863 34.8346 25.7914 34.8296 25.7931C34.6528 26.0525 34.4718 26.2901 34.2866 26.4965C34.2774 26.5099 34.2682 26.5234 34.2589 26.5369C34.2405 26.5638 34.2179 26.5815 34.1944 26.595C33.5064 27.3212 32.7665 27.6893 32.0123 27.6893C31.8606 27.6893 31.6838 27.664 31.507 27.4349C31.3042 27.1299 30.85 26.0879 31.2539 22.9112C31.4785 21.3949 31.8011 20.0268 31.931 19.5408C31.9579 19.4413 31.8908 19.3419 31.7886 19.3293L30.0062 19.1162C29.9241 19.1061 29.8478 19.1566 29.8252 19.2366C29.2704 21.1615 27.0305 27.6885 24.9599 27.6885C24.328 27.6885 24.1512 26.6211 24.1001 26.2909C23.775 23.6264 25.528 18.5492 29.5302 16.2267C29.6048 16.1838 29.635 16.0928 29.5998 16.0136L28.9042 14.467C28.8632 14.3752 28.7501 14.3389 28.6638 14.3886C25.8079 16.0414 24.1847 18.5231 23.2915 20.3436C22.2046 22.5793 21.6993 25.0189 21.9515 26.8738C22.1795 28.7794 23.1398 29.872 24.6054 29.872C26.0543 29.872 27.4369 28.9066 28.7098 27.0187C28.7953 26.8915 28.9889 26.9311 29.0149 27.0819C29.2646 28.5283 29.9811 29.872 31.6579 29.872C33.5282 29.872 35.3232 28.7288 36.7134 26.6447C36.7712 26.5874 36.7972 26.5411 36.8181 26.4906C36.8232 26.4931 36.8282 26.4948 36.8332 26.4973C37.01 26.2025 37.181 25.9051 37.3444 25.6027C37.4508 25.4005 37.5572 25.1992 37.6586 24.9945C37.7181 24.874 37.7743 24.7527 37.8262 24.6289C37.838 24.6002 37.8547 24.5665 37.8706 24.5337", fill: "white" }),
|
|
20578
|
+
/* @__PURE__ */ jsx36("path", { d: "M30.5839 31.6397C25.7546 34.8577 19.4773 34.7853 14.6907 31.5243C13.5368 30.7384 12.5044 32.6498 13.6474 33.4281C19.034 37.0985 26.3077 37.096 31.7218 33.488C32.8791 32.7172 31.7478 30.8639 30.5839 31.6397Z", fill: "white" })
|
|
19043
20579
|
] })
|
|
19044
20580
|
]
|
|
19045
20581
|
}
|
|
@@ -19076,7 +20612,7 @@ var OHW_BADGE_LABEL_STYLE = {
|
|
|
19076
20612
|
whiteSpace: "nowrap"
|
|
19077
20613
|
};
|
|
19078
20614
|
function MadeWithOhhWells() {
|
|
19079
|
-
return /* @__PURE__ */
|
|
20615
|
+
return /* @__PURE__ */ jsxs23(
|
|
19080
20616
|
"a",
|
|
19081
20617
|
{
|
|
19082
20618
|
href: "https://ohhwells.com",
|
|
@@ -19086,8 +20622,8 @@ function MadeWithOhhWells() {
|
|
|
19086
20622
|
"data-ohw-badge": "",
|
|
19087
20623
|
style: OHW_BADGE_STYLE,
|
|
19088
20624
|
children: [
|
|
19089
|
-
/* @__PURE__ */
|
|
19090
|
-
/* @__PURE__ */
|
|
20625
|
+
/* @__PURE__ */ jsx36(OhwBrandMark, {}),
|
|
20626
|
+
/* @__PURE__ */ jsx36("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
|
|
19091
20627
|
]
|
|
19092
20628
|
}
|
|
19093
20629
|
);
|
|
@@ -19577,7 +21113,15 @@ function OhhwellsBridge() {
|
|
|
19577
21113
|
const [floatingPanel, setFloatingPanel] = useState16(null);
|
|
19578
21114
|
const floatingPanelOpenRef = useRef12(false);
|
|
19579
21115
|
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
21116
|
+
const floatingPanelRef = useRef12(null);
|
|
21117
|
+
floatingPanelRef.current = floatingPanel;
|
|
19580
21118
|
const [floatingPanelPos, setFloatingPanelPos] = useState16(null);
|
|
21119
|
+
const buttonCollectionDragRef = useRef12(null);
|
|
21120
|
+
const buttonDropInsertIndexRef = useRef12(null);
|
|
21121
|
+
const [buttonDropSlots, setButtonDropSlots] = useState16([]);
|
|
21122
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState16(null);
|
|
21123
|
+
const buttonPointerDragRef = useRef12(null);
|
|
21124
|
+
const [buttonStyleTick, setButtonStyleTick] = useState16(0);
|
|
19581
21125
|
const [logoSizeDraft, setLogoSizeDraft] = useState16(null);
|
|
19582
21126
|
const [editorViewport, setEditorViewport] = useState16("desktop");
|
|
19583
21127
|
const [parentScrollSnap, setParentScrollSnap] = useState16(null);
|
|
@@ -19878,6 +21422,7 @@ function OhhwellsBridge() {
|
|
|
19878
21422
|
hoveredItemElRef.current = null;
|
|
19879
21423
|
setHoveredItemRect(null);
|
|
19880
21424
|
setFloatingPanel(null);
|
|
21425
|
+
setFloatingPanelPos(null);
|
|
19881
21426
|
setLogoSizeDraft(null);
|
|
19882
21427
|
if (!activeElRef.current) {
|
|
19883
21428
|
if (nestedGroup?.isConnected) {
|
|
@@ -20478,6 +22023,47 @@ function OhhwellsBridge() {
|
|
|
20478
22023
|
},
|
|
20479
22024
|
[beginFooterDrag]
|
|
20480
22025
|
);
|
|
22026
|
+
const persistButtonCollectionDrag = useCallback10(
|
|
22027
|
+
(button, clientX) => {
|
|
22028
|
+
const insertIndex = buttonDropInsertIndexRef.current;
|
|
22029
|
+
if (insertIndex != null) insertButtonAtCollectionIndex(button, insertIndex);
|
|
22030
|
+
else if (typeof clientX === "number" && clientX !== 0) reorderButtonInCollection(button, clientX);
|
|
22031
|
+
buttonDropInsertIndexRef.current = null;
|
|
22032
|
+
const collection = buttonCollectionOf(button);
|
|
22033
|
+
if (collection) {
|
|
22034
|
+
const persisted = persistCollectionOrder(collection, editContentRef.current);
|
|
22035
|
+
if (persisted) {
|
|
22036
|
+
editContentRef.current = persisted.content;
|
|
22037
|
+
postToParent2({ type: "ow:change", nodes: persisted.nodes });
|
|
22038
|
+
}
|
|
22039
|
+
}
|
|
22040
|
+
buttonCollectionDragRef.current = null;
|
|
22041
|
+
buttonPointerDragRef.current = null;
|
|
22042
|
+
setButtonDropSlots([]);
|
|
22043
|
+
setActiveButtonDropIndex(null);
|
|
22044
|
+
setIsItemDragging(false);
|
|
22045
|
+
unlockFooterDragInteraction();
|
|
22046
|
+
if (button.isConnected) setToolbarRect(button.getBoundingClientRect());
|
|
22047
|
+
},
|
|
22048
|
+
[postToParent2]
|
|
22049
|
+
);
|
|
22050
|
+
const refreshButtonDragVisuals = useCallback10((button, clientX, clientY) => {
|
|
22051
|
+
const collection = buttonCollectionOf(button);
|
|
22052
|
+
if (!collection) {
|
|
22053
|
+
setButtonDropSlots([]);
|
|
22054
|
+
setActiveButtonDropIndex(null);
|
|
22055
|
+
buttonDropInsertIndexRef.current = null;
|
|
22056
|
+
return;
|
|
22057
|
+
}
|
|
22058
|
+
const slots = buildButtonCollectionDropSlots(collection);
|
|
22059
|
+
const active = hitTestButtonCollectionDropSlot(collection, clientX, clientY);
|
|
22060
|
+
setButtonDropSlots(slots);
|
|
22061
|
+
const idx = active ? slots.findIndex((slot) => slot.insertIndex === active.insertIndex) : -1;
|
|
22062
|
+
setActiveButtonDropIndex(idx >= 0 ? idx : null);
|
|
22063
|
+
buttonDropInsertIndexRef.current = active?.insertIndex ?? null;
|
|
22064
|
+
setDraggedItemRect(button.getBoundingClientRect());
|
|
22065
|
+
if (selectedElRef.current === button) setToolbarRect(button.getBoundingClientRect());
|
|
22066
|
+
}, []);
|
|
20481
22067
|
const handleItemDragStart = useCallback10(
|
|
20482
22068
|
(e) => {
|
|
20483
22069
|
const selected = selectedElRef.current;
|
|
@@ -20487,6 +22073,17 @@ function OhhwellsBridge() {
|
|
|
20487
22073
|
}
|
|
20488
22074
|
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
20489
22075
|
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
22076
|
+
if (isCtaButton(selected) && collectionDragEnabled(selected)) {
|
|
22077
|
+
buttonCollectionDragRef.current = selected;
|
|
22078
|
+
setMediaHover(null);
|
|
22079
|
+
if (e?.dataTransfer) {
|
|
22080
|
+
e.dataTransfer.effectAllowed = "move";
|
|
22081
|
+
e.dataTransfer.setData("text/plain", buttonId(selected) ?? "button");
|
|
22082
|
+
}
|
|
22083
|
+
setIsItemDragging(true);
|
|
22084
|
+
refreshButtonDragVisuals(selected, clientX, clientY);
|
|
22085
|
+
return;
|
|
22086
|
+
}
|
|
20490
22087
|
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
20491
22088
|
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup2(selected) && selected.closest("footer")) {
|
|
20492
22089
|
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
@@ -20496,10 +22093,15 @@ function OhhwellsBridge() {
|
|
|
20496
22093
|
setSiblingHintRect(null);
|
|
20497
22094
|
setIsItemDragging(true);
|
|
20498
22095
|
},
|
|
20499
|
-
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
22096
|
+
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag, refreshButtonDragVisuals]
|
|
20500
22097
|
);
|
|
20501
22098
|
const handleItemDragEnd = useCallback10(
|
|
20502
22099
|
(e) => {
|
|
22100
|
+
const collectionButton = buttonCollectionDragRef.current;
|
|
22101
|
+
if (collectionButton) {
|
|
22102
|
+
persistButtonCollectionDrag(collectionButton, e?.clientX);
|
|
22103
|
+
return;
|
|
22104
|
+
}
|
|
20503
22105
|
if (footerDragRef.current) {
|
|
20504
22106
|
const x = e?.clientX;
|
|
20505
22107
|
const y = e?.clientY;
|
|
@@ -20522,12 +22124,22 @@ function OhhwellsBridge() {
|
|
|
20522
22124
|
}
|
|
20523
22125
|
setIsItemDragging(false);
|
|
20524
22126
|
},
|
|
20525
|
-
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
22127
|
+
[commitFooterDrag, commitNavDrag, navDragRef, persistButtonCollectionDrag]
|
|
20526
22128
|
);
|
|
20527
22129
|
const handleItemChromePointerDown = useCallback10((e) => {
|
|
20528
22130
|
if (e.button !== 0) return;
|
|
20529
22131
|
const selected = selectedElRef.current;
|
|
20530
22132
|
if (!selected) return;
|
|
22133
|
+
if (isCtaButton(selected) && collectionDragEnabled(selected)) {
|
|
22134
|
+
buttonPointerDragRef.current = {
|
|
22135
|
+
el: selected,
|
|
22136
|
+
startX: e.clientX,
|
|
22137
|
+
startY: e.clientY,
|
|
22138
|
+
pointerId: e.pointerId,
|
|
22139
|
+
started: false
|
|
22140
|
+
};
|
|
22141
|
+
return;
|
|
22142
|
+
}
|
|
20531
22143
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
20532
22144
|
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
20533
22145
|
footerPointerDragRef.current = {
|
|
@@ -20606,10 +22218,29 @@ function OhhwellsBridge() {
|
|
|
20606
22218
|
setIsFooterFrameSelection(false);
|
|
20607
22219
|
setToolbarVariant("link-action");
|
|
20608
22220
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
22221
|
+
if (glowElRef.current) glowElRef.current.style.display = "";
|
|
20609
22222
|
setToolbarShowEditLink(false);
|
|
20610
22223
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
20611
|
-
|
|
20612
|
-
|
|
22224
|
+
const panel = floatingPanelRef.current;
|
|
22225
|
+
if (panel?.kind === "button-style" && isCtaButton(anchor)) {
|
|
22226
|
+
const id = buttonId(anchor);
|
|
22227
|
+
if (id && panel.buttonId !== id) {
|
|
22228
|
+
captureButtonOrigin(anchor);
|
|
22229
|
+
setFloatingPanelPos(null);
|
|
22230
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
22231
|
+
setFloatingPanel({
|
|
22232
|
+
...panel,
|
|
22233
|
+
key: `button-style:${id}`,
|
|
22234
|
+
buttonId: id,
|
|
22235
|
+
context: buttonStyleContext(anchor)
|
|
22236
|
+
});
|
|
22237
|
+
setButtonStyleTick((n) => n + 1);
|
|
22238
|
+
}
|
|
22239
|
+
} else {
|
|
22240
|
+
setFloatingPanel(null);
|
|
22241
|
+
setFloatingPanelPos(null);
|
|
22242
|
+
setLogoSizeDraft(null);
|
|
22243
|
+
}
|
|
20613
22244
|
}, [deactivate, markSelected]);
|
|
20614
22245
|
const selectFrame = useCallback10((el) => {
|
|
20615
22246
|
if (!isNavigationContainer(el)) return;
|
|
@@ -20649,6 +22280,7 @@ function OhhwellsBridge() {
|
|
|
20649
22280
|
setToolbarShowEditLink(false);
|
|
20650
22281
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
20651
22282
|
setFloatingPanel(null);
|
|
22283
|
+
setFloatingPanelPos(null);
|
|
20652
22284
|
setLogoSizeDraft(null);
|
|
20653
22285
|
}, [deactivate, markSelected, postToParent2]);
|
|
20654
22286
|
const selectLogo = useCallback10(
|
|
@@ -20694,6 +22326,7 @@ function OhhwellsBridge() {
|
|
|
20694
22326
|
});
|
|
20695
22327
|
}, []);
|
|
20696
22328
|
const openSocialsDisplayPanel = useCallback10((row) => {
|
|
22329
|
+
setFloatingPanelPos(null);
|
|
20697
22330
|
setParentScrollSnap(parentScrollRef.current);
|
|
20698
22331
|
setFloatingPanel({
|
|
20699
22332
|
key: "socials-display",
|
|
@@ -20703,6 +22336,87 @@ function OhhwellsBridge() {
|
|
|
20703
22336
|
row
|
|
20704
22337
|
});
|
|
20705
22338
|
}, []);
|
|
22339
|
+
const rememberButtonTokens = useCallback10(
|
|
22340
|
+
(content, tokens, nodes) => {
|
|
22341
|
+
if (nodes.length === 0) return content;
|
|
22342
|
+
const next = { ...content };
|
|
22343
|
+
for (const node of nodes) next[node.key] = node.text;
|
|
22344
|
+
editContentRef.current = next;
|
|
22345
|
+
postToParent2({ type: "ow:change", nodes });
|
|
22346
|
+
return next;
|
|
22347
|
+
},
|
|
22348
|
+
[postToParent2]
|
|
22349
|
+
);
|
|
22350
|
+
const tokensForButton = useCallback10(
|
|
22351
|
+
(el, persistFallback = false) => {
|
|
22352
|
+
const stored = readStoredStyleTokens(editContentRef.current);
|
|
22353
|
+
if (stored) return stored;
|
|
22354
|
+
const ensured = ensureButtonStyleTokens(document, editContentRef.current);
|
|
22355
|
+
if (ensured.tokens) {
|
|
22356
|
+
rememberButtonTokens(editContentRef.current, ensured.tokens, ensured.nodes);
|
|
22357
|
+
return ensured.tokens;
|
|
22358
|
+
}
|
|
22359
|
+
const fallback = tokensFromButton(el);
|
|
22360
|
+
if (persistFallback) rememberButtonTokens(editContentRef.current, fallback, styleTokenNodes(fallback));
|
|
22361
|
+
return fallback;
|
|
22362
|
+
},
|
|
22363
|
+
[rememberButtonTokens]
|
|
22364
|
+
);
|
|
22365
|
+
const openButtonStylePanel = useCallback10(
|
|
22366
|
+
(anchor) => {
|
|
22367
|
+
const id = buttonId(anchor);
|
|
22368
|
+
if (!id) return;
|
|
22369
|
+
captureButtonOrigin(anchor);
|
|
22370
|
+
tokensForButton(anchor);
|
|
22371
|
+
setFloatingPanelPos(null);
|
|
22372
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
22373
|
+
setFloatingPanel({
|
|
22374
|
+
key: `button-style:${id}`,
|
|
22375
|
+
title: "Style",
|
|
22376
|
+
context: buttonStyleContext(anchor),
|
|
22377
|
+
kind: "button-style",
|
|
22378
|
+
buttonId: id
|
|
22379
|
+
});
|
|
22380
|
+
},
|
|
22381
|
+
[tokensForButton]
|
|
22382
|
+
);
|
|
22383
|
+
const applySelectedButtonStyle = useCallback10(
|
|
22384
|
+
(patch) => {
|
|
22385
|
+
const panel = floatingPanelRef.current;
|
|
22386
|
+
const id = panel?.kind === "button-style" ? panel.buttonId : null;
|
|
22387
|
+
const el = id ? document.querySelector(`[data-ohw-href-key="${CSS.escape(id)}"]`) : null;
|
|
22388
|
+
if (!el || !id || !isCtaButton(el)) return;
|
|
22389
|
+
const tokens = tokensFromButton(el);
|
|
22390
|
+
const next = { ...assignmentFor(el, editContentRef.current, tokens), ...patch };
|
|
22391
|
+
const assignments = withAssignment(editContentRef.current, id, next);
|
|
22392
|
+
const text = JSON.stringify(assignments);
|
|
22393
|
+
editContentRef.current = { ...editContentRef.current, [BUTTON_ASSIGNMENTS_KEY]: text };
|
|
22394
|
+
applyButtonStyle(el, next, tokens);
|
|
22395
|
+
postToParent2({ type: "ow:change", nodes: [{ key: BUTTON_ASSIGNMENTS_KEY, text }] });
|
|
22396
|
+
setButtonStyleTick((n) => n + 1);
|
|
22397
|
+
if (selectedElRef.current === el) setToolbarRect(el.getBoundingClientRect());
|
|
22398
|
+
},
|
|
22399
|
+
[postToParent2]
|
|
22400
|
+
);
|
|
22401
|
+
useEffect15(() => {
|
|
22402
|
+
const onDragOver = (e) => {
|
|
22403
|
+
const dragged = buttonCollectionDragRef.current;
|
|
22404
|
+
if (!dragged) return;
|
|
22405
|
+
e.preventDefault();
|
|
22406
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
22407
|
+
refreshButtonDragVisuals(dragged, e.clientX, e.clientY);
|
|
22408
|
+
};
|
|
22409
|
+
const onDrop = (e) => {
|
|
22410
|
+
if (!buttonCollectionDragRef.current) return;
|
|
22411
|
+
e.preventDefault();
|
|
22412
|
+
};
|
|
22413
|
+
document.addEventListener("dragover", onDragOver);
|
|
22414
|
+
document.addEventListener("drop", onDrop);
|
|
22415
|
+
return () => {
|
|
22416
|
+
document.removeEventListener("dragover", onDragOver);
|
|
22417
|
+
document.removeEventListener("drop", onDrop);
|
|
22418
|
+
};
|
|
22419
|
+
}, [refreshButtonDragVisuals]);
|
|
20706
22420
|
const isEditModeRef = useRef12(false);
|
|
20707
22421
|
const requestMissingSocialIconsRef = useRef12(() => {
|
|
20708
22422
|
});
|
|
@@ -20745,11 +22459,13 @@ function OhhwellsBridge() {
|
|
|
20745
22459
|
);
|
|
20746
22460
|
const closeFloatingPanelOnly = useCallback10(() => {
|
|
20747
22461
|
setFloatingPanel(null);
|
|
22462
|
+
setFloatingPanelPos(null);
|
|
20748
22463
|
setLogoSizeDraft(null);
|
|
20749
22464
|
}, []);
|
|
20750
22465
|
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
20751
22466
|
const closeFloatingPanelAndDeselect = useCallback10(() => {
|
|
20752
22467
|
setFloatingPanel(null);
|
|
22468
|
+
setFloatingPanelPos(null);
|
|
20753
22469
|
setLogoSizeDraft(null);
|
|
20754
22470
|
deselectRef.current();
|
|
20755
22471
|
}, []);
|
|
@@ -21018,6 +22734,7 @@ function OhhwellsBridge() {
|
|
|
21018
22734
|
reconcileSocialsFromContent(content);
|
|
21019
22735
|
applySocialsDisplayFromContent(content);
|
|
21020
22736
|
applySocialsLabelsFromContent(content, document, { fillEmptyOnly: isEditModeRef.current });
|
|
22737
|
+
syncButtonsFromContent(document, content);
|
|
21021
22738
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
21022
22739
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
21023
22740
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
@@ -21218,6 +22935,7 @@ function OhhwellsBridge() {
|
|
|
21218
22935
|
reconcileSocialsFromContent(content);
|
|
21219
22936
|
applySocialsDisplayFromContent(content);
|
|
21220
22937
|
applySocialsLabelsFromContent(content, document, { fillEmptyOnly: isEditModeRef.current });
|
|
22938
|
+
syncButtonsFromContent(document, content);
|
|
21221
22939
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
21222
22940
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
21223
22941
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
@@ -21306,7 +23024,10 @@ function OhhwellsBridge() {
|
|
|
21306
23024
|
if (roots.length === 0) {
|
|
21307
23025
|
reconcileNavbarItemsFromContent(contentForNav());
|
|
21308
23026
|
reconcileFooterOrderFromContent(contentForNav());
|
|
21309
|
-
if (isEditMode)
|
|
23027
|
+
if (isEditMode) {
|
|
23028
|
+
syncButtonsFromContent(document, contentForNav());
|
|
23029
|
+
syncNavigationDragCursorAttrs();
|
|
23030
|
+
}
|
|
21310
23031
|
return;
|
|
21311
23032
|
}
|
|
21312
23033
|
let rafId = null;
|
|
@@ -21318,7 +23039,7 @@ function OhhwellsBridge() {
|
|
|
21318
23039
|
}
|
|
21319
23040
|
};
|
|
21320
23041
|
const run = () => {
|
|
21321
|
-
if (footerDragRef.current || navDragRef.current || applying) return;
|
|
23042
|
+
if (footerDragRef.current || navDragRef.current || buttonCollectionDragRef.current || applying) return;
|
|
21322
23043
|
applying = true;
|
|
21323
23044
|
observer?.disconnect();
|
|
21324
23045
|
try {
|
|
@@ -21328,6 +23049,7 @@ function OhhwellsBridge() {
|
|
|
21328
23049
|
reconcileSocialsFromContent(content);
|
|
21329
23050
|
applySocialsDisplayFromContent(content);
|
|
21330
23051
|
applySocialsLabelsFromContent(content, document, { fillEmptyOnly: isEditModeRef.current });
|
|
23052
|
+
syncButtonsFromContent(document, content);
|
|
21331
23053
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
21332
23054
|
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
21333
23055
|
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key")) || getSocialItem(el)) {
|
|
@@ -21335,9 +23057,9 @@ function OhhwellsBridge() {
|
|
|
21335
23057
|
}
|
|
21336
23058
|
});
|
|
21337
23059
|
document.querySelectorAll(
|
|
21338
|
-
|
|
23060
|
+
'nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key], [data-ohw-role="navbar-button"]'
|
|
21339
23061
|
).forEach((el) => {
|
|
21340
|
-
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
23062
|
+
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key")) || isCtaButton(el)) {
|
|
21341
23063
|
disableNativeHrefDrag(el);
|
|
21342
23064
|
}
|
|
21343
23065
|
});
|
|
@@ -21362,6 +23084,44 @@ function OhhwellsBridge() {
|
|
|
21362
23084
|
observer?.disconnect();
|
|
21363
23085
|
};
|
|
21364
23086
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
23087
|
+
useEffect15(() => {
|
|
23088
|
+
if (!isEditMode) return;
|
|
23089
|
+
let applying = false;
|
|
23090
|
+
let rafId = null;
|
|
23091
|
+
const run = () => {
|
|
23092
|
+
if (applying || buttonCollectionDragRef.current) return;
|
|
23093
|
+
const content = editContentRef.current;
|
|
23094
|
+
if (!content[BUTTON_COLLECTIONS_KEY] && !content[BUTTON_SNAPSHOTS_KEY]) return;
|
|
23095
|
+
applying = true;
|
|
23096
|
+
try {
|
|
23097
|
+
syncButtonsFromContent(document, content);
|
|
23098
|
+
} finally {
|
|
23099
|
+
applying = false;
|
|
23100
|
+
}
|
|
23101
|
+
};
|
|
23102
|
+
const schedule = () => {
|
|
23103
|
+
if (rafId != null) return;
|
|
23104
|
+
rafId = requestAnimationFrame(() => {
|
|
23105
|
+
rafId = null;
|
|
23106
|
+
run();
|
|
23107
|
+
});
|
|
23108
|
+
};
|
|
23109
|
+
const observer = new MutationObserver((mutations) => {
|
|
23110
|
+
if (mutations.every((m) => {
|
|
23111
|
+
const t = m.target;
|
|
23112
|
+
return t instanceof Element && Boolean(t.closest("[data-ohw-bridge], [data-ohw-bridge-root], [data-ohw-button-collection]"));
|
|
23113
|
+
})) {
|
|
23114
|
+
return;
|
|
23115
|
+
}
|
|
23116
|
+
schedule();
|
|
23117
|
+
});
|
|
23118
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
23119
|
+
run();
|
|
23120
|
+
return () => {
|
|
23121
|
+
if (rafId != null) cancelAnimationFrame(rafId);
|
|
23122
|
+
observer.disconnect();
|
|
23123
|
+
};
|
|
23124
|
+
}, [isEditMode, pathname]);
|
|
21365
23125
|
useEffect15(() => {
|
|
21366
23126
|
if (!isEditMode) return;
|
|
21367
23127
|
let lastPosted = 0;
|
|
@@ -21888,14 +23648,6 @@ function OhhwellsBridge() {
|
|
|
21888
23648
|
}
|
|
21889
23649
|
const clickedButton = findClosestButtonLike(target);
|
|
21890
23650
|
const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
|
|
21891
|
-
console.log("[click-debug]", {
|
|
21892
|
-
editableType: editable.dataset.ohwEditable,
|
|
21893
|
-
editableTag: editable.tagName,
|
|
21894
|
-
targetTag: target.tagName,
|
|
21895
|
-
clickedButtonTag: clickedButton?.tagName ?? null,
|
|
21896
|
-
buttonOnMedia,
|
|
21897
|
-
isMediaEditableEditable: isMediaEditable(editable)
|
|
21898
|
-
});
|
|
21899
23651
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
21900
23652
|
e.preventDefault();
|
|
21901
23653
|
e.stopPropagation();
|
|
@@ -21930,11 +23682,6 @@ function OhhwellsBridge() {
|
|
|
21930
23682
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
21931
23683
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
21932
23684
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
21933
|
-
console.log("[click-debug 2]", {
|
|
21934
|
-
hrefLookupTargetTag: hrefLookupTarget.tagName,
|
|
21935
|
-
hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
|
|
21936
|
-
navAnchorTag: navAnchor?.tagName ?? null
|
|
21937
|
-
});
|
|
21938
23685
|
if (navAnchor) {
|
|
21939
23686
|
e.preventDefault();
|
|
21940
23687
|
e.stopPropagation();
|
|
@@ -22450,6 +24197,20 @@ function OhhwellsBridge() {
|
|
|
22450
24197
|
}
|
|
22451
24198
|
return;
|
|
22452
24199
|
}
|
|
24200
|
+
const navbarCtaHit = findNavbarCtaAtPoint(x, y);
|
|
24201
|
+
if (navbarCtaHit) {
|
|
24202
|
+
hoveredNavContainerRef.current = null;
|
|
24203
|
+
setHoveredNavContainerRect(null);
|
|
24204
|
+
if (selected !== navbarCtaHit && !selected?.contains(navbarCtaHit)) {
|
|
24205
|
+
clearHrefKeyHover(navbarCtaHit);
|
|
24206
|
+
hoveredItemElRef.current = navbarCtaHit;
|
|
24207
|
+
setHoveredItemRect(navbarCtaHit.getBoundingClientRect());
|
|
24208
|
+
} else if (hoveredItemElRef.current === navbarCtaHit) {
|
|
24209
|
+
hoveredItemElRef.current = null;
|
|
24210
|
+
setHoveredItemRect(null);
|
|
24211
|
+
}
|
|
24212
|
+
return;
|
|
24213
|
+
}
|
|
22453
24214
|
const navContainers = Array.from(
|
|
22454
24215
|
document.querySelectorAll("[data-ohw-nav-container]")
|
|
22455
24216
|
);
|
|
@@ -22552,6 +24313,24 @@ function OhhwellsBridge() {
|
|
|
22552
24313
|
return;
|
|
22553
24314
|
}
|
|
22554
24315
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
24316
|
+
if (!isDragOver) {
|
|
24317
|
+
const buttonHit = findButtonAtPoint(x, y);
|
|
24318
|
+
if (buttonHit) {
|
|
24319
|
+
dismissImageHover();
|
|
24320
|
+
if (findNavbarCtaAtPoint(x, y)) {
|
|
24321
|
+
probeNavigationHoverAt(x, y);
|
|
24322
|
+
return;
|
|
24323
|
+
}
|
|
24324
|
+
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
24325
|
+
const selected = selectedElRef.current;
|
|
24326
|
+
if (selected !== buttonHit && !selected?.contains(buttonHit)) {
|
|
24327
|
+
clearHrefKeyHover(buttonHit);
|
|
24328
|
+
hoveredItemElRef.current = buttonHit;
|
|
24329
|
+
setHoveredItemRect(buttonHit.getBoundingClientRect());
|
|
24330
|
+
}
|
|
24331
|
+
return;
|
|
24332
|
+
}
|
|
24333
|
+
}
|
|
22555
24334
|
if (isPointOverNavigation(x, y)) {
|
|
22556
24335
|
dismissImageHover();
|
|
22557
24336
|
probeNavigationHoverAt(x, y);
|
|
@@ -22973,6 +24752,11 @@ function OhhwellsBridge() {
|
|
|
22973
24752
|
return;
|
|
22974
24753
|
}
|
|
22975
24754
|
if (onNavDragOver(e)) return;
|
|
24755
|
+
if (buttonCollectionDragRef.current) {
|
|
24756
|
+
e.preventDefault();
|
|
24757
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
24758
|
+
return;
|
|
24759
|
+
}
|
|
22976
24760
|
e.preventDefault();
|
|
22977
24761
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
22978
24762
|
if (!el) {
|
|
@@ -22997,6 +24781,7 @@ function OhhwellsBridge() {
|
|
|
22997
24781
|
};
|
|
22998
24782
|
const handleDrop = (e) => {
|
|
22999
24783
|
e.preventDefault();
|
|
24784
|
+
if (buttonCollectionDragRef.current || navDragRef.current || footerDragRef.current) return;
|
|
23000
24785
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
23001
24786
|
if (!el) return;
|
|
23002
24787
|
const file = e.dataTransfer?.files?.[0];
|
|
@@ -23352,6 +25137,7 @@ function OhhwellsBridge() {
|
|
|
23352
25137
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
23353
25138
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
23354
25139
|
reconcileFooterOrderFromContent(editContentRef.current);
|
|
25140
|
+
syncButtonsFromContent(document, editContentRef.current);
|
|
23355
25141
|
syncNavigationDragCursorAttrs();
|
|
23356
25142
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
23357
25143
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
@@ -24261,11 +26047,8 @@ function OhhwellsBridge() {
|
|
|
24261
26047
|
};
|
|
24262
26048
|
const handleParentScroll = (e) => {
|
|
24263
26049
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
24264
|
-
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
24265
|
-
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
24266
|
-
if (floatingPanelOpenRef.current) {
|
|
24267
|
-
setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
|
|
24268
|
-
}
|
|
26050
|
+
const { iframeOffsetTop, headerH, canvasH, promptBarH = 0 } = e.data;
|
|
26051
|
+
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH, promptBarH };
|
|
24269
26052
|
if (visibleViewportRef.current) {
|
|
24270
26053
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
24271
26054
|
}
|
|
@@ -24655,6 +26438,97 @@ function OhhwellsBridge() {
|
|
|
24655
26438
|
unlockFooterDragInteraction();
|
|
24656
26439
|
};
|
|
24657
26440
|
}, [isEditMode]);
|
|
26441
|
+
useEffect15(() => {
|
|
26442
|
+
if (!isEditMode) return;
|
|
26443
|
+
const THRESHOLD = 10;
|
|
26444
|
+
const onPointerDown = (e) => {
|
|
26445
|
+
if (e.button !== 0) return;
|
|
26446
|
+
if (buttonCollectionDragRef.current || navDragRef.current || footerDragRef.current) return;
|
|
26447
|
+
if (buttonPointerDragRef.current) return;
|
|
26448
|
+
const target = e.target;
|
|
26449
|
+
if (!target) return;
|
|
26450
|
+
if (target.closest(
|
|
26451
|
+
'[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root], [data-ohw-floating-panel]'
|
|
26452
|
+
)) {
|
|
26453
|
+
return;
|
|
26454
|
+
}
|
|
26455
|
+
const fromTarget = target.closest('[data-ohw-role="navbar-button"]');
|
|
26456
|
+
const anchor = (fromTarget && !fromTarget.closest("[data-ohw-bridge]") ? fromTarget : null) ?? findNavbarCtaAtPoint(e.clientX, e.clientY);
|
|
26457
|
+
if (!anchor || !collectionDragEnabled(anchor)) return;
|
|
26458
|
+
disableNativeHrefDrag(anchor);
|
|
26459
|
+
setMediaHover(null);
|
|
26460
|
+
buttonPointerDragRef.current = {
|
|
26461
|
+
el: anchor,
|
|
26462
|
+
startX: e.clientX,
|
|
26463
|
+
startY: e.clientY,
|
|
26464
|
+
pointerId: e.pointerId,
|
|
26465
|
+
started: false
|
|
26466
|
+
};
|
|
26467
|
+
};
|
|
26468
|
+
const onPointerMove = (e) => {
|
|
26469
|
+
const pending = buttonPointerDragRef.current;
|
|
26470
|
+
if (!pending) return;
|
|
26471
|
+
if (pending.started) {
|
|
26472
|
+
e.preventDefault();
|
|
26473
|
+
clearTextSelection();
|
|
26474
|
+
const dragged = buttonCollectionDragRef.current;
|
|
26475
|
+
if (!dragged) return;
|
|
26476
|
+
refreshButtonDragVisuals(dragged, e.clientX, e.clientY);
|
|
26477
|
+
return;
|
|
26478
|
+
}
|
|
26479
|
+
const dx = e.clientX - pending.startX;
|
|
26480
|
+
const dy = e.clientY - pending.startY;
|
|
26481
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
26482
|
+
e.preventDefault();
|
|
26483
|
+
pending.started = true;
|
|
26484
|
+
armFooterPressDrag();
|
|
26485
|
+
clearTextSelection();
|
|
26486
|
+
try {
|
|
26487
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
26488
|
+
} catch {
|
|
26489
|
+
}
|
|
26490
|
+
if (linkPopoverOpenRef.current) setLinkPopoverRef.current(null);
|
|
26491
|
+
if (activeElRef.current) deactivateRef.current();
|
|
26492
|
+
ensureNavbarButtonCollection(pending.el, editContentRef.current);
|
|
26493
|
+
buttonCollectionDragRef.current = pending.el;
|
|
26494
|
+
lockFooterDuringDrag();
|
|
26495
|
+
setIsItemDragging(true);
|
|
26496
|
+
refreshButtonDragVisuals(pending.el, e.clientX, e.clientY);
|
|
26497
|
+
};
|
|
26498
|
+
const endPointerDrag = (e) => {
|
|
26499
|
+
const pending = buttonPointerDragRef.current;
|
|
26500
|
+
buttonPointerDragRef.current = null;
|
|
26501
|
+
try {
|
|
26502
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
26503
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
26504
|
+
}
|
|
26505
|
+
} catch {
|
|
26506
|
+
}
|
|
26507
|
+
if (!pending) return;
|
|
26508
|
+
if (!pending.started) {
|
|
26509
|
+
unlockFooterDragInteraction();
|
|
26510
|
+
return;
|
|
26511
|
+
}
|
|
26512
|
+
suppressNextClickRef.current = true;
|
|
26513
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
26514
|
+
persistButtonCollectionDrag(pending.el, e.clientX);
|
|
26515
|
+
};
|
|
26516
|
+
const blockSelectStart = (e) => {
|
|
26517
|
+
if (buttonCollectionDragRef.current || buttonPointerDragRef.current?.started) e.preventDefault();
|
|
26518
|
+
};
|
|
26519
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
26520
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
26521
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
26522
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
26523
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
26524
|
+
return () => {
|
|
26525
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
26526
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
26527
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
26528
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
26529
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
26530
|
+
};
|
|
26531
|
+
}, [isEditMode, persistButtonCollectionDrag, refreshButtonDragVisuals]);
|
|
24658
26532
|
useEffect15(() => {
|
|
24659
26533
|
const handler = (e) => {
|
|
24660
26534
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
@@ -24695,7 +26569,7 @@ function OhhwellsBridge() {
|
|
|
24695
26569
|
postToParent2({
|
|
24696
26570
|
type: "ow:ready",
|
|
24697
26571
|
version: "1",
|
|
24698
|
-
bridgeVersion: "0.1.
|
|
26572
|
+
bridgeVersion: "0.1.121",
|
|
24699
26573
|
path: pathname,
|
|
24700
26574
|
nodes: collectEditableNodes(editContentRef.current),
|
|
24701
26575
|
sections
|
|
@@ -24774,12 +26648,12 @@ function OhhwellsBridge() {
|
|
|
24774
26648
|
return;
|
|
24775
26649
|
}
|
|
24776
26650
|
if (type !== "ow:logo-size-set") return;
|
|
24777
|
-
const
|
|
24778
|
-
if (!Number.isFinite(
|
|
24779
|
-
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx:
|
|
26651
|
+
const px2 = Number(e.data.px);
|
|
26652
|
+
if (!Number.isFinite(px2)) return;
|
|
26653
|
+
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px2, mobileFollowing: false } : {
|
|
24780
26654
|
...logoSizeDraft,
|
|
24781
|
-
desktopPx:
|
|
24782
|
-
mobilePx: logoSizeDraft.mobileFollowing ?
|
|
26655
|
+
desktopPx: px2,
|
|
26656
|
+
mobilePx: logoSizeDraft.mobileFollowing ? px2 : logoSizeDraft.mobilePx
|
|
24783
26657
|
};
|
|
24784
26658
|
setLogoSizeDraft(next);
|
|
24785
26659
|
persistLogoSizeDraft(session.placement, next);
|
|
@@ -24877,6 +26751,36 @@ function OhhwellsBridge() {
|
|
|
24877
26751
|
const handleDuplicateSelected = useCallback10(() => {
|
|
24878
26752
|
const selected = selectedElRef.current;
|
|
24879
26753
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
26754
|
+
if (isCtaButton(selected)) {
|
|
26755
|
+
const id = buttonId(selected);
|
|
26756
|
+
if (!id) return;
|
|
26757
|
+
const tokens = tokensForButton(selected, true);
|
|
26758
|
+
if (!readAssignments(editContentRef.current)[id]) {
|
|
26759
|
+
const assignment = assignmentFor(selected, editContentRef.current, tokens);
|
|
26760
|
+
const assignments = withAssignment(editContentRef.current, id, assignment);
|
|
26761
|
+
editContentRef.current = {
|
|
26762
|
+
...editContentRef.current,
|
|
26763
|
+
[BUTTON_ASSIGNMENTS_KEY]: JSON.stringify(assignments)
|
|
26764
|
+
};
|
|
26765
|
+
applyButtonStyle(selected, assignment, tokens);
|
|
26766
|
+
}
|
|
26767
|
+
const result = duplicateButton(selected, editContentRef.current);
|
|
26768
|
+
if (!result) return;
|
|
26769
|
+
editContentRef.current = result.content;
|
|
26770
|
+
const copyHref = result.copy.getAttribute("data-ohw-href-key");
|
|
26771
|
+
const copyHrefVal = copyHref ? result.content[copyHref] : void 0;
|
|
26772
|
+
if (copyHref && copyHrefVal !== void 0) applyLinkByKey(copyHref, copyHrefVal);
|
|
26773
|
+
postToParent2({ type: "ow:change", nodes: result.nodes });
|
|
26774
|
+
enforceLinkHrefs();
|
|
26775
|
+
requestAnimationFrame(() => {
|
|
26776
|
+
selectRef.current(result.copy);
|
|
26777
|
+
requestAnimationFrame(() => {
|
|
26778
|
+
const el = selectedElRef.current;
|
|
26779
|
+
if (el?.isConnected) setToolbarRect(el.getBoundingClientRect());
|
|
26780
|
+
});
|
|
26781
|
+
});
|
|
26782
|
+
return;
|
|
26783
|
+
}
|
|
24880
26784
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
24881
26785
|
if (!hrefKey) return;
|
|
24882
26786
|
const social = getSocialItem(selected);
|
|
@@ -25006,7 +26910,7 @@ function OhhwellsBridge() {
|
|
|
25006
26910
|
selectRef.current(result.anchor);
|
|
25007
26911
|
});
|
|
25008
26912
|
}
|
|
25009
|
-
}, [postToParent2]);
|
|
26913
|
+
}, [postToParent2, tokensForButton]);
|
|
25010
26914
|
const runPendingDeleteUndo = useCallback10(() => {
|
|
25011
26915
|
const pending = pendingDeleteUndoRef.current;
|
|
25012
26916
|
if (!pending) return false;
|
|
@@ -25018,6 +26922,38 @@ function OhhwellsBridge() {
|
|
|
25018
26922
|
const handleDeleteSelected = useCallback10(() => {
|
|
25019
26923
|
const selected = selectedElRef.current;
|
|
25020
26924
|
if (!selected) return false;
|
|
26925
|
+
if (isCtaButton(selected)) {
|
|
26926
|
+
if (!canDeleteButton(selected)) return false;
|
|
26927
|
+
const previousContent = editContentRef.current;
|
|
26928
|
+
const result = deleteButton(selected, previousContent);
|
|
26929
|
+
if (!result) return false;
|
|
26930
|
+
editContentRef.current = result.content;
|
|
26931
|
+
postToParent2({ type: "ow:change", nodes: result.nodes });
|
|
26932
|
+
const actionId = typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `delete-${Date.now()}`;
|
|
26933
|
+
const restoreNodes = result.nodes.map((node) => ({
|
|
26934
|
+
key: node.key,
|
|
26935
|
+
text: previousContent[node.key] ?? ""
|
|
26936
|
+
}));
|
|
26937
|
+
pendingDeleteUndoRef.current = {
|
|
26938
|
+
actionId,
|
|
26939
|
+
restore: () => {
|
|
26940
|
+
result.undo();
|
|
26941
|
+
editContentRef.current = { ...editContentRef.current, ...Object.fromEntries(restoreNodes.map((node) => [node.key, node.text])) };
|
|
26942
|
+
postToParent2({ type: "ow:change", nodes: restoreNodes });
|
|
26943
|
+
syncButtonsFromContent(document, editContentRef.current);
|
|
26944
|
+
}
|
|
26945
|
+
};
|
|
26946
|
+
deselectRef.current();
|
|
26947
|
+
postToParent2({
|
|
26948
|
+
type: "ow:toast",
|
|
26949
|
+
title: "Button deleted",
|
|
26950
|
+
toastType: "success",
|
|
26951
|
+
actionLabel: "Undo",
|
|
26952
|
+
actionId,
|
|
26953
|
+
duration: 6e3
|
|
26954
|
+
});
|
|
26955
|
+
return true;
|
|
26956
|
+
}
|
|
25021
26957
|
return deleteSelectedNavFooterItem({
|
|
25022
26958
|
selected,
|
|
25023
26959
|
isTextEditing: Boolean(activeElRef.current),
|
|
@@ -25155,14 +27091,14 @@ function OhhwellsBridge() {
|
|
|
25155
27091
|
},
|
|
25156
27092
|
[postToParent2]
|
|
25157
27093
|
);
|
|
25158
|
-
return /* @__PURE__ */
|
|
25159
|
-
/* @__PURE__ */
|
|
25160
|
-
/* @__PURE__ */
|
|
25161
|
-
subdomain && !isEditMode && showBranding && /* @__PURE__ */
|
|
27094
|
+
return /* @__PURE__ */ jsxs23(Fragment10, { children: [
|
|
27095
|
+
/* @__PURE__ */ jsx36("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx36(OhwLoaderSpinner, {}) }),
|
|
27096
|
+
/* @__PURE__ */ jsx36("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
|
|
27097
|
+
subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx36(MadeWithOhhWells, {}),
|
|
25162
27098
|
bridgeRoot ? createPortal3(
|
|
25163
|
-
/* @__PURE__ */
|
|
25164
|
-
/* @__PURE__ */
|
|
25165
|
-
isEditMode && /* @__PURE__ */
|
|
27099
|
+
/* @__PURE__ */ jsxs23(Fragment10, { children: [
|
|
27100
|
+
/* @__PURE__ */ jsx36("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
27101
|
+
isEditMode && /* @__PURE__ */ jsx36(
|
|
25166
27102
|
AiSectionOverlay,
|
|
25167
27103
|
{
|
|
25168
27104
|
postToParent: postToParent2,
|
|
@@ -25170,7 +27106,7 @@ function OhhwellsBridge() {
|
|
|
25170
27106
|
onSelectionChange: handleAiSectionSelectionChange
|
|
25171
27107
|
}
|
|
25172
27108
|
),
|
|
25173
|
-
isEditMode && /* @__PURE__ */
|
|
27109
|
+
isEditMode && /* @__PURE__ */ jsx36(
|
|
25174
27110
|
AiMediaStripOverlay,
|
|
25175
27111
|
{
|
|
25176
27112
|
postToParent: postToParent2,
|
|
@@ -25179,7 +27115,7 @@ function OhhwellsBridge() {
|
|
|
25179
27115
|
clearInteractionChromeRef
|
|
25180
27116
|
}
|
|
25181
27117
|
),
|
|
25182
|
-
isEditMode && /* @__PURE__ */
|
|
27118
|
+
isEditMode && /* @__PURE__ */ jsx36(
|
|
25183
27119
|
AiPricingCardOverlay,
|
|
25184
27120
|
{
|
|
25185
27121
|
postToParent: postToParent2,
|
|
@@ -25187,12 +27123,12 @@ function OhhwellsBridge() {
|
|
|
25187
27123
|
applyTreeLocalRef
|
|
25188
27124
|
}
|
|
25189
27125
|
),
|
|
25190
|
-
isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */
|
|
27126
|
+
isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
|
|
25191
27127
|
"div",
|
|
25192
27128
|
{
|
|
25193
27129
|
className: "pointer-events-none fixed z-2147483646",
|
|
25194
27130
|
style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
|
|
25195
|
-
children: /* @__PURE__ */
|
|
27131
|
+
children: /* @__PURE__ */ jsx36(
|
|
25196
27132
|
DropIndicator,
|
|
25197
27133
|
{
|
|
25198
27134
|
direction: "horizontal",
|
|
@@ -25203,7 +27139,7 @@ function OhhwellsBridge() {
|
|
|
25203
27139
|
},
|
|
25204
27140
|
`section-drop-${slot.insertIndex}-${i}`
|
|
25205
27141
|
)),
|
|
25206
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
27142
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx36(
|
|
25207
27143
|
MediaOverlay,
|
|
25208
27144
|
{
|
|
25209
27145
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -25214,7 +27150,7 @@ function OhhwellsBridge() {
|
|
|
25214
27150
|
},
|
|
25215
27151
|
`uploading-${key}`
|
|
25216
27152
|
)),
|
|
25217
|
-
mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */
|
|
27153
|
+
mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ jsx36(
|
|
25218
27154
|
MediaOverlay,
|
|
25219
27155
|
{
|
|
25220
27156
|
hover: mediaHover,
|
|
@@ -25225,7 +27161,7 @@ function OhhwellsBridge() {
|
|
|
25225
27161
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
25226
27162
|
}
|
|
25227
27163
|
),
|
|
25228
|
-
selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */
|
|
27164
|
+
selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ jsx36(
|
|
25229
27165
|
MediaOverlay,
|
|
25230
27166
|
{
|
|
25231
27167
|
hover: selectedMedia,
|
|
@@ -25237,7 +27173,7 @@ function OhhwellsBridge() {
|
|
|
25237
27173
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
25238
27174
|
}
|
|
25239
27175
|
),
|
|
25240
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
27176
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx36(
|
|
25241
27177
|
CarouselOverlay,
|
|
25242
27178
|
{
|
|
25243
27179
|
hover: carouselHover,
|
|
@@ -25245,10 +27181,10 @@ function OhhwellsBridge() {
|
|
|
25245
27181
|
cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
|
|
25246
27182
|
}
|
|
25247
27183
|
),
|
|
25248
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
25249
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
25250
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
25251
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
27184
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
27185
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
27186
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
27187
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
|
|
25252
27188
|
"div",
|
|
25253
27189
|
{
|
|
25254
27190
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -25258,7 +27194,7 @@ function OhhwellsBridge() {
|
|
|
25258
27194
|
width: slot.width,
|
|
25259
27195
|
height: slot.height
|
|
25260
27196
|
},
|
|
25261
|
-
children: /* @__PURE__ */
|
|
27197
|
+
children: /* @__PURE__ */ jsx36(
|
|
25262
27198
|
DropIndicator,
|
|
25263
27199
|
{
|
|
25264
27200
|
direction: slot.direction,
|
|
@@ -25269,7 +27205,7 @@ function OhhwellsBridge() {
|
|
|
25269
27205
|
},
|
|
25270
27206
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
25271
27207
|
)),
|
|
25272
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
27208
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
|
|
25273
27209
|
"div",
|
|
25274
27210
|
{
|
|
25275
27211
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -25279,7 +27215,7 @@ function OhhwellsBridge() {
|
|
|
25279
27215
|
width: slot.width,
|
|
25280
27216
|
height: slot.height
|
|
25281
27217
|
},
|
|
25282
|
-
children: /* @__PURE__ */
|
|
27218
|
+
children: /* @__PURE__ */ jsx36(
|
|
25283
27219
|
DropIndicator,
|
|
25284
27220
|
{
|
|
25285
27221
|
direction: slot.direction,
|
|
@@ -25290,10 +27226,31 @@ function OhhwellsBridge() {
|
|
|
25290
27226
|
},
|
|
25291
27227
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
25292
27228
|
)),
|
|
25293
|
-
|
|
25294
|
-
|
|
25295
|
-
|
|
25296
|
-
|
|
27229
|
+
isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
|
|
27230
|
+
"div",
|
|
27231
|
+
{
|
|
27232
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
27233
|
+
style: {
|
|
27234
|
+
left: slot.left,
|
|
27235
|
+
top: slot.top,
|
|
27236
|
+
width: slot.width,
|
|
27237
|
+
height: slot.height
|
|
27238
|
+
},
|
|
27239
|
+
children: /* @__PURE__ */ jsx36(
|
|
27240
|
+
DropIndicator,
|
|
27241
|
+
{
|
|
27242
|
+
direction: slot.direction,
|
|
27243
|
+
state: activeButtonDropIndex === i ? "dragActive" : "dragIdle",
|
|
27244
|
+
className: "!h-full !w-full"
|
|
27245
|
+
}
|
|
27246
|
+
)
|
|
27247
|
+
},
|
|
27248
|
+
`button-drop-${slot.direction}-${slot.insertIndex}-${i}`
|
|
27249
|
+
)),
|
|
27250
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
27251
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
27252
|
+
hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
27253
|
+
formPickRect && !isItemDragging && /* @__PURE__ */ jsx36(
|
|
25297
27254
|
ItemInteractionLayer,
|
|
25298
27255
|
{
|
|
25299
27256
|
rect: formPickRect,
|
|
@@ -25301,13 +27258,13 @@ function OhhwellsBridge() {
|
|
|
25301
27258
|
itemDragSurface: false,
|
|
25302
27259
|
toolbarAlign: "left",
|
|
25303
27260
|
chromeGap: 24,
|
|
25304
|
-
toolbar: fieldPickRect ? void 0 : /* @__PURE__ */
|
|
27261
|
+
toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs23(
|
|
25305
27262
|
"div",
|
|
25306
27263
|
{
|
|
25307
27264
|
"data-ohw-form-toolbar": "",
|
|
25308
27265
|
className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
|
|
25309
27266
|
children: [
|
|
25310
|
-
/* @__PURE__ */
|
|
27267
|
+
/* @__PURE__ */ jsx36(
|
|
25311
27268
|
"button",
|
|
25312
27269
|
{
|
|
25313
27270
|
type: "button",
|
|
@@ -25315,11 +27272,11 @@ function OhhwellsBridge() {
|
|
|
25315
27272
|
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
|
|
25316
27273
|
onClick: () => setFieldTypePickerOpen((open) => !open),
|
|
25317
27274
|
"data-ohw-add-field": "",
|
|
25318
|
-
children: /* @__PURE__ */
|
|
27275
|
+
children: /* @__PURE__ */ jsx36(Plus4, { size: 15, "aria-hidden": true })
|
|
25319
27276
|
}
|
|
25320
27277
|
),
|
|
25321
|
-
/* @__PURE__ */
|
|
25322
|
-
/* @__PURE__ */
|
|
27278
|
+
/* @__PURE__ */ jsx36("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
27279
|
+
/* @__PURE__ */ jsxs23(
|
|
25323
27280
|
"button",
|
|
25324
27281
|
{
|
|
25325
27282
|
type: "button",
|
|
@@ -25335,11 +27292,11 @@ function OhhwellsBridge() {
|
|
|
25335
27292
|
});
|
|
25336
27293
|
},
|
|
25337
27294
|
children: [
|
|
25338
|
-
/* @__PURE__ */
|
|
27295
|
+
/* @__PURE__ */ jsx36(Settings, { size: 14, "aria-hidden": true }),
|
|
25339
27296
|
"Form settings",
|
|
25340
27297
|
formPickCount ? (
|
|
25341
27298
|
// Counter pill, per the design — not a text suffix.
|
|
25342
|
-
/* @__PURE__ */
|
|
27299
|
+
/* @__PURE__ */ jsx36(
|
|
25343
27300
|
"span",
|
|
25344
27301
|
{
|
|
25345
27302
|
"data-ohw-form-count": "",
|
|
@@ -25351,8 +27308,8 @@ function OhhwellsBridge() {
|
|
|
25351
27308
|
]
|
|
25352
27309
|
}
|
|
25353
27310
|
),
|
|
25354
|
-
/* @__PURE__ */
|
|
25355
|
-
/* @__PURE__ */
|
|
27311
|
+
/* @__PURE__ */ jsx36("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
27312
|
+
/* @__PURE__ */ jsx36("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx36(
|
|
25356
27313
|
"button",
|
|
25357
27314
|
{
|
|
25358
27315
|
type: "button",
|
|
@@ -25383,7 +27340,7 @@ function OhhwellsBridge() {
|
|
|
25383
27340
|
)
|
|
25384
27341
|
}
|
|
25385
27342
|
),
|
|
25386
|
-
formHoverRect && !isItemDragging && /* @__PURE__ */
|
|
27343
|
+
formHoverRect && !isItemDragging && /* @__PURE__ */ jsx36(
|
|
25387
27344
|
ItemInteractionLayer,
|
|
25388
27345
|
{
|
|
25389
27346
|
rect: formHoverRect,
|
|
@@ -25391,7 +27348,7 @@ function OhhwellsBridge() {
|
|
|
25391
27348
|
chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
|
|
25392
27349
|
}
|
|
25393
27350
|
),
|
|
25394
|
-
fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */
|
|
27351
|
+
fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx36(
|
|
25395
27352
|
ItemInteractionLayer,
|
|
25396
27353
|
{
|
|
25397
27354
|
rect: fieldPickRect,
|
|
@@ -25403,7 +27360,7 @@ function OhhwellsBridge() {
|
|
|
25403
27360
|
dragHandleLabel: "Reorder field",
|
|
25404
27361
|
onDragHandleDragStart: handleFieldDragStart,
|
|
25405
27362
|
onDragHandleDragEnd: handleFieldDragEnd,
|
|
25406
|
-
toolbar: /* @__PURE__ */
|
|
27363
|
+
toolbar: /* @__PURE__ */ jsx36(
|
|
25407
27364
|
FormFieldToolbar,
|
|
25408
27365
|
{
|
|
25409
27366
|
type: fieldPickState.type,
|
|
@@ -25416,12 +27373,12 @@ function OhhwellsBridge() {
|
|
|
25416
27373
|
)
|
|
25417
27374
|
}
|
|
25418
27375
|
),
|
|
25419
|
-
fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */
|
|
27376
|
+
fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
|
|
25420
27377
|
"div",
|
|
25421
27378
|
{
|
|
25422
27379
|
className: "pointer-events-none fixed z-[2147483644]",
|
|
25423
27380
|
style: { top: slot.top, left: slot.left, width: slot.width },
|
|
25424
|
-
children: /* @__PURE__ */
|
|
27381
|
+
children: /* @__PURE__ */ jsx36(
|
|
25425
27382
|
DropIndicator,
|
|
25426
27383
|
{
|
|
25427
27384
|
direction: "horizontal",
|
|
@@ -25434,7 +27391,7 @@ function OhhwellsBridge() {
|
|
|
25434
27391
|
)) : null,
|
|
25435
27392
|
fieldTypePickerOpen && formPickRect ? (() => {
|
|
25436
27393
|
const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
|
|
25437
|
-
return /* @__PURE__ */
|
|
27394
|
+
return /* @__PURE__ */ jsx36(
|
|
25438
27395
|
"div",
|
|
25439
27396
|
{
|
|
25440
27397
|
className: "pointer-events-none fixed z-[2147483645]",
|
|
@@ -25442,12 +27399,12 @@ function OhhwellsBridge() {
|
|
|
25442
27399
|
top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
|
|
25443
27400
|
left: toolbar ? toolbar.left : formPickRect.left + 24
|
|
25444
27401
|
},
|
|
25445
|
-
children: /* @__PURE__ */
|
|
27402
|
+
children: /* @__PURE__ */ jsx36(FieldTypePicker, { onPick: handleAddField })
|
|
25446
27403
|
}
|
|
25447
27404
|
);
|
|
25448
27405
|
})() : null,
|
|
25449
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */
|
|
25450
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */
|
|
27406
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx36(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
27407
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx36(
|
|
25451
27408
|
FooterContainerChrome,
|
|
25452
27409
|
{
|
|
25453
27410
|
rect: toolbarRect,
|
|
@@ -25455,13 +27412,17 @@ function OhhwellsBridge() {
|
|
|
25455
27412
|
addDisabled: !canAddFooterColumn()
|
|
25456
27413
|
}
|
|
25457
27414
|
),
|
|
25458
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */
|
|
27415
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx36(
|
|
25459
27416
|
ItemInteractionLayer,
|
|
25460
27417
|
{
|
|
25461
|
-
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
27418
|
+
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected || selectedElRef.current === buttonCollectionDragRef.current) ? draggedItemRect : toolbarRect,
|
|
25462
27419
|
toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
|
|
25463
27420
|
toolbarBelowEl: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanel(selectedElRef.current) : null,
|
|
25464
27421
|
elRef: glowElRef,
|
|
27422
|
+
hidden: isRectOutsideClip(
|
|
27423
|
+
isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected || selectedElRef.current === buttonCollectionDragRef.current) ? draggedItemRect : toolbarRect,
|
|
27424
|
+
getIframeVisibleClip(parentScrollRef.current)
|
|
27425
|
+
),
|
|
25465
27426
|
state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanel(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
25466
27427
|
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
|
|
25467
27428
|
dragDisabled: reorderDragDisabled,
|
|
@@ -25471,18 +27432,25 @@ function OhhwellsBridge() {
|
|
|
25471
27432
|
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
25472
27433
|
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
25473
27434
|
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
|
|
25474
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */
|
|
27435
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx36(
|
|
25475
27436
|
ItemActionToolbar,
|
|
25476
27437
|
{
|
|
25477
27438
|
onEditLink: openLinkPopoverForSelected,
|
|
25478
27439
|
onStyle: () => {
|
|
25479
27440
|
const row = selectedElRef.current;
|
|
25480
27441
|
if (!row) return;
|
|
25481
|
-
|
|
27442
|
+
suppressNextClickRef.current = true;
|
|
27443
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
27444
|
+
if (isCtaButton(row)) {
|
|
27445
|
+
if (floatingPanelRef.current?.kind === "button-style") closeFloatingPanelOnly();
|
|
27446
|
+
else openButtonStylePanel(row);
|
|
27447
|
+
return;
|
|
27448
|
+
}
|
|
27449
|
+
if (floatingPanelRef.current?.kind === "socials-display") closeFloatingPanelOnly();
|
|
25482
27450
|
else openSocialsDisplayPanel(row);
|
|
25483
27451
|
},
|
|
25484
|
-
showStyle: selectedIsSocialsRow,
|
|
25485
|
-
styleActive: floatingPanel?.kind === "socials-display",
|
|
27452
|
+
showStyle: selectedIsSocialsRow || selectedIsCta,
|
|
27453
|
+
styleActive: floatingPanel?.kind === "socials-display" || floatingPanel?.kind === "button-style",
|
|
25486
27454
|
onAddItem: handleAddChildItem,
|
|
25487
27455
|
onSelectParent: handleSelectParent,
|
|
25488
27456
|
onDuplicate: handleDuplicateSelected,
|
|
@@ -25493,11 +27461,11 @@ function OhhwellsBridge() {
|
|
|
25493
27461
|
})(),
|
|
25494
27462
|
editLinkDisabled: false,
|
|
25495
27463
|
moreDisabled: false,
|
|
25496
|
-
deleteDisabled: selectedElRef.current !== null && (() => {
|
|
27464
|
+
deleteDisabled: selectedElRef.current !== null && isCtaButton(selectedElRef.current) && !canDeleteButton(selectedElRef.current) || selectedElRef.current !== null && (() => {
|
|
25497
27465
|
const social = getSocialItem(selectedElRef.current);
|
|
25498
27466
|
return social ? !canRemoveSocialItem(social) : false;
|
|
25499
27467
|
})(),
|
|
25500
|
-
duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && (() => {
|
|
27468
|
+
duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && isCtaButton(selectedElRef.current) && !canDuplicateButton(selectedElRef.current) || selectedElRef.current !== null && (() => {
|
|
25501
27469
|
const social = getSocialItem(selectedElRef.current);
|
|
25502
27470
|
const row = social ? findSocialsRow(social) : null;
|
|
25503
27471
|
return row ? !canAddSocialItem(row) : false;
|
|
@@ -25506,7 +27474,7 @@ function OhhwellsBridge() {
|
|
|
25506
27474
|
showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
|
|
25507
27475
|
selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
|
|
25508
27476
|
),
|
|
25509
|
-
showMore:
|
|
27477
|
+
showMore: !selectedIsSocialsRow,
|
|
25510
27478
|
dropdownOpen: navDropdownPreviewOpen,
|
|
25511
27479
|
onDropdownOpenChange: handleNavDropdownOpenChange,
|
|
25512
27480
|
headingVisible: footerHeadingVisible,
|
|
@@ -25515,8 +27483,8 @@ function OhhwellsBridge() {
|
|
|
25515
27483
|
) : void 0
|
|
25516
27484
|
}
|
|
25517
27485
|
),
|
|
25518
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */
|
|
25519
|
-
/* @__PURE__ */
|
|
27486
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ jsxs23(Fragment10, { children: [
|
|
27487
|
+
/* @__PURE__ */ jsx36(
|
|
25520
27488
|
EditGlowChrome,
|
|
25521
27489
|
{
|
|
25522
27490
|
rect: toolbarRect,
|
|
@@ -25526,7 +27494,7 @@ function OhhwellsBridge() {
|
|
|
25526
27494
|
hideHandle: isItemDragging
|
|
25527
27495
|
}
|
|
25528
27496
|
),
|
|
25529
|
-
/* @__PURE__ */
|
|
27497
|
+
/* @__PURE__ */ jsx36(
|
|
25530
27498
|
FloatingToolbar,
|
|
25531
27499
|
{
|
|
25532
27500
|
rect: toolbarRect,
|
|
@@ -25539,7 +27507,7 @@ function OhhwellsBridge() {
|
|
|
25539
27507
|
}
|
|
25540
27508
|
)
|
|
25541
27509
|
] }),
|
|
25542
|
-
maxBadge && /* @__PURE__ */
|
|
27510
|
+
maxBadge && /* @__PURE__ */ jsxs23(
|
|
25543
27511
|
"div",
|
|
25544
27512
|
{
|
|
25545
27513
|
"data-ohw-max-badge": "",
|
|
@@ -25565,7 +27533,7 @@ function OhhwellsBridge() {
|
|
|
25565
27533
|
]
|
|
25566
27534
|
}
|
|
25567
27535
|
),
|
|
25568
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
27536
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx36(
|
|
25569
27537
|
StateToggle,
|
|
25570
27538
|
{
|
|
25571
27539
|
rect: toggleState.rect,
|
|
@@ -25574,15 +27542,15 @@ function OhhwellsBridge() {
|
|
|
25574
27542
|
onStateChange: handleStateChange
|
|
25575
27543
|
}
|
|
25576
27544
|
),
|
|
25577
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
27545
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs23(
|
|
25578
27546
|
"div",
|
|
25579
27547
|
{
|
|
25580
27548
|
"data-ohw-section-insert-line": "",
|
|
25581
27549
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
25582
27550
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
25583
27551
|
children: [
|
|
25584
|
-
/* @__PURE__ */
|
|
25585
|
-
/* @__PURE__ */
|
|
27552
|
+
/* @__PURE__ */ jsx36("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
|
|
27553
|
+
/* @__PURE__ */ jsx36(
|
|
25586
27554
|
Badge,
|
|
25587
27555
|
{
|
|
25588
27556
|
className: "px-8 py-1 bg-bridge-primary hover:bg-bridge-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
@@ -25599,11 +27567,11 @@ function OhhwellsBridge() {
|
|
|
25599
27567
|
children: "Add Section"
|
|
25600
27568
|
}
|
|
25601
27569
|
),
|
|
25602
|
-
/* @__PURE__ */
|
|
27570
|
+
/* @__PURE__ */ jsx36("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
|
|
25603
27571
|
]
|
|
25604
27572
|
}
|
|
25605
27573
|
),
|
|
25606
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
27574
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx36(
|
|
25607
27575
|
LinkPopover,
|
|
25608
27576
|
{
|
|
25609
27577
|
panelRef: linkPopoverPanelRef,
|
|
@@ -25620,7 +27588,7 @@ function OhhwellsBridge() {
|
|
|
25620
27588
|
},
|
|
25621
27589
|
linkPopover.key
|
|
25622
27590
|
) : null,
|
|
25623
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */
|
|
27591
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx36(
|
|
25624
27592
|
FloatingPanel,
|
|
25625
27593
|
{
|
|
25626
27594
|
open: true,
|
|
@@ -25630,7 +27598,7 @@ function OhhwellsBridge() {
|
|
|
25630
27598
|
onPositionChange: setFloatingPanelPos,
|
|
25631
27599
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
25632
27600
|
onClose: closeFloatingPanelOnly,
|
|
25633
|
-
children: /* @__PURE__ */
|
|
27601
|
+
children: /* @__PURE__ */ jsx36(
|
|
25634
27602
|
SocialsDisplayPanel,
|
|
25635
27603
|
{
|
|
25636
27604
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -25641,7 +27609,48 @@ function OhhwellsBridge() {
|
|
|
25641
27609
|
}
|
|
25642
27610
|
)
|
|
25643
27611
|
}
|
|
25644
|
-
) : null
|
|
27612
|
+
) : null,
|
|
27613
|
+
floatingPanel && floatingPanel.kind === "button-style" ? (() => {
|
|
27614
|
+
const button = document.querySelector(
|
|
27615
|
+
`[data-ohw-href-key="${CSS.escape(floatingPanel.buttonId)}"]`
|
|
27616
|
+
);
|
|
27617
|
+
if (!button) return null;
|
|
27618
|
+
captureButtonOrigin(button);
|
|
27619
|
+
const tokens = tokensFromButton(button);
|
|
27620
|
+
const current = assignmentFor(button, editContentRef.current, tokens);
|
|
27621
|
+
void buttonStyleTick;
|
|
27622
|
+
return /* @__PURE__ */ jsx36(
|
|
27623
|
+
FloatingPanel,
|
|
27624
|
+
{
|
|
27625
|
+
open: true,
|
|
27626
|
+
title: floatingPanel.title,
|
|
27627
|
+
context: floatingPanel.context,
|
|
27628
|
+
icon: /* @__PURE__ */ jsx36(Brush2, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
27629
|
+
position: floatingPanelPos,
|
|
27630
|
+
onPositionChange: setFloatingPanelPos,
|
|
27631
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
27632
|
+
onClose: closeFloatingPanelOnly,
|
|
27633
|
+
bodyClassName: "gap-5",
|
|
27634
|
+
children: /* @__PURE__ */ jsx36(
|
|
27635
|
+
ButtonStylePanel,
|
|
27636
|
+
{
|
|
27637
|
+
variants: tokens.variants,
|
|
27638
|
+
sizes: tokens.sizes,
|
|
27639
|
+
variant: current.variant,
|
|
27640
|
+
size: current.size,
|
|
27641
|
+
slotBackground: previewSlotBackground(button),
|
|
27642
|
+
previewLabel: (button.querySelector(
|
|
27643
|
+
'[data-ohw-editable="text"], [data-ohw-editable="plain"]'
|
|
27644
|
+
)?.textContent ?? button.textContent ?? "Book Now").trim() || "Book Now",
|
|
27645
|
+
onVariant: (variant) => applySelectedButtonStyle({ variant }),
|
|
27646
|
+
onSize: (size) => applySelectedButtonStyle({ size })
|
|
27647
|
+
},
|
|
27648
|
+
floatingPanel.key
|
|
27649
|
+
)
|
|
27650
|
+
},
|
|
27651
|
+
floatingPanel.key
|
|
27652
|
+
);
|
|
27653
|
+
})() : null
|
|
25645
27654
|
] }),
|
|
25646
27655
|
bridgeRoot
|
|
25647
27656
|
) : null
|