@ohhwells/bridge 0.1.100 → 0.1.102
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 +264 -88
- 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 +264 -88
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1307,7 +1307,12 @@ function ButtonEl({
|
|
|
1307
1307
|
textDecoration: "none",
|
|
1308
1308
|
cursor: "pointer",
|
|
1309
1309
|
...buttonShellStyle(ctx, fullWidth),
|
|
1310
|
-
...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } :
|
|
1310
|
+
...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } : (
|
|
1311
|
+
// Off-band, prefer the template button's measured fill/label pair — a template may
|
|
1312
|
+
// fill its CTAs with any token (hvac: accent bg, primary text). On an accent band
|
|
1313
|
+
// the flipped palette keeps contrast, so the brand-driven colours stay.
|
|
1314
|
+
!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : { background: ctx.brand.palette.primary, color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand) }
|
|
1315
|
+
)
|
|
1311
1316
|
},
|
|
1312
1317
|
children: /* @__PURE__ */ jsx("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
|
|
1313
1318
|
}
|
|
@@ -2379,10 +2384,12 @@ function renderNode(node, ctx, path) {
|
|
|
2379
2384
|
cursor: "pointer",
|
|
2380
2385
|
// Shape/padding/typography follow the host template's own buttons.
|
|
2381
2386
|
...buttonShellStyle(ctx),
|
|
2382
|
-
// Brand-styled:
|
|
2383
|
-
// reads
|
|
2384
|
-
background: ctx.
|
|
2385
|
-
|
|
2387
|
+
// Brand-styled: the template button's measured fill/label pair off-band, else
|
|
2388
|
+
// primary fill with a brand-derived label so it reads on custom palettes.
|
|
2389
|
+
...!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : {
|
|
2390
|
+
background: ctx.brand.palette.primary,
|
|
2391
|
+
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
2392
|
+
}
|
|
2386
2393
|
},
|
|
2387
2394
|
children: /* @__PURE__ */ jsx("span", { ...textAttrs(ctx, `${path}.c${i}.label`), children: str(cs.label) })
|
|
2388
2395
|
},
|
|
@@ -2589,11 +2596,19 @@ function deriveTemplateBrand() {
|
|
|
2589
2596
|
}
|
|
2590
2597
|
function deriveTemplateButtonStyle() {
|
|
2591
2598
|
if (typeof document === "undefined") return null;
|
|
2592
|
-
const
|
|
2593
|
-
|
|
2594
|
-
);
|
|
2599
|
+
const candidates = Array.from(
|
|
2600
|
+
document.querySelectorAll('[data-ohw-role="button"]')
|
|
2601
|
+
).filter((el) => !el.closest(`[${CONTAINER_ATTR}]`));
|
|
2602
|
+
const isFilled = (el) => {
|
|
2603
|
+
const bg = getComputedStyle(el).backgroundColor;
|
|
2604
|
+
if (!bg || bg === "transparent") return false;
|
|
2605
|
+
const alpha = bg.match(/rgba?\([^)]*,\s*([\d.]+)\)$/);
|
|
2606
|
+
return !alpha || parseFloat(alpha[1]) > 0;
|
|
2607
|
+
};
|
|
2608
|
+
const btn = candidates.find(isFilled) ?? candidates[0];
|
|
2595
2609
|
if (!btn) return null;
|
|
2596
2610
|
const cs = getComputedStyle(btn);
|
|
2611
|
+
const filled = isFilled(btn);
|
|
2597
2612
|
const corners = [
|
|
2598
2613
|
cs.borderTopLeftRadius,
|
|
2599
2614
|
cs.borderTopRightRadius,
|
|
@@ -2610,6 +2625,7 @@ function deriveTemplateButtonStyle() {
|
|
|
2610
2625
|
return {
|
|
2611
2626
|
radius: radius || "10px",
|
|
2612
2627
|
padding: `${padY}px ${padX}px`,
|
|
2628
|
+
...filled ? { background: cs.backgroundColor, color: cs.color } : {},
|
|
2613
2629
|
fontFamily: cs.fontFamily || "",
|
|
2614
2630
|
fontSize: cs.fontSize || "",
|
|
2615
2631
|
fontWeight: cs.fontWeight || "",
|
|
@@ -7427,9 +7443,7 @@ function ItemActionToolbar({
|
|
|
7427
7443
|
ToggleGroup,
|
|
7428
7444
|
{
|
|
7429
7445
|
value: dropdownOpen ? "open" : "closed",
|
|
7430
|
-
onValueChange: (
|
|
7431
|
-
if (value !== "open" && value !== "closed") return;
|
|
7432
|
-
onDropdownOpenChange?.(value === "open");
|
|
7446
|
+
onValueChange: () => {
|
|
7433
7447
|
},
|
|
7434
7448
|
className: "h-7 gap-0.5 rounded-[calc(var(--radius,0.5rem)-2px)] bg-muted p-0.5",
|
|
7435
7449
|
onMouseDown: (e) => {
|
|
@@ -7444,6 +7458,11 @@ function ItemActionToolbar({
|
|
|
7444
7458
|
size: "sm",
|
|
7445
7459
|
"aria-label": "Closed",
|
|
7446
7460
|
className: "h-6 min-w-0 px-2 text-xs font-medium",
|
|
7461
|
+
onMouseDown: (e) => {
|
|
7462
|
+
e.preventDefault();
|
|
7463
|
+
e.stopPropagation();
|
|
7464
|
+
if (dropdownOpen !== false) onDropdownOpenChange?.(false);
|
|
7465
|
+
},
|
|
7447
7466
|
children: "Closed"
|
|
7448
7467
|
}
|
|
7449
7468
|
),
|
|
@@ -7454,6 +7473,11 @@ function ItemActionToolbar({
|
|
|
7454
7473
|
size: "sm",
|
|
7455
7474
|
"aria-label": "Open",
|
|
7456
7475
|
className: "h-6 min-w-0 px-2 text-xs font-medium",
|
|
7476
|
+
onMouseDown: (e) => {
|
|
7477
|
+
e.preventDefault();
|
|
7478
|
+
e.stopPropagation();
|
|
7479
|
+
if (dropdownOpen !== true) onDropdownOpenChange?.(true);
|
|
7480
|
+
},
|
|
7457
7481
|
children: "Open"
|
|
7458
7482
|
}
|
|
7459
7483
|
)
|
|
@@ -8479,7 +8503,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8479
8503
|
"div",
|
|
8480
8504
|
{
|
|
8481
8505
|
"data-ohw-field-type-picker": "",
|
|
8482
|
-
className: "pointer-events-auto grid w-[
|
|
8506
|
+
className: "pointer-events-auto grid w-[280px] grid-cols-2 gap-2 rounded-xl border border-border bg-background p-3 shadow-lg",
|
|
8483
8507
|
children: FIELD_TYPES.map((entry) => {
|
|
8484
8508
|
const Icon = TYPE_ICONS[entry.type];
|
|
8485
8509
|
return /* @__PURE__ */ jsxs6(
|
|
@@ -8487,7 +8511,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8487
8511
|
{
|
|
8488
8512
|
type: "button",
|
|
8489
8513
|
onClick: () => onPick(entry.type),
|
|
8490
|
-
className: "flex h-[
|
|
8514
|
+
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
8515
|
children: [
|
|
8492
8516
|
/* @__PURE__ */ jsx13(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8493
8517
|
entry.label
|
|
@@ -10840,6 +10864,32 @@ function getNavbarDesktopContainer() {
|
|
|
10840
10864
|
function getNavbarDrawerContainer() {
|
|
10841
10865
|
return document.querySelector("[data-ohw-nav-drawer]");
|
|
10842
10866
|
}
|
|
10867
|
+
function isNavbarListContainerVisible(el) {
|
|
10868
|
+
if (el.hasAttribute("hidden")) return false;
|
|
10869
|
+
if (el.getClientRects().length === 0) return false;
|
|
10870
|
+
const style = window.getComputedStyle(el);
|
|
10871
|
+
return style.display !== "none" && style.visibility !== "hidden";
|
|
10872
|
+
}
|
|
10873
|
+
function getActiveNavbarListContainer(draggedEl) {
|
|
10874
|
+
const desktop = getNavbarDesktopContainer();
|
|
10875
|
+
const drawer = getNavbarDrawerContainer();
|
|
10876
|
+
if (draggedEl) {
|
|
10877
|
+
if (drawer?.contains(draggedEl)) return drawer;
|
|
10878
|
+
if (desktop?.contains(draggedEl)) return desktop;
|
|
10879
|
+
}
|
|
10880
|
+
if (desktop && isNavbarListContainerVisible(desktop)) return desktop;
|
|
10881
|
+
if (drawer && isNavbarListContainerVisible(drawer)) return drawer;
|
|
10882
|
+
return desktop ?? drawer;
|
|
10883
|
+
}
|
|
10884
|
+
function listActiveNavbarItems(draggedEl) {
|
|
10885
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
10886
|
+
if (container) {
|
|
10887
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
10888
|
+
isNavbarLinkItem
|
|
10889
|
+
);
|
|
10890
|
+
}
|
|
10891
|
+
return listNavbarItems();
|
|
10892
|
+
}
|
|
10843
10893
|
function listNavbarItems() {
|
|
10844
10894
|
const desktop = getNavbarDesktopContainer();
|
|
10845
10895
|
if (desktop) {
|
|
@@ -11952,20 +12002,23 @@ function isEmptyLabelValue(value) {
|
|
|
11952
12002
|
function applyStoredValues(item, content) {
|
|
11953
12003
|
const hrefKey = socialHrefKey(item);
|
|
11954
12004
|
const iconKey = socialIconKey(item);
|
|
12005
|
+
const baseKey = hrefKey?.replace(/-href$/, "");
|
|
11955
12006
|
if (hrefKey && content[hrefKey] !== void 0) item.setAttribute("href", content[hrefKey]);
|
|
11956
|
-
|
|
12007
|
+
const glyphKey = iconKey ?? baseKey ?? null;
|
|
12008
|
+
const glyphStored = glyphKey ? content[glyphKey]?.trim() : void 0;
|
|
12009
|
+
if (glyphStored) {
|
|
12010
|
+
ensureIconSlot(item);
|
|
11957
12011
|
const glyph = item.querySelector(ICON_SELECTOR);
|
|
11958
|
-
if (glyph
|
|
11959
|
-
applyIconMarkup(glyph,
|
|
12012
|
+
if (glyph) {
|
|
12013
|
+
applyIconMarkup(glyph, glyphStored);
|
|
11960
12014
|
glyph.removeAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
11961
12015
|
}
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
}
|
|
12016
|
+
}
|
|
12017
|
+
const label = socialLabelElement(item);
|
|
12018
|
+
const labelKey = label?.getAttribute("data-ohw-key");
|
|
12019
|
+
if (label && labelKey && content[labelKey] !== void 0) {
|
|
12020
|
+
const words = isEmptyLabelValue(content[labelKey]) ? "" : content[labelKey];
|
|
12021
|
+
if (label.innerHTML !== words) label.innerHTML = words;
|
|
11969
12022
|
}
|
|
11970
12023
|
}
|
|
11971
12024
|
function socialPlatformKey(iconKey) {
|
|
@@ -12054,6 +12107,9 @@ function insertSocialItem(row, after, content = {}, { placeholder = true, keys }
|
|
|
12054
12107
|
if (placeholder) {
|
|
12055
12108
|
const label = socialLabelElement(item);
|
|
12056
12109
|
if (label) label.textContent = PLACEHOLDER_SOCIAL_LABEL;
|
|
12110
|
+
} else if (keys) {
|
|
12111
|
+
const label = socialLabelElement(item);
|
|
12112
|
+
if (label) label.textContent = "";
|
|
12057
12113
|
}
|
|
12058
12114
|
applySocialsDisplayToRow(row, display);
|
|
12059
12115
|
return { item, hrefKey, iconKey, order: getSocialsOrderFromDom(row.ownerDocument) };
|
|
@@ -13916,8 +13972,8 @@ var lockFooterDuringDrag = lockItemDuringDrag;
|
|
|
13916
13972
|
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
13917
13973
|
|
|
13918
13974
|
// src/lib/nav-dnd.ts
|
|
13919
|
-
function listReorderableNavItems() {
|
|
13920
|
-
return
|
|
13975
|
+
function listReorderableNavItems(draggedEl) {
|
|
13976
|
+
return listActiveNavbarItems(draggedEl).filter((el) => {
|
|
13921
13977
|
const key = el.getAttribute("data-ohw-href-key");
|
|
13922
13978
|
return isNavbarHrefKey(key) && !isNestedNavChild(el);
|
|
13923
13979
|
});
|
|
@@ -13932,8 +13988,8 @@ function resolveParentNavHrefKey(child) {
|
|
|
13932
13988
|
const key = trigger?.getAttribute("data-ohw-href-key");
|
|
13933
13989
|
return key && isNavbarHrefKey(key) ? key : null;
|
|
13934
13990
|
}
|
|
13935
|
-
function listNavChildren(parentHrefKey) {
|
|
13936
|
-
const items =
|
|
13991
|
+
function listNavChildren(parentHrefKey, draggedEl) {
|
|
13992
|
+
const items = listActiveNavbarItems(draggedEl);
|
|
13937
13993
|
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
13938
13994
|
if (!parent) return [];
|
|
13939
13995
|
const group = parent.closest("[data-ohw-nav-group]");
|
|
@@ -13943,20 +13999,83 @@ function listNavChildren(parentHrefKey) {
|
|
|
13943
13999
|
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
13944
14000
|
);
|
|
13945
14001
|
}
|
|
13946
|
-
function
|
|
13947
|
-
const
|
|
13948
|
-
if (
|
|
13949
|
-
const
|
|
13950
|
-
|
|
14002
|
+
function isVerticalNavLayout(items, draggedEl) {
|
|
14003
|
+
const visible = items.filter((el) => el.getClientRects().length > 0);
|
|
14004
|
+
if (visible.length >= 2) {
|
|
14005
|
+
const a = visible[0].getBoundingClientRect();
|
|
14006
|
+
const b = visible[1].getBoundingClientRect();
|
|
14007
|
+
const verticalGap = b.top - a.bottom;
|
|
14008
|
+
const horizontalGap = b.left - a.right;
|
|
14009
|
+
return verticalGap > horizontalGap;
|
|
14010
|
+
}
|
|
14011
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
14012
|
+
if (!container) return false;
|
|
14013
|
+
const style = window.getComputedStyle(container);
|
|
14014
|
+
return style.flexDirection === "column" || style.flexDirection === "column-reverse";
|
|
14015
|
+
}
|
|
14016
|
+
function buildVerticalRootNavDropSlots(items, draggedEl) {
|
|
14017
|
+
const slots = [];
|
|
14018
|
+
const barThickness = 3;
|
|
14019
|
+
if (items.length === 0) {
|
|
14020
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
14021
|
+
if (!container) return slots;
|
|
14022
|
+
const rect = container.getBoundingClientRect();
|
|
14023
|
+
slots.push({
|
|
14024
|
+
insertIndex: 0,
|
|
14025
|
+
parentId: null,
|
|
14026
|
+
left: rect.left,
|
|
14027
|
+
top: rect.top + rect.height / 2 - barThickness / 2,
|
|
14028
|
+
width: Math.max(rect.width, 40),
|
|
14029
|
+
height: barThickness,
|
|
14030
|
+
direction: "horizontal"
|
|
14031
|
+
});
|
|
14032
|
+
return slots;
|
|
14033
|
+
}
|
|
14034
|
+
const edgeGap = (() => {
|
|
14035
|
+
if (items.length < 2) return 16;
|
|
14036
|
+
const a = items[0].getBoundingClientRect();
|
|
14037
|
+
const b = items[1].getBoundingClientRect();
|
|
14038
|
+
return Math.max(0, b.top - a.bottom);
|
|
14039
|
+
})();
|
|
14040
|
+
for (let i = 0; i <= items.length; i++) {
|
|
14041
|
+
let top;
|
|
14042
|
+
let width;
|
|
14043
|
+
let left;
|
|
14044
|
+
if (i === 0) {
|
|
14045
|
+
const first = items[0].getBoundingClientRect();
|
|
14046
|
+
top = first.top - edgeGap / 2 - barThickness / 2;
|
|
14047
|
+
left = first.left;
|
|
14048
|
+
width = first.width;
|
|
14049
|
+
} else if (i === items.length) {
|
|
14050
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
14051
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.top - items[items.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
14052
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
14053
|
+
left = last.left;
|
|
14054
|
+
width = last.width;
|
|
14055
|
+
} else {
|
|
14056
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
14057
|
+
const next = items[i].getBoundingClientRect();
|
|
14058
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
14059
|
+
left = Math.min(prev.left, next.left);
|
|
14060
|
+
width = Math.max(prev.right, next.right) - left;
|
|
14061
|
+
}
|
|
14062
|
+
slots.push({
|
|
14063
|
+
insertIndex: i,
|
|
14064
|
+
parentId: null,
|
|
14065
|
+
left,
|
|
14066
|
+
top,
|
|
14067
|
+
width: Math.max(width, 40),
|
|
14068
|
+
height: barThickness,
|
|
14069
|
+
direction: "horizontal"
|
|
14070
|
+
});
|
|
13951
14071
|
}
|
|
13952
|
-
return
|
|
14072
|
+
return slots;
|
|
13953
14073
|
}
|
|
13954
|
-
function
|
|
13955
|
-
const items = listReorderableNavItems();
|
|
14074
|
+
function buildHorizontalRootNavDropSlots(items, draggedEl) {
|
|
13956
14075
|
const slots = [];
|
|
13957
14076
|
const barThickness = 3;
|
|
13958
14077
|
if (items.length === 0) {
|
|
13959
|
-
const container =
|
|
14078
|
+
const container = getActiveNavbarListContainer(draggedEl);
|
|
13960
14079
|
if (!container) return slots;
|
|
13961
14080
|
const rect = container.getBoundingClientRect();
|
|
13962
14081
|
slots.push({
|
|
@@ -13987,10 +14106,7 @@ function buildRootNavDropSlots() {
|
|
|
13987
14106
|
height = first.height;
|
|
13988
14107
|
} else if (i === items.length) {
|
|
13989
14108
|
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;
|
|
14109
|
+
const lastGap = items.length >= 2 ? Math.max(0, last.left - items[items.length - 2].getBoundingClientRect().right) : edgeGap;
|
|
13994
14110
|
left = last.right + lastGap / 2 - barThickness / 2;
|
|
13995
14111
|
top = last.top;
|
|
13996
14112
|
height = last.height;
|
|
@@ -14013,8 +14129,15 @@ function buildRootNavDropSlots() {
|
|
|
14013
14129
|
}
|
|
14014
14130
|
return slots;
|
|
14015
14131
|
}
|
|
14016
|
-
function
|
|
14017
|
-
const
|
|
14132
|
+
function buildRootNavDropSlots(draggedEl) {
|
|
14133
|
+
const items = listReorderableNavItems(draggedEl);
|
|
14134
|
+
if (isVerticalNavLayout(items, draggedEl)) {
|
|
14135
|
+
return buildVerticalRootNavDropSlots(items, draggedEl);
|
|
14136
|
+
}
|
|
14137
|
+
return buildHorizontalRootNavDropSlots(items, draggedEl);
|
|
14138
|
+
}
|
|
14139
|
+
function buildChildNavDropSlots(parentHrefKey, draggedEl) {
|
|
14140
|
+
const children = listNavChildren(parentHrefKey, draggedEl);
|
|
14018
14141
|
const slots = [];
|
|
14019
14142
|
const barThickness = 3;
|
|
14020
14143
|
if (children.length === 0) return slots;
|
|
@@ -14035,10 +14158,7 @@ function buildChildNavDropSlots(parentHrefKey) {
|
|
|
14035
14158
|
width = first.width;
|
|
14036
14159
|
} else if (i === children.length) {
|
|
14037
14160
|
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;
|
|
14161
|
+
const lastGap = children.length >= 2 ? Math.max(0, last.top - children[children.length - 2].getBoundingClientRect().bottom) : edgeGap;
|
|
14042
14162
|
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
14043
14163
|
left = last.left;
|
|
14044
14164
|
width = last.width;
|
|
@@ -14061,18 +14181,19 @@ function buildChildNavDropSlots(parentHrefKey) {
|
|
|
14061
14181
|
}
|
|
14062
14182
|
return slots;
|
|
14063
14183
|
}
|
|
14064
|
-
function buildAllNavDropSlots(draggedHrefKey) {
|
|
14065
|
-
const
|
|
14066
|
-
|
|
14184
|
+
function buildAllNavDropSlots(draggedHrefKey, draggedEl) {
|
|
14185
|
+
const activeItems = listActiveNavbarItems(draggedEl);
|
|
14186
|
+
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);
|
|
14187
|
+
if (!dragged) return buildRootNavDropSlots(draggedEl);
|
|
14067
14188
|
if (isNestedNavChild(dragged)) {
|
|
14068
14189
|
const parentKey = resolveParentNavHrefKey(dragged);
|
|
14069
14190
|
if (!parentKey) return [];
|
|
14070
|
-
return buildChildNavDropSlots(parentKey);
|
|
14191
|
+
return buildChildNavDropSlots(parentKey, draggedEl);
|
|
14071
14192
|
}
|
|
14072
|
-
return buildRootNavDropSlots();
|
|
14193
|
+
return buildRootNavDropSlots(draggedEl);
|
|
14073
14194
|
}
|
|
14074
|
-
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
14075
|
-
const slots = buildAllNavDropSlots(draggedHrefKey);
|
|
14195
|
+
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
|
|
14196
|
+
const slots = buildAllNavDropSlots(draggedHrefKey, draggedEl);
|
|
14076
14197
|
let best = null;
|
|
14077
14198
|
for (const slot of slots) {
|
|
14078
14199
|
const cx2 = slot.left + slot.width / 2;
|
|
@@ -14123,6 +14244,12 @@ function useNavItemDrag({
|
|
|
14123
14244
|
setIsItemDragging(false);
|
|
14124
14245
|
if (keepOpenEl?.isConnected) {
|
|
14125
14246
|
setNavGroupForceOpen(keepOpenEl, true);
|
|
14247
|
+
requestAnimationFrame(() => {
|
|
14248
|
+
if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
|
|
14249
|
+
requestAnimationFrame(() => {
|
|
14250
|
+
if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
|
|
14251
|
+
});
|
|
14252
|
+
});
|
|
14126
14253
|
} else {
|
|
14127
14254
|
setNavGroupForceOpen(null, false);
|
|
14128
14255
|
}
|
|
@@ -14138,7 +14265,7 @@ function useNavItemDrag({
|
|
|
14138
14265
|
}
|
|
14139
14266
|
session.activeSlot = activeSlot;
|
|
14140
14267
|
setSiblingHintRects([]);
|
|
14141
|
-
const slots = buildAllNavDropSlots(session.hrefKey);
|
|
14268
|
+
const slots = buildAllNavDropSlots(session.hrefKey, session.draggedEl);
|
|
14142
14269
|
setNavDropSlots(slots);
|
|
14143
14270
|
const activeIdx = activeSlot ? slots.findIndex(
|
|
14144
14271
|
(s) => s.parentId === activeSlot.parentId && s.insertIndex === activeSlot.insertIndex
|
|
@@ -14174,7 +14301,12 @@ function useNavItemDrag({
|
|
|
14174
14301
|
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
14175
14302
|
setToolbarRect(rect);
|
|
14176
14303
|
}
|
|
14177
|
-
const initialSlot = hitTestNavDropSlot(
|
|
14304
|
+
const initialSlot = hitTestNavDropSlot(
|
|
14305
|
+
session.lastClientX,
|
|
14306
|
+
session.lastClientY,
|
|
14307
|
+
session.hrefKey,
|
|
14308
|
+
session.draggedEl
|
|
14309
|
+
);
|
|
14178
14310
|
refreshNavDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
14179
14311
|
},
|
|
14180
14312
|
[
|
|
@@ -14196,10 +14328,11 @@ function useNavItemDrag({
|
|
|
14196
14328
|
}
|
|
14197
14329
|
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
14198
14330
|
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
14199
|
-
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey);
|
|
14331
|
+
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey, session.draggedEl);
|
|
14200
14332
|
const planned = slot != null ? planNavItemMove(session.hrefKey, slot.parentId, slot.insertIndex) : null;
|
|
14201
14333
|
const wasSelected = session.wasSelected;
|
|
14202
14334
|
const hrefKey = session.hrefKey;
|
|
14335
|
+
const keepDropdownOpen = Boolean(session.draggedEl.closest("[data-ohw-nav-children]"));
|
|
14203
14336
|
const applySelectionAfterDrop = () => {
|
|
14204
14337
|
if (!wasSelected) {
|
|
14205
14338
|
deselectRef.current();
|
|
@@ -14233,6 +14366,14 @@ function useNavItemDrag({
|
|
|
14233
14366
|
});
|
|
14234
14367
|
applySelectionAfterDrop();
|
|
14235
14368
|
clearNavDragVisuals();
|
|
14369
|
+
if (keepDropdownOpen) {
|
|
14370
|
+
requestAnimationFrame(() => {
|
|
14371
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
14372
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
14373
|
+
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)}"]`);
|
|
14374
|
+
if (link) setNavGroupForceOpen(link, true);
|
|
14375
|
+
});
|
|
14376
|
+
}
|
|
14236
14377
|
requestAnimationFrame(() => {
|
|
14237
14378
|
if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
|
|
14238
14379
|
applyNavForest(planned.forest);
|
|
@@ -14272,7 +14413,7 @@ function useNavItemDrag({
|
|
|
14272
14413
|
if (!session) return false;
|
|
14273
14414
|
e.preventDefault();
|
|
14274
14415
|
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
14275
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
14416
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey, session.draggedEl);
|
|
14276
14417
|
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
14277
14418
|
return true;
|
|
14278
14419
|
},
|
|
@@ -14318,7 +14459,7 @@ function useNavItemDrag({
|
|
|
14318
14459
|
clearTextSelection();
|
|
14319
14460
|
const session = navDragRef.current;
|
|
14320
14461
|
if (!session) return;
|
|
14321
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
14462
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey, session.draggedEl);
|
|
14322
14463
|
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
14323
14464
|
return;
|
|
14324
14465
|
}
|
|
@@ -14334,7 +14475,8 @@ function useNavItemDrag({
|
|
|
14334
14475
|
} catch {
|
|
14335
14476
|
}
|
|
14336
14477
|
if (linkPopoverOpenRef.current) setLinkPopover(null);
|
|
14337
|
-
|
|
14478
|
+
const isNestedDrag = Boolean(pending.el.closest("[data-ohw-nav-children]"));
|
|
14479
|
+
if (activeElRef.current && !isNestedDrag) deactivateRef.current();
|
|
14338
14480
|
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
14339
14481
|
if (!key) return;
|
|
14340
14482
|
beginNavDragRef.current({
|
|
@@ -14345,6 +14487,9 @@ function useNavItemDrag({
|
|
|
14345
14487
|
lastClientY: e.clientY,
|
|
14346
14488
|
activeSlot: null
|
|
14347
14489
|
});
|
|
14490
|
+
if (activeElRef.current && isNestedDrag) {
|
|
14491
|
+
deactivateRef.current();
|
|
14492
|
+
}
|
|
14348
14493
|
};
|
|
14349
14494
|
const endPointerDrag = (e) => {
|
|
14350
14495
|
const pending = navPointerDragRef.current;
|
|
@@ -14422,6 +14567,7 @@ function useNavItemDrag({
|
|
|
14422
14567
|
);
|
|
14423
14568
|
return {
|
|
14424
14569
|
navDragRef,
|
|
14570
|
+
navPointerDragRef,
|
|
14425
14571
|
navDropSlots,
|
|
14426
14572
|
activeNavDropIndex,
|
|
14427
14573
|
startNavLinkDrag,
|
|
@@ -15820,6 +15966,7 @@ function isNavDropdownPanelOpen(childrenRoot) {
|
|
|
15820
15966
|
if (childrenRoot.closest("[data-ohw-nav-drawer]")) return true;
|
|
15821
15967
|
const group = childrenRoot.closest("[data-ohw-nav-group]");
|
|
15822
15968
|
if (group?.hasAttribute("data-ohw-nav-force-open")) return true;
|
|
15969
|
+
if (navDropdownsOpenOnClick()) return false;
|
|
15823
15970
|
if (childrenRoot.clientHeight < 2 || childrenRoot.clientWidth < 2) return false;
|
|
15824
15971
|
const style = window.getComputedStyle(childrenRoot);
|
|
15825
15972
|
if (style.display === "none" || style.visibility === "hidden") return false;
|
|
@@ -15863,6 +16010,11 @@ function getNavigationItemAnchor(el) {
|
|
|
15863
16010
|
function isNavigationItem2(el) {
|
|
15864
16011
|
return getNavigationItemAnchor(el) !== null;
|
|
15865
16012
|
}
|
|
16013
|
+
function isNavFooterScopedNavigationItem(el) {
|
|
16014
|
+
return Boolean(
|
|
16015
|
+
el.closest("nav, footer, [data-ohw-nav-container], [data-ohw-nav-drawer]")
|
|
16016
|
+
);
|
|
16017
|
+
}
|
|
15866
16018
|
function socialWordsClicked(target, item) {
|
|
15867
16019
|
const text = target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
15868
16020
|
return Boolean(text && item.contains(text));
|
|
@@ -16073,6 +16225,7 @@ function getNavigationSelectionParent(el) {
|
|
|
16073
16225
|
}
|
|
16074
16226
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
16075
16227
|
if (!isNavigationItem2(selected)) return [];
|
|
16228
|
+
if (!isNavFooterScopedNavigationItem(selected)) return [];
|
|
16076
16229
|
const socialsRow = findSocialsRow(selected);
|
|
16077
16230
|
if (socialsRow) {
|
|
16078
16231
|
return listSocialItems(socialsRow).filter((item) => item !== selected).map((item) => item.getBoundingClientRect());
|
|
@@ -17244,6 +17397,7 @@ function OhhwellsBridge() {
|
|
|
17244
17397
|
linkPopoverSessionRef.current = linkPopover;
|
|
17245
17398
|
const {
|
|
17246
17399
|
navDragRef,
|
|
17400
|
+
navPointerDragRef,
|
|
17247
17401
|
navDropSlots,
|
|
17248
17402
|
activeNavDropIndex,
|
|
17249
17403
|
startNavLinkDrag,
|
|
@@ -17446,7 +17600,12 @@ function OhhwellsBridge() {
|
|
|
17446
17600
|
if (owner) persistFieldsRef.current(owner);
|
|
17447
17601
|
}
|
|
17448
17602
|
activeElRef.current = null;
|
|
17449
|
-
|
|
17603
|
+
const preserveNavDropdown = Boolean(navPointerDragRef.current?.el?.closest("[data-ohw-nav-children]")) || Boolean(navDragRef.current?.draggedEl?.closest("[data-ohw-nav-children]")) || Boolean(
|
|
17604
|
+
selectedElRef.current?.closest("[data-ohw-nav-children]") && selectedElRef.current?.closest("[data-ohw-nav-group]")?.hasAttribute("data-ohw-nav-force-open")
|
|
17605
|
+
);
|
|
17606
|
+
if (!preserveNavDropdown) {
|
|
17607
|
+
setNavGroupForceOpen(null, false);
|
|
17608
|
+
}
|
|
17450
17609
|
setReorderHrefKey(null);
|
|
17451
17610
|
setReorderDragDisabled(false);
|
|
17452
17611
|
if (!selectedElRef.current) {
|
|
@@ -17568,7 +17727,10 @@ function OhhwellsBridge() {
|
|
|
17568
17727
|
setSelectedIsSocialsRow(false);
|
|
17569
17728
|
const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
|
|
17570
17729
|
if (isNestedNavChild(navAnchor)) {
|
|
17571
|
-
|
|
17730
|
+
const group = navAnchor.closest("[data-ohw-nav-group]");
|
|
17731
|
+
if (group?.hasAttribute("data-ohw-nav-force-open")) {
|
|
17732
|
+
setNavGroupForceOpen(navAnchor, true);
|
|
17733
|
+
}
|
|
17572
17734
|
setNavDropdownPreviewOpen(null);
|
|
17573
17735
|
} else if (isDropdownTrigger) {
|
|
17574
17736
|
const group = navAnchor.closest("[data-ohw-nav-group]");
|
|
@@ -17650,6 +17812,10 @@ function OhhwellsBridge() {
|
|
|
17650
17812
|
const handleNavDropdownOpenChange = useCallback8((open) => {
|
|
17651
17813
|
const selected = selectedElRef.current;
|
|
17652
17814
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
17815
|
+
if (isNestedNavChild(selected)) return;
|
|
17816
|
+
const group = selected.closest("[data-ohw-nav-group]");
|
|
17817
|
+
const domOpen = Boolean(group?.hasAttribute("data-ohw-nav-force-open"));
|
|
17818
|
+
if (open === domOpen) return;
|
|
17653
17819
|
setNavGroupForceOpen(selected, open);
|
|
17654
17820
|
setNavDropdownPreviewOpen(open);
|
|
17655
17821
|
requestAnimationFrame(() => {
|
|
@@ -18179,7 +18345,10 @@ function OhhwellsBridge() {
|
|
|
18179
18345
|
clearHrefKeyHover(anchor);
|
|
18180
18346
|
const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
|
|
18181
18347
|
if (isNestedNavChild(anchor)) {
|
|
18182
|
-
|
|
18348
|
+
const group = anchor.closest("[data-ohw-nav-group]");
|
|
18349
|
+
if (group?.hasAttribute("data-ohw-nav-force-open")) {
|
|
18350
|
+
setNavGroupForceOpen(anchor, true);
|
|
18351
|
+
}
|
|
18183
18352
|
setNavDropdownPreviewOpen(null);
|
|
18184
18353
|
} else if (isDropdownTrigger) {
|
|
18185
18354
|
setNavGroupForceOpen(null, false);
|
|
@@ -19021,28 +19190,19 @@ function OhhwellsBridge() {
|
|
|
19021
19190
|
return;
|
|
19022
19191
|
}
|
|
19023
19192
|
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
|
-
}
|
|
19193
|
+
const canvasHeight = "var(--ohw-canvas-h, 852px)";
|
|
19029
19194
|
const baseCss = `
|
|
19030
19195
|
html { height: auto !important; }
|
|
19031
19196
|
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; }
|
|
19197
|
+
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${canvasHeight} !important; }
|
|
19198
|
+
.h-screen, .h-svh, .h-dvh { height: ${canvasHeight} !important; }
|
|
19199
|
+
/* Literal inline viewport units only \u2014 skip R11 sections that already reference --ohw-canvas-h
|
|
19200
|
+
(their style attribute contains "100svh" only as a var() fallback string). */
|
|
19201
|
+
[style*="100vh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19202
|
+
[style*="100svh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19203
|
+
[style*="100dvh"]:not([style*="--ohw-canvas-h"]) { min-height: ${canvasHeight} !important; height: ${canvasHeight} !important; }
|
|
19204
|
+
/* R11: min-height via --ohw-canvas-h; height must grow with content taller than one screen. */
|
|
19205
|
+
[style*="min-height"][style*="--ohw-canvas-h"] { height: auto !important; }
|
|
19046
19206
|
/* Emptied text keeps somewhere to click. A label typed down to nothing collapses to a
|
|
19047
19207
|
couple of pixels, and getting back into it meant hunting for the caret with the mouse.
|
|
19048
19208
|
Edit mode only \u2014 the published page shows nothing where there is nothing (OHH-736). */
|
|
@@ -19189,6 +19349,10 @@ function OhhwellsBridge() {
|
|
|
19189
19349
|
outline-offset: 0 !important;
|
|
19190
19350
|
box-shadow: none !important;
|
|
19191
19351
|
}
|
|
19352
|
+
/* Open nav dropdown panels paint above AI section selection chrome (2147483000). */
|
|
19353
|
+
[data-ohw-nav-group][data-ohw-nav-force-open] > [data-ohw-nav-children] {
|
|
19354
|
+
z-index: 2147483100 !important;
|
|
19355
|
+
}
|
|
19192
19356
|
/* Text edit wins over grab/default (must beat [data-ohw-can-drag] *). */
|
|
19193
19357
|
[data-ohw-editing],
|
|
19194
19358
|
[data-ohw-editing] *,
|
|
@@ -20527,7 +20691,11 @@ function OhhwellsBridge() {
|
|
|
20527
20691
|
const slotFromItem = hrefKey ? findSocialByHrefKey(hrefKey)?.querySelector('[data-ohw-editable="icon"]') : null;
|
|
20528
20692
|
const requestedIsIconSlot = Boolean(requestedIconKey) && Boolean(document.querySelector(`[data-ohw-key="${requestedIconKey}"][data-ohw-editable="icon"]`));
|
|
20529
20693
|
const requestedIsFree = Boolean(requestedIconKey) && !document.querySelector(`[data-ohw-key="${requestedIconKey}"]`);
|
|
20530
|
-
|
|
20694
|
+
let iconKey = requestedIsIconSlot ? requestedIconKey : slotFromItem?.dataset.ohwKey ?? (requestedIsFree ? requestedIconKey : void 0);
|
|
20695
|
+
const item = hrefKey ? findSocialByHrefKey(hrefKey) : null;
|
|
20696
|
+
if (item && typeof iconMarkup === "string" && iconMarkup) {
|
|
20697
|
+
iconKey = ensureIconSlot(item) ?? iconKey;
|
|
20698
|
+
}
|
|
20531
20699
|
if (iconKey && typeof iconMarkup === "string" && iconMarkup) {
|
|
20532
20700
|
document.querySelectorAll(`[data-ohw-key="${iconKey}"][data-ohw-editable="icon"]`).forEach((el) => {
|
|
20533
20701
|
applyIconMarkup(el, iconMarkup);
|
|
@@ -20537,7 +20705,7 @@ function OhhwellsBridge() {
|
|
|
20537
20705
|
}
|
|
20538
20706
|
if (iconKey && platformId) nodes.push({ key: socialPlatformKey(iconKey), text: platformId });
|
|
20539
20707
|
if (iconKey && label) {
|
|
20540
|
-
const labelKey = socialLabelKey(iconKey);
|
|
20708
|
+
const labelKey = (item ? socialLabelElement(item)?.getAttribute("data-ohw-key") : null) ?? socialLabelKey(iconKey);
|
|
20541
20709
|
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
20542
20710
|
if (keepLabel && el.textContent?.trim()) return;
|
|
20543
20711
|
el.textContent = label;
|
|
@@ -21356,7 +21524,12 @@ function OhhwellsBridge() {
|
|
|
21356
21524
|
}
|
|
21357
21525
|
if (navDragRef.current) {
|
|
21358
21526
|
const session = navDragRef.current;
|
|
21359
|
-
const slot = hitTestNavDropSlot(
|
|
21527
|
+
const slot = hitTestNavDropSlot(
|
|
21528
|
+
session.lastClientX,
|
|
21529
|
+
session.lastClientY,
|
|
21530
|
+
session.hrefKey,
|
|
21531
|
+
session.draggedEl
|
|
21532
|
+
);
|
|
21360
21533
|
refreshNavDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
21361
21534
|
}
|
|
21362
21535
|
if (hoveredImageRef.current) {
|
|
@@ -21558,18 +21731,21 @@ function OhhwellsBridge() {
|
|
|
21558
21731
|
}
|
|
21559
21732
|
return null;
|
|
21560
21733
|
};
|
|
21734
|
+
const isPointInRect = (el, clientX, clientY) => {
|
|
21735
|
+
const r2 = el.getBoundingClientRect();
|
|
21736
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
21737
|
+
};
|
|
21561
21738
|
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
21562
21739
|
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
21563
21740
|
for (const el of editables) {
|
|
21564
|
-
|
|
21565
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
21741
|
+
if (isPointInRect(el, clientX, clientY)) return true;
|
|
21566
21742
|
}
|
|
21567
21743
|
return false;
|
|
21568
21744
|
};
|
|
21569
21745
|
const handleCarouselHover = (e) => {
|
|
21570
21746
|
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
21571
21747
|
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
21572
|
-
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
21748
|
+
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY) || isPointOverNavigation(e.clientX, e.clientY) || isPointOverBridgeChrome(e.clientX, e.clientY)) {
|
|
21573
21749
|
setCarouselHover((prev) => prev ? null : prev);
|
|
21574
21750
|
return;
|
|
21575
21751
|
}
|
|
@@ -22018,7 +22194,7 @@ function OhhwellsBridge() {
|
|
|
22018
22194
|
postToParent2({
|
|
22019
22195
|
type: "ow:ready",
|
|
22020
22196
|
version: "1",
|
|
22021
|
-
bridgeVersion: "0.1.
|
|
22197
|
+
bridgeVersion: "0.1.101",
|
|
22022
22198
|
path: pathname,
|
|
22023
22199
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22024
22200
|
sections
|