@ohhwells/bridge 0.1.140 → 0.1.142
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 +224 -81
- 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 +222 -81
- package/dist/index.js.map +1 -1
- package/dist/styles.css +19 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1256,15 +1256,25 @@ function readAssignments(content) {
|
|
|
1256
1256
|
function cssLength(style, prop) {
|
|
1257
1257
|
return style.getPropertyValue(prop) || "0px";
|
|
1258
1258
|
}
|
|
1259
|
+
function withTransitionsSettled(el, read) {
|
|
1260
|
+
const prior = el.style.getPropertyValue("transition");
|
|
1261
|
+
const priority = el.style.getPropertyPriority("transition");
|
|
1262
|
+
el.style.setProperty("transition", "none", "important");
|
|
1263
|
+
try {
|
|
1264
|
+
return read(getComputedStyle(el));
|
|
1265
|
+
} finally {
|
|
1266
|
+
if (prior) el.style.setProperty("transition", prior, priority);
|
|
1267
|
+
else el.style.removeProperty("transition");
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1259
1270
|
function readVariantSample(el) {
|
|
1260
|
-
|
|
1261
|
-
return {
|
|
1271
|
+
return withTransitionsSettled(el, (style) => ({
|
|
1262
1272
|
background: style.backgroundColor,
|
|
1263
1273
|
color: style.color,
|
|
1264
1274
|
borderColor: style.borderTopColor,
|
|
1265
1275
|
borderWidth: style.borderTopWidth,
|
|
1266
1276
|
className: el.className || ""
|
|
1267
|
-
};
|
|
1277
|
+
}));
|
|
1268
1278
|
}
|
|
1269
1279
|
function readSizeSample(el) {
|
|
1270
1280
|
const style = getComputedStyle(el);
|
|
@@ -5204,19 +5214,21 @@ function findIndexSegment(keys) {
|
|
|
5204
5214
|
if (len < 2 || tokenLists.some((t) => t.length !== len)) return null;
|
|
5205
5215
|
let position = -1;
|
|
5206
5216
|
for (let p = 0; p < len; p++) {
|
|
5207
|
-
const
|
|
5208
|
-
const allSame =
|
|
5217
|
+
const values2 = tokenLists.map((t) => t[p]);
|
|
5218
|
+
const allSame = values2.every((v) => v === values2[0]);
|
|
5209
5219
|
if (allSame) continue;
|
|
5210
|
-
|
|
5211
|
-
if (!allNumeric || position !== -1) return null;
|
|
5220
|
+
if (position !== -1) return null;
|
|
5212
5221
|
position = p;
|
|
5213
5222
|
}
|
|
5214
5223
|
if (position === -1) return null;
|
|
5224
|
+
const values = tokenLists.map((t) => t[position]);
|
|
5225
|
+
const numericCount = values.filter((v) => /^\d+$/.test(v)).length;
|
|
5226
|
+
if (numericCount !== 0 && numericCount !== values.length) return null;
|
|
5227
|
+
if (numericCount === 0 && position === len - 1) return null;
|
|
5215
5228
|
const group = tokenLists[0].slice(0, position).join("-");
|
|
5216
5229
|
if (!group) return null;
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
return { position, group };
|
|
5230
|
+
if (new Set(values).size !== values.length) return null;
|
|
5231
|
+
return numericCount === values.length ? { position, group } : { position, group, slug: true };
|
|
5220
5232
|
}
|
|
5221
5233
|
function singleIndexSegment(key) {
|
|
5222
5234
|
const tokens = baseKey(key).split("-");
|
|
@@ -5262,7 +5274,19 @@ function detectItemGroups(sectionEl) {
|
|
|
5262
5274
|
list.push(m);
|
|
5263
5275
|
byShape.set(shape, list);
|
|
5264
5276
|
}
|
|
5265
|
-
|
|
5277
|
+
const shaped = Array.from(byShape.values());
|
|
5278
|
+
clusters.push(...shaped.filter((c) => c.length >= 2));
|
|
5279
|
+
const singles = shaped.filter((c) => c.length === 1).map((c) => c[0]);
|
|
5280
|
+
const bySlugShape = /* @__PURE__ */ new Map();
|
|
5281
|
+
for (const m of singles) {
|
|
5282
|
+
const primary = primaryKey(keyedDescendants(m));
|
|
5283
|
+
const tokens = baseKey(primary ?? "").split("-");
|
|
5284
|
+
const slugShape = `${tokens.length}|${tokens[0]}|${tokens[tokens.length - 1]}`;
|
|
5285
|
+
const list = bySlugShape.get(slugShape) ?? [];
|
|
5286
|
+
list.push(m);
|
|
5287
|
+
bySlugShape.set(slugShape, list);
|
|
5288
|
+
}
|
|
5289
|
+
clusters.push(...Array.from(bySlugShape.values()));
|
|
5266
5290
|
}
|
|
5267
5291
|
for (const members of clusters) {
|
|
5268
5292
|
const keyedPerMember = members.map((m) => keyedDescendants(m));
|
|
@@ -5273,11 +5297,28 @@ function detectItemGroups(sectionEl) {
|
|
|
5273
5297
|
const dedupeKey = `${segment.group}`;
|
|
5274
5298
|
if (seenParents.has(dedupeKey)) continue;
|
|
5275
5299
|
seenParents.add(dedupeKey);
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5300
|
+
let items;
|
|
5301
|
+
if (segment.slug) {
|
|
5302
|
+
const tokens = members.map((_, i) => baseKey(primaries[i]).split("-")[segment.position]);
|
|
5303
|
+
let nextOriginal = 1;
|
|
5304
|
+
const indices = tokens.map((t) => {
|
|
5305
|
+
const cloneMatch = t.match(/^x(\d+)$/);
|
|
5306
|
+
return cloneMatch ? parseInt(cloneMatch[1], 10) : nextOriginal++;
|
|
5307
|
+
});
|
|
5308
|
+
if (new Set(indices).size !== indices.length) continue;
|
|
5309
|
+
items = members.map((el, i) => ({
|
|
5310
|
+
el,
|
|
5311
|
+
index: indices[i],
|
|
5312
|
+
keyed: keyedPerMember[i],
|
|
5313
|
+
slugToken: tokens[i]
|
|
5314
|
+
}));
|
|
5315
|
+
} else {
|
|
5316
|
+
items = members.map((el, i) => ({
|
|
5317
|
+
el,
|
|
5318
|
+
index: indexFromKey(primaries[i], segment.position),
|
|
5319
|
+
keyed: keyedPerMember[i]
|
|
5320
|
+
}));
|
|
5321
|
+
}
|
|
5281
5322
|
groups.push({ group: segment.group, parent, nested: false, items });
|
|
5282
5323
|
}
|
|
5283
5324
|
}
|
|
@@ -5401,6 +5442,18 @@ function rekeyItemClone(clone, source, sibling, group, newIndex) {
|
|
|
5401
5442
|
const delta = newIndex - source.index;
|
|
5402
5443
|
const cloneKeyed = keyedDescendants(clone);
|
|
5403
5444
|
const pairs = [];
|
|
5445
|
+
if (source.slugToken) {
|
|
5446
|
+
source.keyed.forEach((src, i) => {
|
|
5447
|
+
const target = cloneKeyed[i];
|
|
5448
|
+
if (!target || target.attr !== src.attr) return;
|
|
5449
|
+
const tokens = baseKey(src.key).split("-");
|
|
5450
|
+
if (!tokens.includes(source.slugToken)) return;
|
|
5451
|
+
const next = tokens.map((t) => t === source.slugToken ? `x${newIndex}` : t).join("-") + keySuffix(src.key);
|
|
5452
|
+
target.el.setAttribute(src.attr, next);
|
|
5453
|
+
pairs.push({ from: src.key, to: next });
|
|
5454
|
+
});
|
|
5455
|
+
return pairs;
|
|
5456
|
+
}
|
|
5404
5457
|
source.keyed.forEach((src, i) => {
|
|
5405
5458
|
const target = cloneKeyed[i];
|
|
5406
5459
|
if (!target || target.attr !== src.attr) return;
|
|
@@ -5444,7 +5497,12 @@ function syncGroup(detected, state) {
|
|
|
5444
5497
|
clone.setAttribute(ITEM_ATTR, `${detected.group}:${entry.index}`);
|
|
5445
5498
|
rekeyItemClone(clone, source, sibling, detected.group, entry.index);
|
|
5446
5499
|
source.el.insertAdjacentElement("afterend", clone);
|
|
5447
|
-
byIndex.set(entry.index, {
|
|
5500
|
+
byIndex.set(entry.index, {
|
|
5501
|
+
el: clone,
|
|
5502
|
+
index: entry.index,
|
|
5503
|
+
keyed: keyedDescendants(clone),
|
|
5504
|
+
...source.slugToken ? { slugToken: `x${entry.index}` } : {}
|
|
5505
|
+
});
|
|
5448
5506
|
}
|
|
5449
5507
|
const listed = state.items.map((e) => byIndex.get(e.index)?.el).filter((el) => !!el);
|
|
5450
5508
|
let prev = null;
|
|
@@ -5546,9 +5604,16 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5546
5604
|
const nodes = [];
|
|
5547
5605
|
const added = [];
|
|
5548
5606
|
let elements = syncGroup(detected, state);
|
|
5607
|
+
const sluggy = detected.items.some((item) => item.slugToken);
|
|
5608
|
+
const slugTokenOf = (index) => detected.items.find((item) => item.index === index)?.slugToken ?? (sluggy ? `x${index}` : void 0);
|
|
5549
5609
|
for (const add of ops.add ?? []) {
|
|
5550
5610
|
const sourceEl = elements.get(add.cloneOf);
|
|
5551
|
-
const source = sourceEl ? {
|
|
5611
|
+
const source = sourceEl ? {
|
|
5612
|
+
el: sourceEl,
|
|
5613
|
+
index: add.cloneOf,
|
|
5614
|
+
keyed: keyedDescendants(sourceEl),
|
|
5615
|
+
...slugTokenOf(add.cloneOf) ? { slugToken: slugTokenOf(add.cloneOf) } : {}
|
|
5616
|
+
} : void 0;
|
|
5552
5617
|
if (!source) continue;
|
|
5553
5618
|
const newIndex = Math.max(...state.items.map((e) => e.index), ...detected.items.map((i) => i.index)) + 1;
|
|
5554
5619
|
const sibling = detected.items.find((item) => item.index !== add.cloneOf && !item.el.hasAttribute(ITEM_CLONE_ATTR)) ?? null;
|
|
@@ -5575,7 +5640,12 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5575
5640
|
if (anchor) anchor.insertAdjacentElement("afterend", clone);
|
|
5576
5641
|
else source.el.insertAdjacentElement("afterend", clone);
|
|
5577
5642
|
elements.set(newIndex, clone);
|
|
5578
|
-
detected.items.push({
|
|
5643
|
+
detected.items.push({
|
|
5644
|
+
el: clone,
|
|
5645
|
+
index: newIndex,
|
|
5646
|
+
keyed: cloneKeyed,
|
|
5647
|
+
...sluggy ? { slugToken: `x${newIndex}` } : {}
|
|
5648
|
+
});
|
|
5579
5649
|
added.push(newIndex);
|
|
5580
5650
|
elements = syncGroup(detected, state);
|
|
5581
5651
|
}
|
|
@@ -6018,16 +6088,25 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6018
6088
|
nextTrees.set(id, fresh);
|
|
6019
6089
|
return fresh;
|
|
6020
6090
|
};
|
|
6091
|
+
const stripChildAligns = (node) => node.children ? {
|
|
6092
|
+
...node,
|
|
6093
|
+
children: node.children.map((child) => {
|
|
6094
|
+
const { align: _dropped, ...rest } = child;
|
|
6095
|
+
return stripChildAligns(rest);
|
|
6096
|
+
})
|
|
6097
|
+
} : node;
|
|
6021
6098
|
const nodes = {};
|
|
6022
6099
|
for (const [key, override] of Object.entries(store.nodes)) {
|
|
6023
6100
|
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
6024
6101
|
const tree = match ? treeFor(match[1]) : void 0;
|
|
6025
|
-
const
|
|
6026
|
-
|
|
6102
|
+
const row = match && tree ? tree.rows[Number(match[2])] : void 0;
|
|
6103
|
+
const blockIdx = match ? Number(match[3]) : -1;
|
|
6104
|
+
const block = row?.blocks[blockIdx];
|
|
6105
|
+
if (!row || !block) {
|
|
6027
6106
|
nodes[key] = override;
|
|
6028
6107
|
continue;
|
|
6029
6108
|
}
|
|
6030
|
-
|
|
6109
|
+
row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
|
|
6031
6110
|
const rest = { ...override };
|
|
6032
6111
|
delete rest.align;
|
|
6033
6112
|
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
@@ -6040,7 +6119,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6040
6119
|
continue;
|
|
6041
6120
|
}
|
|
6042
6121
|
for (const row of tree.rows) {
|
|
6043
|
-
|
|
6122
|
+
row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
|
|
6044
6123
|
}
|
|
6045
6124
|
const rest = { ...override };
|
|
6046
6125
|
delete rest.align;
|
|
@@ -7201,6 +7280,7 @@ var blockAlignStyle = (blockAlign) => blockAlign ? {
|
|
|
7201
7280
|
alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
|
|
7202
7281
|
textAlign: blockAlign
|
|
7203
7282
|
} : {};
|
|
7283
|
+
var fullBleedBlock = (block) => block.type === "carousel" || block.type === "group" && str(block.slots?.layout) === "overlap";
|
|
7204
7284
|
var featureLines = (value) => value.split(/\n|<br\s*\/?>/i).map((line) => line.trim()).filter(Boolean);
|
|
7205
7285
|
var AI_MOBILE_CSS = [
|
|
7206
7286
|
// Unscoped (applies at every viewport, not just mobile): re-enables pointer-events for the
|
|
@@ -9266,8 +9346,8 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9266
9346
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9267
9347
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9268
9348
|
// the full section width instead of reading at the usual content width.
|
|
9269
|
-
/* @__PURE__ */ 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") })
|
|
9270
|
-
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? "center" : void 0),
|
|
9349
|
+
/* @__PURE__ */ 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") })
|
|
9350
|
+
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? node.align ?? "center" : void 0),
|
|
9271
9351
|
i === 0 && needsBaseScrim && /* @__PURE__ */ jsx(
|
|
9272
9352
|
"div",
|
|
9273
9353
|
{
|
|
@@ -9300,7 +9380,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9300
9380
|
// child otherwise stretches full-width (unchanged pre-existing behaviour).
|
|
9301
9381
|
...blockAlignStyle(child.align ?? ambientAlign)
|
|
9302
9382
|
},
|
|
9303
|
-
children: renderNode(child, ctx, `${path}.c${i}`, ambientAlign)
|
|
9383
|
+
children: renderNode(child, ctx, `${path}.c${i}`, node.align ?? ambientAlign)
|
|
9304
9384
|
},
|
|
9305
9385
|
i
|
|
9306
9386
|
));
|
|
@@ -9330,8 +9410,20 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9330
9410
|
}
|
|
9331
9411
|
case "button":
|
|
9332
9412
|
return /* @__PURE__ */ jsx(ButtonEl, { slots, ctx, path });
|
|
9333
|
-
case "button-row":
|
|
9334
|
-
|
|
9413
|
+
case "button-row": {
|
|
9414
|
+
const rowAlign = node.align ?? ambientAlign;
|
|
9415
|
+
return /* @__PURE__ */ jsx(
|
|
9416
|
+
"div",
|
|
9417
|
+
{
|
|
9418
|
+
style: {
|
|
9419
|
+
display: "flex",
|
|
9420
|
+
gap: AI_TREE_TOKENS.spacing6,
|
|
9421
|
+
justifyContent: rowAlign === "left" ? "flex-start" : rowAlign === "right" ? "flex-end" : "center"
|
|
9422
|
+
},
|
|
9423
|
+
children: (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }, i))
|
|
9424
|
+
}
|
|
9425
|
+
);
|
|
9426
|
+
}
|
|
9335
9427
|
case "media":
|
|
9336
9428
|
return /* @__PURE__ */ jsx(
|
|
9337
9429
|
MediaBox,
|
|
@@ -9710,7 +9802,7 @@ function AiTreeRenderer({
|
|
|
9710
9802
|
// its own horizontal `align`, which takes priority for that block.
|
|
9711
9803
|
...fillHeight ? { display: "grid" } : {},
|
|
9712
9804
|
// Horizontal placement of the block's content within its column.
|
|
9713
|
-
...cellAlignStyle(block.align),
|
|
9805
|
+
...fullBleedBlock(block) ? {} : cellAlignStyle(block.align),
|
|
9714
9806
|
// space-between: each column becomes a flex column whose content spreads over
|
|
9715
9807
|
// the full row height instead of clumping at the top.
|
|
9716
9808
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -10105,38 +10197,39 @@ function deriveTemplateButtonStyle() {
|
|
|
10105
10197
|
el.querySelectorAll("[data-ohw-editable]").length <= 1
|
|
10106
10198
|
);
|
|
10107
10199
|
const isFilled = (el) => {
|
|
10108
|
-
const bg =
|
|
10200
|
+
const bg = withTransitionsSettled(el, (s) => s.backgroundColor);
|
|
10109
10201
|
if (!bg || bg === "transparent") return false;
|
|
10110
10202
|
const alpha = bg.match(/rgba?\([^)]*,\s*([\d.]+)\)$/);
|
|
10111
10203
|
return !alpha || parseFloat(alpha[1]) > 0;
|
|
10112
10204
|
};
|
|
10113
10205
|
const btn = candidates.find(isFilled) ?? candidates[0];
|
|
10114
10206
|
if (!btn) return null;
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10207
|
+
return withTransitionsSettled(btn, (cs) => {
|
|
10208
|
+
const filled = isFilled(btn);
|
|
10209
|
+
const corners = [
|
|
10210
|
+
cs.borderTopLeftRadius,
|
|
10211
|
+
cs.borderTopRightRadius,
|
|
10212
|
+
cs.borderBottomRightRadius,
|
|
10213
|
+
cs.borderBottomLeftRadius
|
|
10214
|
+
].map((v) => v || "0px");
|
|
10215
|
+
const radius = corners.every((v) => v === corners[0]) ? corners[0] : corners.join(" ");
|
|
10216
|
+
const px2 = (v) => parseFloat(v) || 0;
|
|
10217
|
+
const lineHeight = px2(cs.lineHeight) || px2(cs.fontSize) * 1.2;
|
|
10218
|
+
const contentH = btn.getBoundingClientRect().height - px2(cs.borderTopWidth) - px2(cs.borderBottomWidth);
|
|
10219
|
+
const impliedY = Math.round(Math.max(0, (contentH - lineHeight) / 2));
|
|
10220
|
+
const padY = Math.max(px2(cs.paddingTop), px2(cs.paddingBottom), impliedY);
|
|
10221
|
+
const padX = Math.max(px2(cs.paddingLeft), px2(cs.paddingRight));
|
|
10222
|
+
return {
|
|
10223
|
+
radius: radius || "10px",
|
|
10224
|
+
padding: `${padY}px ${padX}px`,
|
|
10225
|
+
...filled ? { background: cs.backgroundColor, color: cs.color } : {},
|
|
10226
|
+
fontFamily: cs.fontFamily || "",
|
|
10227
|
+
fontSize: cs.fontSize || "",
|
|
10228
|
+
fontWeight: cs.fontWeight || "",
|
|
10229
|
+
letterSpacing: cs.letterSpacing || "",
|
|
10230
|
+
textTransform: cs.textTransform || ""
|
|
10231
|
+
};
|
|
10232
|
+
});
|
|
10140
10233
|
}
|
|
10141
10234
|
var mounted = /* @__PURE__ */ new Map();
|
|
10142
10235
|
function findTemplateSection(id) {
|
|
@@ -18344,10 +18437,23 @@ function setPricingCardStyle(tree, index, style) {
|
|
|
18344
18437
|
});
|
|
18345
18438
|
}
|
|
18346
18439
|
function setPricingCardFeaturedTag(tree, index, on) {
|
|
18347
|
-
return
|
|
18440
|
+
return withPricingCollection(tree, (collection) => {
|
|
18441
|
+
const children = collection.children;
|
|
18442
|
+
if (index < 0 || index >= children.length) return false;
|
|
18443
|
+
if (on) {
|
|
18444
|
+
children.forEach((card, i) => {
|
|
18445
|
+
if (i === index) return;
|
|
18446
|
+
const prev2 = featuredOf(card);
|
|
18447
|
+
if (prev2.enabled !== true || badgeOf(prev2).length === 0) return;
|
|
18448
|
+
card.slots = card.slots ?? {};
|
|
18449
|
+
card.slots.featured = composeFeatured(pricingCardStyleOf(prev2), false, badgeOf(prev2));
|
|
18450
|
+
});
|
|
18451
|
+
}
|
|
18452
|
+
const target = children[index];
|
|
18453
|
+
target.slots = target.slots ?? {};
|
|
18348
18454
|
const prev = featuredOf(target);
|
|
18349
|
-
|
|
18350
|
-
|
|
18455
|
+
target.slots.featured = composeFeatured(pricingCardStyleOf(prev), on, badgeOf(prev));
|
|
18456
|
+
return true;
|
|
18351
18457
|
});
|
|
18352
18458
|
}
|
|
18353
18459
|
function pricingCardStyleOf(featured) {
|
|
@@ -18597,25 +18703,40 @@ function ToolbarSeparator() {
|
|
|
18597
18703
|
}
|
|
18598
18704
|
function CardStyleMenu({
|
|
18599
18705
|
value,
|
|
18600
|
-
onChange
|
|
18706
|
+
onChange,
|
|
18707
|
+
disabled = false
|
|
18601
18708
|
}) {
|
|
18602
18709
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18710
|
+
const trigger = /* @__PURE__ */ jsxs11(
|
|
18711
|
+
"button",
|
|
18712
|
+
{
|
|
18713
|
+
type: "button",
|
|
18714
|
+
"aria-label": "Card style",
|
|
18715
|
+
disabled,
|
|
18716
|
+
className: cn(
|
|
18717
|
+
"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",
|
|
18718
|
+
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
18719
|
+
),
|
|
18720
|
+
children: [
|
|
18721
|
+
/* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
|
|
18722
|
+
/* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
|
|
18723
|
+
/* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
18724
|
+
]
|
|
18725
|
+
}
|
|
18726
|
+
);
|
|
18727
|
+
if (disabled) {
|
|
18728
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18729
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
18730
|
+
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18731
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: trigger }) }),
|
|
18732
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
18733
|
+
] })
|
|
18734
|
+
] });
|
|
18735
|
+
}
|
|
18603
18736
|
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18604
18737
|
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
18605
18738
|
/* @__PURE__ */ jsxs11(DropdownMenu, { modal: false, children: [
|
|
18606
|
-
/* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children:
|
|
18607
|
-
"button",
|
|
18608
|
-
{
|
|
18609
|
-
type: "button",
|
|
18610
|
-
"aria-label": "Card style",
|
|
18611
|
-
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",
|
|
18612
|
-
children: [
|
|
18613
|
-
/* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
|
|
18614
|
-
/* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
|
|
18615
|
-
/* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
18616
|
-
]
|
|
18617
|
-
}
|
|
18618
|
-
) }),
|
|
18739
|
+
/* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
18619
18740
|
/* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
18620
18741
|
const selected = style.value === value;
|
|
18621
18742
|
return /* @__PURE__ */ jsxs11(
|
|
@@ -18679,23 +18800,35 @@ function PricingCardToolbar({
|
|
|
18679
18800
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18680
18801
|
),
|
|
18681
18802
|
children: [
|
|
18682
|
-
/* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle }),
|
|
18683
18803
|
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18684
18804
|
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
18685
18805
|
CustomToolbarButton,
|
|
18686
18806
|
{
|
|
18687
18807
|
type: "button",
|
|
18688
|
-
"aria-label": featuredTag ? "
|
|
18808
|
+
"aria-label": featuredTag ? "Unmark as featured" : "Mark as featured",
|
|
18689
18809
|
"aria-pressed": featuredTag,
|
|
18690
|
-
active: featuredTag,
|
|
18691
18810
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
18692
|
-
className: "size-8",
|
|
18693
|
-
children: /* @__PURE__ */ jsx20(
|
|
18811
|
+
className: "group size-8",
|
|
18812
|
+
children: /* @__PURE__ */ jsx20(
|
|
18813
|
+
Star2,
|
|
18814
|
+
{
|
|
18815
|
+
size: 16,
|
|
18816
|
+
fill: "currentColor",
|
|
18817
|
+
strokeWidth: 0,
|
|
18818
|
+
className: cn(
|
|
18819
|
+
"transition-colors",
|
|
18820
|
+
featuredTag ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
|
|
18821
|
+
),
|
|
18822
|
+
style: { pointerEvents: "none" }
|
|
18823
|
+
}
|
|
18824
|
+
)
|
|
18694
18825
|
}
|
|
18695
18826
|
) }),
|
|
18696
|
-
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "
|
|
18827
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
18697
18828
|
] }),
|
|
18698
18829
|
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18830
|
+
/* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
18831
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18699
18832
|
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx20(ButtonGlyph, {}) }),
|
|
18700
18833
|
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs11("span", { className: "relative inline-flex", children: [
|
|
18701
18834
|
/* @__PURE__ */ jsx20(ButtonGlyph, {}),
|
|
@@ -18838,7 +18971,12 @@ function AiPricingCardOverlay({
|
|
|
18838
18971
|
index: active.index,
|
|
18839
18972
|
pending,
|
|
18840
18973
|
error,
|
|
18841
|
-
onAddTier: () =>
|
|
18974
|
+
onAddTier: () => {
|
|
18975
|
+
const newIndex = pricingCardCount(activeEntry.tree);
|
|
18976
|
+
void runMutation(active.sectionId, addPricingTier).then((applied) => {
|
|
18977
|
+
if (applied) setActive({ sectionId: active.sectionId, index: newIndex });
|
|
18978
|
+
});
|
|
18979
|
+
},
|
|
18842
18980
|
onRemoveTier: () => {
|
|
18843
18981
|
void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
|
|
18844
18982
|
(applied) => {
|
|
@@ -30251,9 +30389,10 @@ function OhhwellsBridge() {
|
|
|
30251
30389
|
if (e.data?.type !== "ow:collect-section") return;
|
|
30252
30390
|
const sectionId = e.data.sectionId;
|
|
30253
30391
|
if (typeof sectionId !== "string" || !sectionId) return;
|
|
30254
|
-
const
|
|
30392
|
+
const foundEl = document.querySelector(
|
|
30255
30393
|
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
30256
30394
|
);
|
|
30395
|
+
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;
|
|
30257
30396
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
30258
30397
|
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
30259
30398
|
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
@@ -30992,7 +31131,7 @@ function OhhwellsBridge() {
|
|
|
30992
31131
|
postToParent2({
|
|
30993
31132
|
type: "ow:ready",
|
|
30994
31133
|
version: "1",
|
|
30995
|
-
bridgeVersion: "0.1.
|
|
31134
|
+
bridgeVersion: "0.1.141",
|
|
30996
31135
|
path: pathname,
|
|
30997
31136
|
nodes: collectEditableNodes(editContentRef.current),
|
|
30998
31137
|
sections
|
|
@@ -32207,6 +32346,7 @@ export {
|
|
|
32207
32346
|
dropIndicatorVariants,
|
|
32208
32347
|
ensureFooterTree,
|
|
32209
32348
|
filterAvailablePages,
|
|
32349
|
+
foldAlignIntoTrees,
|
|
32210
32350
|
getEditModeInitialState,
|
|
32211
32351
|
insertFooterHours,
|
|
32212
32352
|
isEditSessionActive,
|
|
@@ -32215,6 +32355,7 @@ export {
|
|
|
32215
32355
|
isValidUrl,
|
|
32216
32356
|
nextViableSlide,
|
|
32217
32357
|
parseAiFooterState,
|
|
32358
|
+
parseAiSectionsState,
|
|
32218
32359
|
parseTarget,
|
|
32219
32360
|
removeFooterBlock,
|
|
32220
32361
|
resolveFooterCopyright,
|