@ohhwells/bridge 0.1.140 → 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 +184 -52
- 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 +182 -52
- 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,
|
|
@@ -5296,19 +5298,21 @@ function findIndexSegment(keys) {
|
|
|
5296
5298
|
if (len < 2 || tokenLists.some((t) => t.length !== len)) return null;
|
|
5297
5299
|
let position = -1;
|
|
5298
5300
|
for (let p = 0; p < len; p++) {
|
|
5299
|
-
const
|
|
5300
|
-
const allSame =
|
|
5301
|
+
const values2 = tokenLists.map((t) => t[p]);
|
|
5302
|
+
const allSame = values2.every((v) => v === values2[0]);
|
|
5301
5303
|
if (allSame) continue;
|
|
5302
|
-
|
|
5303
|
-
if (!allNumeric || position !== -1) return null;
|
|
5304
|
+
if (position !== -1) return null;
|
|
5304
5305
|
position = p;
|
|
5305
5306
|
}
|
|
5306
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;
|
|
5307
5312
|
const group = tokenLists[0].slice(0, position).join("-");
|
|
5308
5313
|
if (!group) return null;
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
return { position, group };
|
|
5314
|
+
if (new Set(values).size !== values.length) return null;
|
|
5315
|
+
return numericCount === values.length ? { position, group } : { position, group, slug: true };
|
|
5312
5316
|
}
|
|
5313
5317
|
function singleIndexSegment(key) {
|
|
5314
5318
|
const tokens = baseKey(key).split("-");
|
|
@@ -5354,7 +5358,19 @@ function detectItemGroups(sectionEl) {
|
|
|
5354
5358
|
list.push(m);
|
|
5355
5359
|
byShape.set(shape, list);
|
|
5356
5360
|
}
|
|
5357
|
-
|
|
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()));
|
|
5358
5374
|
}
|
|
5359
5375
|
for (const members of clusters) {
|
|
5360
5376
|
const keyedPerMember = members.map((m) => keyedDescendants(m));
|
|
@@ -5365,11 +5381,28 @@ function detectItemGroups(sectionEl) {
|
|
|
5365
5381
|
const dedupeKey = `${segment.group}`;
|
|
5366
5382
|
if (seenParents.has(dedupeKey)) continue;
|
|
5367
5383
|
seenParents.add(dedupeKey);
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
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
|
+
}
|
|
5373
5406
|
groups.push({ group: segment.group, parent, nested: false, items });
|
|
5374
5407
|
}
|
|
5375
5408
|
}
|
|
@@ -5493,6 +5526,18 @@ function rekeyItemClone(clone, source, sibling, group, newIndex) {
|
|
|
5493
5526
|
const delta = newIndex - source.index;
|
|
5494
5527
|
const cloneKeyed = keyedDescendants(clone);
|
|
5495
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
|
+
}
|
|
5496
5541
|
source.keyed.forEach((src, i) => {
|
|
5497
5542
|
const target = cloneKeyed[i];
|
|
5498
5543
|
if (!target || target.attr !== src.attr) return;
|
|
@@ -5536,7 +5581,12 @@ function syncGroup(detected, state) {
|
|
|
5536
5581
|
clone.setAttribute(ITEM_ATTR, `${detected.group}:${entry.index}`);
|
|
5537
5582
|
rekeyItemClone(clone, source, sibling, detected.group, entry.index);
|
|
5538
5583
|
source.el.insertAdjacentElement("afterend", clone);
|
|
5539
|
-
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
|
+
});
|
|
5540
5590
|
}
|
|
5541
5591
|
const listed = state.items.map((e) => byIndex.get(e.index)?.el).filter((el) => !!el);
|
|
5542
5592
|
let prev = null;
|
|
@@ -5638,9 +5688,16 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5638
5688
|
const nodes = [];
|
|
5639
5689
|
const added = [];
|
|
5640
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);
|
|
5641
5693
|
for (const add of ops.add ?? []) {
|
|
5642
5694
|
const sourceEl = elements.get(add.cloneOf);
|
|
5643
|
-
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;
|
|
5644
5701
|
if (!source) continue;
|
|
5645
5702
|
const newIndex = Math.max(...state.items.map((e) => e.index), ...detected.items.map((i) => i.index)) + 1;
|
|
5646
5703
|
const sibling = detected.items.find((item) => item.index !== add.cloneOf && !item.el.hasAttribute(ITEM_CLONE_ATTR)) ?? null;
|
|
@@ -5667,7 +5724,12 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5667
5724
|
if (anchor) anchor.insertAdjacentElement("afterend", clone);
|
|
5668
5725
|
else source.el.insertAdjacentElement("afterend", clone);
|
|
5669
5726
|
elements.set(newIndex, clone);
|
|
5670
|
-
detected.items.push({
|
|
5727
|
+
detected.items.push({
|
|
5728
|
+
el: clone,
|
|
5729
|
+
index: newIndex,
|
|
5730
|
+
keyed: cloneKeyed,
|
|
5731
|
+
...sluggy ? { slugToken: `x${newIndex}` } : {}
|
|
5732
|
+
});
|
|
5671
5733
|
added.push(newIndex);
|
|
5672
5734
|
elements = syncGroup(detected, state);
|
|
5673
5735
|
}
|
|
@@ -6110,16 +6172,25 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6110
6172
|
nextTrees.set(id, fresh);
|
|
6111
6173
|
return fresh;
|
|
6112
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;
|
|
6113
6182
|
const nodes = {};
|
|
6114
6183
|
for (const [key, override] of Object.entries(store.nodes)) {
|
|
6115
6184
|
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
6116
6185
|
const tree = match ? treeFor(match[1]) : void 0;
|
|
6117
|
-
const
|
|
6118
|
-
|
|
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) {
|
|
6119
6190
|
nodes[key] = override;
|
|
6120
6191
|
continue;
|
|
6121
6192
|
}
|
|
6122
|
-
|
|
6193
|
+
row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
|
|
6123
6194
|
const rest = { ...override };
|
|
6124
6195
|
delete rest.align;
|
|
6125
6196
|
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
@@ -6132,7 +6203,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6132
6203
|
continue;
|
|
6133
6204
|
}
|
|
6134
6205
|
for (const row of tree.rows) {
|
|
6135
|
-
|
|
6206
|
+
row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
|
|
6136
6207
|
}
|
|
6137
6208
|
const rest = { ...override };
|
|
6138
6209
|
delete rest.align;
|
|
@@ -7293,6 +7364,7 @@ var blockAlignStyle = (blockAlign) => blockAlign ? {
|
|
|
7293
7364
|
alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
|
|
7294
7365
|
textAlign: blockAlign
|
|
7295
7366
|
} : {};
|
|
7367
|
+
var fullBleedBlock = (block) => block.type === "carousel" || block.type === "group" && str(block.slots?.layout) === "overlap";
|
|
7296
7368
|
var featureLines = (value) => value.split(/\n|<br\s*\/?>/i).map((line) => line.trim()).filter(Boolean);
|
|
7297
7369
|
var AI_MOBILE_CSS = [
|
|
7298
7370
|
// Unscoped (applies at every viewport, not just mobile): re-enables pointer-events for the
|
|
@@ -9358,8 +9430,8 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9358
9430
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9359
9431
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9360
9432
|
// the full section width instead of reading at the usual content width.
|
|
9361
|
-
/* @__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") })
|
|
9362
|
-
) : 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),
|
|
9363
9435
|
i === 0 && needsBaseScrim && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9364
9436
|
"div",
|
|
9365
9437
|
{
|
|
@@ -9392,7 +9464,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9392
9464
|
// child otherwise stretches full-width (unchanged pre-existing behaviour).
|
|
9393
9465
|
...blockAlignStyle(child.align ?? ambientAlign)
|
|
9394
9466
|
},
|
|
9395
|
-
children: renderNode(child, ctx, `${path}.c${i}`, ambientAlign)
|
|
9467
|
+
children: renderNode(child, ctx, `${path}.c${i}`, node.align ?? ambientAlign)
|
|
9396
9468
|
},
|
|
9397
9469
|
i
|
|
9398
9470
|
));
|
|
@@ -9422,8 +9494,20 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9422
9494
|
}
|
|
9423
9495
|
case "button":
|
|
9424
9496
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ButtonEl, { slots, ctx, path });
|
|
9425
|
-
case "button-row":
|
|
9426
|
-
|
|
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
|
+
}
|
|
9427
9511
|
case "media":
|
|
9428
9512
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9429
9513
|
MediaBox,
|
|
@@ -9802,7 +9886,7 @@ function AiTreeRenderer({
|
|
|
9802
9886
|
// its own horizontal `align`, which takes priority for that block.
|
|
9803
9887
|
...fillHeight ? { display: "grid" } : {},
|
|
9804
9888
|
// Horizontal placement of the block's content within its column.
|
|
9805
|
-
...cellAlignStyle(block.align),
|
|
9889
|
+
...fullBleedBlock(block) ? {} : cellAlignStyle(block.align),
|
|
9806
9890
|
// space-between: each column becomes a flex column whose content spreads over
|
|
9807
9891
|
// the full row height instead of clumping at the top.
|
|
9808
9892
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -18436,10 +18520,23 @@ function setPricingCardStyle(tree, index, style) {
|
|
|
18436
18520
|
});
|
|
18437
18521
|
}
|
|
18438
18522
|
function setPricingCardFeaturedTag(tree, index, on) {
|
|
18439
|
-
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 ?? {};
|
|
18440
18537
|
const prev = featuredOf(target);
|
|
18441
|
-
|
|
18442
|
-
|
|
18538
|
+
target.slots.featured = composeFeatured(pricingCardStyleOf(prev), on, badgeOf(prev));
|
|
18539
|
+
return true;
|
|
18443
18540
|
});
|
|
18444
18541
|
}
|
|
18445
18542
|
function pricingCardStyleOf(featured) {
|
|
@@ -18689,25 +18786,40 @@ function ToolbarSeparator() {
|
|
|
18689
18786
|
}
|
|
18690
18787
|
function CardStyleMenu({
|
|
18691
18788
|
value,
|
|
18692
|
-
onChange
|
|
18789
|
+
onChange,
|
|
18790
|
+
disabled = false
|
|
18693
18791
|
}) {
|
|
18694
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
|
+
}
|
|
18695
18819
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18696
18820
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
18697
18821
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
|
|
18698
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children:
|
|
18699
|
-
"button",
|
|
18700
|
-
{
|
|
18701
|
-
type: "button",
|
|
18702
|
-
"aria-label": "Card style",
|
|
18703
|
-
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",
|
|
18704
|
-
children: [
|
|
18705
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
18706
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18707
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18708
|
-
]
|
|
18709
|
-
}
|
|
18710
|
-
) }),
|
|
18822
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
18711
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) => {
|
|
18712
18824
|
const selected = style.value === value;
|
|
18713
18825
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
@@ -18771,23 +18883,35 @@ function PricingCardToolbar({
|
|
|
18771
18883
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18772
18884
|
),
|
|
18773
18885
|
children: [
|
|
18774
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle }),
|
|
18775
18886
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18776
18887
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18777
18888
|
CustomToolbarButton,
|
|
18778
18889
|
{
|
|
18779
18890
|
type: "button",
|
|
18780
|
-
"aria-label": featuredTag ? "
|
|
18891
|
+
"aria-label": featuredTag ? "Unmark as featured" : "Mark as featured",
|
|
18781
18892
|
"aria-pressed": featuredTag,
|
|
18782
|
-
active: featuredTag,
|
|
18783
18893
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
18784
|
-
className: "size-8",
|
|
18785
|
-
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
|
+
)
|
|
18786
18908
|
}
|
|
18787
18909
|
) }),
|
|
18788
|
-
/* @__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" })
|
|
18789
18911
|
] }),
|
|
18790
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, {}),
|
|
18791
18915
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}) }),
|
|
18792
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: [
|
|
18793
18917
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}),
|
|
@@ -18930,7 +19054,12 @@ function AiPricingCardOverlay({
|
|
|
18930
19054
|
index: active.index,
|
|
18931
19055
|
pending,
|
|
18932
19056
|
error,
|
|
18933
|
-
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
|
+
},
|
|
18934
19063
|
onRemoveTier: () => {
|
|
18935
19064
|
void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
|
|
18936
19065
|
(applied) => {
|
|
@@ -30337,9 +30466,10 @@ function OhhwellsBridge() {
|
|
|
30337
30466
|
if (e.data?.type !== "ow:collect-section") return;
|
|
30338
30467
|
const sectionId = e.data.sectionId;
|
|
30339
30468
|
if (typeof sectionId !== "string" || !sectionId) return;
|
|
30340
|
-
const
|
|
30469
|
+
const foundEl = document.querySelector(
|
|
30341
30470
|
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
30342
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;
|
|
30343
30473
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
30344
30474
|
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
30345
30475
|
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
@@ -31078,7 +31208,7 @@ function OhhwellsBridge() {
|
|
|
31078
31208
|
postToParent2({
|
|
31079
31209
|
type: "ow:ready",
|
|
31080
31210
|
version: "1",
|
|
31081
|
-
bridgeVersion: "0.1.
|
|
31211
|
+
bridgeVersion: "0.1.140",
|
|
31082
31212
|
path: pathname,
|
|
31083
31213
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31084
31214
|
sections
|
|
@@ -32294,6 +32424,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32294
32424
|
dropIndicatorVariants,
|
|
32295
32425
|
ensureFooterTree,
|
|
32296
32426
|
filterAvailablePages,
|
|
32427
|
+
foldAlignIntoTrees,
|
|
32297
32428
|
getEditModeInitialState,
|
|
32298
32429
|
insertFooterHours,
|
|
32299
32430
|
isEditSessionActive,
|
|
@@ -32302,6 +32433,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32302
32433
|
isValidUrl,
|
|
32303
32434
|
nextViableSlide,
|
|
32304
32435
|
parseAiFooterState,
|
|
32436
|
+
parseAiSectionsState,
|
|
32305
32437
|
parseTarget,
|
|
32306
32438
|
removeFooterBlock,
|
|
32307
32439
|
resolveFooterCopyright,
|