@ohhwells/bridge 0.1.92-next.269 → 0.1.92-next.274
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 +263 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +263 -87
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -15
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1400,7 +1400,12 @@ function ButtonEl({
|
|
|
1400
1400
|
textDecoration: "none",
|
|
1401
1401
|
cursor: "pointer",
|
|
1402
1402
|
...buttonShellStyle(ctx, fullWidth),
|
|
1403
|
-
...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } :
|
|
1403
|
+
...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } : (
|
|
1404
|
+
// Off-band, prefer the template button's measured fill/label pair — a template may
|
|
1405
|
+
// fill its CTAs with any token (hvac: accent bg, primary text). On an accent band
|
|
1406
|
+
// the flipped palette keeps contrast, so the brand-driven colours stay.
|
|
1407
|
+
!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : { background: ctx.brand.palette.primary, color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand) }
|
|
1408
|
+
)
|
|
1404
1409
|
},
|
|
1405
1410
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
|
|
1406
1411
|
}
|
|
@@ -2472,10 +2477,12 @@ function renderNode(node, ctx, path) {
|
|
|
2472
2477
|
cursor: "pointer",
|
|
2473
2478
|
// Shape/padding/typography follow the host template's own buttons.
|
|
2474
2479
|
...buttonShellStyle(ctx),
|
|
2475
|
-
// Brand-styled:
|
|
2476
|
-
// reads
|
|
2477
|
-
background: ctx.
|
|
2478
|
-
|
|
2480
|
+
// Brand-styled: the template button's measured fill/label pair off-band, else
|
|
2481
|
+
// primary fill with a brand-derived label so it reads on custom palettes.
|
|
2482
|
+
...!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : {
|
|
2483
|
+
background: ctx.brand.palette.primary,
|
|
2484
|
+
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
2485
|
+
}
|
|
2479
2486
|
},
|
|
2480
2487
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...textAttrs(ctx, `${path}.c${i}.label`), children: str(cs.label) })
|
|
2481
2488
|
},
|
|
@@ -2684,11 +2691,19 @@ function deriveTemplateBrand() {
|
|
|
2684
2691
|
}
|
|
2685
2692
|
function deriveTemplateButtonStyle() {
|
|
2686
2693
|
if (typeof document === "undefined") return null;
|
|
2687
|
-
const
|
|
2688
|
-
|
|
2689
|
-
);
|
|
2694
|
+
const candidates = Array.from(
|
|
2695
|
+
document.querySelectorAll('[data-ohw-role="button"]')
|
|
2696
|
+
).filter((el) => !el.closest(`[${CONTAINER_ATTR}]`));
|
|
2697
|
+
const isFilled = (el) => {
|
|
2698
|
+
const bg = getComputedStyle(el).backgroundColor;
|
|
2699
|
+
if (!bg || bg === "transparent") return false;
|
|
2700
|
+
const alpha = bg.match(/rgba?\([^)]*,\s*([\d.]+)\)$/);
|
|
2701
|
+
return !alpha || parseFloat(alpha[1]) > 0;
|
|
2702
|
+
};
|
|
2703
|
+
const btn = candidates.find(isFilled) ?? candidates[0];
|
|
2690
2704
|
if (!btn) return null;
|
|
2691
2705
|
const cs = getComputedStyle(btn);
|
|
2706
|
+
const filled = isFilled(btn);
|
|
2692
2707
|
const corners = [
|
|
2693
2708
|
cs.borderTopLeftRadius,
|
|
2694
2709
|
cs.borderTopRightRadius,
|
|
@@ -2705,6 +2720,7 @@ function deriveTemplateButtonStyle() {
|
|
|
2705
2720
|
return {
|
|
2706
2721
|
radius: radius || "10px",
|
|
2707
2722
|
padding: `${padY}px ${padX}px`,
|
|
2723
|
+
...filled ? { background: cs.backgroundColor, color: cs.color } : {},
|
|
2708
2724
|
fontFamily: cs.fontFamily || "",
|
|
2709
2725
|
fontSize: cs.fontSize || "",
|
|
2710
2726
|
fontWeight: cs.fontWeight || "",
|
|
@@ -7506,9 +7522,7 @@ function ItemActionToolbar({
|
|
|
7506
7522
|
ToggleGroup,
|
|
7507
7523
|
{
|
|
7508
7524
|
value: dropdownOpen ? "open" : "closed",
|
|
7509
|
-
onValueChange: (
|
|
7510
|
-
if (value !== "open" && value !== "closed") return;
|
|
7511
|
-
onDropdownOpenChange?.(value === "open");
|
|
7525
|
+
onValueChange: () => {
|
|
7512
7526
|
},
|
|
7513
7527
|
className: "h-7 gap-0.5 rounded-[calc(var(--radius,0.5rem)-2px)] bg-muted p-0.5",
|
|
7514
7528
|
onMouseDown: (e) => {
|
|
@@ -7523,6 +7537,11 @@ function ItemActionToolbar({
|
|
|
7523
7537
|
size: "sm",
|
|
7524
7538
|
"aria-label": "Closed",
|
|
7525
7539
|
className: "h-6 min-w-0 px-2 text-xs font-medium",
|
|
7540
|
+
onMouseDown: (e) => {
|
|
7541
|
+
e.preventDefault();
|
|
7542
|
+
e.stopPropagation();
|
|
7543
|
+
if (dropdownOpen !== false) onDropdownOpenChange?.(false);
|
|
7544
|
+
},
|
|
7526
7545
|
children: "Closed"
|
|
7527
7546
|
}
|
|
7528
7547
|
),
|
|
@@ -7533,6 +7552,11 @@ function ItemActionToolbar({
|
|
|
7533
7552
|
size: "sm",
|
|
7534
7553
|
"aria-label": "Open",
|
|
7535
7554
|
className: "h-6 min-w-0 px-2 text-xs font-medium",
|
|
7555
|
+
onMouseDown: (e) => {
|
|
7556
|
+
e.preventDefault();
|
|
7557
|
+
e.stopPropagation();
|
|
7558
|
+
if (dropdownOpen !== true) onDropdownOpenChange?.(true);
|
|
7559
|
+
},
|
|
7536
7560
|
children: "Open"
|
|
7537
7561
|
}
|
|
7538
7562
|
)
|
|
@@ -8558,7 +8582,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8558
8582
|
"div",
|
|
8559
8583
|
{
|
|
8560
8584
|
"data-ohw-field-type-picker": "",
|
|
8561
|
-
className: "pointer-events-auto grid w-[
|
|
8585
|
+
className: "pointer-events-auto grid w-[280px] grid-cols-2 gap-2 rounded-xl border border-border bg-background p-3 shadow-lg",
|
|
8562
8586
|
children: FIELD_TYPES.map((entry) => {
|
|
8563
8587
|
const Icon = TYPE_ICONS[entry.type];
|
|
8564
8588
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
@@ -8566,7 +8590,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8566
8590
|
{
|
|
8567
8591
|
type: "button",
|
|
8568
8592
|
onClick: () => onPick(entry.type),
|
|
8569
|
-
className: "flex h-[
|
|
8593
|
+
className: "flex h-[76px] flex-col items-center justify-center gap-2 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-primary hover:bg-primary/5",
|
|
8570
8594
|
children: [
|
|
8571
8595
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8572
8596
|
entry.label
|
|
@@ -10920,6 +10944,32 @@ function getNavbarDesktopContainer() {
|
|
|
10920
10944
|
function getNavbarDrawerContainer() {
|
|
10921
10945
|
return document.querySelector("[data-ohw-nav-drawer]");
|
|
10922
10946
|
}
|
|
10947
|
+
function isNavbarListContainerVisible(el) {
|
|
10948
|
+
if (el.hasAttribute("hidden")) return false;
|
|
10949
|
+
if (el.getClientRects().length === 0) return false;
|
|
10950
|
+
const style = window.getComputedStyle(el);
|
|
10951
|
+
return style.display !== "none" && style.visibility !== "hidden";
|
|
10952
|
+
}
|
|
10953
|
+
function getActiveNavbarListContainer(draggedEl) {
|
|
10954
|
+
const desktop = getNavbarDesktopContainer();
|
|
10955
|
+
const drawer = getNavbarDrawerContainer();
|
|
10956
|
+
if (draggedEl) {
|
|
10957
|
+
if (drawer?.contains(draggedEl)) return drawer;
|
|
10958
|
+
if (desktop?.contains(draggedEl)) return desktop;
|
|
10959
|
+
}
|
|
10960
|
+
if (desktop && isNavbarListContainerVisible(desktop)) return desktop;
|
|
10961
|
+
if (drawer && isNavbarListContainerVisible(drawer)) return drawer;
|
|
10962
|
+
return desktop ?? drawer;
|
|
10963
|
+
}
|
|
10964
|
+
function listActiveNavbarItems(draggedEl) {
|
|
10965
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
10966
|
+
if (container) {
|
|
10967
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
10968
|
+
isNavbarLinkItem
|
|
10969
|
+
);
|
|
10970
|
+
}
|
|
10971
|
+
return listNavbarItems();
|
|
10972
|
+
}
|
|
10923
10973
|
function listNavbarItems() {
|
|
10924
10974
|
const desktop = getNavbarDesktopContainer();
|
|
10925
10975
|
if (desktop) {
|
|
@@ -12032,20 +12082,23 @@ function isEmptyLabelValue(value) {
|
|
|
12032
12082
|
function applyStoredValues(item, content) {
|
|
12033
12083
|
const hrefKey = socialHrefKey(item);
|
|
12034
12084
|
const iconKey = socialIconKey(item);
|
|
12085
|
+
const baseKey = hrefKey?.replace(/-href$/, "");
|
|
12035
12086
|
if (hrefKey && content[hrefKey] !== void 0) item.setAttribute("href", content[hrefKey]);
|
|
12036
|
-
|
|
12087
|
+
const glyphKey = iconKey ?? baseKey ?? null;
|
|
12088
|
+
const glyphStored = glyphKey ? content[glyphKey]?.trim() : void 0;
|
|
12089
|
+
if (glyphStored) {
|
|
12090
|
+
ensureIconSlot(item);
|
|
12037
12091
|
const glyph = item.querySelector(ICON_SELECTOR);
|
|
12038
|
-
if (glyph
|
|
12039
|
-
applyIconMarkup(glyph,
|
|
12092
|
+
if (glyph) {
|
|
12093
|
+
applyIconMarkup(glyph, glyphStored);
|
|
12040
12094
|
glyph.removeAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
12041
12095
|
}
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
|
|
12047
|
-
|
|
12048
|
-
}
|
|
12096
|
+
}
|
|
12097
|
+
const label = socialLabelElement(item);
|
|
12098
|
+
const labelKey = label?.getAttribute("data-ohw-key");
|
|
12099
|
+
if (label && labelKey && content[labelKey] !== void 0) {
|
|
12100
|
+
const words = isEmptyLabelValue(content[labelKey]) ? "" : content[labelKey];
|
|
12101
|
+
if (label.innerHTML !== words) label.innerHTML = words;
|
|
12049
12102
|
}
|
|
12050
12103
|
}
|
|
12051
12104
|
function socialPlatformKey(iconKey) {
|
|
@@ -12134,6 +12187,9 @@ function insertSocialItem(row, after, content = {}, { placeholder = true, keys }
|
|
|
12134
12187
|
if (placeholder) {
|
|
12135
12188
|
const label = socialLabelElement(item);
|
|
12136
12189
|
if (label) label.textContent = PLACEHOLDER_SOCIAL_LABEL;
|
|
12190
|
+
} else if (keys) {
|
|
12191
|
+
const label = socialLabelElement(item);
|
|
12192
|
+
if (label) label.textContent = "";
|
|
12137
12193
|
}
|
|
12138
12194
|
applySocialsDisplayToRow(row, display);
|
|
12139
12195
|
return { item, hrefKey, iconKey, order: getSocialsOrderFromDom(row.ownerDocument) };
|
|
@@ -13991,8 +14047,8 @@ var lockFooterDuringDrag = lockItemDuringDrag;
|
|
|
13991
14047
|
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
13992
14048
|
|
|
13993
14049
|
// src/lib/nav-dnd.ts
|
|
13994
|
-
function listReorderableNavItems() {
|
|
13995
|
-
return
|
|
14050
|
+
function listReorderableNavItems(draggedEl) {
|
|
14051
|
+
return listActiveNavbarItems(draggedEl).filter((el) => {
|
|
13996
14052
|
const key = el.getAttribute("data-ohw-href-key");
|
|
13997
14053
|
return isNavbarHrefKey(key) && !isNestedNavChild(el);
|
|
13998
14054
|
});
|
|
@@ -14007,8 +14063,8 @@ function resolveParentNavHrefKey(child) {
|
|
|
14007
14063
|
const key = trigger?.getAttribute("data-ohw-href-key");
|
|
14008
14064
|
return key && isNavbarHrefKey(key) ? key : null;
|
|
14009
14065
|
}
|
|
14010
|
-
function listNavChildren(parentHrefKey) {
|
|
14011
|
-
const items =
|
|
14066
|
+
function listNavChildren(parentHrefKey, draggedEl) {
|
|
14067
|
+
const items = listActiveNavbarItems(draggedEl);
|
|
14012
14068
|
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
14013
14069
|
if (!parent) return [];
|
|
14014
14070
|
const group = parent.closest("[data-ohw-nav-group]");
|
|
@@ -14018,20 +14074,83 @@ function listNavChildren(parentHrefKey) {
|
|
|
14018
14074
|
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
14019
14075
|
);
|
|
14020
14076
|
}
|
|
14021
|
-
function
|
|
14022
|
-
const
|
|
14023
|
-
if (
|
|
14024
|
-
const
|
|
14025
|
-
|
|
14077
|
+
function isVerticalNavLayout(items, draggedEl) {
|
|
14078
|
+
const visible = items.filter((el) => el.getClientRects().length > 0);
|
|
14079
|
+
if (visible.length >= 2) {
|
|
14080
|
+
const a = visible[0].getBoundingClientRect();
|
|
14081
|
+
const b = visible[1].getBoundingClientRect();
|
|
14082
|
+
const verticalGap = b.top - a.bottom;
|
|
14083
|
+
const horizontalGap = b.left - a.right;
|
|
14084
|
+
return verticalGap > horizontalGap;
|
|
14085
|
+
}
|
|
14086
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
14087
|
+
if (!container) return false;
|
|
14088
|
+
const style = window.getComputedStyle(container);
|
|
14089
|
+
return style.flexDirection === "column" || style.flexDirection === "column-reverse";
|
|
14090
|
+
}
|
|
14091
|
+
function buildVerticalRootNavDropSlots(items, draggedEl) {
|
|
14092
|
+
const slots = [];
|
|
14093
|
+
const barThickness = 3;
|
|
14094
|
+
if (items.length === 0) {
|
|
14095
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
14096
|
+
if (!container) return slots;
|
|
14097
|
+
const rect = container.getBoundingClientRect();
|
|
14098
|
+
slots.push({
|
|
14099
|
+
insertIndex: 0,
|
|
14100
|
+
parentId: null,
|
|
14101
|
+
left: rect.left,
|
|
14102
|
+
top: rect.top + rect.height / 2 - barThickness / 2,
|
|
14103
|
+
width: Math.max(rect.width, 40),
|
|
14104
|
+
height: barThickness,
|
|
14105
|
+
direction: "horizontal"
|
|
14106
|
+
});
|
|
14107
|
+
return slots;
|
|
14108
|
+
}
|
|
14109
|
+
const edgeGap = (() => {
|
|
14110
|
+
if (items.length < 2) return 16;
|
|
14111
|
+
const a = items[0].getBoundingClientRect();
|
|
14112
|
+
const b = items[1].getBoundingClientRect();
|
|
14113
|
+
return Math.max(0, b.top - a.bottom);
|
|
14114
|
+
})();
|
|
14115
|
+
for (let i = 0; i <= items.length; i++) {
|
|
14116
|
+
let top;
|
|
14117
|
+
let width;
|
|
14118
|
+
let left;
|
|
14119
|
+
if (i === 0) {
|
|
14120
|
+
const first = items[0].getBoundingClientRect();
|
|
14121
|
+
top = first.top - edgeGap / 2 - barThickness / 2;
|
|
14122
|
+
left = first.left;
|
|
14123
|
+
width = first.width;
|
|
14124
|
+
} else if (i === items.length) {
|
|
14125
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
14126
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.top - items[items.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
14127
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
14128
|
+
left = last.left;
|
|
14129
|
+
width = last.width;
|
|
14130
|
+
} else {
|
|
14131
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
14132
|
+
const next = items[i].getBoundingClientRect();
|
|
14133
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
14134
|
+
left = Math.min(prev.left, next.left);
|
|
14135
|
+
width = Math.max(prev.right, next.right) - left;
|
|
14136
|
+
}
|
|
14137
|
+
slots.push({
|
|
14138
|
+
insertIndex: i,
|
|
14139
|
+
parentId: null,
|
|
14140
|
+
left,
|
|
14141
|
+
top,
|
|
14142
|
+
width: Math.max(width, 40),
|
|
14143
|
+
height: barThickness,
|
|
14144
|
+
direction: "horizontal"
|
|
14145
|
+
});
|
|
14026
14146
|
}
|
|
14027
|
-
return
|
|
14147
|
+
return slots;
|
|
14028
14148
|
}
|
|
14029
|
-
function
|
|
14030
|
-
const items = listReorderableNavItems();
|
|
14149
|
+
function buildHorizontalRootNavDropSlots(items, draggedEl) {
|
|
14031
14150
|
const slots = [];
|
|
14032
14151
|
const barThickness = 3;
|
|
14033
14152
|
if (items.length === 0) {
|
|
14034
|
-
const container =
|
|
14153
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
14035
14154
|
if (!container) return slots;
|
|
14036
14155
|
const rect = container.getBoundingClientRect();
|
|
14037
14156
|
slots.push({
|
|
@@ -14062,10 +14181,7 @@ function buildRootNavDropSlots() {
|
|
|
14062
14181
|
height = first.height;
|
|
14063
14182
|
} else if (i === items.length) {
|
|
14064
14183
|
const last = items[items.length - 1].getBoundingClientRect();
|
|
14065
|
-
const lastGap = items.length >= 2 ? Math.max(
|
|
14066
|
-
0,
|
|
14067
|
-
last.left - items[items.length - 2].getBoundingClientRect().right
|
|
14068
|
-
) : edgeGap;
|
|
14184
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.left - items[items.length - 2].getBoundingClientRect().right) : edgeGap;
|
|
14069
14185
|
left = last.right + lastGap / 2 - barThickness / 2;
|
|
14070
14186
|
top = last.top;
|
|
14071
14187
|
height = last.height;
|
|
@@ -14088,8 +14204,15 @@ function buildRootNavDropSlots() {
|
|
|
14088
14204
|
}
|
|
14089
14205
|
return slots;
|
|
14090
14206
|
}
|
|
14091
|
-
function
|
|
14092
|
-
const
|
|
14207
|
+
function buildRootNavDropSlots(draggedEl) {
|
|
14208
|
+
const items = listReorderableNavItems(draggedEl);
|
|
14209
|
+
if (isVerticalNavLayout(items, draggedEl)) {
|
|
14210
|
+
return buildVerticalRootNavDropSlots(items, draggedEl);
|
|
14211
|
+
}
|
|
14212
|
+
return buildHorizontalRootNavDropSlots(items, draggedEl);
|
|
14213
|
+
}
|
|
14214
|
+
function buildChildNavDropSlots(parentHrefKey, draggedEl) {
|
|
14215
|
+
const children = listNavChildren(parentHrefKey, draggedEl);
|
|
14093
14216
|
const slots = [];
|
|
14094
14217
|
const barThickness = 3;
|
|
14095
14218
|
if (children.length === 0) return slots;
|
|
@@ -14110,10 +14233,7 @@ function buildChildNavDropSlots(parentHrefKey) {
|
|
|
14110
14233
|
width = first.width;
|
|
14111
14234
|
} else if (i === children.length) {
|
|
14112
14235
|
const last = children[children.length - 1].getBoundingClientRect();
|
|
14113
|
-
const lastGap = children.length >= 2 ? Math.max(
|
|
14114
|
-
0,
|
|
14115
|
-
last.top - children[children.length - 2].getBoundingClientRect().bottom
|
|
14116
|
-
) : edgeGap;
|
|
14236
|
+
const lastGap = children.length >= 2 ? Math.max(0, last.top - children[children.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
14117
14237
|
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
14118
14238
|
left = last.left;
|
|
14119
14239
|
width = last.width;
|
|
@@ -14136,18 +14256,19 @@ function buildChildNavDropSlots(parentHrefKey) {
|
|
|
14136
14256
|
}
|
|
14137
14257
|
return slots;
|
|
14138
14258
|
}
|
|
14139
|
-
function buildAllNavDropSlots(draggedHrefKey) {
|
|
14140
|
-
const
|
|
14141
|
-
|
|
14259
|
+
function buildAllNavDropSlots(draggedHrefKey, draggedEl) {
|
|
14260
|
+
const activeItems = listActiveNavbarItems(draggedEl);
|
|
14261
|
+
const dragged = (draggedEl && activeItems.includes(draggedEl) ? draggedEl : null) ?? activeItems.find((el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey) ?? listNavbarItems().find((el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey);
|
|
14262
|
+
if (!dragged) return buildRootNavDropSlots(draggedEl);
|
|
14142
14263
|
if (isNestedNavChild(dragged)) {
|
|
14143
14264
|
const parentKey = resolveParentNavHrefKey(dragged);
|
|
14144
14265
|
if (!parentKey) return [];
|
|
14145
|
-
return buildChildNavDropSlots(parentKey);
|
|
14266
|
+
return buildChildNavDropSlots(parentKey, draggedEl);
|
|
14146
14267
|
}
|
|
14147
|
-
return buildRootNavDropSlots();
|
|
14268
|
+
return buildRootNavDropSlots(draggedEl);
|
|
14148
14269
|
}
|
|
14149
|
-
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
14150
|
-
const slots = buildAllNavDropSlots(draggedHrefKey);
|
|
14270
|
+
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
|
|
14271
|
+
const slots = buildAllNavDropSlots(draggedHrefKey, draggedEl);
|
|
14151
14272
|
let best = null;
|
|
14152
14273
|
for (const slot of slots) {
|
|
14153
14274
|
const cx2 = slot.left + slot.width / 2;
|
|
@@ -14198,6 +14319,12 @@ function useNavItemDrag({
|
|
|
14198
14319
|
setIsItemDragging(false);
|
|
14199
14320
|
if (keepOpenEl?.isConnected) {
|
|
14200
14321
|
setNavGroupForceOpen(keepOpenEl, true);
|
|
14322
|
+
requestAnimationFrame(() => {
|
|
14323
|
+
if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
|
|
14324
|
+
requestAnimationFrame(() => {
|
|
14325
|
+
if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
|
|
14326
|
+
});
|
|
14327
|
+
});
|
|
14201
14328
|
} else {
|
|
14202
14329
|
setNavGroupForceOpen(null, false);
|
|
14203
14330
|
}
|
|
@@ -14213,7 +14340,7 @@ function useNavItemDrag({
|
|
|
14213
14340
|
}
|
|
14214
14341
|
session.activeSlot = activeSlot;
|
|
14215
14342
|
setSiblingHintRects([]);
|
|
14216
|
-
const slots = buildAllNavDropSlots(session.hrefKey);
|
|
14343
|
+
const slots = buildAllNavDropSlots(session.hrefKey, session.draggedEl);
|
|
14217
14344
|
setNavDropSlots(slots);
|
|
14218
14345
|
const activeIdx = activeSlot ? slots.findIndex(
|
|
14219
14346
|
(s) => s.parentId === activeSlot.parentId && s.insertIndex === activeSlot.insertIndex
|
|
@@ -14249,7 +14376,12 @@ function useNavItemDrag({
|
|
|
14249
14376
|
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
14250
14377
|
setToolbarRect(rect);
|
|
14251
14378
|
}
|
|
14252
|
-
const initialSlot = hitTestNavDropSlot(
|
|
14379
|
+
const initialSlot = hitTestNavDropSlot(
|
|
14380
|
+
session.lastClientX,
|
|
14381
|
+
session.lastClientY,
|
|
14382
|
+
session.hrefKey,
|
|
14383
|
+
session.draggedEl
|
|
14384
|
+
);
|
|
14253
14385
|
refreshNavDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
14254
14386
|
},
|
|
14255
14387
|
[
|
|
@@ -14271,10 +14403,11 @@ function useNavItemDrag({
|
|
|
14271
14403
|
}
|
|
14272
14404
|
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
14273
14405
|
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
14274
|
-
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey);
|
|
14406
|
+
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey, session.draggedEl);
|
|
14275
14407
|
const planned = slot != null ? planNavItemMove(session.hrefKey, slot.parentId, slot.insertIndex) : null;
|
|
14276
14408
|
const wasSelected = session.wasSelected;
|
|
14277
14409
|
const hrefKey = session.hrefKey;
|
|
14410
|
+
const keepDropdownOpen = Boolean(session.draggedEl.closest("[data-ohw-nav-children]"));
|
|
14278
14411
|
const applySelectionAfterDrop = () => {
|
|
14279
14412
|
if (!wasSelected) {
|
|
14280
14413
|
deselectRef.current();
|
|
@@ -14308,6 +14441,14 @@ function useNavItemDrag({
|
|
|
14308
14441
|
});
|
|
14309
14442
|
applySelectionAfterDrop();
|
|
14310
14443
|
clearNavDragVisuals();
|
|
14444
|
+
if (keepDropdownOpen) {
|
|
14445
|
+
requestAnimationFrame(() => {
|
|
14446
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
14447
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
14448
|
+
const link = desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
14449
|
+
if (link) setNavGroupForceOpen(link, true);
|
|
14450
|
+
});
|
|
14451
|
+
}
|
|
14311
14452
|
requestAnimationFrame(() => {
|
|
14312
14453
|
if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
|
|
14313
14454
|
applyNavForest(planned.forest);
|
|
@@ -14347,7 +14488,7 @@ function useNavItemDrag({
|
|
|
14347
14488
|
if (!session) return false;
|
|
14348
14489
|
e.preventDefault();
|
|
14349
14490
|
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
14350
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
14491
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey, session.draggedEl);
|
|
14351
14492
|
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
14352
14493
|
return true;
|
|
14353
14494
|
},
|
|
@@ -14393,7 +14534,7 @@ function useNavItemDrag({
|
|
|
14393
14534
|
clearTextSelection();
|
|
14394
14535
|
const session = navDragRef.current;
|
|
14395
14536
|
if (!session) return;
|
|
14396
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
14537
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey, session.draggedEl);
|
|
14397
14538
|
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
14398
14539
|
return;
|
|
14399
14540
|
}
|
|
@@ -14409,7 +14550,8 @@ function useNavItemDrag({
|
|
|
14409
14550
|
} catch {
|
|
14410
14551
|
}
|
|
14411
14552
|
if (linkPopoverOpenRef.current) setLinkPopover(null);
|
|
14412
|
-
|
|
14553
|
+
const isNestedDrag = Boolean(pending.el.closest("[data-ohw-nav-children]"));
|
|
14554
|
+
if (activeElRef.current && !isNestedDrag) deactivateRef.current();
|
|
14413
14555
|
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
14414
14556
|
if (!key) return;
|
|
14415
14557
|
beginNavDragRef.current({
|
|
@@ -14420,6 +14562,9 @@ function useNavItemDrag({
|
|
|
14420
14562
|
lastClientY: e.clientY,
|
|
14421
14563
|
activeSlot: null
|
|
14422
14564
|
});
|
|
14565
|
+
if (activeElRef.current && isNestedDrag) {
|
|
14566
|
+
deactivateRef.current();
|
|
14567
|
+
}
|
|
14423
14568
|
};
|
|
14424
14569
|
const endPointerDrag = (e) => {
|
|
14425
14570
|
const pending = navPointerDragRef.current;
|
|
@@ -14497,6 +14642,7 @@ function useNavItemDrag({
|
|
|
14497
14642
|
);
|
|
14498
14643
|
return {
|
|
14499
14644
|
navDragRef,
|
|
14645
|
+
navPointerDragRef,
|
|
14500
14646
|
navDropSlots,
|
|
14501
14647
|
activeNavDropIndex,
|
|
14502
14648
|
startNavLinkDrag,
|
|
@@ -15893,6 +16039,7 @@ function isNavDropdownPanelOpen(childrenRoot) {
|
|
|
15893
16039
|
if (childrenRoot.closest("[data-ohw-nav-drawer]")) return true;
|
|
15894
16040
|
const group = childrenRoot.closest("[data-ohw-nav-group]");
|
|
15895
16041
|
if (group?.hasAttribute("data-ohw-nav-force-open")) return true;
|
|
16042
|
+
if (navDropdownsOpenOnClick()) return false;
|
|
15896
16043
|
if (childrenRoot.clientHeight < 2 || childrenRoot.clientWidth < 2) return false;
|
|
15897
16044
|
const style = window.getComputedStyle(childrenRoot);
|
|
15898
16045
|
if (style.display === "none" || style.visibility === "hidden") return false;
|
|
@@ -15936,6 +16083,11 @@ function getNavigationItemAnchor(el) {
|
|
|
15936
16083
|
function isNavigationItem2(el) {
|
|
15937
16084
|
return getNavigationItemAnchor(el) !== null;
|
|
15938
16085
|
}
|
|
16086
|
+
function isNavFooterScopedNavigationItem(el) {
|
|
16087
|
+
return Boolean(
|
|
16088
|
+
el.closest("nav, footer, [data-ohw-nav-container], [data-ohw-nav-drawer]")
|
|
16089
|
+
);
|
|
16090
|
+
}
|
|
15939
16091
|
function socialWordsClicked(target, item) {
|
|
15940
16092
|
const text = target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
15941
16093
|
return Boolean(text && item.contains(text));
|
|
@@ -16146,6 +16298,7 @@ function getNavigationSelectionParent(el) {
|
|
|
16146
16298
|
}
|
|
16147
16299
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
16148
16300
|
if (!isNavigationItem2(selected)) return [];
|
|
16301
|
+
if (!isNavFooterScopedNavigationItem(selected)) return [];
|
|
16149
16302
|
const socialsRow = findSocialsRow(selected);
|
|
16150
16303
|
if (socialsRow) {
|
|
16151
16304
|
return listSocialItems(socialsRow).filter((item) => item !== selected).map((item) => item.getBoundingClientRect());
|
|
@@ -17309,6 +17462,7 @@ function OhhwellsBridge() {
|
|
|
17309
17462
|
}, []);
|
|
17310
17463
|
const {
|
|
17311
17464
|
navDragRef,
|
|
17465
|
+
navPointerDragRef,
|
|
17312
17466
|
navDropSlots,
|
|
17313
17467
|
activeNavDropIndex,
|
|
17314
17468
|
startNavLinkDrag,
|
|
@@ -17511,7 +17665,12 @@ function OhhwellsBridge() {
|
|
|
17511
17665
|
if (owner) persistFieldsRef.current(owner);
|
|
17512
17666
|
}
|
|
17513
17667
|
activeElRef.current = null;
|
|
17514
|
-
|
|
17668
|
+
const preserveNavDropdown = Boolean(navPointerDragRef.current?.el?.closest("[data-ohw-nav-children]")) || Boolean(navDragRef.current?.draggedEl?.closest("[data-ohw-nav-children]")) || Boolean(
|
|
17669
|
+
selectedElRef.current?.closest("[data-ohw-nav-children]") && selectedElRef.current?.closest("[data-ohw-nav-group]")?.hasAttribute("data-ohw-nav-force-open")
|
|
17670
|
+
);
|
|
17671
|
+
if (!preserveNavDropdown) {
|
|
17672
|
+
setNavGroupForceOpen(null, false);
|
|
17673
|
+
}
|
|
17515
17674
|
setReorderHrefKey(null);
|
|
17516
17675
|
setReorderDragDisabled(false);
|
|
17517
17676
|
if (!selectedElRef.current) {
|
|
@@ -17633,7 +17792,10 @@ function OhhwellsBridge() {
|
|
|
17633
17792
|
setSelectedIsSocialsRow(false);
|
|
17634
17793
|
const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
|
|
17635
17794
|
if (isNestedNavChild(navAnchor)) {
|
|
17636
|
-
|
|
17795
|
+
const group = navAnchor.closest("[data-ohw-nav-group]");
|
|
17796
|
+
if (group?.hasAttribute("data-ohw-nav-force-open")) {
|
|
17797
|
+
setNavGroupForceOpen(navAnchor, true);
|
|
17798
|
+
}
|
|
17637
17799
|
setNavDropdownPreviewOpen(null);
|
|
17638
17800
|
} else if (isDropdownTrigger) {
|
|
17639
17801
|
const group = navAnchor.closest("[data-ohw-nav-group]");
|
|
@@ -17715,6 +17877,10 @@ function OhhwellsBridge() {
|
|
|
17715
17877
|
const handleNavDropdownOpenChange = (0, import_react17.useCallback)((open) => {
|
|
17716
17878
|
const selected = selectedElRef.current;
|
|
17717
17879
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
17880
|
+
if (isNestedNavChild(selected)) return;
|
|
17881
|
+
const group = selected.closest("[data-ohw-nav-group]");
|
|
17882
|
+
const domOpen = Boolean(group?.hasAttribute("data-ohw-nav-force-open"));
|
|
17883
|
+
if (open === domOpen) return;
|
|
17718
17884
|
setNavGroupForceOpen(selected, open);
|
|
17719
17885
|
setNavDropdownPreviewOpen(open);
|
|
17720
17886
|
requestAnimationFrame(() => {
|
|
@@ -18244,7 +18410,10 @@ function OhhwellsBridge() {
|
|
|
18244
18410
|
clearHrefKeyHover(anchor);
|
|
18245
18411
|
const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
|
|
18246
18412
|
if (isNestedNavChild(anchor)) {
|
|
18247
|
-
|
|
18413
|
+
const group = anchor.closest("[data-ohw-nav-group]");
|
|
18414
|
+
if (group?.hasAttribute("data-ohw-nav-force-open")) {
|
|
18415
|
+
setNavGroupForceOpen(anchor, true);
|
|
18416
|
+
}
|
|
18248
18417
|
setNavDropdownPreviewOpen(null);
|
|
18249
18418
|
} else if (isDropdownTrigger) {
|
|
18250
18419
|
setNavGroupForceOpen(null, false);
|
|
@@ -19070,28 +19239,19 @@ function OhhwellsBridge() {
|
|
|
19070
19239
|
return;
|
|
19071
19240
|
}
|
|
19072
19241
|
const existing = editStylesRef.current;
|
|
19073
|
-
|
|
19074
|
-
if (existing?.base.textContent) {
|
|
19075
|
-
const match = existing.base.textContent.match(/\.min-h-screen[^{]*\{[^}]*min-height:\s*(\d+)px/);
|
|
19076
|
-
if (match) initialVh = parseInt(match[1], 10);
|
|
19077
|
-
}
|
|
19242
|
+
const canvasHeight = "var(--ohw-canvas-h, 852px)";
|
|
19078
19243
|
const baseCss = `
|
|
19079
19244
|
html { height: auto !important; }
|
|
19080
19245
|
body { height: auto !important; min-height: 0 !important; overflow: hidden !important; }
|
|
19081
|
-
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${
|
|
19082
|
-
.h-screen, .h-svh, .h-dvh { height: ${
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
[style*="
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
so content taller than one screen (a long mobile hero, say) overflows a centered flex
|
|
19091
|
-
column upward, under whatever sits above it. Only the min-height half belongs to it. */
|
|
19092
|
-
[style*="min-height"][style*="100vh"],
|
|
19093
|
-
[style*="min-height"][style*="100svh"],
|
|
19094
|
-
[style*="min-height"][style*="100dvh"] { height: auto !important; }
|
|
19246
|
+
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${canvasHeight} !important; }
|
|
19247
|
+
.h-screen, .h-svh, .h-dvh { height: ${canvasHeight} !important; }
|
|
19248
|
+
/* Literal inline viewport units only \u2014 skip R11 sections that already reference --ohw-canvas-h
|
|
19249
|
+
(their style attribute contains "100svh" only as a var() fallback string). */
|
|
19250
|
+
[style*="100vh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19251
|
+
[style*="100svh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19252
|
+
[style*="100dvh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19253
|
+
/* R11: min-height via --ohw-canvas-h; height must grow with content taller than one screen. */
|
|
19254
|
+
[style*="min-height"][style*="--ohw-canvas-h"] { height: auto !important; }
|
|
19095
19255
|
/* Emptied text keeps somewhere to click. A label typed down to nothing collapses to a
|
|
19096
19256
|
couple of pixels, and getting back into it meant hunting for the caret with the mouse.
|
|
19097
19257
|
Edit mode only \u2014 the published page shows nothing where there is nothing (OHH-736). */
|
|
@@ -19238,6 +19398,10 @@ function OhhwellsBridge() {
|
|
|
19238
19398
|
outline-offset: 0 !important;
|
|
19239
19399
|
box-shadow: none !important;
|
|
19240
19400
|
}
|
|
19401
|
+
/* Open nav dropdown panels paint above AI section selection chrome (2147483000). */
|
|
19402
|
+
[data-ohw-nav-group][data-ohw-nav-force-open] > [data-ohw-nav-children] {
|
|
19403
|
+
z-index: 2147483100 !important;
|
|
19404
|
+
}
|
|
19241
19405
|
/* Text edit wins over grab/default (must beat [data-ohw-can-drag] *). */
|
|
19242
19406
|
[data-ohw-editing],
|
|
19243
19407
|
[data-ohw-editing] *,
|
|
@@ -20575,7 +20739,11 @@ function OhhwellsBridge() {
|
|
|
20575
20739
|
const slotFromItem = hrefKey ? findSocialByHrefKey(hrefKey)?.querySelector('[data-ohw-editable="icon"]') : null;
|
|
20576
20740
|
const requestedIsIconSlot = Boolean(requestedIconKey) && Boolean(document.querySelector(`[data-ohw-key="${requestedIconKey}"][data-ohw-editable="icon"]`));
|
|
20577
20741
|
const requestedIsFree = Boolean(requestedIconKey) && !document.querySelector(`[data-ohw-key="${requestedIconKey}"]`);
|
|
20578
|
-
|
|
20742
|
+
let iconKey = requestedIsIconSlot ? requestedIconKey : slotFromItem?.dataset.ohwKey ?? (requestedIsFree ? requestedIconKey : void 0);
|
|
20743
|
+
const item = hrefKey ? findSocialByHrefKey(hrefKey) : null;
|
|
20744
|
+
if (item && typeof iconMarkup === "string" && iconMarkup) {
|
|
20745
|
+
iconKey = ensureIconSlot(item) ?? iconKey;
|
|
20746
|
+
}
|
|
20579
20747
|
if (iconKey && typeof iconMarkup === "string" && iconMarkup) {
|
|
20580
20748
|
document.querySelectorAll(`[data-ohw-key="${iconKey}"][data-ohw-editable="icon"]`).forEach((el) => {
|
|
20581
20749
|
applyIconMarkup(el, iconMarkup);
|
|
@@ -20585,7 +20753,7 @@ function OhhwellsBridge() {
|
|
|
20585
20753
|
}
|
|
20586
20754
|
if (iconKey && platformId) nodes.push({ key: socialPlatformKey(iconKey), text: platformId });
|
|
20587
20755
|
if (iconKey && label) {
|
|
20588
|
-
const labelKey = socialLabelKey(iconKey);
|
|
20756
|
+
const labelKey = (item ? socialLabelElement(item)?.getAttribute("data-ohw-key") : null) ?? socialLabelKey(iconKey);
|
|
20589
20757
|
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
20590
20758
|
if (keepLabel && el.textContent?.trim()) return;
|
|
20591
20759
|
el.textContent = label;
|
|
@@ -21411,7 +21579,12 @@ function OhhwellsBridge() {
|
|
|
21411
21579
|
}
|
|
21412
21580
|
if (navDragRef.current) {
|
|
21413
21581
|
const session = navDragRef.current;
|
|
21414
|
-
const slot = hitTestNavDropSlot(
|
|
21582
|
+
const slot = hitTestNavDropSlot(
|
|
21583
|
+
session.lastClientX,
|
|
21584
|
+
session.lastClientY,
|
|
21585
|
+
session.hrefKey,
|
|
21586
|
+
session.draggedEl
|
|
21587
|
+
);
|
|
21415
21588
|
refreshNavDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
21416
21589
|
}
|
|
21417
21590
|
if (hoveredImageRef.current) {
|
|
@@ -21617,18 +21790,21 @@ function OhhwellsBridge() {
|
|
|
21617
21790
|
}
|
|
21618
21791
|
return null;
|
|
21619
21792
|
};
|
|
21793
|
+
const isPointInRect = (el, clientX, clientY) => {
|
|
21794
|
+
const r2 = el.getBoundingClientRect();
|
|
21795
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
21796
|
+
};
|
|
21620
21797
|
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
21621
21798
|
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
21622
21799
|
for (const el of editables) {
|
|
21623
|
-
|
|
21624
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
21800
|
+
if (isPointInRect(el, clientX, clientY)) return true;
|
|
21625
21801
|
}
|
|
21626
21802
|
return false;
|
|
21627
21803
|
};
|
|
21628
21804
|
const handleCarouselHover = (e) => {
|
|
21629
21805
|
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
21630
21806
|
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
21631
|
-
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
21807
|
+
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY) || isPointOverNavigation(e.clientX, e.clientY) || isPointOverBridgeChrome(e.clientX, e.clientY)) {
|
|
21632
21808
|
setCarouselHover((prev) => prev ? null : prev);
|
|
21633
21809
|
return;
|
|
21634
21810
|
}
|