@ohhwells/bridge 0.1.151-next.406 → 0.1.152
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
|
@@ -6652,21 +6652,6 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6652
6652
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6653
6653
|
return target ? pricingFeatureList(target).length : 0;
|
|
6654
6654
|
}
|
|
6655
|
-
function prevailingFeatureIcon(features) {
|
|
6656
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6657
|
-
for (const row of features) {
|
|
6658
|
-
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6659
|
-
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6660
|
-
entry.count += 1;
|
|
6661
|
-
counts.set(key, entry);
|
|
6662
|
-
}
|
|
6663
|
-
let best = null;
|
|
6664
|
-
for (const entry of counts.values()) {
|
|
6665
|
-
if (!best || entry.count > best.count) best = entry;
|
|
6666
|
-
}
|
|
6667
|
-
if (!best) return {};
|
|
6668
|
-
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6669
|
-
}
|
|
6670
6655
|
function addPricingCardFeature(tree, index, text) {
|
|
6671
6656
|
return withPricingCollection(tree, (collection) => {
|
|
6672
6657
|
const children = collection.children;
|
|
@@ -6675,7 +6660,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6675
6660
|
const features = pricingFeatureList(target);
|
|
6676
6661
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6677
6662
|
target.slots = target.slots ?? {};
|
|
6678
|
-
target.slots.features = [...features, { text
|
|
6663
|
+
target.slots.features = [...features, { text }];
|
|
6679
6664
|
return true;
|
|
6680
6665
|
});
|
|
6681
6666
|
}
|
|
@@ -7859,7 +7844,7 @@ var AI_MOBILE_CSS = [
|
|
|
7859
7844
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7860
7845
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7861
7846
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7862
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7847
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
7863
7848
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7864
7849
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7865
7850
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7875,10 +7860,8 @@ var AI_MOBILE_CSS = [
|
|
|
7875
7860
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7876
7861
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7877
7862
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7878
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7879
|
-
|
|
7880
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7881
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7863
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7864
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7882
7865
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7883
7866
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7884
7867
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -8083,31 +8066,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
8083
8066
|
function textAttrs(ctx, path) {
|
|
8084
8067
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
8085
8068
|
}
|
|
8086
|
-
var AI_RESPONSIVE_CSS = [
|
|
8087
|
-
"@media (max-width: 960px) {",
|
|
8088
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
8089
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
8090
|
-
"}",
|
|
8091
|
-
"@media (max-width: 640px) {",
|
|
8092
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
8093
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
8094
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
8095
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
8096
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
8097
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
8098
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
8099
|
-
// layered text used to be.
|
|
8100
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
8101
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
8102
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
8103
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
8104
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
8105
|
-
// other rule had already been taught to stand down.
|
|
8106
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
8107
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
8108
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
8109
|
-
"}"
|
|
8110
|
-
].join("\n");
|
|
8111
8069
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8112
8070
|
function MediaBox({
|
|
8113
8071
|
refValue,
|
|
@@ -8162,7 +8120,7 @@ function MediaBox({
|
|
|
8162
8120
|
position: fill ? "absolute" : void 0,
|
|
8163
8121
|
inset: fill ? 0 : void 0,
|
|
8164
8122
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8165
|
-
height: fill ? "100%" :
|
|
8123
|
+
height: fill ? "100%" : void 0,
|
|
8166
8124
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8167
8125
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8168
8126
|
borderRadius: radius,
|
|
@@ -9658,7 +9616,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9658
9616
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9659
9617
|
"div",
|
|
9660
9618
|
{
|
|
9661
|
-
"data-ai-grid":
|
|
9619
|
+
"data-ai-grid": "",
|
|
9662
9620
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9663
9621
|
style: {
|
|
9664
9622
|
display: "grid",
|
|
@@ -9960,7 +9918,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9960
9918
|
},
|
|
9961
9919
|
children: [
|
|
9962
9920
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
9963
|
-
// The section's `data-ai-
|
|
9921
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
9964
9922
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9965
9923
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9966
9924
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10379,7 +10337,6 @@ function AiTreeRenderer({
|
|
|
10379
10337
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10380
10338
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10381
10339
|
...bgAttrs,
|
|
10382
|
-
"data-ai-responsive": "",
|
|
10383
10340
|
style: {
|
|
10384
10341
|
position: "relative",
|
|
10385
10342
|
padding: `${padCss} 0`,
|
|
@@ -10393,13 +10350,12 @@ function AiTreeRenderer({
|
|
|
10393
10350
|
...fillHeight ? { display: "grid" } : {}
|
|
10394
10351
|
},
|
|
10395
10352
|
children: [
|
|
10396
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
10397
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10398
10353
|
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10354
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10399
10355
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10400
10356
|
"div",
|
|
10401
10357
|
{
|
|
10402
|
-
"data-ai-
|
|
10358
|
+
"data-ai-container": "",
|
|
10403
10359
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10404
10360
|
style: {
|
|
10405
10361
|
position: "relative",
|
|
@@ -10416,7 +10372,7 @@ function AiTreeRenderer({
|
|
|
10416
10372
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10417
10373
|
"div",
|
|
10418
10374
|
{
|
|
10419
|
-
"data-ai-
|
|
10375
|
+
"data-ai-row": "",
|
|
10420
10376
|
style: {
|
|
10421
10377
|
display: "grid",
|
|
10422
10378
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -11078,10 +11034,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
11078
11034
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
11079
11035
|
continue;
|
|
11080
11036
|
}
|
|
11037
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
11081
11038
|
let container = existing?.container;
|
|
11082
|
-
let isNewMount = false;
|
|
11083
11039
|
if (!container || !container.isConnected) {
|
|
11084
|
-
isNewMount = true;
|
|
11085
11040
|
existing?.root.unmount();
|
|
11086
11041
|
container?.remove();
|
|
11087
11042
|
container = document.createElement("div");
|
|
@@ -17665,7 +17620,6 @@ function MediaOverlay({
|
|
|
17665
17620
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
17666
17621
|
);
|
|
17667
17622
|
}, [isVideo]);
|
|
17668
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
17669
17623
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
17670
17624
|
const box = {
|
|
17671
17625
|
position: "fixed",
|
|
@@ -17764,10 +17718,11 @@ function MediaOverlay({
|
|
|
17764
17718
|
className: "flex items-center justify-center cursor-pointer",
|
|
17765
17719
|
style: {
|
|
17766
17720
|
...box,
|
|
17767
|
-
//
|
|
17768
|
-
//
|
|
17769
|
-
//
|
|
17770
|
-
|
|
17721
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
17722
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
17723
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
17724
|
+
// Replace still works.
|
|
17725
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
17771
17726
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
17772
17727
|
// than hovered. Hover keeps the existing tinted preview.
|
|
17773
17728
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -17794,17 +17749,17 @@ function MediaOverlay({
|
|
|
17794
17749
|
},
|
|
17795
17750
|
children: [
|
|
17796
17751
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
17797
|
-
|
|
17752
|
+
isVideo ? "Replace video" : "Replace image"
|
|
17798
17753
|
]
|
|
17799
17754
|
}
|
|
17800
17755
|
),
|
|
17801
|
-
|
|
17756
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
17802
17757
|
Button,
|
|
17803
17758
|
{
|
|
17804
17759
|
"data-ohw-media-overlay": "",
|
|
17805
17760
|
variant: "outline",
|
|
17806
17761
|
size: "sm",
|
|
17807
|
-
"aria-label":
|
|
17762
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
17808
17763
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
17809
17764
|
style: {
|
|
17810
17765
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -17827,7 +17782,7 @@ function MediaOverlay({
|
|
|
17827
17782
|
},
|
|
17828
17783
|
children: [
|
|
17829
17784
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
17830
|
-
replaceMode === "full" ?
|
|
17785
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
17831
17786
|
]
|
|
17832
17787
|
}
|
|
17833
17788
|
)
|
|
@@ -18337,7 +18292,7 @@ function AiSectionOverlay({
|
|
|
18337
18292
|
|
|
18338
18293
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18339
18294
|
var import_react10 = require("react");
|
|
18340
|
-
var
|
|
18295
|
+
var import_lucide_react8 = require("lucide-react");
|
|
18341
18296
|
|
|
18342
18297
|
// src/lib/ai-media-strip-tree.ts
|
|
18343
18298
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18451,6 +18406,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18451
18406
|
return true;
|
|
18452
18407
|
});
|
|
18453
18408
|
}
|
|
18409
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18410
|
+
return withMediaStrip(tree, (block) => {
|
|
18411
|
+
const items = block.items;
|
|
18412
|
+
if (index < 0 || index >= items.length) return false;
|
|
18413
|
+
items[index] = { ...items[index], alt };
|
|
18414
|
+
return true;
|
|
18415
|
+
});
|
|
18416
|
+
}
|
|
18454
18417
|
function setMediaStripItemLink(tree, index, link) {
|
|
18455
18418
|
return withMediaStrip(tree, (block) => {
|
|
18456
18419
|
const items = block.items;
|
|
@@ -18468,117 +18431,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18468
18431
|
});
|
|
18469
18432
|
}
|
|
18470
18433
|
|
|
18471
|
-
// src/ui/dialog.tsx
|
|
18472
|
-
var React9 = __toESM(require("react"), 1);
|
|
18473
|
-
var import_radix_ui6 = require("radix-ui");
|
|
18474
|
-
var import_lucide_react8 = require("lucide-react");
|
|
18475
|
-
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18476
|
-
function Dialog2({
|
|
18477
|
-
...props
|
|
18478
|
-
}) {
|
|
18479
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
18480
|
-
}
|
|
18481
|
-
function DialogPortal({
|
|
18482
|
-
...props
|
|
18483
|
-
}) {
|
|
18484
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
18485
|
-
}
|
|
18486
|
-
function DialogOverlay({
|
|
18487
|
-
className,
|
|
18488
|
-
...props
|
|
18489
|
-
}) {
|
|
18490
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18491
|
-
import_radix_ui6.Dialog.Overlay,
|
|
18492
|
-
{
|
|
18493
|
-
"data-slot": "dialog-overlay",
|
|
18494
|
-
"data-ohw-link-modal-root": "",
|
|
18495
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18496
|
-
...props
|
|
18497
|
-
}
|
|
18498
|
-
);
|
|
18499
|
-
}
|
|
18500
|
-
var DialogContent = React9.forwardRef(
|
|
18501
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18502
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
18503
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
18504
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18505
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18506
|
-
import_radix_ui6.Dialog.Content,
|
|
18507
|
-
{
|
|
18508
|
-
ref,
|
|
18509
|
-
"data-slot": "dialog-content",
|
|
18510
|
-
className: cn(
|
|
18511
|
-
positionMode,
|
|
18512
|
-
"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",
|
|
18513
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18514
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18515
|
-
className
|
|
18516
|
-
),
|
|
18517
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
18518
|
-
...props,
|
|
18519
|
-
children: [
|
|
18520
|
-
children,
|
|
18521
|
-
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18522
|
-
import_radix_ui6.Dialog.Close,
|
|
18523
|
-
{
|
|
18524
|
-
type: "button",
|
|
18525
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18526
|
-
"aria-label": "Close",
|
|
18527
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
18528
|
-
}
|
|
18529
|
-
) : null
|
|
18530
|
-
]
|
|
18531
|
-
}
|
|
18532
|
-
)
|
|
18533
|
-
] });
|
|
18534
|
-
}
|
|
18535
|
-
);
|
|
18536
|
-
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
18537
|
-
function DialogHeader({
|
|
18538
|
-
className,
|
|
18539
|
-
...props
|
|
18540
|
-
}) {
|
|
18541
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18542
|
-
}
|
|
18543
|
-
function DialogFooter({
|
|
18544
|
-
className,
|
|
18545
|
-
...props
|
|
18546
|
-
}) {
|
|
18547
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18548
|
-
"div",
|
|
18549
|
-
{
|
|
18550
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
18551
|
-
...props
|
|
18552
|
-
}
|
|
18553
|
-
);
|
|
18554
|
-
}
|
|
18555
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18556
|
-
import_radix_ui6.Dialog.Title,
|
|
18557
|
-
{
|
|
18558
|
-
ref,
|
|
18559
|
-
className: cn(
|
|
18560
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18561
|
-
className
|
|
18562
|
-
),
|
|
18563
|
-
...props
|
|
18564
|
-
}
|
|
18565
|
-
));
|
|
18566
|
-
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
18567
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18568
|
-
import_radix_ui6.Dialog.Description,
|
|
18569
|
-
{
|
|
18570
|
-
ref,
|
|
18571
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
18572
|
-
...props
|
|
18573
|
-
}
|
|
18574
|
-
));
|
|
18575
|
-
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
18576
|
-
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
18577
|
-
|
|
18578
18434
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18579
|
-
var
|
|
18580
|
-
var PRIMARY3 = "
|
|
18581
|
-
var
|
|
18435
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18436
|
+
var PRIMARY3 = "#0885FE";
|
|
18437
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18438
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
18582
18439
|
function findMediaStripItemElement(sectionId, index) {
|
|
18583
18440
|
const sectionEl = findByInstanceId(sectionId);
|
|
18584
18441
|
if (!sectionEl) return null;
|
|
@@ -18588,35 +18445,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18588
18445
|
}
|
|
18589
18446
|
return null;
|
|
18590
18447
|
}
|
|
18591
|
-
function
|
|
18592
|
-
|
|
18593
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18594
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18595
|
-
if (!itemEl) return null;
|
|
18596
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18597
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18598
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18599
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18600
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
18601
|
-
return { sectionId, index };
|
|
18602
|
-
}
|
|
18603
|
-
function sameRef(a, b) {
|
|
18604
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18605
|
-
}
|
|
18606
|
-
function rectOf(el) {
|
|
18448
|
+
function readRect2(ref) {
|
|
18449
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18607
18450
|
if (!el) return null;
|
|
18608
18451
|
const r2 = el.getBoundingClientRect();
|
|
18609
18452
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18610
18453
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18611
18454
|
}
|
|
18612
|
-
function
|
|
18613
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18614
|
-
}
|
|
18615
|
-
function readStripRect(ref) {
|
|
18616
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18617
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18618
|
-
}
|
|
18619
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18455
|
+
function useLiveItemRect(ref) {
|
|
18620
18456
|
const [rect, setRect] = (0, import_react10.useState)(null);
|
|
18621
18457
|
(0, import_react10.useEffect)(() => {
|
|
18622
18458
|
if (!ref) {
|
|
@@ -18624,7 +18460,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18624
18460
|
return;
|
|
18625
18461
|
}
|
|
18626
18462
|
const update = () => {
|
|
18627
|
-
const next =
|
|
18463
|
+
const next = readRect2(ref);
|
|
18628
18464
|
setRect(
|
|
18629
18465
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18630
18466
|
);
|
|
@@ -18639,49 +18475,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18639
18475
|
window.removeEventListener("resize", update);
|
|
18640
18476
|
clearInterval(interval);
|
|
18641
18477
|
};
|
|
18642
|
-
}, [ref?.sectionId, ref?.index
|
|
18478
|
+
}, [ref?.sectionId, ref?.index]);
|
|
18643
18479
|
return rect;
|
|
18644
18480
|
}
|
|
18645
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
18646
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18647
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18648
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
18649
|
-
const slotRef = (0, import_react10.useRef)(null);
|
|
18650
|
-
const [shift, setShift] = (0, import_react10.useState)(0);
|
|
18651
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
18652
|
-
(0, import_react10.useLayoutEffect)(() => {
|
|
18653
|
-
const slot = slotRef.current;
|
|
18654
|
-
if (!slot) return;
|
|
18655
|
-
const clamp = () => {
|
|
18656
|
-
const w = slot.offsetWidth;
|
|
18657
|
-
if (w <= 0) return;
|
|
18658
|
-
const half = w / 2;
|
|
18659
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18660
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18661
|
-
};
|
|
18662
|
-
clamp();
|
|
18663
|
-
const ro = new ResizeObserver(clamp);
|
|
18664
|
-
ro.observe(slot);
|
|
18665
|
-
return () => ro.disconnect();
|
|
18666
|
-
}, [centerX, children]);
|
|
18667
|
-
const mobile = window.innerWidth <= 480;
|
|
18668
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18669
|
-
"div",
|
|
18670
|
-
{
|
|
18671
|
-
ref: slotRef,
|
|
18672
|
-
"data-ohw-bridge": "",
|
|
18673
|
-
"data-ohw-item-interaction": "",
|
|
18674
|
-
className: "pointer-events-auto fixed",
|
|
18675
|
-
style: {
|
|
18676
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18677
|
-
left: centerX + shift,
|
|
18678
|
-
transform: "translate(-50%, -100%)",
|
|
18679
|
-
zIndex: 2147483645
|
|
18680
|
-
},
|
|
18681
|
-
children
|
|
18682
|
-
}
|
|
18683
|
-
);
|
|
18684
|
-
}
|
|
18685
18481
|
function requestValidateTree(postToParent2, tree) {
|
|
18686
18482
|
return new Promise((resolve) => {
|
|
18687
18483
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18718,177 +18514,221 @@ function requestAssetPick(postToParent2) {
|
|
|
18718
18514
|
postToParent2({ type: "ow:asset-pick", id });
|
|
18719
18515
|
});
|
|
18720
18516
|
}
|
|
18721
|
-
function
|
|
18517
|
+
function Pill({
|
|
18722
18518
|
label,
|
|
18723
18519
|
onClick,
|
|
18724
|
-
disabled
|
|
18725
|
-
active
|
|
18726
|
-
children
|
|
18520
|
+
disabled,
|
|
18521
|
+
active
|
|
18727
18522
|
}) {
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
|
|
18732
|
-
|
|
18733
|
-
|
|
18734
|
-
|
|
18735
|
-
|
|
18523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18524
|
+
"button",
|
|
18525
|
+
{
|
|
18526
|
+
type: "button",
|
|
18527
|
+
onClick,
|
|
18528
|
+
disabled,
|
|
18529
|
+
style: {
|
|
18530
|
+
height: 28,
|
|
18531
|
+
padding: "0 10px",
|
|
18532
|
+
display: "inline-flex",
|
|
18533
|
+
alignItems: "center",
|
|
18534
|
+
gap: 4,
|
|
18535
|
+
borderRadius: 999,
|
|
18536
|
+
border: "none",
|
|
18537
|
+
cursor: disabled ? "default" : "pointer",
|
|
18538
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18539
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18540
|
+
opacity: disabled ? 0.4 : 1,
|
|
18541
|
+
fontSize: 12,
|
|
18542
|
+
lineHeight: "16px",
|
|
18543
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18544
|
+
whiteSpace: "nowrap",
|
|
18545
|
+
flex: "0 0 auto"
|
|
18546
|
+
},
|
|
18547
|
+
children: label
|
|
18548
|
+
}
|
|
18549
|
+
);
|
|
18736
18550
|
}
|
|
18737
|
-
function
|
|
18738
|
-
|
|
18739
|
-
value,
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
18747
|
-
|
|
18748
|
-
"
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
) }),
|
|
18759
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
18760
|
-
const selected = option.value === value;
|
|
18761
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
18762
|
-
DropdownMenuItem,
|
|
18551
|
+
function AltInput({ value, onCommit }) {
|
|
18552
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
18553
|
+
(0, import_react10.useEffect)(() => setDraft(value), [value]);
|
|
18554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18555
|
+
"div",
|
|
18556
|
+
{
|
|
18557
|
+
style: {
|
|
18558
|
+
display: "flex",
|
|
18559
|
+
alignItems: "center",
|
|
18560
|
+
gap: 6,
|
|
18561
|
+
height: 28,
|
|
18562
|
+
padding: "0 12px",
|
|
18563
|
+
borderRadius: 999,
|
|
18564
|
+
background: "#ffffff",
|
|
18565
|
+
width: "100%",
|
|
18566
|
+
maxWidth: 260,
|
|
18567
|
+
boxSizing: "border-box"
|
|
18568
|
+
},
|
|
18569
|
+
children: [
|
|
18570
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18571
|
+
"span",
|
|
18763
18572
|
{
|
|
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
|
-
|
|
18793
|
-
|
|
18794
|
-
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
|
|
18573
|
+
style: {
|
|
18574
|
+
flex: "0 0 auto",
|
|
18575
|
+
color: OHW_BLUE_DARK,
|
|
18576
|
+
fontSize: 10,
|
|
18577
|
+
fontWeight: 700,
|
|
18578
|
+
textTransform: "uppercase",
|
|
18579
|
+
letterSpacing: 0.4
|
|
18580
|
+
},
|
|
18581
|
+
children: "Alt"
|
|
18582
|
+
}
|
|
18583
|
+
),
|
|
18584
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18585
|
+
"input",
|
|
18586
|
+
{
|
|
18587
|
+
type: "text",
|
|
18588
|
+
value: draft,
|
|
18589
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18590
|
+
onBlur: () => {
|
|
18591
|
+
if (draft !== value) onCommit(draft);
|
|
18592
|
+
},
|
|
18593
|
+
onKeyDown: (e) => {
|
|
18594
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18595
|
+
if (e.key === "Escape") {
|
|
18596
|
+
setDraft(value);
|
|
18597
|
+
e.currentTarget.blur();
|
|
18598
|
+
}
|
|
18599
|
+
},
|
|
18600
|
+
placeholder: "Describe this image",
|
|
18601
|
+
"aria-label": "Image alt text",
|
|
18602
|
+
style: {
|
|
18603
|
+
flex: 1,
|
|
18604
|
+
minWidth: 0,
|
|
18605
|
+
border: "none",
|
|
18606
|
+
outline: "none",
|
|
18607
|
+
background: "transparent",
|
|
18608
|
+
fontSize: 12,
|
|
18609
|
+
lineHeight: "16px",
|
|
18610
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18611
|
+
color: "#1f2937"
|
|
18612
|
+
}
|
|
18613
|
+
}
|
|
18614
|
+
)
|
|
18615
|
+
]
|
|
18616
|
+
}
|
|
18617
|
+
);
|
|
18618
|
+
}
|
|
18619
|
+
var VARIANTS = [
|
|
18620
|
+
{ value: "logos", label: "Logos" },
|
|
18621
|
+
{ value: "reel", label: "Reel" }
|
|
18622
|
+
];
|
|
18623
|
+
var ALIGNS = [
|
|
18624
|
+
{ value: "left", label: "Left" },
|
|
18625
|
+
{ value: "center", label: "Center" },
|
|
18626
|
+
{ value: "right", label: "Right" }
|
|
18627
|
+
];
|
|
18628
|
+
var HOVERS = [
|
|
18629
|
+
{ value: "none", label: "None" },
|
|
18630
|
+
{ value: "lift", label: "Lift" },
|
|
18631
|
+
{ value: "zoom", label: "Zoom" },
|
|
18632
|
+
{ value: "fade", label: "Fade" }
|
|
18633
|
+
];
|
|
18634
|
+
var TREATMENTS = [
|
|
18635
|
+
{ value: "color", label: "Color" },
|
|
18636
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
18637
|
+
];
|
|
18638
|
+
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18639
|
+
function LinkInput({ value, onCommit }) {
|
|
18640
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
18803
18641
|
const [invalid, setInvalid] = (0, import_react10.useState)(false);
|
|
18804
|
-
|
|
18642
|
+
(0, import_react10.useEffect)(() => {
|
|
18643
|
+
setDraft(value);
|
|
18644
|
+
setInvalid(false);
|
|
18645
|
+
}, [value]);
|
|
18646
|
+
const commit = () => {
|
|
18805
18647
|
const next = draft.trim();
|
|
18806
|
-
if (next
|
|
18807
|
-
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
18811
|
-
onClose();
|
|
18648
|
+
if (next === value) return setInvalid(false);
|
|
18649
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
18650
|
+
setInvalid(false);
|
|
18651
|
+
onCommit(next);
|
|
18812
18652
|
};
|
|
18813
|
-
return /* @__PURE__ */ (0,
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
|
|
18817
|
-
"
|
|
18818
|
-
|
|
18819
|
-
|
|
18820
|
-
|
|
18821
|
-
|
|
18822
|
-
|
|
18823
|
-
|
|
18824
|
-
|
|
18825
|
-
|
|
18826
|
-
|
|
18827
|
-
|
|
18828
|
-
|
|
18829
|
-
|
|
18830
|
-
|
|
18831
|
-
"
|
|
18832
|
-
|
|
18833
|
-
|
|
18834
|
-
|
|
18835
|
-
|
|
18836
|
-
|
|
18837
|
-
|
|
18838
|
-
|
|
18839
|
-
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
|
|
18845
|
-
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
|
|
18852
|
-
|
|
18853
|
-
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18864
|
-
|
|
18865
|
-
|
|
18866
|
-
|
|
18867
|
-
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
|
|
18872
|
-
|
|
18873
|
-
|
|
18874
|
-
|
|
18875
|
-
|
|
18876
|
-
|
|
18877
|
-
|
|
18653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18654
|
+
"div",
|
|
18655
|
+
{
|
|
18656
|
+
style: {
|
|
18657
|
+
display: "flex",
|
|
18658
|
+
alignItems: "center",
|
|
18659
|
+
gap: 6,
|
|
18660
|
+
height: 28,
|
|
18661
|
+
padding: "0 12px",
|
|
18662
|
+
borderRadius: 999,
|
|
18663
|
+
background: "#ffffff",
|
|
18664
|
+
width: "100%",
|
|
18665
|
+
maxWidth: 260,
|
|
18666
|
+
boxSizing: "border-box",
|
|
18667
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18668
|
+
},
|
|
18669
|
+
children: [
|
|
18670
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18671
|
+
"span",
|
|
18672
|
+
{
|
|
18673
|
+
style: {
|
|
18674
|
+
flex: "0 0 auto",
|
|
18675
|
+
color: OHW_BLUE_DARK,
|
|
18676
|
+
fontSize: 10,
|
|
18677
|
+
fontWeight: 700,
|
|
18678
|
+
textTransform: "uppercase",
|
|
18679
|
+
letterSpacing: 0.4
|
|
18680
|
+
},
|
|
18681
|
+
children: "Link"
|
|
18682
|
+
}
|
|
18683
|
+
),
|
|
18684
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18685
|
+
"input",
|
|
18686
|
+
{
|
|
18687
|
+
type: "text",
|
|
18688
|
+
inputMode: "url",
|
|
18689
|
+
value: draft,
|
|
18690
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18691
|
+
onBlur: commit,
|
|
18692
|
+
onKeyDown: (e) => {
|
|
18693
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18694
|
+
if (e.key === "Escape") {
|
|
18695
|
+
setDraft(value);
|
|
18696
|
+
setInvalid(false);
|
|
18697
|
+
e.currentTarget.blur();
|
|
18698
|
+
}
|
|
18699
|
+
},
|
|
18700
|
+
placeholder: "https://example.com",
|
|
18701
|
+
"aria-label": "Image link URL",
|
|
18702
|
+
"aria-invalid": invalid,
|
|
18703
|
+
style: {
|
|
18704
|
+
flex: 1,
|
|
18705
|
+
minWidth: 0,
|
|
18706
|
+
border: "none",
|
|
18707
|
+
outline: "none",
|
|
18708
|
+
background: "transparent",
|
|
18709
|
+
fontSize: 12,
|
|
18710
|
+
lineHeight: "16px",
|
|
18711
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18712
|
+
color: "#1f2937"
|
|
18713
|
+
}
|
|
18714
|
+
}
|
|
18715
|
+
)
|
|
18716
|
+
]
|
|
18717
|
+
}
|
|
18718
|
+
);
|
|
18878
18719
|
}
|
|
18879
18720
|
function MediaStripToolbar({
|
|
18880
18721
|
entry,
|
|
18881
18722
|
index,
|
|
18882
18723
|
pending,
|
|
18883
18724
|
error,
|
|
18884
|
-
itemEditOn,
|
|
18885
|
-
onToggleItemEdit,
|
|
18886
18725
|
onSetVariant,
|
|
18887
18726
|
onSetAlign,
|
|
18888
18727
|
onSetHover,
|
|
18889
18728
|
onSetTreatment,
|
|
18890
18729
|
onResize,
|
|
18891
|
-
|
|
18730
|
+
onSetAlt,
|
|
18731
|
+
onSetLink,
|
|
18892
18732
|
onAddItem,
|
|
18893
18733
|
onRemoveItem,
|
|
18894
18734
|
onChangeImage,
|
|
@@ -18897,102 +18737,81 @@ function MediaStripToolbar({
|
|
|
18897
18737
|
}) {
|
|
18898
18738
|
const items = mediaStripItems(entry.tree);
|
|
18899
18739
|
const itemCount = items.length;
|
|
18740
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
18741
|
+
const currentHref = items[index]?.href ?? "";
|
|
18742
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18900
18743
|
const slots = findMediaStripSlots(entry.tree);
|
|
18901
18744
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18902
18745
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
18903
18746
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
18904
18747
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
18905
18748
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18906
|
-
const
|
|
18907
|
-
const
|
|
18908
|
-
|
|
18749
|
+
const isMobile = window.innerWidth <= 480;
|
|
18750
|
+
const rowStyle = isMobile ? {
|
|
18751
|
+
display: "flex",
|
|
18752
|
+
gap: 6,
|
|
18753
|
+
flexWrap: "nowrap",
|
|
18754
|
+
justifyContent: "center",
|
|
18755
|
+
overflowX: "auto",
|
|
18756
|
+
WebkitOverflowScrolling: "touch",
|
|
18757
|
+
width: "100%",
|
|
18758
|
+
scrollbarWidth: "none"
|
|
18759
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
18760
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18909
18761
|
"div",
|
|
18910
18762
|
{
|
|
18911
18763
|
"data-ohw-bridge": "",
|
|
18912
18764
|
"data-ohw-toolbar": "",
|
|
18913
18765
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18914
|
-
|
|
18915
|
-
|
|
18766
|
+
style: {
|
|
18767
|
+
display: "flex",
|
|
18768
|
+
flexDirection: "column",
|
|
18769
|
+
gap: 6,
|
|
18770
|
+
alignItems: "center",
|
|
18771
|
+
background: OHW_BLUE,
|
|
18772
|
+
padding: 8,
|
|
18773
|
+
borderRadius: 12,
|
|
18774
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18775
|
+
pointerEvents: pending ? "none" : "auto",
|
|
18776
|
+
opacity: pending ? 0.6 : 1,
|
|
18777
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
18778
|
+
},
|
|
18916
18779
|
children: [
|
|
18917
|
-
/* @__PURE__ */ (0,
|
|
18918
|
-
|
|
18919
|
-
{
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
|
|
18923
|
-
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
|
|
18928
|
-
|
|
18929
|
-
|
|
18930
|
-
|
|
18931
|
-
|
|
18932
|
-
|
|
18933
|
-
|
|
18934
|
-
|
|
18935
|
-
|
|
18936
|
-
|
|
18937
|
-
|
|
18938
|
-
|
|
18939
|
-
|
|
18940
|
-
|
|
18941
|
-
|
|
18942
|
-
|
|
18943
|
-
|
|
18944
|
-
|
|
18945
|
-
|
|
18946
|
-
|
|
18947
|
-
|
|
18948
|
-
|
|
18949
|
-
) }),
|
|
18950
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
18951
|
-
] }),
|
|
18952
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
18953
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Image, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18954
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Link, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18955
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ArrowLeft, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18956
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18957
|
-
ToolbarAction,
|
|
18958
|
-
{
|
|
18959
|
-
label: gatedLabel("Move right"),
|
|
18960
|
-
onClick: onMoveRight,
|
|
18961
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
18962
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ArrowRight, { size: 16, style: { pointerEvents: "none" } })
|
|
18963
|
-
}
|
|
18964
|
-
),
|
|
18965
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18966
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
18967
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
18968
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
18969
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18970
|
-
ToolbarAction,
|
|
18971
|
-
{
|
|
18972
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
18973
|
-
active: treatment === "grayscale",
|
|
18974
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
18975
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
18976
|
-
}
|
|
18977
|
-
),
|
|
18978
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
18979
|
-
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
18980
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
18981
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18982
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
18983
|
-
sizeValue,
|
|
18984
|
-
"px"
|
|
18985
|
-
] }),
|
|
18986
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18987
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
18988
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18989
|
-
]
|
|
18990
|
-
}
|
|
18991
|
-
),
|
|
18992
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18780
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
18781
|
+
VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
18782
|
+
ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
18783
|
+
] }),
|
|
18784
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
18785
|
+
HOVERS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
18786
|
+
TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
18787
|
+
] }),
|
|
18788
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
18789
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
18790
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
18791
|
+
sizeValue,
|
|
18792
|
+
"px"
|
|
18793
|
+
] }),
|
|
18794
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "+", onClick: () => onResize(8) })
|
|
18795
|
+
] }),
|
|
18796
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
18797
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkInput, { value: currentHref, onCommit: (href) => onSetLink(href, currentTarget) }) }),
|
|
18798
|
+
currentHref && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
18799
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
18800
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
18801
|
+
] }),
|
|
18802
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
18803
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
18804
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
18805
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
18806
|
+
] }),
|
|
18807
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
18808
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
18809
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
18810
|
+
] }),
|
|
18811
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
18993
18812
|
]
|
|
18994
18813
|
}
|
|
18995
|
-
)
|
|
18814
|
+
);
|
|
18996
18815
|
}
|
|
18997
18816
|
function findMediaStripSlots(tree) {
|
|
18998
18817
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -19011,23 +18830,31 @@ function AiMediaStripOverlay({
|
|
|
19011
18830
|
}) {
|
|
19012
18831
|
const [hover, setHover] = (0, import_react10.useState)(null);
|
|
19013
18832
|
const [active, setActive] = (0, import_react10.useState)(null);
|
|
19014
|
-
const [itemEditOn, setItemEditOn] = (0, import_react10.useState)(false);
|
|
19015
|
-
const [linkOpen, setLinkOpen] = (0, import_react10.useState)(false);
|
|
19016
18833
|
const [pending, setPending] = (0, import_react10.useState)(false);
|
|
19017
18834
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
19018
18835
|
const activeRef = (0, import_react10.useRef)(null);
|
|
19019
18836
|
activeRef.current = active;
|
|
19020
|
-
const linkOpenRef = (0, import_react10.useRef)(false);
|
|
19021
|
-
linkOpenRef.current = linkOpen;
|
|
19022
18837
|
(0, import_react10.useEffect)(() => {
|
|
19023
18838
|
const onMove = (e) => {
|
|
19024
|
-
const ref = itemRefFromTarget(e.target);
|
|
19025
18839
|
const t = e.target;
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
18840
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18841
|
+
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]")) {
|
|
18842
|
+
return;
|
|
18843
|
+
}
|
|
18844
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
18845
|
+
if (!itemEl) {
|
|
18846
|
+
setHover(null);
|
|
18847
|
+
return;
|
|
18848
|
+
}
|
|
18849
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18850
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18851
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18852
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18853
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
18854
|
+
setHover(null);
|
|
18855
|
+
return;
|
|
18856
|
+
}
|
|
18857
|
+
setHover({ sectionId, index });
|
|
19031
18858
|
};
|
|
19032
18859
|
const onLeave = () => setHover(null);
|
|
19033
18860
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -19039,25 +18866,23 @@ function AiMediaStripOverlay({
|
|
|
19039
18866
|
}, []);
|
|
19040
18867
|
(0, import_react10.useEffect)(() => {
|
|
19041
18868
|
const onClick = (e) => {
|
|
18869
|
+
const current = activeRef.current;
|
|
18870
|
+
if (!current) return;
|
|
19042
18871
|
const t = e.target;
|
|
19043
|
-
if (!(t instanceof
|
|
19044
|
-
if (t.closest(
|
|
19045
|
-
const
|
|
19046
|
-
if (
|
|
19047
|
-
|
|
19048
|
-
setItemEditOn(false);
|
|
18872
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18873
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
18874
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
18875
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
18876
|
+
setActive(null);
|
|
19049
18877
|
setError(null);
|
|
19050
|
-
setActive(ref);
|
|
19051
18878
|
};
|
|
19052
18879
|
document.addEventListener("click", onClick, true);
|
|
19053
18880
|
return () => document.removeEventListener("click", onClick, true);
|
|
19054
|
-
}, [
|
|
18881
|
+
}, []);
|
|
19055
18882
|
(0, import_react10.useEffect)(() => {
|
|
19056
18883
|
const onBlur = () => {
|
|
19057
18884
|
if (!activeRef.current) return;
|
|
19058
18885
|
setActive(null);
|
|
19059
|
-
setItemEditOn(false);
|
|
19060
|
-
setLinkOpen(false);
|
|
19061
18886
|
setError(null);
|
|
19062
18887
|
};
|
|
19063
18888
|
window.addEventListener("blur", onBlur);
|
|
@@ -19067,10 +18892,7 @@ function AiMediaStripOverlay({
|
|
|
19067
18892
|
const onKeyDown = (e) => {
|
|
19068
18893
|
if (e.key !== "Escape") return;
|
|
19069
18894
|
if (!activeRef.current) return;
|
|
19070
|
-
if (linkOpenRef.current) return;
|
|
19071
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
19072
18895
|
setActive(null);
|
|
19073
|
-
setItemEditOn(false);
|
|
19074
18896
|
setError(null);
|
|
19075
18897
|
};
|
|
19076
18898
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -19104,133 +18926,137 @@ function AiMediaStripOverlay({
|
|
|
19104
18926
|
tree: nextTree,
|
|
19105
18927
|
label: entry.label,
|
|
19106
18928
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
19107
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
19108
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
19109
|
-
// on every edit reads as the section jumping around.
|
|
19110
|
-
skipScrollIntoView: true
|
|
18929
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
19111
18930
|
});
|
|
19112
18931
|
return true;
|
|
19113
18932
|
},
|
|
19114
18933
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
19115
18934
|
);
|
|
19116
18935
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18936
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
19117
18937
|
const activeItemRect = useLiveItemRect(active);
|
|
19118
|
-
const
|
|
19119
|
-
const
|
|
19120
|
-
|
|
19121
|
-
|
|
19122
|
-
|
|
19123
|
-
|
|
19124
|
-
|
|
19125
|
-
|
|
19126
|
-
|
|
19127
|
-
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
|
|
19138
|
-
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
19148
|
-
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
18938
|
+
const TOOLBAR_APPROX_H = 170;
|
|
18939
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
18940
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
18941
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18942
|
+
"button",
|
|
18943
|
+
{
|
|
18944
|
+
type: "button",
|
|
18945
|
+
"data-ohw-toolbar": "",
|
|
18946
|
+
onClick: () => {
|
|
18947
|
+
clearInteractionChromeRef.current();
|
|
18948
|
+
setActive(hover);
|
|
18949
|
+
},
|
|
18950
|
+
"aria-label": "Configure media item",
|
|
18951
|
+
style: {
|
|
18952
|
+
position: "fixed",
|
|
18953
|
+
top: hoverHandleRect.top + 8,
|
|
18954
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
18955
|
+
width: 28,
|
|
18956
|
+
height: 28,
|
|
18957
|
+
borderRadius: 8,
|
|
18958
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
18959
|
+
background: "#ffffff",
|
|
18960
|
+
color: PRIMARY3,
|
|
18961
|
+
display: "flex",
|
|
18962
|
+
alignItems: "center",
|
|
18963
|
+
justifyContent: "center",
|
|
18964
|
+
cursor: "pointer",
|
|
18965
|
+
zIndex: 2147483643,
|
|
18966
|
+
fontSize: 14,
|
|
18967
|
+
fontWeight: 700
|
|
18968
|
+
},
|
|
18969
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
18970
|
+
}
|
|
18971
|
+
),
|
|
18972
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18973
|
+
ItemInteractionLayer,
|
|
18974
|
+
{
|
|
18975
|
+
rect: activeItemRect,
|
|
18976
|
+
state: toolbarState,
|
|
18977
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18978
|
+
MediaStripToolbar,
|
|
18979
|
+
{
|
|
18980
|
+
entry: activeEntry,
|
|
18981
|
+
index: active.index,
|
|
18982
|
+
pending,
|
|
18983
|
+
error,
|
|
18984
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18985
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18986
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18987
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18988
|
+
onResize: (delta) => {
|
|
18989
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18990
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18991
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18992
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18993
|
+
},
|
|
18994
|
+
onSetAlt: (alt) => {
|
|
18995
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
18996
|
+
},
|
|
18997
|
+
onSetLink: (href, linkTarget) => {
|
|
19152
18998
|
void runMutation(
|
|
19153
18999
|
active.sectionId,
|
|
19154
|
-
(tree) =>
|
|
19155
|
-
|
|
19156
|
-
|
|
19157
|
-
|
|
19000
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19001
|
+
);
|
|
19002
|
+
},
|
|
19003
|
+
onAddItem: () => {
|
|
19004
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19005
|
+
if (!picked) return;
|
|
19006
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
19007
|
+
void runMutation(
|
|
19008
|
+
active.sectionId,
|
|
19009
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
19010
|
+
{ [picked.assetId]: picked.url }
|
|
19011
|
+
).then((applied) => {
|
|
19012
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19013
|
+
});
|
|
19158
19014
|
});
|
|
19159
|
-
}
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19015
|
+
},
|
|
19016
|
+
onChangeImage: () => {
|
|
19017
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19018
|
+
if (!picked) return;
|
|
19019
|
+
void runMutation(
|
|
19020
|
+
active.sectionId,
|
|
19021
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
19022
|
+
{ [picked.assetId]: picked.url }
|
|
19023
|
+
);
|
|
19024
|
+
});
|
|
19025
|
+
},
|
|
19026
|
+
onRemoveItem: () => {
|
|
19027
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
19028
|
+
(applied) => {
|
|
19029
|
+
if (applied) setActive(null);
|
|
19030
|
+
}
|
|
19168
19031
|
);
|
|
19169
|
-
}
|
|
19170
|
-
|
|
19171
|
-
|
|
19172
|
-
|
|
19173
|
-
|
|
19174
|
-
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
19179
|
-
|
|
19180
|
-
|
|
19181
|
-
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
},
|
|
19185
|
-
onMoveRight: () => {
|
|
19186
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19187
|
-
(applied) => {
|
|
19188
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19189
|
-
}
|
|
19190
|
-
);
|
|
19191
|
-
}
|
|
19192
|
-
}
|
|
19193
|
-
) }),
|
|
19194
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19195
|
-
"div",
|
|
19196
|
-
{
|
|
19197
|
-
"data-ohw-bridge": "",
|
|
19198
|
-
"data-ohw-item-interaction": "",
|
|
19199
|
-
"aria-hidden": true,
|
|
19200
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
19201
|
-
style: {
|
|
19202
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
19203
|
-
left: activeItemRect.left - 5,
|
|
19204
|
-
background: PRIMARY3,
|
|
19205
|
-
zIndex: 2147483644
|
|
19206
|
-
},
|
|
19207
|
-
children: "Media item"
|
|
19208
|
-
}
|
|
19209
|
-
),
|
|
19210
|
-
linkOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19211
|
-
LinkModal,
|
|
19212
|
-
{
|
|
19213
|
-
href: activeHref,
|
|
19214
|
-
linkTarget: activeTarget,
|
|
19215
|
-
onClose: () => setLinkOpen(false),
|
|
19216
|
-
onSave: (href, linkTarget) => {
|
|
19217
|
-
void runMutation(
|
|
19218
|
-
active.sectionId,
|
|
19219
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19220
|
-
);
|
|
19032
|
+
},
|
|
19033
|
+
onMoveLeft: () => {
|
|
19034
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
19035
|
+
(applied) => {
|
|
19036
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
19037
|
+
}
|
|
19038
|
+
);
|
|
19039
|
+
},
|
|
19040
|
+
onMoveRight: () => {
|
|
19041
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19042
|
+
(applied) => {
|
|
19043
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19044
|
+
}
|
|
19045
|
+
);
|
|
19046
|
+
}
|
|
19221
19047
|
}
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19048
|
+
)
|
|
19049
|
+
}
|
|
19050
|
+
)
|
|
19225
19051
|
] });
|
|
19226
19052
|
}
|
|
19227
19053
|
|
|
19228
19054
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
19229
19055
|
var import_react11 = require("react");
|
|
19230
|
-
var
|
|
19231
|
-
var
|
|
19056
|
+
var import_lucide_react9 = require("lucide-react");
|
|
19057
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
19232
19058
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
19233
|
-
var
|
|
19059
|
+
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]";
|
|
19234
19060
|
function findPricingCardElement(sectionId, index) {
|
|
19235
19061
|
const sectionEl = findByInstanceId(sectionId);
|
|
19236
19062
|
if (!sectionEl) return null;
|
|
@@ -19242,7 +19068,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19242
19068
|
}
|
|
19243
19069
|
function cardRefFromTarget(target) {
|
|
19244
19070
|
if (!(target instanceof Element)) return null;
|
|
19245
|
-
if (target.closest(
|
|
19071
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19246
19072
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19247
19073
|
if (!cardEl) return null;
|
|
19248
19074
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19252,21 +19078,21 @@ function cardRefFromTarget(target) {
|
|
|
19252
19078
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19253
19079
|
return { sectionId, index };
|
|
19254
19080
|
}
|
|
19255
|
-
function
|
|
19081
|
+
function sameRef(a, b) {
|
|
19256
19082
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19257
19083
|
}
|
|
19258
|
-
function
|
|
19084
|
+
function rectOf(el) {
|
|
19259
19085
|
if (!el) return null;
|
|
19260
19086
|
const r2 = el.getBoundingClientRect();
|
|
19261
19087
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19262
19088
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19263
19089
|
}
|
|
19264
19090
|
function readRect3(ref) {
|
|
19265
|
-
return
|
|
19091
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19266
19092
|
}
|
|
19267
19093
|
function readGridRect(ref) {
|
|
19268
19094
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19269
|
-
return
|
|
19095
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19270
19096
|
}
|
|
19271
19097
|
function useLiveCardRect(ref, grid = false) {
|
|
19272
19098
|
const [rect, setRect] = (0, import_react11.useState)(null);
|
|
@@ -19296,7 +19122,7 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19296
19122
|
}
|
|
19297
19123
|
var TOOLBAR_GRID_GAP = 52;
|
|
19298
19124
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19299
|
-
var
|
|
19125
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19300
19126
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19301
19127
|
const slotRef = (0, import_react11.useRef)(null);
|
|
19302
19128
|
const [shift, setShift] = (0, import_react11.useState)(0);
|
|
@@ -19308,7 +19134,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19308
19134
|
const w = slot.offsetWidth;
|
|
19309
19135
|
if (w <= 0) return;
|
|
19310
19136
|
const half = w / 2;
|
|
19311
|
-
const clamped = Math.max(
|
|
19137
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19312
19138
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19313
19139
|
};
|
|
19314
19140
|
clamp();
|
|
@@ -19317,7 +19143,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19317
19143
|
return () => ro.disconnect();
|
|
19318
19144
|
}, [centerX, children]);
|
|
19319
19145
|
const mobile = window.innerWidth <= 480;
|
|
19320
|
-
return /* @__PURE__ */ (0,
|
|
19146
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19321
19147
|
"div",
|
|
19322
19148
|
{
|
|
19323
19149
|
ref: slotRef,
|
|
@@ -19352,7 +19178,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
19352
19178
|
});
|
|
19353
19179
|
}
|
|
19354
19180
|
function StyleSwatch({ style }) {
|
|
19355
|
-
return /* @__PURE__ */ (0,
|
|
19181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19356
19182
|
"span",
|
|
19357
19183
|
{
|
|
19358
19184
|
"aria-hidden": true,
|
|
@@ -19366,35 +19192,35 @@ function StyleSwatch({ style }) {
|
|
|
19366
19192
|
);
|
|
19367
19193
|
}
|
|
19368
19194
|
function ButtonGlyph() {
|
|
19369
|
-
return /* @__PURE__ */ (0,
|
|
19370
|
-
/* @__PURE__ */ (0,
|
|
19371
|
-
/* @__PURE__ */ (0,
|
|
19195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19196
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19197
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19372
19198
|
] });
|
|
19373
19199
|
}
|
|
19374
19200
|
function FeatureGlyph({ mode }) {
|
|
19375
|
-
return /* @__PURE__ */ (0,
|
|
19376
|
-
/* @__PURE__ */ (0,
|
|
19377
|
-
/* @__PURE__ */ (0,
|
|
19378
|
-
/* @__PURE__ */ (0,
|
|
19379
|
-
/* @__PURE__ */ (0,
|
|
19380
|
-
/* @__PURE__ */ (0,
|
|
19381
|
-
mode === "add" && /* @__PURE__ */ (0,
|
|
19201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19202
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19203
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19204
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19205
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19206
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19207
|
+
mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19382
19208
|
] });
|
|
19383
19209
|
}
|
|
19384
|
-
function
|
|
19210
|
+
function ToolbarAction({
|
|
19385
19211
|
label,
|
|
19386
19212
|
onClick,
|
|
19387
19213
|
disabled = false,
|
|
19388
19214
|
children
|
|
19389
19215
|
}) {
|
|
19390
|
-
const button = /* @__PURE__ */ (0,
|
|
19391
|
-
return /* @__PURE__ */ (0,
|
|
19392
|
-
/* @__PURE__ */ (0,
|
|
19393
|
-
/* @__PURE__ */ (0,
|
|
19216
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19218
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
19219
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19394
19220
|
] });
|
|
19395
19221
|
}
|
|
19396
|
-
function
|
|
19397
|
-
return /* @__PURE__ */ (0,
|
|
19222
|
+
function ToolbarSeparator() {
|
|
19223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19398
19224
|
}
|
|
19399
19225
|
function CardStyleMenu({
|
|
19400
19226
|
value,
|
|
@@ -19402,7 +19228,7 @@ function CardStyleMenu({
|
|
|
19402
19228
|
disabled = false
|
|
19403
19229
|
}) {
|
|
19404
19230
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
19405
|
-
const trigger = /* @__PURE__ */ (0,
|
|
19231
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19406
19232
|
"button",
|
|
19407
19233
|
{
|
|
19408
19234
|
type: "button",
|
|
@@ -19413,28 +19239,28 @@ function CardStyleMenu({
|
|
|
19413
19239
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
19414
19240
|
),
|
|
19415
19241
|
children: [
|
|
19416
|
-
/* @__PURE__ */ (0,
|
|
19417
|
-
/* @__PURE__ */ (0,
|
|
19418
|
-
/* @__PURE__ */ (0,
|
|
19242
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: current.value }),
|
|
19243
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
19244
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
19419
19245
|
]
|
|
19420
19246
|
}
|
|
19421
19247
|
);
|
|
19422
19248
|
if (disabled) {
|
|
19423
|
-
return /* @__PURE__ */ (0,
|
|
19424
|
-
/* @__PURE__ */ (0,
|
|
19425
|
-
/* @__PURE__ */ (0,
|
|
19426
|
-
/* @__PURE__ */ (0,
|
|
19427
|
-
/* @__PURE__ */ (0,
|
|
19249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19250
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19251
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19252
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
19253
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
19428
19254
|
] })
|
|
19429
19255
|
] });
|
|
19430
19256
|
}
|
|
19431
|
-
return /* @__PURE__ */ (0,
|
|
19432
|
-
/* @__PURE__ */ (0,
|
|
19433
|
-
/* @__PURE__ */ (0,
|
|
19434
|
-
/* @__PURE__ */ (0,
|
|
19435
|
-
/* @__PURE__ */ (0,
|
|
19257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19258
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19259
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenu, { modal: false, children: [
|
|
19260
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19261
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
19436
19262
|
const selected = style.value === value;
|
|
19437
|
-
return /* @__PURE__ */ (0,
|
|
19263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19438
19264
|
DropdownMenuItem,
|
|
19439
19265
|
{
|
|
19440
19266
|
role: "menuitemradio",
|
|
@@ -19442,9 +19268,9 @@ function CardStyleMenu({
|
|
|
19442
19268
|
onSelect: () => onChange(style.value),
|
|
19443
19269
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19444
19270
|
children: [
|
|
19445
|
-
/* @__PURE__ */ (0,
|
|
19446
|
-
/* @__PURE__ */ (0,
|
|
19447
|
-
selected && /* @__PURE__ */ (0,
|
|
19271
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: style.value }),
|
|
19272
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: style.label }),
|
|
19273
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
|
|
19448
19274
|
]
|
|
19449
19275
|
},
|
|
19450
19276
|
style.value
|
|
@@ -19474,7 +19300,7 @@ function PricingCardToolbar({
|
|
|
19474
19300
|
const style = pricingCardStyle(entry.tree, index);
|
|
19475
19301
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19476
19302
|
const mobile = window.innerWidth <= 480;
|
|
19477
|
-
return /* @__PURE__ */ (0,
|
|
19303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19478
19304
|
"div",
|
|
19479
19305
|
{
|
|
19480
19306
|
"data-ohw-bridge": "",
|
|
@@ -19486,7 +19312,7 @@ function PricingCardToolbar({
|
|
|
19486
19312
|
),
|
|
19487
19313
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19488
19314
|
children: [
|
|
19489
|
-
/* @__PURE__ */ (0,
|
|
19315
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19490
19316
|
"div",
|
|
19491
19317
|
{
|
|
19492
19318
|
className: cn(
|
|
@@ -19495,8 +19321,8 @@ function PricingCardToolbar({
|
|
|
19495
19321
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19496
19322
|
),
|
|
19497
19323
|
children: [
|
|
19498
|
-
/* @__PURE__ */ (0,
|
|
19499
|
-
/* @__PURE__ */ (0,
|
|
19324
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19325
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19500
19326
|
CustomToolbarButton,
|
|
19501
19327
|
{
|
|
19502
19328
|
type: "button",
|
|
@@ -19504,8 +19330,8 @@ function PricingCardToolbar({
|
|
|
19504
19330
|
"aria-pressed": featuredTag,
|
|
19505
19331
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19506
19332
|
className: "group size-8",
|
|
19507
|
-
children: /* @__PURE__ */ (0,
|
|
19508
|
-
|
|
19333
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19334
|
+
import_lucide_react9.Star,
|
|
19509
19335
|
{
|
|
19510
19336
|
size: 16,
|
|
19511
19337
|
fill: "currentColor",
|
|
@@ -19519,25 +19345,25 @@ function PricingCardToolbar({
|
|
|
19519
19345
|
)
|
|
19520
19346
|
}
|
|
19521
19347
|
) }),
|
|
19522
|
-
/* @__PURE__ */ (0,
|
|
19348
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19523
19349
|
] }),
|
|
19524
|
-
/* @__PURE__ */ (0,
|
|
19525
|
-
/* @__PURE__ */ (0,
|
|
19526
|
-
/* @__PURE__ */ (0,
|
|
19527
|
-
/* @__PURE__ */ (0,
|
|
19528
|
-
/* @__PURE__ */ (0,
|
|
19529
|
-
/* @__PURE__ */ (0,
|
|
19530
|
-
/* @__PURE__ */ (0,
|
|
19350
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19351
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19352
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19353
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}) }),
|
|
19354
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "relative inline-flex", children: [
|
|
19355
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}),
|
|
19356
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.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" })
|
|
19531
19357
|
] }) }),
|
|
19532
|
-
/* @__PURE__ */ (0,
|
|
19533
|
-
/* @__PURE__ */ (0,
|
|
19534
|
-
/* @__PURE__ */ (0,
|
|
19535
|
-
/* @__PURE__ */ (0,
|
|
19536
|
-
/* @__PURE__ */ (0,
|
|
19358
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FeatureGlyph, { mode: "add" }) }),
|
|
19359
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FeatureGlyph, { mode: "remove" }) }),
|
|
19360
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19361
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19362
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19537
19363
|
]
|
|
19538
19364
|
}
|
|
19539
19365
|
),
|
|
19540
|
-
error && /* @__PURE__ */ (0,
|
|
19366
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19541
19367
|
]
|
|
19542
19368
|
}
|
|
19543
19369
|
) });
|
|
@@ -19571,7 +19397,7 @@ function AiPricingCardOverlay({
|
|
|
19571
19397
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19572
19398
|
setHover((prev) => {
|
|
19573
19399
|
const next = ref && !overEditable ? ref : null;
|
|
19574
|
-
return
|
|
19400
|
+
return sameRef(prev, next) ? prev : next;
|
|
19575
19401
|
});
|
|
19576
19402
|
};
|
|
19577
19403
|
const onLeave = () => setHover(null);
|
|
@@ -19586,10 +19412,10 @@ function AiPricingCardOverlay({
|
|
|
19586
19412
|
const onClick = (e) => {
|
|
19587
19413
|
const t = e.target;
|
|
19588
19414
|
if (!(t instanceof Element)) return;
|
|
19589
|
-
if (t.closest(
|
|
19415
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
19590
19416
|
const ref = cardRefFromTarget(t);
|
|
19591
|
-
setActive((prev) =>
|
|
19592
|
-
if (!ref || !
|
|
19417
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19418
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
19593
19419
|
};
|
|
19594
19420
|
document.addEventListener("click", onClick, true);
|
|
19595
19421
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19654,12 +19480,12 @@ function AiPricingCardOverlay({
|
|
|
19654
19480
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19655
19481
|
const activeCardRect = useLiveCardRect(active);
|
|
19656
19482
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19657
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19658
|
-
return /* @__PURE__ */ (0,
|
|
19659
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
19660
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19661
|
-
/* @__PURE__ */ (0,
|
|
19662
|
-
/* @__PURE__ */ (0,
|
|
19483
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19485
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19486
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19487
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19488
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19663
19489
|
PricingCardToolbar,
|
|
19664
19490
|
{
|
|
19665
19491
|
entry: activeEntry,
|
|
@@ -19687,7 +19513,7 @@ function AiPricingCardOverlay({
|
|
|
19687
19513
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
19688
19514
|
}
|
|
19689
19515
|
) }),
|
|
19690
|
-
/* @__PURE__ */ (0,
|
|
19516
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19691
19517
|
"div",
|
|
19692
19518
|
{
|
|
19693
19519
|
"data-ohw-bridge": "",
|
|
@@ -19709,7 +19535,7 @@ function AiPricingCardOverlay({
|
|
|
19709
19535
|
|
|
19710
19536
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19711
19537
|
var import_react12 = require("react");
|
|
19712
|
-
var
|
|
19538
|
+
var import_lucide_react10 = require("lucide-react");
|
|
19713
19539
|
|
|
19714
19540
|
// src/lib/ai-video-tree.ts
|
|
19715
19541
|
function resolveVideoBlock(tree, path) {
|
|
@@ -19780,10 +19606,10 @@ function extractYouTubeId(input) {
|
|
|
19780
19606
|
}
|
|
19781
19607
|
|
|
19782
19608
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19783
|
-
var
|
|
19609
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
19784
19610
|
var PRIMARY5 = "#0885FE";
|
|
19785
|
-
var
|
|
19786
|
-
var
|
|
19611
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19612
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
19787
19613
|
function findVideoBlockElement(sectionId, path) {
|
|
19788
19614
|
const sectionEl = findByInstanceId(sectionId);
|
|
19789
19615
|
if (!sectionEl) return null;
|
|
@@ -19843,12 +19669,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
19843
19669
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
19844
19670
|
});
|
|
19845
19671
|
}
|
|
19846
|
-
function
|
|
19672
|
+
function Pill2({
|
|
19847
19673
|
label,
|
|
19848
19674
|
onClick,
|
|
19849
19675
|
disabled
|
|
19850
19676
|
}) {
|
|
19851
|
-
return /* @__PURE__ */ (0,
|
|
19677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19852
19678
|
"button",
|
|
19853
19679
|
{
|
|
19854
19680
|
type: "button",
|
|
@@ -19864,7 +19690,7 @@ function Pill({
|
|
|
19864
19690
|
border: "none",
|
|
19865
19691
|
cursor: disabled ? "default" : "pointer",
|
|
19866
19692
|
background: "#ffffff",
|
|
19867
|
-
color:
|
|
19693
|
+
color: OHW_BLUE_DARK2,
|
|
19868
19694
|
opacity: disabled ? 0.4 : 1,
|
|
19869
19695
|
fontSize: 12,
|
|
19870
19696
|
lineHeight: "16px",
|
|
@@ -19907,8 +19733,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19907
19733
|
onCommit(id);
|
|
19908
19734
|
}
|
|
19909
19735
|
};
|
|
19910
|
-
return /* @__PURE__ */ (0,
|
|
19911
|
-
/* @__PURE__ */ (0,
|
|
19736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
19737
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
19912
19738
|
"div",
|
|
19913
19739
|
{
|
|
19914
19740
|
style: {
|
|
@@ -19924,12 +19750,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19924
19750
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19925
19751
|
},
|
|
19926
19752
|
children: [
|
|
19927
|
-
/* @__PURE__ */ (0,
|
|
19753
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19928
19754
|
"span",
|
|
19929
19755
|
{
|
|
19930
19756
|
style: {
|
|
19931
19757
|
flex: "0 0 auto",
|
|
19932
|
-
color:
|
|
19758
|
+
color: OHW_BLUE_DARK2,
|
|
19933
19759
|
fontSize: 10,
|
|
19934
19760
|
lineHeight: "16px",
|
|
19935
19761
|
fontWeight: 700,
|
|
@@ -19939,7 +19765,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19939
19765
|
children: "Video"
|
|
19940
19766
|
}
|
|
19941
19767
|
),
|
|
19942
|
-
/* @__PURE__ */ (0,
|
|
19768
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19943
19769
|
"input",
|
|
19944
19770
|
{
|
|
19945
19771
|
type: "text",
|
|
@@ -19976,7 +19802,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19976
19802
|
]
|
|
19977
19803
|
}
|
|
19978
19804
|
),
|
|
19979
|
-
invalid && /* @__PURE__ */ (0,
|
|
19805
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime22.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." })
|
|
19980
19806
|
] });
|
|
19981
19807
|
}
|
|
19982
19808
|
function VideoToolbar({
|
|
@@ -19986,7 +19812,7 @@ function VideoToolbar({
|
|
|
19986
19812
|
onSetVideoId,
|
|
19987
19813
|
onRemove
|
|
19988
19814
|
}) {
|
|
19989
|
-
return /* @__PURE__ */ (0,
|
|
19815
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
19990
19816
|
"div",
|
|
19991
19817
|
{
|
|
19992
19818
|
"data-ohw-bridge": "",
|
|
@@ -19998,7 +19824,7 @@ function VideoToolbar({
|
|
|
19998
19824
|
gap: 6,
|
|
19999
19825
|
alignItems: "center",
|
|
20000
19826
|
width: 280,
|
|
20001
|
-
background:
|
|
19827
|
+
background: OHW_BLUE2,
|
|
20002
19828
|
padding: 8,
|
|
20003
19829
|
borderRadius: 12,
|
|
20004
19830
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20006,9 +19832,9 @@ function VideoToolbar({
|
|
|
20006
19832
|
opacity: pending ? 0.6 : 1
|
|
20007
19833
|
},
|
|
20008
19834
|
children: [
|
|
20009
|
-
/* @__PURE__ */ (0,
|
|
20010
|
-
/* @__PURE__ */ (0,
|
|
20011
|
-
error && /* @__PURE__ */ (0,
|
|
19835
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19836
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19837
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20012
19838
|
]
|
|
20013
19839
|
}
|
|
20014
19840
|
);
|
|
@@ -20128,8 +19954,8 @@ function AiVideoOverlay({
|
|
|
20128
19954
|
const activeBlockRect = useLiveBlockRect(active);
|
|
20129
19955
|
const TOOLBAR_APPROX_H = 90;
|
|
20130
19956
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20131
|
-
return /* @__PURE__ */ (0,
|
|
20132
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
19957
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
19958
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20133
19959
|
"button",
|
|
20134
19960
|
{
|
|
20135
19961
|
type: "button",
|
|
@@ -20157,15 +19983,15 @@ function AiVideoOverlay({
|
|
|
20157
19983
|
fontSize: 14,
|
|
20158
19984
|
fontWeight: 700
|
|
20159
19985
|
},
|
|
20160
|
-
children: /* @__PURE__ */ (0,
|
|
19986
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20161
19987
|
}
|
|
20162
19988
|
),
|
|
20163
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19989
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20164
19990
|
ItemInteractionLayer,
|
|
20165
19991
|
{
|
|
20166
19992
|
rect: activeBlockRect,
|
|
20167
19993
|
state: toolbarState,
|
|
20168
|
-
toolbar: /* @__PURE__ */ (0,
|
|
19994
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20169
19995
|
VideoToolbar,
|
|
20170
19996
|
{
|
|
20171
19997
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20189,7 +20015,7 @@ function AiVideoOverlay({
|
|
|
20189
20015
|
|
|
20190
20016
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20191
20017
|
var import_react13 = require("react");
|
|
20192
|
-
var
|
|
20018
|
+
var import_lucide_react11 = require("lucide-react");
|
|
20193
20019
|
|
|
20194
20020
|
// src/lib/ai-carousel-tree.ts
|
|
20195
20021
|
function isCarouselBlock(node) {
|
|
@@ -20240,10 +20066,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20240
20066
|
}
|
|
20241
20067
|
|
|
20242
20068
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20243
|
-
var
|
|
20069
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
20244
20070
|
var PRIMARY6 = "#0885FE";
|
|
20245
|
-
var
|
|
20246
|
-
var
|
|
20071
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
20072
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20247
20073
|
function findCarouselItemElement(sectionId, index) {
|
|
20248
20074
|
const sectionEl = findByInstanceId(sectionId);
|
|
20249
20075
|
if (!sectionEl) return null;
|
|
@@ -20322,8 +20148,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20322
20148
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20323
20149
|
});
|
|
20324
20150
|
}
|
|
20325
|
-
function
|
|
20326
|
-
return /* @__PURE__ */ (0,
|
|
20151
|
+
function Pill3({ label, onClick, disabled }) {
|
|
20152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20327
20153
|
"button",
|
|
20328
20154
|
{
|
|
20329
20155
|
type: "button",
|
|
@@ -20339,7 +20165,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20339
20165
|
border: "none",
|
|
20340
20166
|
cursor: disabled ? "default" : "pointer",
|
|
20341
20167
|
background: "#ffffff",
|
|
20342
|
-
color:
|
|
20168
|
+
color: OHW_BLUE_DARK3,
|
|
20343
20169
|
opacity: disabled ? 0.4 : 1,
|
|
20344
20170
|
fontSize: 12,
|
|
20345
20171
|
lineHeight: "16px",
|
|
@@ -20357,7 +20183,7 @@ function TogglePill({
|
|
|
20357
20183
|
onToggle,
|
|
20358
20184
|
disabled
|
|
20359
20185
|
}) {
|
|
20360
|
-
return /* @__PURE__ */ (0,
|
|
20186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20361
20187
|
"button",
|
|
20362
20188
|
{
|
|
20363
20189
|
type: "button",
|
|
@@ -20376,7 +20202,7 @@ function TogglePill({
|
|
|
20376
20202
|
border: "none",
|
|
20377
20203
|
cursor: disabled ? "default" : "pointer",
|
|
20378
20204
|
background: "#ffffff",
|
|
20379
|
-
color:
|
|
20205
|
+
color: OHW_BLUE_DARK3,
|
|
20380
20206
|
opacity: disabled ? 0.4 : 1,
|
|
20381
20207
|
fontSize: 12,
|
|
20382
20208
|
lineHeight: "16px",
|
|
@@ -20386,7 +20212,7 @@ function TogglePill({
|
|
|
20386
20212
|
},
|
|
20387
20213
|
children: [
|
|
20388
20214
|
label,
|
|
20389
|
-
/* @__PURE__ */ (0,
|
|
20215
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20390
20216
|
"span",
|
|
20391
20217
|
{
|
|
20392
20218
|
"aria-hidden": true,
|
|
@@ -20399,10 +20225,10 @@ function TogglePill({
|
|
|
20399
20225
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
20400
20226
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
20401
20227
|
// "disabled control" rather than "switch that is off".
|
|
20402
|
-
background: on ?
|
|
20228
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
20403
20229
|
transition: "background 120ms ease"
|
|
20404
20230
|
},
|
|
20405
|
-
children: /* @__PURE__ */ (0,
|
|
20231
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20406
20232
|
"span",
|
|
20407
20233
|
{
|
|
20408
20234
|
style: {
|
|
@@ -20431,7 +20257,7 @@ function CarouselSlideToolbar({
|
|
|
20431
20257
|
onChangeImage,
|
|
20432
20258
|
onToggleAutoplay
|
|
20433
20259
|
}) {
|
|
20434
|
-
return /* @__PURE__ */ (0,
|
|
20260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20435
20261
|
"div",
|
|
20436
20262
|
{
|
|
20437
20263
|
"data-ohw-bridge": "",
|
|
@@ -20442,7 +20268,7 @@ function CarouselSlideToolbar({
|
|
|
20442
20268
|
flexDirection: "column",
|
|
20443
20269
|
gap: 6,
|
|
20444
20270
|
alignItems: "center",
|
|
20445
|
-
background:
|
|
20271
|
+
background: OHW_BLUE3,
|
|
20446
20272
|
padding: 8,
|
|
20447
20273
|
borderRadius: 12,
|
|
20448
20274
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20454,11 +20280,11 @@ function CarouselSlideToolbar({
|
|
|
20454
20280
|
pointerEvents: pending ? "none" : "auto"
|
|
20455
20281
|
},
|
|
20456
20282
|
children: [
|
|
20457
|
-
/* @__PURE__ */ (0,
|
|
20458
|
-
/* @__PURE__ */ (0,
|
|
20459
|
-
/* @__PURE__ */ (0,
|
|
20283
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20284
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20285
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20460
20286
|
] }),
|
|
20461
|
-
error && /* @__PURE__ */ (0,
|
|
20287
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20462
20288
|
]
|
|
20463
20289
|
}
|
|
20464
20290
|
);
|
|
@@ -20598,8 +20424,8 @@ function AiFadeCarouselOverlay({
|
|
|
20598
20424
|
const activeItemRect = useLiveItemRect2(active);
|
|
20599
20425
|
const TOOLBAR_APPROX_H = 90;
|
|
20600
20426
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20601
|
-
return /* @__PURE__ */ (0,
|
|
20602
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
20428
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20603
20429
|
"button",
|
|
20604
20430
|
{
|
|
20605
20431
|
type: "button",
|
|
@@ -20628,10 +20454,10 @@ function AiFadeCarouselOverlay({
|
|
|
20628
20454
|
fontSize: 14,
|
|
20629
20455
|
fontWeight: 700
|
|
20630
20456
|
},
|
|
20631
|
-
children: /* @__PURE__ */ (0,
|
|
20457
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20632
20458
|
}
|
|
20633
20459
|
),
|
|
20634
|
-
swapping && /* @__PURE__ */ (0,
|
|
20460
|
+
swapping && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20635
20461
|
"div",
|
|
20636
20462
|
{
|
|
20637
20463
|
ref: skeletonRef,
|
|
@@ -20649,15 +20475,15 @@ function AiFadeCarouselOverlay({
|
|
|
20649
20475
|
zIndex: 2147483646,
|
|
20650
20476
|
pointerEvents: "none"
|
|
20651
20477
|
},
|
|
20652
|
-
children: /* @__PURE__ */ (0,
|
|
20478
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
20653
20479
|
}
|
|
20654
20480
|
),
|
|
20655
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20481
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20656
20482
|
ItemInteractionLayer,
|
|
20657
20483
|
{
|
|
20658
20484
|
rect: activeItemRect,
|
|
20659
20485
|
state: toolbarState,
|
|
20660
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20486
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20661
20487
|
CarouselSlideToolbar,
|
|
20662
20488
|
{
|
|
20663
20489
|
pending,
|
|
@@ -21010,6 +20836,113 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
21010
20836
|
// src/ui/link-modal/LinkPopover.tsx
|
|
21011
20837
|
var import_react17 = require("react");
|
|
21012
20838
|
|
|
20839
|
+
// src/ui/dialog.tsx
|
|
20840
|
+
var React9 = __toESM(require("react"), 1);
|
|
20841
|
+
var import_radix_ui6 = require("radix-ui");
|
|
20842
|
+
var import_lucide_react12 = require("lucide-react");
|
|
20843
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
20844
|
+
function Dialog2({
|
|
20845
|
+
...props
|
|
20846
|
+
}) {
|
|
20847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
20848
|
+
}
|
|
20849
|
+
function DialogPortal({
|
|
20850
|
+
...props
|
|
20851
|
+
}) {
|
|
20852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
20853
|
+
}
|
|
20854
|
+
function DialogOverlay({
|
|
20855
|
+
className,
|
|
20856
|
+
...props
|
|
20857
|
+
}) {
|
|
20858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
20859
|
+
import_radix_ui6.Dialog.Overlay,
|
|
20860
|
+
{
|
|
20861
|
+
"data-slot": "dialog-overlay",
|
|
20862
|
+
"data-ohw-link-modal-root": "",
|
|
20863
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
20864
|
+
...props
|
|
20865
|
+
}
|
|
20866
|
+
);
|
|
20867
|
+
}
|
|
20868
|
+
var DialogContent = React9.forwardRef(
|
|
20869
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
20870
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
20871
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
20872
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
20873
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
20874
|
+
import_radix_ui6.Dialog.Content,
|
|
20875
|
+
{
|
|
20876
|
+
ref,
|
|
20877
|
+
"data-slot": "dialog-content",
|
|
20878
|
+
className: cn(
|
|
20879
|
+
positionMode,
|
|
20880
|
+
"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",
|
|
20881
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
20882
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
20883
|
+
className
|
|
20884
|
+
),
|
|
20885
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
20886
|
+
...props,
|
|
20887
|
+
children: [
|
|
20888
|
+
children,
|
|
20889
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
20890
|
+
import_radix_ui6.Dialog.Close,
|
|
20891
|
+
{
|
|
20892
|
+
type: "button",
|
|
20893
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
20894
|
+
"aria-label": "Close",
|
|
20895
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
20896
|
+
}
|
|
20897
|
+
) : null
|
|
20898
|
+
]
|
|
20899
|
+
}
|
|
20900
|
+
)
|
|
20901
|
+
] });
|
|
20902
|
+
}
|
|
20903
|
+
);
|
|
20904
|
+
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
20905
|
+
function DialogHeader({
|
|
20906
|
+
className,
|
|
20907
|
+
...props
|
|
20908
|
+
}) {
|
|
20909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
20910
|
+
}
|
|
20911
|
+
function DialogFooter({
|
|
20912
|
+
className,
|
|
20913
|
+
...props
|
|
20914
|
+
}) {
|
|
20915
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
20916
|
+
"div",
|
|
20917
|
+
{
|
|
20918
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
20919
|
+
...props
|
|
20920
|
+
}
|
|
20921
|
+
);
|
|
20922
|
+
}
|
|
20923
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
20924
|
+
import_radix_ui6.Dialog.Title,
|
|
20925
|
+
{
|
|
20926
|
+
ref,
|
|
20927
|
+
className: cn(
|
|
20928
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
20929
|
+
className
|
|
20930
|
+
),
|
|
20931
|
+
...props
|
|
20932
|
+
}
|
|
20933
|
+
));
|
|
20934
|
+
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
20935
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
20936
|
+
import_radix_ui6.Dialog.Description,
|
|
20937
|
+
{
|
|
20938
|
+
ref,
|
|
20939
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
20940
|
+
...props
|
|
20941
|
+
}
|
|
20942
|
+
));
|
|
20943
|
+
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
20944
|
+
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
20945
|
+
|
|
21013
20946
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
21014
20947
|
var import_lucide_react16 = require("lucide-react");
|
|
21015
20948
|
|
|
@@ -22113,7 +22046,6 @@ function shouldUseDevFixtures() {
|
|
|
22113
22046
|
function getLogoElement(el) {
|
|
22114
22047
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
22115
22048
|
if (marked) return marked;
|
|
22116
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
22117
22049
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
22118
22050
|
if (!root) return null;
|
|
22119
22051
|
const anchor = el.closest("a");
|
|
@@ -24694,7 +24626,7 @@ function getNavigationSelectionParent(el) {
|
|
|
24694
24626
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
24695
24627
|
return resolveFooterLinksContainerFrom(el);
|
|
24696
24628
|
}
|
|
24697
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24629
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24698
24630
|
return getNavigationRoot(el);
|
|
24699
24631
|
}
|
|
24700
24632
|
return null;
|
|
@@ -24916,6 +24848,7 @@ var ICONS = {
|
|
|
24916
24848
|
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"/>',
|
|
24917
24849
|
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"/>'
|
|
24918
24850
|
};
|
|
24851
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
24919
24852
|
var SELECTION_CHROME_GAP2 = 4;
|
|
24920
24853
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
24921
24854
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -25013,7 +24946,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
25013
24946
|
el.style.top = `${top}px`;
|
|
25014
24947
|
el.style.height = `${height}px`;
|
|
25015
24948
|
}
|
|
25016
|
-
var
|
|
24949
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
25017
24950
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
25018
24951
|
const isAbove = transform.includes("translateY(-100%)");
|
|
25019
24952
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -25040,8 +24973,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
25040
24973
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
25041
24974
|
const half = toolbarWidth / 2;
|
|
25042
24975
|
return Math.max(
|
|
25043
|
-
|
|
25044
|
-
Math.min(centerX, window.innerWidth -
|
|
24976
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
24977
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
25045
24978
|
);
|
|
25046
24979
|
}
|
|
25047
24980
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -25893,6 +25826,21 @@ function OhhwellsBridge() {
|
|
|
25893
25826
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
25894
25827
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
25895
25828
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
25829
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
25830
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
25831
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
25832
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
25833
|
+
floatingPanelRef.current = floatingPanel;
|
|
25834
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
25835
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
25836
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
25837
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
25838
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
25839
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
25840
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
25841
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
25842
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
25843
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
25896
25844
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
25897
25845
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
25898
25846
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -25918,21 +25866,6 @@ function OhhwellsBridge() {
|
|
|
25918
25866
|
const stylesRef = (0, import_react21.useRef)("");
|
|
25919
25867
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
25920
25868
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
25921
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
25922
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
25923
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
25924
|
-
floatingPanelRef.current = floatingPanel;
|
|
25925
|
-
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
25926
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
25927
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
25928
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
25929
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
25930
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
25931
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
25932
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
25933
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
25934
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
25935
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
25936
25869
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
25937
25870
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
25938
25871
|
const sectionsPrefetchGenRef = (0, import_react21.useRef)(0);
|
|
@@ -25941,18 +25874,7 @@ function OhhwellsBridge() {
|
|
|
25941
25874
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
25942
25875
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
25943
25876
|
setLinkPopoverRef.current = setLinkPopover;
|
|
25944
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
25945
25877
|
linkPopoverSessionRef.current = linkPopover;
|
|
25946
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
25947
|
-
(0, import_react21.useEffect)(() => {
|
|
25948
|
-
const syncViewport = () => {
|
|
25949
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
25950
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
25951
|
-
};
|
|
25952
|
-
syncViewport();
|
|
25953
|
-
window.addEventListener("resize", syncViewport);
|
|
25954
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
25955
|
-
}, []);
|
|
25956
25878
|
(0, import_react21.useEffect)(() => {
|
|
25957
25879
|
setSectionOrderPersistHandler((entries) => {
|
|
25958
25880
|
const currentPath = window.location.pathname;
|
|
@@ -27647,7 +27569,6 @@ function OhhwellsBridge() {
|
|
|
27647
27569
|
applyAiFooterFromContent(content);
|
|
27648
27570
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27649
27571
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
27650
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27651
27572
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27652
27573
|
}
|
|
27653
27574
|
applyBrandChrome(content);
|
|
@@ -27658,12 +27579,12 @@ function OhhwellsBridge() {
|
|
|
27658
27579
|
if (key === "__ohw_sections") continue;
|
|
27659
27580
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27660
27581
|
if (key === AI_FOOTER_KEY) continue;
|
|
27661
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27662
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27663
27582
|
if (key === BRAND_KIT_KEY) continue;
|
|
27664
27583
|
if (key === STYLE_STORE_KEY) continue;
|
|
27665
27584
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27585
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27666
27586
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27587
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27667
27588
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27668
27589
|
continue;
|
|
27669
27590
|
}
|
|
@@ -27879,18 +27800,17 @@ function OhhwellsBridge() {
|
|
|
27879
27800
|
}
|
|
27880
27801
|
applyAiFooterFromContent(content);
|
|
27881
27802
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27882
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27883
27803
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27884
27804
|
}
|
|
27885
27805
|
for (const [key, val] of Object.entries(content)) {
|
|
27886
27806
|
if (key === "__ohw_sections") continue;
|
|
27887
27807
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27888
27808
|
if (key === AI_FOOTER_KEY) continue;
|
|
27889
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27890
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27891
27809
|
if (key === BRAND_KIT_KEY) continue;
|
|
27892
27810
|
if (key === STYLE_STORE_KEY) continue;
|
|
27893
27811
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27812
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27813
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27894
27814
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27895
27815
|
continue;
|
|
27896
27816
|
}
|
|
@@ -28157,11 +28077,26 @@ function OhhwellsBridge() {
|
|
|
28157
28077
|
const t2 = setTimeout(measure, 500);
|
|
28158
28078
|
const ro = new ResizeObserver(schedule);
|
|
28159
28079
|
ro.observe(document.body);
|
|
28080
|
+
let lastWidth = window.innerWidth;
|
|
28081
|
+
let resizeTimers = [];
|
|
28082
|
+
const clearResizeTimers = () => {
|
|
28083
|
+
resizeTimers.forEach(clearTimeout);
|
|
28084
|
+
resizeTimers = [];
|
|
28085
|
+
};
|
|
28086
|
+
const handleResize = () => {
|
|
28087
|
+
if (window.innerWidth === lastWidth) return;
|
|
28088
|
+
lastWidth = window.innerWidth;
|
|
28089
|
+
clearResizeTimers();
|
|
28090
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
28091
|
+
};
|
|
28092
|
+
window.addEventListener("resize", handleResize);
|
|
28160
28093
|
return () => {
|
|
28161
28094
|
clearTimeout(t1);
|
|
28162
28095
|
clearTimeout(t2);
|
|
28163
28096
|
if (raf != null) cancelAnimationFrame(raf);
|
|
28164
28097
|
ro.disconnect();
|
|
28098
|
+
clearResizeTimers();
|
|
28099
|
+
window.removeEventListener("resize", handleResize);
|
|
28165
28100
|
};
|
|
28166
28101
|
}, [pathname, isEditMode, postToParent2]);
|
|
28167
28102
|
(0, import_react21.useEffect)(() => {
|
|
@@ -28458,13 +28393,6 @@ function OhhwellsBridge() {
|
|
|
28458
28393
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28459
28394
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28460
28395
|
if (isInsideLinkEditor(target)) return;
|
|
28461
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28462
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28463
|
-
if (target.closest(
|
|
28464
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28465
|
-
)) {
|
|
28466
|
-
return;
|
|
28467
|
-
}
|
|
28468
28396
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28469
28397
|
clearMediaSelectionRef.current();
|
|
28470
28398
|
}
|
|
@@ -28488,6 +28416,13 @@ function OhhwellsBridge() {
|
|
|
28488
28416
|
return;
|
|
28489
28417
|
}
|
|
28490
28418
|
}
|
|
28419
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28420
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28421
|
+
if (target.closest(
|
|
28422
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28423
|
+
)) {
|
|
28424
|
+
return;
|
|
28425
|
+
}
|
|
28491
28426
|
{
|
|
28492
28427
|
const formEl = getFormElement(target);
|
|
28493
28428
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -28641,13 +28576,9 @@ function OhhwellsBridge() {
|
|
|
28641
28576
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
28642
28577
|
e.preventDefault();
|
|
28643
28578
|
e.stopPropagation();
|
|
28579
|
+
selectIconElementRef.current(editable);
|
|
28644
28580
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
28645
28581
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
28646
|
-
if (aiIcon) {
|
|
28647
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
28648
|
-
} else {
|
|
28649
|
-
selectIconElementRef.current(editable);
|
|
28650
|
-
}
|
|
28651
28582
|
postToParentRef.current({
|
|
28652
28583
|
type: "ow:icon-pick",
|
|
28653
28584
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -28875,9 +28806,6 @@ function OhhwellsBridge() {
|
|
|
28875
28806
|
setHoveredItemRect(null);
|
|
28876
28807
|
hoveredNavContainerRef.current = null;
|
|
28877
28808
|
setHoveredNavContainerRect(null);
|
|
28878
|
-
siblingHintElRef.current = null;
|
|
28879
|
-
setSiblingHintRect(null);
|
|
28880
|
-
setSiblingHintRects([]);
|
|
28881
28809
|
return;
|
|
28882
28810
|
}
|
|
28883
28811
|
{
|
|
@@ -28998,6 +28926,7 @@ function OhhwellsBridge() {
|
|
|
28998
28926
|
hoveredNavContainerRef.current = null;
|
|
28999
28927
|
setHoveredNavContainerRect(null);
|
|
29000
28928
|
hoveredItemElRef.current = editable;
|
|
28929
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
29001
28930
|
}
|
|
29002
28931
|
}
|
|
29003
28932
|
}
|
|
@@ -29707,11 +29636,7 @@ function OhhwellsBridge() {
|
|
|
29707
29636
|
};
|
|
29708
29637
|
const handleMouseMove = (e) => {
|
|
29709
29638
|
const { clientX, clientY } = e;
|
|
29710
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29711
|
-
dismissImageHover();
|
|
29712
|
-
clearImageHover();
|
|
29713
|
-
return;
|
|
29714
|
-
}
|
|
29639
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29715
29640
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
29716
29641
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
29717
29642
|
formHoverElRef.current = null;
|
|
@@ -29740,12 +29665,7 @@ function OhhwellsBridge() {
|
|
|
29740
29665
|
setHoveredItemRect(null);
|
|
29741
29666
|
hoveredNavContainerRef.current = null;
|
|
29742
29667
|
setHoveredNavContainerRect(null);
|
|
29743
|
-
siblingHintElRef.current = null;
|
|
29744
|
-
setSiblingHintRect(null);
|
|
29745
|
-
setSiblingHintRects([]);
|
|
29746
29668
|
dismissImageHover();
|
|
29747
|
-
clearImageHover();
|
|
29748
|
-
setSectionGap(null);
|
|
29749
29669
|
return;
|
|
29750
29670
|
}
|
|
29751
29671
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -29757,11 +29677,7 @@ function OhhwellsBridge() {
|
|
|
29757
29677
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
29758
29678
|
const { clientX, clientY } = e.data;
|
|
29759
29679
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
29760
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29761
|
-
dismissImageHover();
|
|
29762
|
-
clearImageHover();
|
|
29763
|
-
return;
|
|
29764
|
-
}
|
|
29680
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29765
29681
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
29766
29682
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
29767
29683
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -30141,7 +30057,6 @@ function OhhwellsBridge() {
|
|
|
30141
30057
|
applyAiFooterFromContent(content);
|
|
30142
30058
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
30143
30059
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
30144
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
30145
30060
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
30146
30061
|
}
|
|
30147
30062
|
applyBrandChrome(content);
|
|
@@ -30156,12 +30071,12 @@ function OhhwellsBridge() {
|
|
|
30156
30071
|
}
|
|
30157
30072
|
if (key === AI_SECTIONS_KEY) continue;
|
|
30158
30073
|
if (key === AI_FOOTER_KEY) continue;
|
|
30159
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30160
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30161
30074
|
if (key === BRAND_KIT_KEY) continue;
|
|
30162
30075
|
if (key === STYLE_STORE_KEY) continue;
|
|
30163
30076
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
30077
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30164
30078
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
30079
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30165
30080
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
30166
30081
|
continue;
|
|
30167
30082
|
}
|
|
@@ -30797,12 +30712,6 @@ function OhhwellsBridge() {
|
|
|
30797
30712
|
closeLinkPopoverRef.current();
|
|
30798
30713
|
return;
|
|
30799
30714
|
}
|
|
30800
|
-
if (floatingPanelOpenRef.current) {
|
|
30801
|
-
setFloatingPanelRef.current(null);
|
|
30802
|
-
deselectRef.current();
|
|
30803
|
-
deactivateRef.current();
|
|
30804
|
-
return;
|
|
30805
|
-
}
|
|
30806
30715
|
deselectRef.current();
|
|
30807
30716
|
deactivateRef.current();
|
|
30808
30717
|
clearMediaSelectionRef.current();
|
|
@@ -31625,10 +31534,10 @@ function OhhwellsBridge() {
|
|
|
31625
31534
|
window.removeEventListener("message", handleDeleteSection);
|
|
31626
31535
|
window.removeEventListener("message", handleDuplicateSection);
|
|
31627
31536
|
window.removeEventListener("message", handleDeactivate);
|
|
31537
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31628
31538
|
window.removeEventListener("message", handleToastAction);
|
|
31629
31539
|
window.removeEventListener("message", handleFormCount);
|
|
31630
31540
|
window.removeEventListener("message", handleUiEscape);
|
|
31631
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31632
31541
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
31633
31542
|
autoSaveTimers.current.clear();
|
|
31634
31543
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -31922,7 +31831,7 @@ function OhhwellsBridge() {
|
|
|
31922
31831
|
postToParent2({
|
|
31923
31832
|
type: "ow:ready",
|
|
31924
31833
|
version: "1",
|
|
31925
|
-
bridgeVersion: "0.1.
|
|
31834
|
+
bridgeVersion: "0.1.152",
|
|
31926
31835
|
path: pathname,
|
|
31927
31836
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31928
31837
|
sections
|