@ohhwells/bridge 0.1.100 → 0.1.101
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 +240 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +240 -80
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7427,9 +7427,7 @@ function ItemActionToolbar({
|
|
|
7427
7427
|
ToggleGroup,
|
|
7428
7428
|
{
|
|
7429
7429
|
value: dropdownOpen ? "open" : "closed",
|
|
7430
|
-
onValueChange: (
|
|
7431
|
-
if (value !== "open" && value !== "closed") return;
|
|
7432
|
-
onDropdownOpenChange?.(value === "open");
|
|
7430
|
+
onValueChange: () => {
|
|
7433
7431
|
},
|
|
7434
7432
|
className: "h-7 gap-0.5 rounded-[calc(var(--radius,0.5rem)-2px)] bg-muted p-0.5",
|
|
7435
7433
|
onMouseDown: (e) => {
|
|
@@ -7444,6 +7442,11 @@ function ItemActionToolbar({
|
|
|
7444
7442
|
size: "sm",
|
|
7445
7443
|
"aria-label": "Closed",
|
|
7446
7444
|
className: "h-6 min-w-0 px-2 text-xs font-medium",
|
|
7445
|
+
onMouseDown: (e) => {
|
|
7446
|
+
e.preventDefault();
|
|
7447
|
+
e.stopPropagation();
|
|
7448
|
+
if (dropdownOpen !== false) onDropdownOpenChange?.(false);
|
|
7449
|
+
},
|
|
7447
7450
|
children: "Closed"
|
|
7448
7451
|
}
|
|
7449
7452
|
),
|
|
@@ -7454,6 +7457,11 @@ function ItemActionToolbar({
|
|
|
7454
7457
|
size: "sm",
|
|
7455
7458
|
"aria-label": "Open",
|
|
7456
7459
|
className: "h-6 min-w-0 px-2 text-xs font-medium",
|
|
7460
|
+
onMouseDown: (e) => {
|
|
7461
|
+
e.preventDefault();
|
|
7462
|
+
e.stopPropagation();
|
|
7463
|
+
if (dropdownOpen !== true) onDropdownOpenChange?.(true);
|
|
7464
|
+
},
|
|
7457
7465
|
children: "Open"
|
|
7458
7466
|
}
|
|
7459
7467
|
)
|
|
@@ -8479,7 +8487,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8479
8487
|
"div",
|
|
8480
8488
|
{
|
|
8481
8489
|
"data-ohw-field-type-picker": "",
|
|
8482
|
-
className: "pointer-events-auto grid w-[
|
|
8490
|
+
className: "pointer-events-auto grid w-[280px] grid-cols-2 gap-2 rounded-xl border border-border bg-background p-3 shadow-lg",
|
|
8483
8491
|
children: FIELD_TYPES.map((entry) => {
|
|
8484
8492
|
const Icon = TYPE_ICONS[entry.type];
|
|
8485
8493
|
return /* @__PURE__ */ jsxs6(
|
|
@@ -8487,7 +8495,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8487
8495
|
{
|
|
8488
8496
|
type: "button",
|
|
8489
8497
|
onClick: () => onPick(entry.type),
|
|
8490
|
-
className: "flex h-[
|
|
8498
|
+
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",
|
|
8491
8499
|
children: [
|
|
8492
8500
|
/* @__PURE__ */ jsx13(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8493
8501
|
entry.label
|
|
@@ -10840,6 +10848,32 @@ function getNavbarDesktopContainer() {
|
|
|
10840
10848
|
function getNavbarDrawerContainer() {
|
|
10841
10849
|
return document.querySelector("[data-ohw-nav-drawer]");
|
|
10842
10850
|
}
|
|
10851
|
+
function isNavbarListContainerVisible(el) {
|
|
10852
|
+
if (el.hasAttribute("hidden")) return false;
|
|
10853
|
+
if (el.getClientRects().length === 0) return false;
|
|
10854
|
+
const style = window.getComputedStyle(el);
|
|
10855
|
+
return style.display !== "none" && style.visibility !== "hidden";
|
|
10856
|
+
}
|
|
10857
|
+
function getActiveNavbarListContainer(draggedEl) {
|
|
10858
|
+
const desktop = getNavbarDesktopContainer();
|
|
10859
|
+
const drawer = getNavbarDrawerContainer();
|
|
10860
|
+
if (draggedEl) {
|
|
10861
|
+
if (drawer?.contains(draggedEl)) return drawer;
|
|
10862
|
+
if (desktop?.contains(draggedEl)) return desktop;
|
|
10863
|
+
}
|
|
10864
|
+
if (desktop && isNavbarListContainerVisible(desktop)) return desktop;
|
|
10865
|
+
if (drawer && isNavbarListContainerVisible(drawer)) return drawer;
|
|
10866
|
+
return desktop ?? drawer;
|
|
10867
|
+
}
|
|
10868
|
+
function listActiveNavbarItems(draggedEl) {
|
|
10869
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
10870
|
+
if (container) {
|
|
10871
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
10872
|
+
isNavbarLinkItem
|
|
10873
|
+
);
|
|
10874
|
+
}
|
|
10875
|
+
return listNavbarItems();
|
|
10876
|
+
}
|
|
10843
10877
|
function listNavbarItems() {
|
|
10844
10878
|
const desktop = getNavbarDesktopContainer();
|
|
10845
10879
|
if (desktop) {
|
|
@@ -11952,20 +11986,23 @@ function isEmptyLabelValue(value) {
|
|
|
11952
11986
|
function applyStoredValues(item, content) {
|
|
11953
11987
|
const hrefKey = socialHrefKey(item);
|
|
11954
11988
|
const iconKey = socialIconKey(item);
|
|
11989
|
+
const baseKey = hrefKey?.replace(/-href$/, "");
|
|
11955
11990
|
if (hrefKey && content[hrefKey] !== void 0) item.setAttribute("href", content[hrefKey]);
|
|
11956
|
-
|
|
11991
|
+
const glyphKey = iconKey ?? baseKey ?? null;
|
|
11992
|
+
const glyphStored = glyphKey ? content[glyphKey]?.trim() : void 0;
|
|
11993
|
+
if (glyphStored) {
|
|
11994
|
+
ensureIconSlot(item);
|
|
11957
11995
|
const glyph = item.querySelector(ICON_SELECTOR);
|
|
11958
|
-
if (glyph
|
|
11959
|
-
applyIconMarkup(glyph,
|
|
11996
|
+
if (glyph) {
|
|
11997
|
+
applyIconMarkup(glyph, glyphStored);
|
|
11960
11998
|
glyph.removeAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
11961
11999
|
}
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
}
|
|
12000
|
+
}
|
|
12001
|
+
const label = socialLabelElement(item);
|
|
12002
|
+
const labelKey = label?.getAttribute("data-ohw-key");
|
|
12003
|
+
if (label && labelKey && content[labelKey] !== void 0) {
|
|
12004
|
+
const words = isEmptyLabelValue(content[labelKey]) ? "" : content[labelKey];
|
|
12005
|
+
if (label.innerHTML !== words) label.innerHTML = words;
|
|
11969
12006
|
}
|
|
11970
12007
|
}
|
|
11971
12008
|
function socialPlatformKey(iconKey) {
|
|
@@ -12054,6 +12091,9 @@ function insertSocialItem(row, after, content = {}, { placeholder = true, keys }
|
|
|
12054
12091
|
if (placeholder) {
|
|
12055
12092
|
const label = socialLabelElement(item);
|
|
12056
12093
|
if (label) label.textContent = PLACEHOLDER_SOCIAL_LABEL;
|
|
12094
|
+
} else if (keys) {
|
|
12095
|
+
const label = socialLabelElement(item);
|
|
12096
|
+
if (label) label.textContent = "";
|
|
12057
12097
|
}
|
|
12058
12098
|
applySocialsDisplayToRow(row, display);
|
|
12059
12099
|
return { item, hrefKey, iconKey, order: getSocialsOrderFromDom(row.ownerDocument) };
|
|
@@ -13916,8 +13956,8 @@ var lockFooterDuringDrag = lockItemDuringDrag;
|
|
|
13916
13956
|
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
13917
13957
|
|
|
13918
13958
|
// src/lib/nav-dnd.ts
|
|
13919
|
-
function listReorderableNavItems() {
|
|
13920
|
-
return
|
|
13959
|
+
function listReorderableNavItems(draggedEl) {
|
|
13960
|
+
return listActiveNavbarItems(draggedEl).filter((el) => {
|
|
13921
13961
|
const key = el.getAttribute("data-ohw-href-key");
|
|
13922
13962
|
return isNavbarHrefKey(key) && !isNestedNavChild(el);
|
|
13923
13963
|
});
|
|
@@ -13932,8 +13972,8 @@ function resolveParentNavHrefKey(child) {
|
|
|
13932
13972
|
const key = trigger?.getAttribute("data-ohw-href-key");
|
|
13933
13973
|
return key && isNavbarHrefKey(key) ? key : null;
|
|
13934
13974
|
}
|
|
13935
|
-
function listNavChildren(parentHrefKey) {
|
|
13936
|
-
const items =
|
|
13975
|
+
function listNavChildren(parentHrefKey, draggedEl) {
|
|
13976
|
+
const items = listActiveNavbarItems(draggedEl);
|
|
13937
13977
|
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
13938
13978
|
if (!parent) return [];
|
|
13939
13979
|
const group = parent.closest("[data-ohw-nav-group]");
|
|
@@ -13943,20 +13983,83 @@ function listNavChildren(parentHrefKey) {
|
|
|
13943
13983
|
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
13944
13984
|
);
|
|
13945
13985
|
}
|
|
13946
|
-
function
|
|
13947
|
-
const
|
|
13948
|
-
if (
|
|
13949
|
-
const
|
|
13950
|
-
|
|
13986
|
+
function isVerticalNavLayout(items, draggedEl) {
|
|
13987
|
+
const visible = items.filter((el) => el.getClientRects().length > 0);
|
|
13988
|
+
if (visible.length >= 2) {
|
|
13989
|
+
const a = visible[0].getBoundingClientRect();
|
|
13990
|
+
const b = visible[1].getBoundingClientRect();
|
|
13991
|
+
const verticalGap = b.top - a.bottom;
|
|
13992
|
+
const horizontalGap = b.left - a.right;
|
|
13993
|
+
return verticalGap > horizontalGap;
|
|
13994
|
+
}
|
|
13995
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
13996
|
+
if (!container) return false;
|
|
13997
|
+
const style = window.getComputedStyle(container);
|
|
13998
|
+
return style.flexDirection === "column" || style.flexDirection === "column-reverse";
|
|
13999
|
+
}
|
|
14000
|
+
function buildVerticalRootNavDropSlots(items, draggedEl) {
|
|
14001
|
+
const slots = [];
|
|
14002
|
+
const barThickness = 3;
|
|
14003
|
+
if (items.length === 0) {
|
|
14004
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
14005
|
+
if (!container) return slots;
|
|
14006
|
+
const rect = container.getBoundingClientRect();
|
|
14007
|
+
slots.push({
|
|
14008
|
+
insertIndex: 0,
|
|
14009
|
+
parentId: null,
|
|
14010
|
+
left: rect.left,
|
|
14011
|
+
top: rect.top + rect.height / 2 - barThickness / 2,
|
|
14012
|
+
width: Math.max(rect.width, 40),
|
|
14013
|
+
height: barThickness,
|
|
14014
|
+
direction: "horizontal"
|
|
14015
|
+
});
|
|
14016
|
+
return slots;
|
|
13951
14017
|
}
|
|
13952
|
-
|
|
14018
|
+
const edgeGap = (() => {
|
|
14019
|
+
if (items.length < 2) return 16;
|
|
14020
|
+
const a = items[0].getBoundingClientRect();
|
|
14021
|
+
const b = items[1].getBoundingClientRect();
|
|
14022
|
+
return Math.max(0, b.top - a.bottom);
|
|
14023
|
+
})();
|
|
14024
|
+
for (let i = 0; i <= items.length; i++) {
|
|
14025
|
+
let top;
|
|
14026
|
+
let width;
|
|
14027
|
+
let left;
|
|
14028
|
+
if (i === 0) {
|
|
14029
|
+
const first = items[0].getBoundingClientRect();
|
|
14030
|
+
top = first.top - edgeGap / 2 - barThickness / 2;
|
|
14031
|
+
left = first.left;
|
|
14032
|
+
width = first.width;
|
|
14033
|
+
} else if (i === items.length) {
|
|
14034
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
14035
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.top - items[items.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
14036
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
14037
|
+
left = last.left;
|
|
14038
|
+
width = last.width;
|
|
14039
|
+
} else {
|
|
14040
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
14041
|
+
const next = items[i].getBoundingClientRect();
|
|
14042
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
14043
|
+
left = Math.min(prev.left, next.left);
|
|
14044
|
+
width = Math.max(prev.right, next.right) - left;
|
|
14045
|
+
}
|
|
14046
|
+
slots.push({
|
|
14047
|
+
insertIndex: i,
|
|
14048
|
+
parentId: null,
|
|
14049
|
+
left,
|
|
14050
|
+
top,
|
|
14051
|
+
width: Math.max(width, 40),
|
|
14052
|
+
height: barThickness,
|
|
14053
|
+
direction: "horizontal"
|
|
14054
|
+
});
|
|
14055
|
+
}
|
|
14056
|
+
return slots;
|
|
13953
14057
|
}
|
|
13954
|
-
function
|
|
13955
|
-
const items = listReorderableNavItems();
|
|
14058
|
+
function buildHorizontalRootNavDropSlots(items, draggedEl) {
|
|
13956
14059
|
const slots = [];
|
|
13957
14060
|
const barThickness = 3;
|
|
13958
14061
|
if (items.length === 0) {
|
|
13959
|
-
const container =
|
|
14062
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
13960
14063
|
if (!container) return slots;
|
|
13961
14064
|
const rect = container.getBoundingClientRect();
|
|
13962
14065
|
slots.push({
|
|
@@ -13987,10 +14090,7 @@ function buildRootNavDropSlots() {
|
|
|
13987
14090
|
height = first.height;
|
|
13988
14091
|
} else if (i === items.length) {
|
|
13989
14092
|
const last = items[items.length - 1].getBoundingClientRect();
|
|
13990
|
-
const lastGap = items.length >= 2 ? Math.max(
|
|
13991
|
-
0,
|
|
13992
|
-
last.left - items[items.length - 2].getBoundingClientRect().right
|
|
13993
|
-
) : edgeGap;
|
|
14093
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.left - items[items.length - 2].getBoundingClientRect().right) : edgeGap;
|
|
13994
14094
|
left = last.right + lastGap / 2 - barThickness / 2;
|
|
13995
14095
|
top = last.top;
|
|
13996
14096
|
height = last.height;
|
|
@@ -14013,8 +14113,15 @@ function buildRootNavDropSlots() {
|
|
|
14013
14113
|
}
|
|
14014
14114
|
return slots;
|
|
14015
14115
|
}
|
|
14016
|
-
function
|
|
14017
|
-
const
|
|
14116
|
+
function buildRootNavDropSlots(draggedEl) {
|
|
14117
|
+
const items = listReorderableNavItems(draggedEl);
|
|
14118
|
+
if (isVerticalNavLayout(items, draggedEl)) {
|
|
14119
|
+
return buildVerticalRootNavDropSlots(items, draggedEl);
|
|
14120
|
+
}
|
|
14121
|
+
return buildHorizontalRootNavDropSlots(items, draggedEl);
|
|
14122
|
+
}
|
|
14123
|
+
function buildChildNavDropSlots(parentHrefKey, draggedEl) {
|
|
14124
|
+
const children = listNavChildren(parentHrefKey, draggedEl);
|
|
14018
14125
|
const slots = [];
|
|
14019
14126
|
const barThickness = 3;
|
|
14020
14127
|
if (children.length === 0) return slots;
|
|
@@ -14035,10 +14142,7 @@ function buildChildNavDropSlots(parentHrefKey) {
|
|
|
14035
14142
|
width = first.width;
|
|
14036
14143
|
} else if (i === children.length) {
|
|
14037
14144
|
const last = children[children.length - 1].getBoundingClientRect();
|
|
14038
|
-
const lastGap = children.length >= 2 ? Math.max(
|
|
14039
|
-
0,
|
|
14040
|
-
last.top - children[children.length - 2].getBoundingClientRect().bottom
|
|
14041
|
-
) : edgeGap;
|
|
14145
|
+
const lastGap = children.length >= 2 ? Math.max(0, last.top - children[children.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
14042
14146
|
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
14043
14147
|
left = last.left;
|
|
14044
14148
|
width = last.width;
|
|
@@ -14061,18 +14165,19 @@ function buildChildNavDropSlots(parentHrefKey) {
|
|
|
14061
14165
|
}
|
|
14062
14166
|
return slots;
|
|
14063
14167
|
}
|
|
14064
|
-
function buildAllNavDropSlots(draggedHrefKey) {
|
|
14065
|
-
const
|
|
14066
|
-
|
|
14168
|
+
function buildAllNavDropSlots(draggedHrefKey, draggedEl) {
|
|
14169
|
+
const activeItems = listActiveNavbarItems(draggedEl);
|
|
14170
|
+
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);
|
|
14171
|
+
if (!dragged) return buildRootNavDropSlots(draggedEl);
|
|
14067
14172
|
if (isNestedNavChild(dragged)) {
|
|
14068
14173
|
const parentKey = resolveParentNavHrefKey(dragged);
|
|
14069
14174
|
if (!parentKey) return [];
|
|
14070
|
-
return buildChildNavDropSlots(parentKey);
|
|
14175
|
+
return buildChildNavDropSlots(parentKey, draggedEl);
|
|
14071
14176
|
}
|
|
14072
|
-
return buildRootNavDropSlots();
|
|
14177
|
+
return buildRootNavDropSlots(draggedEl);
|
|
14073
14178
|
}
|
|
14074
|
-
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
14075
|
-
const slots = buildAllNavDropSlots(draggedHrefKey);
|
|
14179
|
+
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
|
|
14180
|
+
const slots = buildAllNavDropSlots(draggedHrefKey, draggedEl);
|
|
14076
14181
|
let best = null;
|
|
14077
14182
|
for (const slot of slots) {
|
|
14078
14183
|
const cx2 = slot.left + slot.width / 2;
|
|
@@ -14123,6 +14228,12 @@ function useNavItemDrag({
|
|
|
14123
14228
|
setIsItemDragging(false);
|
|
14124
14229
|
if (keepOpenEl?.isConnected) {
|
|
14125
14230
|
setNavGroupForceOpen(keepOpenEl, true);
|
|
14231
|
+
requestAnimationFrame(() => {
|
|
14232
|
+
if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
|
|
14233
|
+
requestAnimationFrame(() => {
|
|
14234
|
+
if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
|
|
14235
|
+
});
|
|
14236
|
+
});
|
|
14126
14237
|
} else {
|
|
14127
14238
|
setNavGroupForceOpen(null, false);
|
|
14128
14239
|
}
|
|
@@ -14138,7 +14249,7 @@ function useNavItemDrag({
|
|
|
14138
14249
|
}
|
|
14139
14250
|
session.activeSlot = activeSlot;
|
|
14140
14251
|
setSiblingHintRects([]);
|
|
14141
|
-
const slots = buildAllNavDropSlots(session.hrefKey);
|
|
14252
|
+
const slots = buildAllNavDropSlots(session.hrefKey, session.draggedEl);
|
|
14142
14253
|
setNavDropSlots(slots);
|
|
14143
14254
|
const activeIdx = activeSlot ? slots.findIndex(
|
|
14144
14255
|
(s) => s.parentId === activeSlot.parentId && s.insertIndex === activeSlot.insertIndex
|
|
@@ -14174,7 +14285,12 @@ function useNavItemDrag({
|
|
|
14174
14285
|
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
14175
14286
|
setToolbarRect(rect);
|
|
14176
14287
|
}
|
|
14177
|
-
const initialSlot = hitTestNavDropSlot(
|
|
14288
|
+
const initialSlot = hitTestNavDropSlot(
|
|
14289
|
+
session.lastClientX,
|
|
14290
|
+
session.lastClientY,
|
|
14291
|
+
session.hrefKey,
|
|
14292
|
+
session.draggedEl
|
|
14293
|
+
);
|
|
14178
14294
|
refreshNavDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
14179
14295
|
},
|
|
14180
14296
|
[
|
|
@@ -14196,10 +14312,11 @@ function useNavItemDrag({
|
|
|
14196
14312
|
}
|
|
14197
14313
|
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
14198
14314
|
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
14199
|
-
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey);
|
|
14315
|
+
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey, session.draggedEl);
|
|
14200
14316
|
const planned = slot != null ? planNavItemMove(session.hrefKey, slot.parentId, slot.insertIndex) : null;
|
|
14201
14317
|
const wasSelected = session.wasSelected;
|
|
14202
14318
|
const hrefKey = session.hrefKey;
|
|
14319
|
+
const keepDropdownOpen = Boolean(session.draggedEl.closest("[data-ohw-nav-children]"));
|
|
14203
14320
|
const applySelectionAfterDrop = () => {
|
|
14204
14321
|
if (!wasSelected) {
|
|
14205
14322
|
deselectRef.current();
|
|
@@ -14233,6 +14350,14 @@ function useNavItemDrag({
|
|
|
14233
14350
|
});
|
|
14234
14351
|
applySelectionAfterDrop();
|
|
14235
14352
|
clearNavDragVisuals();
|
|
14353
|
+
if (keepDropdownOpen) {
|
|
14354
|
+
requestAnimationFrame(() => {
|
|
14355
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
14356
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
14357
|
+
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)}"]`);
|
|
14358
|
+
if (link) setNavGroupForceOpen(link, true);
|
|
14359
|
+
});
|
|
14360
|
+
}
|
|
14236
14361
|
requestAnimationFrame(() => {
|
|
14237
14362
|
if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
|
|
14238
14363
|
applyNavForest(planned.forest);
|
|
@@ -14272,7 +14397,7 @@ function useNavItemDrag({
|
|
|
14272
14397
|
if (!session) return false;
|
|
14273
14398
|
e.preventDefault();
|
|
14274
14399
|
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
14275
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
14400
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey, session.draggedEl);
|
|
14276
14401
|
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
14277
14402
|
return true;
|
|
14278
14403
|
},
|
|
@@ -14318,7 +14443,7 @@ function useNavItemDrag({
|
|
|
14318
14443
|
clearTextSelection();
|
|
14319
14444
|
const session = navDragRef.current;
|
|
14320
14445
|
if (!session) return;
|
|
14321
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
14446
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey, session.draggedEl);
|
|
14322
14447
|
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
14323
14448
|
return;
|
|
14324
14449
|
}
|
|
@@ -14334,7 +14459,8 @@ function useNavItemDrag({
|
|
|
14334
14459
|
} catch {
|
|
14335
14460
|
}
|
|
14336
14461
|
if (linkPopoverOpenRef.current) setLinkPopover(null);
|
|
14337
|
-
|
|
14462
|
+
const isNestedDrag = Boolean(pending.el.closest("[data-ohw-nav-children]"));
|
|
14463
|
+
if (activeElRef.current && !isNestedDrag) deactivateRef.current();
|
|
14338
14464
|
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
14339
14465
|
if (!key) return;
|
|
14340
14466
|
beginNavDragRef.current({
|
|
@@ -14345,6 +14471,9 @@ function useNavItemDrag({
|
|
|
14345
14471
|
lastClientY: e.clientY,
|
|
14346
14472
|
activeSlot: null
|
|
14347
14473
|
});
|
|
14474
|
+
if (activeElRef.current && isNestedDrag) {
|
|
14475
|
+
deactivateRef.current();
|
|
14476
|
+
}
|
|
14348
14477
|
};
|
|
14349
14478
|
const endPointerDrag = (e) => {
|
|
14350
14479
|
const pending = navPointerDragRef.current;
|
|
@@ -14422,6 +14551,7 @@ function useNavItemDrag({
|
|
|
14422
14551
|
);
|
|
14423
14552
|
return {
|
|
14424
14553
|
navDragRef,
|
|
14554
|
+
navPointerDragRef,
|
|
14425
14555
|
navDropSlots,
|
|
14426
14556
|
activeNavDropIndex,
|
|
14427
14557
|
startNavLinkDrag,
|
|
@@ -15820,6 +15950,7 @@ function isNavDropdownPanelOpen(childrenRoot) {
|
|
|
15820
15950
|
if (childrenRoot.closest("[data-ohw-nav-drawer]")) return true;
|
|
15821
15951
|
const group = childrenRoot.closest("[data-ohw-nav-group]");
|
|
15822
15952
|
if (group?.hasAttribute("data-ohw-nav-force-open")) return true;
|
|
15953
|
+
if (navDropdownsOpenOnClick()) return false;
|
|
15823
15954
|
if (childrenRoot.clientHeight < 2 || childrenRoot.clientWidth < 2) return false;
|
|
15824
15955
|
const style = window.getComputedStyle(childrenRoot);
|
|
15825
15956
|
if (style.display === "none" || style.visibility === "hidden") return false;
|
|
@@ -15863,6 +15994,11 @@ function getNavigationItemAnchor(el) {
|
|
|
15863
15994
|
function isNavigationItem2(el) {
|
|
15864
15995
|
return getNavigationItemAnchor(el) !== null;
|
|
15865
15996
|
}
|
|
15997
|
+
function isNavFooterScopedNavigationItem(el) {
|
|
15998
|
+
return Boolean(
|
|
15999
|
+
el.closest("nav, footer, [data-ohw-nav-container], [data-ohw-nav-drawer]")
|
|
16000
|
+
);
|
|
16001
|
+
}
|
|
15866
16002
|
function socialWordsClicked(target, item) {
|
|
15867
16003
|
const text = target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
15868
16004
|
return Boolean(text && item.contains(text));
|
|
@@ -16073,6 +16209,7 @@ function getNavigationSelectionParent(el) {
|
|
|
16073
16209
|
}
|
|
16074
16210
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
16075
16211
|
if (!isNavigationItem2(selected)) return [];
|
|
16212
|
+
if (!isNavFooterScopedNavigationItem(selected)) return [];
|
|
16076
16213
|
const socialsRow = findSocialsRow(selected);
|
|
16077
16214
|
if (socialsRow) {
|
|
16078
16215
|
return listSocialItems(socialsRow).filter((item) => item !== selected).map((item) => item.getBoundingClientRect());
|
|
@@ -17244,6 +17381,7 @@ function OhhwellsBridge() {
|
|
|
17244
17381
|
linkPopoverSessionRef.current = linkPopover;
|
|
17245
17382
|
const {
|
|
17246
17383
|
navDragRef,
|
|
17384
|
+
navPointerDragRef,
|
|
17247
17385
|
navDropSlots,
|
|
17248
17386
|
activeNavDropIndex,
|
|
17249
17387
|
startNavLinkDrag,
|
|
@@ -17446,7 +17584,12 @@ function OhhwellsBridge() {
|
|
|
17446
17584
|
if (owner) persistFieldsRef.current(owner);
|
|
17447
17585
|
}
|
|
17448
17586
|
activeElRef.current = null;
|
|
17449
|
-
|
|
17587
|
+
const preserveNavDropdown = Boolean(navPointerDragRef.current?.el?.closest("[data-ohw-nav-children]")) || Boolean(navDragRef.current?.draggedEl?.closest("[data-ohw-nav-children]")) || Boolean(
|
|
17588
|
+
selectedElRef.current?.closest("[data-ohw-nav-children]") && selectedElRef.current?.closest("[data-ohw-nav-group]")?.hasAttribute("data-ohw-nav-force-open")
|
|
17589
|
+
);
|
|
17590
|
+
if (!preserveNavDropdown) {
|
|
17591
|
+
setNavGroupForceOpen(null, false);
|
|
17592
|
+
}
|
|
17450
17593
|
setReorderHrefKey(null);
|
|
17451
17594
|
setReorderDragDisabled(false);
|
|
17452
17595
|
if (!selectedElRef.current) {
|
|
@@ -17568,7 +17711,10 @@ function OhhwellsBridge() {
|
|
|
17568
17711
|
setSelectedIsSocialsRow(false);
|
|
17569
17712
|
const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
|
|
17570
17713
|
if (isNestedNavChild(navAnchor)) {
|
|
17571
|
-
|
|
17714
|
+
const group = navAnchor.closest("[data-ohw-nav-group]");
|
|
17715
|
+
if (group?.hasAttribute("data-ohw-nav-force-open")) {
|
|
17716
|
+
setNavGroupForceOpen(navAnchor, true);
|
|
17717
|
+
}
|
|
17572
17718
|
setNavDropdownPreviewOpen(null);
|
|
17573
17719
|
} else if (isDropdownTrigger) {
|
|
17574
17720
|
const group = navAnchor.closest("[data-ohw-nav-group]");
|
|
@@ -17650,6 +17796,10 @@ function OhhwellsBridge() {
|
|
|
17650
17796
|
const handleNavDropdownOpenChange = useCallback8((open) => {
|
|
17651
17797
|
const selected = selectedElRef.current;
|
|
17652
17798
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
17799
|
+
if (isNestedNavChild(selected)) return;
|
|
17800
|
+
const group = selected.closest("[data-ohw-nav-group]");
|
|
17801
|
+
const domOpen = Boolean(group?.hasAttribute("data-ohw-nav-force-open"));
|
|
17802
|
+
if (open === domOpen) return;
|
|
17653
17803
|
setNavGroupForceOpen(selected, open);
|
|
17654
17804
|
setNavDropdownPreviewOpen(open);
|
|
17655
17805
|
requestAnimationFrame(() => {
|
|
@@ -18179,7 +18329,10 @@ function OhhwellsBridge() {
|
|
|
18179
18329
|
clearHrefKeyHover(anchor);
|
|
18180
18330
|
const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
|
|
18181
18331
|
if (isNestedNavChild(anchor)) {
|
|
18182
|
-
|
|
18332
|
+
const group = anchor.closest("[data-ohw-nav-group]");
|
|
18333
|
+
if (group?.hasAttribute("data-ohw-nav-force-open")) {
|
|
18334
|
+
setNavGroupForceOpen(anchor, true);
|
|
18335
|
+
}
|
|
18183
18336
|
setNavDropdownPreviewOpen(null);
|
|
18184
18337
|
} else if (isDropdownTrigger) {
|
|
18185
18338
|
setNavGroupForceOpen(null, false);
|
|
@@ -19021,28 +19174,19 @@ function OhhwellsBridge() {
|
|
|
19021
19174
|
return;
|
|
19022
19175
|
}
|
|
19023
19176
|
const existing = editStylesRef.current;
|
|
19024
|
-
|
|
19025
|
-
if (existing?.base.textContent) {
|
|
19026
|
-
const match = existing.base.textContent.match(/\.min-h-screen[^{]*\{[^}]*min-height:\s*(\d+)px/);
|
|
19027
|
-
if (match) initialVh = parseInt(match[1], 10);
|
|
19028
|
-
}
|
|
19177
|
+
const canvasHeight = "var(--ohw-canvas-h, 852px)";
|
|
19029
19178
|
const baseCss = `
|
|
19030
19179
|
html { height: auto !important; }
|
|
19031
19180
|
body { height: auto !important; min-height: 0 !important; overflow: hidden !important; }
|
|
19032
|
-
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${
|
|
19033
|
-
.h-screen, .h-svh, .h-dvh { height: ${
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
[style*="
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
so content taller than one screen (a long mobile hero, say) overflows a centered flex
|
|
19042
|
-
column upward, under whatever sits above it. Only the min-height half belongs to it. */
|
|
19043
|
-
[style*="min-height"][style*="100vh"],
|
|
19044
|
-
[style*="min-height"][style*="100svh"],
|
|
19045
|
-
[style*="min-height"][style*="100dvh"] { height: auto !important; }
|
|
19181
|
+
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${canvasHeight} !important; }
|
|
19182
|
+
.h-screen, .h-svh, .h-dvh { height: ${canvasHeight} !important; }
|
|
19183
|
+
/* Literal inline viewport units only \u2014 skip R11 sections that already reference --ohw-canvas-h
|
|
19184
|
+
(their style attribute contains "100svh" only as a var() fallback string). */
|
|
19185
|
+
[style*="100vh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19186
|
+
[style*="100svh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19187
|
+
[style*="100dvh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19188
|
+
/* R11: min-height via --ohw-canvas-h; height must grow with content taller than one screen. */
|
|
19189
|
+
[style*="min-height"][style*="--ohw-canvas-h"] { height: auto !important; }
|
|
19046
19190
|
/* Emptied text keeps somewhere to click. A label typed down to nothing collapses to a
|
|
19047
19191
|
couple of pixels, and getting back into it meant hunting for the caret with the mouse.
|
|
19048
19192
|
Edit mode only \u2014 the published page shows nothing where there is nothing (OHH-736). */
|
|
@@ -19189,6 +19333,10 @@ function OhhwellsBridge() {
|
|
|
19189
19333
|
outline-offset: 0 !important;
|
|
19190
19334
|
box-shadow: none !important;
|
|
19191
19335
|
}
|
|
19336
|
+
/* Open nav dropdown panels paint above AI section selection chrome (2147483000). */
|
|
19337
|
+
[data-ohw-nav-group][data-ohw-nav-force-open] > [data-ohw-nav-children] {
|
|
19338
|
+
z-index: 2147483100 !important;
|
|
19339
|
+
}
|
|
19192
19340
|
/* Text edit wins over grab/default (must beat [data-ohw-can-drag] *). */
|
|
19193
19341
|
[data-ohw-editing],
|
|
19194
19342
|
[data-ohw-editing] *,
|
|
@@ -20527,7 +20675,11 @@ function OhhwellsBridge() {
|
|
|
20527
20675
|
const slotFromItem = hrefKey ? findSocialByHrefKey(hrefKey)?.querySelector('[data-ohw-editable="icon"]') : null;
|
|
20528
20676
|
const requestedIsIconSlot = Boolean(requestedIconKey) && Boolean(document.querySelector(`[data-ohw-key="${requestedIconKey}"][data-ohw-editable="icon"]`));
|
|
20529
20677
|
const requestedIsFree = Boolean(requestedIconKey) && !document.querySelector(`[data-ohw-key="${requestedIconKey}"]`);
|
|
20530
|
-
|
|
20678
|
+
let iconKey = requestedIsIconSlot ? requestedIconKey : slotFromItem?.dataset.ohwKey ?? (requestedIsFree ? requestedIconKey : void 0);
|
|
20679
|
+
const item = hrefKey ? findSocialByHrefKey(hrefKey) : null;
|
|
20680
|
+
if (item && typeof iconMarkup === "string" && iconMarkup) {
|
|
20681
|
+
iconKey = ensureIconSlot(item) ?? iconKey;
|
|
20682
|
+
}
|
|
20531
20683
|
if (iconKey && typeof iconMarkup === "string" && iconMarkup) {
|
|
20532
20684
|
document.querySelectorAll(`[data-ohw-key="${iconKey}"][data-ohw-editable="icon"]`).forEach((el) => {
|
|
20533
20685
|
applyIconMarkup(el, iconMarkup);
|
|
@@ -20537,7 +20689,7 @@ function OhhwellsBridge() {
|
|
|
20537
20689
|
}
|
|
20538
20690
|
if (iconKey && platformId) nodes.push({ key: socialPlatformKey(iconKey), text: platformId });
|
|
20539
20691
|
if (iconKey && label) {
|
|
20540
|
-
const labelKey = socialLabelKey(iconKey);
|
|
20692
|
+
const labelKey = (item ? socialLabelElement(item)?.getAttribute("data-ohw-key") : null) ?? socialLabelKey(iconKey);
|
|
20541
20693
|
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
20542
20694
|
if (keepLabel && el.textContent?.trim()) return;
|
|
20543
20695
|
el.textContent = label;
|
|
@@ -21356,7 +21508,12 @@ function OhhwellsBridge() {
|
|
|
21356
21508
|
}
|
|
21357
21509
|
if (navDragRef.current) {
|
|
21358
21510
|
const session = navDragRef.current;
|
|
21359
|
-
const slot = hitTestNavDropSlot(
|
|
21511
|
+
const slot = hitTestNavDropSlot(
|
|
21512
|
+
session.lastClientX,
|
|
21513
|
+
session.lastClientY,
|
|
21514
|
+
session.hrefKey,
|
|
21515
|
+
session.draggedEl
|
|
21516
|
+
);
|
|
21360
21517
|
refreshNavDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
21361
21518
|
}
|
|
21362
21519
|
if (hoveredImageRef.current) {
|
|
@@ -21558,18 +21715,21 @@ function OhhwellsBridge() {
|
|
|
21558
21715
|
}
|
|
21559
21716
|
return null;
|
|
21560
21717
|
};
|
|
21718
|
+
const isPointInRect = (el, clientX, clientY) => {
|
|
21719
|
+
const r2 = el.getBoundingClientRect();
|
|
21720
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
21721
|
+
};
|
|
21561
21722
|
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
21562
21723
|
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
21563
21724
|
for (const el of editables) {
|
|
21564
|
-
|
|
21565
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
21725
|
+
if (isPointInRect(el, clientX, clientY)) return true;
|
|
21566
21726
|
}
|
|
21567
21727
|
return false;
|
|
21568
21728
|
};
|
|
21569
21729
|
const handleCarouselHover = (e) => {
|
|
21570
21730
|
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
21571
21731
|
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
21572
|
-
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
21732
|
+
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY) || isPointOverNavigation(e.clientX, e.clientY) || isPointOverBridgeChrome(e.clientX, e.clientY)) {
|
|
21573
21733
|
setCarouselHover((prev) => prev ? null : prev);
|
|
21574
21734
|
return;
|
|
21575
21735
|
}
|
|
@@ -22018,7 +22178,7 @@ function OhhwellsBridge() {
|
|
|
22018
22178
|
postToParent2({
|
|
22019
22179
|
type: "ow:ready",
|
|
22020
22180
|
version: "1",
|
|
22021
|
-
bridgeVersion: "0.1.
|
|
22181
|
+
bridgeVersion: "0.1.100",
|
|
22022
22182
|
path: pathname,
|
|
22023
22183
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22024
22184
|
sections
|