@ohhwells/bridge 0.1.149-next.400 → 0.1.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +718 -809
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +726 -833
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +1 -1
- package/dist/pages.cjs.map +1 -1
- package/dist/pages.js +1 -1
- package/dist/pages.js.map +1 -1
- package/dist/styles.css +0 -116
- package/package.json +3 -3
package/dist/index.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
|
}
|
|
@@ -7748,7 +7733,7 @@ var AI_MOBILE_CSS = [
|
|
|
7748
7733
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7749
7734
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7750
7735
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7751
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7736
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
7752
7737
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7753
7738
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7754
7739
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7764,10 +7749,8 @@ var AI_MOBILE_CSS = [
|
|
|
7764
7749
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7765
7750
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7766
7751
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7767
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7768
|
-
|
|
7769
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7770
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7752
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7753
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7771
7754
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7772
7755
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7773
7756
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -7972,31 +7955,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
7972
7955
|
function textAttrs(ctx, path) {
|
|
7973
7956
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
7974
7957
|
}
|
|
7975
|
-
var AI_RESPONSIVE_CSS = [
|
|
7976
|
-
"@media (max-width: 960px) {",
|
|
7977
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
7978
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
7979
|
-
"}",
|
|
7980
|
-
"@media (max-width: 640px) {",
|
|
7981
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
7982
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
7983
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
7984
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
7985
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
7986
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
7987
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
7988
|
-
// layered text used to be.
|
|
7989
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
7990
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
7991
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
7992
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
7993
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
7994
|
-
// other rule had already been taught to stand down.
|
|
7995
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
7996
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
7997
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
7998
|
-
"}"
|
|
7999
|
-
].join("\n");
|
|
8000
7958
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8001
7959
|
function MediaBox({
|
|
8002
7960
|
refValue,
|
|
@@ -8051,7 +8009,7 @@ function MediaBox({
|
|
|
8051
8009
|
position: fill ? "absolute" : void 0,
|
|
8052
8010
|
inset: fill ? 0 : void 0,
|
|
8053
8011
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8054
|
-
height: fill ? "100%" :
|
|
8012
|
+
height: fill ? "100%" : void 0,
|
|
8055
8013
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8056
8014
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8057
8015
|
borderRadius: radius,
|
|
@@ -9547,7 +9505,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9547
9505
|
return /* @__PURE__ */ jsx(
|
|
9548
9506
|
"div",
|
|
9549
9507
|
{
|
|
9550
|
-
"data-ai-grid":
|
|
9508
|
+
"data-ai-grid": "",
|
|
9551
9509
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9552
9510
|
style: {
|
|
9553
9511
|
display: "grid",
|
|
@@ -9849,7 +9807,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9849
9807
|
},
|
|
9850
9808
|
children: [
|
|
9851
9809
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
9852
|
-
// The section's `data-ai-
|
|
9810
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
9853
9811
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9854
9812
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9855
9813
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10268,7 +10226,6 @@ function AiTreeRenderer({
|
|
|
10268
10226
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10269
10227
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10270
10228
|
...bgAttrs,
|
|
10271
|
-
"data-ai-responsive": "",
|
|
10272
10229
|
style: {
|
|
10273
10230
|
position: "relative",
|
|
10274
10231
|
padding: `${padCss} 0`,
|
|
@@ -10282,13 +10239,12 @@ function AiTreeRenderer({
|
|
|
10282
10239
|
...fillHeight ? { display: "grid" } : {}
|
|
10283
10240
|
},
|
|
10284
10241
|
children: [
|
|
10285
|
-
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
10286
|
-
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10287
10242
|
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10243
|
+
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10288
10244
|
/* @__PURE__ */ jsx(
|
|
10289
10245
|
"div",
|
|
10290
10246
|
{
|
|
10291
|
-
"data-ai-
|
|
10247
|
+
"data-ai-container": "",
|
|
10292
10248
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10293
10249
|
style: {
|
|
10294
10250
|
position: "relative",
|
|
@@ -10305,7 +10261,7 @@ function AiTreeRenderer({
|
|
|
10305
10261
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
10306
10262
|
"div",
|
|
10307
10263
|
{
|
|
10308
|
-
"data-ai-
|
|
10264
|
+
"data-ai-row": "",
|
|
10309
10265
|
style: {
|
|
10310
10266
|
display: "grid",
|
|
10311
10267
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -10967,10 +10923,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10967
10923
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
10968
10924
|
continue;
|
|
10969
10925
|
}
|
|
10926
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
10970
10927
|
let container = existing?.container;
|
|
10971
|
-
let isNewMount = false;
|
|
10972
10928
|
if (!container || !container.isConnected) {
|
|
10973
|
-
isNewMount = true;
|
|
10974
10929
|
existing?.root.unmount();
|
|
10975
10930
|
container?.remove();
|
|
10976
10931
|
container = document.createElement("div");
|
|
@@ -17412,7 +17367,6 @@ function MediaOverlay({
|
|
|
17412
17367
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
17413
17368
|
);
|
|
17414
17369
|
}, [isVideo]);
|
|
17415
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
17416
17370
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
17417
17371
|
const box = {
|
|
17418
17372
|
position: "fixed",
|
|
@@ -17511,10 +17465,11 @@ function MediaOverlay({
|
|
|
17511
17465
|
className: "flex items-center justify-center cursor-pointer",
|
|
17512
17466
|
style: {
|
|
17513
17467
|
...box,
|
|
17514
|
-
//
|
|
17515
|
-
//
|
|
17516
|
-
//
|
|
17517
|
-
|
|
17468
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
17469
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
17470
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
17471
|
+
// Replace still works.
|
|
17472
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
17518
17473
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
17519
17474
|
// than hovered. Hover keeps the existing tinted preview.
|
|
17520
17475
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -17541,17 +17496,17 @@ function MediaOverlay({
|
|
|
17541
17496
|
},
|
|
17542
17497
|
children: [
|
|
17543
17498
|
isVideo ? /* @__PURE__ */ jsx16(Film, { size: 14 }) : /* @__PURE__ */ jsx16(ImageIcon, { size: 14 }),
|
|
17544
|
-
|
|
17499
|
+
isVideo ? "Replace video" : "Replace image"
|
|
17545
17500
|
]
|
|
17546
17501
|
}
|
|
17547
17502
|
),
|
|
17548
|
-
|
|
17503
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ jsxs7(
|
|
17549
17504
|
Button,
|
|
17550
17505
|
{
|
|
17551
17506
|
"data-ohw-media-overlay": "",
|
|
17552
17507
|
variant: "outline",
|
|
17553
17508
|
size: "sm",
|
|
17554
|
-
"aria-label":
|
|
17509
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
17555
17510
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
17556
17511
|
style: {
|
|
17557
17512
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -17574,7 +17529,7 @@ function MediaOverlay({
|
|
|
17574
17529
|
},
|
|
17575
17530
|
children: [
|
|
17576
17531
|
isVideo ? /* @__PURE__ */ jsx16(Film, { size: 14 }) : /* @__PURE__ */ jsx16(ImageIcon, { size: 14 }),
|
|
17577
|
-
replaceMode === "full" ?
|
|
17532
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
17578
17533
|
]
|
|
17579
17534
|
}
|
|
17580
17535
|
)
|
|
@@ -18083,24 +18038,8 @@ function AiSectionOverlay({
|
|
|
18083
18038
|
}
|
|
18084
18039
|
|
|
18085
18040
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18086
|
-
import { useCallback as useCallback3, useEffect as useEffect6,
|
|
18087
|
-
import {
|
|
18088
|
-
AlignCenter,
|
|
18089
|
-
AlignLeft,
|
|
18090
|
-
AlignRight,
|
|
18091
|
-
ArrowLeft as ArrowLeft2,
|
|
18092
|
-
ArrowRight as ArrowRight2,
|
|
18093
|
-
Check as Check2,
|
|
18094
|
-
ChevronDown as ChevronDown3,
|
|
18095
|
-
Image as ImageIcon2,
|
|
18096
|
-
ImageMinus,
|
|
18097
|
-
ImagePlus,
|
|
18098
|
-
Link as LinkIcon,
|
|
18099
|
-
Minus,
|
|
18100
|
-
Palette,
|
|
18101
|
-
Plus as Plus2,
|
|
18102
|
-
Star
|
|
18103
|
-
} from "lucide-react";
|
|
18041
|
+
import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef5, useState as useState8 } from "react";
|
|
18042
|
+
import { Star } from "lucide-react";
|
|
18104
18043
|
|
|
18105
18044
|
// src/lib/ai-media-strip-tree.ts
|
|
18106
18045
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18214,6 +18153,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18214
18153
|
return true;
|
|
18215
18154
|
});
|
|
18216
18155
|
}
|
|
18156
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18157
|
+
return withMediaStrip(tree, (block) => {
|
|
18158
|
+
const items = block.items;
|
|
18159
|
+
if (index < 0 || index >= items.length) return false;
|
|
18160
|
+
items[index] = { ...items[index], alt };
|
|
18161
|
+
return true;
|
|
18162
|
+
});
|
|
18163
|
+
}
|
|
18217
18164
|
function setMediaStripItemLink(tree, index, link) {
|
|
18218
18165
|
return withMediaStrip(tree, (block) => {
|
|
18219
18166
|
const items = block.items;
|
|
@@ -18231,117 +18178,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18231
18178
|
});
|
|
18232
18179
|
}
|
|
18233
18180
|
|
|
18234
|
-
// src/ui/dialog.tsx
|
|
18235
|
-
import * as React9 from "react";
|
|
18236
|
-
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
18237
|
-
import { X as X2 } from "lucide-react";
|
|
18238
|
-
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
18239
|
-
function Dialog2({
|
|
18240
|
-
...props
|
|
18241
|
-
}) {
|
|
18242
|
-
return /* @__PURE__ */ jsx19(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
18243
|
-
}
|
|
18244
|
-
function DialogPortal({
|
|
18245
|
-
...props
|
|
18246
|
-
}) {
|
|
18247
|
-
return /* @__PURE__ */ jsx19(DialogPrimitive.Portal, { ...props });
|
|
18248
|
-
}
|
|
18249
|
-
function DialogOverlay({
|
|
18250
|
-
className,
|
|
18251
|
-
...props
|
|
18252
|
-
}) {
|
|
18253
|
-
return /* @__PURE__ */ jsx19(
|
|
18254
|
-
DialogPrimitive.Overlay,
|
|
18255
|
-
{
|
|
18256
|
-
"data-slot": "dialog-overlay",
|
|
18257
|
-
"data-ohw-link-modal-root": "",
|
|
18258
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18259
|
-
...props
|
|
18260
|
-
}
|
|
18261
|
-
);
|
|
18262
|
-
}
|
|
18263
|
-
var DialogContent = React9.forwardRef(
|
|
18264
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18265
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
18266
|
-
return /* @__PURE__ */ jsxs10(DialogPortal, { container: container ?? void 0, children: [
|
|
18267
|
-
/* @__PURE__ */ jsx19(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18268
|
-
/* @__PURE__ */ jsxs10(
|
|
18269
|
-
DialogPrimitive.Content,
|
|
18270
|
-
{
|
|
18271
|
-
ref,
|
|
18272
|
-
"data-slot": "dialog-content",
|
|
18273
|
-
className: cn(
|
|
18274
|
-
positionMode,
|
|
18275
|
-
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[448px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-visible",
|
|
18276
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18277
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18278
|
-
className
|
|
18279
|
-
),
|
|
18280
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
18281
|
-
...props,
|
|
18282
|
-
children: [
|
|
18283
|
-
children,
|
|
18284
|
-
showCloseButton ? /* @__PURE__ */ jsx19(
|
|
18285
|
-
DialogPrimitive.Close,
|
|
18286
|
-
{
|
|
18287
|
-
type: "button",
|
|
18288
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18289
|
-
"aria-label": "Close",
|
|
18290
|
-
children: /* @__PURE__ */ jsx19(X2, { size: 16, "aria-hidden": true })
|
|
18291
|
-
}
|
|
18292
|
-
) : null
|
|
18293
|
-
]
|
|
18294
|
-
}
|
|
18295
|
-
)
|
|
18296
|
-
] });
|
|
18297
|
-
}
|
|
18298
|
-
);
|
|
18299
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
18300
|
-
function DialogHeader({
|
|
18301
|
-
className,
|
|
18302
|
-
...props
|
|
18303
|
-
}) {
|
|
18304
|
-
return /* @__PURE__ */ jsx19("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18305
|
-
}
|
|
18306
|
-
function DialogFooter({
|
|
18307
|
-
className,
|
|
18308
|
-
...props
|
|
18309
|
-
}) {
|
|
18310
|
-
return /* @__PURE__ */ jsx19(
|
|
18311
|
-
"div",
|
|
18312
|
-
{
|
|
18313
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
18314
|
-
...props
|
|
18315
|
-
}
|
|
18316
|
-
);
|
|
18317
|
-
}
|
|
18318
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
18319
|
-
DialogPrimitive.Title,
|
|
18320
|
-
{
|
|
18321
|
-
ref,
|
|
18322
|
-
className: cn(
|
|
18323
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18324
|
-
className
|
|
18325
|
-
),
|
|
18326
|
-
...props
|
|
18327
|
-
}
|
|
18328
|
-
));
|
|
18329
|
-
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
18330
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
18331
|
-
DialogPrimitive.Description,
|
|
18332
|
-
{
|
|
18333
|
-
ref,
|
|
18334
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
18335
|
-
...props
|
|
18336
|
-
}
|
|
18337
|
-
));
|
|
18338
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
18339
|
-
var DialogClose = DialogPrimitive.Close;
|
|
18340
|
-
|
|
18341
18181
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18342
|
-
import { Fragment as Fragment6, jsx as
|
|
18343
|
-
var PRIMARY3 = "
|
|
18344
|
-
var
|
|
18182
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
18183
|
+
var PRIMARY3 = "#0885FE";
|
|
18184
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18185
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
18345
18186
|
function findMediaStripItemElement(sectionId, index) {
|
|
18346
18187
|
const sectionEl = findByInstanceId(sectionId);
|
|
18347
18188
|
if (!sectionEl) return null;
|
|
@@ -18351,35 +18192,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18351
18192
|
}
|
|
18352
18193
|
return null;
|
|
18353
18194
|
}
|
|
18354
|
-
function
|
|
18355
|
-
|
|
18356
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18357
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18358
|
-
if (!itemEl) return null;
|
|
18359
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18360
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18361
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18362
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18363
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
18364
|
-
return { sectionId, index };
|
|
18365
|
-
}
|
|
18366
|
-
function sameRef(a, b) {
|
|
18367
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18368
|
-
}
|
|
18369
|
-
function rectOf(el) {
|
|
18195
|
+
function readRect2(ref) {
|
|
18196
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18370
18197
|
if (!el) return null;
|
|
18371
18198
|
const r2 = el.getBoundingClientRect();
|
|
18372
18199
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18373
18200
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18374
18201
|
}
|
|
18375
|
-
function
|
|
18376
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18377
|
-
}
|
|
18378
|
-
function readStripRect(ref) {
|
|
18379
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18380
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18381
|
-
}
|
|
18382
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18202
|
+
function useLiveItemRect(ref) {
|
|
18383
18203
|
const [rect, setRect] = useState8(null);
|
|
18384
18204
|
useEffect6(() => {
|
|
18385
18205
|
if (!ref) {
|
|
@@ -18387,7 +18207,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18387
18207
|
return;
|
|
18388
18208
|
}
|
|
18389
18209
|
const update = () => {
|
|
18390
|
-
const next =
|
|
18210
|
+
const next = readRect2(ref);
|
|
18391
18211
|
setRect(
|
|
18392
18212
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18393
18213
|
);
|
|
@@ -18402,49 +18222,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18402
18222
|
window.removeEventListener("resize", update);
|
|
18403
18223
|
clearInterval(interval);
|
|
18404
18224
|
};
|
|
18405
|
-
}, [ref?.sectionId, ref?.index
|
|
18225
|
+
}, [ref?.sectionId, ref?.index]);
|
|
18406
18226
|
return rect;
|
|
18407
18227
|
}
|
|
18408
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
18409
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18410
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18411
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
18412
|
-
const slotRef = useRef5(null);
|
|
18413
|
-
const [shift, setShift] = useState8(0);
|
|
18414
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
18415
|
-
useLayoutEffect4(() => {
|
|
18416
|
-
const slot = slotRef.current;
|
|
18417
|
-
if (!slot) return;
|
|
18418
|
-
const clamp = () => {
|
|
18419
|
-
const w = slot.offsetWidth;
|
|
18420
|
-
if (w <= 0) return;
|
|
18421
|
-
const half = w / 2;
|
|
18422
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18423
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18424
|
-
};
|
|
18425
|
-
clamp();
|
|
18426
|
-
const ro = new ResizeObserver(clamp);
|
|
18427
|
-
ro.observe(slot);
|
|
18428
|
-
return () => ro.disconnect();
|
|
18429
|
-
}, [centerX, children]);
|
|
18430
|
-
const mobile = window.innerWidth <= 480;
|
|
18431
|
-
return /* @__PURE__ */ jsx20(
|
|
18432
|
-
"div",
|
|
18433
|
-
{
|
|
18434
|
-
ref: slotRef,
|
|
18435
|
-
"data-ohw-bridge": "",
|
|
18436
|
-
"data-ohw-item-interaction": "",
|
|
18437
|
-
className: "pointer-events-auto fixed",
|
|
18438
|
-
style: {
|
|
18439
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18440
|
-
left: centerX + shift,
|
|
18441
|
-
transform: "translate(-50%, -100%)",
|
|
18442
|
-
zIndex: 2147483645
|
|
18443
|
-
},
|
|
18444
|
-
children
|
|
18445
|
-
}
|
|
18446
|
-
);
|
|
18447
|
-
}
|
|
18448
18228
|
function requestValidateTree(postToParent2, tree) {
|
|
18449
18229
|
return new Promise((resolve) => {
|
|
18450
18230
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18481,72 +18261,116 @@ function requestAssetPick(postToParent2) {
|
|
|
18481
18261
|
postToParent2({ type: "ow:asset-pick", id });
|
|
18482
18262
|
});
|
|
18483
18263
|
}
|
|
18484
|
-
function
|
|
18264
|
+
function Pill({
|
|
18485
18265
|
label,
|
|
18486
18266
|
onClick,
|
|
18487
|
-
disabled
|
|
18488
|
-
active
|
|
18489
|
-
children
|
|
18267
|
+
disabled,
|
|
18268
|
+
active
|
|
18490
18269
|
}) {
|
|
18491
|
-
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18270
|
+
return /* @__PURE__ */ jsx19(
|
|
18271
|
+
"button",
|
|
18272
|
+
{
|
|
18273
|
+
type: "button",
|
|
18274
|
+
onClick,
|
|
18275
|
+
disabled,
|
|
18276
|
+
style: {
|
|
18277
|
+
height: 28,
|
|
18278
|
+
padding: "0 10px",
|
|
18279
|
+
display: "inline-flex",
|
|
18280
|
+
alignItems: "center",
|
|
18281
|
+
gap: 4,
|
|
18282
|
+
borderRadius: 999,
|
|
18283
|
+
border: "none",
|
|
18284
|
+
cursor: disabled ? "default" : "pointer",
|
|
18285
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18286
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18287
|
+
opacity: disabled ? 0.4 : 1,
|
|
18288
|
+
fontSize: 12,
|
|
18289
|
+
lineHeight: "16px",
|
|
18290
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18291
|
+
whiteSpace: "nowrap",
|
|
18292
|
+
flex: "0 0 auto"
|
|
18293
|
+
},
|
|
18294
|
+
children: label
|
|
18295
|
+
}
|
|
18296
|
+
);
|
|
18499
18297
|
}
|
|
18500
|
-
function
|
|
18501
|
-
|
|
18502
|
-
value,
|
|
18503
|
-
|
|
18504
|
-
|
|
18505
|
-
|
|
18506
|
-
|
|
18507
|
-
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
|
|
18511
|
-
"
|
|
18512
|
-
|
|
18513
|
-
|
|
18514
|
-
|
|
18515
|
-
|
|
18516
|
-
|
|
18517
|
-
|
|
18518
|
-
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
) }),
|
|
18522
|
-
/* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
18523
|
-
const selected = option.value === value;
|
|
18524
|
-
return /* @__PURE__ */ jsxs11(
|
|
18525
|
-
DropdownMenuItem,
|
|
18298
|
+
function AltInput({ value, onCommit }) {
|
|
18299
|
+
const [draft, setDraft] = useState8(value);
|
|
18300
|
+
useEffect6(() => setDraft(value), [value]);
|
|
18301
|
+
return /* @__PURE__ */ jsxs10(
|
|
18302
|
+
"div",
|
|
18303
|
+
{
|
|
18304
|
+
style: {
|
|
18305
|
+
display: "flex",
|
|
18306
|
+
alignItems: "center",
|
|
18307
|
+
gap: 6,
|
|
18308
|
+
height: 28,
|
|
18309
|
+
padding: "0 12px",
|
|
18310
|
+
borderRadius: 999,
|
|
18311
|
+
background: "#ffffff",
|
|
18312
|
+
width: "100%",
|
|
18313
|
+
maxWidth: 260,
|
|
18314
|
+
boxSizing: "border-box"
|
|
18315
|
+
},
|
|
18316
|
+
children: [
|
|
18317
|
+
/* @__PURE__ */ jsx19(
|
|
18318
|
+
"span",
|
|
18526
18319
|
{
|
|
18527
|
-
|
|
18528
|
-
|
|
18529
|
-
|
|
18530
|
-
|
|
18531
|
-
|
|
18532
|
-
|
|
18533
|
-
|
|
18534
|
-
|
|
18535
|
-
|
|
18536
|
-
|
|
18537
|
-
)
|
|
18538
|
-
|
|
18539
|
-
|
|
18540
|
-
|
|
18320
|
+
style: {
|
|
18321
|
+
flex: "0 0 auto",
|
|
18322
|
+
color: OHW_BLUE_DARK,
|
|
18323
|
+
fontSize: 10,
|
|
18324
|
+
fontWeight: 700,
|
|
18325
|
+
textTransform: "uppercase",
|
|
18326
|
+
letterSpacing: 0.4
|
|
18327
|
+
},
|
|
18328
|
+
children: "Alt"
|
|
18329
|
+
}
|
|
18330
|
+
),
|
|
18331
|
+
/* @__PURE__ */ jsx19(
|
|
18332
|
+
"input",
|
|
18333
|
+
{
|
|
18334
|
+
type: "text",
|
|
18335
|
+
value: draft,
|
|
18336
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18337
|
+
onBlur: () => {
|
|
18338
|
+
if (draft !== value) onCommit(draft);
|
|
18339
|
+
},
|
|
18340
|
+
onKeyDown: (e) => {
|
|
18341
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18342
|
+
if (e.key === "Escape") {
|
|
18343
|
+
setDraft(value);
|
|
18344
|
+
e.currentTarget.blur();
|
|
18345
|
+
}
|
|
18346
|
+
},
|
|
18347
|
+
placeholder: "Describe this image",
|
|
18348
|
+
"aria-label": "Image alt text",
|
|
18349
|
+
style: {
|
|
18350
|
+
flex: 1,
|
|
18351
|
+
minWidth: 0,
|
|
18352
|
+
border: "none",
|
|
18353
|
+
outline: "none",
|
|
18354
|
+
background: "transparent",
|
|
18355
|
+
fontSize: 12,
|
|
18356
|
+
lineHeight: "16px",
|
|
18357
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18358
|
+
color: "#1f2937"
|
|
18359
|
+
}
|
|
18360
|
+
}
|
|
18361
|
+
)
|
|
18362
|
+
]
|
|
18363
|
+
}
|
|
18364
|
+
);
|
|
18541
18365
|
}
|
|
18542
18366
|
var VARIANTS = [
|
|
18543
18367
|
{ value: "logos", label: "Logos" },
|
|
18544
18368
|
{ value: "reel", label: "Reel" }
|
|
18545
18369
|
];
|
|
18546
18370
|
var ALIGNS = [
|
|
18547
|
-
{ value: "left", label: "
|
|
18548
|
-
{ value: "center", label: "
|
|
18549
|
-
{ value: "right", label: "
|
|
18371
|
+
{ value: "left", label: "Left" },
|
|
18372
|
+
{ value: "center", label: "Center" },
|
|
18373
|
+
{ value: "right", label: "Right" }
|
|
18550
18374
|
];
|
|
18551
18375
|
var HOVERS = [
|
|
18552
18376
|
{ value: "none", label: "None" },
|
|
@@ -18554,104 +18378,104 @@ var HOVERS = [
|
|
|
18554
18378
|
{ value: "zoom", label: "Zoom" },
|
|
18555
18379
|
{ value: "fade", label: "Fade" }
|
|
18556
18380
|
];
|
|
18381
|
+
var TREATMENTS = [
|
|
18382
|
+
{ value: "color", label: "Color" },
|
|
18383
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
18384
|
+
];
|
|
18557
18385
|
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18558
|
-
function
|
|
18559
|
-
|
|
18560
|
-
linkTarget,
|
|
18561
|
-
onClose,
|
|
18562
|
-
onSave
|
|
18563
|
-
}) {
|
|
18564
|
-
const [draft, setDraft] = useState8(href);
|
|
18565
|
-
const [newTab, setNewTab] = useState8(linkTarget !== "same-tab");
|
|
18386
|
+
function LinkInput({ value, onCommit }) {
|
|
18387
|
+
const [draft, setDraft] = useState8(value);
|
|
18566
18388
|
const [invalid, setInvalid] = useState8(false);
|
|
18567
|
-
|
|
18389
|
+
useEffect6(() => {
|
|
18390
|
+
setDraft(value);
|
|
18391
|
+
setInvalid(false);
|
|
18392
|
+
}, [value]);
|
|
18393
|
+
const commit = () => {
|
|
18568
18394
|
const next = draft.trim();
|
|
18569
|
-
if (next
|
|
18570
|
-
|
|
18571
|
-
|
|
18572
|
-
|
|
18573
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
18574
|
-
onClose();
|
|
18395
|
+
if (next === value) return setInvalid(false);
|
|
18396
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
18397
|
+
setInvalid(false);
|
|
18398
|
+
onCommit(next);
|
|
18575
18399
|
};
|
|
18576
|
-
return /* @__PURE__ */
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
"
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
|
|
18586
|
-
|
|
18587
|
-
|
|
18588
|
-
|
|
18589
|
-
|
|
18590
|
-
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
"
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
18598
|
-
|
|
18599
|
-
|
|
18600
|
-
|
|
18601
|
-
|
|
18602
|
-
|
|
18603
|
-
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18400
|
+
return /* @__PURE__ */ jsxs10(
|
|
18401
|
+
"div",
|
|
18402
|
+
{
|
|
18403
|
+
style: {
|
|
18404
|
+
display: "flex",
|
|
18405
|
+
alignItems: "center",
|
|
18406
|
+
gap: 6,
|
|
18407
|
+
height: 28,
|
|
18408
|
+
padding: "0 12px",
|
|
18409
|
+
borderRadius: 999,
|
|
18410
|
+
background: "#ffffff",
|
|
18411
|
+
width: "100%",
|
|
18412
|
+
maxWidth: 260,
|
|
18413
|
+
boxSizing: "border-box",
|
|
18414
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18415
|
+
},
|
|
18416
|
+
children: [
|
|
18417
|
+
/* @__PURE__ */ jsx19(
|
|
18418
|
+
"span",
|
|
18419
|
+
{
|
|
18420
|
+
style: {
|
|
18421
|
+
flex: "0 0 auto",
|
|
18422
|
+
color: OHW_BLUE_DARK,
|
|
18423
|
+
fontSize: 10,
|
|
18424
|
+
fontWeight: 700,
|
|
18425
|
+
textTransform: "uppercase",
|
|
18426
|
+
letterSpacing: 0.4
|
|
18427
|
+
},
|
|
18428
|
+
children: "Link"
|
|
18429
|
+
}
|
|
18430
|
+
),
|
|
18431
|
+
/* @__PURE__ */ jsx19(
|
|
18432
|
+
"input",
|
|
18433
|
+
{
|
|
18434
|
+
type: "text",
|
|
18435
|
+
inputMode: "url",
|
|
18436
|
+
value: draft,
|
|
18437
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18438
|
+
onBlur: commit,
|
|
18439
|
+
onKeyDown: (e) => {
|
|
18440
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18441
|
+
if (e.key === "Escape") {
|
|
18442
|
+
setDraft(value);
|
|
18443
|
+
setInvalid(false);
|
|
18444
|
+
e.currentTarget.blur();
|
|
18445
|
+
}
|
|
18446
|
+
},
|
|
18447
|
+
placeholder: "https://example.com",
|
|
18448
|
+
"aria-label": "Image link URL",
|
|
18449
|
+
"aria-invalid": invalid,
|
|
18450
|
+
style: {
|
|
18451
|
+
flex: 1,
|
|
18452
|
+
minWidth: 0,
|
|
18453
|
+
border: "none",
|
|
18454
|
+
outline: "none",
|
|
18455
|
+
background: "transparent",
|
|
18456
|
+
fontSize: 12,
|
|
18457
|
+
lineHeight: "16px",
|
|
18458
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18459
|
+
color: "#1f2937"
|
|
18460
|
+
}
|
|
18461
|
+
}
|
|
18462
|
+
)
|
|
18463
|
+
]
|
|
18464
|
+
}
|
|
18465
|
+
);
|
|
18641
18466
|
}
|
|
18642
18467
|
function MediaStripToolbar({
|
|
18643
18468
|
entry,
|
|
18644
18469
|
index,
|
|
18645
18470
|
pending,
|
|
18646
18471
|
error,
|
|
18647
|
-
itemEditOn,
|
|
18648
|
-
onToggleItemEdit,
|
|
18649
18472
|
onSetVariant,
|
|
18650
18473
|
onSetAlign,
|
|
18651
18474
|
onSetHover,
|
|
18652
18475
|
onSetTreatment,
|
|
18653
18476
|
onResize,
|
|
18654
|
-
|
|
18477
|
+
onSetAlt,
|
|
18478
|
+
onSetLink,
|
|
18655
18479
|
onAddItem,
|
|
18656
18480
|
onRemoveItem,
|
|
18657
18481
|
onChangeImage,
|
|
@@ -18660,102 +18484,81 @@ function MediaStripToolbar({
|
|
|
18660
18484
|
}) {
|
|
18661
18485
|
const items = mediaStripItems(entry.tree);
|
|
18662
18486
|
const itemCount = items.length;
|
|
18487
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
18488
|
+
const currentHref = items[index]?.href ?? "";
|
|
18489
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18663
18490
|
const slots = findMediaStripSlots(entry.tree);
|
|
18664
18491
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18665
18492
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
18666
18493
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
18667
18494
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
18668
18495
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18669
|
-
const
|
|
18670
|
-
const
|
|
18671
|
-
|
|
18496
|
+
const isMobile = window.innerWidth <= 480;
|
|
18497
|
+
const rowStyle = isMobile ? {
|
|
18498
|
+
display: "flex",
|
|
18499
|
+
gap: 6,
|
|
18500
|
+
flexWrap: "nowrap",
|
|
18501
|
+
justifyContent: "center",
|
|
18502
|
+
overflowX: "auto",
|
|
18503
|
+
WebkitOverflowScrolling: "touch",
|
|
18504
|
+
width: "100%",
|
|
18505
|
+
scrollbarWidth: "none"
|
|
18506
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
18507
|
+
return /* @__PURE__ */ jsxs10(
|
|
18672
18508
|
"div",
|
|
18673
18509
|
{
|
|
18674
18510
|
"data-ohw-bridge": "",
|
|
18675
18511
|
"data-ohw-toolbar": "",
|
|
18676
18512
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18677
|
-
|
|
18678
|
-
|
|
18513
|
+
style: {
|
|
18514
|
+
display: "flex",
|
|
18515
|
+
flexDirection: "column",
|
|
18516
|
+
gap: 6,
|
|
18517
|
+
alignItems: "center",
|
|
18518
|
+
background: OHW_BLUE,
|
|
18519
|
+
padding: 8,
|
|
18520
|
+
borderRadius: 12,
|
|
18521
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18522
|
+
pointerEvents: pending ? "none" : "auto",
|
|
18523
|
+
opacity: pending ? 0.6 : 1,
|
|
18524
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
18525
|
+
},
|
|
18679
18526
|
children: [
|
|
18680
|
-
/* @__PURE__ */
|
|
18681
|
-
|
|
18682
|
-
{
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
18686
|
-
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
) }),
|
|
18713
|
-
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
18714
|
-
] }),
|
|
18715
|
-
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18716
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ jsx20(ImageIcon2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18717
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ jsx20(LinkIcon, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18718
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ jsx20(ArrowLeft2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18719
|
-
/* @__PURE__ */ jsx20(
|
|
18720
|
-
ToolbarAction,
|
|
18721
|
-
{
|
|
18722
|
-
label: gatedLabel("Move right"),
|
|
18723
|
-
onClick: onMoveRight,
|
|
18724
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
18725
|
-
children: /* @__PURE__ */ jsx20(ArrowRight2, { size: 16, style: { pointerEvents: "none" } })
|
|
18726
|
-
}
|
|
18727
|
-
),
|
|
18728
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ jsx20(ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18729
|
-
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18730
|
-
/* @__PURE__ */ jsx20(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
18731
|
-
/* @__PURE__ */ jsx20(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
18732
|
-
/* @__PURE__ */ jsx20(
|
|
18733
|
-
ToolbarAction,
|
|
18734
|
-
{
|
|
18735
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
18736
|
-
active: treatment === "grayscale",
|
|
18737
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
18738
|
-
children: /* @__PURE__ */ jsx20(Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
18739
|
-
}
|
|
18740
|
-
),
|
|
18741
|
-
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18742
|
-
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx20(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ jsx20(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
18743
|
-
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18744
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ jsx20(Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18745
|
-
/* @__PURE__ */ jsxs11("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
18746
|
-
sizeValue,
|
|
18747
|
-
"px"
|
|
18748
|
-
] }),
|
|
18749
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ jsx20(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18750
|
-
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18751
|
-
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ jsx20(ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18752
|
-
]
|
|
18753
|
-
}
|
|
18754
|
-
),
|
|
18755
|
-
error && /* @__PURE__ */ jsx20("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18527
|
+
/* @__PURE__ */ jsxs10("div", { style: rowStyle, children: [
|
|
18528
|
+
VARIANTS.map((v) => /* @__PURE__ */ jsx19(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
18529
|
+
ALIGNS.map((a) => /* @__PURE__ */ jsx19(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
18530
|
+
] }),
|
|
18531
|
+
/* @__PURE__ */ jsxs10("div", { style: rowStyle, children: [
|
|
18532
|
+
HOVERS.map((h) => /* @__PURE__ */ jsx19(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
18533
|
+
TREATMENTS.map((t) => /* @__PURE__ */ jsx19(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
18534
|
+
] }),
|
|
18535
|
+
/* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
18536
|
+
/* @__PURE__ */ jsx19(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
18537
|
+
/* @__PURE__ */ jsxs10("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
18538
|
+
sizeValue,
|
|
18539
|
+
"px"
|
|
18540
|
+
] }),
|
|
18541
|
+
/* @__PURE__ */ jsx19(Pill, { label: "+", onClick: () => onResize(8) })
|
|
18542
|
+
] }),
|
|
18543
|
+
/* @__PURE__ */ jsx19("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ jsx19(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
18544
|
+
/* @__PURE__ */ jsx19("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ jsx19(LinkInput, { value: currentHref, onCommit: (href) => onSetLink(href, currentTarget) }) }),
|
|
18545
|
+
currentHref && /* @__PURE__ */ jsxs10("div", { style: rowStyle, children: [
|
|
18546
|
+
/* @__PURE__ */ jsx19(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
18547
|
+
/* @__PURE__ */ jsx19(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
18548
|
+
] }),
|
|
18549
|
+
/* @__PURE__ */ jsxs10("div", { style: rowStyle, children: [
|
|
18550
|
+
/* @__PURE__ */ jsx19(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
18551
|
+
/* @__PURE__ */ jsx19(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
18552
|
+
/* @__PURE__ */ jsx19(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
18553
|
+
] }),
|
|
18554
|
+
/* @__PURE__ */ jsxs10("div", { style: rowStyle, children: [
|
|
18555
|
+
/* @__PURE__ */ jsx19(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
18556
|
+
/* @__PURE__ */ jsx19(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
18557
|
+
] }),
|
|
18558
|
+
error && /* @__PURE__ */ jsx19("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
18756
18559
|
]
|
|
18757
18560
|
}
|
|
18758
|
-
)
|
|
18561
|
+
);
|
|
18759
18562
|
}
|
|
18760
18563
|
function findMediaStripSlots(tree) {
|
|
18761
18564
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -18774,23 +18577,31 @@ function AiMediaStripOverlay({
|
|
|
18774
18577
|
}) {
|
|
18775
18578
|
const [hover, setHover] = useState8(null);
|
|
18776
18579
|
const [active, setActive] = useState8(null);
|
|
18777
|
-
const [itemEditOn, setItemEditOn] = useState8(false);
|
|
18778
|
-
const [linkOpen, setLinkOpen] = useState8(false);
|
|
18779
18580
|
const [pending, setPending] = useState8(false);
|
|
18780
18581
|
const [error, setError] = useState8(null);
|
|
18781
18582
|
const activeRef = useRef5(null);
|
|
18782
18583
|
activeRef.current = active;
|
|
18783
|
-
const linkOpenRef = useRef5(false);
|
|
18784
|
-
linkOpenRef.current = linkOpen;
|
|
18785
18584
|
useEffect6(() => {
|
|
18786
18585
|
const onMove = (e) => {
|
|
18787
|
-
const ref = itemRefFromTarget(e.target);
|
|
18788
18586
|
const t = e.target;
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18587
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18588
|
+
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]")) {
|
|
18589
|
+
return;
|
|
18590
|
+
}
|
|
18591
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
18592
|
+
if (!itemEl) {
|
|
18593
|
+
setHover(null);
|
|
18594
|
+
return;
|
|
18595
|
+
}
|
|
18596
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18597
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18598
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18599
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18600
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
18601
|
+
setHover(null);
|
|
18602
|
+
return;
|
|
18603
|
+
}
|
|
18604
|
+
setHover({ sectionId, index });
|
|
18794
18605
|
};
|
|
18795
18606
|
const onLeave = () => setHover(null);
|
|
18796
18607
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -18802,25 +18613,23 @@ function AiMediaStripOverlay({
|
|
|
18802
18613
|
}, []);
|
|
18803
18614
|
useEffect6(() => {
|
|
18804
18615
|
const onClick = (e) => {
|
|
18616
|
+
const current = activeRef.current;
|
|
18617
|
+
if (!current) return;
|
|
18805
18618
|
const t = e.target;
|
|
18806
|
-
if (!(t instanceof
|
|
18807
|
-
if (t.closest(
|
|
18808
|
-
const
|
|
18809
|
-
if (
|
|
18810
|
-
|
|
18811
|
-
setItemEditOn(false);
|
|
18619
|
+
if (!(t instanceof HTMLElement)) return;
|
|
18620
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
18621
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
18622
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
18623
|
+
setActive(null);
|
|
18812
18624
|
setError(null);
|
|
18813
|
-
setActive(ref);
|
|
18814
18625
|
};
|
|
18815
18626
|
document.addEventListener("click", onClick, true);
|
|
18816
18627
|
return () => document.removeEventListener("click", onClick, true);
|
|
18817
|
-
}, [
|
|
18628
|
+
}, []);
|
|
18818
18629
|
useEffect6(() => {
|
|
18819
18630
|
const onBlur = () => {
|
|
18820
18631
|
if (!activeRef.current) return;
|
|
18821
18632
|
setActive(null);
|
|
18822
|
-
setItemEditOn(false);
|
|
18823
|
-
setLinkOpen(false);
|
|
18824
18633
|
setError(null);
|
|
18825
18634
|
};
|
|
18826
18635
|
window.addEventListener("blur", onBlur);
|
|
@@ -18830,10 +18639,7 @@ function AiMediaStripOverlay({
|
|
|
18830
18639
|
const onKeyDown = (e) => {
|
|
18831
18640
|
if (e.key !== "Escape") return;
|
|
18832
18641
|
if (!activeRef.current) return;
|
|
18833
|
-
if (linkOpenRef.current) return;
|
|
18834
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
18835
18642
|
setActive(null);
|
|
18836
|
-
setItemEditOn(false);
|
|
18837
18643
|
setError(null);
|
|
18838
18644
|
};
|
|
18839
18645
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -18867,133 +18673,137 @@ function AiMediaStripOverlay({
|
|
|
18867
18673
|
tree: nextTree,
|
|
18868
18674
|
label: entry.label,
|
|
18869
18675
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
18870
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
18871
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
18872
|
-
// on every edit reads as the section jumping around.
|
|
18873
|
-
skipScrollIntoView: true
|
|
18676
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
18874
18677
|
});
|
|
18875
18678
|
return true;
|
|
18876
18679
|
},
|
|
18877
18680
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
18878
18681
|
);
|
|
18879
18682
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18683
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
18880
18684
|
const activeItemRect = useLiveItemRect(active);
|
|
18881
|
-
const
|
|
18882
|
-
const
|
|
18883
|
-
|
|
18884
|
-
|
|
18885
|
-
|
|
18886
|
-
|
|
18887
|
-
|
|
18888
|
-
|
|
18889
|
-
|
|
18890
|
-
|
|
18891
|
-
|
|
18892
|
-
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
|
|
18897
|
-
|
|
18898
|
-
|
|
18899
|
-
|
|
18900
|
-
|
|
18901
|
-
|
|
18902
|
-
|
|
18903
|
-
|
|
18904
|
-
|
|
18905
|
-
|
|
18906
|
-
|
|
18907
|
-
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18685
|
+
const TOOLBAR_APPROX_H = 170;
|
|
18686
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
18687
|
+
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
18688
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx19(
|
|
18689
|
+
"button",
|
|
18690
|
+
{
|
|
18691
|
+
type: "button",
|
|
18692
|
+
"data-ohw-toolbar": "",
|
|
18693
|
+
onClick: () => {
|
|
18694
|
+
clearInteractionChromeRef.current();
|
|
18695
|
+
setActive(hover);
|
|
18696
|
+
},
|
|
18697
|
+
"aria-label": "Configure media item",
|
|
18698
|
+
style: {
|
|
18699
|
+
position: "fixed",
|
|
18700
|
+
top: hoverHandleRect.top + 8,
|
|
18701
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
18702
|
+
width: 28,
|
|
18703
|
+
height: 28,
|
|
18704
|
+
borderRadius: 8,
|
|
18705
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
18706
|
+
background: "#ffffff",
|
|
18707
|
+
color: PRIMARY3,
|
|
18708
|
+
display: "flex",
|
|
18709
|
+
alignItems: "center",
|
|
18710
|
+
justifyContent: "center",
|
|
18711
|
+
cursor: "pointer",
|
|
18712
|
+
zIndex: 2147483643,
|
|
18713
|
+
fontSize: 14,
|
|
18714
|
+
fontWeight: 700
|
|
18715
|
+
},
|
|
18716
|
+
children: /* @__PURE__ */ jsx19(Star, { size: 14, style: { pointerEvents: "none" } })
|
|
18717
|
+
}
|
|
18718
|
+
),
|
|
18719
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx19(
|
|
18720
|
+
ItemInteractionLayer,
|
|
18721
|
+
{
|
|
18722
|
+
rect: activeItemRect,
|
|
18723
|
+
state: toolbarState,
|
|
18724
|
+
toolbar: /* @__PURE__ */ jsx19(
|
|
18725
|
+
MediaStripToolbar,
|
|
18726
|
+
{
|
|
18727
|
+
entry: activeEntry,
|
|
18728
|
+
index: active.index,
|
|
18729
|
+
pending,
|
|
18730
|
+
error,
|
|
18731
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18732
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18733
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18734
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18735
|
+
onResize: (delta) => {
|
|
18736
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18737
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18738
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18739
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18740
|
+
},
|
|
18741
|
+
onSetAlt: (alt) => {
|
|
18742
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
18743
|
+
},
|
|
18744
|
+
onSetLink: (href, linkTarget) => {
|
|
18915
18745
|
void runMutation(
|
|
18916
18746
|
active.sectionId,
|
|
18917
|
-
(tree) =>
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18747
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
18748
|
+
);
|
|
18749
|
+
},
|
|
18750
|
+
onAddItem: () => {
|
|
18751
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18752
|
+
if (!picked) return;
|
|
18753
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18754
|
+
void runMutation(
|
|
18755
|
+
active.sectionId,
|
|
18756
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18757
|
+
{ [picked.assetId]: picked.url }
|
|
18758
|
+
).then((applied) => {
|
|
18759
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18760
|
+
});
|
|
18921
18761
|
});
|
|
18922
|
-
}
|
|
18923
|
-
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
|
|
18928
|
-
|
|
18929
|
-
|
|
18930
|
-
|
|
18762
|
+
},
|
|
18763
|
+
onChangeImage: () => {
|
|
18764
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18765
|
+
if (!picked) return;
|
|
18766
|
+
void runMutation(
|
|
18767
|
+
active.sectionId,
|
|
18768
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
18769
|
+
{ [picked.assetId]: picked.url }
|
|
18770
|
+
);
|
|
18771
|
+
});
|
|
18772
|
+
},
|
|
18773
|
+
onRemoveItem: () => {
|
|
18774
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
18775
|
+
(applied) => {
|
|
18776
|
+
if (applied) setActive(null);
|
|
18777
|
+
}
|
|
18931
18778
|
);
|
|
18932
|
-
}
|
|
18933
|
-
|
|
18934
|
-
|
|
18935
|
-
|
|
18936
|
-
|
|
18937
|
-
|
|
18938
|
-
|
|
18939
|
-
|
|
18940
|
-
|
|
18941
|
-
|
|
18942
|
-
|
|
18943
|
-
|
|
18944
|
-
|
|
18945
|
-
|
|
18946
|
-
|
|
18947
|
-
},
|
|
18948
|
-
onMoveRight: () => {
|
|
18949
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18950
|
-
(applied) => {
|
|
18951
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18952
|
-
}
|
|
18953
|
-
);
|
|
18954
|
-
}
|
|
18955
|
-
}
|
|
18956
|
-
) }),
|
|
18957
|
-
/* @__PURE__ */ jsx20(
|
|
18958
|
-
"div",
|
|
18959
|
-
{
|
|
18960
|
-
"data-ohw-bridge": "",
|
|
18961
|
-
"data-ohw-item-interaction": "",
|
|
18962
|
-
"aria-hidden": true,
|
|
18963
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
18964
|
-
style: {
|
|
18965
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
18966
|
-
left: activeItemRect.left - 5,
|
|
18967
|
-
background: PRIMARY3,
|
|
18968
|
-
zIndex: 2147483644
|
|
18969
|
-
},
|
|
18970
|
-
children: "Media item"
|
|
18971
|
-
}
|
|
18972
|
-
),
|
|
18973
|
-
linkOpen && /* @__PURE__ */ jsx20(
|
|
18974
|
-
LinkModal,
|
|
18975
|
-
{
|
|
18976
|
-
href: activeHref,
|
|
18977
|
-
linkTarget: activeTarget,
|
|
18978
|
-
onClose: () => setLinkOpen(false),
|
|
18979
|
-
onSave: (href, linkTarget) => {
|
|
18980
|
-
void runMutation(
|
|
18981
|
-
active.sectionId,
|
|
18982
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
18983
|
-
);
|
|
18779
|
+
},
|
|
18780
|
+
onMoveLeft: () => {
|
|
18781
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18782
|
+
(applied) => {
|
|
18783
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18784
|
+
}
|
|
18785
|
+
);
|
|
18786
|
+
},
|
|
18787
|
+
onMoveRight: () => {
|
|
18788
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18789
|
+
(applied) => {
|
|
18790
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18791
|
+
}
|
|
18792
|
+
);
|
|
18793
|
+
}
|
|
18984
18794
|
}
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18795
|
+
)
|
|
18796
|
+
}
|
|
18797
|
+
)
|
|
18988
18798
|
] });
|
|
18989
18799
|
}
|
|
18990
18800
|
|
|
18991
18801
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
18992
|
-
import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as
|
|
18993
|
-
import { Check as
|
|
18994
|
-
import { Fragment as Fragment7, jsx as
|
|
18802
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as useLayoutEffect4, useRef as useRef6, useState as useState9 } from "react";
|
|
18803
|
+
import { Check as Check2, ChevronDown as ChevronDown3, Minus, Plus as Plus2, Star as Star2 } from "lucide-react";
|
|
18804
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
18995
18805
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
18996
|
-
var
|
|
18806
|
+
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]";
|
|
18997
18807
|
function findPricingCardElement(sectionId, index) {
|
|
18998
18808
|
const sectionEl = findByInstanceId(sectionId);
|
|
18999
18809
|
if (!sectionEl) return null;
|
|
@@ -19005,7 +18815,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19005
18815
|
}
|
|
19006
18816
|
function cardRefFromTarget(target) {
|
|
19007
18817
|
if (!(target instanceof Element)) return null;
|
|
19008
|
-
if (target.closest(
|
|
18818
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19009
18819
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19010
18820
|
if (!cardEl) return null;
|
|
19011
18821
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19015,21 +18825,21 @@ function cardRefFromTarget(target) {
|
|
|
19015
18825
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19016
18826
|
return { sectionId, index };
|
|
19017
18827
|
}
|
|
19018
|
-
function
|
|
18828
|
+
function sameRef(a, b) {
|
|
19019
18829
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19020
18830
|
}
|
|
19021
|
-
function
|
|
18831
|
+
function rectOf(el) {
|
|
19022
18832
|
if (!el) return null;
|
|
19023
18833
|
const r2 = el.getBoundingClientRect();
|
|
19024
18834
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19025
18835
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19026
18836
|
}
|
|
19027
18837
|
function readRect3(ref) {
|
|
19028
|
-
return
|
|
18838
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19029
18839
|
}
|
|
19030
18840
|
function readGridRect(ref) {
|
|
19031
18841
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19032
|
-
return
|
|
18842
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19033
18843
|
}
|
|
19034
18844
|
function useLiveCardRect(ref, grid = false) {
|
|
19035
18845
|
const [rect, setRect] = useState9(null);
|
|
@@ -19059,19 +18869,19 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19059
18869
|
}
|
|
19060
18870
|
var TOOLBAR_GRID_GAP = 52;
|
|
19061
18871
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19062
|
-
var
|
|
18872
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19063
18873
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19064
18874
|
const slotRef = useRef6(null);
|
|
19065
18875
|
const [shift, setShift] = useState9(0);
|
|
19066
18876
|
const centerX = gridRect.left + gridRect.width / 2;
|
|
19067
|
-
|
|
18877
|
+
useLayoutEffect4(() => {
|
|
19068
18878
|
const slot = slotRef.current;
|
|
19069
18879
|
if (!slot) return;
|
|
19070
18880
|
const clamp = () => {
|
|
19071
18881
|
const w = slot.offsetWidth;
|
|
19072
18882
|
if (w <= 0) return;
|
|
19073
18883
|
const half = w / 2;
|
|
19074
|
-
const clamped = Math.max(
|
|
18884
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19075
18885
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19076
18886
|
};
|
|
19077
18887
|
clamp();
|
|
@@ -19080,7 +18890,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19080
18890
|
return () => ro.disconnect();
|
|
19081
18891
|
}, [centerX, children]);
|
|
19082
18892
|
const mobile = window.innerWidth <= 480;
|
|
19083
|
-
return /* @__PURE__ */
|
|
18893
|
+
return /* @__PURE__ */ jsx20(
|
|
19084
18894
|
"div",
|
|
19085
18895
|
{
|
|
19086
18896
|
ref: slotRef,
|
|
@@ -19115,7 +18925,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
19115
18925
|
});
|
|
19116
18926
|
}
|
|
19117
18927
|
function StyleSwatch({ style }) {
|
|
19118
|
-
return /* @__PURE__ */
|
|
18928
|
+
return /* @__PURE__ */ jsx20(
|
|
19119
18929
|
"span",
|
|
19120
18930
|
{
|
|
19121
18931
|
"aria-hidden": true,
|
|
@@ -19129,35 +18939,35 @@ function StyleSwatch({ style }) {
|
|
|
19129
18939
|
);
|
|
19130
18940
|
}
|
|
19131
18941
|
function ButtonGlyph() {
|
|
19132
|
-
return /* @__PURE__ */
|
|
19133
|
-
/* @__PURE__ */
|
|
19134
|
-
/* @__PURE__ */
|
|
18942
|
+
return /* @__PURE__ */ jsxs11("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
18943
|
+
/* @__PURE__ */ jsx20("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
18944
|
+
/* @__PURE__ */ jsx20("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19135
18945
|
] });
|
|
19136
18946
|
}
|
|
19137
18947
|
function FeatureGlyph({ mode }) {
|
|
19138
|
-
return /* @__PURE__ */
|
|
19139
|
-
/* @__PURE__ */
|
|
19140
|
-
/* @__PURE__ */
|
|
19141
|
-
/* @__PURE__ */
|
|
19142
|
-
/* @__PURE__ */
|
|
19143
|
-
/* @__PURE__ */
|
|
19144
|
-
mode === "add" && /* @__PURE__ */
|
|
18948
|
+
return /* @__PURE__ */ jsxs11("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
18949
|
+
/* @__PURE__ */ jsx20("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
18950
|
+
/* @__PURE__ */ jsx20("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
18951
|
+
/* @__PURE__ */ jsx20("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
18952
|
+
/* @__PURE__ */ jsx20("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
18953
|
+
/* @__PURE__ */ jsx20("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
18954
|
+
mode === "add" && /* @__PURE__ */ jsx20("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19145
18955
|
] });
|
|
19146
18956
|
}
|
|
19147
|
-
function
|
|
18957
|
+
function ToolbarAction({
|
|
19148
18958
|
label,
|
|
19149
18959
|
onClick,
|
|
19150
18960
|
disabled = false,
|
|
19151
18961
|
children
|
|
19152
18962
|
}) {
|
|
19153
|
-
const button = /* @__PURE__ */
|
|
19154
|
-
return /* @__PURE__ */
|
|
19155
|
-
/* @__PURE__ */
|
|
19156
|
-
/* @__PURE__ */
|
|
18963
|
+
const button = /* @__PURE__ */ jsx20(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
18964
|
+
return /* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18965
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: button }) : button }),
|
|
18966
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19157
18967
|
] });
|
|
19158
18968
|
}
|
|
19159
|
-
function
|
|
19160
|
-
return /* @__PURE__ */
|
|
18969
|
+
function ToolbarSeparator() {
|
|
18970
|
+
return /* @__PURE__ */ jsx20("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19161
18971
|
}
|
|
19162
18972
|
function CardStyleMenu({
|
|
19163
18973
|
value,
|
|
@@ -19165,7 +18975,7 @@ function CardStyleMenu({
|
|
|
19165
18975
|
disabled = false
|
|
19166
18976
|
}) {
|
|
19167
18977
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
19168
|
-
const trigger = /* @__PURE__ */
|
|
18978
|
+
const trigger = /* @__PURE__ */ jsxs11(
|
|
19169
18979
|
"button",
|
|
19170
18980
|
{
|
|
19171
18981
|
type: "button",
|
|
@@ -19176,28 +18986,28 @@ function CardStyleMenu({
|
|
|
19176
18986
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
19177
18987
|
),
|
|
19178
18988
|
children: [
|
|
19179
|
-
/* @__PURE__ */
|
|
19180
|
-
/* @__PURE__ */
|
|
19181
|
-
/* @__PURE__ */
|
|
18989
|
+
/* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
|
|
18990
|
+
/* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
|
|
18991
|
+
/* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
19182
18992
|
]
|
|
19183
18993
|
}
|
|
19184
18994
|
);
|
|
19185
18995
|
if (disabled) {
|
|
19186
|
-
return /* @__PURE__ */
|
|
19187
|
-
/* @__PURE__ */
|
|
19188
|
-
/* @__PURE__ */
|
|
19189
|
-
/* @__PURE__ */
|
|
19190
|
-
/* @__PURE__ */
|
|
18996
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18997
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
18998
|
+
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18999
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: trigger }) }),
|
|
19000
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
19191
19001
|
] })
|
|
19192
19002
|
] });
|
|
19193
19003
|
}
|
|
19194
|
-
return /* @__PURE__ */
|
|
19195
|
-
/* @__PURE__ */
|
|
19196
|
-
/* @__PURE__ */
|
|
19197
|
-
/* @__PURE__ */
|
|
19198
|
-
/* @__PURE__ */
|
|
19004
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19005
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19006
|
+
/* @__PURE__ */ jsxs11(DropdownMenu, { modal: false, children: [
|
|
19007
|
+
/* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19008
|
+
/* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
19199
19009
|
const selected = style.value === value;
|
|
19200
|
-
return /* @__PURE__ */
|
|
19010
|
+
return /* @__PURE__ */ jsxs11(
|
|
19201
19011
|
DropdownMenuItem,
|
|
19202
19012
|
{
|
|
19203
19013
|
role: "menuitemradio",
|
|
@@ -19205,9 +19015,9 @@ function CardStyleMenu({
|
|
|
19205
19015
|
onSelect: () => onChange(style.value),
|
|
19206
19016
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19207
19017
|
children: [
|
|
19208
|
-
/* @__PURE__ */
|
|
19209
|
-
/* @__PURE__ */
|
|
19210
|
-
selected && /* @__PURE__ */
|
|
19018
|
+
/* @__PURE__ */ jsx20(StyleSwatch, { style: style.value }),
|
|
19019
|
+
/* @__PURE__ */ jsx20("span", { children: style.label }),
|
|
19020
|
+
selected && /* @__PURE__ */ jsx20(Check2, { size: 16, className: "text-bridge-primary" })
|
|
19211
19021
|
]
|
|
19212
19022
|
},
|
|
19213
19023
|
style.value
|
|
@@ -19237,7 +19047,7 @@ function PricingCardToolbar({
|
|
|
19237
19047
|
const style = pricingCardStyle(entry.tree, index);
|
|
19238
19048
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19239
19049
|
const mobile = window.innerWidth <= 480;
|
|
19240
|
-
return /* @__PURE__ */
|
|
19050
|
+
return /* @__PURE__ */ jsx20(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs11(
|
|
19241
19051
|
"div",
|
|
19242
19052
|
{
|
|
19243
19053
|
"data-ohw-bridge": "",
|
|
@@ -19249,7 +19059,7 @@ function PricingCardToolbar({
|
|
|
19249
19059
|
),
|
|
19250
19060
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19251
19061
|
children: [
|
|
19252
|
-
/* @__PURE__ */
|
|
19062
|
+
/* @__PURE__ */ jsxs11(
|
|
19253
19063
|
"div",
|
|
19254
19064
|
{
|
|
19255
19065
|
className: cn(
|
|
@@ -19258,8 +19068,8 @@ function PricingCardToolbar({
|
|
|
19258
19068
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19259
19069
|
),
|
|
19260
19070
|
children: [
|
|
19261
|
-
/* @__PURE__ */
|
|
19262
|
-
/* @__PURE__ */
|
|
19071
|
+
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
19072
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
19263
19073
|
CustomToolbarButton,
|
|
19264
19074
|
{
|
|
19265
19075
|
type: "button",
|
|
@@ -19267,7 +19077,7 @@ function PricingCardToolbar({
|
|
|
19267
19077
|
"aria-pressed": featuredTag,
|
|
19268
19078
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19269
19079
|
className: "group size-8",
|
|
19270
|
-
children: /* @__PURE__ */
|
|
19080
|
+
children: /* @__PURE__ */ jsx20(
|
|
19271
19081
|
Star2,
|
|
19272
19082
|
{
|
|
19273
19083
|
size: 16,
|
|
@@ -19282,25 +19092,25 @@ function PricingCardToolbar({
|
|
|
19282
19092
|
)
|
|
19283
19093
|
}
|
|
19284
19094
|
) }),
|
|
19285
|
-
/* @__PURE__ */
|
|
19095
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19286
19096
|
] }),
|
|
19287
|
-
/* @__PURE__ */
|
|
19288
|
-
/* @__PURE__ */
|
|
19289
|
-
/* @__PURE__ */
|
|
19290
|
-
/* @__PURE__ */
|
|
19291
|
-
/* @__PURE__ */
|
|
19292
|
-
/* @__PURE__ */
|
|
19293
|
-
/* @__PURE__ */
|
|
19097
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
19098
|
+
/* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19099
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
19100
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx20(ButtonGlyph, {}) }),
|
|
19101
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs11("span", { className: "relative inline-flex", children: [
|
|
19102
|
+
/* @__PURE__ */ jsx20(ButtonGlyph, {}),
|
|
19103
|
+
/* @__PURE__ */ jsx20(Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
19294
19104
|
] }) }),
|
|
19295
|
-
/* @__PURE__ */
|
|
19296
|
-
/* @__PURE__ */
|
|
19297
|
-
/* @__PURE__ */
|
|
19298
|
-
/* @__PURE__ */
|
|
19299
|
-
/* @__PURE__ */
|
|
19105
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ jsx20(FeatureGlyph, { mode: "add" }) }),
|
|
19106
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ jsx20(FeatureGlyph, { mode: "remove" }) }),
|
|
19107
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
19108
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ jsx20(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19109
|
+
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ jsx20(Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19300
19110
|
]
|
|
19301
19111
|
}
|
|
19302
19112
|
),
|
|
19303
|
-
error && /* @__PURE__ */
|
|
19113
|
+
error && /* @__PURE__ */ jsx20("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19304
19114
|
]
|
|
19305
19115
|
}
|
|
19306
19116
|
) });
|
|
@@ -19334,7 +19144,7 @@ function AiPricingCardOverlay({
|
|
|
19334
19144
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19335
19145
|
setHover((prev) => {
|
|
19336
19146
|
const next = ref && !overEditable ? ref : null;
|
|
19337
|
-
return
|
|
19147
|
+
return sameRef(prev, next) ? prev : next;
|
|
19338
19148
|
});
|
|
19339
19149
|
};
|
|
19340
19150
|
const onLeave = () => setHover(null);
|
|
@@ -19349,10 +19159,10 @@ function AiPricingCardOverlay({
|
|
|
19349
19159
|
const onClick = (e) => {
|
|
19350
19160
|
const t = e.target;
|
|
19351
19161
|
if (!(t instanceof Element)) return;
|
|
19352
|
-
if (t.closest(
|
|
19162
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
19353
19163
|
const ref = cardRefFromTarget(t);
|
|
19354
|
-
setActive((prev) =>
|
|
19355
|
-
if (!ref || !
|
|
19164
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19165
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
19356
19166
|
};
|
|
19357
19167
|
document.addEventListener("click", onClick, true);
|
|
19358
19168
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19417,12 +19227,12 @@ function AiPricingCardOverlay({
|
|
|
19417
19227
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19418
19228
|
const activeCardRect = useLiveCardRect(active);
|
|
19419
19229
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19420
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19421
|
-
return /* @__PURE__ */
|
|
19422
|
-
hoverRect && /* @__PURE__ */
|
|
19423
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */
|
|
19424
|
-
/* @__PURE__ */
|
|
19425
|
-
/* @__PURE__ */
|
|
19230
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19231
|
+
return /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
19232
|
+
hoverRect && /* @__PURE__ */ jsx20(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19233
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
19234
|
+
/* @__PURE__ */ jsx20(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19235
|
+
/* @__PURE__ */ jsx20(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ jsx20(
|
|
19426
19236
|
PricingCardToolbar,
|
|
19427
19237
|
{
|
|
19428
19238
|
entry: activeEntry,
|
|
@@ -19450,7 +19260,7 @@ function AiPricingCardOverlay({
|
|
|
19450
19260
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
19451
19261
|
}
|
|
19452
19262
|
) }),
|
|
19453
|
-
/* @__PURE__ */
|
|
19263
|
+
/* @__PURE__ */ jsx20(
|
|
19454
19264
|
"div",
|
|
19455
19265
|
{
|
|
19456
19266
|
"data-ohw-bridge": "",
|
|
@@ -19543,10 +19353,10 @@ function extractYouTubeId(input) {
|
|
|
19543
19353
|
}
|
|
19544
19354
|
|
|
19545
19355
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19546
|
-
import { Fragment as Fragment8, jsx as
|
|
19356
|
+
import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
19547
19357
|
var PRIMARY5 = "#0885FE";
|
|
19548
|
-
var
|
|
19549
|
-
var
|
|
19358
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19359
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
19550
19360
|
function findVideoBlockElement(sectionId, path) {
|
|
19551
19361
|
const sectionEl = findByInstanceId(sectionId);
|
|
19552
19362
|
if (!sectionEl) return null;
|
|
@@ -19606,12 +19416,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
19606
19416
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
19607
19417
|
});
|
|
19608
19418
|
}
|
|
19609
|
-
function
|
|
19419
|
+
function Pill2({
|
|
19610
19420
|
label,
|
|
19611
19421
|
onClick,
|
|
19612
19422
|
disabled
|
|
19613
19423
|
}) {
|
|
19614
|
-
return /* @__PURE__ */
|
|
19424
|
+
return /* @__PURE__ */ jsx21(
|
|
19615
19425
|
"button",
|
|
19616
19426
|
{
|
|
19617
19427
|
type: "button",
|
|
@@ -19627,7 +19437,7 @@ function Pill({
|
|
|
19627
19437
|
border: "none",
|
|
19628
19438
|
cursor: disabled ? "default" : "pointer",
|
|
19629
19439
|
background: "#ffffff",
|
|
19630
|
-
color:
|
|
19440
|
+
color: OHW_BLUE_DARK2,
|
|
19631
19441
|
opacity: disabled ? 0.4 : 1,
|
|
19632
19442
|
fontSize: 12,
|
|
19633
19443
|
lineHeight: "16px",
|
|
@@ -19670,8 +19480,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19670
19480
|
onCommit(id);
|
|
19671
19481
|
}
|
|
19672
19482
|
};
|
|
19673
|
-
return /* @__PURE__ */
|
|
19674
|
-
/* @__PURE__ */
|
|
19483
|
+
return /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
19484
|
+
/* @__PURE__ */ jsxs12(
|
|
19675
19485
|
"div",
|
|
19676
19486
|
{
|
|
19677
19487
|
style: {
|
|
@@ -19687,12 +19497,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19687
19497
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19688
19498
|
},
|
|
19689
19499
|
children: [
|
|
19690
|
-
/* @__PURE__ */
|
|
19500
|
+
/* @__PURE__ */ jsx21(
|
|
19691
19501
|
"span",
|
|
19692
19502
|
{
|
|
19693
19503
|
style: {
|
|
19694
19504
|
flex: "0 0 auto",
|
|
19695
|
-
color:
|
|
19505
|
+
color: OHW_BLUE_DARK2,
|
|
19696
19506
|
fontSize: 10,
|
|
19697
19507
|
lineHeight: "16px",
|
|
19698
19508
|
fontWeight: 700,
|
|
@@ -19702,7 +19512,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19702
19512
|
children: "Video"
|
|
19703
19513
|
}
|
|
19704
19514
|
),
|
|
19705
|
-
/* @__PURE__ */
|
|
19515
|
+
/* @__PURE__ */ jsx21(
|
|
19706
19516
|
"input",
|
|
19707
19517
|
{
|
|
19708
19518
|
type: "text",
|
|
@@ -19739,7 +19549,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19739
19549
|
]
|
|
19740
19550
|
}
|
|
19741
19551
|
),
|
|
19742
|
-
invalid && /* @__PURE__ */
|
|
19552
|
+
invalid && /* @__PURE__ */ jsx21("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
19743
19553
|
] });
|
|
19744
19554
|
}
|
|
19745
19555
|
function VideoToolbar({
|
|
@@ -19749,7 +19559,7 @@ function VideoToolbar({
|
|
|
19749
19559
|
onSetVideoId,
|
|
19750
19560
|
onRemove
|
|
19751
19561
|
}) {
|
|
19752
|
-
return /* @__PURE__ */
|
|
19562
|
+
return /* @__PURE__ */ jsxs12(
|
|
19753
19563
|
"div",
|
|
19754
19564
|
{
|
|
19755
19565
|
"data-ohw-bridge": "",
|
|
@@ -19761,7 +19571,7 @@ function VideoToolbar({
|
|
|
19761
19571
|
gap: 6,
|
|
19762
19572
|
alignItems: "center",
|
|
19763
19573
|
width: 280,
|
|
19764
|
-
background:
|
|
19574
|
+
background: OHW_BLUE2,
|
|
19765
19575
|
padding: 8,
|
|
19766
19576
|
borderRadius: 12,
|
|
19767
19577
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19769,9 +19579,9 @@ function VideoToolbar({
|
|
|
19769
19579
|
opacity: pending ? 0.6 : 1
|
|
19770
19580
|
},
|
|
19771
19581
|
children: [
|
|
19772
|
-
/* @__PURE__ */
|
|
19773
|
-
/* @__PURE__ */
|
|
19774
|
-
error && /* @__PURE__ */
|
|
19582
|
+
/* @__PURE__ */ jsx21(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19583
|
+
/* @__PURE__ */ jsx21(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19584
|
+
error && /* @__PURE__ */ jsx21("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19775
19585
|
]
|
|
19776
19586
|
}
|
|
19777
19587
|
);
|
|
@@ -19891,8 +19701,8 @@ function AiVideoOverlay({
|
|
|
19891
19701
|
const activeBlockRect = useLiveBlockRect(active);
|
|
19892
19702
|
const TOOLBAR_APPROX_H = 90;
|
|
19893
19703
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19894
|
-
return /* @__PURE__ */
|
|
19895
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
19704
|
+
return /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
19705
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx21(
|
|
19896
19706
|
"button",
|
|
19897
19707
|
{
|
|
19898
19708
|
type: "button",
|
|
@@ -19920,15 +19730,15 @@ function AiVideoOverlay({
|
|
|
19920
19730
|
fontSize: 14,
|
|
19921
19731
|
fontWeight: 700
|
|
19922
19732
|
},
|
|
19923
|
-
children: /* @__PURE__ */
|
|
19733
|
+
children: /* @__PURE__ */ jsx21(Star3, { size: 14, style: { pointerEvents: "none" } })
|
|
19924
19734
|
}
|
|
19925
19735
|
),
|
|
19926
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */
|
|
19736
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ jsx21(
|
|
19927
19737
|
ItemInteractionLayer,
|
|
19928
19738
|
{
|
|
19929
19739
|
rect: activeBlockRect,
|
|
19930
19740
|
state: toolbarState,
|
|
19931
|
-
toolbar: /* @__PURE__ */
|
|
19741
|
+
toolbar: /* @__PURE__ */ jsx21(
|
|
19932
19742
|
VideoToolbar,
|
|
19933
19743
|
{
|
|
19934
19744
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20003,10 +19813,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20003
19813
|
}
|
|
20004
19814
|
|
|
20005
19815
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20006
|
-
import { Fragment as Fragment9, jsx as
|
|
19816
|
+
import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
20007
19817
|
var PRIMARY6 = "#0885FE";
|
|
20008
|
-
var
|
|
20009
|
-
var
|
|
19818
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
19819
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20010
19820
|
function findCarouselItemElement(sectionId, index) {
|
|
20011
19821
|
const sectionEl = findByInstanceId(sectionId);
|
|
20012
19822
|
if (!sectionEl) return null;
|
|
@@ -20085,8 +19895,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20085
19895
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20086
19896
|
});
|
|
20087
19897
|
}
|
|
20088
|
-
function
|
|
20089
|
-
return /* @__PURE__ */
|
|
19898
|
+
function Pill3({ label, onClick, disabled }) {
|
|
19899
|
+
return /* @__PURE__ */ jsx22(
|
|
20090
19900
|
"button",
|
|
20091
19901
|
{
|
|
20092
19902
|
type: "button",
|
|
@@ -20102,7 +19912,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20102
19912
|
border: "none",
|
|
20103
19913
|
cursor: disabled ? "default" : "pointer",
|
|
20104
19914
|
background: "#ffffff",
|
|
20105
|
-
color:
|
|
19915
|
+
color: OHW_BLUE_DARK3,
|
|
20106
19916
|
opacity: disabled ? 0.4 : 1,
|
|
20107
19917
|
fontSize: 12,
|
|
20108
19918
|
lineHeight: "16px",
|
|
@@ -20120,7 +19930,7 @@ function TogglePill({
|
|
|
20120
19930
|
onToggle,
|
|
20121
19931
|
disabled
|
|
20122
19932
|
}) {
|
|
20123
|
-
return /* @__PURE__ */
|
|
19933
|
+
return /* @__PURE__ */ jsxs13(
|
|
20124
19934
|
"button",
|
|
20125
19935
|
{
|
|
20126
19936
|
type: "button",
|
|
@@ -20139,7 +19949,7 @@ function TogglePill({
|
|
|
20139
19949
|
border: "none",
|
|
20140
19950
|
cursor: disabled ? "default" : "pointer",
|
|
20141
19951
|
background: "#ffffff",
|
|
20142
|
-
color:
|
|
19952
|
+
color: OHW_BLUE_DARK3,
|
|
20143
19953
|
opacity: disabled ? 0.4 : 1,
|
|
20144
19954
|
fontSize: 12,
|
|
20145
19955
|
lineHeight: "16px",
|
|
@@ -20149,7 +19959,7 @@ function TogglePill({
|
|
|
20149
19959
|
},
|
|
20150
19960
|
children: [
|
|
20151
19961
|
label,
|
|
20152
|
-
/* @__PURE__ */
|
|
19962
|
+
/* @__PURE__ */ jsx22(
|
|
20153
19963
|
"span",
|
|
20154
19964
|
{
|
|
20155
19965
|
"aria-hidden": true,
|
|
@@ -20162,10 +19972,10 @@ function TogglePill({
|
|
|
20162
19972
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
20163
19973
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
20164
19974
|
// "disabled control" rather than "switch that is off".
|
|
20165
|
-
background: on ?
|
|
19975
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
20166
19976
|
transition: "background 120ms ease"
|
|
20167
19977
|
},
|
|
20168
|
-
children: /* @__PURE__ */
|
|
19978
|
+
children: /* @__PURE__ */ jsx22(
|
|
20169
19979
|
"span",
|
|
20170
19980
|
{
|
|
20171
19981
|
style: {
|
|
@@ -20194,7 +20004,7 @@ function CarouselSlideToolbar({
|
|
|
20194
20004
|
onChangeImage,
|
|
20195
20005
|
onToggleAutoplay
|
|
20196
20006
|
}) {
|
|
20197
|
-
return /* @__PURE__ */
|
|
20007
|
+
return /* @__PURE__ */ jsxs13(
|
|
20198
20008
|
"div",
|
|
20199
20009
|
{
|
|
20200
20010
|
"data-ohw-bridge": "",
|
|
@@ -20205,7 +20015,7 @@ function CarouselSlideToolbar({
|
|
|
20205
20015
|
flexDirection: "column",
|
|
20206
20016
|
gap: 6,
|
|
20207
20017
|
alignItems: "center",
|
|
20208
|
-
background:
|
|
20018
|
+
background: OHW_BLUE3,
|
|
20209
20019
|
padding: 8,
|
|
20210
20020
|
borderRadius: 12,
|
|
20211
20021
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20217,11 +20027,11 @@ function CarouselSlideToolbar({
|
|
|
20217
20027
|
pointerEvents: pending ? "none" : "auto"
|
|
20218
20028
|
},
|
|
20219
20029
|
children: [
|
|
20220
|
-
/* @__PURE__ */
|
|
20221
|
-
/* @__PURE__ */
|
|
20222
|
-
/* @__PURE__ */
|
|
20030
|
+
/* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20031
|
+
/* @__PURE__ */ jsx22(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20032
|
+
/* @__PURE__ */ jsx22(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20223
20033
|
] }),
|
|
20224
|
-
error && /* @__PURE__ */
|
|
20034
|
+
error && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20225
20035
|
]
|
|
20226
20036
|
}
|
|
20227
20037
|
);
|
|
@@ -20361,8 +20171,8 @@ function AiFadeCarouselOverlay({
|
|
|
20361
20171
|
const activeItemRect = useLiveItemRect2(active);
|
|
20362
20172
|
const TOOLBAR_APPROX_H = 90;
|
|
20363
20173
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20364
|
-
return /* @__PURE__ */
|
|
20365
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
20174
|
+
return /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
20175
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx22(
|
|
20366
20176
|
"button",
|
|
20367
20177
|
{
|
|
20368
20178
|
type: "button",
|
|
@@ -20391,10 +20201,10 @@ function AiFadeCarouselOverlay({
|
|
|
20391
20201
|
fontSize: 14,
|
|
20392
20202
|
fontWeight: 700
|
|
20393
20203
|
},
|
|
20394
|
-
children: /* @__PURE__ */
|
|
20204
|
+
children: /* @__PURE__ */ jsx22(Star4, { size: 14, style: { pointerEvents: "none" } })
|
|
20395
20205
|
}
|
|
20396
20206
|
),
|
|
20397
|
-
swapping && /* @__PURE__ */
|
|
20207
|
+
swapping && /* @__PURE__ */ jsx22(
|
|
20398
20208
|
"div",
|
|
20399
20209
|
{
|
|
20400
20210
|
ref: skeletonRef,
|
|
@@ -20412,15 +20222,15 @@ function AiFadeCarouselOverlay({
|
|
|
20412
20222
|
zIndex: 2147483646,
|
|
20413
20223
|
pointerEvents: "none"
|
|
20414
20224
|
},
|
|
20415
|
-
children: /* @__PURE__ */
|
|
20225
|
+
children: /* @__PURE__ */ jsx22("style", { children: MEDIA_SKELETON_CSS })
|
|
20416
20226
|
}
|
|
20417
20227
|
),
|
|
20418
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */
|
|
20228
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx22(
|
|
20419
20229
|
ItemInteractionLayer,
|
|
20420
20230
|
{
|
|
20421
20231
|
rect: activeItemRect,
|
|
20422
20232
|
state: toolbarState,
|
|
20423
|
-
toolbar: /* @__PURE__ */
|
|
20233
|
+
toolbar: /* @__PURE__ */ jsx22(
|
|
20424
20234
|
CarouselSlideToolbar,
|
|
20425
20235
|
{
|
|
20426
20236
|
pending,
|
|
@@ -20773,11 +20583,118 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
20773
20583
|
// src/ui/link-modal/LinkPopover.tsx
|
|
20774
20584
|
import { useEffect as useEffect13 } from "react";
|
|
20775
20585
|
|
|
20586
|
+
// src/ui/dialog.tsx
|
|
20587
|
+
import * as React9 from "react";
|
|
20588
|
+
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
20589
|
+
import { X as X2 } from "lucide-react";
|
|
20590
|
+
import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
20591
|
+
function Dialog2({
|
|
20592
|
+
...props
|
|
20593
|
+
}) {
|
|
20594
|
+
return /* @__PURE__ */ jsx23(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
20595
|
+
}
|
|
20596
|
+
function DialogPortal({
|
|
20597
|
+
...props
|
|
20598
|
+
}) {
|
|
20599
|
+
return /* @__PURE__ */ jsx23(DialogPrimitive.Portal, { ...props });
|
|
20600
|
+
}
|
|
20601
|
+
function DialogOverlay({
|
|
20602
|
+
className,
|
|
20603
|
+
...props
|
|
20604
|
+
}) {
|
|
20605
|
+
return /* @__PURE__ */ jsx23(
|
|
20606
|
+
DialogPrimitive.Overlay,
|
|
20607
|
+
{
|
|
20608
|
+
"data-slot": "dialog-overlay",
|
|
20609
|
+
"data-ohw-link-modal-root": "",
|
|
20610
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
20611
|
+
...props
|
|
20612
|
+
}
|
|
20613
|
+
);
|
|
20614
|
+
}
|
|
20615
|
+
var DialogContent = React9.forwardRef(
|
|
20616
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
20617
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
20618
|
+
return /* @__PURE__ */ jsxs14(DialogPortal, { container: container ?? void 0, children: [
|
|
20619
|
+
/* @__PURE__ */ jsx23(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
20620
|
+
/* @__PURE__ */ jsxs14(
|
|
20621
|
+
DialogPrimitive.Content,
|
|
20622
|
+
{
|
|
20623
|
+
ref,
|
|
20624
|
+
"data-slot": "dialog-content",
|
|
20625
|
+
className: cn(
|
|
20626
|
+
positionMode,
|
|
20627
|
+
"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",
|
|
20628
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
20629
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
20630
|
+
className
|
|
20631
|
+
),
|
|
20632
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
20633
|
+
...props,
|
|
20634
|
+
children: [
|
|
20635
|
+
children,
|
|
20636
|
+
showCloseButton ? /* @__PURE__ */ jsx23(
|
|
20637
|
+
DialogPrimitive.Close,
|
|
20638
|
+
{
|
|
20639
|
+
type: "button",
|
|
20640
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
20641
|
+
"aria-label": "Close",
|
|
20642
|
+
children: /* @__PURE__ */ jsx23(X2, { size: 16, "aria-hidden": true })
|
|
20643
|
+
}
|
|
20644
|
+
) : null
|
|
20645
|
+
]
|
|
20646
|
+
}
|
|
20647
|
+
)
|
|
20648
|
+
] });
|
|
20649
|
+
}
|
|
20650
|
+
);
|
|
20651
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
20652
|
+
function DialogHeader({
|
|
20653
|
+
className,
|
|
20654
|
+
...props
|
|
20655
|
+
}) {
|
|
20656
|
+
return /* @__PURE__ */ jsx23("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
20657
|
+
}
|
|
20658
|
+
function DialogFooter({
|
|
20659
|
+
className,
|
|
20660
|
+
...props
|
|
20661
|
+
}) {
|
|
20662
|
+
return /* @__PURE__ */ jsx23(
|
|
20663
|
+
"div",
|
|
20664
|
+
{
|
|
20665
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
20666
|
+
...props
|
|
20667
|
+
}
|
|
20668
|
+
);
|
|
20669
|
+
}
|
|
20670
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
20671
|
+
DialogPrimitive.Title,
|
|
20672
|
+
{
|
|
20673
|
+
ref,
|
|
20674
|
+
className: cn(
|
|
20675
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
20676
|
+
className
|
|
20677
|
+
),
|
|
20678
|
+
...props
|
|
20679
|
+
}
|
|
20680
|
+
));
|
|
20681
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
20682
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
20683
|
+
DialogPrimitive.Description,
|
|
20684
|
+
{
|
|
20685
|
+
ref,
|
|
20686
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
20687
|
+
...props
|
|
20688
|
+
}
|
|
20689
|
+
));
|
|
20690
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
20691
|
+
var DialogClose = DialogPrimitive.Close;
|
|
20692
|
+
|
|
20776
20693
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
20777
20694
|
import { Info, X as X4 } from "lucide-react";
|
|
20778
20695
|
|
|
20779
20696
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
20780
|
-
import { ArrowRight as
|
|
20697
|
+
import { ArrowRight as ArrowRight2, File, GalleryVertical } from "lucide-react";
|
|
20781
20698
|
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
20782
20699
|
function DestinationBreadcrumb({
|
|
20783
20700
|
pageTitle,
|
|
@@ -20791,7 +20708,7 @@ function DestinationBreadcrumb({
|
|
|
20791
20708
|
/* @__PURE__ */ jsx24("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
20792
20709
|
] }),
|
|
20793
20710
|
/* @__PURE__ */ jsx24(
|
|
20794
|
-
|
|
20711
|
+
ArrowRight2,
|
|
20795
20712
|
{
|
|
20796
20713
|
size: 16,
|
|
20797
20714
|
className: "shrink-0 text-muted-foreground",
|
|
@@ -20903,7 +20820,7 @@ function Label({ className, ...props }) {
|
|
|
20903
20820
|
}
|
|
20904
20821
|
|
|
20905
20822
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
20906
|
-
import { ChevronDown as
|
|
20823
|
+
import { ChevronDown as ChevronDown4, File as File2, X as X3 } from "lucide-react";
|
|
20907
20824
|
import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
20908
20825
|
function FieldChevron({
|
|
20909
20826
|
onClick
|
|
@@ -20916,7 +20833,7 @@ function FieldChevron({
|
|
|
20916
20833
|
onClick,
|
|
20917
20834
|
"aria-label": "Open page list",
|
|
20918
20835
|
tabIndex: -1,
|
|
20919
|
-
children: /* @__PURE__ */ jsx28(
|
|
20836
|
+
children: /* @__PURE__ */ jsx28(ChevronDown4, { size: 16 })
|
|
20920
20837
|
}
|
|
20921
20838
|
);
|
|
20922
20839
|
}
|
|
@@ -21146,7 +21063,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
21146
21063
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
21147
21064
|
import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
|
|
21148
21065
|
import { createPortal as createPortal2 } from "react-dom";
|
|
21149
|
-
import { ArrowLeft as
|
|
21066
|
+
import { ArrowLeft as ArrowLeft2, Check as Check3 } from "lucide-react";
|
|
21150
21067
|
import { usePathname, useRouter as useRouter2 } from "next/navigation";
|
|
21151
21068
|
|
|
21152
21069
|
// src/lib/parent-scroll.ts
|
|
@@ -21423,7 +21340,7 @@ function SectionPickerOverlay({
|
|
|
21423
21340
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
21424
21341
|
onClick: onBack,
|
|
21425
21342
|
children: [
|
|
21426
|
-
/* @__PURE__ */ jsx30(
|
|
21343
|
+
/* @__PURE__ */ jsx30(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
21427
21344
|
"Back"
|
|
21428
21345
|
]
|
|
21429
21346
|
}
|
|
@@ -21492,7 +21409,7 @@ function SectionPickerOverlay({
|
|
|
21492
21409
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
21493
21410
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
21494
21411
|
"aria-hidden": true,
|
|
21495
|
-
children: /* @__PURE__ */ jsx30(
|
|
21412
|
+
children: /* @__PURE__ */ jsx30(Check3, { className: "size-5" })
|
|
21496
21413
|
}
|
|
21497
21414
|
) : null
|
|
21498
21415
|
]
|
|
@@ -21876,7 +21793,6 @@ function shouldUseDevFixtures() {
|
|
|
21876
21793
|
function getLogoElement(el) {
|
|
21877
21794
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
21878
21795
|
if (marked) return marked;
|
|
21879
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
21880
21796
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
21881
21797
|
if (!root) return null;
|
|
21882
21798
|
const anchor = el.closest("a");
|
|
@@ -21946,7 +21862,7 @@ function addFooterColumnWithPersist({
|
|
|
21946
21862
|
import {
|
|
21947
21863
|
useCallback as useCallback9,
|
|
21948
21864
|
useEffect as useEffect14,
|
|
21949
|
-
useLayoutEffect as
|
|
21865
|
+
useLayoutEffect as useLayoutEffect5,
|
|
21950
21866
|
useRef as useRef11,
|
|
21951
21867
|
useState as useState15
|
|
21952
21868
|
} from "react";
|
|
@@ -22043,7 +21959,7 @@ function FloatingPanel({
|
|
|
22043
21959
|
return () => window.removeEventListener("message", onParentScroll);
|
|
22044
21960
|
}, [open]);
|
|
22045
21961
|
const positionRef = useRef11(position);
|
|
22046
|
-
|
|
21962
|
+
useLayoutEffect5(() => {
|
|
22047
21963
|
if (!open) {
|
|
22048
21964
|
positionRef.current = position;
|
|
22049
21965
|
return;
|
|
@@ -22053,7 +21969,7 @@ function FloatingPanel({
|
|
|
22053
21969
|
}
|
|
22054
21970
|
positionRef.current = position;
|
|
22055
21971
|
}, [open, position, liveScroll, parentScroll]);
|
|
22056
|
-
|
|
21972
|
+
useLayoutEffect5(() => {
|
|
22057
21973
|
if (!open || !panelRef.current) return;
|
|
22058
21974
|
const el = panelRef.current;
|
|
22059
21975
|
const header = el.querySelector("[data-ohw-floating-panel-header]");
|
|
@@ -22262,7 +22178,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
22262
22178
|
}
|
|
22263
22179
|
|
|
22264
22180
|
// src/ui/button-style-panel.tsx
|
|
22265
|
-
import { Check as
|
|
22181
|
+
import { Check as Check4 } from "lucide-react";
|
|
22266
22182
|
import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
22267
22183
|
var SIZE_LABEL = { s: "S", m: "M", l: "L" };
|
|
22268
22184
|
function ButtonStylePanel({
|
|
@@ -22333,7 +22249,7 @@ function ButtonStylePanel({
|
|
|
22333
22249
|
{
|
|
22334
22250
|
className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
22335
22251
|
"aria-hidden": true,
|
|
22336
|
-
children: /* @__PURE__ */ jsx34(
|
|
22252
|
+
children: /* @__PURE__ */ jsx34(Check4, { className: "size-3", strokeWidth: 3 })
|
|
22337
22253
|
}
|
|
22338
22254
|
) : null
|
|
22339
22255
|
]
|
|
@@ -23358,7 +23274,7 @@ function useSectionDrag({
|
|
|
23358
23274
|
}
|
|
23359
23275
|
|
|
23360
23276
|
// src/ui/footer-container-chrome.tsx
|
|
23361
|
-
import { Plus as
|
|
23277
|
+
import { Plus as Plus3 } from "lucide-react";
|
|
23362
23278
|
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
23363
23279
|
function FooterContainerChrome({
|
|
23364
23280
|
rect,
|
|
@@ -23399,7 +23315,7 @@ function FooterContainerChrome({
|
|
|
23399
23315
|
if (addDisabled) return;
|
|
23400
23316
|
onAdd();
|
|
23401
23317
|
},
|
|
23402
|
-
children: /* @__PURE__ */ jsx35(
|
|
23318
|
+
children: /* @__PURE__ */ jsx35(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
23403
23319
|
}
|
|
23404
23320
|
) }),
|
|
23405
23321
|
/* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
@@ -23578,7 +23494,7 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
23578
23494
|
}
|
|
23579
23495
|
|
|
23580
23496
|
// src/ui/navbar-container-chrome.tsx
|
|
23581
|
-
import { Plus as
|
|
23497
|
+
import { Plus as Plus4 } from "lucide-react";
|
|
23582
23498
|
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
23583
23499
|
function NavbarContainerChrome({
|
|
23584
23500
|
rect,
|
|
@@ -23614,7 +23530,7 @@ function NavbarContainerChrome({
|
|
|
23614
23530
|
e.stopPropagation();
|
|
23615
23531
|
onAdd();
|
|
23616
23532
|
},
|
|
23617
|
-
children: /* @__PURE__ */ jsx36(
|
|
23533
|
+
children: /* @__PURE__ */ jsx36(Plus4, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
23618
23534
|
}
|
|
23619
23535
|
)
|
|
23620
23536
|
}
|
|
@@ -23686,7 +23602,7 @@ function Badge({ className, variant, ...props }) {
|
|
|
23686
23602
|
}
|
|
23687
23603
|
|
|
23688
23604
|
// src/OhhwellsBridge.tsx
|
|
23689
|
-
import { Brush as Brush2, Link as Link2, Plus as
|
|
23605
|
+
import { Brush as Brush2, Link as Link2, Plus as Plus5, Settings } from "lucide-react";
|
|
23690
23606
|
import { Fragment as Fragment12, jsx as jsx39, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
23691
23607
|
var PRIMARY7 = "#0885FE";
|
|
23692
23608
|
var IMAGE_FADE_MS = 300;
|
|
@@ -24463,7 +24379,7 @@ function getNavigationSelectionParent(el) {
|
|
|
24463
24379
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
24464
24380
|
return resolveFooterLinksContainerFrom(el);
|
|
24465
24381
|
}
|
|
24466
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24382
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24467
24383
|
return getNavigationRoot(el);
|
|
24468
24384
|
}
|
|
24469
24385
|
return null;
|
|
@@ -24685,6 +24601,7 @@ var ICONS = {
|
|
|
24685
24601
|
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"/>',
|
|
24686
24602
|
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"/>'
|
|
24687
24603
|
};
|
|
24604
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
24688
24605
|
var SELECTION_CHROME_GAP2 = 4;
|
|
24689
24606
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
24690
24607
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24782,7 +24699,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
24782
24699
|
el.style.top = `${top}px`;
|
|
24783
24700
|
el.style.height = `${height}px`;
|
|
24784
24701
|
}
|
|
24785
|
-
var
|
|
24702
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
24786
24703
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
24787
24704
|
const isAbove = transform.includes("translateY(-100%)");
|
|
24788
24705
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -24809,8 +24726,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
24809
24726
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
24810
24727
|
const half = toolbarWidth / 2;
|
|
24811
24728
|
return Math.max(
|
|
24812
|
-
|
|
24813
|
-
Math.min(centerX, window.innerWidth -
|
|
24729
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
24730
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
24814
24731
|
);
|
|
24815
24732
|
}
|
|
24816
24733
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -25249,7 +25166,7 @@ function OhhwellsBridge() {
|
|
|
25249
25166
|
}, []);
|
|
25250
25167
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
25251
25168
|
const [subdomain, setSubdomain] = useState18(() => resolveSubdomain(subdomainFromQuery));
|
|
25252
|
-
|
|
25169
|
+
useLayoutEffect6(() => {
|
|
25253
25170
|
const next = resolveSubdomain(subdomainFromQuery);
|
|
25254
25171
|
if (next !== subdomain) setSubdomain(next);
|
|
25255
25172
|
if (next) return;
|
|
@@ -25700,6 +25617,21 @@ function OhhwellsBridge() {
|
|
|
25700
25617
|
const [isItemDragging, setIsItemDragging] = useState18(false);
|
|
25701
25618
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState18(false);
|
|
25702
25619
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
25620
|
+
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
25621
|
+
const floatingPanelOpenRef = useRef14(false);
|
|
25622
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
25623
|
+
const floatingPanelRef = useRef14(null);
|
|
25624
|
+
floatingPanelRef.current = floatingPanel;
|
|
25625
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
25626
|
+
const buttonCollectionDragRef = useRef14(null);
|
|
25627
|
+
const buttonDropInsertIndexRef = useRef14(null);
|
|
25628
|
+
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
25629
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
25630
|
+
const buttonPointerDragRef = useRef14(null);
|
|
25631
|
+
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
25632
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
25633
|
+
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
25634
|
+
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
25703
25635
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState18(null);
|
|
25704
25636
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState18(null);
|
|
25705
25637
|
const footerDragRef = useRef14(null);
|
|
@@ -25725,21 +25657,6 @@ function OhhwellsBridge() {
|
|
|
25725
25657
|
const stylesRef = useRef14("");
|
|
25726
25658
|
const appliedDrawerRef = useRef14(null);
|
|
25727
25659
|
const pendingDeleteUndoRef = useRef14(null);
|
|
25728
|
-
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
25729
|
-
const floatingPanelOpenRef = useRef14(false);
|
|
25730
|
-
const floatingPanelRef = useRef14(null);
|
|
25731
|
-
floatingPanelRef.current = floatingPanel;
|
|
25732
|
-
const setFloatingPanelRef = useRef14(setFloatingPanel);
|
|
25733
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
25734
|
-
const buttonCollectionDragRef = useRef14(null);
|
|
25735
|
-
const buttonDropInsertIndexRef = useRef14(null);
|
|
25736
|
-
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
25737
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
25738
|
-
const buttonPointerDragRef = useRef14(null);
|
|
25739
|
-
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
25740
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
25741
|
-
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
25742
|
-
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
25743
25660
|
const [sitePages, setSitePages] = useState18([]);
|
|
25744
25661
|
const [sectionsByPath, setSectionsByPath] = useState18({});
|
|
25745
25662
|
const sectionsPrefetchGenRef = useRef14(0);
|
|
@@ -25748,18 +25665,7 @@ function OhhwellsBridge() {
|
|
|
25748
25665
|
const linkPopoverOpenRef = useRef14(false);
|
|
25749
25666
|
const linkPopoverGraceUntilRef = useRef14(0);
|
|
25750
25667
|
setLinkPopoverRef.current = setLinkPopover;
|
|
25751
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
25752
25668
|
linkPopoverSessionRef.current = linkPopover;
|
|
25753
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
25754
|
-
useEffect17(() => {
|
|
25755
|
-
const syncViewport = () => {
|
|
25756
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
25757
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
25758
|
-
};
|
|
25759
|
-
syncViewport();
|
|
25760
|
-
window.addEventListener("resize", syncViewport);
|
|
25761
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
25762
|
-
}, []);
|
|
25763
25669
|
useEffect17(() => {
|
|
25764
25670
|
setSectionOrderPersistHandler((entries) => {
|
|
25765
25671
|
const currentPath = window.location.pathname;
|
|
@@ -27427,7 +27333,7 @@ function OhhwellsBridge() {
|
|
|
27427
27333
|
isFooterFrameSelection,
|
|
27428
27334
|
postToParent2
|
|
27429
27335
|
]);
|
|
27430
|
-
|
|
27336
|
+
useLayoutEffect6(() => {
|
|
27431
27337
|
if (!subdomain || isEditMode) {
|
|
27432
27338
|
setFetchState("done");
|
|
27433
27339
|
return;
|
|
@@ -27454,7 +27360,6 @@ function OhhwellsBridge() {
|
|
|
27454
27360
|
applyAiFooterFromContent(content);
|
|
27455
27361
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27456
27362
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
27457
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27458
27363
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27459
27364
|
}
|
|
27460
27365
|
applyBrandChrome(content);
|
|
@@ -27465,12 +27370,12 @@ function OhhwellsBridge() {
|
|
|
27465
27370
|
if (key === "__ohw_sections") continue;
|
|
27466
27371
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27467
27372
|
if (key === AI_FOOTER_KEY) continue;
|
|
27468
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27469
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27470
27373
|
if (key === BRAND_KIT_KEY) continue;
|
|
27471
27374
|
if (key === STYLE_STORE_KEY) continue;
|
|
27472
27375
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27376
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27473
27377
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27378
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27474
27379
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27475
27380
|
continue;
|
|
27476
27381
|
}
|
|
@@ -27685,18 +27590,17 @@ function OhhwellsBridge() {
|
|
|
27685
27590
|
}
|
|
27686
27591
|
applyAiFooterFromContent(content);
|
|
27687
27592
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27688
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27689
27593
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27690
27594
|
}
|
|
27691
27595
|
for (const [key, val] of Object.entries(content)) {
|
|
27692
27596
|
if (key === "__ohw_sections") continue;
|
|
27693
27597
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27694
27598
|
if (key === AI_FOOTER_KEY) continue;
|
|
27695
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27696
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27697
27599
|
if (key === BRAND_KIT_KEY) continue;
|
|
27698
27600
|
if (key === STYLE_STORE_KEY) continue;
|
|
27699
27601
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27602
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27603
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27700
27604
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27701
27605
|
continue;
|
|
27702
27606
|
}
|
|
@@ -27769,7 +27673,7 @@ function OhhwellsBridge() {
|
|
|
27769
27673
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
27770
27674
|
};
|
|
27771
27675
|
}, [subdomain, isEditMode, pathname]);
|
|
27772
|
-
|
|
27676
|
+
useLayoutEffect6(() => {
|
|
27773
27677
|
const el = document.getElementById("ohw-loader");
|
|
27774
27678
|
if (!el) return;
|
|
27775
27679
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
@@ -27953,11 +27857,26 @@ function OhhwellsBridge() {
|
|
|
27953
27857
|
const t2 = setTimeout(measure, 500);
|
|
27954
27858
|
const ro = new ResizeObserver(schedule);
|
|
27955
27859
|
ro.observe(document.body);
|
|
27860
|
+
let lastWidth = window.innerWidth;
|
|
27861
|
+
let resizeTimers = [];
|
|
27862
|
+
const clearResizeTimers = () => {
|
|
27863
|
+
resizeTimers.forEach(clearTimeout);
|
|
27864
|
+
resizeTimers = [];
|
|
27865
|
+
};
|
|
27866
|
+
const handleResize = () => {
|
|
27867
|
+
if (window.innerWidth === lastWidth) return;
|
|
27868
|
+
lastWidth = window.innerWidth;
|
|
27869
|
+
clearResizeTimers();
|
|
27870
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
27871
|
+
};
|
|
27872
|
+
window.addEventListener("resize", handleResize);
|
|
27956
27873
|
return () => {
|
|
27957
27874
|
clearTimeout(t1);
|
|
27958
27875
|
clearTimeout(t2);
|
|
27959
27876
|
if (raf != null) cancelAnimationFrame(raf);
|
|
27960
27877
|
ro.disconnect();
|
|
27878
|
+
clearResizeTimers();
|
|
27879
|
+
window.removeEventListener("resize", handleResize);
|
|
27961
27880
|
};
|
|
27962
27881
|
}, [pathname, isEditMode, postToParent2]);
|
|
27963
27882
|
useEffect17(() => {
|
|
@@ -28256,13 +28175,6 @@ function OhhwellsBridge() {
|
|
|
28256
28175
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28257
28176
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28258
28177
|
if (isInsideLinkEditor(target)) return;
|
|
28259
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28260
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28261
|
-
if (target.closest(
|
|
28262
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28263
|
-
)) {
|
|
28264
|
-
return;
|
|
28265
|
-
}
|
|
28266
28178
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28267
28179
|
clearMediaSelectionRef.current();
|
|
28268
28180
|
}
|
|
@@ -28286,6 +28198,13 @@ function OhhwellsBridge() {
|
|
|
28286
28198
|
return;
|
|
28287
28199
|
}
|
|
28288
28200
|
}
|
|
28201
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28202
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28203
|
+
if (target.closest(
|
|
28204
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28205
|
+
)) {
|
|
28206
|
+
return;
|
|
28207
|
+
}
|
|
28289
28208
|
{
|
|
28290
28209
|
const formEl = getFormElement(target);
|
|
28291
28210
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -28439,13 +28358,9 @@ function OhhwellsBridge() {
|
|
|
28439
28358
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
28440
28359
|
e.preventDefault();
|
|
28441
28360
|
e.stopPropagation();
|
|
28361
|
+
selectIconElementRef.current(editable);
|
|
28442
28362
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
28443
28363
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
28444
|
-
if (aiIcon) {
|
|
28445
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
28446
|
-
} else {
|
|
28447
|
-
selectIconElementRef.current(editable);
|
|
28448
|
-
}
|
|
28449
28364
|
postToParentRef.current({
|
|
28450
28365
|
type: "ow:icon-pick",
|
|
28451
28366
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -28673,9 +28588,6 @@ function OhhwellsBridge() {
|
|
|
28673
28588
|
setHoveredItemRect(null);
|
|
28674
28589
|
hoveredNavContainerRef.current = null;
|
|
28675
28590
|
setHoveredNavContainerRect(null);
|
|
28676
|
-
siblingHintElRef.current = null;
|
|
28677
|
-
setSiblingHintRect(null);
|
|
28678
|
-
setSiblingHintRects([]);
|
|
28679
28591
|
return;
|
|
28680
28592
|
}
|
|
28681
28593
|
{
|
|
@@ -28796,6 +28708,7 @@ function OhhwellsBridge() {
|
|
|
28796
28708
|
hoveredNavContainerRef.current = null;
|
|
28797
28709
|
setHoveredNavContainerRect(null);
|
|
28798
28710
|
hoveredItemElRef.current = editable;
|
|
28711
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
28799
28712
|
}
|
|
28800
28713
|
}
|
|
28801
28714
|
}
|
|
@@ -29505,11 +29418,7 @@ function OhhwellsBridge() {
|
|
|
29505
29418
|
};
|
|
29506
29419
|
const handleMouseMove = (e) => {
|
|
29507
29420
|
const { clientX, clientY } = e;
|
|
29508
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29509
|
-
dismissImageHover();
|
|
29510
|
-
clearImageHover();
|
|
29511
|
-
return;
|
|
29512
|
-
}
|
|
29421
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29513
29422
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
29514
29423
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
29515
29424
|
formHoverElRef.current = null;
|
|
@@ -29538,12 +29447,7 @@ function OhhwellsBridge() {
|
|
|
29538
29447
|
setHoveredItemRect(null);
|
|
29539
29448
|
hoveredNavContainerRef.current = null;
|
|
29540
29449
|
setHoveredNavContainerRect(null);
|
|
29541
|
-
siblingHintElRef.current = null;
|
|
29542
|
-
setSiblingHintRect(null);
|
|
29543
|
-
setSiblingHintRects([]);
|
|
29544
29450
|
dismissImageHover();
|
|
29545
|
-
clearImageHover();
|
|
29546
|
-
setSectionGap(null);
|
|
29547
29451
|
return;
|
|
29548
29452
|
}
|
|
29549
29453
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -29555,11 +29459,7 @@ function OhhwellsBridge() {
|
|
|
29555
29459
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
29556
29460
|
const { clientX, clientY } = e.data;
|
|
29557
29461
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
29558
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29559
|
-
dismissImageHover();
|
|
29560
|
-
clearImageHover();
|
|
29561
|
-
return;
|
|
29562
|
-
}
|
|
29462
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
29563
29463
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
29564
29464
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
29565
29465
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -29939,7 +29839,6 @@ function OhhwellsBridge() {
|
|
|
29939
29839
|
applyAiFooterFromContent(content);
|
|
29940
29840
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
29941
29841
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
29942
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
29943
29842
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
29944
29843
|
}
|
|
29945
29844
|
applyBrandChrome(content);
|
|
@@ -29954,12 +29853,12 @@ function OhhwellsBridge() {
|
|
|
29954
29853
|
}
|
|
29955
29854
|
if (key === AI_SECTIONS_KEY) continue;
|
|
29956
29855
|
if (key === AI_FOOTER_KEY) continue;
|
|
29957
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
29958
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
29959
29856
|
if (key === BRAND_KIT_KEY) continue;
|
|
29960
29857
|
if (key === STYLE_STORE_KEY) continue;
|
|
29961
29858
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
29859
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
29962
29860
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
29861
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
29963
29862
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
29964
29863
|
continue;
|
|
29965
29864
|
}
|
|
@@ -30595,12 +30494,6 @@ function OhhwellsBridge() {
|
|
|
30595
30494
|
closeLinkPopoverRef.current();
|
|
30596
30495
|
return;
|
|
30597
30496
|
}
|
|
30598
|
-
if (floatingPanelOpenRef.current) {
|
|
30599
|
-
setFloatingPanelRef.current(null);
|
|
30600
|
-
deselectRef.current();
|
|
30601
|
-
deactivateRef.current();
|
|
30602
|
-
return;
|
|
30603
|
-
}
|
|
30604
30497
|
deselectRef.current();
|
|
30605
30498
|
deactivateRef.current();
|
|
30606
30499
|
clearMediaSelectionRef.current();
|
|
@@ -31423,10 +31316,10 @@ function OhhwellsBridge() {
|
|
|
31423
31316
|
window.removeEventListener("message", handleDeleteSection);
|
|
31424
31317
|
window.removeEventListener("message", handleDuplicateSection);
|
|
31425
31318
|
window.removeEventListener("message", handleDeactivate);
|
|
31319
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31426
31320
|
window.removeEventListener("message", handleToastAction);
|
|
31427
31321
|
window.removeEventListener("message", handleFormCount);
|
|
31428
31322
|
window.removeEventListener("message", handleUiEscape);
|
|
31429
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
31430
31323
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
31431
31324
|
autoSaveTimers.current.clear();
|
|
31432
31325
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -31720,7 +31613,7 @@ function OhhwellsBridge() {
|
|
|
31720
31613
|
postToParent2({
|
|
31721
31614
|
type: "ow:ready",
|
|
31722
31615
|
version: "1",
|
|
31723
|
-
bridgeVersion: "0.1.
|
|
31616
|
+
bridgeVersion: "0.1.148",
|
|
31724
31617
|
path: pathname,
|
|
31725
31618
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31726
31619
|
sections
|
|
@@ -32456,7 +32349,7 @@ function OhhwellsBridge() {
|
|
|
32456
32349
|
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
|
|
32457
32350
|
onClick: () => setFieldTypePickerOpen((open) => !open),
|
|
32458
32351
|
"data-ohw-add-field": "",
|
|
32459
|
-
children: /* @__PURE__ */ jsx39(
|
|
32352
|
+
children: /* @__PURE__ */ jsx39(Plus5, { size: 15, "aria-hidden": true })
|
|
32460
32353
|
}
|
|
32461
32354
|
),
|
|
32462
32355
|
/* @__PURE__ */ jsx39("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|