@ohhwells/bridge 0.1.149-next.400 → 0.1.149
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 +718 -809
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +726 -833
- 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 +0 -116
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -6637,21 +6637,6 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6637
6637
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6638
6638
|
return target ? pricingFeatureList(target).length : 0;
|
|
6639
6639
|
}
|
|
6640
|
-
function prevailingFeatureIcon(features) {
|
|
6641
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6642
|
-
for (const row of features) {
|
|
6643
|
-
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6644
|
-
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6645
|
-
entry.count += 1;
|
|
6646
|
-
counts.set(key, entry);
|
|
6647
|
-
}
|
|
6648
|
-
let best = null;
|
|
6649
|
-
for (const entry of counts.values()) {
|
|
6650
|
-
if (!best || entry.count > best.count) best = entry;
|
|
6651
|
-
}
|
|
6652
|
-
if (!best) return {};
|
|
6653
|
-
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6654
|
-
}
|
|
6655
6640
|
function addPricingCardFeature(tree, index, text) {
|
|
6656
6641
|
return withPricingCollection(tree, (collection) => {
|
|
6657
6642
|
const children = collection.children;
|
|
@@ -6660,7 +6645,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6660
6645
|
const features = pricingFeatureList(target);
|
|
6661
6646
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6662
6647
|
target.slots = target.slots ?? {};
|
|
6663
|
-
target.slots.features = [...features, { text
|
|
6648
|
+
target.slots.features = [...features, { text }];
|
|
6664
6649
|
return true;
|
|
6665
6650
|
});
|
|
6666
6651
|
}
|
|
@@ -7843,7 +7828,7 @@ var AI_MOBILE_CSS = [
|
|
|
7843
7828
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7844
7829
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7845
7830
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7846
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7831
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
7847
7832
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7848
7833
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7849
7834
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7859,10 +7844,8 @@ var AI_MOBILE_CSS = [
|
|
|
7859
7844
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7860
7845
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7861
7846
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7862
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7863
|
-
|
|
7864
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7865
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7847
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7848
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7866
7849
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7867
7850
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7868
7851
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -8067,31 +8050,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
8067
8050
|
function textAttrs(ctx, path) {
|
|
8068
8051
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
8069
8052
|
}
|
|
8070
|
-
var AI_RESPONSIVE_CSS = [
|
|
8071
|
-
"@media (max-width: 960px) {",
|
|
8072
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
8073
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
8074
|
-
"}",
|
|
8075
|
-
"@media (max-width: 640px) {",
|
|
8076
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
8077
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
8078
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
8079
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
8080
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
8081
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
8082
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
8083
|
-
// layered text used to be.
|
|
8084
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
8085
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
8086
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
8087
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
8088
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
8089
|
-
// other rule had already been taught to stand down.
|
|
8090
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
8091
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
8092
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
8093
|
-
"}"
|
|
8094
|
-
].join("\n");
|
|
8095
8053
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8096
8054
|
function MediaBox({
|
|
8097
8055
|
refValue,
|
|
@@ -8146,7 +8104,7 @@ function MediaBox({
|
|
|
8146
8104
|
position: fill ? "absolute" : void 0,
|
|
8147
8105
|
inset: fill ? 0 : void 0,
|
|
8148
8106
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8149
|
-
height: fill ? "100%" :
|
|
8107
|
+
height: fill ? "100%" : void 0,
|
|
8150
8108
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8151
8109
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8152
8110
|
borderRadius: radius,
|
|
@@ -9642,7 +9600,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9642
9600
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9643
9601
|
"div",
|
|
9644
9602
|
{
|
|
9645
|
-
"data-ai-grid":
|
|
9603
|
+
"data-ai-grid": "",
|
|
9646
9604
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9647
9605
|
style: {
|
|
9648
9606
|
display: "grid",
|
|
@@ -9944,7 +9902,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9944
9902
|
},
|
|
9945
9903
|
children: [
|
|
9946
9904
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
9947
|
-
// The section's `data-ai-
|
|
9905
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
9948
9906
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9949
9907
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9950
9908
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10363,7 +10321,6 @@ function AiTreeRenderer({
|
|
|
10363
10321
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10364
10322
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10365
10323
|
...bgAttrs,
|
|
10366
|
-
"data-ai-responsive": "",
|
|
10367
10324
|
style: {
|
|
10368
10325
|
position: "relative",
|
|
10369
10326
|
padding: `${padCss} 0`,
|
|
@@ -10377,13 +10334,12 @@ function AiTreeRenderer({
|
|
|
10377
10334
|
...fillHeight ? { display: "grid" } : {}
|
|
10378
10335
|
},
|
|
10379
10336
|
children: [
|
|
10380
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
10381
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10382
10337
|
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10338
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10383
10339
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10384
10340
|
"div",
|
|
10385
10341
|
{
|
|
10386
|
-
"data-ai-
|
|
10342
|
+
"data-ai-container": "",
|
|
10387
10343
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10388
10344
|
style: {
|
|
10389
10345
|
position: "relative",
|
|
@@ -10400,7 +10356,7 @@ function AiTreeRenderer({
|
|
|
10400
10356
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10401
10357
|
"div",
|
|
10402
10358
|
{
|
|
10403
|
-
"data-ai-
|
|
10359
|
+
"data-ai-row": "",
|
|
10404
10360
|
style: {
|
|
10405
10361
|
display: "grid",
|
|
10406
10362
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -11062,10 +11018,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
11062
11018
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
11063
11019
|
continue;
|
|
11064
11020
|
}
|
|
11021
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
11065
11022
|
let container = existing?.container;
|
|
11066
|
-
let isNewMount = false;
|
|
11067
11023
|
if (!container || !container.isConnected) {
|
|
11068
|
-
isNewMount = true;
|
|
11069
11024
|
existing?.root.unmount();
|
|
11070
11025
|
container?.remove();
|
|
11071
11026
|
container = document.createElement("div");
|
|
@@ -17507,7 +17462,6 @@ function MediaOverlay({
|
|
|
17507
17462
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
17508
17463
|
);
|
|
17509
17464
|
}, [isVideo]);
|
|
17510
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
17511
17465
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
17512
17466
|
const box = {
|
|
17513
17467
|
position: "fixed",
|
|
@@ -17606,10 +17560,11 @@ function MediaOverlay({
|
|
|
17606
17560
|
className: "flex items-center justify-center cursor-pointer",
|
|
17607
17561
|
style: {
|
|
17608
17562
|
...box,
|
|
17609
|
-
//
|
|
17610
|
-
//
|
|
17611
|
-
//
|
|
17612
|
-
|
|
17563
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
17564
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
17565
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
17566
|
+
// Replace still works.
|
|
17567
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
17613
17568
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
17614
17569
|
// than hovered. Hover keeps the existing tinted preview.
|
|
17615
17570
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -17636,17 +17591,17 @@ function MediaOverlay({
|
|
|
17636
17591
|
},
|
|
17637
17592
|
children: [
|
|
17638
17593
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
17639
|
-
|
|
17594
|
+
isVideo ? "Replace video" : "Replace image"
|
|
17640
17595
|
]
|
|
17641
17596
|
}
|
|
17642
17597
|
),
|
|
17643
|
-
|
|
17598
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
17644
17599
|
Button,
|
|
17645
17600
|
{
|
|
17646
17601
|
"data-ohw-media-overlay": "",
|
|
17647
17602
|
variant: "outline",
|
|
17648
17603
|
size: "sm",
|
|
17649
|
-
"aria-label":
|
|
17604
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
17650
17605
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
17651
17606
|
style: {
|
|
17652
17607
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -17669,7 +17624,7 @@ function MediaOverlay({
|
|
|
17669
17624
|
},
|
|
17670
17625
|
children: [
|
|
17671
17626
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
17672
|
-
replaceMode === "full" ?
|
|
17627
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
17673
17628
|
]
|
|
17674
17629
|
}
|
|
17675
17630
|
)
|
|
@@ -18179,7 +18134,7 @@ function AiSectionOverlay({
|
|
|
18179
18134
|
|
|
18180
18135
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18181
18136
|
var import_react10 = require("react");
|
|
18182
|
-
var
|
|
18137
|
+
var import_lucide_react8 = require("lucide-react");
|
|
18183
18138
|
|
|
18184
18139
|
// src/lib/ai-media-strip-tree.ts
|
|
18185
18140
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18293,6 +18248,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18293
18248
|
return true;
|
|
18294
18249
|
});
|
|
18295
18250
|
}
|
|
18251
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18252
|
+
return withMediaStrip(tree, (block) => {
|
|
18253
|
+
const items = block.items;
|
|
18254
|
+
if (index < 0 || index >= items.length) return false;
|
|
18255
|
+
items[index] = { ...items[index], alt };
|
|
18256
|
+
return true;
|
|
18257
|
+
});
|
|
18258
|
+
}
|
|
18296
18259
|
function setMediaStripItemLink(tree, index, link) {
|
|
18297
18260
|
return withMediaStrip(tree, (block) => {
|
|
18298
18261
|
const items = block.items;
|
|
@@ -18310,117 +18273,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18310
18273
|
});
|
|
18311
18274
|
}
|
|
18312
18275
|
|
|
18313
|
-
// src/ui/dialog.tsx
|
|
18314
|
-
var React9 = __toESM(require("react"), 1);
|
|
18315
|
-
var import_radix_ui6 = require("radix-ui");
|
|
18316
|
-
var import_lucide_react8 = require("lucide-react");
|
|
18317
|
-
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
18318
|
-
function Dialog2({
|
|
18319
|
-
...props
|
|
18320
|
-
}) {
|
|
18321
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
18322
|
-
}
|
|
18323
|
-
function DialogPortal({
|
|
18324
|
-
...props
|
|
18325
|
-
}) {
|
|
18326
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
18327
|
-
}
|
|
18328
|
-
function DialogOverlay({
|
|
18329
|
-
className,
|
|
18330
|
-
...props
|
|
18331
|
-
}) {
|
|
18332
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18333
|
-
import_radix_ui6.Dialog.Overlay,
|
|
18334
|
-
{
|
|
18335
|
-
"data-slot": "dialog-overlay",
|
|
18336
|
-
"data-ohw-link-modal-root": "",
|
|
18337
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18338
|
-
...props
|
|
18339
|
-
}
|
|
18340
|
-
);
|
|
18341
|
-
}
|
|
18342
|
-
var DialogContent = React9.forwardRef(
|
|
18343
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18344
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
18345
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
18346
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18347
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18348
|
-
import_radix_ui6.Dialog.Content,
|
|
18349
|
-
{
|
|
18350
|
-
ref,
|
|
18351
|
-
"data-slot": "dialog-content",
|
|
18352
|
-
className: cn(
|
|
18353
|
-
positionMode,
|
|
18354
|
-
"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",
|
|
18355
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18356
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18357
|
-
className
|
|
18358
|
-
),
|
|
18359
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
18360
|
-
...props,
|
|
18361
|
-
children: [
|
|
18362
|
-
children,
|
|
18363
|
-
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18364
|
-
import_radix_ui6.Dialog.Close,
|
|
18365
|
-
{
|
|
18366
|
-
type: "button",
|
|
18367
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18368
|
-
"aria-label": "Close",
|
|
18369
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
18370
|
-
}
|
|
18371
|
-
) : null
|
|
18372
|
-
]
|
|
18373
|
-
}
|
|
18374
|
-
)
|
|
18375
|
-
] });
|
|
18376
|
-
}
|
|
18377
|
-
);
|
|
18378
|
-
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
18379
|
-
function DialogHeader({
|
|
18380
|
-
className,
|
|
18381
|
-
...props
|
|
18382
|
-
}) {
|
|
18383
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18384
|
-
}
|
|
18385
|
-
function DialogFooter({
|
|
18386
|
-
className,
|
|
18387
|
-
...props
|
|
18388
|
-
}) {
|
|
18389
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18390
|
-
"div",
|
|
18391
|
-
{
|
|
18392
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
18393
|
-
...props
|
|
18394
|
-
}
|
|
18395
|
-
);
|
|
18396
|
-
}
|
|
18397
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18398
|
-
import_radix_ui6.Dialog.Title,
|
|
18399
|
-
{
|
|
18400
|
-
ref,
|
|
18401
|
-
className: cn(
|
|
18402
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18403
|
-
className
|
|
18404
|
-
),
|
|
18405
|
-
...props
|
|
18406
|
-
}
|
|
18407
|
-
));
|
|
18408
|
-
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
18409
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18410
|
-
import_radix_ui6.Dialog.Description,
|
|
18411
|
-
{
|
|
18412
|
-
ref,
|
|
18413
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
18414
|
-
...props
|
|
18415
|
-
}
|
|
18416
|
-
));
|
|
18417
|
-
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
18418
|
-
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
18419
|
-
|
|
18420
18276
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18421
|
-
var
|
|
18422
|
-
var PRIMARY3 = "
|
|
18423
|
-
var
|
|
18277
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
18278
|
+
var PRIMARY3 = "#0885FE";
|
|
18279
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18280
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
18424
18281
|
function findMediaStripItemElement(sectionId, index) {
|
|
18425
18282
|
const sectionEl = findByInstanceId(sectionId);
|
|
18426
18283
|
if (!sectionEl) return null;
|
|
@@ -18430,35 +18287,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18430
18287
|
}
|
|
18431
18288
|
return null;
|
|
18432
18289
|
}
|
|
18433
|
-
function
|
|
18434
|
-
|
|
18435
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18436
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18437
|
-
if (!itemEl) return null;
|
|
18438
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18439
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18440
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18441
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18442
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
18443
|
-
return { sectionId, index };
|
|
18444
|
-
}
|
|
18445
|
-
function sameRef(a, b) {
|
|
18446
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18447
|
-
}
|
|
18448
|
-
function rectOf(el) {
|
|
18290
|
+
function readRect2(ref) {
|
|
18291
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18449
18292
|
if (!el) return null;
|
|
18450
18293
|
const r2 = el.getBoundingClientRect();
|
|
18451
18294
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18452
18295
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18453
18296
|
}
|
|
18454
|
-
function
|
|
18455
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18456
|
-
}
|
|
18457
|
-
function readStripRect(ref) {
|
|
18458
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18459
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18460
|
-
}
|
|
18461
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18297
|
+
function useLiveItemRect(ref) {
|
|
18462
18298
|
const [rect, setRect] = (0, import_react10.useState)(null);
|
|
18463
18299
|
(0, import_react10.useEffect)(() => {
|
|
18464
18300
|
if (!ref) {
|
|
@@ -18466,7 +18302,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18466
18302
|
return;
|
|
18467
18303
|
}
|
|
18468
18304
|
const update = () => {
|
|
18469
|
-
const next =
|
|
18305
|
+
const next = readRect2(ref);
|
|
18470
18306
|
setRect(
|
|
18471
18307
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18472
18308
|
);
|
|
@@ -18481,49 +18317,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18481
18317
|
window.removeEventListener("resize", update);
|
|
18482
18318
|
clearInterval(interval);
|
|
18483
18319
|
};
|
|
18484
|
-
}, [ref?.sectionId, ref?.index
|
|
18320
|
+
}, [ref?.sectionId, ref?.index]);
|
|
18485
18321
|
return rect;
|
|
18486
18322
|
}
|
|
18487
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
18488
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18489
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18490
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
18491
|
-
const slotRef = (0, import_react10.useRef)(null);
|
|
18492
|
-
const [shift, setShift] = (0, import_react10.useState)(0);
|
|
18493
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
18494
|
-
(0, import_react10.useLayoutEffect)(() => {
|
|
18495
|
-
const slot = slotRef.current;
|
|
18496
|
-
if (!slot) return;
|
|
18497
|
-
const clamp = () => {
|
|
18498
|
-
const w = slot.offsetWidth;
|
|
18499
|
-
if (w <= 0) return;
|
|
18500
|
-
const half = w / 2;
|
|
18501
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18502
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18503
|
-
};
|
|
18504
|
-
clamp();
|
|
18505
|
-
const ro = new ResizeObserver(clamp);
|
|
18506
|
-
ro.observe(slot);
|
|
18507
|
-
return () => ro.disconnect();
|
|
18508
|
-
}, [centerX, children]);
|
|
18509
|
-
const mobile = window.innerWidth <= 480;
|
|
18510
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18511
|
-
"div",
|
|
18512
|
-
{
|
|
18513
|
-
ref: slotRef,
|
|
18514
|
-
"data-ohw-bridge": "",
|
|
18515
|
-
"data-ohw-item-interaction": "",
|
|
18516
|
-
className: "pointer-events-auto fixed",
|
|
18517
|
-
style: {
|
|
18518
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18519
|
-
left: centerX + shift,
|
|
18520
|
-
transform: "translate(-50%, -100%)",
|
|
18521
|
-
zIndex: 2147483645
|
|
18522
|
-
},
|
|
18523
|
-
children
|
|
18524
|
-
}
|
|
18525
|
-
);
|
|
18526
|
-
}
|
|
18527
18323
|
function requestValidateTree(postToParent2, tree) {
|
|
18528
18324
|
return new Promise((resolve) => {
|
|
18529
18325
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18560,177 +18356,221 @@ function requestAssetPick(postToParent2) {
|
|
|
18560
18356
|
postToParent2({ type: "ow:asset-pick", id });
|
|
18561
18357
|
});
|
|
18562
18358
|
}
|
|
18563
|
-
function
|
|
18359
|
+
function Pill({
|
|
18564
18360
|
label,
|
|
18565
18361
|
onClick,
|
|
18566
|
-
disabled
|
|
18567
|
-
active
|
|
18568
|
-
children
|
|
18362
|
+
disabled,
|
|
18363
|
+
active
|
|
18569
18364
|
}) {
|
|
18570
|
-
|
|
18571
|
-
|
|
18572
|
-
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
|
|
18365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18366
|
+
"button",
|
|
18367
|
+
{
|
|
18368
|
+
type: "button",
|
|
18369
|
+
onClick,
|
|
18370
|
+
disabled,
|
|
18371
|
+
style: {
|
|
18372
|
+
height: 28,
|
|
18373
|
+
padding: "0 10px",
|
|
18374
|
+
display: "inline-flex",
|
|
18375
|
+
alignItems: "center",
|
|
18376
|
+
gap: 4,
|
|
18377
|
+
borderRadius: 999,
|
|
18378
|
+
border: "none",
|
|
18379
|
+
cursor: disabled ? "default" : "pointer",
|
|
18380
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18381
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18382
|
+
opacity: disabled ? 0.4 : 1,
|
|
18383
|
+
fontSize: 12,
|
|
18384
|
+
lineHeight: "16px",
|
|
18385
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18386
|
+
whiteSpace: "nowrap",
|
|
18387
|
+
flex: "0 0 auto"
|
|
18388
|
+
},
|
|
18389
|
+
children: label
|
|
18390
|
+
}
|
|
18391
|
+
);
|
|
18578
18392
|
}
|
|
18579
|
-
function
|
|
18580
|
-
|
|
18581
|
-
value,
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
|
|
18586
|
-
|
|
18587
|
-
|
|
18588
|
-
|
|
18589
|
-
|
|
18590
|
-
"
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
18598
|
-
|
|
18599
|
-
|
|
18600
|
-
) }),
|
|
18601
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
18602
|
-
const selected = option.value === value;
|
|
18603
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18604
|
-
DropdownMenuItem,
|
|
18393
|
+
function AltInput({ value, onCommit }) {
|
|
18394
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
18395
|
+
(0, import_react10.useEffect)(() => setDraft(value), [value]);
|
|
18396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18397
|
+
"div",
|
|
18398
|
+
{
|
|
18399
|
+
style: {
|
|
18400
|
+
display: "flex",
|
|
18401
|
+
alignItems: "center",
|
|
18402
|
+
gap: 6,
|
|
18403
|
+
height: 28,
|
|
18404
|
+
padding: "0 12px",
|
|
18405
|
+
borderRadius: 999,
|
|
18406
|
+
background: "#ffffff",
|
|
18407
|
+
width: "100%",
|
|
18408
|
+
maxWidth: 260,
|
|
18409
|
+
boxSizing: "border-box"
|
|
18410
|
+
},
|
|
18411
|
+
children: [
|
|
18412
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18413
|
+
"span",
|
|
18605
18414
|
{
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
)
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18641
|
-
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18415
|
+
style: {
|
|
18416
|
+
flex: "0 0 auto",
|
|
18417
|
+
color: OHW_BLUE_DARK,
|
|
18418
|
+
fontSize: 10,
|
|
18419
|
+
fontWeight: 700,
|
|
18420
|
+
textTransform: "uppercase",
|
|
18421
|
+
letterSpacing: 0.4
|
|
18422
|
+
},
|
|
18423
|
+
children: "Alt"
|
|
18424
|
+
}
|
|
18425
|
+
),
|
|
18426
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18427
|
+
"input",
|
|
18428
|
+
{
|
|
18429
|
+
type: "text",
|
|
18430
|
+
value: draft,
|
|
18431
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18432
|
+
onBlur: () => {
|
|
18433
|
+
if (draft !== value) onCommit(draft);
|
|
18434
|
+
},
|
|
18435
|
+
onKeyDown: (e) => {
|
|
18436
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18437
|
+
if (e.key === "Escape") {
|
|
18438
|
+
setDraft(value);
|
|
18439
|
+
e.currentTarget.blur();
|
|
18440
|
+
}
|
|
18441
|
+
},
|
|
18442
|
+
placeholder: "Describe this image",
|
|
18443
|
+
"aria-label": "Image alt text",
|
|
18444
|
+
style: {
|
|
18445
|
+
flex: 1,
|
|
18446
|
+
minWidth: 0,
|
|
18447
|
+
border: "none",
|
|
18448
|
+
outline: "none",
|
|
18449
|
+
background: "transparent",
|
|
18450
|
+
fontSize: 12,
|
|
18451
|
+
lineHeight: "16px",
|
|
18452
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18453
|
+
color: "#1f2937"
|
|
18454
|
+
}
|
|
18455
|
+
}
|
|
18456
|
+
)
|
|
18457
|
+
]
|
|
18458
|
+
}
|
|
18459
|
+
);
|
|
18460
|
+
}
|
|
18461
|
+
var VARIANTS = [
|
|
18462
|
+
{ value: "logos", label: "Logos" },
|
|
18463
|
+
{ value: "reel", label: "Reel" }
|
|
18464
|
+
];
|
|
18465
|
+
var ALIGNS = [
|
|
18466
|
+
{ value: "left", label: "Left" },
|
|
18467
|
+
{ value: "center", label: "Center" },
|
|
18468
|
+
{ value: "right", label: "Right" }
|
|
18469
|
+
];
|
|
18470
|
+
var HOVERS = [
|
|
18471
|
+
{ value: "none", label: "None" },
|
|
18472
|
+
{ value: "lift", label: "Lift" },
|
|
18473
|
+
{ value: "zoom", label: "Zoom" },
|
|
18474
|
+
{ value: "fade", label: "Fade" }
|
|
18475
|
+
];
|
|
18476
|
+
var TREATMENTS = [
|
|
18477
|
+
{ value: "color", label: "Color" },
|
|
18478
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
18479
|
+
];
|
|
18480
|
+
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18481
|
+
function LinkInput({ value, onCommit }) {
|
|
18482
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
18645
18483
|
const [invalid, setInvalid] = (0, import_react10.useState)(false);
|
|
18646
|
-
|
|
18484
|
+
(0, import_react10.useEffect)(() => {
|
|
18485
|
+
setDraft(value);
|
|
18486
|
+
setInvalid(false);
|
|
18487
|
+
}, [value]);
|
|
18488
|
+
const commit = () => {
|
|
18647
18489
|
const next = draft.trim();
|
|
18648
|
-
if (next
|
|
18649
|
-
|
|
18650
|
-
|
|
18651
|
-
|
|
18652
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
18653
|
-
onClose();
|
|
18490
|
+
if (next === value) return setInvalid(false);
|
|
18491
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
18492
|
+
setInvalid(false);
|
|
18493
|
+
onCommit(next);
|
|
18654
18494
|
};
|
|
18655
|
-
return /* @__PURE__ */ (0,
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
"
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
"
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
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
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
|
|
18717
|
-
|
|
18718
|
-
|
|
18719
|
-
|
|
18495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18496
|
+
"div",
|
|
18497
|
+
{
|
|
18498
|
+
style: {
|
|
18499
|
+
display: "flex",
|
|
18500
|
+
alignItems: "center",
|
|
18501
|
+
gap: 6,
|
|
18502
|
+
height: 28,
|
|
18503
|
+
padding: "0 12px",
|
|
18504
|
+
borderRadius: 999,
|
|
18505
|
+
background: "#ffffff",
|
|
18506
|
+
width: "100%",
|
|
18507
|
+
maxWidth: 260,
|
|
18508
|
+
boxSizing: "border-box",
|
|
18509
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18510
|
+
},
|
|
18511
|
+
children: [
|
|
18512
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18513
|
+
"span",
|
|
18514
|
+
{
|
|
18515
|
+
style: {
|
|
18516
|
+
flex: "0 0 auto",
|
|
18517
|
+
color: OHW_BLUE_DARK,
|
|
18518
|
+
fontSize: 10,
|
|
18519
|
+
fontWeight: 700,
|
|
18520
|
+
textTransform: "uppercase",
|
|
18521
|
+
letterSpacing: 0.4
|
|
18522
|
+
},
|
|
18523
|
+
children: "Link"
|
|
18524
|
+
}
|
|
18525
|
+
),
|
|
18526
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18527
|
+
"input",
|
|
18528
|
+
{
|
|
18529
|
+
type: "text",
|
|
18530
|
+
inputMode: "url",
|
|
18531
|
+
value: draft,
|
|
18532
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18533
|
+
onBlur: commit,
|
|
18534
|
+
onKeyDown: (e) => {
|
|
18535
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18536
|
+
if (e.key === "Escape") {
|
|
18537
|
+
setDraft(value);
|
|
18538
|
+
setInvalid(false);
|
|
18539
|
+
e.currentTarget.blur();
|
|
18540
|
+
}
|
|
18541
|
+
},
|
|
18542
|
+
placeholder: "https://example.com",
|
|
18543
|
+
"aria-label": "Image link URL",
|
|
18544
|
+
"aria-invalid": invalid,
|
|
18545
|
+
style: {
|
|
18546
|
+
flex: 1,
|
|
18547
|
+
minWidth: 0,
|
|
18548
|
+
border: "none",
|
|
18549
|
+
outline: "none",
|
|
18550
|
+
background: "transparent",
|
|
18551
|
+
fontSize: 12,
|
|
18552
|
+
lineHeight: "16px",
|
|
18553
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18554
|
+
color: "#1f2937"
|
|
18555
|
+
}
|
|
18556
|
+
}
|
|
18557
|
+
)
|
|
18558
|
+
]
|
|
18559
|
+
}
|
|
18560
|
+
);
|
|
18720
18561
|
}
|
|
18721
18562
|
function MediaStripToolbar({
|
|
18722
18563
|
entry,
|
|
18723
18564
|
index,
|
|
18724
18565
|
pending,
|
|
18725
18566
|
error,
|
|
18726
|
-
itemEditOn,
|
|
18727
|
-
onToggleItemEdit,
|
|
18728
18567
|
onSetVariant,
|
|
18729
18568
|
onSetAlign,
|
|
18730
18569
|
onSetHover,
|
|
18731
18570
|
onSetTreatment,
|
|
18732
18571
|
onResize,
|
|
18733
|
-
|
|
18572
|
+
onSetAlt,
|
|
18573
|
+
onSetLink,
|
|
18734
18574
|
onAddItem,
|
|
18735
18575
|
onRemoveItem,
|
|
18736
18576
|
onChangeImage,
|
|
@@ -18739,102 +18579,81 @@ function MediaStripToolbar({
|
|
|
18739
18579
|
}) {
|
|
18740
18580
|
const items = mediaStripItems(entry.tree);
|
|
18741
18581
|
const itemCount = items.length;
|
|
18582
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
18583
|
+
const currentHref = items[index]?.href ?? "";
|
|
18584
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18742
18585
|
const slots = findMediaStripSlots(entry.tree);
|
|
18743
18586
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18744
18587
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
18745
18588
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
18746
18589
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
18747
18590
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18748
|
-
const
|
|
18749
|
-
const
|
|
18750
|
-
|
|
18591
|
+
const isMobile = window.innerWidth <= 480;
|
|
18592
|
+
const rowStyle = isMobile ? {
|
|
18593
|
+
display: "flex",
|
|
18594
|
+
gap: 6,
|
|
18595
|
+
flexWrap: "nowrap",
|
|
18596
|
+
justifyContent: "center",
|
|
18597
|
+
overflowX: "auto",
|
|
18598
|
+
WebkitOverflowScrolling: "touch",
|
|
18599
|
+
width: "100%",
|
|
18600
|
+
scrollbarWidth: "none"
|
|
18601
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
18602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18751
18603
|
"div",
|
|
18752
18604
|
{
|
|
18753
18605
|
"data-ohw-bridge": "",
|
|
18754
18606
|
"data-ohw-toolbar": "",
|
|
18755
18607
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18756
|
-
|
|
18757
|
-
|
|
18608
|
+
style: {
|
|
18609
|
+
display: "flex",
|
|
18610
|
+
flexDirection: "column",
|
|
18611
|
+
gap: 6,
|
|
18612
|
+
alignItems: "center",
|
|
18613
|
+
background: OHW_BLUE,
|
|
18614
|
+
padding: 8,
|
|
18615
|
+
borderRadius: 12,
|
|
18616
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18617
|
+
pointerEvents: pending ? "none" : "auto",
|
|
18618
|
+
opacity: pending ? 0.6 : 1,
|
|
18619
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
18620
|
+
},
|
|
18758
18621
|
children: [
|
|
18759
|
-
/* @__PURE__ */ (0,
|
|
18760
|
-
|
|
18761
|
-
{
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
) }),
|
|
18792
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
18793
|
-
] }),
|
|
18794
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18795
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Image, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18796
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Link, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18797
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ArrowLeft, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18798
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18799
|
-
ToolbarAction,
|
|
18800
|
-
{
|
|
18801
|
-
label: gatedLabel("Move right"),
|
|
18802
|
-
onClick: onMoveRight,
|
|
18803
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
18804
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ArrowRight, { size: 16, style: { pointerEvents: "none" } })
|
|
18805
|
-
}
|
|
18806
|
-
),
|
|
18807
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18808
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18809
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
18810
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
18811
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18812
|
-
ToolbarAction,
|
|
18813
|
-
{
|
|
18814
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
18815
|
-
active: treatment === "grayscale",
|
|
18816
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
18817
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
18818
|
-
}
|
|
18819
|
-
),
|
|
18820
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18821
|
-
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
18822
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18823
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18824
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
18825
|
-
sizeValue,
|
|
18826
|
-
"px"
|
|
18827
|
-
] }),
|
|
18828
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18829
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18830
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18831
|
-
]
|
|
18832
|
-
}
|
|
18833
|
-
),
|
|
18834
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18622
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: rowStyle, children: [
|
|
18623
|
+
VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
18624
|
+
ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
18625
|
+
] }),
|
|
18626
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: rowStyle, children: [
|
|
18627
|
+
HOVERS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
18628
|
+
TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
18629
|
+
] }),
|
|
18630
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
18631
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
18632
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
18633
|
+
sizeValue,
|
|
18634
|
+
"px"
|
|
18635
|
+
] }),
|
|
18636
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "+", onClick: () => onResize(8) })
|
|
18637
|
+
] }),
|
|
18638
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
18639
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LinkInput, { value: currentHref, onCommit: (href) => onSetLink(href, currentTarget) }) }),
|
|
18640
|
+
currentHref && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: rowStyle, children: [
|
|
18641
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
18642
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
18643
|
+
] }),
|
|
18644
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: rowStyle, children: [
|
|
18645
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
18646
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
18647
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
18648
|
+
] }),
|
|
18649
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: rowStyle, children: [
|
|
18650
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
18651
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
18652
|
+
] }),
|
|
18653
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
18835
18654
|
]
|
|
18836
18655
|
}
|
|
18837
|
-
)
|
|
18656
|
+
);
|
|
18838
18657
|
}
|
|
18839
18658
|
function findMediaStripSlots(tree) {
|
|
18840
18659
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -18853,23 +18672,31 @@ function AiMediaStripOverlay({
|
|
|
18853
18672
|
}) {
|
|
18854
18673
|
const [hover, setHover] = (0, import_react10.useState)(null);
|
|
18855
18674
|
const [active, setActive] = (0, import_react10.useState)(null);
|
|
18856
|
-
const [itemEditOn, setItemEditOn] = (0, import_react10.useState)(false);
|
|
18857
|
-
const [linkOpen, setLinkOpen] = (0, import_react10.useState)(false);
|
|
18858
18675
|
const [pending, setPending] = (0, import_react10.useState)(false);
|
|
18859
18676
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
18860
18677
|
const activeRef = (0, import_react10.useRef)(null);
|
|
18861
18678
|
activeRef.current = active;
|
|
18862
|
-
const linkOpenRef = (0, import_react10.useRef)(false);
|
|
18863
|
-
linkOpenRef.current = linkOpen;
|
|
18864
18679
|
(0, import_react10.useEffect)(() => {
|
|
18865
18680
|
const onMove = (e) => {
|
|
18866
|
-
const ref = itemRefFromTarget(e.target);
|
|
18867
18681
|
const t = e.target;
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
|
|
18872
|
-
|
|
18682
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18683
|
+
if (t.closest("[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-link-modal-root], [data-ohw-section-picker], [data-ohw-ai-review]")) {
|
|
18684
|
+
return;
|
|
18685
|
+
}
|
|
18686
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
18687
|
+
if (!itemEl) {
|
|
18688
|
+
setHover(null);
|
|
18689
|
+
return;
|
|
18690
|
+
}
|
|
18691
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18692
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18693
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18694
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18695
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
18696
|
+
setHover(null);
|
|
18697
|
+
return;
|
|
18698
|
+
}
|
|
18699
|
+
setHover({ sectionId, index });
|
|
18873
18700
|
};
|
|
18874
18701
|
const onLeave = () => setHover(null);
|
|
18875
18702
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -18881,25 +18708,23 @@ function AiMediaStripOverlay({
|
|
|
18881
18708
|
}, []);
|
|
18882
18709
|
(0, import_react10.useEffect)(() => {
|
|
18883
18710
|
const onClick = (e) => {
|
|
18711
|
+
const current = activeRef.current;
|
|
18712
|
+
if (!current) return;
|
|
18884
18713
|
const t = e.target;
|
|
18885
|
-
if (!(t instanceof
|
|
18886
|
-
if (t.closest(
|
|
18887
|
-
const
|
|
18888
|
-
if (
|
|
18889
|
-
|
|
18890
|
-
setItemEditOn(false);
|
|
18714
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18715
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
18716
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
18717
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
18718
|
+
setActive(null);
|
|
18891
18719
|
setError(null);
|
|
18892
|
-
setActive(ref);
|
|
18893
18720
|
};
|
|
18894
18721
|
document.addEventListener("click", onClick, true);
|
|
18895
18722
|
return () => document.removeEventListener("click", onClick, true);
|
|
18896
|
-
}, [
|
|
18723
|
+
}, []);
|
|
18897
18724
|
(0, import_react10.useEffect)(() => {
|
|
18898
18725
|
const onBlur = () => {
|
|
18899
18726
|
if (!activeRef.current) return;
|
|
18900
18727
|
setActive(null);
|
|
18901
|
-
setItemEditOn(false);
|
|
18902
|
-
setLinkOpen(false);
|
|
18903
18728
|
setError(null);
|
|
18904
18729
|
};
|
|
18905
18730
|
window.addEventListener("blur", onBlur);
|
|
@@ -18909,10 +18734,7 @@ function AiMediaStripOverlay({
|
|
|
18909
18734
|
const onKeyDown = (e) => {
|
|
18910
18735
|
if (e.key !== "Escape") return;
|
|
18911
18736
|
if (!activeRef.current) return;
|
|
18912
|
-
if (linkOpenRef.current) return;
|
|
18913
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
18914
18737
|
setActive(null);
|
|
18915
|
-
setItemEditOn(false);
|
|
18916
18738
|
setError(null);
|
|
18917
18739
|
};
|
|
18918
18740
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -18946,133 +18768,137 @@ function AiMediaStripOverlay({
|
|
|
18946
18768
|
tree: nextTree,
|
|
18947
18769
|
label: entry.label,
|
|
18948
18770
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
18949
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
18950
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
18951
|
-
// on every edit reads as the section jumping around.
|
|
18952
|
-
skipScrollIntoView: true
|
|
18771
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
18953
18772
|
});
|
|
18954
18773
|
return true;
|
|
18955
18774
|
},
|
|
18956
18775
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
18957
18776
|
);
|
|
18958
18777
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18778
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
18959
18779
|
const activeItemRect = useLiveItemRect(active);
|
|
18960
|
-
const
|
|
18961
|
-
const
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
18991
|
-
|
|
18992
|
-
|
|
18993
|
-
|
|
18780
|
+
const TOOLBAR_APPROX_H = 170;
|
|
18781
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
18782
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
18783
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18784
|
+
"button",
|
|
18785
|
+
{
|
|
18786
|
+
type: "button",
|
|
18787
|
+
"data-ohw-toolbar": "",
|
|
18788
|
+
onClick: () => {
|
|
18789
|
+
clearInteractionChromeRef.current();
|
|
18790
|
+
setActive(hover);
|
|
18791
|
+
},
|
|
18792
|
+
"aria-label": "Configure media item",
|
|
18793
|
+
style: {
|
|
18794
|
+
position: "fixed",
|
|
18795
|
+
top: hoverHandleRect.top + 8,
|
|
18796
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
18797
|
+
width: 28,
|
|
18798
|
+
height: 28,
|
|
18799
|
+
borderRadius: 8,
|
|
18800
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
18801
|
+
background: "#ffffff",
|
|
18802
|
+
color: PRIMARY3,
|
|
18803
|
+
display: "flex",
|
|
18804
|
+
alignItems: "center",
|
|
18805
|
+
justifyContent: "center",
|
|
18806
|
+
cursor: "pointer",
|
|
18807
|
+
zIndex: 2147483643,
|
|
18808
|
+
fontSize: 14,
|
|
18809
|
+
fontWeight: 700
|
|
18810
|
+
},
|
|
18811
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
18812
|
+
}
|
|
18813
|
+
),
|
|
18814
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18815
|
+
ItemInteractionLayer,
|
|
18816
|
+
{
|
|
18817
|
+
rect: activeItemRect,
|
|
18818
|
+
state: toolbarState,
|
|
18819
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18820
|
+
MediaStripToolbar,
|
|
18821
|
+
{
|
|
18822
|
+
entry: activeEntry,
|
|
18823
|
+
index: active.index,
|
|
18824
|
+
pending,
|
|
18825
|
+
error,
|
|
18826
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18827
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18828
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18829
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18830
|
+
onResize: (delta) => {
|
|
18831
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18832
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18833
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18834
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18835
|
+
},
|
|
18836
|
+
onSetAlt: (alt) => {
|
|
18837
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
18838
|
+
},
|
|
18839
|
+
onSetLink: (href, linkTarget) => {
|
|
18994
18840
|
void runMutation(
|
|
18995
18841
|
active.sectionId,
|
|
18996
|
-
(tree) =>
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
18842
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
18843
|
+
);
|
|
18844
|
+
},
|
|
18845
|
+
onAddItem: () => {
|
|
18846
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18847
|
+
if (!picked) return;
|
|
18848
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18849
|
+
void runMutation(
|
|
18850
|
+
active.sectionId,
|
|
18851
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18852
|
+
{ [picked.assetId]: picked.url }
|
|
18853
|
+
).then((applied) => {
|
|
18854
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18855
|
+
});
|
|
19000
18856
|
});
|
|
19001
|
-
}
|
|
19002
|
-
|
|
19003
|
-
|
|
19004
|
-
|
|
19005
|
-
|
|
19006
|
-
|
|
19007
|
-
|
|
19008
|
-
|
|
19009
|
-
|
|
18857
|
+
},
|
|
18858
|
+
onChangeImage: () => {
|
|
18859
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18860
|
+
if (!picked) return;
|
|
18861
|
+
void runMutation(
|
|
18862
|
+
active.sectionId,
|
|
18863
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
18864
|
+
{ [picked.assetId]: picked.url }
|
|
18865
|
+
);
|
|
18866
|
+
});
|
|
18867
|
+
},
|
|
18868
|
+
onRemoveItem: () => {
|
|
18869
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
18870
|
+
(applied) => {
|
|
18871
|
+
if (applied) setActive(null);
|
|
18872
|
+
}
|
|
19010
18873
|
);
|
|
19011
|
-
}
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
|
|
19018
|
-
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
|
|
19022
|
-
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
},
|
|
19027
|
-
onMoveRight: () => {
|
|
19028
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19029
|
-
(applied) => {
|
|
19030
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19031
|
-
}
|
|
19032
|
-
);
|
|
19033
|
-
}
|
|
19034
|
-
}
|
|
19035
|
-
) }),
|
|
19036
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19037
|
-
"div",
|
|
19038
|
-
{
|
|
19039
|
-
"data-ohw-bridge": "",
|
|
19040
|
-
"data-ohw-item-interaction": "",
|
|
19041
|
-
"aria-hidden": true,
|
|
19042
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
19043
|
-
style: {
|
|
19044
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
19045
|
-
left: activeItemRect.left - 5,
|
|
19046
|
-
background: PRIMARY3,
|
|
19047
|
-
zIndex: 2147483644
|
|
19048
|
-
},
|
|
19049
|
-
children: "Media item"
|
|
19050
|
-
}
|
|
19051
|
-
),
|
|
19052
|
-
linkOpen && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19053
|
-
LinkModal,
|
|
19054
|
-
{
|
|
19055
|
-
href: activeHref,
|
|
19056
|
-
linkTarget: activeTarget,
|
|
19057
|
-
onClose: () => setLinkOpen(false),
|
|
19058
|
-
onSave: (href, linkTarget) => {
|
|
19059
|
-
void runMutation(
|
|
19060
|
-
active.sectionId,
|
|
19061
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19062
|
-
);
|
|
18874
|
+
},
|
|
18875
|
+
onMoveLeft: () => {
|
|
18876
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18877
|
+
(applied) => {
|
|
18878
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18879
|
+
}
|
|
18880
|
+
);
|
|
18881
|
+
},
|
|
18882
|
+
onMoveRight: () => {
|
|
18883
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18884
|
+
(applied) => {
|
|
18885
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18886
|
+
}
|
|
18887
|
+
);
|
|
18888
|
+
}
|
|
19063
18889
|
}
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
18890
|
+
)
|
|
18891
|
+
}
|
|
18892
|
+
)
|
|
19067
18893
|
] });
|
|
19068
18894
|
}
|
|
19069
18895
|
|
|
19070
18896
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
19071
18897
|
var import_react11 = require("react");
|
|
19072
|
-
var
|
|
19073
|
-
var
|
|
18898
|
+
var import_lucide_react9 = require("lucide-react");
|
|
18899
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
19074
18900
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
19075
|
-
var
|
|
18901
|
+
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]";
|
|
19076
18902
|
function findPricingCardElement(sectionId, index) {
|
|
19077
18903
|
const sectionEl = findByInstanceId(sectionId);
|
|
19078
18904
|
if (!sectionEl) return null;
|
|
@@ -19084,7 +18910,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19084
18910
|
}
|
|
19085
18911
|
function cardRefFromTarget(target) {
|
|
19086
18912
|
if (!(target instanceof Element)) return null;
|
|
19087
|
-
if (target.closest(
|
|
18913
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19088
18914
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19089
18915
|
if (!cardEl) return null;
|
|
19090
18916
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19094,21 +18920,21 @@ function cardRefFromTarget(target) {
|
|
|
19094
18920
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19095
18921
|
return { sectionId, index };
|
|
19096
18922
|
}
|
|
19097
|
-
function
|
|
18923
|
+
function sameRef(a, b) {
|
|
19098
18924
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19099
18925
|
}
|
|
19100
|
-
function
|
|
18926
|
+
function rectOf(el) {
|
|
19101
18927
|
if (!el) return null;
|
|
19102
18928
|
const r2 = el.getBoundingClientRect();
|
|
19103
18929
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19104
18930
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19105
18931
|
}
|
|
19106
18932
|
function readRect3(ref) {
|
|
19107
|
-
return
|
|
18933
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19108
18934
|
}
|
|
19109
18935
|
function readGridRect(ref) {
|
|
19110
18936
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19111
|
-
return
|
|
18937
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19112
18938
|
}
|
|
19113
18939
|
function useLiveCardRect(ref, grid = false) {
|
|
19114
18940
|
const [rect, setRect] = (0, import_react11.useState)(null);
|
|
@@ -19138,7 +18964,7 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19138
18964
|
}
|
|
19139
18965
|
var TOOLBAR_GRID_GAP = 52;
|
|
19140
18966
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19141
|
-
var
|
|
18967
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19142
18968
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19143
18969
|
const slotRef = (0, import_react11.useRef)(null);
|
|
19144
18970
|
const [shift, setShift] = (0, import_react11.useState)(0);
|
|
@@ -19150,7 +18976,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19150
18976
|
const w = slot.offsetWidth;
|
|
19151
18977
|
if (w <= 0) return;
|
|
19152
18978
|
const half = w / 2;
|
|
19153
|
-
const clamped = Math.max(
|
|
18979
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19154
18980
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19155
18981
|
};
|
|
19156
18982
|
clamp();
|
|
@@ -19159,7 +18985,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19159
18985
|
return () => ro.disconnect();
|
|
19160
18986
|
}, [centerX, children]);
|
|
19161
18987
|
const mobile = window.innerWidth <= 480;
|
|
19162
|
-
return /* @__PURE__ */ (0,
|
|
18988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19163
18989
|
"div",
|
|
19164
18990
|
{
|
|
19165
18991
|
ref: slotRef,
|
|
@@ -19194,7 +19020,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
19194
19020
|
});
|
|
19195
19021
|
}
|
|
19196
19022
|
function StyleSwatch({ style }) {
|
|
19197
|
-
return /* @__PURE__ */ (0,
|
|
19023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19198
19024
|
"span",
|
|
19199
19025
|
{
|
|
19200
19026
|
"aria-hidden": true,
|
|
@@ -19208,35 +19034,35 @@ function StyleSwatch({ style }) {
|
|
|
19208
19034
|
);
|
|
19209
19035
|
}
|
|
19210
19036
|
function ButtonGlyph() {
|
|
19211
|
-
return /* @__PURE__ */ (0,
|
|
19212
|
-
/* @__PURE__ */ (0,
|
|
19213
|
-
/* @__PURE__ */ (0,
|
|
19037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19038
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19039
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19214
19040
|
] });
|
|
19215
19041
|
}
|
|
19216
19042
|
function FeatureGlyph({ mode }) {
|
|
19217
|
-
return /* @__PURE__ */ (0,
|
|
19218
|
-
/* @__PURE__ */ (0,
|
|
19219
|
-
/* @__PURE__ */ (0,
|
|
19220
|
-
/* @__PURE__ */ (0,
|
|
19221
|
-
/* @__PURE__ */ (0,
|
|
19222
|
-
/* @__PURE__ */ (0,
|
|
19223
|
-
mode === "add" && /* @__PURE__ */ (0,
|
|
19043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19044
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19045
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19046
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19047
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19048
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19049
|
+
mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19224
19050
|
] });
|
|
19225
19051
|
}
|
|
19226
|
-
function
|
|
19052
|
+
function ToolbarAction({
|
|
19227
19053
|
label,
|
|
19228
19054
|
onClick,
|
|
19229
19055
|
disabled = false,
|
|
19230
19056
|
children
|
|
19231
19057
|
}) {
|
|
19232
|
-
const button = /* @__PURE__ */ (0,
|
|
19233
|
-
return /* @__PURE__ */ (0,
|
|
19234
|
-
/* @__PURE__ */ (0,
|
|
19235
|
-
/* @__PURE__ */ (0,
|
|
19058
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
19060
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
19061
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19236
19062
|
] });
|
|
19237
19063
|
}
|
|
19238
|
-
function
|
|
19239
|
-
return /* @__PURE__ */ (0,
|
|
19064
|
+
function ToolbarSeparator() {
|
|
19065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19240
19066
|
}
|
|
19241
19067
|
function CardStyleMenu({
|
|
19242
19068
|
value,
|
|
@@ -19244,7 +19070,7 @@ function CardStyleMenu({
|
|
|
19244
19070
|
disabled = false
|
|
19245
19071
|
}) {
|
|
19246
19072
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
19247
|
-
const trigger = /* @__PURE__ */ (0,
|
|
19073
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19248
19074
|
"button",
|
|
19249
19075
|
{
|
|
19250
19076
|
type: "button",
|
|
@@ -19255,28 +19081,28 @@ function CardStyleMenu({
|
|
|
19255
19081
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
19256
19082
|
),
|
|
19257
19083
|
children: [
|
|
19258
|
-
/* @__PURE__ */ (0,
|
|
19259
|
-
/* @__PURE__ */ (0,
|
|
19260
|
-
/* @__PURE__ */ (0,
|
|
19084
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
|
|
19085
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
19086
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
19261
19087
|
]
|
|
19262
19088
|
}
|
|
19263
19089
|
);
|
|
19264
19090
|
if (disabled) {
|
|
19265
|
-
return /* @__PURE__ */ (0,
|
|
19266
|
-
/* @__PURE__ */ (0,
|
|
19267
|
-
/* @__PURE__ */ (0,
|
|
19268
|
-
/* @__PURE__ */ (0,
|
|
19269
|
-
/* @__PURE__ */ (0,
|
|
19091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19092
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19093
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
19094
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
19095
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
19270
19096
|
] })
|
|
19271
19097
|
] });
|
|
19272
19098
|
}
|
|
19273
|
-
return /* @__PURE__ */ (0,
|
|
19274
|
-
/* @__PURE__ */ (0,
|
|
19275
|
-
/* @__PURE__ */ (0,
|
|
19276
|
-
/* @__PURE__ */ (0,
|
|
19277
|
-
/* @__PURE__ */ (0,
|
|
19099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19100
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19101
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
|
|
19102
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19103
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
19278
19104
|
const selected = style.value === value;
|
|
19279
|
-
return /* @__PURE__ */ (0,
|
|
19105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19280
19106
|
DropdownMenuItem,
|
|
19281
19107
|
{
|
|
19282
19108
|
role: "menuitemradio",
|
|
@@ -19284,9 +19110,9 @@ function CardStyleMenu({
|
|
|
19284
19110
|
onSelect: () => onChange(style.value),
|
|
19285
19111
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19286
19112
|
children: [
|
|
19287
|
-
/* @__PURE__ */ (0,
|
|
19288
|
-
/* @__PURE__ */ (0,
|
|
19289
|
-
selected && /* @__PURE__ */ (0,
|
|
19113
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: style.value }),
|
|
19114
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: style.label }),
|
|
19115
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
|
|
19290
19116
|
]
|
|
19291
19117
|
},
|
|
19292
19118
|
style.value
|
|
@@ -19316,7 +19142,7 @@ function PricingCardToolbar({
|
|
|
19316
19142
|
const style = pricingCardStyle(entry.tree, index);
|
|
19317
19143
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19318
19144
|
const mobile = window.innerWidth <= 480;
|
|
19319
|
-
return /* @__PURE__ */ (0,
|
|
19145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19320
19146
|
"div",
|
|
19321
19147
|
{
|
|
19322
19148
|
"data-ohw-bridge": "",
|
|
@@ -19328,7 +19154,7 @@ function PricingCardToolbar({
|
|
|
19328
19154
|
),
|
|
19329
19155
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19330
19156
|
children: [
|
|
19331
|
-
/* @__PURE__ */ (0,
|
|
19157
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19332
19158
|
"div",
|
|
19333
19159
|
{
|
|
19334
19160
|
className: cn(
|
|
@@ -19337,8 +19163,8 @@ function PricingCardToolbar({
|
|
|
19337
19163
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19338
19164
|
),
|
|
19339
19165
|
children: [
|
|
19340
|
-
/* @__PURE__ */ (0,
|
|
19341
|
-
/* @__PURE__ */ (0,
|
|
19166
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
19167
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19342
19168
|
CustomToolbarButton,
|
|
19343
19169
|
{
|
|
19344
19170
|
type: "button",
|
|
@@ -19346,8 +19172,8 @@ function PricingCardToolbar({
|
|
|
19346
19172
|
"aria-pressed": featuredTag,
|
|
19347
19173
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19348
19174
|
className: "group size-8",
|
|
19349
|
-
children: /* @__PURE__ */ (0,
|
|
19350
|
-
|
|
19175
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19176
|
+
import_lucide_react9.Star,
|
|
19351
19177
|
{
|
|
19352
19178
|
size: 16,
|
|
19353
19179
|
fill: "currentColor",
|
|
@@ -19361,25 +19187,25 @@ function PricingCardToolbar({
|
|
|
19361
19187
|
)
|
|
19362
19188
|
}
|
|
19363
19189
|
) }),
|
|
19364
|
-
/* @__PURE__ */ (0,
|
|
19190
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19365
19191
|
] }),
|
|
19366
|
-
/* @__PURE__ */ (0,
|
|
19367
|
-
/* @__PURE__ */ (0,
|
|
19368
|
-
/* @__PURE__ */ (0,
|
|
19369
|
-
/* @__PURE__ */ (0,
|
|
19370
|
-
/* @__PURE__ */ (0,
|
|
19371
|
-
/* @__PURE__ */ (0,
|
|
19372
|
-
/* @__PURE__ */ (0,
|
|
19192
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
19193
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19194
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
19195
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}) }),
|
|
19196
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "relative inline-flex", children: [
|
|
19197
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}),
|
|
19198
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
19373
19199
|
] }) }),
|
|
19374
|
-
/* @__PURE__ */ (0,
|
|
19375
|
-
/* @__PURE__ */ (0,
|
|
19376
|
-
/* @__PURE__ */ (0,
|
|
19377
|
-
/* @__PURE__ */ (0,
|
|
19378
|
-
/* @__PURE__ */ (0,
|
|
19200
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FeatureGlyph, { mode: "add" }) }),
|
|
19201
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FeatureGlyph, { mode: "remove" }) }),
|
|
19202
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
19203
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19204
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19379
19205
|
]
|
|
19380
19206
|
}
|
|
19381
19207
|
),
|
|
19382
|
-
error && /* @__PURE__ */ (0,
|
|
19208
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19383
19209
|
]
|
|
19384
19210
|
}
|
|
19385
19211
|
) });
|
|
@@ -19413,7 +19239,7 @@ function AiPricingCardOverlay({
|
|
|
19413
19239
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19414
19240
|
setHover((prev) => {
|
|
19415
19241
|
const next = ref && !overEditable ? ref : null;
|
|
19416
|
-
return
|
|
19242
|
+
return sameRef(prev, next) ? prev : next;
|
|
19417
19243
|
});
|
|
19418
19244
|
};
|
|
19419
19245
|
const onLeave = () => setHover(null);
|
|
@@ -19428,10 +19254,10 @@ function AiPricingCardOverlay({
|
|
|
19428
19254
|
const onClick = (e) => {
|
|
19429
19255
|
const t = e.target;
|
|
19430
19256
|
if (!(t instanceof Element)) return;
|
|
19431
|
-
if (t.closest(
|
|
19257
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
19432
19258
|
const ref = cardRefFromTarget(t);
|
|
19433
|
-
setActive((prev) =>
|
|
19434
|
-
if (!ref || !
|
|
19259
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19260
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
19435
19261
|
};
|
|
19436
19262
|
document.addEventListener("click", onClick, true);
|
|
19437
19263
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19496,12 +19322,12 @@ function AiPricingCardOverlay({
|
|
|
19496
19322
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19497
19323
|
const activeCardRect = useLiveCardRect(active);
|
|
19498
19324
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19499
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19500
|
-
return /* @__PURE__ */ (0,
|
|
19501
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
19502
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19503
|
-
/* @__PURE__ */ (0,
|
|
19504
|
-
/* @__PURE__ */ (0,
|
|
19325
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
19327
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19328
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
19329
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19330
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19505
19331
|
PricingCardToolbar,
|
|
19506
19332
|
{
|
|
19507
19333
|
entry: activeEntry,
|
|
@@ -19529,7 +19355,7 @@ function AiPricingCardOverlay({
|
|
|
19529
19355
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
19530
19356
|
}
|
|
19531
19357
|
) }),
|
|
19532
|
-
/* @__PURE__ */ (0,
|
|
19358
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19533
19359
|
"div",
|
|
19534
19360
|
{
|
|
19535
19361
|
"data-ohw-bridge": "",
|
|
@@ -19551,7 +19377,7 @@ function AiPricingCardOverlay({
|
|
|
19551
19377
|
|
|
19552
19378
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19553
19379
|
var import_react12 = require("react");
|
|
19554
|
-
var
|
|
19380
|
+
var import_lucide_react10 = require("lucide-react");
|
|
19555
19381
|
|
|
19556
19382
|
// src/lib/ai-video-tree.ts
|
|
19557
19383
|
function resolveVideoBlock(tree, path) {
|
|
@@ -19622,10 +19448,10 @@ function extractYouTubeId(input) {
|
|
|
19622
19448
|
}
|
|
19623
19449
|
|
|
19624
19450
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19625
|
-
var
|
|
19451
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
19626
19452
|
var PRIMARY5 = "#0885FE";
|
|
19627
|
-
var
|
|
19628
|
-
var
|
|
19453
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19454
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
19629
19455
|
function findVideoBlockElement(sectionId, path) {
|
|
19630
19456
|
const sectionEl = findByInstanceId(sectionId);
|
|
19631
19457
|
if (!sectionEl) return null;
|
|
@@ -19685,12 +19511,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
19685
19511
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
19686
19512
|
});
|
|
19687
19513
|
}
|
|
19688
|
-
function
|
|
19514
|
+
function Pill2({
|
|
19689
19515
|
label,
|
|
19690
19516
|
onClick,
|
|
19691
19517
|
disabled
|
|
19692
19518
|
}) {
|
|
19693
|
-
return /* @__PURE__ */ (0,
|
|
19519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19694
19520
|
"button",
|
|
19695
19521
|
{
|
|
19696
19522
|
type: "button",
|
|
@@ -19706,7 +19532,7 @@ function Pill({
|
|
|
19706
19532
|
border: "none",
|
|
19707
19533
|
cursor: disabled ? "default" : "pointer",
|
|
19708
19534
|
background: "#ffffff",
|
|
19709
|
-
color:
|
|
19535
|
+
color: OHW_BLUE_DARK2,
|
|
19710
19536
|
opacity: disabled ? 0.4 : 1,
|
|
19711
19537
|
fontSize: 12,
|
|
19712
19538
|
lineHeight: "16px",
|
|
@@ -19749,8 +19575,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19749
19575
|
onCommit(id);
|
|
19750
19576
|
}
|
|
19751
19577
|
};
|
|
19752
|
-
return /* @__PURE__ */ (0,
|
|
19753
|
-
/* @__PURE__ */ (0,
|
|
19578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
19579
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19754
19580
|
"div",
|
|
19755
19581
|
{
|
|
19756
19582
|
style: {
|
|
@@ -19766,12 +19592,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19766
19592
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19767
19593
|
},
|
|
19768
19594
|
children: [
|
|
19769
|
-
/* @__PURE__ */ (0,
|
|
19595
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19770
19596
|
"span",
|
|
19771
19597
|
{
|
|
19772
19598
|
style: {
|
|
19773
19599
|
flex: "0 0 auto",
|
|
19774
|
-
color:
|
|
19600
|
+
color: OHW_BLUE_DARK2,
|
|
19775
19601
|
fontSize: 10,
|
|
19776
19602
|
lineHeight: "16px",
|
|
19777
19603
|
fontWeight: 700,
|
|
@@ -19781,7 +19607,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19781
19607
|
children: "Video"
|
|
19782
19608
|
}
|
|
19783
19609
|
),
|
|
19784
|
-
/* @__PURE__ */ (0,
|
|
19610
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19785
19611
|
"input",
|
|
19786
19612
|
{
|
|
19787
19613
|
type: "text",
|
|
@@ -19818,7 +19644,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19818
19644
|
]
|
|
19819
19645
|
}
|
|
19820
19646
|
),
|
|
19821
|
-
invalid && /* @__PURE__ */ (0,
|
|
19647
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
19822
19648
|
] });
|
|
19823
19649
|
}
|
|
19824
19650
|
function VideoToolbar({
|
|
@@ -19828,7 +19654,7 @@ function VideoToolbar({
|
|
|
19828
19654
|
onSetVideoId,
|
|
19829
19655
|
onRemove
|
|
19830
19656
|
}) {
|
|
19831
|
-
return /* @__PURE__ */ (0,
|
|
19657
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19832
19658
|
"div",
|
|
19833
19659
|
{
|
|
19834
19660
|
"data-ohw-bridge": "",
|
|
@@ -19840,7 +19666,7 @@ function VideoToolbar({
|
|
|
19840
19666
|
gap: 6,
|
|
19841
19667
|
alignItems: "center",
|
|
19842
19668
|
width: 280,
|
|
19843
|
-
background:
|
|
19669
|
+
background: OHW_BLUE2,
|
|
19844
19670
|
padding: 8,
|
|
19845
19671
|
borderRadius: 12,
|
|
19846
19672
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19848,9 +19674,9 @@ function VideoToolbar({
|
|
|
19848
19674
|
opacity: pending ? 0.6 : 1
|
|
19849
19675
|
},
|
|
19850
19676
|
children: [
|
|
19851
|
-
/* @__PURE__ */ (0,
|
|
19852
|
-
/* @__PURE__ */ (0,
|
|
19853
|
-
error && /* @__PURE__ */ (0,
|
|
19677
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19678
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19679
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19854
19680
|
]
|
|
19855
19681
|
}
|
|
19856
19682
|
);
|
|
@@ -19970,8 +19796,8 @@ function AiVideoOverlay({
|
|
|
19970
19796
|
const activeBlockRect = useLiveBlockRect(active);
|
|
19971
19797
|
const TOOLBAR_APPROX_H = 90;
|
|
19972
19798
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19973
|
-
return /* @__PURE__ */ (0,
|
|
19974
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
19799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19800
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19975
19801
|
"button",
|
|
19976
19802
|
{
|
|
19977
19803
|
type: "button",
|
|
@@ -19999,15 +19825,15 @@ function AiVideoOverlay({
|
|
|
19999
19825
|
fontSize: 14,
|
|
20000
19826
|
fontWeight: 700
|
|
20001
19827
|
},
|
|
20002
|
-
children: /* @__PURE__ */ (0,
|
|
19828
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20003
19829
|
}
|
|
20004
19830
|
),
|
|
20005
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19831
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
20006
19832
|
ItemInteractionLayer,
|
|
20007
19833
|
{
|
|
20008
19834
|
rect: activeBlockRect,
|
|
20009
19835
|
state: toolbarState,
|
|
20010
|
-
toolbar: /* @__PURE__ */ (0,
|
|
19836
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
20011
19837
|
VideoToolbar,
|
|
20012
19838
|
{
|
|
20013
19839
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20031,7 +19857,7 @@ function AiVideoOverlay({
|
|
|
20031
19857
|
|
|
20032
19858
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20033
19859
|
var import_react13 = require("react");
|
|
20034
|
-
var
|
|
19860
|
+
var import_lucide_react11 = require("lucide-react");
|
|
20035
19861
|
|
|
20036
19862
|
// src/lib/ai-carousel-tree.ts
|
|
20037
19863
|
function isCarouselBlock(node) {
|
|
@@ -20082,10 +19908,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20082
19908
|
}
|
|
20083
19909
|
|
|
20084
19910
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20085
|
-
var
|
|
19911
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
20086
19912
|
var PRIMARY6 = "#0885FE";
|
|
20087
|
-
var
|
|
20088
|
-
var
|
|
19913
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
19914
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20089
19915
|
function findCarouselItemElement(sectionId, index) {
|
|
20090
19916
|
const sectionEl = findByInstanceId(sectionId);
|
|
20091
19917
|
if (!sectionEl) return null;
|
|
@@ -20164,8 +19990,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20164
19990
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20165
19991
|
});
|
|
20166
19992
|
}
|
|
20167
|
-
function
|
|
20168
|
-
return /* @__PURE__ */ (0,
|
|
19993
|
+
function Pill3({ label, onClick, disabled }) {
|
|
19994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20169
19995
|
"button",
|
|
20170
19996
|
{
|
|
20171
19997
|
type: "button",
|
|
@@ -20181,7 +20007,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20181
20007
|
border: "none",
|
|
20182
20008
|
cursor: disabled ? "default" : "pointer",
|
|
20183
20009
|
background: "#ffffff",
|
|
20184
|
-
color:
|
|
20010
|
+
color: OHW_BLUE_DARK3,
|
|
20185
20011
|
opacity: disabled ? 0.4 : 1,
|
|
20186
20012
|
fontSize: 12,
|
|
20187
20013
|
lineHeight: "16px",
|
|
@@ -20199,7 +20025,7 @@ function TogglePill({
|
|
|
20199
20025
|
onToggle,
|
|
20200
20026
|
disabled
|
|
20201
20027
|
}) {
|
|
20202
|
-
return /* @__PURE__ */ (0,
|
|
20028
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
20203
20029
|
"button",
|
|
20204
20030
|
{
|
|
20205
20031
|
type: "button",
|
|
@@ -20218,7 +20044,7 @@ function TogglePill({
|
|
|
20218
20044
|
border: "none",
|
|
20219
20045
|
cursor: disabled ? "default" : "pointer",
|
|
20220
20046
|
background: "#ffffff",
|
|
20221
|
-
color:
|
|
20047
|
+
color: OHW_BLUE_DARK3,
|
|
20222
20048
|
opacity: disabled ? 0.4 : 1,
|
|
20223
20049
|
fontSize: 12,
|
|
20224
20050
|
lineHeight: "16px",
|
|
@@ -20228,7 +20054,7 @@ function TogglePill({
|
|
|
20228
20054
|
},
|
|
20229
20055
|
children: [
|
|
20230
20056
|
label,
|
|
20231
|
-
/* @__PURE__ */ (0,
|
|
20057
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20232
20058
|
"span",
|
|
20233
20059
|
{
|
|
20234
20060
|
"aria-hidden": true,
|
|
@@ -20241,10 +20067,10 @@ function TogglePill({
|
|
|
20241
20067
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
20242
20068
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
20243
20069
|
// "disabled control" rather than "switch that is off".
|
|
20244
|
-
background: on ?
|
|
20070
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
20245
20071
|
transition: "background 120ms ease"
|
|
20246
20072
|
},
|
|
20247
|
-
children: /* @__PURE__ */ (0,
|
|
20073
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20248
20074
|
"span",
|
|
20249
20075
|
{
|
|
20250
20076
|
style: {
|
|
@@ -20273,7 +20099,7 @@ function CarouselSlideToolbar({
|
|
|
20273
20099
|
onChangeImage,
|
|
20274
20100
|
onToggleAutoplay
|
|
20275
20101
|
}) {
|
|
20276
|
-
return /* @__PURE__ */ (0,
|
|
20102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
20277
20103
|
"div",
|
|
20278
20104
|
{
|
|
20279
20105
|
"data-ohw-bridge": "",
|
|
@@ -20284,7 +20110,7 @@ function CarouselSlideToolbar({
|
|
|
20284
20110
|
flexDirection: "column",
|
|
20285
20111
|
gap: 6,
|
|
20286
20112
|
alignItems: "center",
|
|
20287
|
-
background:
|
|
20113
|
+
background: OHW_BLUE3,
|
|
20288
20114
|
padding: 8,
|
|
20289
20115
|
borderRadius: 12,
|
|
20290
20116
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20296,11 +20122,11 @@ function CarouselSlideToolbar({
|
|
|
20296
20122
|
pointerEvents: pending ? "none" : "auto"
|
|
20297
20123
|
},
|
|
20298
20124
|
children: [
|
|
20299
|
-
/* @__PURE__ */ (0,
|
|
20300
|
-
/* @__PURE__ */ (0,
|
|
20301
|
-
/* @__PURE__ */ (0,
|
|
20125
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20126
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20127
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20302
20128
|
] }),
|
|
20303
|
-
error && /* @__PURE__ */ (0,
|
|
20129
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20304
20130
|
]
|
|
20305
20131
|
}
|
|
20306
20132
|
);
|
|
@@ -20440,8 +20266,8 @@ function AiFadeCarouselOverlay({
|
|
|
20440
20266
|
const activeItemRect = useLiveItemRect2(active);
|
|
20441
20267
|
const TOOLBAR_APPROX_H = 90;
|
|
20442
20268
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20443
|
-
return /* @__PURE__ */ (0,
|
|
20444
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
20270
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20445
20271
|
"button",
|
|
20446
20272
|
{
|
|
20447
20273
|
type: "button",
|
|
@@ -20470,10 +20296,10 @@ function AiFadeCarouselOverlay({
|
|
|
20470
20296
|
fontSize: 14,
|
|
20471
20297
|
fontWeight: 700
|
|
20472
20298
|
},
|
|
20473
|
-
children: /* @__PURE__ */ (0,
|
|
20299
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20474
20300
|
}
|
|
20475
20301
|
),
|
|
20476
|
-
swapping && /* @__PURE__ */ (0,
|
|
20302
|
+
swapping && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20477
20303
|
"div",
|
|
20478
20304
|
{
|
|
20479
20305
|
ref: skeletonRef,
|
|
@@ -20491,15 +20317,15 @@ function AiFadeCarouselOverlay({
|
|
|
20491
20317
|
zIndex: 2147483646,
|
|
20492
20318
|
pointerEvents: "none"
|
|
20493
20319
|
},
|
|
20494
|
-
children: /* @__PURE__ */ (0,
|
|
20320
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
20495
20321
|
}
|
|
20496
20322
|
),
|
|
20497
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20323
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20498
20324
|
ItemInteractionLayer,
|
|
20499
20325
|
{
|
|
20500
20326
|
rect: activeItemRect,
|
|
20501
20327
|
state: toolbarState,
|
|
20502
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20328
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20503
20329
|
CarouselSlideToolbar,
|
|
20504
20330
|
{
|
|
20505
20331
|
pending,
|
|
@@ -20852,6 +20678,113 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
20852
20678
|
// src/ui/link-modal/LinkPopover.tsx
|
|
20853
20679
|
var import_react17 = require("react");
|
|
20854
20680
|
|
|
20681
|
+
// src/ui/dialog.tsx
|
|
20682
|
+
var React9 = __toESM(require("react"), 1);
|
|
20683
|
+
var import_radix_ui6 = require("radix-ui");
|
|
20684
|
+
var import_lucide_react12 = require("lucide-react");
|
|
20685
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
20686
|
+
function Dialog2({
|
|
20687
|
+
...props
|
|
20688
|
+
}) {
|
|
20689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
20690
|
+
}
|
|
20691
|
+
function DialogPortal({
|
|
20692
|
+
...props
|
|
20693
|
+
}) {
|
|
20694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
20695
|
+
}
|
|
20696
|
+
function DialogOverlay({
|
|
20697
|
+
className,
|
|
20698
|
+
...props
|
|
20699
|
+
}) {
|
|
20700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20701
|
+
import_radix_ui6.Dialog.Overlay,
|
|
20702
|
+
{
|
|
20703
|
+
"data-slot": "dialog-overlay",
|
|
20704
|
+
"data-ohw-link-modal-root": "",
|
|
20705
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
20706
|
+
...props
|
|
20707
|
+
}
|
|
20708
|
+
);
|
|
20709
|
+
}
|
|
20710
|
+
var DialogContent = React9.forwardRef(
|
|
20711
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
20712
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
20713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
20714
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
20715
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20716
|
+
import_radix_ui6.Dialog.Content,
|
|
20717
|
+
{
|
|
20718
|
+
ref,
|
|
20719
|
+
"data-slot": "dialog-content",
|
|
20720
|
+
className: cn(
|
|
20721
|
+
positionMode,
|
|
20722
|
+
"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",
|
|
20723
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
20724
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
20725
|
+
className
|
|
20726
|
+
),
|
|
20727
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
20728
|
+
...props,
|
|
20729
|
+
children: [
|
|
20730
|
+
children,
|
|
20731
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20732
|
+
import_radix_ui6.Dialog.Close,
|
|
20733
|
+
{
|
|
20734
|
+
type: "button",
|
|
20735
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
20736
|
+
"aria-label": "Close",
|
|
20737
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
20738
|
+
}
|
|
20739
|
+
) : null
|
|
20740
|
+
]
|
|
20741
|
+
}
|
|
20742
|
+
)
|
|
20743
|
+
] });
|
|
20744
|
+
}
|
|
20745
|
+
);
|
|
20746
|
+
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
20747
|
+
function DialogHeader({
|
|
20748
|
+
className,
|
|
20749
|
+
...props
|
|
20750
|
+
}) {
|
|
20751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
20752
|
+
}
|
|
20753
|
+
function DialogFooter({
|
|
20754
|
+
className,
|
|
20755
|
+
...props
|
|
20756
|
+
}) {
|
|
20757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20758
|
+
"div",
|
|
20759
|
+
{
|
|
20760
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
20761
|
+
...props
|
|
20762
|
+
}
|
|
20763
|
+
);
|
|
20764
|
+
}
|
|
20765
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20766
|
+
import_radix_ui6.Dialog.Title,
|
|
20767
|
+
{
|
|
20768
|
+
ref,
|
|
20769
|
+
className: cn(
|
|
20770
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
20771
|
+
className
|
|
20772
|
+
),
|
|
20773
|
+
...props
|
|
20774
|
+
}
|
|
20775
|
+
));
|
|
20776
|
+
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
20777
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20778
|
+
import_radix_ui6.Dialog.Description,
|
|
20779
|
+
{
|
|
20780
|
+
ref,
|
|
20781
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
20782
|
+
...props
|
|
20783
|
+
}
|
|
20784
|
+
));
|
|
20785
|
+
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
20786
|
+
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
20787
|
+
|
|
20855
20788
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
20856
20789
|
var import_lucide_react16 = require("lucide-react");
|
|
20857
20790
|
|
|
@@ -21955,7 +21888,6 @@ function shouldUseDevFixtures() {
|
|
|
21955
21888
|
function getLogoElement(el) {
|
|
21956
21889
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
21957
21890
|
if (marked) return marked;
|
|
21958
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
21959
21891
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
21960
21892
|
if (!root) return null;
|
|
21961
21893
|
const anchor = el.closest("a");
|
|
@@ -24536,7 +24468,7 @@ function getNavigationSelectionParent(el) {
|
|
|
24536
24468
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
24537
24469
|
return resolveFooterLinksContainerFrom(el);
|
|
24538
24470
|
}
|
|
24539
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24471
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24540
24472
|
return getNavigationRoot(el);
|
|
24541
24473
|
}
|
|
24542
24474
|
return null;
|
|
@@ -24758,6 +24690,7 @@ var ICONS = {
|
|
|
24758
24690
|
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"/>',
|
|
24759
24691
|
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"/>'
|
|
24760
24692
|
};
|
|
24693
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
24761
24694
|
var SELECTION_CHROME_GAP2 = 4;
|
|
24762
24695
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
24763
24696
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24855,7 +24788,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
24855
24788
|
el.style.top = `${top}px`;
|
|
24856
24789
|
el.style.height = `${height}px`;
|
|
24857
24790
|
}
|
|
24858
|
-
var
|
|
24791
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
24859
24792
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
24860
24793
|
const isAbove = transform.includes("translateY(-100%)");
|
|
24861
24794
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -24882,8 +24815,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
24882
24815
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
24883
24816
|
const half = toolbarWidth / 2;
|
|
24884
24817
|
return Math.max(
|
|
24885
|
-
|
|
24886
|
-
Math.min(centerX, window.innerWidth -
|
|
24818
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
24819
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
24887
24820
|
);
|
|
24888
24821
|
}
|
|
24889
24822
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -25773,6 +25706,21 @@ function OhhwellsBridge() {
|
|
|
25773
25706
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
25774
25707
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
25775
25708
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
25709
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
25710
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
25711
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
25712
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
25713
|
+
floatingPanelRef.current = floatingPanel;
|
|
25714
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
25715
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
25716
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
25717
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
25718
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
25719
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
25720
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
25721
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
25722
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
25723
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
25776
25724
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
25777
25725
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
25778
25726
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -25798,21 +25746,6 @@ function OhhwellsBridge() {
|
|
|
25798
25746
|
const stylesRef = (0, import_react21.useRef)("");
|
|
25799
25747
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
25800
25748
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
25801
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
25802
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
25803
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
25804
|
-
floatingPanelRef.current = floatingPanel;
|
|
25805
|
-
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
25806
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
25807
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
25808
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
25809
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
25810
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
25811
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
25812
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
25813
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
25814
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
25815
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
25816
25749
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
25817
25750
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
25818
25751
|
const sectionsPrefetchGenRef = (0, import_react21.useRef)(0);
|
|
@@ -25821,18 +25754,7 @@ function OhhwellsBridge() {
|
|
|
25821
25754
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
25822
25755
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
25823
25756
|
setLinkPopoverRef.current = setLinkPopover;
|
|
25824
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
25825
25757
|
linkPopoverSessionRef.current = linkPopover;
|
|
25826
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
25827
|
-
(0, import_react21.useEffect)(() => {
|
|
25828
|
-
const syncViewport = () => {
|
|
25829
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
25830
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
25831
|
-
};
|
|
25832
|
-
syncViewport();
|
|
25833
|
-
window.addEventListener("resize", syncViewport);
|
|
25834
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
25835
|
-
}, []);
|
|
25836
25758
|
(0, import_react21.useEffect)(() => {
|
|
25837
25759
|
setSectionOrderPersistHandler((entries) => {
|
|
25838
25760
|
const currentPath = window.location.pathname;
|
|
@@ -27527,7 +27449,6 @@ function OhhwellsBridge() {
|
|
|
27527
27449
|
applyAiFooterFromContent(content);
|
|
27528
27450
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27529
27451
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
27530
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27531
27452
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27532
27453
|
}
|
|
27533
27454
|
applyBrandChrome(content);
|
|
@@ -27538,12 +27459,12 @@ function OhhwellsBridge() {
|
|
|
27538
27459
|
if (key === "__ohw_sections") continue;
|
|
27539
27460
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27540
27461
|
if (key === AI_FOOTER_KEY) continue;
|
|
27541
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27542
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27543
27462
|
if (key === BRAND_KIT_KEY) continue;
|
|
27544
27463
|
if (key === STYLE_STORE_KEY) continue;
|
|
27545
27464
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27465
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27546
27466
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27467
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27547
27468
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27548
27469
|
continue;
|
|
27549
27470
|
}
|
|
@@ -27758,18 +27679,17 @@ function OhhwellsBridge() {
|
|
|
27758
27679
|
}
|
|
27759
27680
|
applyAiFooterFromContent(content);
|
|
27760
27681
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27761
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27762
27682
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27763
27683
|
}
|
|
27764
27684
|
for (const [key, val] of Object.entries(content)) {
|
|
27765
27685
|
if (key === "__ohw_sections") continue;
|
|
27766
27686
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27767
27687
|
if (key === AI_FOOTER_KEY) continue;
|
|
27768
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27769
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27770
27688
|
if (key === BRAND_KIT_KEY) continue;
|
|
27771
27689
|
if (key === STYLE_STORE_KEY) continue;
|
|
27772
27690
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27691
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27692
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27773
27693
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27774
27694
|
continue;
|
|
27775
27695
|
}
|
|
@@ -28026,11 +27946,26 @@ function OhhwellsBridge() {
|
|
|
28026
27946
|
const t2 = setTimeout(measure, 500);
|
|
28027
27947
|
const ro = new ResizeObserver(schedule);
|
|
28028
27948
|
ro.observe(document.body);
|
|
27949
|
+
let lastWidth = window.innerWidth;
|
|
27950
|
+
let resizeTimers = [];
|
|
27951
|
+
const clearResizeTimers = () => {
|
|
27952
|
+
resizeTimers.forEach(clearTimeout);
|
|
27953
|
+
resizeTimers = [];
|
|
27954
|
+
};
|
|
27955
|
+
const handleResize = () => {
|
|
27956
|
+
if (window.innerWidth === lastWidth) return;
|
|
27957
|
+
lastWidth = window.innerWidth;
|
|
27958
|
+
clearResizeTimers();
|
|
27959
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
27960
|
+
};
|
|
27961
|
+
window.addEventListener("resize", handleResize);
|
|
28029
27962
|
return () => {
|
|
28030
27963
|
clearTimeout(t1);
|
|
28031
27964
|
clearTimeout(t2);
|
|
28032
27965
|
if (raf != null) cancelAnimationFrame(raf);
|
|
28033
27966
|
ro.disconnect();
|
|
27967
|
+
clearResizeTimers();
|
|
27968
|
+
window.removeEventListener("resize", handleResize);
|
|
28034
27969
|
};
|
|
28035
27970
|
}, [pathname, isEditMode, postToParent2]);
|
|
28036
27971
|
(0, import_react21.useEffect)(() => {
|
|
@@ -28329,13 +28264,6 @@ function OhhwellsBridge() {
|
|
|
28329
28264
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28330
28265
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28331
28266
|
if (isInsideLinkEditor(target)) return;
|
|
28332
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28333
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28334
|
-
if (target.closest(
|
|
28335
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28336
|
-
)) {
|
|
28337
|
-
return;
|
|
28338
|
-
}
|
|
28339
28267
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28340
28268
|
clearMediaSelectionRef.current();
|
|
28341
28269
|
}
|
|
@@ -28359,6 +28287,13 @@ function OhhwellsBridge() {
|
|
|
28359
28287
|
return;
|
|
28360
28288
|
}
|
|
28361
28289
|
}
|
|
28290
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28291
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28292
|
+
if (target.closest(
|
|
28293
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28294
|
+
)) {
|
|
28295
|
+
return;
|
|
28296
|
+
}
|
|
28362
28297
|
{
|
|
28363
28298
|
const formEl = getFormElement(target);
|
|
28364
28299
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -28512,13 +28447,9 @@ function OhhwellsBridge() {
|
|
|
28512
28447
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
28513
28448
|
e.preventDefault();
|
|
28514
28449
|
e.stopPropagation();
|
|
28450
|
+
selectIconElementRef.current(editable);
|
|
28515
28451
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
28516
28452
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
28517
|
-
if (aiIcon) {
|
|
28518
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
28519
|
-
} else {
|
|
28520
|
-
selectIconElementRef.current(editable);
|
|
28521
|
-
}
|
|
28522
28453
|
postToParentRef.current({
|
|
28523
28454
|
type: "ow:icon-pick",
|
|
28524
28455
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -28746,9 +28677,6 @@ function OhhwellsBridge() {
|
|
|
28746
28677
|
setHoveredItemRect(null);
|
|
28747
28678
|
hoveredNavContainerRef.current = null;
|
|
28748
28679
|
setHoveredNavContainerRect(null);
|
|
28749
|
-
siblingHintElRef.current = null;
|
|
28750
|
-
setSiblingHintRect(null);
|
|
28751
|
-
setSiblingHintRects([]);
|
|
28752
28680
|
return;
|
|
28753
28681
|
}
|
|
28754
28682
|
{
|
|
@@ -28869,6 +28797,7 @@ function OhhwellsBridge() {
|
|
|
28869
28797
|
hoveredNavContainerRef.current = null;
|
|
28870
28798
|
setHoveredNavContainerRect(null);
|
|
28871
28799
|
hoveredItemElRef.current = editable;
|
|
28800
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
28872
28801
|
}
|
|
28873
28802
|
}
|
|
28874
28803
|
}
|
|
@@ -29578,11 +29507,7 @@ function OhhwellsBridge() {
|
|
|
29578
29507
|
};
|
|
29579
29508
|
const handleMouseMove = (e) => {
|
|
29580
29509
|
const { clientX, clientY } = e;
|
|
29581
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29582
|
-
dismissImageHover();
|
|
29583
|
-
clearImageHover();
|
|
29584
|
-
return;
|
|
29585
|
-
}
|
|
29510
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29586
29511
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
29587
29512
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
29588
29513
|
formHoverElRef.current = null;
|
|
@@ -29611,12 +29536,7 @@ function OhhwellsBridge() {
|
|
|
29611
29536
|
setHoveredItemRect(null);
|
|
29612
29537
|
hoveredNavContainerRef.current = null;
|
|
29613
29538
|
setHoveredNavContainerRect(null);
|
|
29614
|
-
siblingHintElRef.current = null;
|
|
29615
|
-
setSiblingHintRect(null);
|
|
29616
|
-
setSiblingHintRects([]);
|
|
29617
29539
|
dismissImageHover();
|
|
29618
|
-
clearImageHover();
|
|
29619
|
-
setSectionGap(null);
|
|
29620
29540
|
return;
|
|
29621
29541
|
}
|
|
29622
29542
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -29628,11 +29548,7 @@ function OhhwellsBridge() {
|
|
|
29628
29548
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
29629
29549
|
const { clientX, clientY } = e.data;
|
|
29630
29550
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
29631
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29632
|
-
dismissImageHover();
|
|
29633
|
-
clearImageHover();
|
|
29634
|
-
return;
|
|
29635
|
-
}
|
|
29551
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29636
29552
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
29637
29553
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
29638
29554
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -30012,7 +29928,6 @@ function OhhwellsBridge() {
|
|
|
30012
29928
|
applyAiFooterFromContent(content);
|
|
30013
29929
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
30014
29930
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
30015
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
30016
29931
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
30017
29932
|
}
|
|
30018
29933
|
applyBrandChrome(content);
|
|
@@ -30027,12 +29942,12 @@ function OhhwellsBridge() {
|
|
|
30027
29942
|
}
|
|
30028
29943
|
if (key === AI_SECTIONS_KEY) continue;
|
|
30029
29944
|
if (key === AI_FOOTER_KEY) continue;
|
|
30030
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30031
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30032
29945
|
if (key === BRAND_KIT_KEY) continue;
|
|
30033
29946
|
if (key === STYLE_STORE_KEY) continue;
|
|
30034
29947
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
29948
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30035
29949
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
29950
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30036
29951
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
30037
29952
|
continue;
|
|
30038
29953
|
}
|
|
@@ -30668,12 +30583,6 @@ function OhhwellsBridge() {
|
|
|
30668
30583
|
closeLinkPopoverRef.current();
|
|
30669
30584
|
return;
|
|
30670
30585
|
}
|
|
30671
|
-
if (floatingPanelOpenRef.current) {
|
|
30672
|
-
setFloatingPanelRef.current(null);
|
|
30673
|
-
deselectRef.current();
|
|
30674
|
-
deactivateRef.current();
|
|
30675
|
-
return;
|
|
30676
|
-
}
|
|
30677
30586
|
deselectRef.current();
|
|
30678
30587
|
deactivateRef.current();
|
|
30679
30588
|
clearMediaSelectionRef.current();
|
|
@@ -31496,10 +31405,10 @@ function OhhwellsBridge() {
|
|
|
31496
31405
|
window.removeEventListener("message", handleDeleteSection);
|
|
31497
31406
|
window.removeEventListener("message", handleDuplicateSection);
|
|
31498
31407
|
window.removeEventListener("message", handleDeactivate);
|
|
31408
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31499
31409
|
window.removeEventListener("message", handleToastAction);
|
|
31500
31410
|
window.removeEventListener("message", handleFormCount);
|
|
31501
31411
|
window.removeEventListener("message", handleUiEscape);
|
|
31502
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31503
31412
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
31504
31413
|
autoSaveTimers.current.clear();
|
|
31505
31414
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -31793,7 +31702,7 @@ function OhhwellsBridge() {
|
|
|
31793
31702
|
postToParent2({
|
|
31794
31703
|
type: "ow:ready",
|
|
31795
31704
|
version: "1",
|
|
31796
|
-
bridgeVersion: "0.1.
|
|
31705
|
+
bridgeVersion: "0.1.148",
|
|
31797
31706
|
path: pathname,
|
|
31798
31707
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31799
31708
|
sections
|