@ohhwells/bridge 0.1.136 → 0.1.138
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 +369 -221
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +390 -242
- package/dist/index.js.map +1 -1
- package/dist/styles.css +72 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5924,6 +5924,7 @@ function applyStylesToDom(store) {
|
|
|
5924
5924
|
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
5925
5925
|
}
|
|
5926
5926
|
if (override.cardBackgroundColor !== void 0 && !isDrawerMarker) {
|
|
5927
|
+
detectItemGroups(section);
|
|
5927
5928
|
section.style.setProperty("--ohw-card-bg", override.cardBackgroundColor);
|
|
5928
5929
|
section.setAttribute("data-ohw-style-cardbg", "");
|
|
5929
5930
|
}
|
|
@@ -7921,6 +7922,21 @@ function PricingCard({ node, ctx, path }) {
|
|
|
7921
7922
|
const fg = emphasis.fg;
|
|
7922
7923
|
const features = pricingFeatureItems(slots.features);
|
|
7923
7924
|
const buttons = (node.children ?? []).map((child, i) => ({ child, i })).filter((entry) => entry.child.type === "button");
|
|
7925
|
+
const badge = featured.enabled && str(featured.badge) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
7926
|
+
"div",
|
|
7927
|
+
{
|
|
7928
|
+
...ctx.keyFor ? { "data-ohw-key": ctx.keyFor(`${path}.featured.badge`), "data-ohw-editable": "plain" } : {},
|
|
7929
|
+
style: {
|
|
7930
|
+
alignSelf: "flex-start",
|
|
7931
|
+
padding: `${AI_TREE_TOKENS.spacing2 / 2}px ${AI_TREE_TOKENS.spacing3}px`,
|
|
7932
|
+
borderRadius: 999,
|
|
7933
|
+
background: ctx.brand.palette.primary,
|
|
7934
|
+
color: primaryButtonLabel(ctx.brand),
|
|
7935
|
+
...typeStyle(AI_TREE_TOKENS.type.eyebrow, ctx.brand.fonts.body)
|
|
7936
|
+
},
|
|
7937
|
+
children: str(featured.badge)
|
|
7938
|
+
}
|
|
7939
|
+
) : null;
|
|
7924
7940
|
const headingBlock = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing2 }, children: [
|
|
7925
7941
|
str(slots.heading) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
7926
7942
|
"div",
|
|
@@ -7970,32 +7986,31 @@ function PricingCard({ node, ctx, path }) {
|
|
|
7970
7986
|
position: "relative"
|
|
7971
7987
|
},
|
|
7972
7988
|
children: [
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
) : headingBlock,
|
|
7989
|
+
emphasis.headerBg ? (
|
|
7990
|
+
// The badge rides inside the band so the tint runs from the card's top edge down
|
|
7991
|
+
// through the price block, instead of starting underneath the badge.
|
|
7992
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
7993
|
+
"div",
|
|
7994
|
+
{
|
|
7995
|
+
style: {
|
|
7996
|
+
background: emphasis.headerBg,
|
|
7997
|
+
margin: `-${AI_TREE_TOKENS.paddingBlock}px -${AI_TREE_TOKENS.paddingBlock}px 0`,
|
|
7998
|
+
padding: AI_TREE_TOKENS.paddingBlock,
|
|
7999
|
+
borderRadius: `${cardRadius(slots)}px ${cardRadius(slots)}px 0 0`,
|
|
8000
|
+
display: "flex",
|
|
8001
|
+
flexDirection: "column",
|
|
8002
|
+
gap: AI_TREE_TOKENS.spacing8
|
|
8003
|
+
},
|
|
8004
|
+
children: [
|
|
8005
|
+
badge,
|
|
8006
|
+
headingBlock
|
|
8007
|
+
]
|
|
8008
|
+
}
|
|
8009
|
+
)
|
|
8010
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
8011
|
+
badge,
|
|
8012
|
+
headingBlock
|
|
8013
|
+
] }),
|
|
7999
8014
|
features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
8000
8015
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: "none", borderTop: `1px solid ${fg}`, opacity: 0.2, margin: 0, width: "100%" } }),
|
|
8001
8016
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing4 }, children: [
|
|
@@ -18300,16 +18315,65 @@ function removePricingTier(tree, index) {
|
|
|
18300
18315
|
return true;
|
|
18301
18316
|
});
|
|
18302
18317
|
}
|
|
18303
|
-
|
|
18318
|
+
var PRICING_CARD_STYLES = [
|
|
18319
|
+
{ value: "outline", label: "Outline", treatment: null },
|
|
18320
|
+
{ value: "lift", label: "Lift", treatment: "lifted" },
|
|
18321
|
+
{ value: "invert", label: "Invert", treatment: "inverted" },
|
|
18322
|
+
{ value: "header", label: "Header", treatment: "accent-header" }
|
|
18323
|
+
];
|
|
18324
|
+
var DEFAULT_FEATURED_BADGE = "Most popular";
|
|
18325
|
+
function featuredOf(target) {
|
|
18326
|
+
const raw = target?.slots?.featured;
|
|
18327
|
+
if (raw === true) return { enabled: true, treatment: "outlined" };
|
|
18328
|
+
return typeof raw === "object" && raw !== null ? raw : {};
|
|
18329
|
+
}
|
|
18330
|
+
function badgeOf(featured) {
|
|
18331
|
+
return typeof featured.badge === "string" ? featured.badge.trim() : "";
|
|
18332
|
+
}
|
|
18333
|
+
function pricingCardStyle(tree, index) {
|
|
18334
|
+
const featured = featuredOf(findPricingCollection(tree)?.children?.[index]);
|
|
18335
|
+
if (featured.enabled !== true) return "outline";
|
|
18336
|
+
return PRICING_CARD_STYLES.find((s) => s.treatment === featured.treatment)?.value ?? "outline";
|
|
18337
|
+
}
|
|
18338
|
+
function pricingCardFeaturedTag(tree, index) {
|
|
18339
|
+
const featured = featuredOf(findPricingCollection(tree)?.children?.[index]);
|
|
18340
|
+
return featured.enabled === true && badgeOf(featured).length > 0;
|
|
18341
|
+
}
|
|
18342
|
+
function composeFeatured(style, tagOn, badgeText) {
|
|
18343
|
+
const treatment = PRICING_CARD_STYLES.find((s) => s.value === style)?.treatment ?? null;
|
|
18344
|
+
if (tagOn) return { enabled: true, badge: badgeText || DEFAULT_FEATURED_BADGE, treatment: treatment ?? "outlined" };
|
|
18345
|
+
if (treatment) return { enabled: true, treatment };
|
|
18346
|
+
return badgeText.length > 0 ? { enabled: false, badge: badgeText } : { enabled: false };
|
|
18347
|
+
}
|
|
18348
|
+
function withPricingCard(tree, index, mutate) {
|
|
18304
18349
|
return withPricingCollection(tree, (collection) => {
|
|
18305
18350
|
const children = collection.children;
|
|
18306
18351
|
if (index < 0 || index >= children.length) return false;
|
|
18307
18352
|
const target = children[index];
|
|
18308
18353
|
target.slots = target.slots ?? {};
|
|
18309
|
-
target
|
|
18354
|
+
mutate(target);
|
|
18310
18355
|
return true;
|
|
18311
18356
|
});
|
|
18312
18357
|
}
|
|
18358
|
+
function setPricingCardStyle(tree, index, style) {
|
|
18359
|
+
if (!PRICING_CARD_STYLES.some((s) => s.value === style)) return null;
|
|
18360
|
+
return withPricingCard(tree, index, (target) => {
|
|
18361
|
+
const prev = featuredOf(target);
|
|
18362
|
+
const tagOn = prev.enabled === true && badgeOf(prev).length > 0;
|
|
18363
|
+
target.slots.featured = composeFeatured(style, tagOn, badgeOf(prev));
|
|
18364
|
+
});
|
|
18365
|
+
}
|
|
18366
|
+
function setPricingCardFeaturedTag(tree, index, on) {
|
|
18367
|
+
return withPricingCard(tree, index, (target) => {
|
|
18368
|
+
const prev = featuredOf(target);
|
|
18369
|
+
const style = pricingCardStyleOf(prev);
|
|
18370
|
+
target.slots.featured = composeFeatured(style, on, badgeOf(prev));
|
|
18371
|
+
});
|
|
18372
|
+
}
|
|
18373
|
+
function pricingCardStyleOf(featured) {
|
|
18374
|
+
if (featured.enabled !== true) return "outline";
|
|
18375
|
+
return PRICING_CARD_STYLES.find((s) => s.treatment === featured.treatment)?.value ?? "outline";
|
|
18376
|
+
}
|
|
18313
18377
|
function addPricingCardButton(tree, index, label) {
|
|
18314
18378
|
return withPricingCollection(tree, (collection) => {
|
|
18315
18379
|
const children = collection.children;
|
|
@@ -18384,15 +18448,8 @@ function removePricingCardFeature(tree, index) {
|
|
|
18384
18448
|
|
|
18385
18449
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
18386
18450
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18387
|
-
var
|
|
18388
|
-
|
|
18389
|
-
{ value: "lifted", label: "Lift" },
|
|
18390
|
-
{ value: "inverted", label: "Invert" },
|
|
18391
|
-
{ value: "accent-header", label: "Header" }
|
|
18392
|
-
];
|
|
18393
|
-
var PRIMARY4 = "#0885FE";
|
|
18394
|
-
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY4})`;
|
|
18395
|
-
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY4}) 60%, #000000)`;
|
|
18451
|
+
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
18452
|
+
var CHROME_SELECTOR = "[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-link-modal-root], [data-ohw-section-picker], [data-ohw-ai-review], [data-ohw-more-menu]";
|
|
18396
18453
|
function findPricingCardElement(sectionId, index) {
|
|
18397
18454
|
const sectionEl = findByInstanceId(sectionId);
|
|
18398
18455
|
if (!sectionEl) return null;
|
|
@@ -18402,14 +18459,35 @@ function findPricingCardElement(sectionId, index) {
|
|
|
18402
18459
|
}
|
|
18403
18460
|
return null;
|
|
18404
18461
|
}
|
|
18405
|
-
function
|
|
18406
|
-
|
|
18462
|
+
function cardRefFromTarget(target) {
|
|
18463
|
+
if (!(target instanceof Element)) return null;
|
|
18464
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18465
|
+
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
18466
|
+
if (!cardEl) return null;
|
|
18467
|
+
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
18468
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18469
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18470
|
+
const index = Number(cardEl.dataset.ohwPricingIndex);
|
|
18471
|
+
if (!sectionId || Number.isNaN(index)) return null;
|
|
18472
|
+
return { sectionId, index };
|
|
18473
|
+
}
|
|
18474
|
+
function sameRef(a, b) {
|
|
18475
|
+
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18476
|
+
}
|
|
18477
|
+
function rectOf(el) {
|
|
18407
18478
|
if (!el) return null;
|
|
18408
18479
|
const r2 = el.getBoundingClientRect();
|
|
18409
18480
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18410
18481
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18411
18482
|
}
|
|
18412
|
-
function
|
|
18483
|
+
function readRect3(ref) {
|
|
18484
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
18485
|
+
}
|
|
18486
|
+
function readGridRect(ref) {
|
|
18487
|
+
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
18488
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
18489
|
+
}
|
|
18490
|
+
function useLiveCardRect(ref, grid = false) {
|
|
18413
18491
|
const [rect, setRect] = (0, import_react11.useState)(null);
|
|
18414
18492
|
(0, import_react11.useEffect)(() => {
|
|
18415
18493
|
if (!ref) {
|
|
@@ -18417,7 +18495,7 @@ function useLiveCardRect(ref) {
|
|
|
18417
18495
|
return;
|
|
18418
18496
|
}
|
|
18419
18497
|
const update = () => {
|
|
18420
|
-
const next = readRect3(ref);
|
|
18498
|
+
const next = grid ? readGridRect(ref) : readRect3(ref);
|
|
18421
18499
|
setRect(
|
|
18422
18500
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18423
18501
|
);
|
|
@@ -18432,9 +18510,49 @@ function useLiveCardRect(ref) {
|
|
|
18432
18510
|
window.removeEventListener("resize", update);
|
|
18433
18511
|
clearInterval(interval);
|
|
18434
18512
|
};
|
|
18435
|
-
}, [ref?.sectionId, ref?.index]);
|
|
18513
|
+
}, [ref?.sectionId, ref?.index, grid]);
|
|
18436
18514
|
return rect;
|
|
18437
18515
|
}
|
|
18516
|
+
var TOOLBAR_GRID_GAP = 52;
|
|
18517
|
+
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
18518
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18519
|
+
function GridToolbarSlot({ gridRect, children }) {
|
|
18520
|
+
const slotRef = (0, import_react11.useRef)(null);
|
|
18521
|
+
const [shift, setShift] = (0, import_react11.useState)(0);
|
|
18522
|
+
const centerX = gridRect.left + gridRect.width / 2;
|
|
18523
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
18524
|
+
const slot = slotRef.current;
|
|
18525
|
+
if (!slot) return;
|
|
18526
|
+
const clamp = () => {
|
|
18527
|
+
const w = slot.offsetWidth;
|
|
18528
|
+
if (w <= 0) return;
|
|
18529
|
+
const half = w / 2;
|
|
18530
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18531
|
+
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18532
|
+
};
|
|
18533
|
+
clamp();
|
|
18534
|
+
const ro = new ResizeObserver(clamp);
|
|
18535
|
+
ro.observe(slot);
|
|
18536
|
+
return () => ro.disconnect();
|
|
18537
|
+
}, [centerX, children]);
|
|
18538
|
+
const mobile = window.innerWidth <= 480;
|
|
18539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18540
|
+
"div",
|
|
18541
|
+
{
|
|
18542
|
+
ref: slotRef,
|
|
18543
|
+
"data-ohw-bridge": "",
|
|
18544
|
+
"data-ohw-item-interaction": "",
|
|
18545
|
+
className: "pointer-events-auto fixed",
|
|
18546
|
+
style: {
|
|
18547
|
+
top: gridRect.top - (mobile ? TOOLBAR_GRID_GAP_MOBILE : TOOLBAR_GRID_GAP),
|
|
18548
|
+
left: centerX + shift,
|
|
18549
|
+
transform: "translate(-50%, -100%)",
|
|
18550
|
+
zIndex: 2147483645
|
|
18551
|
+
},
|
|
18552
|
+
children
|
|
18553
|
+
}
|
|
18554
|
+
);
|
|
18555
|
+
}
|
|
18438
18556
|
function requestValidateTree2(postToParent2, tree) {
|
|
18439
18557
|
return new Promise((resolve) => {
|
|
18440
18558
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18452,40 +18570,93 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
18452
18570
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
18453
18571
|
});
|
|
18454
18572
|
}
|
|
18455
|
-
function
|
|
18456
|
-
label,
|
|
18457
|
-
onClick,
|
|
18458
|
-
disabled,
|
|
18459
|
-
active
|
|
18460
|
-
}) {
|
|
18573
|
+
function StyleSwatch({ style }) {
|
|
18461
18574
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18462
|
-
"
|
|
18575
|
+
"span",
|
|
18463
18576
|
{
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18471
|
-
alignItems: "center",
|
|
18472
|
-
gap: 4,
|
|
18473
|
-
borderRadius: 999,
|
|
18474
|
-
border: "none",
|
|
18475
|
-
cursor: disabled ? "default" : "pointer",
|
|
18476
|
-
background: active ? OHW_BLUE_DARK2 : "#ffffff",
|
|
18477
|
-
color: active ? "#ffffff" : OHW_BLUE_DARK2,
|
|
18478
|
-
opacity: disabled ? 0.4 : 1,
|
|
18479
|
-
fontSize: 12,
|
|
18480
|
-
lineHeight: "16px",
|
|
18481
|
-
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18482
|
-
whiteSpace: "nowrap",
|
|
18483
|
-
flex: "0 0 auto"
|
|
18484
|
-
},
|
|
18485
|
-
children: label
|
|
18577
|
+
"aria-hidden": true,
|
|
18578
|
+
className: cn(
|
|
18579
|
+
"inline-block h-4 w-[18px] shrink-0 rounded-[3px] border border-border bg-background",
|
|
18580
|
+
style === "lift" && "border-transparent shadow-[0_3px_5px_rgba(0,0,0,0.22)]",
|
|
18581
|
+
style === "invert" && "border-foreground bg-foreground",
|
|
18582
|
+
style === "header" && "bg-[linear-gradient(var(--ohw-foreground,#0c0a09)_48%,var(--ohw-background,#ffffff)_48%)]"
|
|
18583
|
+
)
|
|
18486
18584
|
}
|
|
18487
18585
|
);
|
|
18488
18586
|
}
|
|
18587
|
+
function ButtonGlyph() {
|
|
18588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
18589
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
18590
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
18591
|
+
] });
|
|
18592
|
+
}
|
|
18593
|
+
function FeatureGlyph({ mode }) {
|
|
18594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
18595
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
18596
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
18597
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
18598
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
18599
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
18600
|
+
mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
18601
|
+
] });
|
|
18602
|
+
}
|
|
18603
|
+
function ToolbarAction({
|
|
18604
|
+
label,
|
|
18605
|
+
onClick,
|
|
18606
|
+
disabled = false,
|
|
18607
|
+
children
|
|
18608
|
+
}) {
|
|
18609
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
18610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18611
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
18612
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
18613
|
+
] });
|
|
18614
|
+
}
|
|
18615
|
+
function ToolbarSeparator() {
|
|
18616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
18617
|
+
}
|
|
18618
|
+
function CardStyleMenu({
|
|
18619
|
+
value,
|
|
18620
|
+
onChange
|
|
18621
|
+
}) {
|
|
18622
|
+
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18624
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
18625
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
|
|
18626
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18627
|
+
"button",
|
|
18628
|
+
{
|
|
18629
|
+
type: "button",
|
|
18630
|
+
"aria-label": "Card style",
|
|
18631
|
+
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",
|
|
18632
|
+
children: [
|
|
18633
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
18634
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18635
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18636
|
+
]
|
|
18637
|
+
}
|
|
18638
|
+
) }),
|
|
18639
|
+
/* @__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) => {
|
|
18640
|
+
const selected = style.value === value;
|
|
18641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18642
|
+
DropdownMenuItem,
|
|
18643
|
+
{
|
|
18644
|
+
role: "menuitemradio",
|
|
18645
|
+
"aria-checked": selected,
|
|
18646
|
+
onSelect: () => onChange(style.value),
|
|
18647
|
+
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
18648
|
+
children: [
|
|
18649
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: style.value }),
|
|
18650
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: style.label }),
|
|
18651
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
|
|
18652
|
+
]
|
|
18653
|
+
},
|
|
18654
|
+
style.value
|
|
18655
|
+
);
|
|
18656
|
+
}) })
|
|
18657
|
+
] })
|
|
18658
|
+
] });
|
|
18659
|
+
}
|
|
18489
18660
|
function PricingCardToolbar({
|
|
18490
18661
|
entry,
|
|
18491
18662
|
index,
|
|
@@ -18493,8 +18664,8 @@ function PricingCardToolbar({
|
|
|
18493
18664
|
error,
|
|
18494
18665
|
onAddTier,
|
|
18495
18666
|
onRemoveTier,
|
|
18496
|
-
|
|
18497
|
-
|
|
18667
|
+
onSetStyle,
|
|
18668
|
+
onSetFeaturedTag,
|
|
18498
18669
|
onAddButton,
|
|
18499
18670
|
onRemoveButton,
|
|
18500
18671
|
onAddFeature,
|
|
@@ -18502,55 +18673,66 @@ function PricingCardToolbar({
|
|
|
18502
18673
|
}) {
|
|
18503
18674
|
const collectionCount = pricingCardCount(entry.tree);
|
|
18504
18675
|
const card = findPricingCardNode(entry.tree, index);
|
|
18505
|
-
const featured = card?.slots?.featured;
|
|
18506
|
-
const isFeatured = featured?.enabled === true;
|
|
18507
18676
|
const buttonCount = (card?.children ?? []).filter((c) => c.type === "button").length;
|
|
18508
18677
|
const featureCount = pricingCardFeatureCount(entry.tree, index);
|
|
18509
|
-
const
|
|
18510
|
-
|
|
18678
|
+
const style = pricingCardStyle(entry.tree, index);
|
|
18679
|
+
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
18680
|
+
const mobile = window.innerWidth <= 480;
|
|
18681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18511
18682
|
"div",
|
|
18512
18683
|
{
|
|
18513
18684
|
"data-ohw-bridge": "",
|
|
18514
18685
|
"data-ohw-toolbar": "",
|
|
18515
18686
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18516
|
-
|
|
18517
|
-
|
|
18518
|
-
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
background: OHW_BLUE2,
|
|
18522
|
-
padding: 8,
|
|
18523
|
-
borderRadius: 12,
|
|
18524
|
-
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18525
|
-
pointerEvents: pending ? "none" : "auto",
|
|
18526
|
-
opacity: pending ? 0.6 : 1,
|
|
18527
|
-
// Only cap width on mobile, where the pill rows wrap — on desktop the row stays on one
|
|
18528
|
-
// line and should size to fit it, not get clipped/overflow against a fixed cap.
|
|
18529
|
-
maxWidth: pillWrap === "wrap" ? "calc(100vw - 24px)" : "none"
|
|
18530
|
-
},
|
|
18687
|
+
className: cn(
|
|
18688
|
+
"flex flex-col items-center gap-1.5 font-sans",
|
|
18689
|
+
pending && "pointer-events-none opacity-60"
|
|
18690
|
+
),
|
|
18691
|
+
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
18531
18692
|
children: [
|
|
18532
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18533
|
-
|
|
18534
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "- Tier", onClick: onRemoveTier, disabled: collectionCount <= 1 }),
|
|
18535
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "Featured", active: isFeatured, onClick: () => onToggleFeatured(!isFeatured) }),
|
|
18536
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "+ Button", onClick: onAddButton, disabled: buttonCount >= 2 }),
|
|
18537
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "- Button", onClick: onRemoveButton, disabled: buttonCount === 0 }),
|
|
18538
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "+ Feature", onClick: onAddFeature, disabled: featureCount >= 10 }),
|
|
18539
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "- Feature", onClick: onRemoveFeature, disabled: featureCount <= 1 })
|
|
18540
|
-
] }),
|
|
18541
|
-
isFeatured && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: EMPHASIS_TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18542
|
-
Pill2,
|
|
18693
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18694
|
+
"div",
|
|
18543
18695
|
{
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18547
|
-
|
|
18548
|
-
|
|
18549
|
-
|
|
18550
|
-
|
|
18696
|
+
className: cn(
|
|
18697
|
+
"flex items-center gap-1 rounded-[10px] border border-border bg-background p-1 whitespace-nowrap",
|
|
18698
|
+
"shadow-[0px_10px_15px_-3px_rgba(0,0,0,0.1),0px_4px_6px_-4px_rgba(0,0,0,0.1)]",
|
|
18699
|
+
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18700
|
+
),
|
|
18701
|
+
children: [
|
|
18702
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle }),
|
|
18703
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18704
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18705
|
+
CustomToolbarButton,
|
|
18706
|
+
{
|
|
18707
|
+
type: "button",
|
|
18708
|
+
"aria-label": featuredTag ? "Remove featured tag" : "Add featured tag",
|
|
18709
|
+
"aria-pressed": featuredTag,
|
|
18710
|
+
active: featuredTag,
|
|
18711
|
+
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
18712
|
+
className: "size-8",
|
|
18713
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Star, { size: 16, fill: featuredTag ? "currentColor" : "none", style: { pointerEvents: "none" } })
|
|
18714
|
+
}
|
|
18715
|
+
) }),
|
|
18716
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Remove featured tag" : "Add featured tag" })
|
|
18717
|
+
] }),
|
|
18718
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18719
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}) }),
|
|
18720
|
+
/* @__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: [
|
|
18721
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}),
|
|
18722
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
18723
|
+
] }) }),
|
|
18724
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FeatureGlyph, { mode: "add" }) }),
|
|
18725
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FeatureGlyph, { mode: "remove" }) }),
|
|
18726
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18727
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18728
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18729
|
+
]
|
|
18730
|
+
}
|
|
18731
|
+
),
|
|
18732
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18551
18733
|
]
|
|
18552
18734
|
}
|
|
18553
|
-
);
|
|
18735
|
+
) });
|
|
18554
18736
|
}
|
|
18555
18737
|
function findPricingCardNode(tree, index) {
|
|
18556
18738
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -18576,25 +18758,13 @@ function AiPricingCardOverlay({
|
|
|
18576
18758
|
activeRef.current = active;
|
|
18577
18759
|
(0, import_react11.useEffect)(() => {
|
|
18578
18760
|
const onMove = (e) => {
|
|
18761
|
+
const ref = cardRefFromTarget(e.target);
|
|
18579
18762
|
const t = e.target;
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
if (!cardEl) {
|
|
18586
|
-
setHover(null);
|
|
18587
|
-
return;
|
|
18588
|
-
}
|
|
18589
|
-
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
18590
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18591
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18592
|
-
const index = Number(cardEl.dataset.ohwPricingIndex);
|
|
18593
|
-
if (!sectionId || Number.isNaN(index)) {
|
|
18594
|
-
setHover(null);
|
|
18595
|
-
return;
|
|
18596
|
-
}
|
|
18597
|
-
setHover({ sectionId, index });
|
|
18763
|
+
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
18764
|
+
setHover((prev) => {
|
|
18765
|
+
const next = ref && !overEditable ? ref : null;
|
|
18766
|
+
return sameRef(prev, next) ? prev : next;
|
|
18767
|
+
});
|
|
18598
18768
|
};
|
|
18599
18769
|
const onLeave = () => setHover(null);
|
|
18600
18770
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -18606,15 +18776,12 @@ function AiPricingCardOverlay({
|
|
|
18606
18776
|
}, []);
|
|
18607
18777
|
(0, import_react11.useEffect)(() => {
|
|
18608
18778
|
const onClick = (e) => {
|
|
18609
|
-
const current = activeRef.current;
|
|
18610
|
-
if (!current) return;
|
|
18611
18779
|
const t = e.target;
|
|
18612
|
-
if (!(t instanceof
|
|
18613
|
-
if (t.closest(
|
|
18614
|
-
const
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
setError(null);
|
|
18780
|
+
if (!(t instanceof Element)) return;
|
|
18781
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
18782
|
+
const ref = cardRefFromTarget(t);
|
|
18783
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
18784
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
18618
18785
|
};
|
|
18619
18786
|
document.addEventListener("click", onClick, true);
|
|
18620
18787
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -18632,6 +18799,7 @@ function AiPricingCardOverlay({
|
|
|
18632
18799
|
const onKeyDown = (e) => {
|
|
18633
18800
|
if (e.key !== "Escape") return;
|
|
18634
18801
|
if (!activeRef.current) return;
|
|
18802
|
+
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
18635
18803
|
setActive(null);
|
|
18636
18804
|
setError(null);
|
|
18637
18805
|
};
|
|
@@ -18677,72 +18845,52 @@ function AiPricingCardOverlay({
|
|
|
18677
18845
|
);
|
|
18678
18846
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18679
18847
|
const activeCardRect = useLiveCardRect(active);
|
|
18680
|
-
const
|
|
18848
|
+
const activeGridRect = useLiveCardRect(active, true);
|
|
18849
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
18681
18850
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
18682
|
-
|
|
18683
|
-
|
|
18684
|
-
{
|
|
18685
|
-
|
|
18686
|
-
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
}
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
|
|
18717
|
-
|
|
18718
|
-
|
|
18719
|
-
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
18725
|
-
(applied) => {
|
|
18726
|
-
if (applied) setActive(null);
|
|
18727
|
-
}
|
|
18728
|
-
);
|
|
18729
|
-
},
|
|
18730
|
-
onToggleFeatured: (enabled) => runMutation(
|
|
18731
|
-
active.sectionId,
|
|
18732
|
-
(tree) => setPricingCardFeatured(tree, active.index, { enabled })
|
|
18733
|
-
),
|
|
18734
|
-
onSetTreatment: (treatment) => runMutation(
|
|
18735
|
-
active.sectionId,
|
|
18736
|
-
(tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
|
|
18737
|
-
),
|
|
18738
|
-
onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
|
|
18739
|
-
onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
|
|
18740
|
-
onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
|
|
18741
|
-
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
18742
|
-
}
|
|
18743
|
-
)
|
|
18744
|
-
}
|
|
18745
|
-
)
|
|
18851
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
18852
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
18853
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
18854
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18855
|
+
PricingCardToolbar,
|
|
18856
|
+
{
|
|
18857
|
+
entry: activeEntry,
|
|
18858
|
+
index: active.index,
|
|
18859
|
+
pending,
|
|
18860
|
+
error,
|
|
18861
|
+
onAddTier: () => runMutation(active.sectionId, addPricingTier),
|
|
18862
|
+
onRemoveTier: () => {
|
|
18863
|
+
void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
|
|
18864
|
+
(applied) => {
|
|
18865
|
+
if (applied) setActive(null);
|
|
18866
|
+
}
|
|
18867
|
+
);
|
|
18868
|
+
},
|
|
18869
|
+
onSetFeaturedTag: (on) => runMutation(active.sectionId, (tree) => setPricingCardFeaturedTag(tree, active.index, on)),
|
|
18870
|
+
onSetStyle: (style) => runMutation(active.sectionId, (tree) => setPricingCardStyle(tree, active.index, style)),
|
|
18871
|
+
onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
|
|
18872
|
+
onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
|
|
18873
|
+
onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
|
|
18874
|
+
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
18875
|
+
}
|
|
18876
|
+
) }),
|
|
18877
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18878
|
+
"div",
|
|
18879
|
+
{
|
|
18880
|
+
"data-ohw-bridge": "",
|
|
18881
|
+
"data-ohw-item-interaction": "",
|
|
18882
|
+
"aria-hidden": true,
|
|
18883
|
+
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
18884
|
+
style: {
|
|
18885
|
+
top: activeCardRect.top + activeCardRect.height + 10,
|
|
18886
|
+
left: activeCardRect.left - 5,
|
|
18887
|
+
background: PRIMARY4,
|
|
18888
|
+
zIndex: 2147483644
|
|
18889
|
+
},
|
|
18890
|
+
children: "Pricing card"
|
|
18891
|
+
}
|
|
18892
|
+
)
|
|
18893
|
+
] })
|
|
18746
18894
|
] });
|
|
18747
18895
|
}
|
|
18748
18896
|
|
|
@@ -18821,8 +18969,8 @@ function extractYouTubeId(input) {
|
|
|
18821
18969
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
18822
18970
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
18823
18971
|
var PRIMARY5 = "#0885FE";
|
|
18824
|
-
var
|
|
18825
|
-
var
|
|
18972
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
18973
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
18826
18974
|
function findVideoBlockElement(sectionId, path) {
|
|
18827
18975
|
const sectionEl = findByInstanceId(sectionId);
|
|
18828
18976
|
if (!sectionEl) return null;
|
|
@@ -18882,7 +19030,7 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
18882
19030
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
18883
19031
|
});
|
|
18884
19032
|
}
|
|
18885
|
-
function
|
|
19033
|
+
function Pill2({
|
|
18886
19034
|
label,
|
|
18887
19035
|
onClick,
|
|
18888
19036
|
disabled
|
|
@@ -18903,7 +19051,7 @@ function Pill3({
|
|
|
18903
19051
|
border: "none",
|
|
18904
19052
|
cursor: disabled ? "default" : "pointer",
|
|
18905
19053
|
background: "#ffffff",
|
|
18906
|
-
color:
|
|
19054
|
+
color: OHW_BLUE_DARK2,
|
|
18907
19055
|
opacity: disabled ? 0.4 : 1,
|
|
18908
19056
|
fontSize: 12,
|
|
18909
19057
|
lineHeight: "16px",
|
|
@@ -18968,7 +19116,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
18968
19116
|
{
|
|
18969
19117
|
style: {
|
|
18970
19118
|
flex: "0 0 auto",
|
|
18971
|
-
color:
|
|
19119
|
+
color: OHW_BLUE_DARK2,
|
|
18972
19120
|
fontSize: 10,
|
|
18973
19121
|
lineHeight: "16px",
|
|
18974
19122
|
fontWeight: 700,
|
|
@@ -19037,7 +19185,7 @@ function VideoToolbar({
|
|
|
19037
19185
|
gap: 6,
|
|
19038
19186
|
alignItems: "center",
|
|
19039
19187
|
width: 280,
|
|
19040
|
-
background:
|
|
19188
|
+
background: OHW_BLUE2,
|
|
19041
19189
|
padding: 8,
|
|
19042
19190
|
borderRadius: 12,
|
|
19043
19191
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19046,7 +19194,7 @@ function VideoToolbar({
|
|
|
19046
19194
|
},
|
|
19047
19195
|
children: [
|
|
19048
19196
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19049
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19197
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19050
19198
|
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19051
19199
|
]
|
|
19052
19200
|
}
|
|
@@ -19281,8 +19429,8 @@ function setCarouselAutoplay(tree, on) {
|
|
|
19281
19429
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
19282
19430
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
19283
19431
|
var PRIMARY6 = "#0885FE";
|
|
19284
|
-
var
|
|
19285
|
-
var
|
|
19432
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
19433
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
19286
19434
|
function findCarouselItemElement(sectionId, index) {
|
|
19287
19435
|
const sectionEl = findByInstanceId(sectionId);
|
|
19288
19436
|
if (!sectionEl) return null;
|
|
@@ -19361,7 +19509,7 @@ function requestAssetPick2(postToParent2) {
|
|
|
19361
19509
|
postToParent2({ type: "ow:asset-pick", id });
|
|
19362
19510
|
});
|
|
19363
19511
|
}
|
|
19364
|
-
function
|
|
19512
|
+
function Pill3({ label, onClick, disabled }) {
|
|
19365
19513
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19366
19514
|
"button",
|
|
19367
19515
|
{
|
|
@@ -19378,7 +19526,7 @@ function Pill4({ label, onClick, disabled }) {
|
|
|
19378
19526
|
border: "none",
|
|
19379
19527
|
cursor: disabled ? "default" : "pointer",
|
|
19380
19528
|
background: "#ffffff",
|
|
19381
|
-
color:
|
|
19529
|
+
color: OHW_BLUE_DARK3,
|
|
19382
19530
|
opacity: disabled ? 0.4 : 1,
|
|
19383
19531
|
fontSize: 12,
|
|
19384
19532
|
lineHeight: "16px",
|
|
@@ -19415,7 +19563,7 @@ function TogglePill({
|
|
|
19415
19563
|
border: "none",
|
|
19416
19564
|
cursor: disabled ? "default" : "pointer",
|
|
19417
19565
|
background: "#ffffff",
|
|
19418
|
-
color:
|
|
19566
|
+
color: OHW_BLUE_DARK3,
|
|
19419
19567
|
opacity: disabled ? 0.4 : 1,
|
|
19420
19568
|
fontSize: 12,
|
|
19421
19569
|
lineHeight: "16px",
|
|
@@ -19438,7 +19586,7 @@ function TogglePill({
|
|
|
19438
19586
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
19439
19587
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
19440
19588
|
// "disabled control" rather than "switch that is off".
|
|
19441
|
-
background: on ?
|
|
19589
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
19442
19590
|
transition: "background 120ms ease"
|
|
19443
19591
|
},
|
|
19444
19592
|
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
@@ -19481,7 +19629,7 @@ function CarouselSlideToolbar({
|
|
|
19481
19629
|
flexDirection: "column",
|
|
19482
19630
|
gap: 6,
|
|
19483
19631
|
alignItems: "center",
|
|
19484
|
-
background:
|
|
19632
|
+
background: OHW_BLUE3,
|
|
19485
19633
|
padding: 8,
|
|
19486
19634
|
borderRadius: 12,
|
|
19487
19635
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19494,7 +19642,7 @@ function CarouselSlideToolbar({
|
|
|
19494
19642
|
},
|
|
19495
19643
|
children: [
|
|
19496
19644
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
19497
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19645
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
19498
19646
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
19499
19647
|
] }),
|
|
19500
19648
|
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
@@ -24142,7 +24290,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
24142
24290
|
el.style.top = `${top}px`;
|
|
24143
24291
|
el.style.height = `${height}px`;
|
|
24144
24292
|
}
|
|
24145
|
-
var
|
|
24293
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
24146
24294
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
24147
24295
|
const isAbove = transform.includes("translateY(-100%)");
|
|
24148
24296
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -24169,8 +24317,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
24169
24317
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
24170
24318
|
const half = toolbarWidth / 2;
|
|
24171
24319
|
return Math.max(
|
|
24172
|
-
|
|
24173
|
-
Math.min(centerX, window.innerWidth -
|
|
24320
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
24321
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
24174
24322
|
);
|
|
24175
24323
|
}
|
|
24176
24324
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -30857,7 +31005,7 @@ function OhhwellsBridge() {
|
|
|
30857
31005
|
postToParent2({
|
|
30858
31006
|
type: "ow:ready",
|
|
30859
31007
|
version: "1",
|
|
30860
|
-
bridgeVersion: "0.1.
|
|
31008
|
+
bridgeVersion: "0.1.137",
|
|
30861
31009
|
path: pathname,
|
|
30862
31010
|
nodes: collectEditableNodes(editContentRef.current),
|
|
30863
31011
|
sections
|