@ohhwells/bridge 0.1.148 → 0.1.149-next.400
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 +860 -724
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +898 -746
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +1 -1
- package/dist/pages.cjs.map +1 -1
- package/dist/pages.js +1 -1
- package/dist/pages.js.map +1 -1
- package/dist/styles.css +116 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as
|
|
4
|
+
import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as useLayoutEffect7, useRef as useRef14, useState as useState18 } from "react";
|
|
5
5
|
import { createRoot as createRoot3 } from "react-dom/client";
|
|
6
6
|
import { flushSync as flushSync3 } from "react-dom";
|
|
7
7
|
|
|
@@ -1631,7 +1631,8 @@ function labelElement2(el) {
|
|
|
1631
1631
|
return el.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? el.querySelector("[data-ohw-key]");
|
|
1632
1632
|
}
|
|
1633
1633
|
function buttonLabel(el) {
|
|
1634
|
-
|
|
1634
|
+
const label = labelElement2(el);
|
|
1635
|
+
return (label ? label.innerHTML : el.textContent ?? "").trim();
|
|
1635
1636
|
}
|
|
1636
1637
|
function buttonHref(el) {
|
|
1637
1638
|
return el.getAttribute("href") ?? "";
|
|
@@ -1770,7 +1771,7 @@ function duplicateButton(source, content) {
|
|
|
1770
1771
|
stampVariantClass(copy, copyAssignment.variant);
|
|
1771
1772
|
applyButtonStyle(copy, copyAssignment, paintedTokensOf(source) ?? tokens);
|
|
1772
1773
|
const copyLabelEl = labelElement2(copy);
|
|
1773
|
-
if (copyLabelEl) copyLabelEl.
|
|
1774
|
+
if (copyLabelEl) copyLabelEl.innerHTML = label;
|
|
1774
1775
|
let collection = buttonCollectionOf(source);
|
|
1775
1776
|
const collections = readCollections(content);
|
|
1776
1777
|
let collectionId = collection?.getAttribute(COLLECTION_ATTR) ?? "";
|
|
@@ -2096,7 +2097,7 @@ function applySnapshotContent(el, snapshot, content) {
|
|
|
2096
2097
|
const label = labelElement2(el);
|
|
2097
2098
|
if (label) {
|
|
2098
2099
|
if (label.getAttribute("data-ohw-key") !== labelKey) label.setAttribute("data-ohw-key", labelKey);
|
|
2099
|
-
if (label.
|
|
2100
|
+
if (label.innerHTML !== text) label.innerHTML = text;
|
|
2100
2101
|
}
|
|
2101
2102
|
}
|
|
2102
2103
|
function reconcileButtonCollections(doc, content) {
|
|
@@ -4181,7 +4182,7 @@ function buildNavLink(index, href, label, template) {
|
|
|
4181
4182
|
const span = document.createElement("span");
|
|
4182
4183
|
span.setAttribute("data-ohw-editable", "text");
|
|
4183
4184
|
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
4184
|
-
span.
|
|
4185
|
+
span.innerHTML = label;
|
|
4185
4186
|
anchor.appendChild(span);
|
|
4186
4187
|
return anchor;
|
|
4187
4188
|
}
|
|
@@ -6541,6 +6542,21 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6541
6542
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6542
6543
|
return target ? pricingFeatureList(target).length : 0;
|
|
6543
6544
|
}
|
|
6545
|
+
function prevailingFeatureIcon(features) {
|
|
6546
|
+
const counts = /* @__PURE__ */ new Map();
|
|
6547
|
+
for (const row of features) {
|
|
6548
|
+
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6549
|
+
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6550
|
+
entry.count += 1;
|
|
6551
|
+
counts.set(key, entry);
|
|
6552
|
+
}
|
|
6553
|
+
let best = null;
|
|
6554
|
+
for (const entry of counts.values()) {
|
|
6555
|
+
if (!best || entry.count > best.count) best = entry;
|
|
6556
|
+
}
|
|
6557
|
+
if (!best) return {};
|
|
6558
|
+
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6559
|
+
}
|
|
6544
6560
|
function addPricingCardFeature(tree, index, text) {
|
|
6545
6561
|
return withPricingCollection(tree, (collection) => {
|
|
6546
6562
|
const children = collection.children;
|
|
@@ -6549,7 +6565,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6549
6565
|
const features = pricingFeatureList(target);
|
|
6550
6566
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6551
6567
|
target.slots = target.slots ?? {};
|
|
6552
|
-
target.slots.features = [...features, { text }];
|
|
6568
|
+
target.slots.features = [...features, { text, ...prevailingFeatureIcon(features) }];
|
|
6553
6569
|
return true;
|
|
6554
6570
|
});
|
|
6555
6571
|
}
|
|
@@ -7732,7 +7748,7 @@ var AI_MOBILE_CSS = [
|
|
|
7732
7748
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7733
7749
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7734
7750
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7735
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7751
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-section-inner`.
|
|
7736
7752
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7737
7753
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7738
7754
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7748,8 +7764,10 @@ var AI_MOBILE_CSS = [
|
|
|
7748
7764
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7749
7765
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7750
7766
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7751
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7752
|
-
|
|
7767
|
+
// still got a 20px band of section background down both sides on a phone. The footer's own
|
|
7768
|
+
// container keeps the unguarded rule below — `data-ai-full-bleed` can never appear on it.
|
|
7769
|
+
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7770
|
+
"[data-ai-container]{padding:0 20px !important}",
|
|
7753
7771
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7754
7772
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7755
7773
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -7954,6 +7972,31 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
7954
7972
|
function textAttrs(ctx, path) {
|
|
7955
7973
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
7956
7974
|
}
|
|
7975
|
+
var AI_RESPONSIVE_CSS = [
|
|
7976
|
+
"@media (max-width: 960px) {",
|
|
7977
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
7978
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
7979
|
+
"}",
|
|
7980
|
+
"@media (max-width: 640px) {",
|
|
7981
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
7982
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
7983
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
7984
|
+
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
7985
|
+
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
7986
|
+
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
7987
|
+
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
7988
|
+
// layered text used to be.
|
|
7989
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
7990
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
7991
|
+
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
7992
|
+
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
7993
|
+
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
7994
|
+
// other rule had already been taught to stand down.
|
|
7995
|
+
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
7996
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
7997
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
7998
|
+
"}"
|
|
7999
|
+
].join("\n");
|
|
7957
8000
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
7958
8001
|
function MediaBox({
|
|
7959
8002
|
refValue,
|
|
@@ -8008,7 +8051,7 @@ function MediaBox({
|
|
|
8008
8051
|
position: fill ? "absolute" : void 0,
|
|
8009
8052
|
inset: fill ? 0 : void 0,
|
|
8010
8053
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8011
|
-
height: fill ? "100%" : void 0,
|
|
8054
|
+
height: fill ? "100%" : fixedSize ? height : void 0,
|
|
8012
8055
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8013
8056
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8014
8057
|
borderRadius: radius,
|
|
@@ -9504,7 +9547,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9504
9547
|
return /* @__PURE__ */ jsx(
|
|
9505
9548
|
"div",
|
|
9506
9549
|
{
|
|
9507
|
-
"data-ai-grid":
|
|
9550
|
+
"data-ai-grid": String(itemsPerRow),
|
|
9508
9551
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9509
9552
|
style: {
|
|
9510
9553
|
display: "grid",
|
|
@@ -9806,7 +9849,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9806
9849
|
},
|
|
9807
9850
|
children: [
|
|
9808
9851
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
9809
|
-
// The section's `data-ai-
|
|
9852
|
+
// The section's `data-ai-section-inner` gave up its max-width/gutter so the base
|
|
9810
9853
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9811
9854
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9812
9855
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10225,6 +10268,7 @@ function AiTreeRenderer({
|
|
|
10225
10268
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10226
10269
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10227
10270
|
...bgAttrs,
|
|
10271
|
+
"data-ai-responsive": "",
|
|
10228
10272
|
style: {
|
|
10229
10273
|
position: "relative",
|
|
10230
10274
|
padding: `${padCss} 0`,
|
|
@@ -10238,12 +10282,13 @@ function AiTreeRenderer({
|
|
|
10238
10282
|
...fillHeight ? { display: "grid" } : {}
|
|
10239
10283
|
},
|
|
10240
10284
|
children: [
|
|
10241
|
-
|
|
10285
|
+
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
10242
10286
|
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10287
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10243
10288
|
/* @__PURE__ */ jsx(
|
|
10244
10289
|
"div",
|
|
10245
10290
|
{
|
|
10246
|
-
"data-ai-
|
|
10291
|
+
"data-ai-section-inner": "",
|
|
10247
10292
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10248
10293
|
style: {
|
|
10249
10294
|
position: "relative",
|
|
@@ -10260,7 +10305,7 @@ function AiTreeRenderer({
|
|
|
10260
10305
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
10261
10306
|
"div",
|
|
10262
10307
|
{
|
|
10263
|
-
"data-ai-
|
|
10308
|
+
"data-ai-columns": "",
|
|
10264
10309
|
style: {
|
|
10265
10310
|
display: "grid",
|
|
10266
10311
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -10285,7 +10330,12 @@ function AiTreeRenderer({
|
|
|
10285
10330
|
// the full row height instead of clumping at the top.
|
|
10286
10331
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
10287
10332
|
},
|
|
10288
|
-
children: renderNode(
|
|
10333
|
+
children: renderNode(
|
|
10334
|
+
block,
|
|
10335
|
+
ctx,
|
|
10336
|
+
`r${r2}.b${b}`,
|
|
10337
|
+
settings.alignment === "center" ? "center" : "left"
|
|
10338
|
+
)
|
|
10289
10339
|
},
|
|
10290
10340
|
b
|
|
10291
10341
|
))
|
|
@@ -10917,9 +10967,10 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10917
10967
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
10918
10968
|
continue;
|
|
10919
10969
|
}
|
|
10920
|
-
const isNewMount = !existing || !existing.container.isConnected;
|
|
10921
10970
|
let container = existing?.container;
|
|
10971
|
+
let isNewMount = false;
|
|
10922
10972
|
if (!container || !container.isConnected) {
|
|
10973
|
+
isNewMount = true;
|
|
10923
10974
|
existing?.root.unmount();
|
|
10924
10975
|
container?.remove();
|
|
10925
10976
|
container = document.createElement("div");
|
|
@@ -17361,6 +17412,7 @@ function MediaOverlay({
|
|
|
17361
17412
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
17362
17413
|
);
|
|
17363
17414
|
}, [isVideo]);
|
|
17415
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
17364
17416
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
17365
17417
|
const box = {
|
|
17366
17418
|
position: "fixed",
|
|
@@ -17459,11 +17511,10 @@ function MediaOverlay({
|
|
|
17459
17511
|
className: "flex items-center justify-center cursor-pointer",
|
|
17460
17512
|
style: {
|
|
17461
17513
|
...box,
|
|
17462
|
-
//
|
|
17463
|
-
//
|
|
17464
|
-
//
|
|
17465
|
-
|
|
17466
|
-
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
17514
|
+
// Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
|
|
17515
|
+
// (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
|
|
17516
|
+
// and cueOnly also need clicks to fall through — Replace / video controls opt back in.
|
|
17517
|
+
pointerEvents: "none",
|
|
17467
17518
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
17468
17519
|
// than hovered. Hover keeps the existing tinted preview.
|
|
17469
17520
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -17490,17 +17541,17 @@ function MediaOverlay({
|
|
|
17490
17541
|
},
|
|
17491
17542
|
children: [
|
|
17492
17543
|
isVideo ? /* @__PURE__ */ jsx16(Film, { size: 14 }) : /* @__PURE__ */ jsx16(ImageIcon, { size: 14 }),
|
|
17493
|
-
|
|
17544
|
+
replaceLabel
|
|
17494
17545
|
]
|
|
17495
17546
|
}
|
|
17496
17547
|
),
|
|
17497
|
-
replaceMode
|
|
17548
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ jsxs7(
|
|
17498
17549
|
Button,
|
|
17499
17550
|
{
|
|
17500
17551
|
"data-ohw-media-overlay": "",
|
|
17501
17552
|
variant: "outline",
|
|
17502
17553
|
size: "sm",
|
|
17503
|
-
"aria-label":
|
|
17554
|
+
"aria-label": replaceLabel,
|
|
17504
17555
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
17505
17556
|
style: {
|
|
17506
17557
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -17523,7 +17574,7 @@ function MediaOverlay({
|
|
|
17523
17574
|
},
|
|
17524
17575
|
children: [
|
|
17525
17576
|
isVideo ? /* @__PURE__ */ jsx16(Film, { size: 14 }) : /* @__PURE__ */ jsx16(ImageIcon, { size: 14 }),
|
|
17526
|
-
replaceMode === "full" ?
|
|
17577
|
+
replaceMode === "full" ? replaceLabel : null
|
|
17527
17578
|
]
|
|
17528
17579
|
}
|
|
17529
17580
|
)
|
|
@@ -18032,8 +18083,24 @@ function AiSectionOverlay({
|
|
|
18032
18083
|
}
|
|
18033
18084
|
|
|
18034
18085
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18035
|
-
import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef5, useState as useState8 } from "react";
|
|
18036
|
-
import {
|
|
18086
|
+
import { useCallback as useCallback3, useEffect as useEffect6, useLayoutEffect as useLayoutEffect4, useRef as useRef5, useState as useState8 } from "react";
|
|
18087
|
+
import {
|
|
18088
|
+
AlignCenter,
|
|
18089
|
+
AlignLeft,
|
|
18090
|
+
AlignRight,
|
|
18091
|
+
ArrowLeft as ArrowLeft2,
|
|
18092
|
+
ArrowRight as ArrowRight2,
|
|
18093
|
+
Check as Check2,
|
|
18094
|
+
ChevronDown as ChevronDown3,
|
|
18095
|
+
Image as ImageIcon2,
|
|
18096
|
+
ImageMinus,
|
|
18097
|
+
ImagePlus,
|
|
18098
|
+
Link as LinkIcon,
|
|
18099
|
+
Minus,
|
|
18100
|
+
Palette,
|
|
18101
|
+
Plus as Plus2,
|
|
18102
|
+
Star
|
|
18103
|
+
} from "lucide-react";
|
|
18037
18104
|
|
|
18038
18105
|
// src/lib/ai-media-strip-tree.ts
|
|
18039
18106
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18147,14 +18214,6 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18147
18214
|
return true;
|
|
18148
18215
|
});
|
|
18149
18216
|
}
|
|
18150
|
-
function setMediaStripItemAlt(tree, index, alt) {
|
|
18151
|
-
return withMediaStrip(tree, (block) => {
|
|
18152
|
-
const items = block.items;
|
|
18153
|
-
if (index < 0 || index >= items.length) return false;
|
|
18154
|
-
items[index] = { ...items[index], alt };
|
|
18155
|
-
return true;
|
|
18156
|
-
});
|
|
18157
|
-
}
|
|
18158
18217
|
function setMediaStripItemLink(tree, index, link) {
|
|
18159
18218
|
return withMediaStrip(tree, (block) => {
|
|
18160
18219
|
const items = block.items;
|
|
@@ -18172,11 +18231,117 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18172
18231
|
});
|
|
18173
18232
|
}
|
|
18174
18233
|
|
|
18234
|
+
// src/ui/dialog.tsx
|
|
18235
|
+
import * as React9 from "react";
|
|
18236
|
+
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
18237
|
+
import { X as X2 } from "lucide-react";
|
|
18238
|
+
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
18239
|
+
function Dialog2({
|
|
18240
|
+
...props
|
|
18241
|
+
}) {
|
|
18242
|
+
return /* @__PURE__ */ jsx19(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
18243
|
+
}
|
|
18244
|
+
function DialogPortal({
|
|
18245
|
+
...props
|
|
18246
|
+
}) {
|
|
18247
|
+
return /* @__PURE__ */ jsx19(DialogPrimitive.Portal, { ...props });
|
|
18248
|
+
}
|
|
18249
|
+
function DialogOverlay({
|
|
18250
|
+
className,
|
|
18251
|
+
...props
|
|
18252
|
+
}) {
|
|
18253
|
+
return /* @__PURE__ */ jsx19(
|
|
18254
|
+
DialogPrimitive.Overlay,
|
|
18255
|
+
{
|
|
18256
|
+
"data-slot": "dialog-overlay",
|
|
18257
|
+
"data-ohw-link-modal-root": "",
|
|
18258
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18259
|
+
...props
|
|
18260
|
+
}
|
|
18261
|
+
);
|
|
18262
|
+
}
|
|
18263
|
+
var DialogContent = React9.forwardRef(
|
|
18264
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18265
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
18266
|
+
return /* @__PURE__ */ jsxs10(DialogPortal, { container: container ?? void 0, children: [
|
|
18267
|
+
/* @__PURE__ */ jsx19(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18268
|
+
/* @__PURE__ */ jsxs10(
|
|
18269
|
+
DialogPrimitive.Content,
|
|
18270
|
+
{
|
|
18271
|
+
ref,
|
|
18272
|
+
"data-slot": "dialog-content",
|
|
18273
|
+
className: cn(
|
|
18274
|
+
positionMode,
|
|
18275
|
+
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[448px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-visible",
|
|
18276
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18277
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18278
|
+
className
|
|
18279
|
+
),
|
|
18280
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
18281
|
+
...props,
|
|
18282
|
+
children: [
|
|
18283
|
+
children,
|
|
18284
|
+
showCloseButton ? /* @__PURE__ */ jsx19(
|
|
18285
|
+
DialogPrimitive.Close,
|
|
18286
|
+
{
|
|
18287
|
+
type: "button",
|
|
18288
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18289
|
+
"aria-label": "Close",
|
|
18290
|
+
children: /* @__PURE__ */ jsx19(X2, { size: 16, "aria-hidden": true })
|
|
18291
|
+
}
|
|
18292
|
+
) : null
|
|
18293
|
+
]
|
|
18294
|
+
}
|
|
18295
|
+
)
|
|
18296
|
+
] });
|
|
18297
|
+
}
|
|
18298
|
+
);
|
|
18299
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
18300
|
+
function DialogHeader({
|
|
18301
|
+
className,
|
|
18302
|
+
...props
|
|
18303
|
+
}) {
|
|
18304
|
+
return /* @__PURE__ */ jsx19("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18305
|
+
}
|
|
18306
|
+
function DialogFooter({
|
|
18307
|
+
className,
|
|
18308
|
+
...props
|
|
18309
|
+
}) {
|
|
18310
|
+
return /* @__PURE__ */ jsx19(
|
|
18311
|
+
"div",
|
|
18312
|
+
{
|
|
18313
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
18314
|
+
...props
|
|
18315
|
+
}
|
|
18316
|
+
);
|
|
18317
|
+
}
|
|
18318
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
18319
|
+
DialogPrimitive.Title,
|
|
18320
|
+
{
|
|
18321
|
+
ref,
|
|
18322
|
+
className: cn(
|
|
18323
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18324
|
+
className
|
|
18325
|
+
),
|
|
18326
|
+
...props
|
|
18327
|
+
}
|
|
18328
|
+
));
|
|
18329
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
18330
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
18331
|
+
DialogPrimitive.Description,
|
|
18332
|
+
{
|
|
18333
|
+
ref,
|
|
18334
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
18335
|
+
...props
|
|
18336
|
+
}
|
|
18337
|
+
));
|
|
18338
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
18339
|
+
var DialogClose = DialogPrimitive.Close;
|
|
18340
|
+
|
|
18175
18341
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18176
|
-
import { Fragment as Fragment6, jsx as
|
|
18177
|
-
var PRIMARY3 = "#0885FE";
|
|
18178
|
-
var
|
|
18179
|
-
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
18342
|
+
import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
18343
|
+
var PRIMARY3 = "var(--ohw-primary, #0885FE)";
|
|
18344
|
+
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]";
|
|
18180
18345
|
function findMediaStripItemElement(sectionId, index) {
|
|
18181
18346
|
const sectionEl = findByInstanceId(sectionId);
|
|
18182
18347
|
if (!sectionEl) return null;
|
|
@@ -18186,14 +18351,35 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18186
18351
|
}
|
|
18187
18352
|
return null;
|
|
18188
18353
|
}
|
|
18189
|
-
function
|
|
18190
|
-
|
|
18354
|
+
function itemRefFromTarget(target) {
|
|
18355
|
+
if (!(target instanceof Element)) return null;
|
|
18356
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18357
|
+
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18358
|
+
if (!itemEl) return null;
|
|
18359
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18360
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18361
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18362
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18363
|
+
if (!sectionId || Number.isNaN(index)) return null;
|
|
18364
|
+
return { sectionId, index };
|
|
18365
|
+
}
|
|
18366
|
+
function sameRef(a, b) {
|
|
18367
|
+
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18368
|
+
}
|
|
18369
|
+
function rectOf(el) {
|
|
18191
18370
|
if (!el) return null;
|
|
18192
18371
|
const r2 = el.getBoundingClientRect();
|
|
18193
18372
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18194
18373
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18195
18374
|
}
|
|
18196
|
-
function
|
|
18375
|
+
function readRect2(ref) {
|
|
18376
|
+
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18377
|
+
}
|
|
18378
|
+
function readStripRect(ref) {
|
|
18379
|
+
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18380
|
+
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18381
|
+
}
|
|
18382
|
+
function useLiveItemRect(ref, strip = false) {
|
|
18197
18383
|
const [rect, setRect] = useState8(null);
|
|
18198
18384
|
useEffect6(() => {
|
|
18199
18385
|
if (!ref) {
|
|
@@ -18201,7 +18387,7 @@ function useLiveItemRect(ref) {
|
|
|
18201
18387
|
return;
|
|
18202
18388
|
}
|
|
18203
18389
|
const update = () => {
|
|
18204
|
-
const next = readRect2(ref);
|
|
18390
|
+
const next = strip ? readStripRect(ref) : readRect2(ref);
|
|
18205
18391
|
setRect(
|
|
18206
18392
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18207
18393
|
);
|
|
@@ -18216,9 +18402,49 @@ function useLiveItemRect(ref) {
|
|
|
18216
18402
|
window.removeEventListener("resize", update);
|
|
18217
18403
|
clearInterval(interval);
|
|
18218
18404
|
};
|
|
18219
|
-
}, [ref?.sectionId, ref?.index]);
|
|
18405
|
+
}, [ref?.sectionId, ref?.index, strip]);
|
|
18220
18406
|
return rect;
|
|
18221
18407
|
}
|
|
18408
|
+
var TOOLBAR_STRIP_GAP = 52;
|
|
18409
|
+
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18410
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18411
|
+
function StripToolbarSlot({ stripRect, children }) {
|
|
18412
|
+
const slotRef = useRef5(null);
|
|
18413
|
+
const [shift, setShift] = useState8(0);
|
|
18414
|
+
const centerX = stripRect.left + stripRect.width / 2;
|
|
18415
|
+
useLayoutEffect4(() => {
|
|
18416
|
+
const slot = slotRef.current;
|
|
18417
|
+
if (!slot) return;
|
|
18418
|
+
const clamp = () => {
|
|
18419
|
+
const w = slot.offsetWidth;
|
|
18420
|
+
if (w <= 0) return;
|
|
18421
|
+
const half = w / 2;
|
|
18422
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18423
|
+
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18424
|
+
};
|
|
18425
|
+
clamp();
|
|
18426
|
+
const ro = new ResizeObserver(clamp);
|
|
18427
|
+
ro.observe(slot);
|
|
18428
|
+
return () => ro.disconnect();
|
|
18429
|
+
}, [centerX, children]);
|
|
18430
|
+
const mobile = window.innerWidth <= 480;
|
|
18431
|
+
return /* @__PURE__ */ jsx20(
|
|
18432
|
+
"div",
|
|
18433
|
+
{
|
|
18434
|
+
ref: slotRef,
|
|
18435
|
+
"data-ohw-bridge": "",
|
|
18436
|
+
"data-ohw-item-interaction": "",
|
|
18437
|
+
className: "pointer-events-auto fixed",
|
|
18438
|
+
style: {
|
|
18439
|
+
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18440
|
+
left: centerX + shift,
|
|
18441
|
+
transform: "translate(-50%, -100%)",
|
|
18442
|
+
zIndex: 2147483645
|
|
18443
|
+
},
|
|
18444
|
+
children
|
|
18445
|
+
}
|
|
18446
|
+
);
|
|
18447
|
+
}
|
|
18222
18448
|
function requestValidateTree(postToParent2, tree) {
|
|
18223
18449
|
return new Promise((resolve) => {
|
|
18224
18450
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18255,221 +18481,177 @@ function requestAssetPick(postToParent2) {
|
|
|
18255
18481
|
postToParent2({ type: "ow:asset-pick", id });
|
|
18256
18482
|
});
|
|
18257
18483
|
}
|
|
18258
|
-
function
|
|
18484
|
+
function ToolbarAction({
|
|
18259
18485
|
label,
|
|
18260
18486
|
onClick,
|
|
18261
|
-
disabled,
|
|
18262
|
-
active
|
|
18487
|
+
disabled = false,
|
|
18488
|
+
active = false,
|
|
18489
|
+
children
|
|
18263
18490
|
}) {
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
{
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
disabled,
|
|
18270
|
-
style: {
|
|
18271
|
-
height: 28,
|
|
18272
|
-
padding: "0 10px",
|
|
18273
|
-
display: "inline-flex",
|
|
18274
|
-
alignItems: "center",
|
|
18275
|
-
gap: 4,
|
|
18276
|
-
borderRadius: 999,
|
|
18277
|
-
border: "none",
|
|
18278
|
-
cursor: disabled ? "default" : "pointer",
|
|
18279
|
-
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18280
|
-
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18281
|
-
opacity: disabled ? 0.4 : 1,
|
|
18282
|
-
fontSize: 12,
|
|
18283
|
-
lineHeight: "16px",
|
|
18284
|
-
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18285
|
-
whiteSpace: "nowrap",
|
|
18286
|
-
flex: "0 0 auto"
|
|
18287
|
-
},
|
|
18288
|
-
children: label
|
|
18289
|
-
}
|
|
18290
|
-
);
|
|
18491
|
+
const button = /* @__PURE__ */ jsx20(CustomToolbarButton, { type: "button", "aria-label": label, disabled, active, onClick, className: "size-8", children });
|
|
18492
|
+
return /* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18493
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: button }) : button }),
|
|
18494
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
18495
|
+
] });
|
|
18291
18496
|
}
|
|
18292
|
-
function
|
|
18293
|
-
|
|
18294
|
-
useEffect6(() => setDraft(value), [value]);
|
|
18295
|
-
return /* @__PURE__ */ jsxs10(
|
|
18296
|
-
"div",
|
|
18297
|
-
{
|
|
18298
|
-
style: {
|
|
18299
|
-
display: "flex",
|
|
18300
|
-
alignItems: "center",
|
|
18301
|
-
gap: 6,
|
|
18302
|
-
height: 28,
|
|
18303
|
-
padding: "0 12px",
|
|
18304
|
-
borderRadius: 999,
|
|
18305
|
-
background: "#ffffff",
|
|
18306
|
-
width: "100%",
|
|
18307
|
-
maxWidth: 260,
|
|
18308
|
-
boxSizing: "border-box"
|
|
18309
|
-
},
|
|
18310
|
-
children: [
|
|
18311
|
-
/* @__PURE__ */ jsx19(
|
|
18312
|
-
"span",
|
|
18313
|
-
{
|
|
18314
|
-
style: {
|
|
18315
|
-
flex: "0 0 auto",
|
|
18316
|
-
color: OHW_BLUE_DARK,
|
|
18317
|
-
fontSize: 10,
|
|
18318
|
-
fontWeight: 700,
|
|
18319
|
-
textTransform: "uppercase",
|
|
18320
|
-
letterSpacing: 0.4
|
|
18321
|
-
},
|
|
18322
|
-
children: "Alt"
|
|
18323
|
-
}
|
|
18324
|
-
),
|
|
18325
|
-
/* @__PURE__ */ jsx19(
|
|
18326
|
-
"input",
|
|
18327
|
-
{
|
|
18328
|
-
type: "text",
|
|
18329
|
-
value: draft,
|
|
18330
|
-
onChange: (e) => setDraft(e.target.value),
|
|
18331
|
-
onBlur: () => {
|
|
18332
|
-
if (draft !== value) onCommit(draft);
|
|
18333
|
-
},
|
|
18334
|
-
onKeyDown: (e) => {
|
|
18335
|
-
if (e.key === "Enter") e.currentTarget.blur();
|
|
18336
|
-
if (e.key === "Escape") {
|
|
18337
|
-
setDraft(value);
|
|
18338
|
-
e.currentTarget.blur();
|
|
18339
|
-
}
|
|
18340
|
-
},
|
|
18341
|
-
placeholder: "Describe this image",
|
|
18342
|
-
"aria-label": "Image alt text",
|
|
18343
|
-
style: {
|
|
18344
|
-
flex: 1,
|
|
18345
|
-
minWidth: 0,
|
|
18346
|
-
border: "none",
|
|
18347
|
-
outline: "none",
|
|
18348
|
-
background: "transparent",
|
|
18349
|
-
fontSize: 12,
|
|
18350
|
-
lineHeight: "16px",
|
|
18351
|
-
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18352
|
-
color: "#1f2937"
|
|
18353
|
-
}
|
|
18354
|
-
}
|
|
18355
|
-
)
|
|
18356
|
-
]
|
|
18357
|
-
}
|
|
18358
|
-
);
|
|
18497
|
+
function ToolbarSeparator() {
|
|
18498
|
+
return /* @__PURE__ */ jsx20("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
18359
18499
|
}
|
|
18360
|
-
|
|
18361
|
-
|
|
18362
|
-
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
|
|
18369
|
-
|
|
18370
|
-
|
|
18371
|
-
|
|
18372
|
-
|
|
18373
|
-
|
|
18374
|
-
|
|
18375
|
-
|
|
18376
|
-
|
|
18377
|
-
|
|
18378
|
-
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
|
|
18383
|
-
|
|
18384
|
-
|
|
18385
|
-
|
|
18386
|
-
}, [value]);
|
|
18387
|
-
const commit = () => {
|
|
18388
|
-
const next = draft.trim();
|
|
18389
|
-
if (next === value) return setInvalid(false);
|
|
18390
|
-
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
18391
|
-
setInvalid(false);
|
|
18392
|
-
onCommit(next);
|
|
18393
|
-
};
|
|
18394
|
-
return /* @__PURE__ */ jsxs10(
|
|
18395
|
-
"div",
|
|
18396
|
-
{
|
|
18397
|
-
style: {
|
|
18398
|
-
display: "flex",
|
|
18399
|
-
alignItems: "center",
|
|
18400
|
-
gap: 6,
|
|
18401
|
-
height: 28,
|
|
18402
|
-
padding: "0 12px",
|
|
18403
|
-
borderRadius: 999,
|
|
18404
|
-
background: "#ffffff",
|
|
18405
|
-
width: "100%",
|
|
18406
|
-
maxWidth: 260,
|
|
18407
|
-
boxSizing: "border-box",
|
|
18408
|
-
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18409
|
-
},
|
|
18410
|
-
children: [
|
|
18411
|
-
/* @__PURE__ */ jsx19(
|
|
18412
|
-
"span",
|
|
18413
|
-
{
|
|
18414
|
-
style: {
|
|
18415
|
-
flex: "0 0 auto",
|
|
18416
|
-
color: OHW_BLUE_DARK,
|
|
18417
|
-
fontSize: 10,
|
|
18418
|
-
fontWeight: 700,
|
|
18419
|
-
textTransform: "uppercase",
|
|
18420
|
-
letterSpacing: 0.4
|
|
18421
|
-
},
|
|
18422
|
-
children: "Link"
|
|
18423
|
-
}
|
|
18424
|
-
),
|
|
18425
|
-
/* @__PURE__ */ jsx19(
|
|
18426
|
-
"input",
|
|
18500
|
+
function OptionMenu({
|
|
18501
|
+
label,
|
|
18502
|
+
value,
|
|
18503
|
+
options,
|
|
18504
|
+
onChange
|
|
18505
|
+
}) {
|
|
18506
|
+
const current = options.find((o) => o.value === value) ?? options[0];
|
|
18507
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18508
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: label }),
|
|
18509
|
+
/* @__PURE__ */ jsxs11(DropdownMenu, { modal: false, children: [
|
|
18510
|
+
/* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
|
|
18511
|
+
"button",
|
|
18512
|
+
{
|
|
18513
|
+
type: "button",
|
|
18514
|
+
"aria-label": label,
|
|
18515
|
+
className: "inline-flex h-8 min-w-[76px] 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",
|
|
18516
|
+
children: [
|
|
18517
|
+
/* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
|
|
18518
|
+
/* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
18519
|
+
]
|
|
18520
|
+
}
|
|
18521
|
+
) }),
|
|
18522
|
+
/* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
18523
|
+
const selected = option.value === value;
|
|
18524
|
+
return /* @__PURE__ */ jsxs11(
|
|
18525
|
+
DropdownMenuItem,
|
|
18427
18526
|
{
|
|
18428
|
-
|
|
18429
|
-
|
|
18430
|
-
|
|
18431
|
-
|
|
18432
|
-
|
|
18433
|
-
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
|
|
18437
|
-
|
|
18438
|
-
|
|
18439
|
-
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18446
|
-
|
|
18447
|
-
|
|
18448
|
-
|
|
18449
|
-
|
|
18450
|
-
|
|
18451
|
-
|
|
18452
|
-
|
|
18453
|
-
|
|
18454
|
-
|
|
18455
|
-
|
|
18456
|
-
|
|
18457
|
-
|
|
18527
|
+
role: "menuitemradio",
|
|
18528
|
+
"aria-checked": selected,
|
|
18529
|
+
onSelect: () => onChange(option.value),
|
|
18530
|
+
className: cn("grid grid-cols-[1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
18531
|
+
children: [
|
|
18532
|
+
/* @__PURE__ */ jsx20("span", { children: option.label }),
|
|
18533
|
+
selected && /* @__PURE__ */ jsx20(Check2, { size: 16, className: "text-bridge-primary" })
|
|
18534
|
+
]
|
|
18535
|
+
},
|
|
18536
|
+
option.value
|
|
18537
|
+
);
|
|
18538
|
+
}) })
|
|
18539
|
+
] })
|
|
18540
|
+
] });
|
|
18541
|
+
}
|
|
18542
|
+
var VARIANTS = [
|
|
18543
|
+
{ value: "logos", label: "Logos" },
|
|
18544
|
+
{ value: "reel", label: "Reel" }
|
|
18545
|
+
];
|
|
18546
|
+
var ALIGNS = [
|
|
18547
|
+
{ value: "left", label: "Align left", Icon: AlignLeft },
|
|
18548
|
+
{ value: "center", label: "Align center", Icon: AlignCenter },
|
|
18549
|
+
{ value: "right", label: "Align right", Icon: AlignRight }
|
|
18550
|
+
];
|
|
18551
|
+
var HOVERS = [
|
|
18552
|
+
{ value: "none", label: "None" },
|
|
18553
|
+
{ value: "lift", label: "Lift" },
|
|
18554
|
+
{ value: "zoom", label: "Zoom" },
|
|
18555
|
+
{ value: "fade", label: "Fade" }
|
|
18556
|
+
];
|
|
18557
|
+
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18558
|
+
function LinkModal({
|
|
18559
|
+
href,
|
|
18560
|
+
linkTarget,
|
|
18561
|
+
onClose,
|
|
18562
|
+
onSave
|
|
18563
|
+
}) {
|
|
18564
|
+
const [draft, setDraft] = useState8(href);
|
|
18565
|
+
const [newTab, setNewTab] = useState8(linkTarget !== "same-tab");
|
|
18566
|
+
const [invalid, setInvalid] = useState8(false);
|
|
18567
|
+
const save = () => {
|
|
18568
|
+
const next = draft.trim();
|
|
18569
|
+
if (next && !HTTP_URL_RE.test(next)) {
|
|
18570
|
+
setInvalid(true);
|
|
18571
|
+
return;
|
|
18458
18572
|
}
|
|
18459
|
-
|
|
18573
|
+
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
18574
|
+
onClose();
|
|
18575
|
+
};
|
|
18576
|
+
return /* @__PURE__ */ jsx20(Dialog2, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs11(DialogContent, { "data-ohw-link-modal-root": "", className: "max-w-[400px] gap-4 p-5", children: [
|
|
18577
|
+
/* @__PURE__ */ jsx20(DialogHeader, { children: /* @__PURE__ */ jsx20(DialogTitle, { className: "text-base", children: "Image link" }) }),
|
|
18578
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-3", children: [
|
|
18579
|
+
/* @__PURE__ */ jsx20(
|
|
18580
|
+
"input",
|
|
18581
|
+
{
|
|
18582
|
+
autoFocus: true,
|
|
18583
|
+
type: "text",
|
|
18584
|
+
inputMode: "url",
|
|
18585
|
+
value: draft,
|
|
18586
|
+
onChange: (e) => {
|
|
18587
|
+
setDraft(e.target.value);
|
|
18588
|
+
setInvalid(false);
|
|
18589
|
+
},
|
|
18590
|
+
onKeyDown: (e) => {
|
|
18591
|
+
if (e.key === "Enter") save();
|
|
18592
|
+
},
|
|
18593
|
+
placeholder: "https://example.com",
|
|
18594
|
+
"aria-label": "Image link URL",
|
|
18595
|
+
"aria-invalid": invalid,
|
|
18596
|
+
className: cn(
|
|
18597
|
+
"h-9 w-full rounded-[6px] border border-border bg-background px-3 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/70 focus:border-bridge-primary",
|
|
18598
|
+
invalid && "border-destructive focus:border-destructive"
|
|
18599
|
+
)
|
|
18600
|
+
}
|
|
18601
|
+
),
|
|
18602
|
+
invalid && /* @__PURE__ */ jsx20("p", { className: "text-xs text-destructive", children: "Enter a full URL starting with http:// or https://" }),
|
|
18603
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-[13px] text-foreground", children: [
|
|
18604
|
+
/* @__PURE__ */ jsx20("input", { type: "checkbox", checked: newTab, onChange: (e) => setNewTab(e.target.checked) }),
|
|
18605
|
+
"Open in new tab"
|
|
18606
|
+
] })
|
|
18607
|
+
] }),
|
|
18608
|
+
/* @__PURE__ */ jsxs11(DialogFooter, { children: [
|
|
18609
|
+
href && /* @__PURE__ */ jsx20(
|
|
18610
|
+
"button",
|
|
18611
|
+
{
|
|
18612
|
+
type: "button",
|
|
18613
|
+
onClick: () => {
|
|
18614
|
+
onSave("", "new-tab");
|
|
18615
|
+
onClose();
|
|
18616
|
+
},
|
|
18617
|
+
className: "mr-auto rounded-[6px] px-3 py-2 text-[13px] font-medium text-destructive transition-colors hover:bg-muted",
|
|
18618
|
+
children: "Remove link"
|
|
18619
|
+
}
|
|
18620
|
+
),
|
|
18621
|
+
/* @__PURE__ */ jsx20(
|
|
18622
|
+
"button",
|
|
18623
|
+
{
|
|
18624
|
+
type: "button",
|
|
18625
|
+
onClick: onClose,
|
|
18626
|
+
className: "rounded-[6px] px-3 py-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted",
|
|
18627
|
+
children: "Cancel"
|
|
18628
|
+
}
|
|
18629
|
+
),
|
|
18630
|
+
/* @__PURE__ */ jsx20(
|
|
18631
|
+
"button",
|
|
18632
|
+
{
|
|
18633
|
+
type: "button",
|
|
18634
|
+
onClick: save,
|
|
18635
|
+
className: "rounded-[6px] bg-bridge-primary px-3 py-2 text-[13px] font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
18636
|
+
children: "Save"
|
|
18637
|
+
}
|
|
18638
|
+
)
|
|
18639
|
+
] })
|
|
18640
|
+
] }) });
|
|
18460
18641
|
}
|
|
18461
18642
|
function MediaStripToolbar({
|
|
18462
18643
|
entry,
|
|
18463
18644
|
index,
|
|
18464
18645
|
pending,
|
|
18465
18646
|
error,
|
|
18647
|
+
itemEditOn,
|
|
18648
|
+
onToggleItemEdit,
|
|
18466
18649
|
onSetVariant,
|
|
18467
18650
|
onSetAlign,
|
|
18468
18651
|
onSetHover,
|
|
18469
18652
|
onSetTreatment,
|
|
18470
18653
|
onResize,
|
|
18471
|
-
|
|
18472
|
-
onSetLink,
|
|
18654
|
+
onOpenLink,
|
|
18473
18655
|
onAddItem,
|
|
18474
18656
|
onRemoveItem,
|
|
18475
18657
|
onChangeImage,
|
|
@@ -18478,81 +18660,102 @@ function MediaStripToolbar({
|
|
|
18478
18660
|
}) {
|
|
18479
18661
|
const items = mediaStripItems(entry.tree);
|
|
18480
18662
|
const itemCount = items.length;
|
|
18481
|
-
const currentAlt = items[index]?.alt ?? "";
|
|
18482
|
-
const currentHref = items[index]?.href ?? "";
|
|
18483
|
-
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18484
18663
|
const slots = findMediaStripSlots(entry.tree);
|
|
18485
18664
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18486
18665
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
18487
18666
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
18488
18667
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
18489
18668
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18490
|
-
const
|
|
18491
|
-
const
|
|
18492
|
-
|
|
18493
|
-
gap: 6,
|
|
18494
|
-
flexWrap: "nowrap",
|
|
18495
|
-
justifyContent: "center",
|
|
18496
|
-
overflowX: "auto",
|
|
18497
|
-
WebkitOverflowScrolling: "touch",
|
|
18498
|
-
width: "100%",
|
|
18499
|
-
scrollbarWidth: "none"
|
|
18500
|
-
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
18501
|
-
return /* @__PURE__ */ jsxs10(
|
|
18669
|
+
const mobile = window.innerWidth <= 480;
|
|
18670
|
+
const gatedLabel = (label) => itemEditOn ? label : "Turn on the star to edit this image";
|
|
18671
|
+
return /* @__PURE__ */ jsx20(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs11(
|
|
18502
18672
|
"div",
|
|
18503
18673
|
{
|
|
18504
18674
|
"data-ohw-bridge": "",
|
|
18505
18675
|
"data-ohw-toolbar": "",
|
|
18506
18676
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18507
|
-
|
|
18508
|
-
|
|
18509
|
-
flexDirection: "column",
|
|
18510
|
-
gap: 6,
|
|
18511
|
-
alignItems: "center",
|
|
18512
|
-
background: OHW_BLUE,
|
|
18513
|
-
padding: 8,
|
|
18514
|
-
borderRadius: 12,
|
|
18515
|
-
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18516
|
-
pointerEvents: pending ? "none" : "auto",
|
|
18517
|
-
opacity: pending ? 0.6 : 1,
|
|
18518
|
-
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
18519
|
-
},
|
|
18677
|
+
className: cn("flex flex-col items-center gap-1.5 font-sans", pending && "pointer-events-none opacity-60"),
|
|
18678
|
+
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
18520
18679
|
children: [
|
|
18521
|
-
/* @__PURE__ */
|
|
18522
|
-
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
|
|
18526
|
-
|
|
18527
|
-
|
|
18528
|
-
|
|
18529
|
-
|
|
18530
|
-
|
|
18531
|
-
|
|
18532
|
-
|
|
18533
|
-
|
|
18534
|
-
|
|
18535
|
-
|
|
18536
|
-
|
|
18537
|
-
|
|
18538
|
-
|
|
18539
|
-
|
|
18540
|
-
|
|
18541
|
-
|
|
18542
|
-
|
|
18543
|
-
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18547
|
-
|
|
18548
|
-
|
|
18549
|
-
|
|
18550
|
-
|
|
18551
|
-
|
|
18552
|
-
|
|
18680
|
+
/* @__PURE__ */ jsxs11(
|
|
18681
|
+
"div",
|
|
18682
|
+
{
|
|
18683
|
+
className: cn(
|
|
18684
|
+
"flex items-center gap-1 rounded-[10px] border border-border bg-background p-1 whitespace-nowrap",
|
|
18685
|
+
"shadow-[0px_10px_15px_-3px_rgba(0,0,0,0.1),0px_4px_6px_-4px_rgba(0,0,0,0.1)]",
|
|
18686
|
+
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18687
|
+
),
|
|
18688
|
+
children: [
|
|
18689
|
+
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18690
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
18691
|
+
CustomToolbarButton,
|
|
18692
|
+
{
|
|
18693
|
+
type: "button",
|
|
18694
|
+
"aria-label": itemEditOn ? "Done editing this image" : "Edit this image",
|
|
18695
|
+
"aria-pressed": itemEditOn,
|
|
18696
|
+
onClick: onToggleItemEdit,
|
|
18697
|
+
className: "group size-8",
|
|
18698
|
+
children: /* @__PURE__ */ jsx20(
|
|
18699
|
+
Star,
|
|
18700
|
+
{
|
|
18701
|
+
size: 16,
|
|
18702
|
+
fill: "currentColor",
|
|
18703
|
+
strokeWidth: 0,
|
|
18704
|
+
className: cn(
|
|
18705
|
+
"transition-colors",
|
|
18706
|
+
itemEditOn ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
|
|
18707
|
+
),
|
|
18708
|
+
style: { pointerEvents: "none" }
|
|
18709
|
+
}
|
|
18710
|
+
)
|
|
18711
|
+
}
|
|
18712
|
+
) }),
|
|
18713
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
18714
|
+
] }),
|
|
18715
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18716
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ jsx20(ImageIcon2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18717
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ jsx20(LinkIcon, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18718
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ jsx20(ArrowLeft2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18719
|
+
/* @__PURE__ */ jsx20(
|
|
18720
|
+
ToolbarAction,
|
|
18721
|
+
{
|
|
18722
|
+
label: gatedLabel("Move right"),
|
|
18723
|
+
onClick: onMoveRight,
|
|
18724
|
+
disabled: !itemEditOn || index >= itemCount - 1,
|
|
18725
|
+
children: /* @__PURE__ */ jsx20(ArrowRight2, { size: 16, style: { pointerEvents: "none" } })
|
|
18726
|
+
}
|
|
18727
|
+
),
|
|
18728
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ jsx20(ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18729
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18730
|
+
/* @__PURE__ */ jsx20(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
18731
|
+
/* @__PURE__ */ jsx20(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
18732
|
+
/* @__PURE__ */ jsx20(
|
|
18733
|
+
ToolbarAction,
|
|
18734
|
+
{
|
|
18735
|
+
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
18736
|
+
active: treatment === "grayscale",
|
|
18737
|
+
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
18738
|
+
children: /* @__PURE__ */ jsx20(Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
18739
|
+
}
|
|
18740
|
+
),
|
|
18741
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18742
|
+
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx20(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ jsx20(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
18743
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18744
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ jsx20(Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18745
|
+
/* @__PURE__ */ jsxs11("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
18746
|
+
sizeValue,
|
|
18747
|
+
"px"
|
|
18748
|
+
] }),
|
|
18749
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ jsx20(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18750
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18751
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ jsx20(ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18752
|
+
]
|
|
18753
|
+
}
|
|
18754
|
+
),
|
|
18755
|
+
error && /* @__PURE__ */ jsx20("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18553
18756
|
]
|
|
18554
18757
|
}
|
|
18555
|
-
);
|
|
18758
|
+
) });
|
|
18556
18759
|
}
|
|
18557
18760
|
function findMediaStripSlots(tree) {
|
|
18558
18761
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -18571,31 +18774,23 @@ function AiMediaStripOverlay({
|
|
|
18571
18774
|
}) {
|
|
18572
18775
|
const [hover, setHover] = useState8(null);
|
|
18573
18776
|
const [active, setActive] = useState8(null);
|
|
18777
|
+
const [itemEditOn, setItemEditOn] = useState8(false);
|
|
18778
|
+
const [linkOpen, setLinkOpen] = useState8(false);
|
|
18574
18779
|
const [pending, setPending] = useState8(false);
|
|
18575
18780
|
const [error, setError] = useState8(null);
|
|
18576
18781
|
const activeRef = useRef5(null);
|
|
18577
18782
|
activeRef.current = active;
|
|
18783
|
+
const linkOpenRef = useRef5(false);
|
|
18784
|
+
linkOpenRef.current = linkOpen;
|
|
18578
18785
|
useEffect6(() => {
|
|
18579
18786
|
const onMove = (e) => {
|
|
18787
|
+
const ref = itemRefFromTarget(e.target);
|
|
18580
18788
|
const t = e.target;
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
|
|
18586
|
-
if (!itemEl) {
|
|
18587
|
-
setHover(null);
|
|
18588
|
-
return;
|
|
18589
|
-
}
|
|
18590
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18591
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18592
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18593
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18594
|
-
if (!sectionId || Number.isNaN(index)) {
|
|
18595
|
-
setHover(null);
|
|
18596
|
-
return;
|
|
18597
|
-
}
|
|
18598
|
-
setHover({ sectionId, index });
|
|
18789
|
+
const overEditable = Boolean(t?.closest?.("[data-ohw-editable]"));
|
|
18790
|
+
setHover((prev) => {
|
|
18791
|
+
const next = ref && !overEditable ? ref : null;
|
|
18792
|
+
return sameRef(prev, next) ? prev : next;
|
|
18793
|
+
});
|
|
18599
18794
|
};
|
|
18600
18795
|
const onLeave = () => setHover(null);
|
|
18601
18796
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -18607,23 +18802,25 @@ function AiMediaStripOverlay({
|
|
|
18607
18802
|
}, []);
|
|
18608
18803
|
useEffect6(() => {
|
|
18609
18804
|
const onClick = (e) => {
|
|
18610
|
-
const current = activeRef.current;
|
|
18611
|
-
if (!current) return;
|
|
18612
18805
|
const t = e.target;
|
|
18613
|
-
if (!(t instanceof
|
|
18614
|
-
if (t.closest(
|
|
18615
|
-
const
|
|
18616
|
-
if (
|
|
18617
|
-
|
|
18806
|
+
if (!(t instanceof Element)) return;
|
|
18807
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
18808
|
+
const ref = itemRefFromTarget(t);
|
|
18809
|
+
if (sameRef(activeRef.current, ref)) return;
|
|
18810
|
+
if (ref) clearInteractionChromeRef.current();
|
|
18811
|
+
setItemEditOn(false);
|
|
18618
18812
|
setError(null);
|
|
18813
|
+
setActive(ref);
|
|
18619
18814
|
};
|
|
18620
18815
|
document.addEventListener("click", onClick, true);
|
|
18621
18816
|
return () => document.removeEventListener("click", onClick, true);
|
|
18622
|
-
}, []);
|
|
18817
|
+
}, [clearInteractionChromeRef]);
|
|
18623
18818
|
useEffect6(() => {
|
|
18624
18819
|
const onBlur = () => {
|
|
18625
18820
|
if (!activeRef.current) return;
|
|
18626
18821
|
setActive(null);
|
|
18822
|
+
setItemEditOn(false);
|
|
18823
|
+
setLinkOpen(false);
|
|
18627
18824
|
setError(null);
|
|
18628
18825
|
};
|
|
18629
18826
|
window.addEventListener("blur", onBlur);
|
|
@@ -18633,7 +18830,10 @@ function AiMediaStripOverlay({
|
|
|
18633
18830
|
const onKeyDown = (e) => {
|
|
18634
18831
|
if (e.key !== "Escape") return;
|
|
18635
18832
|
if (!activeRef.current) return;
|
|
18833
|
+
if (linkOpenRef.current) return;
|
|
18834
|
+
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
18636
18835
|
setActive(null);
|
|
18836
|
+
setItemEditOn(false);
|
|
18637
18837
|
setError(null);
|
|
18638
18838
|
};
|
|
18639
18839
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -18667,137 +18867,133 @@ function AiMediaStripOverlay({
|
|
|
18667
18867
|
tree: nextTree,
|
|
18668
18868
|
label: entry.label,
|
|
18669
18869
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
18670
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
18870
|
+
...entry.brand ? { brand: entry.brand } : {},
|
|
18871
|
+
// The user is already looking at the strip they just edited — recentering the viewport
|
|
18872
|
+
// on every edit reads as the section jumping around.
|
|
18873
|
+
skipScrollIntoView: true
|
|
18671
18874
|
});
|
|
18672
18875
|
return true;
|
|
18673
18876
|
},
|
|
18674
18877
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
18675
18878
|
);
|
|
18676
18879
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18677
|
-
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
18678
18880
|
const activeItemRect = useLiveItemRect(active);
|
|
18679
|
-
const
|
|
18680
|
-
const
|
|
18681
|
-
|
|
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
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx19(
|
|
18714
|
-
ItemInteractionLayer,
|
|
18715
|
-
{
|
|
18716
|
-
rect: activeItemRect,
|
|
18717
|
-
state: toolbarState,
|
|
18718
|
-
toolbar: /* @__PURE__ */ jsx19(
|
|
18719
|
-
MediaStripToolbar,
|
|
18720
|
-
{
|
|
18721
|
-
entry: activeEntry,
|
|
18722
|
-
index: active.index,
|
|
18723
|
-
pending,
|
|
18724
|
-
error,
|
|
18725
|
-
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18726
|
-
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18727
|
-
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18728
|
-
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18729
|
-
onResize: (delta) => {
|
|
18730
|
-
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18731
|
-
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18732
|
-
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18733
|
-
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18734
|
-
},
|
|
18735
|
-
onSetAlt: (alt) => {
|
|
18736
|
-
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
18737
|
-
},
|
|
18738
|
-
onSetLink: (href, linkTarget) => {
|
|
18881
|
+
const activeStripRect = useLiveItemRect(active, true);
|
|
18882
|
+
const hoverRect = useLiveItemRect(hover && !sameRef(hover, active) ? hover : null);
|
|
18883
|
+
const activeItems = activeEntry ? mediaStripItems(activeEntry.tree) : [];
|
|
18884
|
+
const activeItem = active ? activeItems[active.index] : void 0;
|
|
18885
|
+
const activeHref = activeItem?.href ?? "";
|
|
18886
|
+
const activeTarget = activeItem?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18887
|
+
return /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
18888
|
+
hoverRect && /* @__PURE__ */ jsx20(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
18889
|
+
activeItemRect && activeStripRect && active && activeEntry && /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
18890
|
+
/* @__PURE__ */ jsx20(ItemInteractionLayer, { rect: activeItemRect, state: "active-top" }),
|
|
18891
|
+
/* @__PURE__ */ jsx20(StripToolbarSlot, { stripRect: activeStripRect, children: /* @__PURE__ */ jsx20(
|
|
18892
|
+
MediaStripToolbar,
|
|
18893
|
+
{
|
|
18894
|
+
entry: activeEntry,
|
|
18895
|
+
index: active.index,
|
|
18896
|
+
pending,
|
|
18897
|
+
error,
|
|
18898
|
+
itemEditOn,
|
|
18899
|
+
onToggleItemEdit: () => setItemEditOn((on) => !on),
|
|
18900
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18901
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18902
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18903
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18904
|
+
onResize: (delta) => {
|
|
18905
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18906
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18907
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18908
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18909
|
+
},
|
|
18910
|
+
onOpenLink: () => setLinkOpen(true),
|
|
18911
|
+
onAddItem: () => {
|
|
18912
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18913
|
+
if (!picked) return;
|
|
18914
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18739
18915
|
void runMutation(
|
|
18740
18916
|
active.sectionId,
|
|
18741
|
-
(tree) =>
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
void requestAssetPick(postToParent2).then((picked) => {
|
|
18746
|
-
if (!picked) return;
|
|
18747
|
-
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18748
|
-
void runMutation(
|
|
18749
|
-
active.sectionId,
|
|
18750
|
-
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18751
|
-
{ [picked.assetId]: picked.url }
|
|
18752
|
-
).then((applied) => {
|
|
18753
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18754
|
-
});
|
|
18917
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18918
|
+
{ [picked.assetId]: picked.url }
|
|
18919
|
+
).then((applied) => {
|
|
18920
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18755
18921
|
});
|
|
18756
|
-
}
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
|
|
18765
|
-
});
|
|
18766
|
-
},
|
|
18767
|
-
onRemoveItem: () => {
|
|
18768
|
-
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
18769
|
-
(applied) => {
|
|
18770
|
-
if (applied) setActive(null);
|
|
18771
|
-
}
|
|
18772
|
-
);
|
|
18773
|
-
},
|
|
18774
|
-
onMoveLeft: () => {
|
|
18775
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18776
|
-
(applied) => {
|
|
18777
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18778
|
-
}
|
|
18779
|
-
);
|
|
18780
|
-
},
|
|
18781
|
-
onMoveRight: () => {
|
|
18782
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18783
|
-
(applied) => {
|
|
18784
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18785
|
-
}
|
|
18922
|
+
});
|
|
18923
|
+
},
|
|
18924
|
+
onChangeImage: () => {
|
|
18925
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18926
|
+
if (!picked) return;
|
|
18927
|
+
void runMutation(
|
|
18928
|
+
active.sectionId,
|
|
18929
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
18930
|
+
{ [picked.assetId]: picked.url }
|
|
18786
18931
|
);
|
|
18787
|
-
}
|
|
18932
|
+
});
|
|
18933
|
+
},
|
|
18934
|
+
onRemoveItem: () => {
|
|
18935
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
18936
|
+
(applied) => {
|
|
18937
|
+
if (applied) setActive(null);
|
|
18938
|
+
}
|
|
18939
|
+
);
|
|
18940
|
+
},
|
|
18941
|
+
onMoveLeft: () => {
|
|
18942
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18943
|
+
(applied) => {
|
|
18944
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18945
|
+
}
|
|
18946
|
+
);
|
|
18947
|
+
},
|
|
18948
|
+
onMoveRight: () => {
|
|
18949
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18950
|
+
(applied) => {
|
|
18951
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18952
|
+
}
|
|
18953
|
+
);
|
|
18788
18954
|
}
|
|
18789
|
-
|
|
18790
|
-
}
|
|
18791
|
-
|
|
18955
|
+
}
|
|
18956
|
+
) }),
|
|
18957
|
+
/* @__PURE__ */ jsx20(
|
|
18958
|
+
"div",
|
|
18959
|
+
{
|
|
18960
|
+
"data-ohw-bridge": "",
|
|
18961
|
+
"data-ohw-item-interaction": "",
|
|
18962
|
+
"aria-hidden": true,
|
|
18963
|
+
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
18964
|
+
style: {
|
|
18965
|
+
top: activeItemRect.top + activeItemRect.height + 10,
|
|
18966
|
+
left: activeItemRect.left - 5,
|
|
18967
|
+
background: PRIMARY3,
|
|
18968
|
+
zIndex: 2147483644
|
|
18969
|
+
},
|
|
18970
|
+
children: "Media item"
|
|
18971
|
+
}
|
|
18972
|
+
),
|
|
18973
|
+
linkOpen && /* @__PURE__ */ jsx20(
|
|
18974
|
+
LinkModal,
|
|
18975
|
+
{
|
|
18976
|
+
href: activeHref,
|
|
18977
|
+
linkTarget: activeTarget,
|
|
18978
|
+
onClose: () => setLinkOpen(false),
|
|
18979
|
+
onSave: (href, linkTarget) => {
|
|
18980
|
+
void runMutation(
|
|
18981
|
+
active.sectionId,
|
|
18982
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
18983
|
+
);
|
|
18984
|
+
}
|
|
18985
|
+
}
|
|
18986
|
+
)
|
|
18987
|
+
] })
|
|
18792
18988
|
] });
|
|
18793
18989
|
}
|
|
18794
18990
|
|
|
18795
18991
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
18796
|
-
import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as
|
|
18797
|
-
import { Check as
|
|
18798
|
-
import { Fragment as Fragment7, jsx as
|
|
18992
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as useLayoutEffect5, useRef as useRef6, useState as useState9 } from "react";
|
|
18993
|
+
import { Check as Check3, ChevronDown as ChevronDown4, Minus as Minus2, Plus as Plus3, Star as Star2 } from "lucide-react";
|
|
18994
|
+
import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
18799
18995
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
18800
|
-
var
|
|
18996
|
+
var CHROME_SELECTOR2 = "[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]";
|
|
18801
18997
|
function findPricingCardElement(sectionId, index) {
|
|
18802
18998
|
const sectionEl = findByInstanceId(sectionId);
|
|
18803
18999
|
if (!sectionEl) return null;
|
|
@@ -18809,7 +19005,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
18809
19005
|
}
|
|
18810
19006
|
function cardRefFromTarget(target) {
|
|
18811
19007
|
if (!(target instanceof Element)) return null;
|
|
18812
|
-
if (target.closest(
|
|
19008
|
+
if (target.closest(CHROME_SELECTOR2)) return null;
|
|
18813
19009
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
18814
19010
|
if (!cardEl) return null;
|
|
18815
19011
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -18819,21 +19015,21 @@ function cardRefFromTarget(target) {
|
|
|
18819
19015
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
18820
19016
|
return { sectionId, index };
|
|
18821
19017
|
}
|
|
18822
|
-
function
|
|
19018
|
+
function sameRef2(a, b) {
|
|
18823
19019
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18824
19020
|
}
|
|
18825
|
-
function
|
|
19021
|
+
function rectOf2(el) {
|
|
18826
19022
|
if (!el) return null;
|
|
18827
19023
|
const r2 = el.getBoundingClientRect();
|
|
18828
19024
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18829
19025
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18830
19026
|
}
|
|
18831
19027
|
function readRect3(ref) {
|
|
18832
|
-
return
|
|
19028
|
+
return rectOf2(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
18833
19029
|
}
|
|
18834
19030
|
function readGridRect(ref) {
|
|
18835
19031
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
18836
|
-
return
|
|
19032
|
+
return rectOf2(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
18837
19033
|
}
|
|
18838
19034
|
function useLiveCardRect(ref, grid = false) {
|
|
18839
19035
|
const [rect, setRect] = useState9(null);
|
|
@@ -18863,19 +19059,19 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
18863
19059
|
}
|
|
18864
19060
|
var TOOLBAR_GRID_GAP = 52;
|
|
18865
19061
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
18866
|
-
var
|
|
19062
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
18867
19063
|
function GridToolbarSlot({ gridRect, children }) {
|
|
18868
19064
|
const slotRef = useRef6(null);
|
|
18869
19065
|
const [shift, setShift] = useState9(0);
|
|
18870
19066
|
const centerX = gridRect.left + gridRect.width / 2;
|
|
18871
|
-
|
|
19067
|
+
useLayoutEffect5(() => {
|
|
18872
19068
|
const slot = slotRef.current;
|
|
18873
19069
|
if (!slot) return;
|
|
18874
19070
|
const clamp = () => {
|
|
18875
19071
|
const w = slot.offsetWidth;
|
|
18876
19072
|
if (w <= 0) return;
|
|
18877
19073
|
const half = w / 2;
|
|
18878
|
-
const clamped = Math.max(
|
|
19074
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN3 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half));
|
|
18879
19075
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18880
19076
|
};
|
|
18881
19077
|
clamp();
|
|
@@ -18884,7 +19080,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
18884
19080
|
return () => ro.disconnect();
|
|
18885
19081
|
}, [centerX, children]);
|
|
18886
19082
|
const mobile = window.innerWidth <= 480;
|
|
18887
|
-
return /* @__PURE__ */
|
|
19083
|
+
return /* @__PURE__ */ jsx21(
|
|
18888
19084
|
"div",
|
|
18889
19085
|
{
|
|
18890
19086
|
ref: slotRef,
|
|
@@ -18919,7 +19115,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
18919
19115
|
});
|
|
18920
19116
|
}
|
|
18921
19117
|
function StyleSwatch({ style }) {
|
|
18922
|
-
return /* @__PURE__ */
|
|
19118
|
+
return /* @__PURE__ */ jsx21(
|
|
18923
19119
|
"span",
|
|
18924
19120
|
{
|
|
18925
19121
|
"aria-hidden": true,
|
|
@@ -18933,35 +19129,35 @@ function StyleSwatch({ style }) {
|
|
|
18933
19129
|
);
|
|
18934
19130
|
}
|
|
18935
19131
|
function ButtonGlyph() {
|
|
18936
|
-
return /* @__PURE__ */
|
|
18937
|
-
/* @__PURE__ */
|
|
18938
|
-
/* @__PURE__ */
|
|
19132
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19133
|
+
/* @__PURE__ */ jsx21("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19134
|
+
/* @__PURE__ */ jsx21("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
18939
19135
|
] });
|
|
18940
19136
|
}
|
|
18941
19137
|
function FeatureGlyph({ mode }) {
|
|
18942
|
-
return /* @__PURE__ */
|
|
18943
|
-
/* @__PURE__ */
|
|
18944
|
-
/* @__PURE__ */
|
|
18945
|
-
/* @__PURE__ */
|
|
18946
|
-
/* @__PURE__ */
|
|
18947
|
-
/* @__PURE__ */
|
|
18948
|
-
mode === "add" && /* @__PURE__ */
|
|
19138
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19139
|
+
/* @__PURE__ */ jsx21("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19140
|
+
/* @__PURE__ */ jsx21("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19141
|
+
/* @__PURE__ */ jsx21("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19142
|
+
/* @__PURE__ */ jsx21("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19143
|
+
/* @__PURE__ */ jsx21("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19144
|
+
mode === "add" && /* @__PURE__ */ jsx21("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
18949
19145
|
] });
|
|
18950
19146
|
}
|
|
18951
|
-
function
|
|
19147
|
+
function ToolbarAction2({
|
|
18952
19148
|
label,
|
|
18953
19149
|
onClick,
|
|
18954
19150
|
disabled = false,
|
|
18955
19151
|
children
|
|
18956
19152
|
}) {
|
|
18957
|
-
const button = /* @__PURE__ */
|
|
18958
|
-
return /* @__PURE__ */
|
|
18959
|
-
/* @__PURE__ */
|
|
18960
|
-
/* @__PURE__ */
|
|
19153
|
+
const button = /* @__PURE__ */ jsx21(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19154
|
+
return /* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19155
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: button }) : button }),
|
|
19156
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
18961
19157
|
] });
|
|
18962
19158
|
}
|
|
18963
|
-
function
|
|
18964
|
-
return /* @__PURE__ */
|
|
19159
|
+
function ToolbarSeparator2() {
|
|
19160
|
+
return /* @__PURE__ */ jsx21("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
18965
19161
|
}
|
|
18966
19162
|
function CardStyleMenu({
|
|
18967
19163
|
value,
|
|
@@ -18969,7 +19165,7 @@ function CardStyleMenu({
|
|
|
18969
19165
|
disabled = false
|
|
18970
19166
|
}) {
|
|
18971
19167
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18972
|
-
const trigger = /* @__PURE__ */
|
|
19168
|
+
const trigger = /* @__PURE__ */ jsxs12(
|
|
18973
19169
|
"button",
|
|
18974
19170
|
{
|
|
18975
19171
|
type: "button",
|
|
@@ -18980,28 +19176,28 @@ function CardStyleMenu({
|
|
|
18980
19176
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
18981
19177
|
),
|
|
18982
19178
|
children: [
|
|
18983
|
-
/* @__PURE__ */
|
|
18984
|
-
/* @__PURE__ */
|
|
18985
|
-
/* @__PURE__ */
|
|
19179
|
+
/* @__PURE__ */ jsx21(StyleSwatch, { style: current.value }),
|
|
19180
|
+
/* @__PURE__ */ jsx21("span", { className: "flex-1 text-left", children: current.label }),
|
|
19181
|
+
/* @__PURE__ */ jsx21(ChevronDown4, { size: 16, style: { pointerEvents: "none" } })
|
|
18986
19182
|
]
|
|
18987
19183
|
}
|
|
18988
19184
|
);
|
|
18989
19185
|
if (disabled) {
|
|
18990
|
-
return /* @__PURE__ */
|
|
18991
|
-
/* @__PURE__ */
|
|
18992
|
-
/* @__PURE__ */
|
|
18993
|
-
/* @__PURE__ */
|
|
18994
|
-
/* @__PURE__ */
|
|
19186
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19187
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19188
|
+
/* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19189
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: trigger }) }),
|
|
19190
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
18995
19191
|
] })
|
|
18996
19192
|
] });
|
|
18997
19193
|
}
|
|
18998
|
-
return /* @__PURE__ */
|
|
18999
|
-
/* @__PURE__ */
|
|
19000
|
-
/* @__PURE__ */
|
|
19001
|
-
/* @__PURE__ */
|
|
19002
|
-
/* @__PURE__ */
|
|
19194
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19195
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19196
|
+
/* @__PURE__ */ jsxs12(DropdownMenu, { modal: false, children: [
|
|
19197
|
+
/* @__PURE__ */ jsx21(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19198
|
+
/* @__PURE__ */ jsx21(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
19003
19199
|
const selected = style.value === value;
|
|
19004
|
-
return /* @__PURE__ */
|
|
19200
|
+
return /* @__PURE__ */ jsxs12(
|
|
19005
19201
|
DropdownMenuItem,
|
|
19006
19202
|
{
|
|
19007
19203
|
role: "menuitemradio",
|
|
@@ -19009,9 +19205,9 @@ function CardStyleMenu({
|
|
|
19009
19205
|
onSelect: () => onChange(style.value),
|
|
19010
19206
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19011
19207
|
children: [
|
|
19012
|
-
/* @__PURE__ */
|
|
19013
|
-
/* @__PURE__ */
|
|
19014
|
-
selected && /* @__PURE__ */
|
|
19208
|
+
/* @__PURE__ */ jsx21(StyleSwatch, { style: style.value }),
|
|
19209
|
+
/* @__PURE__ */ jsx21("span", { children: style.label }),
|
|
19210
|
+
selected && /* @__PURE__ */ jsx21(Check3, { size: 16, className: "text-bridge-primary" })
|
|
19015
19211
|
]
|
|
19016
19212
|
},
|
|
19017
19213
|
style.value
|
|
@@ -19041,7 +19237,7 @@ function PricingCardToolbar({
|
|
|
19041
19237
|
const style = pricingCardStyle(entry.tree, index);
|
|
19042
19238
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19043
19239
|
const mobile = window.innerWidth <= 480;
|
|
19044
|
-
return /* @__PURE__ */
|
|
19240
|
+
return /* @__PURE__ */ jsx21(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs12(
|
|
19045
19241
|
"div",
|
|
19046
19242
|
{
|
|
19047
19243
|
"data-ohw-bridge": "",
|
|
@@ -19053,7 +19249,7 @@ function PricingCardToolbar({
|
|
|
19053
19249
|
),
|
|
19054
19250
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19055
19251
|
children: [
|
|
19056
|
-
/* @__PURE__ */
|
|
19252
|
+
/* @__PURE__ */ jsxs12(
|
|
19057
19253
|
"div",
|
|
19058
19254
|
{
|
|
19059
19255
|
className: cn(
|
|
@@ -19062,8 +19258,8 @@ function PricingCardToolbar({
|
|
|
19062
19258
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19063
19259
|
),
|
|
19064
19260
|
children: [
|
|
19065
|
-
/* @__PURE__ */
|
|
19066
|
-
/* @__PURE__ */
|
|
19261
|
+
/* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19262
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
|
|
19067
19263
|
CustomToolbarButton,
|
|
19068
19264
|
{
|
|
19069
19265
|
type: "button",
|
|
@@ -19071,7 +19267,7 @@ function PricingCardToolbar({
|
|
|
19071
19267
|
"aria-pressed": featuredTag,
|
|
19072
19268
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19073
19269
|
className: "group size-8",
|
|
19074
|
-
children: /* @__PURE__ */
|
|
19270
|
+
children: /* @__PURE__ */ jsx21(
|
|
19075
19271
|
Star2,
|
|
19076
19272
|
{
|
|
19077
19273
|
size: 16,
|
|
@@ -19086,25 +19282,25 @@ function PricingCardToolbar({
|
|
|
19086
19282
|
)
|
|
19087
19283
|
}
|
|
19088
19284
|
) }),
|
|
19089
|
-
/* @__PURE__ */
|
|
19285
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19090
19286
|
] }),
|
|
19091
|
-
/* @__PURE__ */
|
|
19092
|
-
/* @__PURE__ */
|
|
19093
|
-
/* @__PURE__ */
|
|
19094
|
-
/* @__PURE__ */
|
|
19095
|
-
/* @__PURE__ */
|
|
19096
|
-
/* @__PURE__ */
|
|
19097
|
-
/* @__PURE__ */
|
|
19287
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator2, {}),
|
|
19288
|
+
/* @__PURE__ */ jsx21(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19289
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator2, {}),
|
|
19290
|
+
/* @__PURE__ */ jsx21(ToolbarAction2, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx21(ButtonGlyph, {}) }),
|
|
19291
|
+
/* @__PURE__ */ jsx21(ToolbarAction2, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs12("span", { className: "relative inline-flex", children: [
|
|
19292
|
+
/* @__PURE__ */ jsx21(ButtonGlyph, {}),
|
|
19293
|
+
/* @__PURE__ */ jsx21(Minus2, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
19098
19294
|
] }) }),
|
|
19099
|
-
/* @__PURE__ */
|
|
19100
|
-
/* @__PURE__ */
|
|
19101
|
-
/* @__PURE__ */
|
|
19102
|
-
/* @__PURE__ */
|
|
19103
|
-
/* @__PURE__ */
|
|
19295
|
+
/* @__PURE__ */ jsx21(ToolbarAction2, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ jsx21(FeatureGlyph, { mode: "add" }) }),
|
|
19296
|
+
/* @__PURE__ */ jsx21(ToolbarAction2, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ jsx21(FeatureGlyph, { mode: "remove" }) }),
|
|
19297
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator2, {}),
|
|
19298
|
+
/* @__PURE__ */ jsx21(ToolbarAction2, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ jsx21(Plus3, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19299
|
+
/* @__PURE__ */ jsx21(ToolbarAction2, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ jsx21(Minus2, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19104
19300
|
]
|
|
19105
19301
|
}
|
|
19106
19302
|
),
|
|
19107
|
-
error && /* @__PURE__ */
|
|
19303
|
+
error && /* @__PURE__ */ jsx21("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19108
19304
|
]
|
|
19109
19305
|
}
|
|
19110
19306
|
) });
|
|
@@ -19138,7 +19334,7 @@ function AiPricingCardOverlay({
|
|
|
19138
19334
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19139
19335
|
setHover((prev) => {
|
|
19140
19336
|
const next = ref && !overEditable ? ref : null;
|
|
19141
|
-
return
|
|
19337
|
+
return sameRef2(prev, next) ? prev : next;
|
|
19142
19338
|
});
|
|
19143
19339
|
};
|
|
19144
19340
|
const onLeave = () => setHover(null);
|
|
@@ -19153,10 +19349,10 @@ function AiPricingCardOverlay({
|
|
|
19153
19349
|
const onClick = (e) => {
|
|
19154
19350
|
const t = e.target;
|
|
19155
19351
|
if (!(t instanceof Element)) return;
|
|
19156
|
-
if (t.closest(
|
|
19352
|
+
if (t.closest(CHROME_SELECTOR2)) return;
|
|
19157
19353
|
const ref = cardRefFromTarget(t);
|
|
19158
|
-
setActive((prev) =>
|
|
19159
|
-
if (!ref || !
|
|
19354
|
+
setActive((prev) => sameRef2(prev, ref) ? prev : ref);
|
|
19355
|
+
if (!ref || !sameRef2(activeRef.current, ref)) setError(null);
|
|
19160
19356
|
};
|
|
19161
19357
|
document.addEventListener("click", onClick, true);
|
|
19162
19358
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19221,12 +19417,12 @@ function AiPricingCardOverlay({
|
|
|
19221
19417
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19222
19418
|
const activeCardRect = useLiveCardRect(active);
|
|
19223
19419
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19224
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19225
|
-
return /* @__PURE__ */
|
|
19226
|
-
hoverRect && /* @__PURE__ */
|
|
19227
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */
|
|
19228
|
-
/* @__PURE__ */
|
|
19229
|
-
/* @__PURE__ */
|
|
19420
|
+
const hoverRect = useLiveCardRect(hover && !sameRef2(hover, active) ? hover : null);
|
|
19421
|
+
return /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
19422
|
+
hoverRect && /* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19423
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
19424
|
+
/* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19425
|
+
/* @__PURE__ */ jsx21(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ jsx21(
|
|
19230
19426
|
PricingCardToolbar,
|
|
19231
19427
|
{
|
|
19232
19428
|
entry: activeEntry,
|
|
@@ -19254,7 +19450,7 @@ function AiPricingCardOverlay({
|
|
|
19254
19450
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
19255
19451
|
}
|
|
19256
19452
|
) }),
|
|
19257
|
-
/* @__PURE__ */
|
|
19453
|
+
/* @__PURE__ */ jsx21(
|
|
19258
19454
|
"div",
|
|
19259
19455
|
{
|
|
19260
19456
|
"data-ohw-bridge": "",
|
|
@@ -19347,10 +19543,10 @@ function extractYouTubeId(input) {
|
|
|
19347
19543
|
}
|
|
19348
19544
|
|
|
19349
19545
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19350
|
-
import { Fragment as Fragment8, jsx as
|
|
19546
|
+
import { Fragment as Fragment8, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
19351
19547
|
var PRIMARY5 = "#0885FE";
|
|
19352
|
-
var
|
|
19353
|
-
var
|
|
19548
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19549
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
19354
19550
|
function findVideoBlockElement(sectionId, path) {
|
|
19355
19551
|
const sectionEl = findByInstanceId(sectionId);
|
|
19356
19552
|
if (!sectionEl) return null;
|
|
@@ -19410,12 +19606,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
19410
19606
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
19411
19607
|
});
|
|
19412
19608
|
}
|
|
19413
|
-
function
|
|
19609
|
+
function Pill({
|
|
19414
19610
|
label,
|
|
19415
19611
|
onClick,
|
|
19416
19612
|
disabled
|
|
19417
19613
|
}) {
|
|
19418
|
-
return /* @__PURE__ */
|
|
19614
|
+
return /* @__PURE__ */ jsx22(
|
|
19419
19615
|
"button",
|
|
19420
19616
|
{
|
|
19421
19617
|
type: "button",
|
|
@@ -19431,7 +19627,7 @@ function Pill2({
|
|
|
19431
19627
|
border: "none",
|
|
19432
19628
|
cursor: disabled ? "default" : "pointer",
|
|
19433
19629
|
background: "#ffffff",
|
|
19434
|
-
color:
|
|
19630
|
+
color: OHW_BLUE_DARK,
|
|
19435
19631
|
opacity: disabled ? 0.4 : 1,
|
|
19436
19632
|
fontSize: 12,
|
|
19437
19633
|
lineHeight: "16px",
|
|
@@ -19474,8 +19670,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19474
19670
|
onCommit(id);
|
|
19475
19671
|
}
|
|
19476
19672
|
};
|
|
19477
|
-
return /* @__PURE__ */
|
|
19478
|
-
/* @__PURE__ */
|
|
19673
|
+
return /* @__PURE__ */ jsxs13("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
19674
|
+
/* @__PURE__ */ jsxs13(
|
|
19479
19675
|
"div",
|
|
19480
19676
|
{
|
|
19481
19677
|
style: {
|
|
@@ -19491,12 +19687,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19491
19687
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19492
19688
|
},
|
|
19493
19689
|
children: [
|
|
19494
|
-
/* @__PURE__ */
|
|
19690
|
+
/* @__PURE__ */ jsx22(
|
|
19495
19691
|
"span",
|
|
19496
19692
|
{
|
|
19497
19693
|
style: {
|
|
19498
19694
|
flex: "0 0 auto",
|
|
19499
|
-
color:
|
|
19695
|
+
color: OHW_BLUE_DARK,
|
|
19500
19696
|
fontSize: 10,
|
|
19501
19697
|
lineHeight: "16px",
|
|
19502
19698
|
fontWeight: 700,
|
|
@@ -19506,7 +19702,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19506
19702
|
children: "Video"
|
|
19507
19703
|
}
|
|
19508
19704
|
),
|
|
19509
|
-
/* @__PURE__ */
|
|
19705
|
+
/* @__PURE__ */ jsx22(
|
|
19510
19706
|
"input",
|
|
19511
19707
|
{
|
|
19512
19708
|
type: "text",
|
|
@@ -19543,7 +19739,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19543
19739
|
]
|
|
19544
19740
|
}
|
|
19545
19741
|
),
|
|
19546
|
-
invalid && /* @__PURE__ */
|
|
19742
|
+
invalid && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
19547
19743
|
] });
|
|
19548
19744
|
}
|
|
19549
19745
|
function VideoToolbar({
|
|
@@ -19553,7 +19749,7 @@ function VideoToolbar({
|
|
|
19553
19749
|
onSetVideoId,
|
|
19554
19750
|
onRemove
|
|
19555
19751
|
}) {
|
|
19556
|
-
return /* @__PURE__ */
|
|
19752
|
+
return /* @__PURE__ */ jsxs13(
|
|
19557
19753
|
"div",
|
|
19558
19754
|
{
|
|
19559
19755
|
"data-ohw-bridge": "",
|
|
@@ -19565,7 +19761,7 @@ function VideoToolbar({
|
|
|
19565
19761
|
gap: 6,
|
|
19566
19762
|
alignItems: "center",
|
|
19567
19763
|
width: 280,
|
|
19568
|
-
background:
|
|
19764
|
+
background: OHW_BLUE,
|
|
19569
19765
|
padding: 8,
|
|
19570
19766
|
borderRadius: 12,
|
|
19571
19767
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19573,9 +19769,9 @@ function VideoToolbar({
|
|
|
19573
19769
|
opacity: pending ? 0.6 : 1
|
|
19574
19770
|
},
|
|
19575
19771
|
children: [
|
|
19576
|
-
/* @__PURE__ */
|
|
19577
|
-
/* @__PURE__ */
|
|
19578
|
-
error && /* @__PURE__ */
|
|
19772
|
+
/* @__PURE__ */ jsx22(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19773
|
+
/* @__PURE__ */ jsx22(Pill, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19774
|
+
error && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19579
19775
|
]
|
|
19580
19776
|
}
|
|
19581
19777
|
);
|
|
@@ -19695,8 +19891,8 @@ function AiVideoOverlay({
|
|
|
19695
19891
|
const activeBlockRect = useLiveBlockRect(active);
|
|
19696
19892
|
const TOOLBAR_APPROX_H = 90;
|
|
19697
19893
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19698
|
-
return /* @__PURE__ */
|
|
19699
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
19894
|
+
return /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
19895
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx22(
|
|
19700
19896
|
"button",
|
|
19701
19897
|
{
|
|
19702
19898
|
type: "button",
|
|
@@ -19724,15 +19920,15 @@ function AiVideoOverlay({
|
|
|
19724
19920
|
fontSize: 14,
|
|
19725
19921
|
fontWeight: 700
|
|
19726
19922
|
},
|
|
19727
|
-
children: /* @__PURE__ */
|
|
19923
|
+
children: /* @__PURE__ */ jsx22(Star3, { size: 14, style: { pointerEvents: "none" } })
|
|
19728
19924
|
}
|
|
19729
19925
|
),
|
|
19730
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */
|
|
19926
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ jsx22(
|
|
19731
19927
|
ItemInteractionLayer,
|
|
19732
19928
|
{
|
|
19733
19929
|
rect: activeBlockRect,
|
|
19734
19930
|
state: toolbarState,
|
|
19735
|
-
toolbar: /* @__PURE__ */
|
|
19931
|
+
toolbar: /* @__PURE__ */ jsx22(
|
|
19736
19932
|
VideoToolbar,
|
|
19737
19933
|
{
|
|
19738
19934
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -19807,10 +20003,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
19807
20003
|
}
|
|
19808
20004
|
|
|
19809
20005
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
19810
|
-
import { Fragment as Fragment9, jsx as
|
|
20006
|
+
import { Fragment as Fragment9, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
19811
20007
|
var PRIMARY6 = "#0885FE";
|
|
19812
|
-
var
|
|
19813
|
-
var
|
|
20008
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
20009
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
19814
20010
|
function findCarouselItemElement(sectionId, index) {
|
|
19815
20011
|
const sectionEl = findByInstanceId(sectionId);
|
|
19816
20012
|
if (!sectionEl) return null;
|
|
@@ -19889,8 +20085,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
19889
20085
|
postToParent2({ type: "ow:asset-pick", id });
|
|
19890
20086
|
});
|
|
19891
20087
|
}
|
|
19892
|
-
function
|
|
19893
|
-
return /* @__PURE__ */
|
|
20088
|
+
function Pill2({ label, onClick, disabled }) {
|
|
20089
|
+
return /* @__PURE__ */ jsx23(
|
|
19894
20090
|
"button",
|
|
19895
20091
|
{
|
|
19896
20092
|
type: "button",
|
|
@@ -19906,7 +20102,7 @@ function Pill3({ label, onClick, disabled }) {
|
|
|
19906
20102
|
border: "none",
|
|
19907
20103
|
cursor: disabled ? "default" : "pointer",
|
|
19908
20104
|
background: "#ffffff",
|
|
19909
|
-
color:
|
|
20105
|
+
color: OHW_BLUE_DARK2,
|
|
19910
20106
|
opacity: disabled ? 0.4 : 1,
|
|
19911
20107
|
fontSize: 12,
|
|
19912
20108
|
lineHeight: "16px",
|
|
@@ -19924,7 +20120,7 @@ function TogglePill({
|
|
|
19924
20120
|
onToggle,
|
|
19925
20121
|
disabled
|
|
19926
20122
|
}) {
|
|
19927
|
-
return /* @__PURE__ */
|
|
20123
|
+
return /* @__PURE__ */ jsxs14(
|
|
19928
20124
|
"button",
|
|
19929
20125
|
{
|
|
19930
20126
|
type: "button",
|
|
@@ -19943,7 +20139,7 @@ function TogglePill({
|
|
|
19943
20139
|
border: "none",
|
|
19944
20140
|
cursor: disabled ? "default" : "pointer",
|
|
19945
20141
|
background: "#ffffff",
|
|
19946
|
-
color:
|
|
20142
|
+
color: OHW_BLUE_DARK2,
|
|
19947
20143
|
opacity: disabled ? 0.4 : 1,
|
|
19948
20144
|
fontSize: 12,
|
|
19949
20145
|
lineHeight: "16px",
|
|
@@ -19953,7 +20149,7 @@ function TogglePill({
|
|
|
19953
20149
|
},
|
|
19954
20150
|
children: [
|
|
19955
20151
|
label,
|
|
19956
|
-
/* @__PURE__ */
|
|
20152
|
+
/* @__PURE__ */ jsx23(
|
|
19957
20153
|
"span",
|
|
19958
20154
|
{
|
|
19959
20155
|
"aria-hidden": true,
|
|
@@ -19966,10 +20162,10 @@ function TogglePill({
|
|
|
19966
20162
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
19967
20163
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
19968
20164
|
// "disabled control" rather than "switch that is off".
|
|
19969
|
-
background: on ?
|
|
20165
|
+
background: on ? OHW_BLUE_DARK2 : "#CBD5E1",
|
|
19970
20166
|
transition: "background 120ms ease"
|
|
19971
20167
|
},
|
|
19972
|
-
children: /* @__PURE__ */
|
|
20168
|
+
children: /* @__PURE__ */ jsx23(
|
|
19973
20169
|
"span",
|
|
19974
20170
|
{
|
|
19975
20171
|
style: {
|
|
@@ -19998,7 +20194,7 @@ function CarouselSlideToolbar({
|
|
|
19998
20194
|
onChangeImage,
|
|
19999
20195
|
onToggleAutoplay
|
|
20000
20196
|
}) {
|
|
20001
|
-
return /* @__PURE__ */
|
|
20197
|
+
return /* @__PURE__ */ jsxs14(
|
|
20002
20198
|
"div",
|
|
20003
20199
|
{
|
|
20004
20200
|
"data-ohw-bridge": "",
|
|
@@ -20009,7 +20205,7 @@ function CarouselSlideToolbar({
|
|
|
20009
20205
|
flexDirection: "column",
|
|
20010
20206
|
gap: 6,
|
|
20011
20207
|
alignItems: "center",
|
|
20012
|
-
background:
|
|
20208
|
+
background: OHW_BLUE2,
|
|
20013
20209
|
padding: 8,
|
|
20014
20210
|
borderRadius: 12,
|
|
20015
20211
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20021,11 +20217,11 @@ function CarouselSlideToolbar({
|
|
|
20021
20217
|
pointerEvents: pending ? "none" : "auto"
|
|
20022
20218
|
},
|
|
20023
20219
|
children: [
|
|
20024
|
-
/* @__PURE__ */
|
|
20025
|
-
/* @__PURE__ */
|
|
20026
|
-
/* @__PURE__ */
|
|
20220
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20221
|
+
/* @__PURE__ */ jsx23(Pill2, { label: "Change Image", onClick: onChangeImage }),
|
|
20222
|
+
/* @__PURE__ */ jsx23(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20027
20223
|
] }),
|
|
20028
|
-
error && /* @__PURE__ */
|
|
20224
|
+
error && /* @__PURE__ */ jsx23("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20029
20225
|
]
|
|
20030
20226
|
}
|
|
20031
20227
|
);
|
|
@@ -20165,8 +20361,8 @@ function AiFadeCarouselOverlay({
|
|
|
20165
20361
|
const activeItemRect = useLiveItemRect2(active);
|
|
20166
20362
|
const TOOLBAR_APPROX_H = 90;
|
|
20167
20363
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20168
|
-
return /* @__PURE__ */
|
|
20169
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
20364
|
+
return /* @__PURE__ */ jsxs14(Fragment9, { children: [
|
|
20365
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx23(
|
|
20170
20366
|
"button",
|
|
20171
20367
|
{
|
|
20172
20368
|
type: "button",
|
|
@@ -20195,10 +20391,10 @@ function AiFadeCarouselOverlay({
|
|
|
20195
20391
|
fontSize: 14,
|
|
20196
20392
|
fontWeight: 700
|
|
20197
20393
|
},
|
|
20198
|
-
children: /* @__PURE__ */
|
|
20394
|
+
children: /* @__PURE__ */ jsx23(Star4, { size: 14, style: { pointerEvents: "none" } })
|
|
20199
20395
|
}
|
|
20200
20396
|
),
|
|
20201
|
-
swapping && /* @__PURE__ */
|
|
20397
|
+
swapping && /* @__PURE__ */ jsx23(
|
|
20202
20398
|
"div",
|
|
20203
20399
|
{
|
|
20204
20400
|
ref: skeletonRef,
|
|
@@ -20216,15 +20412,15 @@ function AiFadeCarouselOverlay({
|
|
|
20216
20412
|
zIndex: 2147483646,
|
|
20217
20413
|
pointerEvents: "none"
|
|
20218
20414
|
},
|
|
20219
|
-
children: /* @__PURE__ */
|
|
20415
|
+
children: /* @__PURE__ */ jsx23("style", { children: MEDIA_SKELETON_CSS })
|
|
20220
20416
|
}
|
|
20221
20417
|
),
|
|
20222
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */
|
|
20418
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx23(
|
|
20223
20419
|
ItemInteractionLayer,
|
|
20224
20420
|
{
|
|
20225
20421
|
rect: activeItemRect,
|
|
20226
20422
|
state: toolbarState,
|
|
20227
|
-
toolbar: /* @__PURE__ */
|
|
20423
|
+
toolbar: /* @__PURE__ */ jsx23(
|
|
20228
20424
|
CarouselSlideToolbar,
|
|
20229
20425
|
{
|
|
20230
20426
|
pending,
|
|
@@ -20577,118 +20773,11 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
20577
20773
|
// src/ui/link-modal/LinkPopover.tsx
|
|
20578
20774
|
import { useEffect as useEffect13 } from "react";
|
|
20579
20775
|
|
|
20580
|
-
// src/ui/dialog.tsx
|
|
20581
|
-
import * as React9 from "react";
|
|
20582
|
-
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
20583
|
-
import { X as X2 } from "lucide-react";
|
|
20584
|
-
import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
20585
|
-
function Dialog2({
|
|
20586
|
-
...props
|
|
20587
|
-
}) {
|
|
20588
|
-
return /* @__PURE__ */ jsx23(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
20589
|
-
}
|
|
20590
|
-
function DialogPortal({
|
|
20591
|
-
...props
|
|
20592
|
-
}) {
|
|
20593
|
-
return /* @__PURE__ */ jsx23(DialogPrimitive.Portal, { ...props });
|
|
20594
|
-
}
|
|
20595
|
-
function DialogOverlay({
|
|
20596
|
-
className,
|
|
20597
|
-
...props
|
|
20598
|
-
}) {
|
|
20599
|
-
return /* @__PURE__ */ jsx23(
|
|
20600
|
-
DialogPrimitive.Overlay,
|
|
20601
|
-
{
|
|
20602
|
-
"data-slot": "dialog-overlay",
|
|
20603
|
-
"data-ohw-link-modal-root": "",
|
|
20604
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
20605
|
-
...props
|
|
20606
|
-
}
|
|
20607
|
-
);
|
|
20608
|
-
}
|
|
20609
|
-
var DialogContent = React9.forwardRef(
|
|
20610
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
20611
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
20612
|
-
return /* @__PURE__ */ jsxs14(DialogPortal, { container: container ?? void 0, children: [
|
|
20613
|
-
/* @__PURE__ */ jsx23(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
20614
|
-
/* @__PURE__ */ jsxs14(
|
|
20615
|
-
DialogPrimitive.Content,
|
|
20616
|
-
{
|
|
20617
|
-
ref,
|
|
20618
|
-
"data-slot": "dialog-content",
|
|
20619
|
-
className: cn(
|
|
20620
|
-
positionMode,
|
|
20621
|
-
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[448px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-visible",
|
|
20622
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
20623
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
20624
|
-
className
|
|
20625
|
-
),
|
|
20626
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
20627
|
-
...props,
|
|
20628
|
-
children: [
|
|
20629
|
-
children,
|
|
20630
|
-
showCloseButton ? /* @__PURE__ */ jsx23(
|
|
20631
|
-
DialogPrimitive.Close,
|
|
20632
|
-
{
|
|
20633
|
-
type: "button",
|
|
20634
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
20635
|
-
"aria-label": "Close",
|
|
20636
|
-
children: /* @__PURE__ */ jsx23(X2, { size: 16, "aria-hidden": true })
|
|
20637
|
-
}
|
|
20638
|
-
) : null
|
|
20639
|
-
]
|
|
20640
|
-
}
|
|
20641
|
-
)
|
|
20642
|
-
] });
|
|
20643
|
-
}
|
|
20644
|
-
);
|
|
20645
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
20646
|
-
function DialogHeader({
|
|
20647
|
-
className,
|
|
20648
|
-
...props
|
|
20649
|
-
}) {
|
|
20650
|
-
return /* @__PURE__ */ jsx23("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
20651
|
-
}
|
|
20652
|
-
function DialogFooter({
|
|
20653
|
-
className,
|
|
20654
|
-
...props
|
|
20655
|
-
}) {
|
|
20656
|
-
return /* @__PURE__ */ jsx23(
|
|
20657
|
-
"div",
|
|
20658
|
-
{
|
|
20659
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
20660
|
-
...props
|
|
20661
|
-
}
|
|
20662
|
-
);
|
|
20663
|
-
}
|
|
20664
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
20665
|
-
DialogPrimitive.Title,
|
|
20666
|
-
{
|
|
20667
|
-
ref,
|
|
20668
|
-
className: cn(
|
|
20669
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
20670
|
-
className
|
|
20671
|
-
),
|
|
20672
|
-
...props
|
|
20673
|
-
}
|
|
20674
|
-
));
|
|
20675
|
-
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
20676
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
20677
|
-
DialogPrimitive.Description,
|
|
20678
|
-
{
|
|
20679
|
-
ref,
|
|
20680
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
20681
|
-
...props
|
|
20682
|
-
}
|
|
20683
|
-
));
|
|
20684
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
20685
|
-
var DialogClose = DialogPrimitive.Close;
|
|
20686
|
-
|
|
20687
20776
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
20688
20777
|
import { Info, X as X4 } from "lucide-react";
|
|
20689
20778
|
|
|
20690
20779
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
20691
|
-
import { ArrowRight as
|
|
20780
|
+
import { ArrowRight as ArrowRight3, File, GalleryVertical } from "lucide-react";
|
|
20692
20781
|
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
20693
20782
|
function DestinationBreadcrumb({
|
|
20694
20783
|
pageTitle,
|
|
@@ -20702,7 +20791,7 @@ function DestinationBreadcrumb({
|
|
|
20702
20791
|
/* @__PURE__ */ jsx24("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
20703
20792
|
] }),
|
|
20704
20793
|
/* @__PURE__ */ jsx24(
|
|
20705
|
-
|
|
20794
|
+
ArrowRight3,
|
|
20706
20795
|
{
|
|
20707
20796
|
size: 16,
|
|
20708
20797
|
className: "shrink-0 text-muted-foreground",
|
|
@@ -20814,7 +20903,7 @@ function Label({ className, ...props }) {
|
|
|
20814
20903
|
}
|
|
20815
20904
|
|
|
20816
20905
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
20817
|
-
import { ChevronDown as
|
|
20906
|
+
import { ChevronDown as ChevronDown5, File as File2, X as X3 } from "lucide-react";
|
|
20818
20907
|
import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
20819
20908
|
function FieldChevron({
|
|
20820
20909
|
onClick
|
|
@@ -20827,7 +20916,7 @@ function FieldChevron({
|
|
|
20827
20916
|
onClick,
|
|
20828
20917
|
"aria-label": "Open page list",
|
|
20829
20918
|
tabIndex: -1,
|
|
20830
|
-
children: /* @__PURE__ */ jsx28(
|
|
20919
|
+
children: /* @__PURE__ */ jsx28(ChevronDown5, { size: 16 })
|
|
20831
20920
|
}
|
|
20832
20921
|
);
|
|
20833
20922
|
}
|
|
@@ -21057,7 +21146,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
21057
21146
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
21058
21147
|
import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
|
|
21059
21148
|
import { createPortal as createPortal2 } from "react-dom";
|
|
21060
|
-
import { ArrowLeft as
|
|
21149
|
+
import { ArrowLeft as ArrowLeft3, Check as Check4 } from "lucide-react";
|
|
21061
21150
|
import { usePathname, useRouter as useRouter2 } from "next/navigation";
|
|
21062
21151
|
|
|
21063
21152
|
// src/lib/parent-scroll.ts
|
|
@@ -21334,7 +21423,7 @@ function SectionPickerOverlay({
|
|
|
21334
21423
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
21335
21424
|
onClick: onBack,
|
|
21336
21425
|
children: [
|
|
21337
|
-
/* @__PURE__ */ jsx30(
|
|
21426
|
+
/* @__PURE__ */ jsx30(ArrowLeft3, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
21338
21427
|
"Back"
|
|
21339
21428
|
]
|
|
21340
21429
|
}
|
|
@@ -21403,7 +21492,7 @@ function SectionPickerOverlay({
|
|
|
21403
21492
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
21404
21493
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
21405
21494
|
"aria-hidden": true,
|
|
21406
|
-
children: /* @__PURE__ */ jsx30(
|
|
21495
|
+
children: /* @__PURE__ */ jsx30(Check4, { className: "size-5" })
|
|
21407
21496
|
}
|
|
21408
21497
|
) : null
|
|
21409
21498
|
]
|
|
@@ -21787,6 +21876,7 @@ function shouldUseDevFixtures() {
|
|
|
21787
21876
|
function getLogoElement(el) {
|
|
21788
21877
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
21789
21878
|
if (marked) return marked;
|
|
21879
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
21790
21880
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
21791
21881
|
if (!root) return null;
|
|
21792
21882
|
const anchor = el.closest("a");
|
|
@@ -21856,7 +21946,7 @@ function addFooterColumnWithPersist({
|
|
|
21856
21946
|
import {
|
|
21857
21947
|
useCallback as useCallback9,
|
|
21858
21948
|
useEffect as useEffect14,
|
|
21859
|
-
useLayoutEffect as
|
|
21949
|
+
useLayoutEffect as useLayoutEffect6,
|
|
21860
21950
|
useRef as useRef11,
|
|
21861
21951
|
useState as useState15
|
|
21862
21952
|
} from "react";
|
|
@@ -21953,7 +22043,7 @@ function FloatingPanel({
|
|
|
21953
22043
|
return () => window.removeEventListener("message", onParentScroll);
|
|
21954
22044
|
}, [open]);
|
|
21955
22045
|
const positionRef = useRef11(position);
|
|
21956
|
-
|
|
22046
|
+
useLayoutEffect6(() => {
|
|
21957
22047
|
if (!open) {
|
|
21958
22048
|
positionRef.current = position;
|
|
21959
22049
|
return;
|
|
@@ -21963,7 +22053,7 @@ function FloatingPanel({
|
|
|
21963
22053
|
}
|
|
21964
22054
|
positionRef.current = position;
|
|
21965
22055
|
}, [open, position, liveScroll, parentScroll]);
|
|
21966
|
-
|
|
22056
|
+
useLayoutEffect6(() => {
|
|
21967
22057
|
if (!open || !panelRef.current) return;
|
|
21968
22058
|
const el = panelRef.current;
|
|
21969
22059
|
const header = el.querySelector("[data-ohw-floating-panel-header]");
|
|
@@ -22172,7 +22262,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
22172
22262
|
}
|
|
22173
22263
|
|
|
22174
22264
|
// src/ui/button-style-panel.tsx
|
|
22175
|
-
import { Check as
|
|
22265
|
+
import { Check as Check5 } from "lucide-react";
|
|
22176
22266
|
import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
22177
22267
|
var SIZE_LABEL = { s: "S", m: "M", l: "L" };
|
|
22178
22268
|
function ButtonStylePanel({
|
|
@@ -22243,7 +22333,7 @@ function ButtonStylePanel({
|
|
|
22243
22333
|
{
|
|
22244
22334
|
className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
22245
22335
|
"aria-hidden": true,
|
|
22246
|
-
children: /* @__PURE__ */ jsx34(
|
|
22336
|
+
children: /* @__PURE__ */ jsx34(Check5, { className: "size-3", strokeWidth: 3 })
|
|
22247
22337
|
}
|
|
22248
22338
|
) : null
|
|
22249
22339
|
]
|
|
@@ -23268,7 +23358,7 @@ function useSectionDrag({
|
|
|
23268
23358
|
}
|
|
23269
23359
|
|
|
23270
23360
|
// src/ui/footer-container-chrome.tsx
|
|
23271
|
-
import { Plus as
|
|
23361
|
+
import { Plus as Plus4 } from "lucide-react";
|
|
23272
23362
|
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
23273
23363
|
function FooterContainerChrome({
|
|
23274
23364
|
rect,
|
|
@@ -23309,7 +23399,7 @@ function FooterContainerChrome({
|
|
|
23309
23399
|
if (addDisabled) return;
|
|
23310
23400
|
onAdd();
|
|
23311
23401
|
},
|
|
23312
|
-
children: /* @__PURE__ */ jsx35(
|
|
23402
|
+
children: /* @__PURE__ */ jsx35(Plus4, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
23313
23403
|
}
|
|
23314
23404
|
) }),
|
|
23315
23405
|
/* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
@@ -23488,7 +23578,7 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
23488
23578
|
}
|
|
23489
23579
|
|
|
23490
23580
|
// src/ui/navbar-container-chrome.tsx
|
|
23491
|
-
import { Plus as
|
|
23581
|
+
import { Plus as Plus5 } from "lucide-react";
|
|
23492
23582
|
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
23493
23583
|
function NavbarContainerChrome({
|
|
23494
23584
|
rect,
|
|
@@ -23524,7 +23614,7 @@ function NavbarContainerChrome({
|
|
|
23524
23614
|
e.stopPropagation();
|
|
23525
23615
|
onAdd();
|
|
23526
23616
|
},
|
|
23527
|
-
children: /* @__PURE__ */ jsx36(
|
|
23617
|
+
children: /* @__PURE__ */ jsx36(Plus5, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
23528
23618
|
}
|
|
23529
23619
|
)
|
|
23530
23620
|
}
|
|
@@ -23596,7 +23686,7 @@ function Badge({ className, variant, ...props }) {
|
|
|
23596
23686
|
}
|
|
23597
23687
|
|
|
23598
23688
|
// src/OhhwellsBridge.tsx
|
|
23599
|
-
import { Brush as Brush2, Link as Link2, Plus as
|
|
23689
|
+
import { Brush as Brush2, Link as Link2, Plus as Plus6, Settings } from "lucide-react";
|
|
23600
23690
|
import { Fragment as Fragment12, jsx as jsx39, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
23601
23691
|
var PRIMARY7 = "#0885FE";
|
|
23602
23692
|
var IMAGE_FADE_MS = 300;
|
|
@@ -24373,7 +24463,7 @@ function getNavigationSelectionParent(el) {
|
|
|
24373
24463
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
24374
24464
|
return resolveFooterLinksContainerFrom(el);
|
|
24375
24465
|
}
|
|
24376
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24466
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
24377
24467
|
return getNavigationRoot(el);
|
|
24378
24468
|
}
|
|
24379
24469
|
return null;
|
|
@@ -24595,7 +24685,6 @@ var ICONS = {
|
|
|
24595
24685
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
24596
24686
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
24597
24687
|
};
|
|
24598
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
24599
24688
|
var SELECTION_CHROME_GAP2 = 4;
|
|
24600
24689
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
24601
24690
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24693,7 +24782,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
24693
24782
|
el.style.top = `${top}px`;
|
|
24694
24783
|
el.style.height = `${height}px`;
|
|
24695
24784
|
}
|
|
24696
|
-
var
|
|
24785
|
+
var TOOLBAR_EDGE_MARGIN4 = 4;
|
|
24697
24786
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
24698
24787
|
const isAbove = transform.includes("translateY(-100%)");
|
|
24699
24788
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -24720,8 +24809,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
24720
24809
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
24721
24810
|
const half = toolbarWidth / 2;
|
|
24722
24811
|
return Math.max(
|
|
24723
|
-
|
|
24724
|
-
Math.min(centerX, window.innerWidth -
|
|
24812
|
+
TOOLBAR_EDGE_MARGIN4 + half,
|
|
24813
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN4 - half)
|
|
24725
24814
|
);
|
|
24726
24815
|
}
|
|
24727
24816
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -25160,7 +25249,7 @@ function OhhwellsBridge() {
|
|
|
25160
25249
|
}, []);
|
|
25161
25250
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
25162
25251
|
const [subdomain, setSubdomain] = useState18(() => resolveSubdomain(subdomainFromQuery));
|
|
25163
|
-
|
|
25252
|
+
useLayoutEffect7(() => {
|
|
25164
25253
|
const next = resolveSubdomain(subdomainFromQuery);
|
|
25165
25254
|
if (next !== subdomain) setSubdomain(next);
|
|
25166
25255
|
if (next) return;
|
|
@@ -25611,21 +25700,6 @@ function OhhwellsBridge() {
|
|
|
25611
25700
|
const [isItemDragging, setIsItemDragging] = useState18(false);
|
|
25612
25701
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState18(false);
|
|
25613
25702
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
25614
|
-
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
25615
|
-
const floatingPanelOpenRef = useRef14(false);
|
|
25616
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
25617
|
-
const floatingPanelRef = useRef14(null);
|
|
25618
|
-
floatingPanelRef.current = floatingPanel;
|
|
25619
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
25620
|
-
const buttonCollectionDragRef = useRef14(null);
|
|
25621
|
-
const buttonDropInsertIndexRef = useRef14(null);
|
|
25622
|
-
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
25623
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
25624
|
-
const buttonPointerDragRef = useRef14(null);
|
|
25625
|
-
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
25626
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
25627
|
-
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
25628
|
-
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
25629
25703
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState18(null);
|
|
25630
25704
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState18(null);
|
|
25631
25705
|
const footerDragRef = useRef14(null);
|
|
@@ -25651,6 +25725,21 @@ function OhhwellsBridge() {
|
|
|
25651
25725
|
const stylesRef = useRef14("");
|
|
25652
25726
|
const appliedDrawerRef = useRef14(null);
|
|
25653
25727
|
const pendingDeleteUndoRef = useRef14(null);
|
|
25728
|
+
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
25729
|
+
const floatingPanelOpenRef = useRef14(false);
|
|
25730
|
+
const floatingPanelRef = useRef14(null);
|
|
25731
|
+
floatingPanelRef.current = floatingPanel;
|
|
25732
|
+
const setFloatingPanelRef = useRef14(setFloatingPanel);
|
|
25733
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
25734
|
+
const buttonCollectionDragRef = useRef14(null);
|
|
25735
|
+
const buttonDropInsertIndexRef = useRef14(null);
|
|
25736
|
+
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
25737
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
25738
|
+
const buttonPointerDragRef = useRef14(null);
|
|
25739
|
+
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
25740
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
25741
|
+
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
25742
|
+
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
25654
25743
|
const [sitePages, setSitePages] = useState18([]);
|
|
25655
25744
|
const [sectionsByPath, setSectionsByPath] = useState18({});
|
|
25656
25745
|
const sectionsPrefetchGenRef = useRef14(0);
|
|
@@ -25659,7 +25748,18 @@ function OhhwellsBridge() {
|
|
|
25659
25748
|
const linkPopoverOpenRef = useRef14(false);
|
|
25660
25749
|
const linkPopoverGraceUntilRef = useRef14(0);
|
|
25661
25750
|
setLinkPopoverRef.current = setLinkPopover;
|
|
25751
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
25662
25752
|
linkPopoverSessionRef.current = linkPopover;
|
|
25753
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
25754
|
+
useEffect17(() => {
|
|
25755
|
+
const syncViewport = () => {
|
|
25756
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
25757
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
25758
|
+
};
|
|
25759
|
+
syncViewport();
|
|
25760
|
+
window.addEventListener("resize", syncViewport);
|
|
25761
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
25762
|
+
}, []);
|
|
25663
25763
|
useEffect17(() => {
|
|
25664
25764
|
setSectionOrderPersistHandler((entries) => {
|
|
25665
25765
|
const currentPath = window.location.pathname;
|
|
@@ -27327,7 +27427,7 @@ function OhhwellsBridge() {
|
|
|
27327
27427
|
isFooterFrameSelection,
|
|
27328
27428
|
postToParent2
|
|
27329
27429
|
]);
|
|
27330
|
-
|
|
27430
|
+
useLayoutEffect7(() => {
|
|
27331
27431
|
if (!subdomain || isEditMode) {
|
|
27332
27432
|
setFetchState("done");
|
|
27333
27433
|
return;
|
|
@@ -27354,6 +27454,7 @@ function OhhwellsBridge() {
|
|
|
27354
27454
|
applyAiFooterFromContent(content);
|
|
27355
27455
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27356
27456
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
27457
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27357
27458
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27358
27459
|
}
|
|
27359
27460
|
applyBrandChrome(content);
|
|
@@ -27364,12 +27465,12 @@ function OhhwellsBridge() {
|
|
|
27364
27465
|
if (key === "__ohw_sections") continue;
|
|
27365
27466
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27366
27467
|
if (key === AI_FOOTER_KEY) continue;
|
|
27468
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27469
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27367
27470
|
if (key === BRAND_KIT_KEY) continue;
|
|
27368
27471
|
if (key === STYLE_STORE_KEY) continue;
|
|
27369
27472
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27370
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27371
27473
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27372
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27373
27474
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27374
27475
|
continue;
|
|
27375
27476
|
}
|
|
@@ -27584,17 +27685,18 @@ function OhhwellsBridge() {
|
|
|
27584
27685
|
}
|
|
27585
27686
|
applyAiFooterFromContent(content);
|
|
27586
27687
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27688
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27587
27689
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27588
27690
|
}
|
|
27589
27691
|
for (const [key, val] of Object.entries(content)) {
|
|
27590
27692
|
if (key === "__ohw_sections") continue;
|
|
27591
27693
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27592
27694
|
if (key === AI_FOOTER_KEY) continue;
|
|
27695
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27696
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27593
27697
|
if (key === BRAND_KIT_KEY) continue;
|
|
27594
27698
|
if (key === STYLE_STORE_KEY) continue;
|
|
27595
27699
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27596
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27597
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27598
27700
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27599
27701
|
continue;
|
|
27600
27702
|
}
|
|
@@ -27667,7 +27769,7 @@ function OhhwellsBridge() {
|
|
|
27667
27769
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
27668
27770
|
};
|
|
27669
27771
|
}, [subdomain, isEditMode, pathname]);
|
|
27670
|
-
|
|
27772
|
+
useLayoutEffect7(() => {
|
|
27671
27773
|
const el = document.getElementById("ohw-loader");
|
|
27672
27774
|
if (!el) return;
|
|
27673
27775
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
@@ -27851,26 +27953,11 @@ function OhhwellsBridge() {
|
|
|
27851
27953
|
const t2 = setTimeout(measure, 500);
|
|
27852
27954
|
const ro = new ResizeObserver(schedule);
|
|
27853
27955
|
ro.observe(document.body);
|
|
27854
|
-
let lastWidth = window.innerWidth;
|
|
27855
|
-
let resizeTimers = [];
|
|
27856
|
-
const clearResizeTimers = () => {
|
|
27857
|
-
resizeTimers.forEach(clearTimeout);
|
|
27858
|
-
resizeTimers = [];
|
|
27859
|
-
};
|
|
27860
|
-
const handleResize = () => {
|
|
27861
|
-
if (window.innerWidth === lastWidth) return;
|
|
27862
|
-
lastWidth = window.innerWidth;
|
|
27863
|
-
clearResizeTimers();
|
|
27864
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
27865
|
-
};
|
|
27866
|
-
window.addEventListener("resize", handleResize);
|
|
27867
27956
|
return () => {
|
|
27868
27957
|
clearTimeout(t1);
|
|
27869
27958
|
clearTimeout(t2);
|
|
27870
27959
|
if (raf != null) cancelAnimationFrame(raf);
|
|
27871
27960
|
ro.disconnect();
|
|
27872
|
-
clearResizeTimers();
|
|
27873
|
-
window.removeEventListener("resize", handleResize);
|
|
27874
27961
|
};
|
|
27875
27962
|
}, [pathname, isEditMode, postToParent2]);
|
|
27876
27963
|
useEffect17(() => {
|
|
@@ -28169,6 +28256,13 @@ function OhhwellsBridge() {
|
|
|
28169
28256
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28170
28257
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28171
28258
|
if (isInsideLinkEditor(target)) return;
|
|
28259
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28260
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28261
|
+
if (target.closest(
|
|
28262
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28263
|
+
)) {
|
|
28264
|
+
return;
|
|
28265
|
+
}
|
|
28172
28266
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28173
28267
|
clearMediaSelectionRef.current();
|
|
28174
28268
|
}
|
|
@@ -28192,13 +28286,6 @@ function OhhwellsBridge() {
|
|
|
28192
28286
|
return;
|
|
28193
28287
|
}
|
|
28194
28288
|
}
|
|
28195
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28196
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28197
|
-
if (target.closest(
|
|
28198
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28199
|
-
)) {
|
|
28200
|
-
return;
|
|
28201
|
-
}
|
|
28202
28289
|
{
|
|
28203
28290
|
const formEl = getFormElement(target);
|
|
28204
28291
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -28352,9 +28439,13 @@ function OhhwellsBridge() {
|
|
|
28352
28439
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
28353
28440
|
e.preventDefault();
|
|
28354
28441
|
e.stopPropagation();
|
|
28355
|
-
selectIconElementRef.current(editable);
|
|
28356
28442
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
28357
28443
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
28444
|
+
if (aiIcon) {
|
|
28445
|
+
aiSectionApiRef.current?.selectFromElement(editable);
|
|
28446
|
+
} else {
|
|
28447
|
+
selectIconElementRef.current(editable);
|
|
28448
|
+
}
|
|
28358
28449
|
postToParentRef.current({
|
|
28359
28450
|
type: "ow:icon-pick",
|
|
28360
28451
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -28582,6 +28673,9 @@ function OhhwellsBridge() {
|
|
|
28582
28673
|
setHoveredItemRect(null);
|
|
28583
28674
|
hoveredNavContainerRef.current = null;
|
|
28584
28675
|
setHoveredNavContainerRect(null);
|
|
28676
|
+
siblingHintElRef.current = null;
|
|
28677
|
+
setSiblingHintRect(null);
|
|
28678
|
+
setSiblingHintRects([]);
|
|
28585
28679
|
return;
|
|
28586
28680
|
}
|
|
28587
28681
|
{
|
|
@@ -28702,7 +28796,6 @@ function OhhwellsBridge() {
|
|
|
28702
28796
|
hoveredNavContainerRef.current = null;
|
|
28703
28797
|
setHoveredNavContainerRect(null);
|
|
28704
28798
|
hoveredItemElRef.current = editable;
|
|
28705
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
28706
28799
|
}
|
|
28707
28800
|
}
|
|
28708
28801
|
}
|
|
@@ -29412,7 +29505,11 @@ function OhhwellsBridge() {
|
|
|
29412
29505
|
};
|
|
29413
29506
|
const handleMouseMove = (e) => {
|
|
29414
29507
|
const { clientX, clientY } = e;
|
|
29415
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29508
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
29509
|
+
dismissImageHover();
|
|
29510
|
+
clearImageHover();
|
|
29511
|
+
return;
|
|
29512
|
+
}
|
|
29416
29513
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
29417
29514
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
29418
29515
|
formHoverElRef.current = null;
|
|
@@ -29441,7 +29538,12 @@ function OhhwellsBridge() {
|
|
|
29441
29538
|
setHoveredItemRect(null);
|
|
29442
29539
|
hoveredNavContainerRef.current = null;
|
|
29443
29540
|
setHoveredNavContainerRect(null);
|
|
29541
|
+
siblingHintElRef.current = null;
|
|
29542
|
+
setSiblingHintRect(null);
|
|
29543
|
+
setSiblingHintRects([]);
|
|
29444
29544
|
dismissImageHover();
|
|
29545
|
+
clearImageHover();
|
|
29546
|
+
setSectionGap(null);
|
|
29445
29547
|
return;
|
|
29446
29548
|
}
|
|
29447
29549
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -29453,7 +29555,11 @@ function OhhwellsBridge() {
|
|
|
29453
29555
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
29454
29556
|
const { clientX, clientY } = e.data;
|
|
29455
29557
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
29456
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29558
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
29559
|
+
dismissImageHover();
|
|
29560
|
+
clearImageHover();
|
|
29561
|
+
return;
|
|
29562
|
+
}
|
|
29457
29563
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
29458
29564
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
29459
29565
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -29833,6 +29939,7 @@ function OhhwellsBridge() {
|
|
|
29833
29939
|
applyAiFooterFromContent(content);
|
|
29834
29940
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
29835
29941
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
29942
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
29836
29943
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
29837
29944
|
}
|
|
29838
29945
|
applyBrandChrome(content);
|
|
@@ -29847,12 +29954,12 @@ function OhhwellsBridge() {
|
|
|
29847
29954
|
}
|
|
29848
29955
|
if (key === AI_SECTIONS_KEY) continue;
|
|
29849
29956
|
if (key === AI_FOOTER_KEY) continue;
|
|
29957
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
29958
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
29850
29959
|
if (key === BRAND_KIT_KEY) continue;
|
|
29851
29960
|
if (key === STYLE_STORE_KEY) continue;
|
|
29852
29961
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
29853
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
29854
29962
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
29855
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
29856
29963
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
29857
29964
|
continue;
|
|
29858
29965
|
}
|
|
@@ -30227,6 +30334,44 @@ function OhhwellsBridge() {
|
|
|
30227
30334
|
});
|
|
30228
30335
|
};
|
|
30229
30336
|
window.addEventListener("message", handleAiSetStyles);
|
|
30337
|
+
const handleAiSetButtonStyle = (e) => {
|
|
30338
|
+
if (e.data?.type !== "ow:ai-set-button-style") return;
|
|
30339
|
+
const nodeKey = typeof e.data.hrefKey === "string" ? e.data.hrefKey : "";
|
|
30340
|
+
const keyed = nodeKey ? document.querySelector(
|
|
30341
|
+
`[data-ohw-href-key="${CSS.escape(nodeKey)}"], [data-ohw-key="${CSS.escape(nodeKey)}"]`
|
|
30342
|
+
) : null;
|
|
30343
|
+
const hrefKey = buttonId(keyed);
|
|
30344
|
+
const el = hrefKey ? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) : null;
|
|
30345
|
+
const previous = editContentRef.current[BUTTON_ASSIGNMENTS_KEY] ?? "";
|
|
30346
|
+
if (!el || !hrefKey || !isCtaButton(el)) {
|
|
30347
|
+
postToParentRef.current({ type: "ow:ai-button-style-applied", ok: false, previous, value: previous });
|
|
30348
|
+
return;
|
|
30349
|
+
}
|
|
30350
|
+
const tokens = tokensFromButton(el);
|
|
30351
|
+
const current = assignmentFor(el, editContentRef.current, tokens);
|
|
30352
|
+
const patch = e.data.assignment;
|
|
30353
|
+
const next = {
|
|
30354
|
+
variant: patch?.variant ?? current.variant,
|
|
30355
|
+
size: patch?.size ?? current.size
|
|
30356
|
+
};
|
|
30357
|
+
const value = typeof e.data.assignments === "string" ? e.data.assignments : JSON.stringify(withAssignment(editContentRef.current, hrefKey, next));
|
|
30358
|
+
editContentRef.current = { ...editContentRef.current, [BUTTON_ASSIGNMENTS_KEY]: value };
|
|
30359
|
+
applyButtonStyle(el, next, tokens);
|
|
30360
|
+
postToParentRef.current({
|
|
30361
|
+
type: "ow:change",
|
|
30362
|
+
nodes: [{ key: BUTTON_ASSIGNMENTS_KEY, text: value }]
|
|
30363
|
+
});
|
|
30364
|
+
postToParentRef.current({
|
|
30365
|
+
type: "ow:ai-button-style-applied",
|
|
30366
|
+
ok: true,
|
|
30367
|
+
// The resolved id, which may differ from the key the editor sent — undo must target this one.
|
|
30368
|
+
hrefKey,
|
|
30369
|
+
previous,
|
|
30370
|
+
previousAssignment: current,
|
|
30371
|
+
value
|
|
30372
|
+
});
|
|
30373
|
+
};
|
|
30374
|
+
window.addEventListener("message", handleAiSetButtonStyle);
|
|
30230
30375
|
const handleGetBrand = (e) => {
|
|
30231
30376
|
if (e.data?.type !== "ow:get-brand") return;
|
|
30232
30377
|
const template = deriveTemplateBrand();
|
|
@@ -30450,6 +30595,12 @@ function OhhwellsBridge() {
|
|
|
30450
30595
|
closeLinkPopoverRef.current();
|
|
30451
30596
|
return;
|
|
30452
30597
|
}
|
|
30598
|
+
if (floatingPanelOpenRef.current) {
|
|
30599
|
+
setFloatingPanelRef.current(null);
|
|
30600
|
+
deselectRef.current();
|
|
30601
|
+
deactivateRef.current();
|
|
30602
|
+
return;
|
|
30603
|
+
}
|
|
30453
30604
|
deselectRef.current();
|
|
30454
30605
|
deactivateRef.current();
|
|
30455
30606
|
clearMediaSelectionRef.current();
|
|
@@ -31260,6 +31411,7 @@ function OhhwellsBridge() {
|
|
|
31260
31411
|
window.removeEventListener("message", handleAiSetSections);
|
|
31261
31412
|
window.removeEventListener("message", handleAiSetBrand);
|
|
31262
31413
|
window.removeEventListener("message", handleAiSetStyles);
|
|
31414
|
+
window.removeEventListener("message", handleAiSetButtonStyle);
|
|
31263
31415
|
window.removeEventListener("message", handleCollectItems);
|
|
31264
31416
|
window.removeEventListener("message", handleAiApplyItems);
|
|
31265
31417
|
window.removeEventListener("message", handleGetBrand);
|
|
@@ -31271,10 +31423,10 @@ function OhhwellsBridge() {
|
|
|
31271
31423
|
window.removeEventListener("message", handleDeleteSection);
|
|
31272
31424
|
window.removeEventListener("message", handleDuplicateSection);
|
|
31273
31425
|
window.removeEventListener("message", handleDeactivate);
|
|
31274
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31275
31426
|
window.removeEventListener("message", handleToastAction);
|
|
31276
31427
|
window.removeEventListener("message", handleFormCount);
|
|
31277
31428
|
window.removeEventListener("message", handleUiEscape);
|
|
31429
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31278
31430
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
31279
31431
|
autoSaveTimers.current.clear();
|
|
31280
31432
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -31568,7 +31720,7 @@ function OhhwellsBridge() {
|
|
|
31568
31720
|
postToParent2({
|
|
31569
31721
|
type: "ow:ready",
|
|
31570
31722
|
version: "1",
|
|
31571
|
-
bridgeVersion: "0.1.
|
|
31723
|
+
bridgeVersion: "0.1.149",
|
|
31572
31724
|
path: pathname,
|
|
31573
31725
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31574
31726
|
sections
|
|
@@ -32304,7 +32456,7 @@ function OhhwellsBridge() {
|
|
|
32304
32456
|
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
|
|
32305
32457
|
onClick: () => setFieldTypePickerOpen((open) => !open),
|
|
32306
32458
|
"data-ohw-add-field": "",
|
|
32307
|
-
children: /* @__PURE__ */ jsx39(
|
|
32459
|
+
children: /* @__PURE__ */ jsx39(Plus6, { size: 15, "aria-hidden": true })
|
|
32308
32460
|
}
|
|
32309
32461
|
),
|
|
32310
32462
|
/* @__PURE__ */ jsx39("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|