@ohhwells/bridge 0.1.139-next.373 → 0.1.139-next.375
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 +262 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -1
- package/dist/index.d.ts +135 -1
- package/dist/index.js +260 -74
- package/dist/index.js.map +1 -1
- package/dist/styles.css +19 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -72,6 +72,7 @@ __export(index_exports, {
|
|
|
72
72
|
dropIndicatorVariants: () => dropIndicatorVariants,
|
|
73
73
|
ensureFooterTree: () => ensureFooterTree,
|
|
74
74
|
filterAvailablePages: () => filterAvailablePages,
|
|
75
|
+
foldAlignIntoTrees: () => foldAlignIntoTrees,
|
|
75
76
|
getEditModeInitialState: () => getEditModeInitialState,
|
|
76
77
|
insertFooterHours: () => insertFooterHours,
|
|
77
78
|
isEditSessionActive: () => isEditSessionActive,
|
|
@@ -80,6 +81,7 @@ __export(index_exports, {
|
|
|
80
81
|
isValidUrl: () => isValidUrl,
|
|
81
82
|
nextViableSlide: () => nextViableSlide,
|
|
82
83
|
parseAiFooterState: () => parseAiFooterState,
|
|
84
|
+
parseAiSectionsState: () => parseAiSectionsState,
|
|
83
85
|
parseTarget: () => parseTarget,
|
|
84
86
|
removeFooterBlock: () => removeFooterBlock,
|
|
85
87
|
resolveFooterCopyright: () => resolveFooterCopyright,
|
|
@@ -2919,14 +2921,22 @@ function isInactiveFooterChrome(el) {
|
|
|
2919
2921
|
if (footer && footer.style.display === "none") return true;
|
|
2920
2922
|
return false;
|
|
2921
2923
|
}
|
|
2924
|
+
function isIncidentalFooter(el) {
|
|
2925
|
+
return Boolean(el.closest("blockquote, article, figure"));
|
|
2926
|
+
}
|
|
2922
2927
|
function getFooterRoot() {
|
|
2923
2928
|
const ai = document.querySelector("footer[data-ai-footer]");
|
|
2924
2929
|
if (ai) return ai;
|
|
2925
2930
|
for (const el of Array.from(
|
|
2926
|
-
document.querySelectorAll('footer[data-ohw-section="footer"]
|
|
2931
|
+
document.querySelectorAll('footer[data-ohw-section="footer"]')
|
|
2927
2932
|
)) {
|
|
2933
|
+
if (isInactiveFooterChrome(el)) continue;
|
|
2934
|
+
return el;
|
|
2935
|
+
}
|
|
2936
|
+
for (const el of Array.from(document.querySelectorAll("footer"))) {
|
|
2928
2937
|
if (el.hasAttribute("data-ai-footer")) continue;
|
|
2929
2938
|
if (isInactiveFooterChrome(el)) continue;
|
|
2939
|
+
if (isIncidentalFooter(el)) continue;
|
|
2930
2940
|
return el;
|
|
2931
2941
|
}
|
|
2932
2942
|
return null;
|
|
@@ -3337,8 +3347,8 @@ function buildFooterLink(colIndex, itemIndex, href, label, template) {
|
|
|
3337
3347
|
return anchor;
|
|
3338
3348
|
}
|
|
3339
3349
|
function footerColumnExistsInDom(colIndex) {
|
|
3340
|
-
const
|
|
3341
|
-
return
|
|
3350
|
+
const scope = getFooterLinksContainer() ?? getFooterRoot() ?? document;
|
|
3351
|
+
return scope.querySelector(`[data-ohw-footer-col="${colIndex}"]`) !== null || scope.querySelector(`[data-ohw-href-key^="footer-${colIndex}-"]`) !== null || scope.querySelector(`[data-ohw-key="footer-${colIndex}-heading"]`) !== null;
|
|
3342
3352
|
}
|
|
3343
3353
|
function getFooterLinkTemplate() {
|
|
3344
3354
|
for (const col of listFooterColumns()) {
|
|
@@ -5288,19 +5298,21 @@ function findIndexSegment(keys) {
|
|
|
5288
5298
|
if (len < 2 || tokenLists.some((t) => t.length !== len)) return null;
|
|
5289
5299
|
let position = -1;
|
|
5290
5300
|
for (let p = 0; p < len; p++) {
|
|
5291
|
-
const
|
|
5292
|
-
const allSame =
|
|
5301
|
+
const values2 = tokenLists.map((t) => t[p]);
|
|
5302
|
+
const allSame = values2.every((v) => v === values2[0]);
|
|
5293
5303
|
if (allSame) continue;
|
|
5294
|
-
|
|
5295
|
-
if (!allNumeric || position !== -1) return null;
|
|
5304
|
+
if (position !== -1) return null;
|
|
5296
5305
|
position = p;
|
|
5297
5306
|
}
|
|
5298
5307
|
if (position === -1) return null;
|
|
5308
|
+
const values = tokenLists.map((t) => t[position]);
|
|
5309
|
+
const numericCount = values.filter((v) => /^\d+$/.test(v)).length;
|
|
5310
|
+
if (numericCount !== 0 && numericCount !== values.length) return null;
|
|
5311
|
+
if (numericCount === 0 && position === len - 1) return null;
|
|
5299
5312
|
const group = tokenLists[0].slice(0, position).join("-");
|
|
5300
5313
|
if (!group) return null;
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
return { position, group };
|
|
5314
|
+
if (new Set(values).size !== values.length) return null;
|
|
5315
|
+
return numericCount === values.length ? { position, group } : { position, group, slug: true };
|
|
5304
5316
|
}
|
|
5305
5317
|
function singleIndexSegment(key) {
|
|
5306
5318
|
const tokens = baseKey(key).split("-");
|
|
@@ -5346,7 +5358,19 @@ function detectItemGroups(sectionEl) {
|
|
|
5346
5358
|
list.push(m);
|
|
5347
5359
|
byShape.set(shape, list);
|
|
5348
5360
|
}
|
|
5349
|
-
|
|
5361
|
+
const shaped = Array.from(byShape.values());
|
|
5362
|
+
clusters.push(...shaped.filter((c) => c.length >= 2));
|
|
5363
|
+
const singles = shaped.filter((c) => c.length === 1).map((c) => c[0]);
|
|
5364
|
+
const bySlugShape = /* @__PURE__ */ new Map();
|
|
5365
|
+
for (const m of singles) {
|
|
5366
|
+
const primary = primaryKey(keyedDescendants(m));
|
|
5367
|
+
const tokens = baseKey(primary ?? "").split("-");
|
|
5368
|
+
const slugShape = `${tokens.length}|${tokens[0]}|${tokens[tokens.length - 1]}`;
|
|
5369
|
+
const list = bySlugShape.get(slugShape) ?? [];
|
|
5370
|
+
list.push(m);
|
|
5371
|
+
bySlugShape.set(slugShape, list);
|
|
5372
|
+
}
|
|
5373
|
+
clusters.push(...Array.from(bySlugShape.values()));
|
|
5350
5374
|
}
|
|
5351
5375
|
for (const members of clusters) {
|
|
5352
5376
|
const keyedPerMember = members.map((m) => keyedDescendants(m));
|
|
@@ -5357,11 +5381,28 @@ function detectItemGroups(sectionEl) {
|
|
|
5357
5381
|
const dedupeKey = `${segment.group}`;
|
|
5358
5382
|
if (seenParents.has(dedupeKey)) continue;
|
|
5359
5383
|
seenParents.add(dedupeKey);
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5384
|
+
let items;
|
|
5385
|
+
if (segment.slug) {
|
|
5386
|
+
const tokens = members.map((_, i) => baseKey(primaries[i]).split("-")[segment.position]);
|
|
5387
|
+
let nextOriginal = 1;
|
|
5388
|
+
const indices = tokens.map((t) => {
|
|
5389
|
+
const cloneMatch = t.match(/^x(\d+)$/);
|
|
5390
|
+
return cloneMatch ? parseInt(cloneMatch[1], 10) : nextOriginal++;
|
|
5391
|
+
});
|
|
5392
|
+
if (new Set(indices).size !== indices.length) continue;
|
|
5393
|
+
items = members.map((el, i) => ({
|
|
5394
|
+
el,
|
|
5395
|
+
index: indices[i],
|
|
5396
|
+
keyed: keyedPerMember[i],
|
|
5397
|
+
slugToken: tokens[i]
|
|
5398
|
+
}));
|
|
5399
|
+
} else {
|
|
5400
|
+
items = members.map((el, i) => ({
|
|
5401
|
+
el,
|
|
5402
|
+
index: indexFromKey(primaries[i], segment.position),
|
|
5403
|
+
keyed: keyedPerMember[i]
|
|
5404
|
+
}));
|
|
5405
|
+
}
|
|
5365
5406
|
groups.push({ group: segment.group, parent, nested: false, items });
|
|
5366
5407
|
}
|
|
5367
5408
|
}
|
|
@@ -5485,6 +5526,18 @@ function rekeyItemClone(clone, source, sibling, group, newIndex) {
|
|
|
5485
5526
|
const delta = newIndex - source.index;
|
|
5486
5527
|
const cloneKeyed = keyedDescendants(clone);
|
|
5487
5528
|
const pairs = [];
|
|
5529
|
+
if (source.slugToken) {
|
|
5530
|
+
source.keyed.forEach((src, i) => {
|
|
5531
|
+
const target = cloneKeyed[i];
|
|
5532
|
+
if (!target || target.attr !== src.attr) return;
|
|
5533
|
+
const tokens = baseKey(src.key).split("-");
|
|
5534
|
+
if (!tokens.includes(source.slugToken)) return;
|
|
5535
|
+
const next = tokens.map((t) => t === source.slugToken ? `x${newIndex}` : t).join("-") + keySuffix(src.key);
|
|
5536
|
+
target.el.setAttribute(src.attr, next);
|
|
5537
|
+
pairs.push({ from: src.key, to: next });
|
|
5538
|
+
});
|
|
5539
|
+
return pairs;
|
|
5540
|
+
}
|
|
5488
5541
|
source.keyed.forEach((src, i) => {
|
|
5489
5542
|
const target = cloneKeyed[i];
|
|
5490
5543
|
if (!target || target.attr !== src.attr) return;
|
|
@@ -5528,7 +5581,12 @@ function syncGroup(detected, state) {
|
|
|
5528
5581
|
clone.setAttribute(ITEM_ATTR, `${detected.group}:${entry.index}`);
|
|
5529
5582
|
rekeyItemClone(clone, source, sibling, detected.group, entry.index);
|
|
5530
5583
|
source.el.insertAdjacentElement("afterend", clone);
|
|
5531
|
-
byIndex.set(entry.index, {
|
|
5584
|
+
byIndex.set(entry.index, {
|
|
5585
|
+
el: clone,
|
|
5586
|
+
index: entry.index,
|
|
5587
|
+
keyed: keyedDescendants(clone),
|
|
5588
|
+
...source.slugToken ? { slugToken: `x${entry.index}` } : {}
|
|
5589
|
+
});
|
|
5532
5590
|
}
|
|
5533
5591
|
const listed = state.items.map((e) => byIndex.get(e.index)?.el).filter((el) => !!el);
|
|
5534
5592
|
let prev = null;
|
|
@@ -5630,9 +5688,16 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5630
5688
|
const nodes = [];
|
|
5631
5689
|
const added = [];
|
|
5632
5690
|
let elements = syncGroup(detected, state);
|
|
5691
|
+
const sluggy = detected.items.some((item) => item.slugToken);
|
|
5692
|
+
const slugTokenOf = (index) => detected.items.find((item) => item.index === index)?.slugToken ?? (sluggy ? `x${index}` : void 0);
|
|
5633
5693
|
for (const add of ops.add ?? []) {
|
|
5634
5694
|
const sourceEl = elements.get(add.cloneOf);
|
|
5635
|
-
const source = sourceEl ? {
|
|
5695
|
+
const source = sourceEl ? {
|
|
5696
|
+
el: sourceEl,
|
|
5697
|
+
index: add.cloneOf,
|
|
5698
|
+
keyed: keyedDescendants(sourceEl),
|
|
5699
|
+
...slugTokenOf(add.cloneOf) ? { slugToken: slugTokenOf(add.cloneOf) } : {}
|
|
5700
|
+
} : void 0;
|
|
5636
5701
|
if (!source) continue;
|
|
5637
5702
|
const newIndex = Math.max(...state.items.map((e) => e.index), ...detected.items.map((i) => i.index)) + 1;
|
|
5638
5703
|
const sibling = detected.items.find((item) => item.index !== add.cloneOf && !item.el.hasAttribute(ITEM_CLONE_ATTR)) ?? null;
|
|
@@ -5659,7 +5724,12 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5659
5724
|
if (anchor) anchor.insertAdjacentElement("afterend", clone);
|
|
5660
5725
|
else source.el.insertAdjacentElement("afterend", clone);
|
|
5661
5726
|
elements.set(newIndex, clone);
|
|
5662
|
-
detected.items.push({
|
|
5727
|
+
detected.items.push({
|
|
5728
|
+
el: clone,
|
|
5729
|
+
index: newIndex,
|
|
5730
|
+
keyed: cloneKeyed,
|
|
5731
|
+
...sluggy ? { slugToken: `x${newIndex}` } : {}
|
|
5732
|
+
});
|
|
5663
5733
|
added.push(newIndex);
|
|
5664
5734
|
elements = syncGroup(detected, state);
|
|
5665
5735
|
}
|
|
@@ -6102,16 +6172,25 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6102
6172
|
nextTrees.set(id, fresh);
|
|
6103
6173
|
return fresh;
|
|
6104
6174
|
};
|
|
6175
|
+
const stripChildAligns = (node) => node.children ? {
|
|
6176
|
+
...node,
|
|
6177
|
+
children: node.children.map((child) => {
|
|
6178
|
+
const { align: _dropped, ...rest } = child;
|
|
6179
|
+
return stripChildAligns(rest);
|
|
6180
|
+
})
|
|
6181
|
+
} : node;
|
|
6105
6182
|
const nodes = {};
|
|
6106
6183
|
for (const [key, override] of Object.entries(store.nodes)) {
|
|
6107
6184
|
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
6108
6185
|
const tree = match ? treeFor(match[1]) : void 0;
|
|
6109
|
-
const
|
|
6110
|
-
|
|
6186
|
+
const row = match && tree ? tree.rows[Number(match[2])] : void 0;
|
|
6187
|
+
const blockIdx = match ? Number(match[3]) : -1;
|
|
6188
|
+
const block = row?.blocks[blockIdx];
|
|
6189
|
+
if (!row || !block) {
|
|
6111
6190
|
nodes[key] = override;
|
|
6112
6191
|
continue;
|
|
6113
6192
|
}
|
|
6114
|
-
|
|
6193
|
+
row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
|
|
6115
6194
|
const rest = { ...override };
|
|
6116
6195
|
delete rest.align;
|
|
6117
6196
|
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
@@ -6124,7 +6203,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6124
6203
|
continue;
|
|
6125
6204
|
}
|
|
6126
6205
|
for (const row of tree.rows) {
|
|
6127
|
-
|
|
6206
|
+
row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
|
|
6128
6207
|
}
|
|
6129
6208
|
const rest = { ...override };
|
|
6130
6209
|
delete rest.align;
|
|
@@ -6355,6 +6434,20 @@ function applyBrandChrome(content) {
|
|
|
6355
6434
|
|
|
6356
6435
|
// src/lib/brand-kit.ts
|
|
6357
6436
|
var BRAND_KIT_KEY = "__ohw_brand";
|
|
6437
|
+
var appliedPalette = null;
|
|
6438
|
+
var appliedFonts = null;
|
|
6439
|
+
function getAppliedBrand() {
|
|
6440
|
+
if (!appliedPalette) return null;
|
|
6441
|
+
return appliedFonts ? { palette: appliedPalette, fonts: appliedFonts } : { palette: appliedPalette };
|
|
6442
|
+
}
|
|
6443
|
+
function brandForGenerated(fallback) {
|
|
6444
|
+
const applied = getAppliedBrand();
|
|
6445
|
+
if (!applied) return fallback ?? void 0;
|
|
6446
|
+
return {
|
|
6447
|
+
palette: applied.palette,
|
|
6448
|
+
fonts: applied.fonts ?? fallback?.fonts ?? AI_DEFAULT_BRAND.fonts
|
|
6449
|
+
};
|
|
6450
|
+
}
|
|
6358
6451
|
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
6359
6452
|
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
6360
6453
|
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
@@ -6658,6 +6751,8 @@ function loadCustomFonts(fonts) {
|
|
|
6658
6751
|
function applyBrandToDom(kit) {
|
|
6659
6752
|
const root = document.documentElement;
|
|
6660
6753
|
if (!kit) {
|
|
6754
|
+
appliedPalette = null;
|
|
6755
|
+
appliedFonts = null;
|
|
6661
6756
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...BUTTON_VAR_NAMES]) {
|
|
6662
6757
|
root.style.removeProperty(name);
|
|
6663
6758
|
}
|
|
@@ -6671,11 +6766,16 @@ function applyBrandToDom(kit) {
|
|
|
6671
6766
|
const applyFonts = kit.touched ? kit.touched.fonts === true : true;
|
|
6672
6767
|
if (kit.palette) {
|
|
6673
6768
|
if (applyPalette) {
|
|
6769
|
+
appliedPalette = kit.palette;
|
|
6674
6770
|
for (const [name, value] of Object.entries(brandColorVars(kit.palette))) root.style.setProperty(name, value);
|
|
6675
6771
|
} else {
|
|
6772
|
+
appliedPalette = null;
|
|
6676
6773
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
|
|
6677
6774
|
}
|
|
6678
6775
|
}
|
|
6776
|
+
if (kit.fonts) {
|
|
6777
|
+
appliedFonts = applyFonts ? kit.fonts : null;
|
|
6778
|
+
}
|
|
6679
6779
|
if (kit.buttons) {
|
|
6680
6780
|
for (const name of BUTTON_VAR_NAMES) root.style.removeProperty(name);
|
|
6681
6781
|
for (const [name, value] of Object.entries(buttonStyleVars({ ...kit, buttons: kit.buttons }))) root.style.setProperty(name, value);
|
|
@@ -7208,6 +7308,35 @@ function withThemeFonts(brand) {
|
|
|
7208
7308
|
}
|
|
7209
7309
|
};
|
|
7210
7310
|
}
|
|
7311
|
+
function liveBrandColor(role, fallback) {
|
|
7312
|
+
if (role === "dark") {
|
|
7313
|
+
return `var(--brand-text, var(--ohw-brand-dark, var(--color-dark, ${fallback})))`;
|
|
7314
|
+
}
|
|
7315
|
+
if (role === "light") {
|
|
7316
|
+
return `var(--brand-background, var(--ohw-brand-light, var(--color-light, ${fallback})))`;
|
|
7317
|
+
}
|
|
7318
|
+
return `var(--brand-${role}, var(--ohw-brand-${role}, var(--color-${role}, ${fallback})))`;
|
|
7319
|
+
}
|
|
7320
|
+
function withLivePalette(brand, source) {
|
|
7321
|
+
const sourceOf = (color) => {
|
|
7322
|
+
const value = color.trim().toLowerCase();
|
|
7323
|
+
const entries = Object.entries(source.palette);
|
|
7324
|
+
return entries.find(([, hex]) => hex.trim().toLowerCase() === value)?.[0] ?? null;
|
|
7325
|
+
};
|
|
7326
|
+
const map = (color) => {
|
|
7327
|
+
const role = sourceOf(color);
|
|
7328
|
+
return role ? liveBrandColor(role, source.palette[role]) : color;
|
|
7329
|
+
};
|
|
7330
|
+
return {
|
|
7331
|
+
...brand,
|
|
7332
|
+
palette: {
|
|
7333
|
+
dark: map(brand.palette.dark),
|
|
7334
|
+
primary: map(brand.palette.primary),
|
|
7335
|
+
accent: map(brand.palette.accent),
|
|
7336
|
+
light: map(brand.palette.light)
|
|
7337
|
+
}
|
|
7338
|
+
};
|
|
7339
|
+
}
|
|
7211
7340
|
function footerLogoStyle(fallbackFont, fallbackColor) {
|
|
7212
7341
|
return {
|
|
7213
7342
|
fontFamily: `var(--brand-font-heading, var(--font-heading, var(--font-display, ${quotedFont(fallbackFont)})))`,
|
|
@@ -7235,6 +7364,7 @@ var blockAlignStyle = (blockAlign) => blockAlign ? {
|
|
|
7235
7364
|
alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
|
|
7236
7365
|
textAlign: blockAlign
|
|
7237
7366
|
} : {};
|
|
7367
|
+
var fullBleedBlock = (block) => block.type === "carousel" || block.type === "group" && str(block.slots?.layout) === "overlap";
|
|
7238
7368
|
var featureLines = (value) => value.split(/\n|<br\s*\/?>/i).map((line) => line.trim()).filter(Boolean);
|
|
7239
7369
|
var AI_MOBILE_CSS = [
|
|
7240
7370
|
// Unscoped (applies at every viewport, not just mobile): re-enables pointer-events for the
|
|
@@ -7427,7 +7557,7 @@ function hexContrast(a, b) {
|
|
|
7427
7557
|
function primaryButtonLabel(brand) {
|
|
7428
7558
|
const darkC = hexContrast(brand.palette.primary, brand.palette.dark);
|
|
7429
7559
|
const lightC = hexContrast(brand.palette.primary, AI_TREE_TOKENS.textPrimaryForeground);
|
|
7430
|
-
if (darkC === null || lightC === null) return AI_TREE_TOKENS.textPrimaryForeground
|
|
7560
|
+
if (darkC === null || lightC === null) return `var(--brand-on-primary, ${AI_TREE_TOKENS.textPrimaryForeground})`;
|
|
7431
7561
|
return darkC > lightC ? brand.palette.dark : AI_TREE_TOKENS.textPrimaryForeground;
|
|
7432
7562
|
}
|
|
7433
7563
|
function accentBandContext(brand) {
|
|
@@ -7451,7 +7581,11 @@ function readableForeground(bg, brand) {
|
|
|
7451
7581
|
return darkC > lightC ? brand.palette.dark : AI_TREE_TOKENS.textPrimaryForeground;
|
|
7452
7582
|
}
|
|
7453
7583
|
function hexWithAlpha(hex, alpha) {
|
|
7454
|
-
const
|
|
7584
|
+
const value = hex.trim();
|
|
7585
|
+
if (value.startsWith("var(") || value.startsWith("color-mix(")) {
|
|
7586
|
+
return `color-mix(in srgb, ${value} ${Math.round(alpha * 100)}%, transparent)`;
|
|
7587
|
+
}
|
|
7588
|
+
const m = /^#([0-9a-f]{6})$/i.exec(value);
|
|
7455
7589
|
if (!m) return hex;
|
|
7456
7590
|
const r2 = parseInt(m[1].slice(0, 2), 16);
|
|
7457
7591
|
const g = parseInt(m[1].slice(2, 4), 16);
|
|
@@ -7750,12 +7884,10 @@ function ButtonEl({
|
|
|
7750
7884
|
cursor: "pointer",
|
|
7751
7885
|
whiteSpace: "nowrap",
|
|
7752
7886
|
...buttonShellStyle(ctx, variant, fullWidth),
|
|
7753
|
-
...tokenColorStyle ?? (secondary ? { border: `1px solid ${secondaryColor ?? ctx.brand.palette.dark}`, color: secondaryColor ?? ctx.brand.palette.dark } :
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : { background: ctx.brand.palette.primary, color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand) }
|
|
7758
|
-
))
|
|
7887
|
+
...tokenColorStyle ?? (secondary ? { border: `1px solid ${secondaryColor ?? ctx.brand.palette.dark}`, color: secondaryColor ?? ctx.brand.palette.dark } : {
|
|
7888
|
+
background: ctx.brand.palette.primary,
|
|
7889
|
+
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
7890
|
+
})
|
|
7759
7891
|
},
|
|
7760
7892
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
|
|
7761
7893
|
}
|
|
@@ -9326,8 +9458,8 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9326
9458
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9327
9459
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9328
9460
|
// the full section width instead of reading at the usual content width.
|
|
9329
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { maxWidth: AI_TREE_TOKENS.sectionMaxWidth, margin: "0 auto", padding: "0 40px", width: "100%", boxSizing: "border-box" }, children: renderNode(child, ctx, `${path}.c${i}`, child.align ?? "center") })
|
|
9330
|
-
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? "center" : void 0),
|
|
9461
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { maxWidth: AI_TREE_TOKENS.sectionMaxWidth, margin: "0 auto", padding: "0 40px", width: "100%", boxSizing: "border-box" }, children: renderNode(child, ctx, `${path}.c${i}`, child.align ?? node.align ?? "center") })
|
|
9462
|
+
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? node.align ?? "center" : void 0),
|
|
9331
9463
|
i === 0 && needsBaseScrim && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9332
9464
|
"div",
|
|
9333
9465
|
{
|
|
@@ -9360,7 +9492,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9360
9492
|
// child otherwise stretches full-width (unchanged pre-existing behaviour).
|
|
9361
9493
|
...blockAlignStyle(child.align ?? ambientAlign)
|
|
9362
9494
|
},
|
|
9363
|
-
children: renderNode(child, ctx, `${path}.c${i}`, ambientAlign)
|
|
9495
|
+
children: renderNode(child, ctx, `${path}.c${i}`, node.align ?? ambientAlign)
|
|
9364
9496
|
},
|
|
9365
9497
|
i
|
|
9366
9498
|
));
|
|
@@ -9390,8 +9522,20 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9390
9522
|
}
|
|
9391
9523
|
case "button":
|
|
9392
9524
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ButtonEl, { slots, ctx, path });
|
|
9393
|
-
case "button-row":
|
|
9394
|
-
|
|
9525
|
+
case "button-row": {
|
|
9526
|
+
const rowAlign = node.align ?? ambientAlign;
|
|
9527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9528
|
+
"div",
|
|
9529
|
+
{
|
|
9530
|
+
style: {
|
|
9531
|
+
display: "flex",
|
|
9532
|
+
gap: AI_TREE_TOKENS.spacing6,
|
|
9533
|
+
justifyContent: rowAlign === "left" ? "flex-start" : rowAlign === "right" ? "flex-end" : "center"
|
|
9534
|
+
},
|
|
9535
|
+
children: (node.children ?? []).map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }, i))
|
|
9536
|
+
}
|
|
9537
|
+
);
|
|
9538
|
+
}
|
|
9395
9539
|
case "media":
|
|
9396
9540
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9397
9541
|
MediaBox,
|
|
@@ -9600,10 +9744,10 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9600
9744
|
...buttonShellStyle(ctx, "primary"),
|
|
9601
9745
|
// Brand-styled: the template button's measured fill/label pair off-band, else
|
|
9602
9746
|
// primary fill with a brand-derived label so it reads on custom palettes.
|
|
9603
|
-
...buttonColorStyle(ctx, "primary") ??
|
|
9747
|
+
...buttonColorStyle(ctx, "primary") ?? {
|
|
9604
9748
|
background: ctx.brand.palette.primary,
|
|
9605
9749
|
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
9606
|
-
}
|
|
9750
|
+
}
|
|
9607
9751
|
},
|
|
9608
9752
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...textAttrs(ctx, `${path}.c${i}.label`), children: str(cs.label) })
|
|
9609
9753
|
},
|
|
@@ -9647,7 +9791,7 @@ function AiTreeRenderer({
|
|
|
9647
9791
|
}
|
|
9648
9792
|
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
9649
9793
|
const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
|
|
9650
|
-
const blockBrand = band?.brand ?? resolvedBrand;
|
|
9794
|
+
const blockBrand = withLivePalette(band?.brand ?? resolvedBrand, resolvedBrand);
|
|
9651
9795
|
const placeholderMap = buildPlaceholderMap(tree);
|
|
9652
9796
|
const hasOverlapBackground = tree.scaffold === "overlay" && tree.rows.some(
|
|
9653
9797
|
(row) => (row.blocks ?? []).some((b) => b.type === "group" && str(b.slots?.layout) === "overlap")
|
|
@@ -9663,7 +9807,7 @@ function AiTreeRenderer({
|
|
|
9663
9807
|
// standalone resolve), so generated galleries, image rows, and overlay backgrounds arrive with
|
|
9664
9808
|
// photos instead of grey boxes.
|
|
9665
9809
|
resolveMedia: (ref) => resolveMedia?.(ref) ?? placeholderMap[ref] ?? resolvePlaceholderRef(ref),
|
|
9666
|
-
cardSurface:
|
|
9810
|
+
cardSurface: resolvedBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${blockBrand.palette.light} 90%, ${blockBrand.palette.dark})`,
|
|
9667
9811
|
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
|
|
9668
9812
|
sectionAlignment: (tree.settings ?? {}).alignment === "center" ? "center" : "left",
|
|
9669
9813
|
buttonStyle,
|
|
@@ -9680,7 +9824,7 @@ function AiTreeRenderer({
|
|
|
9680
9824
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
9681
9825
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
9682
9826
|
const toneBackground = (() => {
|
|
9683
|
-
const { dark, primary, light } =
|
|
9827
|
+
const { dark, primary, light } = blockBrand.palette;
|
|
9684
9828
|
switch (settings.sectionBackground) {
|
|
9685
9829
|
case "surface":
|
|
9686
9830
|
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
@@ -9772,7 +9916,7 @@ function AiTreeRenderer({
|
|
|
9772
9916
|
// its own horizontal `align`, which takes priority for that block.
|
|
9773
9917
|
...fillHeight ? { display: "grid" } : {},
|
|
9774
9918
|
// Horizontal placement of the block's content within its column.
|
|
9775
|
-
...cellAlignStyle(block.align),
|
|
9919
|
+
...fullBleedBlock(block) ? {} : cellAlignStyle(block.align),
|
|
9776
9920
|
// space-between: each column becomes a flex column whose content spreads over
|
|
9777
9921
|
// the full row height instead of clumping at the top.
|
|
9778
9922
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -9803,14 +9947,15 @@ function AiFooterRenderer({
|
|
|
9803
9947
|
if (!isRenderableFooterTree(tree)) {
|
|
9804
9948
|
return null;
|
|
9805
9949
|
}
|
|
9806
|
-
const
|
|
9950
|
+
const hexBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
9951
|
+
const resolvedBrand = withLivePalette(hexBrand, brand ?? AI_DEFAULT_BRAND);
|
|
9807
9952
|
const bandBg = surface?.background ?? resolvedBrand.palette.dark;
|
|
9808
9953
|
const bandText = surface?.text ?? resolvedBrand.palette.light;
|
|
9809
9954
|
const onDark = surface ? isDarkColor(surface.background) : true;
|
|
9810
9955
|
const ctx = {
|
|
9811
9956
|
brand: resolvedBrand,
|
|
9812
9957
|
resolveMedia: (ref) => resolveMedia?.(ref) ?? resolvePlaceholderRef(ref),
|
|
9813
|
-
cardSurface:
|
|
9958
|
+
cardSurface: hexBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${resolvedBrand.palette.light} 90%, ${resolvedBrand.palette.dark})`,
|
|
9814
9959
|
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
|
|
9815
9960
|
logoUrl: logoUrl ?? null,
|
|
9816
9961
|
resolvePageHref
|
|
@@ -10386,10 +10531,9 @@ function syncSoftRemovedGenerated() {
|
|
|
10386
10531
|
}
|
|
10387
10532
|
function applyAiSectionsToDom(state, options) {
|
|
10388
10533
|
if (typeof document === "undefined") return;
|
|
10389
|
-
const brandOverride = deriveBrandOverride();
|
|
10390
10534
|
const templateBrand = deriveTemplateBrand();
|
|
10391
10535
|
const templateButtonStyle = deriveTemplateButtonStyle();
|
|
10392
|
-
const brandKey =
|
|
10536
|
+
const brandKey = JSON.stringify(getAppliedBrand() ?? deriveBrandOverride() ?? null);
|
|
10393
10537
|
const pagePath = window.location.pathname;
|
|
10394
10538
|
const pageSections = state.sections.filter((entry) => (entry.path ?? "/") === pagePath);
|
|
10395
10539
|
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
@@ -10433,7 +10577,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10433
10577
|
AiTreeRenderer,
|
|
10434
10578
|
{
|
|
10435
10579
|
tree: entry.tree,
|
|
10436
|
-
brand:
|
|
10580
|
+
brand: brandForGenerated(deriveBrandOverride() ?? entry.brand ?? options?.brand ?? templateBrand),
|
|
10437
10581
|
buttonStyle: templateButtonStyle,
|
|
10438
10582
|
resolveMedia,
|
|
10439
10583
|
editKeyPrefix: `ai.${entry.id}`
|
|
@@ -10599,7 +10743,7 @@ function applyAiFooterToDom(state, content) {
|
|
|
10599
10743
|
const templateFooter = findTemplateFooter();
|
|
10600
10744
|
captureTemplateFooterSurface(templateFooter);
|
|
10601
10745
|
const surface = capturedSurface ?? null;
|
|
10602
|
-
const brand = mountOptions.brand ?? deriveTemplateBrand();
|
|
10746
|
+
const brand = brandForGenerated(mountOptions.brand ?? deriveTemplateBrand());
|
|
10603
10747
|
const logoUrl = resolveLogoFromContent(content, templateFooter);
|
|
10604
10748
|
const serialized = JSON.stringify(state) + JSON.stringify(brand ?? null) + (logoUrl ?? "") + JSON.stringify(surface) + JSON.stringify(defaultLegal());
|
|
10605
10749
|
if (mounted2 && mounted2.serialized === serialized && mounted2.container.isConnected) {
|
|
@@ -18407,10 +18551,23 @@ function setPricingCardStyle(tree, index, style) {
|
|
|
18407
18551
|
});
|
|
18408
18552
|
}
|
|
18409
18553
|
function setPricingCardFeaturedTag(tree, index, on) {
|
|
18410
|
-
return
|
|
18554
|
+
return withPricingCollection(tree, (collection) => {
|
|
18555
|
+
const children = collection.children;
|
|
18556
|
+
if (index < 0 || index >= children.length) return false;
|
|
18557
|
+
if (on) {
|
|
18558
|
+
children.forEach((card, i) => {
|
|
18559
|
+
if (i === index) return;
|
|
18560
|
+
const prev2 = featuredOf(card);
|
|
18561
|
+
if (prev2.enabled !== true || badgeOf(prev2).length === 0) return;
|
|
18562
|
+
card.slots = card.slots ?? {};
|
|
18563
|
+
card.slots.featured = composeFeatured(pricingCardStyleOf(prev2), false, badgeOf(prev2));
|
|
18564
|
+
});
|
|
18565
|
+
}
|
|
18566
|
+
const target = children[index];
|
|
18567
|
+
target.slots = target.slots ?? {};
|
|
18411
18568
|
const prev = featuredOf(target);
|
|
18412
|
-
|
|
18413
|
-
|
|
18569
|
+
target.slots.featured = composeFeatured(pricingCardStyleOf(prev), on, badgeOf(prev));
|
|
18570
|
+
return true;
|
|
18414
18571
|
});
|
|
18415
18572
|
}
|
|
18416
18573
|
function pricingCardStyleOf(featured) {
|
|
@@ -18660,25 +18817,40 @@ function ToolbarSeparator() {
|
|
|
18660
18817
|
}
|
|
18661
18818
|
function CardStyleMenu({
|
|
18662
18819
|
value,
|
|
18663
|
-
onChange
|
|
18820
|
+
onChange,
|
|
18821
|
+
disabled = false
|
|
18664
18822
|
}) {
|
|
18665
18823
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18824
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18825
|
+
"button",
|
|
18826
|
+
{
|
|
18827
|
+
type: "button",
|
|
18828
|
+
"aria-label": "Card style",
|
|
18829
|
+
disabled,
|
|
18830
|
+
className: cn(
|
|
18831
|
+
"inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
|
|
18832
|
+
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
18833
|
+
),
|
|
18834
|
+
children: [
|
|
18835
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
18836
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18837
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18838
|
+
]
|
|
18839
|
+
}
|
|
18840
|
+
);
|
|
18841
|
+
if (disabled) {
|
|
18842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18843
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
18844
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18845
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
18846
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
18847
|
+
] })
|
|
18848
|
+
] });
|
|
18849
|
+
}
|
|
18666
18850
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18667
18851
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
18668
18852
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
|
|
18669
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children:
|
|
18670
|
-
"button",
|
|
18671
|
-
{
|
|
18672
|
-
type: "button",
|
|
18673
|
-
"aria-label": "Card style",
|
|
18674
|
-
className: "inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
|
|
18675
|
-
children: [
|
|
18676
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
18677
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18678
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18679
|
-
]
|
|
18680
|
-
}
|
|
18681
|
-
) }),
|
|
18853
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
18682
18854
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
18683
18855
|
const selected = style.value === value;
|
|
18684
18856
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
@@ -18742,23 +18914,35 @@ function PricingCardToolbar({
|
|
|
18742
18914
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18743
18915
|
),
|
|
18744
18916
|
children: [
|
|
18745
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle }),
|
|
18746
18917
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18747
18918
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18748
18919
|
CustomToolbarButton,
|
|
18749
18920
|
{
|
|
18750
18921
|
type: "button",
|
|
18751
|
-
"aria-label": featuredTag ? "
|
|
18922
|
+
"aria-label": featuredTag ? "Unmark as featured" : "Mark as featured",
|
|
18752
18923
|
"aria-pressed": featuredTag,
|
|
18753
|
-
active: featuredTag,
|
|
18754
18924
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
18755
|
-
className: "size-8",
|
|
18756
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18925
|
+
className: "group size-8",
|
|
18926
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18927
|
+
import_lucide_react9.Star,
|
|
18928
|
+
{
|
|
18929
|
+
size: 16,
|
|
18930
|
+
fill: "currentColor",
|
|
18931
|
+
strokeWidth: 0,
|
|
18932
|
+
className: cn(
|
|
18933
|
+
"transition-colors",
|
|
18934
|
+
featuredTag ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
|
|
18935
|
+
),
|
|
18936
|
+
style: { pointerEvents: "none" }
|
|
18937
|
+
}
|
|
18938
|
+
)
|
|
18757
18939
|
}
|
|
18758
18940
|
) }),
|
|
18759
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "
|
|
18941
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
18760
18942
|
] }),
|
|
18761
18943
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18944
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
18945
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18762
18946
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}) }),
|
|
18763
18947
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "relative inline-flex", children: [
|
|
18764
18948
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}),
|
|
@@ -27325,7 +27509,7 @@ function OhhwellsBridge() {
|
|
|
27325
27509
|
if (!subdomain) return {};
|
|
27326
27510
|
return contentCache.get(subdomain) ?? {};
|
|
27327
27511
|
};
|
|
27328
|
-
const observeRoots = () => [document.querySelector("nav"),
|
|
27512
|
+
const observeRoots = () => [document.querySelector("nav"), getFooterRoot()].filter(
|
|
27329
27513
|
(el) => Boolean(el)
|
|
27330
27514
|
);
|
|
27331
27515
|
const roots = observeRoots();
|
|
@@ -27781,7 +27965,7 @@ function OhhwellsBridge() {
|
|
|
27781
27965
|
{
|
|
27782
27966
|
const formEl = getFormElement(target);
|
|
27783
27967
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
27784
|
-
if (formEl && formKeyOf(formEl) && !onSuccessText) {
|
|
27968
|
+
if (formEl && formKeyOf(formEl) && !onSuccessText && !isCtaButton(target)) {
|
|
27785
27969
|
const fieldEl = getFieldWrapper(target);
|
|
27786
27970
|
if (fieldEl) {
|
|
27787
27971
|
const label = target.closest("label");
|
|
@@ -29690,6 +29874,7 @@ function OhhwellsBridge() {
|
|
|
29690
29874
|
brandKitRef.current = value;
|
|
29691
29875
|
applyBrandToDom(parseBrandKit(value));
|
|
29692
29876
|
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
29877
|
+
applyAiFooterFromContent(editContentRef.current);
|
|
29693
29878
|
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
29694
29879
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
29695
29880
|
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
@@ -30327,9 +30512,10 @@ function OhhwellsBridge() {
|
|
|
30327
30512
|
if (e.data?.type !== "ow:collect-section") return;
|
|
30328
30513
|
const sectionId = e.data.sectionId;
|
|
30329
30514
|
if (typeof sectionId !== "string" || !sectionId) return;
|
|
30330
|
-
const
|
|
30515
|
+
const foundEl = document.querySelector(
|
|
30331
30516
|
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
30332
30517
|
);
|
|
30518
|
+
const sectionEl = foundEl && !foundEl.hasAttribute("data-ohw-ai-template-hidden") && !foundEl.hasAttribute("data-ohw-ai-removed") && !foundEl.hasAttribute("data-ohw-ai-replaced-by") ? foundEl : null;
|
|
30333
30519
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
30334
30520
|
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
30335
30521
|
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
@@ -32284,6 +32470,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32284
32470
|
dropIndicatorVariants,
|
|
32285
32471
|
ensureFooterTree,
|
|
32286
32472
|
filterAvailablePages,
|
|
32473
|
+
foldAlignIntoTrees,
|
|
32287
32474
|
getEditModeInitialState,
|
|
32288
32475
|
insertFooterHours,
|
|
32289
32476
|
isEditSessionActive,
|
|
@@ -32292,6 +32479,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32292
32479
|
isValidUrl,
|
|
32293
32480
|
nextViableSlide,
|
|
32294
32481
|
parseAiFooterState,
|
|
32482
|
+
parseAiSectionsState,
|
|
32295
32483
|
parseTarget,
|
|
32296
32484
|
removeFooterBlock,
|
|
32297
32485
|
resolveFooterCopyright,
|