@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.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as
|
|
4
|
+
import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as useLayoutEffect6, useRef as useRef14, useState as useState18 } from "react";
|
|
5
5
|
import { createRoot as createRoot3 } from "react-dom/client";
|
|
6
6
|
import { flushSync as flushSync3 } from "react-dom";
|
|
7
7
|
|
|
@@ -6542,21 +6542,6 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6542
6542
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6543
6543
|
return target ? pricingFeatureList(target).length : 0;
|
|
6544
6544
|
}
|
|
6545
|
-
function prevailingFeatureIcon(features) {
|
|
6546
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6547
|
-
for (const row of features) {
|
|
6548
|
-
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6549
|
-
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6550
|
-
entry.count += 1;
|
|
6551
|
-
counts.set(key, entry);
|
|
6552
|
-
}
|
|
6553
|
-
let best = null;
|
|
6554
|
-
for (const entry of counts.values()) {
|
|
6555
|
-
if (!best || entry.count > best.count) best = entry;
|
|
6556
|
-
}
|
|
6557
|
-
if (!best) return {};
|
|
6558
|
-
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6559
|
-
}
|
|
6560
6545
|
function addPricingCardFeature(tree, index, text) {
|
|
6561
6546
|
return withPricingCollection(tree, (collection) => {
|
|
6562
6547
|
const children = collection.children;
|
|
@@ -6565,7 +6550,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6565
6550
|
const features = pricingFeatureList(target);
|
|
6566
6551
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6567
6552
|
target.slots = target.slots ?? {};
|
|
6568
|
-
target.slots.features = [...features, { text
|
|
6553
|
+
target.slots.features = [...features, { text }];
|
|
6569
6554
|
return true;
|
|
6570
6555
|
});
|
|
6571
6556
|
}
|
|
@@ -7749,7 +7734,7 @@ var AI_MOBILE_CSS = [
|
|
|
7749
7734
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7750
7735
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7751
7736
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7752
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7737
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
7753
7738
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7754
7739
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7755
7740
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7765,10 +7750,8 @@ var AI_MOBILE_CSS = [
|
|
|
7765
7750
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7766
7751
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7767
7752
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7768
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7769
|
-
|
|
7770
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7771
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7753
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7754
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7772
7755
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7773
7756
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7774
7757
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -7973,31 +7956,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
7973
7956
|
function textAttrs(ctx, path) {
|
|
7974
7957
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
7975
7958
|
}
|
|
7976
|
-
var AI_RESPONSIVE_CSS = [
|
|
7977
|
-
"@media (max-width: 960px) {",
|
|
7978
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
7979
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
7980
|
-
"}",
|
|
7981
|
-
"@media (max-width: 640px) {",
|
|
7982
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
7983
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
7984
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
7985
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
7986
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
7987
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
7988
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
7989
|
-
// layered text used to be.
|
|
7990
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
7991
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
7992
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
7993
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
7994
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
7995
|
-
// other rule had already been taught to stand down.
|
|
7996
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
7997
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
7998
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
7999
|
-
"}"
|
|
8000
|
-
].join("\n");
|
|
8001
7959
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8002
7960
|
function MediaBox({
|
|
8003
7961
|
refValue,
|
|
@@ -8052,7 +8010,7 @@ function MediaBox({
|
|
|
8052
8010
|
position: fill ? "absolute" : void 0,
|
|
8053
8011
|
inset: fill ? 0 : void 0,
|
|
8054
8012
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8055
|
-
height: fill ? "100%" :
|
|
8013
|
+
height: fill ? "100%" : void 0,
|
|
8056
8014
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8057
8015
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8058
8016
|
borderRadius: radius,
|
|
@@ -9548,7 +9506,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9548
9506
|
return /* @__PURE__ */ jsx(
|
|
9549
9507
|
"div",
|
|
9550
9508
|
{
|
|
9551
|
-
"data-ai-grid":
|
|
9509
|
+
"data-ai-grid": "",
|
|
9552
9510
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9553
9511
|
style: {
|
|
9554
9512
|
display: "grid",
|
|
@@ -9850,7 +9808,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9850
9808
|
},
|
|
9851
9809
|
children: [
|
|
9852
9810
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
9853
|
-
// The section's `data-ai-
|
|
9811
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
9854
9812
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9855
9813
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9856
9814
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10269,7 +10227,6 @@ function AiTreeRenderer({
|
|
|
10269
10227
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10270
10228
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10271
10229
|
...bgAttrs,
|
|
10272
|
-
"data-ai-responsive": "",
|
|
10273
10230
|
style: {
|
|
10274
10231
|
position: "relative",
|
|
10275
10232
|
padding: `${padCss} 0`,
|
|
@@ -10283,13 +10240,12 @@ function AiTreeRenderer({
|
|
|
10283
10240
|
...fillHeight ? { display: "grid" } : {}
|
|
10284
10241
|
},
|
|
10285
10242
|
children: [
|
|
10286
|
-
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
10287
|
-
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10288
10243
|
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10244
|
+
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10289
10245
|
/* @__PURE__ */ jsx(
|
|
10290
10246
|
"div",
|
|
10291
10247
|
{
|
|
10292
|
-
"data-ai-
|
|
10248
|
+
"data-ai-container": "",
|
|
10293
10249
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10294
10250
|
style: {
|
|
10295
10251
|
position: "relative",
|
|
@@ -10306,7 +10262,7 @@ function AiTreeRenderer({
|
|
|
10306
10262
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
10307
10263
|
"div",
|
|
10308
10264
|
{
|
|
10309
|
-
"data-ai-
|
|
10265
|
+
"data-ai-row": "",
|
|
10310
10266
|
style: {
|
|
10311
10267
|
display: "grid",
|
|
10312
10268
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -10968,10 +10924,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10968
10924
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
10969
10925
|
continue;
|
|
10970
10926
|
}
|
|
10927
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
10971
10928
|
let container = existing?.container;
|
|
10972
|
-
let isNewMount = false;
|
|
10973
10929
|
if (!container || !container.isConnected) {
|
|
10974
|
-
isNewMount = true;
|
|
10975
10930
|
existing?.root.unmount();
|
|
10976
10931
|
container?.remove();
|
|
10977
10932
|
container = document.createElement("div");
|
|
@@ -17555,7 +17510,6 @@ function MediaOverlay({
|
|
|
17555
17510
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
17556
17511
|
);
|
|
17557
17512
|
}, [isVideo]);
|
|
17558
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
17559
17513
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
17560
17514
|
const box = {
|
|
17561
17515
|
position: "fixed",
|
|
@@ -17654,10 +17608,11 @@ function MediaOverlay({
|
|
|
17654
17608
|
className: "flex items-center justify-center cursor-pointer",
|
|
17655
17609
|
style: {
|
|
17656
17610
|
...box,
|
|
17657
|
-
//
|
|
17658
|
-
//
|
|
17659
|
-
//
|
|
17660
|
-
|
|
17611
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
17612
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
17613
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
17614
|
+
// Replace still works.
|
|
17615
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
17661
17616
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
17662
17617
|
// than hovered. Hover keeps the existing tinted preview.
|
|
17663
17618
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -17684,17 +17639,17 @@ function MediaOverlay({
|
|
|
17684
17639
|
},
|
|
17685
17640
|
children: [
|
|
17686
17641
|
isVideo ? /* @__PURE__ */ jsx17(Film, { size: 14 }) : /* @__PURE__ */ jsx17(ImageIcon, { size: 14 }),
|
|
17687
|
-
|
|
17642
|
+
isVideo ? "Replace video" : "Replace image"
|
|
17688
17643
|
]
|
|
17689
17644
|
}
|
|
17690
17645
|
),
|
|
17691
|
-
|
|
17646
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ jsxs8(
|
|
17692
17647
|
Button,
|
|
17693
17648
|
{
|
|
17694
17649
|
"data-ohw-media-overlay": "",
|
|
17695
17650
|
variant: "outline",
|
|
17696
17651
|
size: "sm",
|
|
17697
|
-
"aria-label":
|
|
17652
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
17698
17653
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
17699
17654
|
style: {
|
|
17700
17655
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -17717,7 +17672,7 @@ function MediaOverlay({
|
|
|
17717
17672
|
},
|
|
17718
17673
|
children: [
|
|
17719
17674
|
isVideo ? /* @__PURE__ */ jsx17(Film, { size: 14 }) : /* @__PURE__ */ jsx17(ImageIcon, { size: 14 }),
|
|
17720
|
-
replaceMode === "full" ?
|
|
17675
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
17721
17676
|
]
|
|
17722
17677
|
}
|
|
17723
17678
|
)
|
|
@@ -18226,24 +18181,8 @@ function AiSectionOverlay({
|
|
|
18226
18181
|
}
|
|
18227
18182
|
|
|
18228
18183
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18229
|
-
import { useCallback as useCallback3, useEffect as useEffect6,
|
|
18230
|
-
import {
|
|
18231
|
-
AlignCenter,
|
|
18232
|
-
AlignLeft,
|
|
18233
|
-
AlignRight,
|
|
18234
|
-
ArrowLeft as ArrowLeft2,
|
|
18235
|
-
ArrowRight as ArrowRight2,
|
|
18236
|
-
Check as Check2,
|
|
18237
|
-
ChevronDown as ChevronDown3,
|
|
18238
|
-
Image as ImageIcon2,
|
|
18239
|
-
ImageMinus,
|
|
18240
|
-
ImagePlus,
|
|
18241
|
-
Link as LinkIcon,
|
|
18242
|
-
Minus,
|
|
18243
|
-
Palette,
|
|
18244
|
-
Plus as Plus2,
|
|
18245
|
-
Star
|
|
18246
|
-
} from "lucide-react";
|
|
18184
|
+
import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef5, useState as useState8 } from "react";
|
|
18185
|
+
import { Star } from "lucide-react";
|
|
18247
18186
|
|
|
18248
18187
|
// src/lib/ai-media-strip-tree.ts
|
|
18249
18188
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18357,6 +18296,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18357
18296
|
return true;
|
|
18358
18297
|
});
|
|
18359
18298
|
}
|
|
18299
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18300
|
+
return withMediaStrip(tree, (block) => {
|
|
18301
|
+
const items = block.items;
|
|
18302
|
+
if (index < 0 || index >= items.length) return false;
|
|
18303
|
+
items[index] = { ...items[index], alt };
|
|
18304
|
+
return true;
|
|
18305
|
+
});
|
|
18306
|
+
}
|
|
18360
18307
|
function setMediaStripItemLink(tree, index, link) {
|
|
18361
18308
|
return withMediaStrip(tree, (block) => {
|
|
18362
18309
|
const items = block.items;
|
|
@@ -18374,117 +18321,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18374
18321
|
});
|
|
18375
18322
|
}
|
|
18376
18323
|
|
|
18377
|
-
// src/ui/dialog.tsx
|
|
18378
|
-
import * as React9 from "react";
|
|
18379
|
-
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
18380
|
-
import { X as X2 } from "lucide-react";
|
|
18381
|
-
import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
18382
|
-
function Dialog2({
|
|
18383
|
-
...props
|
|
18384
|
-
}) {
|
|
18385
|
-
return /* @__PURE__ */ jsx20(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
18386
|
-
}
|
|
18387
|
-
function DialogPortal({
|
|
18388
|
-
...props
|
|
18389
|
-
}) {
|
|
18390
|
-
return /* @__PURE__ */ jsx20(DialogPrimitive.Portal, { ...props });
|
|
18391
|
-
}
|
|
18392
|
-
function DialogOverlay({
|
|
18393
|
-
className,
|
|
18394
|
-
...props
|
|
18395
|
-
}) {
|
|
18396
|
-
return /* @__PURE__ */ jsx20(
|
|
18397
|
-
DialogPrimitive.Overlay,
|
|
18398
|
-
{
|
|
18399
|
-
"data-slot": "dialog-overlay",
|
|
18400
|
-
"data-ohw-link-modal-root": "",
|
|
18401
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18402
|
-
...props
|
|
18403
|
-
}
|
|
18404
|
-
);
|
|
18405
|
-
}
|
|
18406
|
-
var DialogContent = React9.forwardRef(
|
|
18407
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18408
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
18409
|
-
return /* @__PURE__ */ jsxs11(DialogPortal, { container: container ?? void 0, children: [
|
|
18410
|
-
/* @__PURE__ */ jsx20(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18411
|
-
/* @__PURE__ */ jsxs11(
|
|
18412
|
-
DialogPrimitive.Content,
|
|
18413
|
-
{
|
|
18414
|
-
ref,
|
|
18415
|
-
"data-slot": "dialog-content",
|
|
18416
|
-
className: cn(
|
|
18417
|
-
positionMode,
|
|
18418
|
-
"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",
|
|
18419
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18420
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18421
|
-
className
|
|
18422
|
-
),
|
|
18423
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
18424
|
-
...props,
|
|
18425
|
-
children: [
|
|
18426
|
-
children,
|
|
18427
|
-
showCloseButton ? /* @__PURE__ */ jsx20(
|
|
18428
|
-
DialogPrimitive.Close,
|
|
18429
|
-
{
|
|
18430
|
-
type: "button",
|
|
18431
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18432
|
-
"aria-label": "Close",
|
|
18433
|
-
children: /* @__PURE__ */ jsx20(X2, { size: 16, "aria-hidden": true })
|
|
18434
|
-
}
|
|
18435
|
-
) : null
|
|
18436
|
-
]
|
|
18437
|
-
}
|
|
18438
|
-
)
|
|
18439
|
-
] });
|
|
18440
|
-
}
|
|
18441
|
-
);
|
|
18442
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
18443
|
-
function DialogHeader({
|
|
18444
|
-
className,
|
|
18445
|
-
...props
|
|
18446
|
-
}) {
|
|
18447
|
-
return /* @__PURE__ */ jsx20("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18448
|
-
}
|
|
18449
|
-
function DialogFooter({
|
|
18450
|
-
className,
|
|
18451
|
-
...props
|
|
18452
|
-
}) {
|
|
18453
|
-
return /* @__PURE__ */ jsx20(
|
|
18454
|
-
"div",
|
|
18455
|
-
{
|
|
18456
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
18457
|
-
...props
|
|
18458
|
-
}
|
|
18459
|
-
);
|
|
18460
|
-
}
|
|
18461
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
|
|
18462
|
-
DialogPrimitive.Title,
|
|
18463
|
-
{
|
|
18464
|
-
ref,
|
|
18465
|
-
className: cn(
|
|
18466
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18467
|
-
className
|
|
18468
|
-
),
|
|
18469
|
-
...props
|
|
18470
|
-
}
|
|
18471
|
-
));
|
|
18472
|
-
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
18473
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
|
|
18474
|
-
DialogPrimitive.Description,
|
|
18475
|
-
{
|
|
18476
|
-
ref,
|
|
18477
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
18478
|
-
...props
|
|
18479
|
-
}
|
|
18480
|
-
));
|
|
18481
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
18482
|
-
var DialogClose = DialogPrimitive.Close;
|
|
18483
|
-
|
|
18484
18324
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18485
|
-
import { Fragment as Fragment7, jsx as
|
|
18486
|
-
var PRIMARY3 = "
|
|
18487
|
-
var
|
|
18325
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
18326
|
+
var PRIMARY3 = "#0885FE";
|
|
18327
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18328
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
18488
18329
|
function findMediaStripItemElement(sectionId, index) {
|
|
18489
18330
|
const sectionEl = findByInstanceId(sectionId);
|
|
18490
18331
|
if (!sectionEl) return null;
|
|
@@ -18494,35 +18335,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18494
18335
|
}
|
|
18495
18336
|
return null;
|
|
18496
18337
|
}
|
|
18497
|
-
function
|
|
18498
|
-
|
|
18499
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18500
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18501
|
-
if (!itemEl) return null;
|
|
18502
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18503
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18504
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18505
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18506
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
18507
|
-
return { sectionId, index };
|
|
18508
|
-
}
|
|
18509
|
-
function sameRef(a, b) {
|
|
18510
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18511
|
-
}
|
|
18512
|
-
function rectOf(el) {
|
|
18338
|
+
function readRect2(ref) {
|
|
18339
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18513
18340
|
if (!el) return null;
|
|
18514
18341
|
const r2 = el.getBoundingClientRect();
|
|
18515
18342
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18516
18343
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18517
18344
|
}
|
|
18518
|
-
function
|
|
18519
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18520
|
-
}
|
|
18521
|
-
function readStripRect(ref) {
|
|
18522
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18523
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18524
|
-
}
|
|
18525
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18345
|
+
function useLiveItemRect(ref) {
|
|
18526
18346
|
const [rect, setRect] = useState8(null);
|
|
18527
18347
|
useEffect6(() => {
|
|
18528
18348
|
if (!ref) {
|
|
@@ -18530,7 +18350,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18530
18350
|
return;
|
|
18531
18351
|
}
|
|
18532
18352
|
const update = () => {
|
|
18533
|
-
const next =
|
|
18353
|
+
const next = readRect2(ref);
|
|
18534
18354
|
setRect(
|
|
18535
18355
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18536
18356
|
);
|
|
@@ -18545,49 +18365,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18545
18365
|
window.removeEventListener("resize", update);
|
|
18546
18366
|
clearInterval(interval);
|
|
18547
18367
|
};
|
|
18548
|
-
}, [ref?.sectionId, ref?.index
|
|
18368
|
+
}, [ref?.sectionId, ref?.index]);
|
|
18549
18369
|
return rect;
|
|
18550
18370
|
}
|
|
18551
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
18552
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18553
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18554
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
18555
|
-
const slotRef = useRef5(null);
|
|
18556
|
-
const [shift, setShift] = useState8(0);
|
|
18557
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
18558
|
-
useLayoutEffect4(() => {
|
|
18559
|
-
const slot = slotRef.current;
|
|
18560
|
-
if (!slot) return;
|
|
18561
|
-
const clamp = () => {
|
|
18562
|
-
const w = slot.offsetWidth;
|
|
18563
|
-
if (w <= 0) return;
|
|
18564
|
-
const half = w / 2;
|
|
18565
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18566
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18567
|
-
};
|
|
18568
|
-
clamp();
|
|
18569
|
-
const ro = new ResizeObserver(clamp);
|
|
18570
|
-
ro.observe(slot);
|
|
18571
|
-
return () => ro.disconnect();
|
|
18572
|
-
}, [centerX, children]);
|
|
18573
|
-
const mobile = window.innerWidth <= 480;
|
|
18574
|
-
return /* @__PURE__ */ jsx21(
|
|
18575
|
-
"div",
|
|
18576
|
-
{
|
|
18577
|
-
ref: slotRef,
|
|
18578
|
-
"data-ohw-bridge": "",
|
|
18579
|
-
"data-ohw-item-interaction": "",
|
|
18580
|
-
className: "pointer-events-auto fixed",
|
|
18581
|
-
style: {
|
|
18582
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18583
|
-
left: centerX + shift,
|
|
18584
|
-
transform: "translate(-50%, -100%)",
|
|
18585
|
-
zIndex: 2147483645
|
|
18586
|
-
},
|
|
18587
|
-
children
|
|
18588
|
-
}
|
|
18589
|
-
);
|
|
18590
|
-
}
|
|
18591
18371
|
function requestValidateTree(postToParent2, tree) {
|
|
18592
18372
|
return new Promise((resolve) => {
|
|
18593
18373
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18624,72 +18404,116 @@ function requestAssetPick(postToParent2) {
|
|
|
18624
18404
|
postToParent2({ type: "ow:asset-pick", id });
|
|
18625
18405
|
});
|
|
18626
18406
|
}
|
|
18627
|
-
function
|
|
18407
|
+
function Pill({
|
|
18628
18408
|
label,
|
|
18629
18409
|
onClick,
|
|
18630
|
-
disabled
|
|
18631
|
-
active
|
|
18632
|
-
children
|
|
18410
|
+
disabled,
|
|
18411
|
+
active
|
|
18633
18412
|
}) {
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18641
|
-
|
|
18413
|
+
return /* @__PURE__ */ jsx20(
|
|
18414
|
+
"button",
|
|
18415
|
+
{
|
|
18416
|
+
type: "button",
|
|
18417
|
+
onClick,
|
|
18418
|
+
disabled,
|
|
18419
|
+
style: {
|
|
18420
|
+
height: 28,
|
|
18421
|
+
padding: "0 10px",
|
|
18422
|
+
display: "inline-flex",
|
|
18423
|
+
alignItems: "center",
|
|
18424
|
+
gap: 4,
|
|
18425
|
+
borderRadius: 999,
|
|
18426
|
+
border: "none",
|
|
18427
|
+
cursor: disabled ? "default" : "pointer",
|
|
18428
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18429
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18430
|
+
opacity: disabled ? 0.4 : 1,
|
|
18431
|
+
fontSize: 12,
|
|
18432
|
+
lineHeight: "16px",
|
|
18433
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18434
|
+
whiteSpace: "nowrap",
|
|
18435
|
+
flex: "0 0 auto"
|
|
18436
|
+
},
|
|
18437
|
+
children: label
|
|
18438
|
+
}
|
|
18439
|
+
);
|
|
18642
18440
|
}
|
|
18643
|
-
function
|
|
18644
|
-
|
|
18645
|
-
value,
|
|
18646
|
-
|
|
18647
|
-
|
|
18648
|
-
|
|
18649
|
-
|
|
18650
|
-
|
|
18651
|
-
|
|
18652
|
-
|
|
18653
|
-
|
|
18654
|
-
"
|
|
18655
|
-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
) }),
|
|
18665
|
-
/* @__PURE__ */ jsx21(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
18666
|
-
const selected = option.value === value;
|
|
18667
|
-
return /* @__PURE__ */ jsxs12(
|
|
18668
|
-
DropdownMenuItem,
|
|
18441
|
+
function AltInput({ value, onCommit }) {
|
|
18442
|
+
const [draft, setDraft] = useState8(value);
|
|
18443
|
+
useEffect6(() => setDraft(value), [value]);
|
|
18444
|
+
return /* @__PURE__ */ jsxs11(
|
|
18445
|
+
"div",
|
|
18446
|
+
{
|
|
18447
|
+
style: {
|
|
18448
|
+
display: "flex",
|
|
18449
|
+
alignItems: "center",
|
|
18450
|
+
gap: 6,
|
|
18451
|
+
height: 28,
|
|
18452
|
+
padding: "0 12px",
|
|
18453
|
+
borderRadius: 999,
|
|
18454
|
+
background: "#ffffff",
|
|
18455
|
+
width: "100%",
|
|
18456
|
+
maxWidth: 260,
|
|
18457
|
+
boxSizing: "border-box"
|
|
18458
|
+
},
|
|
18459
|
+
children: [
|
|
18460
|
+
/* @__PURE__ */ jsx20(
|
|
18461
|
+
"span",
|
|
18669
18462
|
{
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
)
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
|
|
18463
|
+
style: {
|
|
18464
|
+
flex: "0 0 auto",
|
|
18465
|
+
color: OHW_BLUE_DARK,
|
|
18466
|
+
fontSize: 10,
|
|
18467
|
+
fontWeight: 700,
|
|
18468
|
+
textTransform: "uppercase",
|
|
18469
|
+
letterSpacing: 0.4
|
|
18470
|
+
},
|
|
18471
|
+
children: "Alt"
|
|
18472
|
+
}
|
|
18473
|
+
),
|
|
18474
|
+
/* @__PURE__ */ jsx20(
|
|
18475
|
+
"input",
|
|
18476
|
+
{
|
|
18477
|
+
type: "text",
|
|
18478
|
+
value: draft,
|
|
18479
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18480
|
+
onBlur: () => {
|
|
18481
|
+
if (draft !== value) onCommit(draft);
|
|
18482
|
+
},
|
|
18483
|
+
onKeyDown: (e) => {
|
|
18484
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18485
|
+
if (e.key === "Escape") {
|
|
18486
|
+
setDraft(value);
|
|
18487
|
+
e.currentTarget.blur();
|
|
18488
|
+
}
|
|
18489
|
+
},
|
|
18490
|
+
placeholder: "Describe this image",
|
|
18491
|
+
"aria-label": "Image alt text",
|
|
18492
|
+
style: {
|
|
18493
|
+
flex: 1,
|
|
18494
|
+
minWidth: 0,
|
|
18495
|
+
border: "none",
|
|
18496
|
+
outline: "none",
|
|
18497
|
+
background: "transparent",
|
|
18498
|
+
fontSize: 12,
|
|
18499
|
+
lineHeight: "16px",
|
|
18500
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18501
|
+
color: "#1f2937"
|
|
18502
|
+
}
|
|
18503
|
+
}
|
|
18504
|
+
)
|
|
18505
|
+
]
|
|
18506
|
+
}
|
|
18507
|
+
);
|
|
18684
18508
|
}
|
|
18685
18509
|
var VARIANTS = [
|
|
18686
18510
|
{ value: "logos", label: "Logos" },
|
|
18687
18511
|
{ value: "reel", label: "Reel" }
|
|
18688
18512
|
];
|
|
18689
18513
|
var ALIGNS = [
|
|
18690
|
-
{ value: "left", label: "
|
|
18691
|
-
{ value: "center", label: "
|
|
18692
|
-
{ value: "right", label: "
|
|
18514
|
+
{ value: "left", label: "Left" },
|
|
18515
|
+
{ value: "center", label: "Center" },
|
|
18516
|
+
{ value: "right", label: "Right" }
|
|
18693
18517
|
];
|
|
18694
18518
|
var HOVERS = [
|
|
18695
18519
|
{ value: "none", label: "None" },
|
|
@@ -18697,104 +18521,104 @@ var HOVERS = [
|
|
|
18697
18521
|
{ value: "zoom", label: "Zoom" },
|
|
18698
18522
|
{ value: "fade", label: "Fade" }
|
|
18699
18523
|
];
|
|
18524
|
+
var TREATMENTS = [
|
|
18525
|
+
{ value: "color", label: "Color" },
|
|
18526
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
18527
|
+
];
|
|
18700
18528
|
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18701
|
-
function
|
|
18702
|
-
|
|
18703
|
-
linkTarget,
|
|
18704
|
-
onClose,
|
|
18705
|
-
onSave
|
|
18706
|
-
}) {
|
|
18707
|
-
const [draft, setDraft] = useState8(href);
|
|
18708
|
-
const [newTab, setNewTab] = useState8(linkTarget !== "same-tab");
|
|
18529
|
+
function LinkInput({ value, onCommit }) {
|
|
18530
|
+
const [draft, setDraft] = useState8(value);
|
|
18709
18531
|
const [invalid, setInvalid] = useState8(false);
|
|
18710
|
-
|
|
18532
|
+
useEffect6(() => {
|
|
18533
|
+
setDraft(value);
|
|
18534
|
+
setInvalid(false);
|
|
18535
|
+
}, [value]);
|
|
18536
|
+
const commit = () => {
|
|
18711
18537
|
const next = draft.trim();
|
|
18712
|
-
if (next
|
|
18713
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
18717
|
-
onClose();
|
|
18538
|
+
if (next === value) return setInvalid(false);
|
|
18539
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
18540
|
+
setInvalid(false);
|
|
18541
|
+
onCommit(next);
|
|
18718
18542
|
};
|
|
18719
|
-
return /* @__PURE__ */
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
|
|
18723
|
-
"
|
|
18724
|
-
|
|
18725
|
-
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
|
|
18732
|
-
|
|
18733
|
-
|
|
18734
|
-
|
|
18735
|
-
|
|
18736
|
-
|
|
18737
|
-
"
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18543
|
+
return /* @__PURE__ */ jsxs11(
|
|
18544
|
+
"div",
|
|
18545
|
+
{
|
|
18546
|
+
style: {
|
|
18547
|
+
display: "flex",
|
|
18548
|
+
alignItems: "center",
|
|
18549
|
+
gap: 6,
|
|
18550
|
+
height: 28,
|
|
18551
|
+
padding: "0 12px",
|
|
18552
|
+
borderRadius: 999,
|
|
18553
|
+
background: "#ffffff",
|
|
18554
|
+
width: "100%",
|
|
18555
|
+
maxWidth: 260,
|
|
18556
|
+
boxSizing: "border-box",
|
|
18557
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18558
|
+
},
|
|
18559
|
+
children: [
|
|
18560
|
+
/* @__PURE__ */ jsx20(
|
|
18561
|
+
"span",
|
|
18562
|
+
{
|
|
18563
|
+
style: {
|
|
18564
|
+
flex: "0 0 auto",
|
|
18565
|
+
color: OHW_BLUE_DARK,
|
|
18566
|
+
fontSize: 10,
|
|
18567
|
+
fontWeight: 700,
|
|
18568
|
+
textTransform: "uppercase",
|
|
18569
|
+
letterSpacing: 0.4
|
|
18570
|
+
},
|
|
18571
|
+
children: "Link"
|
|
18572
|
+
}
|
|
18573
|
+
),
|
|
18574
|
+
/* @__PURE__ */ jsx20(
|
|
18575
|
+
"input",
|
|
18576
|
+
{
|
|
18577
|
+
type: "text",
|
|
18578
|
+
inputMode: "url",
|
|
18579
|
+
value: draft,
|
|
18580
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18581
|
+
onBlur: commit,
|
|
18582
|
+
onKeyDown: (e) => {
|
|
18583
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18584
|
+
if (e.key === "Escape") {
|
|
18585
|
+
setDraft(value);
|
|
18586
|
+
setInvalid(false);
|
|
18587
|
+
e.currentTarget.blur();
|
|
18588
|
+
}
|
|
18589
|
+
},
|
|
18590
|
+
placeholder: "https://example.com",
|
|
18591
|
+
"aria-label": "Image link URL",
|
|
18592
|
+
"aria-invalid": invalid,
|
|
18593
|
+
style: {
|
|
18594
|
+
flex: 1,
|
|
18595
|
+
minWidth: 0,
|
|
18596
|
+
border: "none",
|
|
18597
|
+
outline: "none",
|
|
18598
|
+
background: "transparent",
|
|
18599
|
+
fontSize: 12,
|
|
18600
|
+
lineHeight: "16px",
|
|
18601
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18602
|
+
color: "#1f2937"
|
|
18603
|
+
}
|
|
18604
|
+
}
|
|
18605
|
+
)
|
|
18606
|
+
]
|
|
18607
|
+
}
|
|
18608
|
+
);
|
|
18784
18609
|
}
|
|
18785
18610
|
function MediaStripToolbar({
|
|
18786
18611
|
entry,
|
|
18787
18612
|
index,
|
|
18788
18613
|
pending,
|
|
18789
18614
|
error,
|
|
18790
|
-
itemEditOn,
|
|
18791
|
-
onToggleItemEdit,
|
|
18792
18615
|
onSetVariant,
|
|
18793
18616
|
onSetAlign,
|
|
18794
18617
|
onSetHover,
|
|
18795
18618
|
onSetTreatment,
|
|
18796
18619
|
onResize,
|
|
18797
|
-
|
|
18620
|
+
onSetAlt,
|
|
18621
|
+
onSetLink,
|
|
18798
18622
|
onAddItem,
|
|
18799
18623
|
onRemoveItem,
|
|
18800
18624
|
onChangeImage,
|
|
@@ -18803,102 +18627,81 @@ function MediaStripToolbar({
|
|
|
18803
18627
|
}) {
|
|
18804
18628
|
const items = mediaStripItems(entry.tree);
|
|
18805
18629
|
const itemCount = items.length;
|
|
18630
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
18631
|
+
const currentHref = items[index]?.href ?? "";
|
|
18632
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18806
18633
|
const slots = findMediaStripSlots(entry.tree);
|
|
18807
18634
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18808
18635
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
18809
18636
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
18810
18637
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
18811
18638
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18812
|
-
const
|
|
18813
|
-
const
|
|
18814
|
-
|
|
18639
|
+
const isMobile = window.innerWidth <= 480;
|
|
18640
|
+
const rowStyle = isMobile ? {
|
|
18641
|
+
display: "flex",
|
|
18642
|
+
gap: 6,
|
|
18643
|
+
flexWrap: "nowrap",
|
|
18644
|
+
justifyContent: "center",
|
|
18645
|
+
overflowX: "auto",
|
|
18646
|
+
WebkitOverflowScrolling: "touch",
|
|
18647
|
+
width: "100%",
|
|
18648
|
+
scrollbarWidth: "none"
|
|
18649
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
18650
|
+
return /* @__PURE__ */ jsxs11(
|
|
18815
18651
|
"div",
|
|
18816
18652
|
{
|
|
18817
18653
|
"data-ohw-bridge": "",
|
|
18818
18654
|
"data-ohw-toolbar": "",
|
|
18819
18655
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18820
|
-
|
|
18821
|
-
|
|
18656
|
+
style: {
|
|
18657
|
+
display: "flex",
|
|
18658
|
+
flexDirection: "column",
|
|
18659
|
+
gap: 6,
|
|
18660
|
+
alignItems: "center",
|
|
18661
|
+
background: OHW_BLUE,
|
|
18662
|
+
padding: 8,
|
|
18663
|
+
borderRadius: 12,
|
|
18664
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18665
|
+
pointerEvents: pending ? "none" : "auto",
|
|
18666
|
+
opacity: pending ? 0.6 : 1,
|
|
18667
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
18668
|
+
},
|
|
18822
18669
|
children: [
|
|
18823
|
-
/* @__PURE__ */
|
|
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
|
-
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
18857
|
-
] }),
|
|
18858
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
18859
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ jsx21(ImageIcon2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18860
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ jsx21(LinkIcon, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18861
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ jsx21(ArrowLeft2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18862
|
-
/* @__PURE__ */ jsx21(
|
|
18863
|
-
ToolbarAction,
|
|
18864
|
-
{
|
|
18865
|
-
label: gatedLabel("Move right"),
|
|
18866
|
-
onClick: onMoveRight,
|
|
18867
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
18868
|
-
children: /* @__PURE__ */ jsx21(ArrowRight2, { size: 16, style: { pointerEvents: "none" } })
|
|
18869
|
-
}
|
|
18870
|
-
),
|
|
18871
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ jsx21(ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18872
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
18873
|
-
/* @__PURE__ */ jsx21(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
18874
|
-
/* @__PURE__ */ jsx21(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
18875
|
-
/* @__PURE__ */ jsx21(
|
|
18876
|
-
ToolbarAction,
|
|
18877
|
-
{
|
|
18878
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
18879
|
-
active: treatment === "grayscale",
|
|
18880
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
18881
|
-
children: /* @__PURE__ */ jsx21(Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
18882
|
-
}
|
|
18883
|
-
),
|
|
18884
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
18885
|
-
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx21(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ jsx21(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
18886
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
18887
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ jsx21(Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18888
|
-
/* @__PURE__ */ jsxs12("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
18889
|
-
sizeValue,
|
|
18890
|
-
"px"
|
|
18891
|
-
] }),
|
|
18892
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ jsx21(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18893
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
18894
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ jsx21(ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18895
|
-
]
|
|
18896
|
-
}
|
|
18897
|
-
),
|
|
18898
|
-
error && /* @__PURE__ */ jsx21("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18670
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
18671
|
+
VARIANTS.map((v) => /* @__PURE__ */ jsx20(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
18672
|
+
ALIGNS.map((a) => /* @__PURE__ */ jsx20(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
18673
|
+
] }),
|
|
18674
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
18675
|
+
HOVERS.map((h) => /* @__PURE__ */ jsx20(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
18676
|
+
TREATMENTS.map((t) => /* @__PURE__ */ jsx20(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
18677
|
+
] }),
|
|
18678
|
+
/* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
18679
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
18680
|
+
/* @__PURE__ */ jsxs11("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
18681
|
+
sizeValue,
|
|
18682
|
+
"px"
|
|
18683
|
+
] }),
|
|
18684
|
+
/* @__PURE__ */ jsx20(Pill, { label: "+", onClick: () => onResize(8) })
|
|
18685
|
+
] }),
|
|
18686
|
+
/* @__PURE__ */ jsx20("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ jsx20(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
18687
|
+
/* @__PURE__ */ jsx20("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ jsx20(LinkInput, { value: currentHref, onCommit: (href) => onSetLink(href, currentTarget) }) }),
|
|
18688
|
+
currentHref && /* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
18689
|
+
/* @__PURE__ */ jsx20(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
18690
|
+
/* @__PURE__ */ jsx20(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
18691
|
+
] }),
|
|
18692
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
18693
|
+
/* @__PURE__ */ jsx20(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
18694
|
+
/* @__PURE__ */ jsx20(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
18695
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
18696
|
+
] }),
|
|
18697
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
18698
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
18699
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
18700
|
+
] }),
|
|
18701
|
+
error && /* @__PURE__ */ jsx20("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
18899
18702
|
]
|
|
18900
18703
|
}
|
|
18901
|
-
)
|
|
18704
|
+
);
|
|
18902
18705
|
}
|
|
18903
18706
|
function findMediaStripSlots(tree) {
|
|
18904
18707
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -18917,23 +18720,31 @@ function AiMediaStripOverlay({
|
|
|
18917
18720
|
}) {
|
|
18918
18721
|
const [hover, setHover] = useState8(null);
|
|
18919
18722
|
const [active, setActive] = useState8(null);
|
|
18920
|
-
const [itemEditOn, setItemEditOn] = useState8(false);
|
|
18921
|
-
const [linkOpen, setLinkOpen] = useState8(false);
|
|
18922
18723
|
const [pending, setPending] = useState8(false);
|
|
18923
18724
|
const [error, setError] = useState8(null);
|
|
18924
18725
|
const activeRef = useRef5(null);
|
|
18925
18726
|
activeRef.current = active;
|
|
18926
|
-
const linkOpenRef = useRef5(false);
|
|
18927
|
-
linkOpenRef.current = linkOpen;
|
|
18928
18727
|
useEffect6(() => {
|
|
18929
18728
|
const onMove = (e) => {
|
|
18930
|
-
const ref = itemRefFromTarget(e.target);
|
|
18931
18729
|
const t = e.target;
|
|
18932
|
-
|
|
18933
|
-
|
|
18934
|
-
|
|
18935
|
-
|
|
18936
|
-
|
|
18730
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18731
|
+
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]")) {
|
|
18732
|
+
return;
|
|
18733
|
+
}
|
|
18734
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
18735
|
+
if (!itemEl) {
|
|
18736
|
+
setHover(null);
|
|
18737
|
+
return;
|
|
18738
|
+
}
|
|
18739
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18740
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18741
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18742
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18743
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
18744
|
+
setHover(null);
|
|
18745
|
+
return;
|
|
18746
|
+
}
|
|
18747
|
+
setHover({ sectionId, index });
|
|
18937
18748
|
};
|
|
18938
18749
|
const onLeave = () => setHover(null);
|
|
18939
18750
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -18945,25 +18756,23 @@ function AiMediaStripOverlay({
|
|
|
18945
18756
|
}, []);
|
|
18946
18757
|
useEffect6(() => {
|
|
18947
18758
|
const onClick = (e) => {
|
|
18759
|
+
const current = activeRef.current;
|
|
18760
|
+
if (!current) return;
|
|
18948
18761
|
const t = e.target;
|
|
18949
|
-
if (!(t instanceof
|
|
18950
|
-
if (t.closest(
|
|
18951
|
-
const
|
|
18952
|
-
if (
|
|
18953
|
-
|
|
18954
|
-
setItemEditOn(false);
|
|
18762
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18763
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
18764
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
18765
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
18766
|
+
setActive(null);
|
|
18955
18767
|
setError(null);
|
|
18956
|
-
setActive(ref);
|
|
18957
18768
|
};
|
|
18958
18769
|
document.addEventListener("click", onClick, true);
|
|
18959
18770
|
return () => document.removeEventListener("click", onClick, true);
|
|
18960
|
-
}, [
|
|
18771
|
+
}, []);
|
|
18961
18772
|
useEffect6(() => {
|
|
18962
18773
|
const onBlur = () => {
|
|
18963
18774
|
if (!activeRef.current) return;
|
|
18964
18775
|
setActive(null);
|
|
18965
|
-
setItemEditOn(false);
|
|
18966
|
-
setLinkOpen(false);
|
|
18967
18776
|
setError(null);
|
|
18968
18777
|
};
|
|
18969
18778
|
window.addEventListener("blur", onBlur);
|
|
@@ -18973,10 +18782,7 @@ function AiMediaStripOverlay({
|
|
|
18973
18782
|
const onKeyDown = (e) => {
|
|
18974
18783
|
if (e.key !== "Escape") return;
|
|
18975
18784
|
if (!activeRef.current) return;
|
|
18976
|
-
if (linkOpenRef.current) return;
|
|
18977
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
18978
18785
|
setActive(null);
|
|
18979
|
-
setItemEditOn(false);
|
|
18980
18786
|
setError(null);
|
|
18981
18787
|
};
|
|
18982
18788
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -19010,133 +18816,137 @@ function AiMediaStripOverlay({
|
|
|
19010
18816
|
tree: nextTree,
|
|
19011
18817
|
label: entry.label,
|
|
19012
18818
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
19013
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
19014
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
19015
|
-
// on every edit reads as the section jumping around.
|
|
19016
|
-
skipScrollIntoView: true
|
|
18819
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
19017
18820
|
});
|
|
19018
18821
|
return true;
|
|
19019
18822
|
},
|
|
19020
18823
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
19021
18824
|
);
|
|
19022
18825
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18826
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
19023
18827
|
const activeItemRect = useLiveItemRect(active);
|
|
19024
|
-
const
|
|
19025
|
-
const
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
18828
|
+
const TOOLBAR_APPROX_H = 170;
|
|
18829
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
18830
|
+
return /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
18831
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx20(
|
|
18832
|
+
"button",
|
|
18833
|
+
{
|
|
18834
|
+
type: "button",
|
|
18835
|
+
"data-ohw-toolbar": "",
|
|
18836
|
+
onClick: () => {
|
|
18837
|
+
clearInteractionChromeRef.current();
|
|
18838
|
+
setActive(hover);
|
|
18839
|
+
},
|
|
18840
|
+
"aria-label": "Configure media item",
|
|
18841
|
+
style: {
|
|
18842
|
+
position: "fixed",
|
|
18843
|
+
top: hoverHandleRect.top + 8,
|
|
18844
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
18845
|
+
width: 28,
|
|
18846
|
+
height: 28,
|
|
18847
|
+
borderRadius: 8,
|
|
18848
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
18849
|
+
background: "#ffffff",
|
|
18850
|
+
color: PRIMARY3,
|
|
18851
|
+
display: "flex",
|
|
18852
|
+
alignItems: "center",
|
|
18853
|
+
justifyContent: "center",
|
|
18854
|
+
cursor: "pointer",
|
|
18855
|
+
zIndex: 2147483643,
|
|
18856
|
+
fontSize: 14,
|
|
18857
|
+
fontWeight: 700
|
|
18858
|
+
},
|
|
18859
|
+
children: /* @__PURE__ */ jsx20(Star, { size: 14, style: { pointerEvents: "none" } })
|
|
18860
|
+
}
|
|
18861
|
+
),
|
|
18862
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx20(
|
|
18863
|
+
ItemInteractionLayer,
|
|
18864
|
+
{
|
|
18865
|
+
rect: activeItemRect,
|
|
18866
|
+
state: toolbarState,
|
|
18867
|
+
toolbar: /* @__PURE__ */ jsx20(
|
|
18868
|
+
MediaStripToolbar,
|
|
18869
|
+
{
|
|
18870
|
+
entry: activeEntry,
|
|
18871
|
+
index: active.index,
|
|
18872
|
+
pending,
|
|
18873
|
+
error,
|
|
18874
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18875
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18876
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18877
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18878
|
+
onResize: (delta) => {
|
|
18879
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18880
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18881
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18882
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18883
|
+
},
|
|
18884
|
+
onSetAlt: (alt) => {
|
|
18885
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
18886
|
+
},
|
|
18887
|
+
onSetLink: (href, linkTarget) => {
|
|
19058
18888
|
void runMutation(
|
|
19059
18889
|
active.sectionId,
|
|
19060
|
-
(tree) =>
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
18890
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
18891
|
+
);
|
|
18892
|
+
},
|
|
18893
|
+
onAddItem: () => {
|
|
18894
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18895
|
+
if (!picked) return;
|
|
18896
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18897
|
+
void runMutation(
|
|
18898
|
+
active.sectionId,
|
|
18899
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18900
|
+
{ [picked.assetId]: picked.url }
|
|
18901
|
+
).then((applied) => {
|
|
18902
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18903
|
+
});
|
|
19064
18904
|
});
|
|
19065
|
-
}
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
|
|
19072
|
-
|
|
19073
|
-
|
|
18905
|
+
},
|
|
18906
|
+
onChangeImage: () => {
|
|
18907
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18908
|
+
if (!picked) return;
|
|
18909
|
+
void runMutation(
|
|
18910
|
+
active.sectionId,
|
|
18911
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
18912
|
+
{ [picked.assetId]: picked.url }
|
|
18913
|
+
);
|
|
18914
|
+
});
|
|
18915
|
+
},
|
|
18916
|
+
onRemoveItem: () => {
|
|
18917
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
18918
|
+
(applied) => {
|
|
18919
|
+
if (applied) setActive(null);
|
|
18920
|
+
}
|
|
19074
18921
|
);
|
|
19075
|
-
}
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
},
|
|
19091
|
-
onMoveRight: () => {
|
|
19092
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19093
|
-
(applied) => {
|
|
19094
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19095
|
-
}
|
|
19096
|
-
);
|
|
19097
|
-
}
|
|
19098
|
-
}
|
|
19099
|
-
) }),
|
|
19100
|
-
/* @__PURE__ */ jsx21(
|
|
19101
|
-
"div",
|
|
19102
|
-
{
|
|
19103
|
-
"data-ohw-bridge": "",
|
|
19104
|
-
"data-ohw-item-interaction": "",
|
|
19105
|
-
"aria-hidden": true,
|
|
19106
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
19107
|
-
style: {
|
|
19108
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
19109
|
-
left: activeItemRect.left - 5,
|
|
19110
|
-
background: PRIMARY3,
|
|
19111
|
-
zIndex: 2147483644
|
|
19112
|
-
},
|
|
19113
|
-
children: "Media item"
|
|
19114
|
-
}
|
|
19115
|
-
),
|
|
19116
|
-
linkOpen && /* @__PURE__ */ jsx21(
|
|
19117
|
-
LinkModal,
|
|
19118
|
-
{
|
|
19119
|
-
href: activeHref,
|
|
19120
|
-
linkTarget: activeTarget,
|
|
19121
|
-
onClose: () => setLinkOpen(false),
|
|
19122
|
-
onSave: (href, linkTarget) => {
|
|
19123
|
-
void runMutation(
|
|
19124
|
-
active.sectionId,
|
|
19125
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19126
|
-
);
|
|
18922
|
+
},
|
|
18923
|
+
onMoveLeft: () => {
|
|
18924
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18925
|
+
(applied) => {
|
|
18926
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18927
|
+
}
|
|
18928
|
+
);
|
|
18929
|
+
},
|
|
18930
|
+
onMoveRight: () => {
|
|
18931
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18932
|
+
(applied) => {
|
|
18933
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18934
|
+
}
|
|
18935
|
+
);
|
|
18936
|
+
}
|
|
19127
18937
|
}
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
|
|
18938
|
+
)
|
|
18939
|
+
}
|
|
18940
|
+
)
|
|
19131
18941
|
] });
|
|
19132
18942
|
}
|
|
19133
18943
|
|
|
19134
18944
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
19135
|
-
import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as
|
|
19136
|
-
import { Check as
|
|
19137
|
-
import { Fragment as Fragment8, jsx as
|
|
18945
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as useLayoutEffect4, useRef as useRef6, useState as useState9 } from "react";
|
|
18946
|
+
import { Check as Check2, ChevronDown as ChevronDown3, Minus, Plus as Plus2, Star as Star2 } from "lucide-react";
|
|
18947
|
+
import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
19138
18948
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
19139
|
-
var
|
|
18949
|
+
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]";
|
|
19140
18950
|
function findPricingCardElement(sectionId, index) {
|
|
19141
18951
|
const sectionEl = findByInstanceId(sectionId);
|
|
19142
18952
|
if (!sectionEl) return null;
|
|
@@ -19148,7 +18958,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19148
18958
|
}
|
|
19149
18959
|
function cardRefFromTarget(target) {
|
|
19150
18960
|
if (!(target instanceof Element)) return null;
|
|
19151
|
-
if (target.closest(
|
|
18961
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19152
18962
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19153
18963
|
if (!cardEl) return null;
|
|
19154
18964
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19158,21 +18968,21 @@ function cardRefFromTarget(target) {
|
|
|
19158
18968
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19159
18969
|
return { sectionId, index };
|
|
19160
18970
|
}
|
|
19161
|
-
function
|
|
18971
|
+
function sameRef(a, b) {
|
|
19162
18972
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19163
18973
|
}
|
|
19164
|
-
function
|
|
18974
|
+
function rectOf(el) {
|
|
19165
18975
|
if (!el) return null;
|
|
19166
18976
|
const r2 = el.getBoundingClientRect();
|
|
19167
18977
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19168
18978
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19169
18979
|
}
|
|
19170
18980
|
function readRect3(ref) {
|
|
19171
|
-
return
|
|
18981
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19172
18982
|
}
|
|
19173
18983
|
function readGridRect(ref) {
|
|
19174
18984
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19175
|
-
return
|
|
18985
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19176
18986
|
}
|
|
19177
18987
|
function useLiveCardRect(ref, grid = false) {
|
|
19178
18988
|
const [rect, setRect] = useState9(null);
|
|
@@ -19202,19 +19012,19 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19202
19012
|
}
|
|
19203
19013
|
var TOOLBAR_GRID_GAP = 52;
|
|
19204
19014
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19205
|
-
var
|
|
19015
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19206
19016
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19207
19017
|
const slotRef = useRef6(null);
|
|
19208
19018
|
const [shift, setShift] = useState9(0);
|
|
19209
19019
|
const centerX = gridRect.left + gridRect.width / 2;
|
|
19210
|
-
|
|
19020
|
+
useLayoutEffect4(() => {
|
|
19211
19021
|
const slot = slotRef.current;
|
|
19212
19022
|
if (!slot) return;
|
|
19213
19023
|
const clamp = () => {
|
|
19214
19024
|
const w = slot.offsetWidth;
|
|
19215
19025
|
if (w <= 0) return;
|
|
19216
19026
|
const half = w / 2;
|
|
19217
|
-
const clamped = Math.max(
|
|
19027
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19218
19028
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19219
19029
|
};
|
|
19220
19030
|
clamp();
|
|
@@ -19223,7 +19033,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19223
19033
|
return () => ro.disconnect();
|
|
19224
19034
|
}, [centerX, children]);
|
|
19225
19035
|
const mobile = window.innerWidth <= 480;
|
|
19226
|
-
return /* @__PURE__ */
|
|
19036
|
+
return /* @__PURE__ */ jsx21(
|
|
19227
19037
|
"div",
|
|
19228
19038
|
{
|
|
19229
19039
|
ref: slotRef,
|
|
@@ -19258,7 +19068,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
19258
19068
|
});
|
|
19259
19069
|
}
|
|
19260
19070
|
function StyleSwatch({ style }) {
|
|
19261
|
-
return /* @__PURE__ */
|
|
19071
|
+
return /* @__PURE__ */ jsx21(
|
|
19262
19072
|
"span",
|
|
19263
19073
|
{
|
|
19264
19074
|
"aria-hidden": true,
|
|
@@ -19272,35 +19082,35 @@ function StyleSwatch({ style }) {
|
|
|
19272
19082
|
);
|
|
19273
19083
|
}
|
|
19274
19084
|
function ButtonGlyph() {
|
|
19275
|
-
return /* @__PURE__ */
|
|
19276
|
-
/* @__PURE__ */
|
|
19277
|
-
/* @__PURE__ */
|
|
19085
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19086
|
+
/* @__PURE__ */ jsx21("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19087
|
+
/* @__PURE__ */ jsx21("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19278
19088
|
] });
|
|
19279
19089
|
}
|
|
19280
19090
|
function FeatureGlyph({ mode }) {
|
|
19281
|
-
return /* @__PURE__ */
|
|
19282
|
-
/* @__PURE__ */
|
|
19283
|
-
/* @__PURE__ */
|
|
19284
|
-
/* @__PURE__ */
|
|
19285
|
-
/* @__PURE__ */
|
|
19286
|
-
/* @__PURE__ */
|
|
19287
|
-
mode === "add" && /* @__PURE__ */
|
|
19091
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19092
|
+
/* @__PURE__ */ jsx21("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19093
|
+
/* @__PURE__ */ jsx21("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19094
|
+
/* @__PURE__ */ jsx21("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19095
|
+
/* @__PURE__ */ jsx21("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19096
|
+
/* @__PURE__ */ jsx21("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19097
|
+
mode === "add" && /* @__PURE__ */ jsx21("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19288
19098
|
] });
|
|
19289
19099
|
}
|
|
19290
|
-
function
|
|
19100
|
+
function ToolbarAction({
|
|
19291
19101
|
label,
|
|
19292
19102
|
onClick,
|
|
19293
19103
|
disabled = false,
|
|
19294
19104
|
children
|
|
19295
19105
|
}) {
|
|
19296
|
-
const button = /* @__PURE__ */
|
|
19297
|
-
return /* @__PURE__ */
|
|
19298
|
-
/* @__PURE__ */
|
|
19299
|
-
/* @__PURE__ */
|
|
19106
|
+
const button = /* @__PURE__ */ jsx21(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19107
|
+
return /* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19108
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: button }) : button }),
|
|
19109
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19300
19110
|
] });
|
|
19301
19111
|
}
|
|
19302
|
-
function
|
|
19303
|
-
return /* @__PURE__ */
|
|
19112
|
+
function ToolbarSeparator() {
|
|
19113
|
+
return /* @__PURE__ */ jsx21("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19304
19114
|
}
|
|
19305
19115
|
function CardStyleMenu({
|
|
19306
19116
|
value,
|
|
@@ -19308,7 +19118,7 @@ function CardStyleMenu({
|
|
|
19308
19118
|
disabled = false
|
|
19309
19119
|
}) {
|
|
19310
19120
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
19311
|
-
const trigger = /* @__PURE__ */
|
|
19121
|
+
const trigger = /* @__PURE__ */ jsxs12(
|
|
19312
19122
|
"button",
|
|
19313
19123
|
{
|
|
19314
19124
|
type: "button",
|
|
@@ -19319,28 +19129,28 @@ function CardStyleMenu({
|
|
|
19319
19129
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
19320
19130
|
),
|
|
19321
19131
|
children: [
|
|
19322
|
-
/* @__PURE__ */
|
|
19323
|
-
/* @__PURE__ */
|
|
19324
|
-
/* @__PURE__ */
|
|
19132
|
+
/* @__PURE__ */ jsx21(StyleSwatch, { style: current.value }),
|
|
19133
|
+
/* @__PURE__ */ jsx21("span", { className: "flex-1 text-left", children: current.label }),
|
|
19134
|
+
/* @__PURE__ */ jsx21(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
19325
19135
|
]
|
|
19326
19136
|
}
|
|
19327
19137
|
);
|
|
19328
19138
|
if (disabled) {
|
|
19329
|
-
return /* @__PURE__ */
|
|
19330
|
-
/* @__PURE__ */
|
|
19331
|
-
/* @__PURE__ */
|
|
19332
|
-
/* @__PURE__ */
|
|
19333
|
-
/* @__PURE__ */
|
|
19139
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19140
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19141
|
+
/* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19142
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: trigger }) }),
|
|
19143
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
19334
19144
|
] })
|
|
19335
19145
|
] });
|
|
19336
19146
|
}
|
|
19337
|
-
return /* @__PURE__ */
|
|
19338
|
-
/* @__PURE__ */
|
|
19339
|
-
/* @__PURE__ */
|
|
19340
|
-
/* @__PURE__ */
|
|
19341
|
-
/* @__PURE__ */
|
|
19147
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19148
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19149
|
+
/* @__PURE__ */ jsxs12(DropdownMenu, { modal: false, children: [
|
|
19150
|
+
/* @__PURE__ */ jsx21(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19151
|
+
/* @__PURE__ */ jsx21(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
19342
19152
|
const selected = style.value === value;
|
|
19343
|
-
return /* @__PURE__ */
|
|
19153
|
+
return /* @__PURE__ */ jsxs12(
|
|
19344
19154
|
DropdownMenuItem,
|
|
19345
19155
|
{
|
|
19346
19156
|
role: "menuitemradio",
|
|
@@ -19348,9 +19158,9 @@ function CardStyleMenu({
|
|
|
19348
19158
|
onSelect: () => onChange(style.value),
|
|
19349
19159
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19350
19160
|
children: [
|
|
19351
|
-
/* @__PURE__ */
|
|
19352
|
-
/* @__PURE__ */
|
|
19353
|
-
selected && /* @__PURE__ */
|
|
19161
|
+
/* @__PURE__ */ jsx21(StyleSwatch, { style: style.value }),
|
|
19162
|
+
/* @__PURE__ */ jsx21("span", { children: style.label }),
|
|
19163
|
+
selected && /* @__PURE__ */ jsx21(Check2, { size: 16, className: "text-bridge-primary" })
|
|
19354
19164
|
]
|
|
19355
19165
|
},
|
|
19356
19166
|
style.value
|
|
@@ -19380,7 +19190,7 @@ function PricingCardToolbar({
|
|
|
19380
19190
|
const style = pricingCardStyle(entry.tree, index);
|
|
19381
19191
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19382
19192
|
const mobile = window.innerWidth <= 480;
|
|
19383
|
-
return /* @__PURE__ */
|
|
19193
|
+
return /* @__PURE__ */ jsx21(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs12(
|
|
19384
19194
|
"div",
|
|
19385
19195
|
{
|
|
19386
19196
|
"data-ohw-bridge": "",
|
|
@@ -19392,7 +19202,7 @@ function PricingCardToolbar({
|
|
|
19392
19202
|
),
|
|
19393
19203
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19394
19204
|
children: [
|
|
19395
|
-
/* @__PURE__ */
|
|
19205
|
+
/* @__PURE__ */ jsxs12(
|
|
19396
19206
|
"div",
|
|
19397
19207
|
{
|
|
19398
19208
|
className: cn(
|
|
@@ -19401,8 +19211,8 @@ function PricingCardToolbar({
|
|
|
19401
19211
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19402
19212
|
),
|
|
19403
19213
|
children: [
|
|
19404
|
-
/* @__PURE__ */
|
|
19405
|
-
/* @__PURE__ */
|
|
19214
|
+
/* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19215
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
|
|
19406
19216
|
CustomToolbarButton,
|
|
19407
19217
|
{
|
|
19408
19218
|
type: "button",
|
|
@@ -19410,7 +19220,7 @@ function PricingCardToolbar({
|
|
|
19410
19220
|
"aria-pressed": featuredTag,
|
|
19411
19221
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19412
19222
|
className: "group size-8",
|
|
19413
|
-
children: /* @__PURE__ */
|
|
19223
|
+
children: /* @__PURE__ */ jsx21(
|
|
19414
19224
|
Star2,
|
|
19415
19225
|
{
|
|
19416
19226
|
size: 16,
|
|
@@ -19425,25 +19235,25 @@ function PricingCardToolbar({
|
|
|
19425
19235
|
)
|
|
19426
19236
|
}
|
|
19427
19237
|
) }),
|
|
19428
|
-
/* @__PURE__ */
|
|
19238
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19429
19239
|
] }),
|
|
19430
|
-
/* @__PURE__ */
|
|
19431
|
-
/* @__PURE__ */
|
|
19432
|
-
/* @__PURE__ */
|
|
19433
|
-
/* @__PURE__ */
|
|
19434
|
-
/* @__PURE__ */
|
|
19435
|
-
/* @__PURE__ */
|
|
19436
|
-
/* @__PURE__ */
|
|
19240
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19241
|
+
/* @__PURE__ */ jsx21(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19242
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19243
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx21(ButtonGlyph, {}) }),
|
|
19244
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs12("span", { className: "relative inline-flex", children: [
|
|
19245
|
+
/* @__PURE__ */ jsx21(ButtonGlyph, {}),
|
|
19246
|
+
/* @__PURE__ */ jsx21(Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
19437
19247
|
] }) }),
|
|
19438
|
-
/* @__PURE__ */
|
|
19439
|
-
/* @__PURE__ */
|
|
19440
|
-
/* @__PURE__ */
|
|
19441
|
-
/* @__PURE__ */
|
|
19442
|
-
/* @__PURE__ */
|
|
19248
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ jsx21(FeatureGlyph, { mode: "add" }) }),
|
|
19249
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ jsx21(FeatureGlyph, { mode: "remove" }) }),
|
|
19250
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19251
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ jsx21(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19252
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ jsx21(Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19443
19253
|
]
|
|
19444
19254
|
}
|
|
19445
19255
|
),
|
|
19446
|
-
error && /* @__PURE__ */
|
|
19256
|
+
error && /* @__PURE__ */ jsx21("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19447
19257
|
]
|
|
19448
19258
|
}
|
|
19449
19259
|
) });
|
|
@@ -19477,7 +19287,7 @@ function AiPricingCardOverlay({
|
|
|
19477
19287
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19478
19288
|
setHover((prev) => {
|
|
19479
19289
|
const next = ref && !overEditable ? ref : null;
|
|
19480
|
-
return
|
|
19290
|
+
return sameRef(prev, next) ? prev : next;
|
|
19481
19291
|
});
|
|
19482
19292
|
};
|
|
19483
19293
|
const onLeave = () => setHover(null);
|
|
@@ -19492,10 +19302,10 @@ function AiPricingCardOverlay({
|
|
|
19492
19302
|
const onClick = (e) => {
|
|
19493
19303
|
const t = e.target;
|
|
19494
19304
|
if (!(t instanceof Element)) return;
|
|
19495
|
-
if (t.closest(
|
|
19305
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
19496
19306
|
const ref = cardRefFromTarget(t);
|
|
19497
|
-
setActive((prev) =>
|
|
19498
|
-
if (!ref || !
|
|
19307
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19308
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
19499
19309
|
};
|
|
19500
19310
|
document.addEventListener("click", onClick, true);
|
|
19501
19311
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19560,12 +19370,12 @@ function AiPricingCardOverlay({
|
|
|
19560
19370
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19561
19371
|
const activeCardRect = useLiveCardRect(active);
|
|
19562
19372
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19563
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19564
|
-
return /* @__PURE__ */
|
|
19565
|
-
hoverRect && /* @__PURE__ */
|
|
19566
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */
|
|
19567
|
-
/* @__PURE__ */
|
|
19568
|
-
/* @__PURE__ */
|
|
19373
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19374
|
+
return /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
19375
|
+
hoverRect && /* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19376
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
19377
|
+
/* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19378
|
+
/* @__PURE__ */ jsx21(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ jsx21(
|
|
19569
19379
|
PricingCardToolbar,
|
|
19570
19380
|
{
|
|
19571
19381
|
entry: activeEntry,
|
|
@@ -19593,7 +19403,7 @@ function AiPricingCardOverlay({
|
|
|
19593
19403
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
19594
19404
|
}
|
|
19595
19405
|
) }),
|
|
19596
|
-
/* @__PURE__ */
|
|
19406
|
+
/* @__PURE__ */ jsx21(
|
|
19597
19407
|
"div",
|
|
19598
19408
|
{
|
|
19599
19409
|
"data-ohw-bridge": "",
|
|
@@ -19686,10 +19496,10 @@ function extractYouTubeId(input) {
|
|
|
19686
19496
|
}
|
|
19687
19497
|
|
|
19688
19498
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19689
|
-
import { Fragment as Fragment9, jsx as
|
|
19499
|
+
import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
19690
19500
|
var PRIMARY5 = "#0885FE";
|
|
19691
|
-
var
|
|
19692
|
-
var
|
|
19501
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19502
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
19693
19503
|
function findVideoBlockElement(sectionId, path) {
|
|
19694
19504
|
const sectionEl = findByInstanceId(sectionId);
|
|
19695
19505
|
if (!sectionEl) return null;
|
|
@@ -19749,12 +19559,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
19749
19559
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
19750
19560
|
});
|
|
19751
19561
|
}
|
|
19752
|
-
function
|
|
19562
|
+
function Pill2({
|
|
19753
19563
|
label,
|
|
19754
19564
|
onClick,
|
|
19755
19565
|
disabled
|
|
19756
19566
|
}) {
|
|
19757
|
-
return /* @__PURE__ */
|
|
19567
|
+
return /* @__PURE__ */ jsx22(
|
|
19758
19568
|
"button",
|
|
19759
19569
|
{
|
|
19760
19570
|
type: "button",
|
|
@@ -19770,7 +19580,7 @@ function Pill({
|
|
|
19770
19580
|
border: "none",
|
|
19771
19581
|
cursor: disabled ? "default" : "pointer",
|
|
19772
19582
|
background: "#ffffff",
|
|
19773
|
-
color:
|
|
19583
|
+
color: OHW_BLUE_DARK2,
|
|
19774
19584
|
opacity: disabled ? 0.4 : 1,
|
|
19775
19585
|
fontSize: 12,
|
|
19776
19586
|
lineHeight: "16px",
|
|
@@ -19813,8 +19623,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19813
19623
|
onCommit(id);
|
|
19814
19624
|
}
|
|
19815
19625
|
};
|
|
19816
|
-
return /* @__PURE__ */
|
|
19817
|
-
/* @__PURE__ */
|
|
19626
|
+
return /* @__PURE__ */ jsxs13("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
19627
|
+
/* @__PURE__ */ jsxs13(
|
|
19818
19628
|
"div",
|
|
19819
19629
|
{
|
|
19820
19630
|
style: {
|
|
@@ -19830,12 +19640,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19830
19640
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19831
19641
|
},
|
|
19832
19642
|
children: [
|
|
19833
|
-
/* @__PURE__ */
|
|
19643
|
+
/* @__PURE__ */ jsx22(
|
|
19834
19644
|
"span",
|
|
19835
19645
|
{
|
|
19836
19646
|
style: {
|
|
19837
19647
|
flex: "0 0 auto",
|
|
19838
|
-
color:
|
|
19648
|
+
color: OHW_BLUE_DARK2,
|
|
19839
19649
|
fontSize: 10,
|
|
19840
19650
|
lineHeight: "16px",
|
|
19841
19651
|
fontWeight: 700,
|
|
@@ -19845,7 +19655,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19845
19655
|
children: "Video"
|
|
19846
19656
|
}
|
|
19847
19657
|
),
|
|
19848
|
-
/* @__PURE__ */
|
|
19658
|
+
/* @__PURE__ */ jsx22(
|
|
19849
19659
|
"input",
|
|
19850
19660
|
{
|
|
19851
19661
|
type: "text",
|
|
@@ -19882,7 +19692,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19882
19692
|
]
|
|
19883
19693
|
}
|
|
19884
19694
|
),
|
|
19885
|
-
invalid && /* @__PURE__ */
|
|
19695
|
+
invalid && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
19886
19696
|
] });
|
|
19887
19697
|
}
|
|
19888
19698
|
function VideoToolbar({
|
|
@@ -19892,7 +19702,7 @@ function VideoToolbar({
|
|
|
19892
19702
|
onSetVideoId,
|
|
19893
19703
|
onRemove
|
|
19894
19704
|
}) {
|
|
19895
|
-
return /* @__PURE__ */
|
|
19705
|
+
return /* @__PURE__ */ jsxs13(
|
|
19896
19706
|
"div",
|
|
19897
19707
|
{
|
|
19898
19708
|
"data-ohw-bridge": "",
|
|
@@ -19904,7 +19714,7 @@ function VideoToolbar({
|
|
|
19904
19714
|
gap: 6,
|
|
19905
19715
|
alignItems: "center",
|
|
19906
19716
|
width: 280,
|
|
19907
|
-
background:
|
|
19717
|
+
background: OHW_BLUE2,
|
|
19908
19718
|
padding: 8,
|
|
19909
19719
|
borderRadius: 12,
|
|
19910
19720
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19912,9 +19722,9 @@ function VideoToolbar({
|
|
|
19912
19722
|
opacity: pending ? 0.6 : 1
|
|
19913
19723
|
},
|
|
19914
19724
|
children: [
|
|
19915
|
-
/* @__PURE__ */
|
|
19916
|
-
/* @__PURE__ */
|
|
19917
|
-
error && /* @__PURE__ */
|
|
19725
|
+
/* @__PURE__ */ jsx22(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19726
|
+
/* @__PURE__ */ jsx22(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19727
|
+
error && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19918
19728
|
]
|
|
19919
19729
|
}
|
|
19920
19730
|
);
|
|
@@ -20034,8 +19844,8 @@ function AiVideoOverlay({
|
|
|
20034
19844
|
const activeBlockRect = useLiveBlockRect(active);
|
|
20035
19845
|
const TOOLBAR_APPROX_H = 90;
|
|
20036
19846
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20037
|
-
return /* @__PURE__ */
|
|
20038
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
19847
|
+
return /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
19848
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx22(
|
|
20039
19849
|
"button",
|
|
20040
19850
|
{
|
|
20041
19851
|
type: "button",
|
|
@@ -20063,15 +19873,15 @@ function AiVideoOverlay({
|
|
|
20063
19873
|
fontSize: 14,
|
|
20064
19874
|
fontWeight: 700
|
|
20065
19875
|
},
|
|
20066
|
-
children: /* @__PURE__ */
|
|
19876
|
+
children: /* @__PURE__ */ jsx22(Star3, { size: 14, style: { pointerEvents: "none" } })
|
|
20067
19877
|
}
|
|
20068
19878
|
),
|
|
20069
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */
|
|
19879
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ jsx22(
|
|
20070
19880
|
ItemInteractionLayer,
|
|
20071
19881
|
{
|
|
20072
19882
|
rect: activeBlockRect,
|
|
20073
19883
|
state: toolbarState,
|
|
20074
|
-
toolbar: /* @__PURE__ */
|
|
19884
|
+
toolbar: /* @__PURE__ */ jsx22(
|
|
20075
19885
|
VideoToolbar,
|
|
20076
19886
|
{
|
|
20077
19887
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20146,10 +19956,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20146
19956
|
}
|
|
20147
19957
|
|
|
20148
19958
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20149
|
-
import { Fragment as Fragment10, jsx as
|
|
19959
|
+
import { Fragment as Fragment10, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
20150
19960
|
var PRIMARY6 = "#0885FE";
|
|
20151
|
-
var
|
|
20152
|
-
var
|
|
19961
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
19962
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20153
19963
|
function findCarouselItemElement(sectionId, index) {
|
|
20154
19964
|
const sectionEl = findByInstanceId(sectionId);
|
|
20155
19965
|
if (!sectionEl) return null;
|
|
@@ -20228,8 +20038,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20228
20038
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20229
20039
|
});
|
|
20230
20040
|
}
|
|
20231
|
-
function
|
|
20232
|
-
return /* @__PURE__ */
|
|
20041
|
+
function Pill3({ label, onClick, disabled }) {
|
|
20042
|
+
return /* @__PURE__ */ jsx23(
|
|
20233
20043
|
"button",
|
|
20234
20044
|
{
|
|
20235
20045
|
type: "button",
|
|
@@ -20245,7 +20055,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20245
20055
|
border: "none",
|
|
20246
20056
|
cursor: disabled ? "default" : "pointer",
|
|
20247
20057
|
background: "#ffffff",
|
|
20248
|
-
color:
|
|
20058
|
+
color: OHW_BLUE_DARK3,
|
|
20249
20059
|
opacity: disabled ? 0.4 : 1,
|
|
20250
20060
|
fontSize: 12,
|
|
20251
20061
|
lineHeight: "16px",
|
|
@@ -20263,7 +20073,7 @@ function TogglePill({
|
|
|
20263
20073
|
onToggle,
|
|
20264
20074
|
disabled
|
|
20265
20075
|
}) {
|
|
20266
|
-
return /* @__PURE__ */
|
|
20076
|
+
return /* @__PURE__ */ jsxs14(
|
|
20267
20077
|
"button",
|
|
20268
20078
|
{
|
|
20269
20079
|
type: "button",
|
|
@@ -20282,7 +20092,7 @@ function TogglePill({
|
|
|
20282
20092
|
border: "none",
|
|
20283
20093
|
cursor: disabled ? "default" : "pointer",
|
|
20284
20094
|
background: "#ffffff",
|
|
20285
|
-
color:
|
|
20095
|
+
color: OHW_BLUE_DARK3,
|
|
20286
20096
|
opacity: disabled ? 0.4 : 1,
|
|
20287
20097
|
fontSize: 12,
|
|
20288
20098
|
lineHeight: "16px",
|
|
@@ -20292,7 +20102,7 @@ function TogglePill({
|
|
|
20292
20102
|
},
|
|
20293
20103
|
children: [
|
|
20294
20104
|
label,
|
|
20295
|
-
/* @__PURE__ */
|
|
20105
|
+
/* @__PURE__ */ jsx23(
|
|
20296
20106
|
"span",
|
|
20297
20107
|
{
|
|
20298
20108
|
"aria-hidden": true,
|
|
@@ -20305,10 +20115,10 @@ function TogglePill({
|
|
|
20305
20115
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
20306
20116
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
20307
20117
|
// "disabled control" rather than "switch that is off".
|
|
20308
|
-
background: on ?
|
|
20118
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
20309
20119
|
transition: "background 120ms ease"
|
|
20310
20120
|
},
|
|
20311
|
-
children: /* @__PURE__ */
|
|
20121
|
+
children: /* @__PURE__ */ jsx23(
|
|
20312
20122
|
"span",
|
|
20313
20123
|
{
|
|
20314
20124
|
style: {
|
|
@@ -20337,7 +20147,7 @@ function CarouselSlideToolbar({
|
|
|
20337
20147
|
onChangeImage,
|
|
20338
20148
|
onToggleAutoplay
|
|
20339
20149
|
}) {
|
|
20340
|
-
return /* @__PURE__ */
|
|
20150
|
+
return /* @__PURE__ */ jsxs14(
|
|
20341
20151
|
"div",
|
|
20342
20152
|
{
|
|
20343
20153
|
"data-ohw-bridge": "",
|
|
@@ -20348,7 +20158,7 @@ function CarouselSlideToolbar({
|
|
|
20348
20158
|
flexDirection: "column",
|
|
20349
20159
|
gap: 6,
|
|
20350
20160
|
alignItems: "center",
|
|
20351
|
-
background:
|
|
20161
|
+
background: OHW_BLUE3,
|
|
20352
20162
|
padding: 8,
|
|
20353
20163
|
borderRadius: 12,
|
|
20354
20164
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20360,11 +20170,11 @@ function CarouselSlideToolbar({
|
|
|
20360
20170
|
pointerEvents: pending ? "none" : "auto"
|
|
20361
20171
|
},
|
|
20362
20172
|
children: [
|
|
20363
|
-
/* @__PURE__ */
|
|
20364
|
-
/* @__PURE__ */
|
|
20365
|
-
/* @__PURE__ */
|
|
20173
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20174
|
+
/* @__PURE__ */ jsx23(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20175
|
+
/* @__PURE__ */ jsx23(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20366
20176
|
] }),
|
|
20367
|
-
error && /* @__PURE__ */
|
|
20177
|
+
error && /* @__PURE__ */ jsx23("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20368
20178
|
]
|
|
20369
20179
|
}
|
|
20370
20180
|
);
|
|
@@ -20504,8 +20314,8 @@ function AiFadeCarouselOverlay({
|
|
|
20504
20314
|
const activeItemRect = useLiveItemRect2(active);
|
|
20505
20315
|
const TOOLBAR_APPROX_H = 90;
|
|
20506
20316
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20507
|
-
return /* @__PURE__ */
|
|
20508
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
20317
|
+
return /* @__PURE__ */ jsxs14(Fragment10, { children: [
|
|
20318
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx23(
|
|
20509
20319
|
"button",
|
|
20510
20320
|
{
|
|
20511
20321
|
type: "button",
|
|
@@ -20534,10 +20344,10 @@ function AiFadeCarouselOverlay({
|
|
|
20534
20344
|
fontSize: 14,
|
|
20535
20345
|
fontWeight: 700
|
|
20536
20346
|
},
|
|
20537
|
-
children: /* @__PURE__ */
|
|
20347
|
+
children: /* @__PURE__ */ jsx23(Star4, { size: 14, style: { pointerEvents: "none" } })
|
|
20538
20348
|
}
|
|
20539
20349
|
),
|
|
20540
|
-
swapping && /* @__PURE__ */
|
|
20350
|
+
swapping && /* @__PURE__ */ jsx23(
|
|
20541
20351
|
"div",
|
|
20542
20352
|
{
|
|
20543
20353
|
ref: skeletonRef,
|
|
@@ -20555,15 +20365,15 @@ function AiFadeCarouselOverlay({
|
|
|
20555
20365
|
zIndex: 2147483646,
|
|
20556
20366
|
pointerEvents: "none"
|
|
20557
20367
|
},
|
|
20558
|
-
children: /* @__PURE__ */
|
|
20368
|
+
children: /* @__PURE__ */ jsx23("style", { children: MEDIA_SKELETON_CSS })
|
|
20559
20369
|
}
|
|
20560
20370
|
),
|
|
20561
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */
|
|
20371
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx23(
|
|
20562
20372
|
ItemInteractionLayer,
|
|
20563
20373
|
{
|
|
20564
20374
|
rect: activeItemRect,
|
|
20565
20375
|
state: toolbarState,
|
|
20566
|
-
toolbar: /* @__PURE__ */
|
|
20376
|
+
toolbar: /* @__PURE__ */ jsx23(
|
|
20567
20377
|
CarouselSlideToolbar,
|
|
20568
20378
|
{
|
|
20569
20379
|
pending,
|
|
@@ -20916,11 +20726,118 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
20916
20726
|
// src/ui/link-modal/LinkPopover.tsx
|
|
20917
20727
|
import { useEffect as useEffect13 } from "react";
|
|
20918
20728
|
|
|
20729
|
+
// src/ui/dialog.tsx
|
|
20730
|
+
import * as React9 from "react";
|
|
20731
|
+
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
20732
|
+
import { X as X2 } from "lucide-react";
|
|
20733
|
+
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
20734
|
+
function Dialog2({
|
|
20735
|
+
...props
|
|
20736
|
+
}) {
|
|
20737
|
+
return /* @__PURE__ */ jsx24(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
20738
|
+
}
|
|
20739
|
+
function DialogPortal({
|
|
20740
|
+
...props
|
|
20741
|
+
}) {
|
|
20742
|
+
return /* @__PURE__ */ jsx24(DialogPrimitive.Portal, { ...props });
|
|
20743
|
+
}
|
|
20744
|
+
function DialogOverlay({
|
|
20745
|
+
className,
|
|
20746
|
+
...props
|
|
20747
|
+
}) {
|
|
20748
|
+
return /* @__PURE__ */ jsx24(
|
|
20749
|
+
DialogPrimitive.Overlay,
|
|
20750
|
+
{
|
|
20751
|
+
"data-slot": "dialog-overlay",
|
|
20752
|
+
"data-ohw-link-modal-root": "",
|
|
20753
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
20754
|
+
...props
|
|
20755
|
+
}
|
|
20756
|
+
);
|
|
20757
|
+
}
|
|
20758
|
+
var DialogContent = React9.forwardRef(
|
|
20759
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
20760
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
20761
|
+
return /* @__PURE__ */ jsxs15(DialogPortal, { container: container ?? void 0, children: [
|
|
20762
|
+
/* @__PURE__ */ jsx24(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
20763
|
+
/* @__PURE__ */ jsxs15(
|
|
20764
|
+
DialogPrimitive.Content,
|
|
20765
|
+
{
|
|
20766
|
+
ref,
|
|
20767
|
+
"data-slot": "dialog-content",
|
|
20768
|
+
className: cn(
|
|
20769
|
+
positionMode,
|
|
20770
|
+
"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",
|
|
20771
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
20772
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
20773
|
+
className
|
|
20774
|
+
),
|
|
20775
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
20776
|
+
...props,
|
|
20777
|
+
children: [
|
|
20778
|
+
children,
|
|
20779
|
+
showCloseButton ? /* @__PURE__ */ jsx24(
|
|
20780
|
+
DialogPrimitive.Close,
|
|
20781
|
+
{
|
|
20782
|
+
type: "button",
|
|
20783
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
20784
|
+
"aria-label": "Close",
|
|
20785
|
+
children: /* @__PURE__ */ jsx24(X2, { size: 16, "aria-hidden": true })
|
|
20786
|
+
}
|
|
20787
|
+
) : null
|
|
20788
|
+
]
|
|
20789
|
+
}
|
|
20790
|
+
)
|
|
20791
|
+
] });
|
|
20792
|
+
}
|
|
20793
|
+
);
|
|
20794
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
20795
|
+
function DialogHeader({
|
|
20796
|
+
className,
|
|
20797
|
+
...props
|
|
20798
|
+
}) {
|
|
20799
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
20800
|
+
}
|
|
20801
|
+
function DialogFooter({
|
|
20802
|
+
className,
|
|
20803
|
+
...props
|
|
20804
|
+
}) {
|
|
20805
|
+
return /* @__PURE__ */ jsx24(
|
|
20806
|
+
"div",
|
|
20807
|
+
{
|
|
20808
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
20809
|
+
...props
|
|
20810
|
+
}
|
|
20811
|
+
);
|
|
20812
|
+
}
|
|
20813
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
20814
|
+
DialogPrimitive.Title,
|
|
20815
|
+
{
|
|
20816
|
+
ref,
|
|
20817
|
+
className: cn(
|
|
20818
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
20819
|
+
className
|
|
20820
|
+
),
|
|
20821
|
+
...props
|
|
20822
|
+
}
|
|
20823
|
+
));
|
|
20824
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
20825
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
20826
|
+
DialogPrimitive.Description,
|
|
20827
|
+
{
|
|
20828
|
+
ref,
|
|
20829
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
20830
|
+
...props
|
|
20831
|
+
}
|
|
20832
|
+
));
|
|
20833
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
20834
|
+
var DialogClose = DialogPrimitive.Close;
|
|
20835
|
+
|
|
20919
20836
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
20920
20837
|
import { Info, X as X4 } from "lucide-react";
|
|
20921
20838
|
|
|
20922
20839
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
20923
|
-
import { ArrowRight as
|
|
20840
|
+
import { ArrowRight as ArrowRight2, File, GalleryVertical } from "lucide-react";
|
|
20924
20841
|
import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
20925
20842
|
function DestinationBreadcrumb({
|
|
20926
20843
|
pageTitle,
|
|
@@ -20934,7 +20851,7 @@ function DestinationBreadcrumb({
|
|
|
20934
20851
|
/* @__PURE__ */ jsx25("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
20935
20852
|
] }),
|
|
20936
20853
|
/* @__PURE__ */ jsx25(
|
|
20937
|
-
|
|
20854
|
+
ArrowRight2,
|
|
20938
20855
|
{
|
|
20939
20856
|
size: 16,
|
|
20940
20857
|
className: "shrink-0 text-muted-foreground",
|
|
@@ -21046,7 +20963,7 @@ function Label({ className, ...props }) {
|
|
|
21046
20963
|
}
|
|
21047
20964
|
|
|
21048
20965
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
21049
|
-
import { ChevronDown as
|
|
20966
|
+
import { ChevronDown as ChevronDown4, File as File2, X as X3 } from "lucide-react";
|
|
21050
20967
|
import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
21051
20968
|
function FieldChevron({
|
|
21052
20969
|
onClick
|
|
@@ -21059,7 +20976,7 @@ function FieldChevron({
|
|
|
21059
20976
|
onClick,
|
|
21060
20977
|
"aria-label": "Open page list",
|
|
21061
20978
|
tabIndex: -1,
|
|
21062
|
-
children: /* @__PURE__ */ jsx29(
|
|
20979
|
+
children: /* @__PURE__ */ jsx29(ChevronDown4, { size: 16 })
|
|
21063
20980
|
}
|
|
21064
20981
|
);
|
|
21065
20982
|
}
|
|
@@ -21289,7 +21206,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
21289
21206
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
21290
21207
|
import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
|
|
21291
21208
|
import { createPortal as createPortal2 } from "react-dom";
|
|
21292
|
-
import { ArrowLeft as
|
|
21209
|
+
import { ArrowLeft as ArrowLeft2, Check as Check3 } from "lucide-react";
|
|
21293
21210
|
import { usePathname, useRouter as useRouter2 } from "next/navigation";
|
|
21294
21211
|
|
|
21295
21212
|
// src/lib/parent-scroll.ts
|
|
@@ -21566,7 +21483,7 @@ function SectionPickerOverlay({
|
|
|
21566
21483
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
21567
21484
|
onClick: onBack,
|
|
21568
21485
|
children: [
|
|
21569
|
-
/* @__PURE__ */ jsx31(
|
|
21486
|
+
/* @__PURE__ */ jsx31(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
21570
21487
|
"Back"
|
|
21571
21488
|
]
|
|
21572
21489
|
}
|
|
@@ -21635,7 +21552,7 @@ function SectionPickerOverlay({
|
|
|
21635
21552
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
21636
21553
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
21637
21554
|
"aria-hidden": true,
|
|
21638
|
-
children: /* @__PURE__ */ jsx31(
|
|
21555
|
+
children: /* @__PURE__ */ jsx31(Check3, { className: "size-5" })
|
|
21639
21556
|
}
|
|
21640
21557
|
) : null
|
|
21641
21558
|
]
|
|
@@ -22019,7 +21936,6 @@ function shouldUseDevFixtures() {
|
|
|
22019
21936
|
function getLogoElement(el) {
|
|
22020
21937
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
22021
21938
|
if (marked) return marked;
|
|
22022
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
22023
21939
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
22024
21940
|
if (!root) return null;
|
|
22025
21941
|
const anchor = el.closest("a");
|
|
@@ -22089,7 +22005,7 @@ function addFooterColumnWithPersist({
|
|
|
22089
22005
|
import {
|
|
22090
22006
|
useCallback as useCallback9,
|
|
22091
22007
|
useEffect as useEffect14,
|
|
22092
|
-
useLayoutEffect as
|
|
22008
|
+
useLayoutEffect as useLayoutEffect5,
|
|
22093
22009
|
useRef as useRef11,
|
|
22094
22010
|
useState as useState15
|
|
22095
22011
|
} from "react";
|
|
@@ -22186,7 +22102,7 @@ function FloatingPanel({
|
|
|
22186
22102
|
return () => window.removeEventListener("message", onParentScroll);
|
|
22187
22103
|
}, [open]);
|
|
22188
22104
|
const positionRef = useRef11(position);
|
|
22189
|
-
|
|
22105
|
+
useLayoutEffect5(() => {
|
|
22190
22106
|
if (!open) {
|
|
22191
22107
|
positionRef.current = position;
|
|
22192
22108
|
return;
|
|
@@ -22196,7 +22112,7 @@ function FloatingPanel({
|
|
|
22196
22112
|
}
|
|
22197
22113
|
positionRef.current = position;
|
|
22198
22114
|
}, [open, position, liveScroll, parentScroll]);
|
|
22199
|
-
|
|
22115
|
+
useLayoutEffect5(() => {
|
|
22200
22116
|
if (!open || !panelRef.current) return;
|
|
22201
22117
|
const el = panelRef.current;
|
|
22202
22118
|
const header = el.querySelector("[data-ohw-floating-panel-header]");
|
|
@@ -22405,7 +22321,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
22405
22321
|
}
|
|
22406
22322
|
|
|
22407
22323
|
// src/ui/button-style-panel.tsx
|
|
22408
|
-
import { Check as
|
|
22324
|
+
import { Check as Check4 } from "lucide-react";
|
|
22409
22325
|
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
22410
22326
|
var SIZE_LABEL = { s: "S", m: "M", l: "L" };
|
|
22411
22327
|
function ButtonStylePanel({
|
|
@@ -22476,7 +22392,7 @@ function ButtonStylePanel({
|
|
|
22476
22392
|
{
|
|
22477
22393
|
className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
22478
22394
|
"aria-hidden": true,
|
|
22479
|
-
children: /* @__PURE__ */ jsx35(
|
|
22395
|
+
children: /* @__PURE__ */ jsx35(Check4, { className: "size-3", strokeWidth: 3 })
|
|
22480
22396
|
}
|
|
22481
22397
|
) : null
|
|
22482
22398
|
]
|
|
@@ -23501,7 +23417,7 @@ function useSectionDrag({
|
|
|
23501
23417
|
}
|
|
23502
23418
|
|
|
23503
23419
|
// src/ui/footer-container-chrome.tsx
|
|
23504
|
-
import { Plus as
|
|
23420
|
+
import { Plus as Plus3 } from "lucide-react";
|
|
23505
23421
|
import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
23506
23422
|
function FooterContainerChrome({
|
|
23507
23423
|
rect,
|
|
@@ -23542,7 +23458,7 @@ function FooterContainerChrome({
|
|
|
23542
23458
|
if (addDisabled) return;
|
|
23543
23459
|
onAdd();
|
|
23544
23460
|
},
|
|
23545
|
-
children: /* @__PURE__ */ jsx36(
|
|
23461
|
+
children: /* @__PURE__ */ jsx36(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
23546
23462
|
}
|
|
23547
23463
|
) }),
|
|
23548
23464
|
/* @__PURE__ */ jsx36(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
@@ -23721,7 +23637,7 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
23721
23637
|
}
|
|
23722
23638
|
|
|
23723
23639
|
// src/ui/navbar-container-chrome.tsx
|
|
23724
|
-
import { Plus as
|
|
23640
|
+
import { Plus as Plus4 } from "lucide-react";
|
|
23725
23641
|
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
23726
23642
|
function NavbarContainerChrome({
|
|
23727
23643
|
rect,
|
|
@@ -23757,7 +23673,7 @@ function NavbarContainerChrome({
|
|
|
23757
23673
|
e.stopPropagation();
|
|
23758
23674
|
onAdd();
|
|
23759
23675
|
},
|
|
23760
|
-
children: /* @__PURE__ */ jsx37(
|
|
23676
|
+
children: /* @__PURE__ */ jsx37(Plus4, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
23761
23677
|
}
|
|
23762
23678
|
)
|
|
23763
23679
|
}
|
|
@@ -23829,7 +23745,7 @@ function Badge({ className, variant, ...props }) {
|
|
|
23829
23745
|
}
|
|
23830
23746
|
|
|
23831
23747
|
// src/OhhwellsBridge.tsx
|
|
23832
|
-
import { Brush as Brush2, Link as Link2, Plus as
|
|
23748
|
+
import { Brush as Brush2, Link as Link2, Plus as Plus5, Settings } from "lucide-react";
|
|
23833
23749
|
import { Fragment as Fragment13, jsx as jsx40, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
23834
23750
|
var PRIMARY7 = "#0885FE";
|
|
23835
23751
|
var IMAGE_FADE_MS = 300;
|
|
@@ -24606,7 +24522,7 @@ function getNavigationSelectionParent(el) {
|
|
|
24606
24522
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
24607
24523
|
return resolveFooterLinksContainerFrom(el);
|
|
24608
24524
|
}
|
|
24609
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24525
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24610
24526
|
return getNavigationRoot(el);
|
|
24611
24527
|
}
|
|
24612
24528
|
return null;
|
|
@@ -24828,6 +24744,7 @@ var ICONS = {
|
|
|
24828
24744
|
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"/>',
|
|
24829
24745
|
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"/>'
|
|
24830
24746
|
};
|
|
24747
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
24831
24748
|
var SELECTION_CHROME_GAP2 = 4;
|
|
24832
24749
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
24833
24750
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24925,7 +24842,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
24925
24842
|
el.style.top = `${top}px`;
|
|
24926
24843
|
el.style.height = `${height}px`;
|
|
24927
24844
|
}
|
|
24928
|
-
var
|
|
24845
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
24929
24846
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
24930
24847
|
const isAbove = transform.includes("translateY(-100%)");
|
|
24931
24848
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -24952,8 +24869,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
24952
24869
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
24953
24870
|
const half = toolbarWidth / 2;
|
|
24954
24871
|
return Math.max(
|
|
24955
|
-
|
|
24956
|
-
Math.min(centerX, window.innerWidth -
|
|
24872
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
24873
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
24957
24874
|
);
|
|
24958
24875
|
}
|
|
24959
24876
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -25354,7 +25271,7 @@ function OhhwellsBridge() {
|
|
|
25354
25271
|
}, []);
|
|
25355
25272
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
25356
25273
|
const [subdomain, setSubdomain] = useState18(() => resolveSubdomain(subdomainFromQuery));
|
|
25357
|
-
|
|
25274
|
+
useLayoutEffect6(() => {
|
|
25358
25275
|
const next = resolveSubdomain(subdomainFromQuery);
|
|
25359
25276
|
if (next !== subdomain) setSubdomain(next);
|
|
25360
25277
|
if (next) return;
|
|
@@ -25805,6 +25722,21 @@ function OhhwellsBridge() {
|
|
|
25805
25722
|
const [isItemDragging, setIsItemDragging] = useState18(false);
|
|
25806
25723
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState18(false);
|
|
25807
25724
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
25725
|
+
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
25726
|
+
const floatingPanelOpenRef = useRef14(false);
|
|
25727
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
25728
|
+
const floatingPanelRef = useRef14(null);
|
|
25729
|
+
floatingPanelRef.current = floatingPanel;
|
|
25730
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
25731
|
+
const buttonCollectionDragRef = useRef14(null);
|
|
25732
|
+
const buttonDropInsertIndexRef = useRef14(null);
|
|
25733
|
+
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
25734
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
25735
|
+
const buttonPointerDragRef = useRef14(null);
|
|
25736
|
+
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
25737
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
25738
|
+
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
25739
|
+
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
25808
25740
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState18(null);
|
|
25809
25741
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState18(null);
|
|
25810
25742
|
const footerDragRef = useRef14(null);
|
|
@@ -25830,21 +25762,6 @@ function OhhwellsBridge() {
|
|
|
25830
25762
|
const stylesRef = useRef14("");
|
|
25831
25763
|
const appliedDrawerRef = useRef14(null);
|
|
25832
25764
|
const pendingDeleteUndoRef = useRef14(null);
|
|
25833
|
-
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
25834
|
-
const floatingPanelOpenRef = useRef14(false);
|
|
25835
|
-
const floatingPanelRef = useRef14(null);
|
|
25836
|
-
floatingPanelRef.current = floatingPanel;
|
|
25837
|
-
const setFloatingPanelRef = useRef14(setFloatingPanel);
|
|
25838
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
25839
|
-
const buttonCollectionDragRef = useRef14(null);
|
|
25840
|
-
const buttonDropInsertIndexRef = useRef14(null);
|
|
25841
|
-
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
25842
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
25843
|
-
const buttonPointerDragRef = useRef14(null);
|
|
25844
|
-
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
25845
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
25846
|
-
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
25847
|
-
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
25848
25765
|
const [sitePages, setSitePages] = useState18([]);
|
|
25849
25766
|
const [sectionsByPath, setSectionsByPath] = useState18({});
|
|
25850
25767
|
const sectionsPrefetchGenRef = useRef14(0);
|
|
@@ -25853,18 +25770,7 @@ function OhhwellsBridge() {
|
|
|
25853
25770
|
const linkPopoverOpenRef = useRef14(false);
|
|
25854
25771
|
const linkPopoverGraceUntilRef = useRef14(0);
|
|
25855
25772
|
setLinkPopoverRef.current = setLinkPopover;
|
|
25856
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
25857
25773
|
linkPopoverSessionRef.current = linkPopover;
|
|
25858
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
25859
|
-
useEffect17(() => {
|
|
25860
|
-
const syncViewport = () => {
|
|
25861
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
25862
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
25863
|
-
};
|
|
25864
|
-
syncViewport();
|
|
25865
|
-
window.addEventListener("resize", syncViewport);
|
|
25866
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
25867
|
-
}, []);
|
|
25868
25774
|
useEffect17(() => {
|
|
25869
25775
|
setSectionOrderPersistHandler((entries) => {
|
|
25870
25776
|
const currentPath = window.location.pathname;
|
|
@@ -27532,7 +27438,7 @@ function OhhwellsBridge() {
|
|
|
27532
27438
|
isFooterFrameSelection,
|
|
27533
27439
|
postToParent2
|
|
27534
27440
|
]);
|
|
27535
|
-
|
|
27441
|
+
useLayoutEffect6(() => {
|
|
27536
27442
|
if (!subdomain || isEditMode) {
|
|
27537
27443
|
setFetchState("done");
|
|
27538
27444
|
return;
|
|
@@ -27559,7 +27465,6 @@ function OhhwellsBridge() {
|
|
|
27559
27465
|
applyAiFooterFromContent(content);
|
|
27560
27466
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27561
27467
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
27562
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27563
27468
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27564
27469
|
}
|
|
27565
27470
|
applyBrandChrome(content);
|
|
@@ -27570,12 +27475,12 @@ function OhhwellsBridge() {
|
|
|
27570
27475
|
if (key === "__ohw_sections") continue;
|
|
27571
27476
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27572
27477
|
if (key === AI_FOOTER_KEY) continue;
|
|
27573
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27574
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27575
27478
|
if (key === BRAND_KIT_KEY) continue;
|
|
27576
27479
|
if (key === STYLE_STORE_KEY) continue;
|
|
27577
27480
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27481
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27578
27482
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27483
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27579
27484
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27580
27485
|
continue;
|
|
27581
27486
|
}
|
|
@@ -27791,18 +27696,17 @@ function OhhwellsBridge() {
|
|
|
27791
27696
|
}
|
|
27792
27697
|
applyAiFooterFromContent(content);
|
|
27793
27698
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27794
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27795
27699
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27796
27700
|
}
|
|
27797
27701
|
for (const [key, val] of Object.entries(content)) {
|
|
27798
27702
|
if (key === "__ohw_sections") continue;
|
|
27799
27703
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27800
27704
|
if (key === AI_FOOTER_KEY) continue;
|
|
27801
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27802
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27803
27705
|
if (key === BRAND_KIT_KEY) continue;
|
|
27804
27706
|
if (key === STYLE_STORE_KEY) continue;
|
|
27805
27707
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27708
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27709
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27806
27710
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27807
27711
|
continue;
|
|
27808
27712
|
}
|
|
@@ -27885,7 +27789,7 @@ function OhhwellsBridge() {
|
|
|
27885
27789
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
27886
27790
|
};
|
|
27887
27791
|
}, [subdomain, isEditMode, pathname]);
|
|
27888
|
-
|
|
27792
|
+
useLayoutEffect6(() => {
|
|
27889
27793
|
const el = document.getElementById("ohw-loader");
|
|
27890
27794
|
if (!el) return;
|
|
27891
27795
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
@@ -28069,11 +27973,26 @@ function OhhwellsBridge() {
|
|
|
28069
27973
|
const t2 = setTimeout(measure, 500);
|
|
28070
27974
|
const ro = new ResizeObserver(schedule);
|
|
28071
27975
|
ro.observe(document.body);
|
|
27976
|
+
let lastWidth = window.innerWidth;
|
|
27977
|
+
let resizeTimers = [];
|
|
27978
|
+
const clearResizeTimers = () => {
|
|
27979
|
+
resizeTimers.forEach(clearTimeout);
|
|
27980
|
+
resizeTimers = [];
|
|
27981
|
+
};
|
|
27982
|
+
const handleResize = () => {
|
|
27983
|
+
if (window.innerWidth === lastWidth) return;
|
|
27984
|
+
lastWidth = window.innerWidth;
|
|
27985
|
+
clearResizeTimers();
|
|
27986
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
27987
|
+
};
|
|
27988
|
+
window.addEventListener("resize", handleResize);
|
|
28072
27989
|
return () => {
|
|
28073
27990
|
clearTimeout(t1);
|
|
28074
27991
|
clearTimeout(t2);
|
|
28075
27992
|
if (raf != null) cancelAnimationFrame(raf);
|
|
28076
27993
|
ro.disconnect();
|
|
27994
|
+
clearResizeTimers();
|
|
27995
|
+
window.removeEventListener("resize", handleResize);
|
|
28077
27996
|
};
|
|
28078
27997
|
}, [pathname, isEditMode, postToParent2]);
|
|
28079
27998
|
useEffect17(() => {
|
|
@@ -28370,13 +28289,6 @@ function OhhwellsBridge() {
|
|
|
28370
28289
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28371
28290
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28372
28291
|
if (isInsideLinkEditor(target)) return;
|
|
28373
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28374
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28375
|
-
if (target.closest(
|
|
28376
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28377
|
-
)) {
|
|
28378
|
-
return;
|
|
28379
|
-
}
|
|
28380
28292
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28381
28293
|
clearMediaSelectionRef.current();
|
|
28382
28294
|
}
|
|
@@ -28400,6 +28312,13 @@ function OhhwellsBridge() {
|
|
|
28400
28312
|
return;
|
|
28401
28313
|
}
|
|
28402
28314
|
}
|
|
28315
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28316
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28317
|
+
if (target.closest(
|
|
28318
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28319
|
+
)) {
|
|
28320
|
+
return;
|
|
28321
|
+
}
|
|
28403
28322
|
{
|
|
28404
28323
|
const formEl = getFormElement(target);
|
|
28405
28324
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -28553,13 +28472,9 @@ function OhhwellsBridge() {
|
|
|
28553
28472
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
28554
28473
|
e.preventDefault();
|
|
28555
28474
|
e.stopPropagation();
|
|
28475
|
+
selectIconElementRef.current(editable);
|
|
28556
28476
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
28557
28477
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
28558
|
-
if (aiIcon) {
|
|
28559
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
28560
|
-
} else {
|
|
28561
|
-
selectIconElementRef.current(editable);
|
|
28562
|
-
}
|
|
28563
28478
|
postToParentRef.current({
|
|
28564
28479
|
type: "ow:icon-pick",
|
|
28565
28480
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -28787,9 +28702,6 @@ function OhhwellsBridge() {
|
|
|
28787
28702
|
setHoveredItemRect(null);
|
|
28788
28703
|
hoveredNavContainerRef.current = null;
|
|
28789
28704
|
setHoveredNavContainerRect(null);
|
|
28790
|
-
siblingHintElRef.current = null;
|
|
28791
|
-
setSiblingHintRect(null);
|
|
28792
|
-
setSiblingHintRects([]);
|
|
28793
28705
|
return;
|
|
28794
28706
|
}
|
|
28795
28707
|
{
|
|
@@ -28910,6 +28822,7 @@ function OhhwellsBridge() {
|
|
|
28910
28822
|
hoveredNavContainerRef.current = null;
|
|
28911
28823
|
setHoveredNavContainerRect(null);
|
|
28912
28824
|
hoveredItemElRef.current = editable;
|
|
28825
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
28913
28826
|
}
|
|
28914
28827
|
}
|
|
28915
28828
|
}
|
|
@@ -29619,11 +29532,7 @@ function OhhwellsBridge() {
|
|
|
29619
29532
|
};
|
|
29620
29533
|
const handleMouseMove = (e) => {
|
|
29621
29534
|
const { clientX, clientY } = e;
|
|
29622
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29623
|
-
dismissImageHover();
|
|
29624
|
-
clearImageHover();
|
|
29625
|
-
return;
|
|
29626
|
-
}
|
|
29535
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29627
29536
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
29628
29537
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
29629
29538
|
formHoverElRef.current = null;
|
|
@@ -29652,12 +29561,7 @@ function OhhwellsBridge() {
|
|
|
29652
29561
|
setHoveredItemRect(null);
|
|
29653
29562
|
hoveredNavContainerRef.current = null;
|
|
29654
29563
|
setHoveredNavContainerRect(null);
|
|
29655
|
-
siblingHintElRef.current = null;
|
|
29656
|
-
setSiblingHintRect(null);
|
|
29657
|
-
setSiblingHintRects([]);
|
|
29658
29564
|
dismissImageHover();
|
|
29659
|
-
clearImageHover();
|
|
29660
|
-
setSectionGap(null);
|
|
29661
29565
|
return;
|
|
29662
29566
|
}
|
|
29663
29567
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -29669,11 +29573,7 @@ function OhhwellsBridge() {
|
|
|
29669
29573
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
29670
29574
|
const { clientX, clientY } = e.data;
|
|
29671
29575
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
29672
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29673
|
-
dismissImageHover();
|
|
29674
|
-
clearImageHover();
|
|
29675
|
-
return;
|
|
29676
|
-
}
|
|
29576
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29677
29577
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
29678
29578
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
29679
29579
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -30053,7 +29953,6 @@ function OhhwellsBridge() {
|
|
|
30053
29953
|
applyAiFooterFromContent(content);
|
|
30054
29954
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
30055
29955
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
30056
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
30057
29956
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
30058
29957
|
}
|
|
30059
29958
|
applyBrandChrome(content);
|
|
@@ -30068,12 +29967,12 @@ function OhhwellsBridge() {
|
|
|
30068
29967
|
}
|
|
30069
29968
|
if (key === AI_SECTIONS_KEY) continue;
|
|
30070
29969
|
if (key === AI_FOOTER_KEY) continue;
|
|
30071
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30072
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30073
29970
|
if (key === BRAND_KIT_KEY) continue;
|
|
30074
29971
|
if (key === STYLE_STORE_KEY) continue;
|
|
30075
29972
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
29973
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30076
29974
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
29975
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30077
29976
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
30078
29977
|
continue;
|
|
30079
29978
|
}
|
|
@@ -30709,12 +30608,6 @@ function OhhwellsBridge() {
|
|
|
30709
30608
|
closeLinkPopoverRef.current();
|
|
30710
30609
|
return;
|
|
30711
30610
|
}
|
|
30712
|
-
if (floatingPanelOpenRef.current) {
|
|
30713
|
-
setFloatingPanelRef.current(null);
|
|
30714
|
-
deselectRef.current();
|
|
30715
|
-
deactivateRef.current();
|
|
30716
|
-
return;
|
|
30717
|
-
}
|
|
30718
30611
|
deselectRef.current();
|
|
30719
30612
|
deactivateRef.current();
|
|
30720
30613
|
clearMediaSelectionRef.current();
|
|
@@ -31537,10 +31430,10 @@ function OhhwellsBridge() {
|
|
|
31537
31430
|
window.removeEventListener("message", handleDeleteSection);
|
|
31538
31431
|
window.removeEventListener("message", handleDuplicateSection);
|
|
31539
31432
|
window.removeEventListener("message", handleDeactivate);
|
|
31433
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31540
31434
|
window.removeEventListener("message", handleToastAction);
|
|
31541
31435
|
window.removeEventListener("message", handleFormCount);
|
|
31542
31436
|
window.removeEventListener("message", handleUiEscape);
|
|
31543
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31544
31437
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
31545
31438
|
autoSaveTimers.current.clear();
|
|
31546
31439
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -31834,7 +31727,7 @@ function OhhwellsBridge() {
|
|
|
31834
31727
|
postToParent2({
|
|
31835
31728
|
type: "ow:ready",
|
|
31836
31729
|
version: "1",
|
|
31837
|
-
bridgeVersion: "0.1.
|
|
31730
|
+
bridgeVersion: "0.1.152",
|
|
31838
31731
|
path: pathname,
|
|
31839
31732
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31840
31733
|
sections
|
|
@@ -32569,7 +32462,7 @@ function OhhwellsBridge() {
|
|
|
32569
32462
|
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
|
|
32570
32463
|
onClick: () => setFieldTypePickerOpen((open) => !open),
|
|
32571
32464
|
"data-ohw-add-field": "",
|
|
32572
|
-
children: /* @__PURE__ */ jsx40(
|
|
32465
|
+
children: /* @__PURE__ */ jsx40(Plus5, { size: 15, "aria-hidden": true })
|
|
32573
32466
|
}
|
|
32574
32467
|
),
|
|
32575
32468
|
/* @__PURE__ */ jsx40("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|