@ohhwells/bridge 0.1.139 → 0.1.141
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 +269 -76
- 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 +267 -76
- 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
|
|
@@ -7425,7 +7555,7 @@ function hexContrast(a, b) {
|
|
|
7425
7555
|
function primaryButtonLabel(brand) {
|
|
7426
7556
|
const darkC = hexContrast(brand.palette.primary, brand.palette.dark);
|
|
7427
7557
|
const lightC = hexContrast(brand.palette.primary, AI_TREE_TOKENS.textPrimaryForeground);
|
|
7428
|
-
if (darkC === null || lightC === null) return AI_TREE_TOKENS.textPrimaryForeground
|
|
7558
|
+
if (darkC === null || lightC === null) return `var(--brand-on-primary, ${AI_TREE_TOKENS.textPrimaryForeground})`;
|
|
7429
7559
|
return darkC > lightC ? brand.palette.dark : AI_TREE_TOKENS.textPrimaryForeground;
|
|
7430
7560
|
}
|
|
7431
7561
|
function accentBandContext(brand) {
|
|
@@ -7449,7 +7579,11 @@ function readableForeground(bg, brand) {
|
|
|
7449
7579
|
return darkC > lightC ? brand.palette.dark : AI_TREE_TOKENS.textPrimaryForeground;
|
|
7450
7580
|
}
|
|
7451
7581
|
function hexWithAlpha(hex, alpha) {
|
|
7452
|
-
const
|
|
7582
|
+
const value = hex.trim();
|
|
7583
|
+
if (value.startsWith("var(") || value.startsWith("color-mix(")) {
|
|
7584
|
+
return `color-mix(in srgb, ${value} ${Math.round(alpha * 100)}%, transparent)`;
|
|
7585
|
+
}
|
|
7586
|
+
const m = /^#([0-9a-f]{6})$/i.exec(value);
|
|
7453
7587
|
if (!m) return hex;
|
|
7454
7588
|
const r2 = parseInt(m[1].slice(0, 2), 16);
|
|
7455
7589
|
const g = parseInt(m[1].slice(2, 4), 16);
|
|
@@ -7722,12 +7856,10 @@ function ButtonEl({
|
|
|
7722
7856
|
cursor: "pointer",
|
|
7723
7857
|
whiteSpace: "nowrap",
|
|
7724
7858
|
...buttonShellStyle(ctx, variant, fullWidth),
|
|
7725
|
-
...tokenColorStyle ?? (secondary ? { border: `1px solid ${secondaryColor ?? ctx.brand.palette.dark}`, color: secondaryColor ?? ctx.brand.palette.dark } :
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : { background: ctx.brand.palette.primary, color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand) }
|
|
7730
|
-
))
|
|
7859
|
+
...tokenColorStyle ?? (secondary ? { border: `1px solid ${secondaryColor ?? ctx.brand.palette.dark}`, color: secondaryColor ?? ctx.brand.palette.dark } : {
|
|
7860
|
+
background: ctx.brand.palette.primary,
|
|
7861
|
+
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
7862
|
+
})
|
|
7731
7863
|
},
|
|
7732
7864
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
|
|
7733
7865
|
}
|
|
@@ -9298,8 +9430,8 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9298
9430
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9299
9431
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9300
9432
|
// the full section width instead of reading at the usual content width.
|
|
9301
|
-
/* @__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") })
|
|
9302
|
-
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? "center" : void 0),
|
|
9433
|
+
/* @__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") })
|
|
9434
|
+
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? node.align ?? "center" : void 0),
|
|
9303
9435
|
i === 0 && needsBaseScrim && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9304
9436
|
"div",
|
|
9305
9437
|
{
|
|
@@ -9332,7 +9464,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9332
9464
|
// child otherwise stretches full-width (unchanged pre-existing behaviour).
|
|
9333
9465
|
...blockAlignStyle(child.align ?? ambientAlign)
|
|
9334
9466
|
},
|
|
9335
|
-
children: renderNode(child, ctx, `${path}.c${i}`, ambientAlign)
|
|
9467
|
+
children: renderNode(child, ctx, `${path}.c${i}`, node.align ?? ambientAlign)
|
|
9336
9468
|
},
|
|
9337
9469
|
i
|
|
9338
9470
|
));
|
|
@@ -9362,8 +9494,20 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9362
9494
|
}
|
|
9363
9495
|
case "button":
|
|
9364
9496
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ButtonEl, { slots, ctx, path });
|
|
9365
|
-
case "button-row":
|
|
9366
|
-
|
|
9497
|
+
case "button-row": {
|
|
9498
|
+
const rowAlign = node.align ?? ambientAlign;
|
|
9499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9500
|
+
"div",
|
|
9501
|
+
{
|
|
9502
|
+
style: {
|
|
9503
|
+
display: "flex",
|
|
9504
|
+
gap: AI_TREE_TOKENS.spacing6,
|
|
9505
|
+
justifyContent: rowAlign === "left" ? "flex-start" : rowAlign === "right" ? "flex-end" : "center"
|
|
9506
|
+
},
|
|
9507
|
+
children: (node.children ?? []).map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }, i))
|
|
9508
|
+
}
|
|
9509
|
+
);
|
|
9510
|
+
}
|
|
9367
9511
|
case "media":
|
|
9368
9512
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9369
9513
|
MediaBox,
|
|
@@ -9572,10 +9716,10 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9572
9716
|
...buttonShellStyle(ctx, "primary"),
|
|
9573
9717
|
// Brand-styled: the template button's measured fill/label pair off-band, else
|
|
9574
9718
|
// primary fill with a brand-derived label so it reads on custom palettes.
|
|
9575
|
-
...buttonColorStyle(ctx, "primary") ??
|
|
9719
|
+
...buttonColorStyle(ctx, "primary") ?? {
|
|
9576
9720
|
background: ctx.brand.palette.primary,
|
|
9577
9721
|
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
9578
|
-
}
|
|
9722
|
+
}
|
|
9579
9723
|
},
|
|
9580
9724
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...textAttrs(ctx, `${path}.c${i}.label`), children: str(cs.label) })
|
|
9581
9725
|
},
|
|
@@ -9619,7 +9763,7 @@ function AiTreeRenderer({
|
|
|
9619
9763
|
}
|
|
9620
9764
|
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
9621
9765
|
const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
|
|
9622
|
-
const blockBrand = band?.brand ?? resolvedBrand;
|
|
9766
|
+
const blockBrand = withLivePalette(band?.brand ?? resolvedBrand, resolvedBrand);
|
|
9623
9767
|
const placeholderMap = buildPlaceholderMap(tree);
|
|
9624
9768
|
const hasOverlapBackground = tree.scaffold === "overlay" && tree.rows.some(
|
|
9625
9769
|
(row) => (row.blocks ?? []).some((b) => b.type === "group" && str(b.slots?.layout) === "overlap")
|
|
@@ -9635,7 +9779,7 @@ function AiTreeRenderer({
|
|
|
9635
9779
|
// standalone resolve), so generated galleries, image rows, and overlay backgrounds arrive with
|
|
9636
9780
|
// photos instead of grey boxes.
|
|
9637
9781
|
resolveMedia: (ref) => resolveMedia?.(ref) ?? placeholderMap[ref] ?? resolvePlaceholderRef(ref),
|
|
9638
|
-
cardSurface:
|
|
9782
|
+
cardSurface: resolvedBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${blockBrand.palette.light} 90%, ${blockBrand.palette.dark})`,
|
|
9639
9783
|
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
|
|
9640
9784
|
sectionAlignment: (tree.settings ?? {}).alignment === "center" ? "center" : "left",
|
|
9641
9785
|
buttonStyle,
|
|
@@ -9652,7 +9796,7 @@ function AiTreeRenderer({
|
|
|
9652
9796
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
9653
9797
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
9654
9798
|
const toneBackground = (() => {
|
|
9655
|
-
const { dark, primary, light } =
|
|
9799
|
+
const { dark, primary, light } = blockBrand.palette;
|
|
9656
9800
|
switch (settings.sectionBackground) {
|
|
9657
9801
|
case "surface":
|
|
9658
9802
|
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
@@ -9742,7 +9886,7 @@ function AiTreeRenderer({
|
|
|
9742
9886
|
// its own horizontal `align`, which takes priority for that block.
|
|
9743
9887
|
...fillHeight ? { display: "grid" } : {},
|
|
9744
9888
|
// Horizontal placement of the block's content within its column.
|
|
9745
|
-
...cellAlignStyle(block.align),
|
|
9889
|
+
...fullBleedBlock(block) ? {} : cellAlignStyle(block.align),
|
|
9746
9890
|
// space-between: each column becomes a flex column whose content spreads over
|
|
9747
9891
|
// the full row height instead of clumping at the top.
|
|
9748
9892
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -9773,14 +9917,15 @@ function AiFooterRenderer({
|
|
|
9773
9917
|
if (!isRenderableFooterTree(tree)) {
|
|
9774
9918
|
return null;
|
|
9775
9919
|
}
|
|
9776
|
-
const
|
|
9920
|
+
const hexBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
9921
|
+
const resolvedBrand = withLivePalette(hexBrand, brand ?? AI_DEFAULT_BRAND);
|
|
9777
9922
|
const bandBg = surface?.background ?? resolvedBrand.palette.dark;
|
|
9778
9923
|
const bandText = surface?.text ?? resolvedBrand.palette.light;
|
|
9779
9924
|
const onDark = surface ? isDarkColor(surface.background) : true;
|
|
9780
9925
|
const ctx = {
|
|
9781
9926
|
brand: resolvedBrand,
|
|
9782
9927
|
resolveMedia: (ref) => resolveMedia?.(ref) ?? resolvePlaceholderRef(ref),
|
|
9783
|
-
cardSurface:
|
|
9928
|
+
cardSurface: hexBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${resolvedBrand.palette.light} 90%, ${resolvedBrand.palette.dark})`,
|
|
9784
9929
|
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
|
|
9785
9930
|
logoUrl: logoUrl ?? null,
|
|
9786
9931
|
resolvePageHref
|
|
@@ -10356,10 +10501,9 @@ function syncSoftRemovedGenerated() {
|
|
|
10356
10501
|
}
|
|
10357
10502
|
function applyAiSectionsToDom(state, options) {
|
|
10358
10503
|
if (typeof document === "undefined") return;
|
|
10359
|
-
const brandOverride = deriveBrandOverride();
|
|
10360
10504
|
const templateBrand = deriveTemplateBrand();
|
|
10361
10505
|
const templateButtonStyle = deriveTemplateButtonStyle();
|
|
10362
|
-
const brandKey =
|
|
10506
|
+
const brandKey = JSON.stringify(getAppliedBrand() ?? deriveBrandOverride() ?? null);
|
|
10363
10507
|
const pagePath = window.location.pathname;
|
|
10364
10508
|
const pageSections = state.sections.filter((entry) => (entry.path ?? "/") === pagePath);
|
|
10365
10509
|
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
@@ -10402,7 +10546,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10402
10546
|
AiTreeRenderer,
|
|
10403
10547
|
{
|
|
10404
10548
|
tree: entry.tree,
|
|
10405
|
-
brand:
|
|
10549
|
+
brand: brandForGenerated(deriveBrandOverride() ?? entry.brand ?? options?.brand ?? templateBrand),
|
|
10406
10550
|
buttonStyle: templateButtonStyle,
|
|
10407
10551
|
resolveMedia,
|
|
10408
10552
|
editKeyPrefix: `ai.${entry.id}`
|
|
@@ -10568,7 +10712,7 @@ function applyAiFooterToDom(state, content) {
|
|
|
10568
10712
|
const templateFooter = findTemplateFooter();
|
|
10569
10713
|
captureTemplateFooterSurface(templateFooter);
|
|
10570
10714
|
const surface = capturedSurface ?? null;
|
|
10571
|
-
const brand = mountOptions.brand ?? deriveTemplateBrand();
|
|
10715
|
+
const brand = brandForGenerated(mountOptions.brand ?? deriveTemplateBrand());
|
|
10572
10716
|
const logoUrl = resolveLogoFromContent(content, templateFooter);
|
|
10573
10717
|
const serialized = JSON.stringify(state) + JSON.stringify(brand ?? null) + (logoUrl ?? "") + JSON.stringify(surface) + JSON.stringify(defaultLegal());
|
|
10574
10718
|
if (mounted2 && mounted2.serialized === serialized && mounted2.container.isConnected) {
|
|
@@ -18376,10 +18520,23 @@ function setPricingCardStyle(tree, index, style) {
|
|
|
18376
18520
|
});
|
|
18377
18521
|
}
|
|
18378
18522
|
function setPricingCardFeaturedTag(tree, index, on) {
|
|
18379
|
-
return
|
|
18523
|
+
return withPricingCollection(tree, (collection) => {
|
|
18524
|
+
const children = collection.children;
|
|
18525
|
+
if (index < 0 || index >= children.length) return false;
|
|
18526
|
+
if (on) {
|
|
18527
|
+
children.forEach((card, i) => {
|
|
18528
|
+
if (i === index) return;
|
|
18529
|
+
const prev2 = featuredOf(card);
|
|
18530
|
+
if (prev2.enabled !== true || badgeOf(prev2).length === 0) return;
|
|
18531
|
+
card.slots = card.slots ?? {};
|
|
18532
|
+
card.slots.featured = composeFeatured(pricingCardStyleOf(prev2), false, badgeOf(prev2));
|
|
18533
|
+
});
|
|
18534
|
+
}
|
|
18535
|
+
const target = children[index];
|
|
18536
|
+
target.slots = target.slots ?? {};
|
|
18380
18537
|
const prev = featuredOf(target);
|
|
18381
|
-
|
|
18382
|
-
|
|
18538
|
+
target.slots.featured = composeFeatured(pricingCardStyleOf(prev), on, badgeOf(prev));
|
|
18539
|
+
return true;
|
|
18383
18540
|
});
|
|
18384
18541
|
}
|
|
18385
18542
|
function pricingCardStyleOf(featured) {
|
|
@@ -18629,25 +18786,40 @@ function ToolbarSeparator() {
|
|
|
18629
18786
|
}
|
|
18630
18787
|
function CardStyleMenu({
|
|
18631
18788
|
value,
|
|
18632
|
-
onChange
|
|
18789
|
+
onChange,
|
|
18790
|
+
disabled = false
|
|
18633
18791
|
}) {
|
|
18634
18792
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18793
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18794
|
+
"button",
|
|
18795
|
+
{
|
|
18796
|
+
type: "button",
|
|
18797
|
+
"aria-label": "Card style",
|
|
18798
|
+
disabled,
|
|
18799
|
+
className: cn(
|
|
18800
|
+
"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",
|
|
18801
|
+
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
18802
|
+
),
|
|
18803
|
+
children: [
|
|
18804
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
18805
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18806
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18807
|
+
]
|
|
18808
|
+
}
|
|
18809
|
+
);
|
|
18810
|
+
if (disabled) {
|
|
18811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18812
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
18813
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18814
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
18815
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
18816
|
+
] })
|
|
18817
|
+
] });
|
|
18818
|
+
}
|
|
18635
18819
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18636
18820
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
18637
18821
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
|
|
18638
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children:
|
|
18639
|
-
"button",
|
|
18640
|
-
{
|
|
18641
|
-
type: "button",
|
|
18642
|
-
"aria-label": "Card style",
|
|
18643
|
-
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",
|
|
18644
|
-
children: [
|
|
18645
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
18646
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18647
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18648
|
-
]
|
|
18649
|
-
}
|
|
18650
|
-
) }),
|
|
18822
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
18651
18823
|
/* @__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) => {
|
|
18652
18824
|
const selected = style.value === value;
|
|
18653
18825
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
@@ -18711,23 +18883,35 @@ function PricingCardToolbar({
|
|
|
18711
18883
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18712
18884
|
),
|
|
18713
18885
|
children: [
|
|
18714
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle }),
|
|
18715
18886
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18716
18887
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18717
18888
|
CustomToolbarButton,
|
|
18718
18889
|
{
|
|
18719
18890
|
type: "button",
|
|
18720
|
-
"aria-label": featuredTag ? "
|
|
18891
|
+
"aria-label": featuredTag ? "Unmark as featured" : "Mark as featured",
|
|
18721
18892
|
"aria-pressed": featuredTag,
|
|
18722
|
-
active: featuredTag,
|
|
18723
18893
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
18724
|
-
className: "size-8",
|
|
18725
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18894
|
+
className: "group size-8",
|
|
18895
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18896
|
+
import_lucide_react9.Star,
|
|
18897
|
+
{
|
|
18898
|
+
size: 16,
|
|
18899
|
+
fill: "currentColor",
|
|
18900
|
+
strokeWidth: 0,
|
|
18901
|
+
className: cn(
|
|
18902
|
+
"transition-colors",
|
|
18903
|
+
featuredTag ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
|
|
18904
|
+
),
|
|
18905
|
+
style: { pointerEvents: "none" }
|
|
18906
|
+
}
|
|
18907
|
+
)
|
|
18726
18908
|
}
|
|
18727
18909
|
) }),
|
|
18728
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "
|
|
18910
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
18729
18911
|
] }),
|
|
18730
18912
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18913
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
18914
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18731
18915
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}) }),
|
|
18732
18916
|
/* @__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: [
|
|
18733
18917
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}),
|
|
@@ -18870,7 +19054,12 @@ function AiPricingCardOverlay({
|
|
|
18870
19054
|
index: active.index,
|
|
18871
19055
|
pending,
|
|
18872
19056
|
error,
|
|
18873
|
-
onAddTier: () =>
|
|
19057
|
+
onAddTier: () => {
|
|
19058
|
+
const newIndex = pricingCardCount(activeEntry.tree);
|
|
19059
|
+
void runMutation(active.sectionId, addPricingTier).then((applied) => {
|
|
19060
|
+
if (applied) setActive({ sectionId: active.sectionId, index: newIndex });
|
|
19061
|
+
});
|
|
19062
|
+
},
|
|
18874
19063
|
onRemoveTier: () => {
|
|
18875
19064
|
void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
|
|
18876
19065
|
(applied) => {
|
|
@@ -27281,7 +27470,7 @@ function OhhwellsBridge() {
|
|
|
27281
27470
|
if (!subdomain) return {};
|
|
27282
27471
|
return contentCache.get(subdomain) ?? {};
|
|
27283
27472
|
};
|
|
27284
|
-
const observeRoots = () => [document.querySelector("nav"),
|
|
27473
|
+
const observeRoots = () => [document.querySelector("nav"), getFooterRoot()].filter(
|
|
27285
27474
|
(el) => Boolean(el)
|
|
27286
27475
|
);
|
|
27287
27476
|
const roots = observeRoots();
|
|
@@ -27752,7 +27941,7 @@ function OhhwellsBridge() {
|
|
|
27752
27941
|
{
|
|
27753
27942
|
const formEl = getFormElement(target);
|
|
27754
27943
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
27755
|
-
if (formEl && formKeyOf(formEl) && !onSuccessText) {
|
|
27944
|
+
if (formEl && formKeyOf(formEl) && !onSuccessText && !isCtaButton(target)) {
|
|
27756
27945
|
const fieldEl = getFieldWrapper(target);
|
|
27757
27946
|
if (fieldEl) {
|
|
27758
27947
|
const label = target.closest("label");
|
|
@@ -29645,6 +29834,7 @@ function OhhwellsBridge() {
|
|
|
29645
29834
|
brandKitRef.current = value;
|
|
29646
29835
|
applyBrandToDom(parseBrandKit(value));
|
|
29647
29836
|
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
29837
|
+
applyAiFooterFromContent(editContentRef.current);
|
|
29648
29838
|
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
29649
29839
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
29650
29840
|
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
@@ -30276,9 +30466,10 @@ function OhhwellsBridge() {
|
|
|
30276
30466
|
if (e.data?.type !== "ow:collect-section") return;
|
|
30277
30467
|
const sectionId = e.data.sectionId;
|
|
30278
30468
|
if (typeof sectionId !== "string" || !sectionId) return;
|
|
30279
|
-
const
|
|
30469
|
+
const foundEl = document.querySelector(
|
|
30280
30470
|
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
30281
30471
|
);
|
|
30472
|
+
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;
|
|
30282
30473
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
30283
30474
|
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
30284
30475
|
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
@@ -31017,7 +31208,7 @@ function OhhwellsBridge() {
|
|
|
31017
31208
|
postToParent2({
|
|
31018
31209
|
type: "ow:ready",
|
|
31019
31210
|
version: "1",
|
|
31020
|
-
bridgeVersion: "0.1.
|
|
31211
|
+
bridgeVersion: "0.1.140",
|
|
31021
31212
|
path: pathname,
|
|
31022
31213
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31023
31214
|
sections
|
|
@@ -32233,6 +32424,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32233
32424
|
dropIndicatorVariants,
|
|
32234
32425
|
ensureFooterTree,
|
|
32235
32426
|
filterAvailablePages,
|
|
32427
|
+
foldAlignIntoTrees,
|
|
32236
32428
|
getEditModeInitialState,
|
|
32237
32429
|
insertFooterHours,
|
|
32238
32430
|
isEditSessionActive,
|
|
@@ -32241,6 +32433,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32241
32433
|
isValidUrl,
|
|
32242
32434
|
nextViableSlide,
|
|
32243
32435
|
parseAiFooterState,
|
|
32436
|
+
parseAiSectionsState,
|
|
32244
32437
|
parseTarget,
|
|
32245
32438
|
removeFooterBlock,
|
|
32246
32439
|
resolveFooterCopyright,
|