@ohhwells/bridge 0.1.158-next.424 → 0.1.159
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/README.md +1 -1
- package/dist/index.cjs +722 -946
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +730 -970
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +1 -9
- package/dist/pages.cjs.map +1 -1
- package/dist/pages.d.cts +0 -2
- package/dist/pages.d.ts +0 -2
- package/dist/pages.js +1 -9
- package/dist/pages.js.map +1 -1
- package/dist/styles.css +0 -116
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -6763,21 +6763,6 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6763
6763
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6764
6764
|
return target ? pricingFeatureList(target).length : 0;
|
|
6765
6765
|
}
|
|
6766
|
-
function prevailingFeatureIcon(features) {
|
|
6767
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6768
|
-
for (const row of features) {
|
|
6769
|
-
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6770
|
-
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6771
|
-
entry.count += 1;
|
|
6772
|
-
counts.set(key, entry);
|
|
6773
|
-
}
|
|
6774
|
-
let best = null;
|
|
6775
|
-
for (const entry of counts.values()) {
|
|
6776
|
-
if (!best || entry.count > best.count) best = entry;
|
|
6777
|
-
}
|
|
6778
|
-
if (!best) return {};
|
|
6779
|
-
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6780
|
-
}
|
|
6781
6766
|
function addPricingCardFeature(tree, index, text) {
|
|
6782
6767
|
return withPricingCollection(tree, (collection) => {
|
|
6783
6768
|
const children = collection.children;
|
|
@@ -6786,7 +6771,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6786
6771
|
const features = pricingFeatureList(target);
|
|
6787
6772
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6788
6773
|
target.slots = target.slots ?? {};
|
|
6789
|
-
target.slots.features = [...features, { text
|
|
6774
|
+
target.slots.features = [...features, { text }];
|
|
6790
6775
|
return true;
|
|
6791
6776
|
});
|
|
6792
6777
|
}
|
|
@@ -7986,7 +7971,7 @@ var AI_MOBILE_CSS = [
|
|
|
7986
7971
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7987
7972
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7988
7973
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7989
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7974
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
7990
7975
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7991
7976
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7992
7977
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -8002,10 +7987,8 @@ var AI_MOBILE_CSS = [
|
|
|
8002
7987
|
"[data-ai-section]{overflow-x:hidden}",
|
|
8003
7988
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
8004
7989
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
8005
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
8006
|
-
|
|
8007
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
8008
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7990
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7991
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
8009
7992
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
8010
7993
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
8011
7994
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -8210,31 +8193,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
8210
8193
|
function textAttrs(ctx, path) {
|
|
8211
8194
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
8212
8195
|
}
|
|
8213
|
-
var AI_RESPONSIVE_CSS = [
|
|
8214
|
-
"@media (max-width: 960px) {",
|
|
8215
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
8216
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
8217
|
-
"}",
|
|
8218
|
-
"@media (max-width: 640px) {",
|
|
8219
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
8220
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
8221
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
8222
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
8223
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
8224
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
8225
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
8226
|
-
// layered text used to be.
|
|
8227
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
8228
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
8229
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
8230
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
8231
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
8232
|
-
// other rule had already been taught to stand down.
|
|
8233
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
8234
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
8235
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
8236
|
-
"}"
|
|
8237
|
-
].join("\n");
|
|
8238
8196
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8239
8197
|
function MediaBox({
|
|
8240
8198
|
refValue,
|
|
@@ -8289,7 +8247,7 @@ function MediaBox({
|
|
|
8289
8247
|
position: fill ? "absolute" : void 0,
|
|
8290
8248
|
inset: fill ? 0 : void 0,
|
|
8291
8249
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8292
|
-
height: fill ? "100%" :
|
|
8250
|
+
height: fill ? "100%" : void 0,
|
|
8293
8251
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8294
8252
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8295
8253
|
borderRadius: radius,
|
|
@@ -9785,7 +9743,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9785
9743
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9786
9744
|
"div",
|
|
9787
9745
|
{
|
|
9788
|
-
"data-ai-grid":
|
|
9746
|
+
"data-ai-grid": "",
|
|
9789
9747
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9790
9748
|
style: {
|
|
9791
9749
|
display: "grid",
|
|
@@ -10087,7 +10045,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
10087
10045
|
},
|
|
10088
10046
|
children: [
|
|
10089
10047
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
10090
|
-
// The section's `data-ai-
|
|
10048
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
10091
10049
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
10092
10050
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
10093
10051
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10506,7 +10464,6 @@ function AiTreeRenderer({
|
|
|
10506
10464
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10507
10465
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10508
10466
|
...bgAttrs,
|
|
10509
|
-
"data-ai-responsive": "",
|
|
10510
10467
|
style: {
|
|
10511
10468
|
position: "relative",
|
|
10512
10469
|
padding: `${padCss} 0`,
|
|
@@ -10520,13 +10477,12 @@ function AiTreeRenderer({
|
|
|
10520
10477
|
...fillHeight ? { display: "grid" } : {}
|
|
10521
10478
|
},
|
|
10522
10479
|
children: [
|
|
10523
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
10524
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10525
10480
|
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10481
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10526
10482
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10527
10483
|
"div",
|
|
10528
10484
|
{
|
|
10529
|
-
"data-ai-
|
|
10485
|
+
"data-ai-container": "",
|
|
10530
10486
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10531
10487
|
style: {
|
|
10532
10488
|
position: "relative",
|
|
@@ -10543,7 +10499,7 @@ function AiTreeRenderer({
|
|
|
10543
10499
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10544
10500
|
"div",
|
|
10545
10501
|
{
|
|
10546
|
-
"data-ai-
|
|
10502
|
+
"data-ai-row": "",
|
|
10547
10503
|
style: {
|
|
10548
10504
|
display: "grid",
|
|
10549
10505
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -11205,10 +11161,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
11205
11161
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
11206
11162
|
continue;
|
|
11207
11163
|
}
|
|
11164
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
11208
11165
|
let container = existing?.container;
|
|
11209
|
-
let isNewMount = false;
|
|
11210
11166
|
if (!container || !container.isConnected) {
|
|
11211
|
-
isNewMount = true;
|
|
11212
11167
|
existing?.root.unmount();
|
|
11213
11168
|
container?.remove();
|
|
11214
11169
|
container = document.createElement("div");
|
|
@@ -17367,7 +17322,7 @@ function apiBase() {
|
|
|
17367
17322
|
function bridgeVersion() {
|
|
17368
17323
|
try {
|
|
17369
17324
|
if (true) {
|
|
17370
|
-
return "0.1.
|
|
17325
|
+
return "0.1.159";
|
|
17371
17326
|
}
|
|
17372
17327
|
} catch {
|
|
17373
17328
|
}
|
|
@@ -17381,7 +17336,7 @@ function stampBridgeVersionOnDocument() {
|
|
|
17381
17336
|
return;
|
|
17382
17337
|
}
|
|
17383
17338
|
try {
|
|
17384
|
-
const v = true ? "0.1.
|
|
17339
|
+
const v = true ? "0.1.159" : "";
|
|
17385
17340
|
if (v) {
|
|
17386
17341
|
document.documentElement.setAttribute("data-ohw-bridge-version", v);
|
|
17387
17342
|
window.__OHW_BRIDGE_VERSION__ = v;
|
|
@@ -18059,7 +18014,6 @@ function MediaOverlay({
|
|
|
18059
18014
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
18060
18015
|
);
|
|
18061
18016
|
}, [isVideo]);
|
|
18062
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
18063
18017
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
18064
18018
|
const box = {
|
|
18065
18019
|
position: "fixed",
|
|
@@ -18158,10 +18112,11 @@ function MediaOverlay({
|
|
|
18158
18112
|
className: "flex items-center justify-center cursor-pointer",
|
|
18159
18113
|
style: {
|
|
18160
18114
|
...box,
|
|
18161
|
-
//
|
|
18162
|
-
//
|
|
18163
|
-
//
|
|
18164
|
-
|
|
18115
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
18116
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
18117
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
18118
|
+
// Replace still works.
|
|
18119
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
18165
18120
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
18166
18121
|
// than hovered. Hover keeps the existing tinted preview.
|
|
18167
18122
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -18188,17 +18143,17 @@ function MediaOverlay({
|
|
|
18188
18143
|
},
|
|
18189
18144
|
children: [
|
|
18190
18145
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
18191
|
-
|
|
18146
|
+
isVideo ? "Replace video" : "Replace image"
|
|
18192
18147
|
]
|
|
18193
18148
|
}
|
|
18194
18149
|
),
|
|
18195
|
-
|
|
18150
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
18196
18151
|
Button,
|
|
18197
18152
|
{
|
|
18198
18153
|
"data-ohw-media-overlay": "",
|
|
18199
18154
|
variant: "outline",
|
|
18200
18155
|
size: "sm",
|
|
18201
|
-
"aria-label":
|
|
18156
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
18202
18157
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
18203
18158
|
style: {
|
|
18204
18159
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -18221,7 +18176,7 @@ function MediaOverlay({
|
|
|
18221
18176
|
},
|
|
18222
18177
|
children: [
|
|
18223
18178
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
18224
|
-
replaceMode === "full" ?
|
|
18179
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
18225
18180
|
]
|
|
18226
18181
|
}
|
|
18227
18182
|
)
|
|
@@ -18815,7 +18770,7 @@ function AiSectionOverlay({
|
|
|
18815
18770
|
|
|
18816
18771
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18817
18772
|
var import_react10 = require("react");
|
|
18818
|
-
var
|
|
18773
|
+
var import_lucide_react8 = require("lucide-react");
|
|
18819
18774
|
|
|
18820
18775
|
// src/lib/ai-media-strip-tree.ts
|
|
18821
18776
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18929,6 +18884,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18929
18884
|
return true;
|
|
18930
18885
|
});
|
|
18931
18886
|
}
|
|
18887
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18888
|
+
return withMediaStrip(tree, (block) => {
|
|
18889
|
+
const items = block.items;
|
|
18890
|
+
if (index < 0 || index >= items.length) return false;
|
|
18891
|
+
items[index] = { ...items[index], alt };
|
|
18892
|
+
return true;
|
|
18893
|
+
});
|
|
18894
|
+
}
|
|
18932
18895
|
function setMediaStripItemLink(tree, index, link) {
|
|
18933
18896
|
return withMediaStrip(tree, (block) => {
|
|
18934
18897
|
const items = block.items;
|
|
@@ -18946,117 +18909,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18946
18909
|
});
|
|
18947
18910
|
}
|
|
18948
18911
|
|
|
18949
|
-
// src/ui/dialog.tsx
|
|
18950
|
-
var React9 = __toESM(require("react"), 1);
|
|
18951
|
-
var import_radix_ui6 = require("radix-ui");
|
|
18952
|
-
var import_lucide_react8 = require("lucide-react");
|
|
18953
|
-
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18954
|
-
function Dialog2({
|
|
18955
|
-
...props
|
|
18956
|
-
}) {
|
|
18957
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
18958
|
-
}
|
|
18959
|
-
function DialogPortal({
|
|
18960
|
-
...props
|
|
18961
|
-
}) {
|
|
18962
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
18963
|
-
}
|
|
18964
|
-
function DialogOverlay({
|
|
18965
|
-
className,
|
|
18966
|
-
...props
|
|
18967
|
-
}) {
|
|
18968
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18969
|
-
import_radix_ui6.Dialog.Overlay,
|
|
18970
|
-
{
|
|
18971
|
-
"data-slot": "dialog-overlay",
|
|
18972
|
-
"data-ohw-link-modal-root": "",
|
|
18973
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18974
|
-
...props
|
|
18975
|
-
}
|
|
18976
|
-
);
|
|
18977
|
-
}
|
|
18978
|
-
var DialogContent = React9.forwardRef(
|
|
18979
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18980
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
18981
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
18982
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18983
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18984
|
-
import_radix_ui6.Dialog.Content,
|
|
18985
|
-
{
|
|
18986
|
-
ref,
|
|
18987
|
-
"data-slot": "dialog-content",
|
|
18988
|
-
className: cn(
|
|
18989
|
-
positionMode,
|
|
18990
|
-
"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",
|
|
18991
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18992
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18993
|
-
className
|
|
18994
|
-
),
|
|
18995
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
18996
|
-
...props,
|
|
18997
|
-
children: [
|
|
18998
|
-
children,
|
|
18999
|
-
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19000
|
-
import_radix_ui6.Dialog.Close,
|
|
19001
|
-
{
|
|
19002
|
-
type: "button",
|
|
19003
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
19004
|
-
"aria-label": "Close",
|
|
19005
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
19006
|
-
}
|
|
19007
|
-
) : null
|
|
19008
|
-
]
|
|
19009
|
-
}
|
|
19010
|
-
)
|
|
19011
|
-
] });
|
|
19012
|
-
}
|
|
19013
|
-
);
|
|
19014
|
-
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
19015
|
-
function DialogHeader({
|
|
19016
|
-
className,
|
|
19017
|
-
...props
|
|
19018
|
-
}) {
|
|
19019
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
19020
|
-
}
|
|
19021
|
-
function DialogFooter({
|
|
19022
|
-
className,
|
|
19023
|
-
...props
|
|
19024
|
-
}) {
|
|
19025
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19026
|
-
"div",
|
|
19027
|
-
{
|
|
19028
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
19029
|
-
...props
|
|
19030
|
-
}
|
|
19031
|
-
);
|
|
19032
|
-
}
|
|
19033
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19034
|
-
import_radix_ui6.Dialog.Title,
|
|
19035
|
-
{
|
|
19036
|
-
ref,
|
|
19037
|
-
className: cn(
|
|
19038
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
19039
|
-
className
|
|
19040
|
-
),
|
|
19041
|
-
...props
|
|
19042
|
-
}
|
|
19043
|
-
));
|
|
19044
|
-
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
19045
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19046
|
-
import_radix_ui6.Dialog.Description,
|
|
19047
|
-
{
|
|
19048
|
-
ref,
|
|
19049
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
19050
|
-
...props
|
|
19051
|
-
}
|
|
19052
|
-
));
|
|
19053
|
-
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
19054
|
-
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
19055
|
-
|
|
19056
18912
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
19057
|
-
var
|
|
19058
|
-
var PRIMARY3 = "
|
|
19059
|
-
var
|
|
18913
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18914
|
+
var PRIMARY3 = "#0885FE";
|
|
18915
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18916
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
19060
18917
|
function findMediaStripItemElement(sectionId, index) {
|
|
19061
18918
|
const sectionEl = findByInstanceId(sectionId);
|
|
19062
18919
|
if (!sectionEl) return null;
|
|
@@ -19066,35 +18923,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
19066
18923
|
}
|
|
19067
18924
|
return null;
|
|
19068
18925
|
}
|
|
19069
|
-
function
|
|
19070
|
-
|
|
19071
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19072
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
19073
|
-
if (!itemEl) return null;
|
|
19074
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
19075
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
19076
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
19077
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
19078
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
19079
|
-
return { sectionId, index };
|
|
19080
|
-
}
|
|
19081
|
-
function sameRef(a, b) {
|
|
19082
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19083
|
-
}
|
|
19084
|
-
function rectOf(el) {
|
|
18926
|
+
function readRect2(ref) {
|
|
18927
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
19085
18928
|
if (!el) return null;
|
|
19086
18929
|
const r2 = el.getBoundingClientRect();
|
|
19087
18930
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19088
18931
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19089
18932
|
}
|
|
19090
|
-
function
|
|
19091
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
19092
|
-
}
|
|
19093
|
-
function readStripRect(ref) {
|
|
19094
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
19095
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
19096
|
-
}
|
|
19097
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18933
|
+
function useLiveItemRect(ref) {
|
|
19098
18934
|
const [rect, setRect] = (0, import_react10.useState)(null);
|
|
19099
18935
|
(0, import_react10.useEffect)(() => {
|
|
19100
18936
|
if (!ref) {
|
|
@@ -19102,7 +18938,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
19102
18938
|
return;
|
|
19103
18939
|
}
|
|
19104
18940
|
const update = () => {
|
|
19105
|
-
const next =
|
|
18941
|
+
const next = readRect2(ref);
|
|
19106
18942
|
setRect(
|
|
19107
18943
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
19108
18944
|
);
|
|
@@ -19117,49 +18953,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
19117
18953
|
window.removeEventListener("resize", update);
|
|
19118
18954
|
clearInterval(interval);
|
|
19119
18955
|
};
|
|
19120
|
-
}, [ref?.sectionId, ref?.index
|
|
18956
|
+
}, [ref?.sectionId, ref?.index]);
|
|
19121
18957
|
return rect;
|
|
19122
18958
|
}
|
|
19123
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
19124
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
19125
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19126
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
19127
|
-
const slotRef = (0, import_react10.useRef)(null);
|
|
19128
|
-
const [shift, setShift] = (0, import_react10.useState)(0);
|
|
19129
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
19130
|
-
(0, import_react10.useLayoutEffect)(() => {
|
|
19131
|
-
const slot = slotRef.current;
|
|
19132
|
-
if (!slot) return;
|
|
19133
|
-
const clamp = () => {
|
|
19134
|
-
const w = slot.offsetWidth;
|
|
19135
|
-
if (w <= 0) return;
|
|
19136
|
-
const half = w / 2;
|
|
19137
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19138
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19139
|
-
};
|
|
19140
|
-
clamp();
|
|
19141
|
-
const ro = new ResizeObserver(clamp);
|
|
19142
|
-
ro.observe(slot);
|
|
19143
|
-
return () => ro.disconnect();
|
|
19144
|
-
}, [centerX, children]);
|
|
19145
|
-
const mobile = window.innerWidth <= 480;
|
|
19146
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19147
|
-
"div",
|
|
19148
|
-
{
|
|
19149
|
-
ref: slotRef,
|
|
19150
|
-
"data-ohw-bridge": "",
|
|
19151
|
-
"data-ohw-item-interaction": "",
|
|
19152
|
-
className: "pointer-events-auto fixed",
|
|
19153
|
-
style: {
|
|
19154
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
19155
|
-
left: centerX + shift,
|
|
19156
|
-
transform: "translate(-50%, -100%)",
|
|
19157
|
-
zIndex: 2147483645
|
|
19158
|
-
},
|
|
19159
|
-
children
|
|
19160
|
-
}
|
|
19161
|
-
);
|
|
19162
|
-
}
|
|
19163
18959
|
function requestValidateTree(postToParent2, tree) {
|
|
19164
18960
|
return new Promise((resolve) => {
|
|
19165
18961
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -19196,177 +18992,221 @@ function requestAssetPick(postToParent2) {
|
|
|
19196
18992
|
postToParent2({ type: "ow:asset-pick", id });
|
|
19197
18993
|
});
|
|
19198
18994
|
}
|
|
19199
|
-
function
|
|
18995
|
+
function Pill({
|
|
19200
18996
|
label,
|
|
19201
18997
|
onClick,
|
|
19202
|
-
disabled
|
|
19203
|
-
active
|
|
19204
|
-
children
|
|
18998
|
+
disabled,
|
|
18999
|
+
active
|
|
19205
19000
|
}) {
|
|
19206
|
-
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
19211
|
-
|
|
19212
|
-
|
|
19213
|
-
|
|
19001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19002
|
+
"button",
|
|
19003
|
+
{
|
|
19004
|
+
type: "button",
|
|
19005
|
+
onClick,
|
|
19006
|
+
disabled,
|
|
19007
|
+
style: {
|
|
19008
|
+
height: 28,
|
|
19009
|
+
padding: "0 10px",
|
|
19010
|
+
display: "inline-flex",
|
|
19011
|
+
alignItems: "center",
|
|
19012
|
+
gap: 4,
|
|
19013
|
+
borderRadius: 999,
|
|
19014
|
+
border: "none",
|
|
19015
|
+
cursor: disabled ? "default" : "pointer",
|
|
19016
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
19017
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
19018
|
+
opacity: disabled ? 0.4 : 1,
|
|
19019
|
+
fontSize: 12,
|
|
19020
|
+
lineHeight: "16px",
|
|
19021
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19022
|
+
whiteSpace: "nowrap",
|
|
19023
|
+
flex: "0 0 auto"
|
|
19024
|
+
},
|
|
19025
|
+
children: label
|
|
19026
|
+
}
|
|
19027
|
+
);
|
|
19214
19028
|
}
|
|
19215
|
-
function
|
|
19216
|
-
|
|
19217
|
-
value,
|
|
19218
|
-
|
|
19219
|
-
|
|
19220
|
-
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19225
|
-
|
|
19226
|
-
"
|
|
19227
|
-
|
|
19228
|
-
|
|
19229
|
-
|
|
19230
|
-
|
|
19231
|
-
|
|
19232
|
-
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
) }),
|
|
19237
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
19238
|
-
const selected = option.value === value;
|
|
19239
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19240
|
-
DropdownMenuItem,
|
|
19029
|
+
function AltInput({ value, onCommit }) {
|
|
19030
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
19031
|
+
(0, import_react10.useEffect)(() => setDraft(value), [value]);
|
|
19032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19033
|
+
"div",
|
|
19034
|
+
{
|
|
19035
|
+
style: {
|
|
19036
|
+
display: "flex",
|
|
19037
|
+
alignItems: "center",
|
|
19038
|
+
gap: 6,
|
|
19039
|
+
height: 28,
|
|
19040
|
+
padding: "0 12px",
|
|
19041
|
+
borderRadius: 999,
|
|
19042
|
+
background: "#ffffff",
|
|
19043
|
+
width: "100%",
|
|
19044
|
+
maxWidth: 260,
|
|
19045
|
+
boxSizing: "border-box"
|
|
19046
|
+
},
|
|
19047
|
+
children: [
|
|
19048
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19049
|
+
"span",
|
|
19241
19050
|
{
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
)
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19278
|
-
|
|
19279
|
-
|
|
19280
|
-
|
|
19051
|
+
style: {
|
|
19052
|
+
flex: "0 0 auto",
|
|
19053
|
+
color: OHW_BLUE_DARK,
|
|
19054
|
+
fontSize: 10,
|
|
19055
|
+
fontWeight: 700,
|
|
19056
|
+
textTransform: "uppercase",
|
|
19057
|
+
letterSpacing: 0.4
|
|
19058
|
+
},
|
|
19059
|
+
children: "Alt"
|
|
19060
|
+
}
|
|
19061
|
+
),
|
|
19062
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19063
|
+
"input",
|
|
19064
|
+
{
|
|
19065
|
+
type: "text",
|
|
19066
|
+
value: draft,
|
|
19067
|
+
onChange: (e) => setDraft(e.target.value),
|
|
19068
|
+
onBlur: () => {
|
|
19069
|
+
if (draft !== value) onCommit(draft);
|
|
19070
|
+
},
|
|
19071
|
+
onKeyDown: (e) => {
|
|
19072
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
19073
|
+
if (e.key === "Escape") {
|
|
19074
|
+
setDraft(value);
|
|
19075
|
+
e.currentTarget.blur();
|
|
19076
|
+
}
|
|
19077
|
+
},
|
|
19078
|
+
placeholder: "Describe this image",
|
|
19079
|
+
"aria-label": "Image alt text",
|
|
19080
|
+
style: {
|
|
19081
|
+
flex: 1,
|
|
19082
|
+
minWidth: 0,
|
|
19083
|
+
border: "none",
|
|
19084
|
+
outline: "none",
|
|
19085
|
+
background: "transparent",
|
|
19086
|
+
fontSize: 12,
|
|
19087
|
+
lineHeight: "16px",
|
|
19088
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19089
|
+
color: "#1f2937"
|
|
19090
|
+
}
|
|
19091
|
+
}
|
|
19092
|
+
)
|
|
19093
|
+
]
|
|
19094
|
+
}
|
|
19095
|
+
);
|
|
19096
|
+
}
|
|
19097
|
+
var VARIANTS = [
|
|
19098
|
+
{ value: "logos", label: "Logos" },
|
|
19099
|
+
{ value: "reel", label: "Reel" }
|
|
19100
|
+
];
|
|
19101
|
+
var ALIGNS = [
|
|
19102
|
+
{ value: "left", label: "Left" },
|
|
19103
|
+
{ value: "center", label: "Center" },
|
|
19104
|
+
{ value: "right", label: "Right" }
|
|
19105
|
+
];
|
|
19106
|
+
var HOVERS = [
|
|
19107
|
+
{ value: "none", label: "None" },
|
|
19108
|
+
{ value: "lift", label: "Lift" },
|
|
19109
|
+
{ value: "zoom", label: "Zoom" },
|
|
19110
|
+
{ value: "fade", label: "Fade" }
|
|
19111
|
+
];
|
|
19112
|
+
var TREATMENTS = [
|
|
19113
|
+
{ value: "color", label: "Color" },
|
|
19114
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
19115
|
+
];
|
|
19116
|
+
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
19117
|
+
function LinkInput({ value, onCommit }) {
|
|
19118
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
19281
19119
|
const [invalid, setInvalid] = (0, import_react10.useState)(false);
|
|
19282
|
-
|
|
19120
|
+
(0, import_react10.useEffect)(() => {
|
|
19121
|
+
setDraft(value);
|
|
19122
|
+
setInvalid(false);
|
|
19123
|
+
}, [value]);
|
|
19124
|
+
const commit = () => {
|
|
19283
19125
|
const next = draft.trim();
|
|
19284
|
-
if (next
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
19289
|
-
onClose();
|
|
19126
|
+
if (next === value) return setInvalid(false);
|
|
19127
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
19128
|
+
setInvalid(false);
|
|
19129
|
+
onCommit(next);
|
|
19290
19130
|
};
|
|
19291
|
-
return /* @__PURE__ */ (0,
|
|
19292
|
-
|
|
19293
|
-
|
|
19294
|
-
|
|
19295
|
-
"
|
|
19296
|
-
|
|
19297
|
-
|
|
19298
|
-
|
|
19299
|
-
|
|
19300
|
-
|
|
19301
|
-
|
|
19302
|
-
|
|
19303
|
-
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
"
|
|
19310
|
-
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19350
|
-
|
|
19351
|
-
|
|
19352
|
-
|
|
19353
|
-
|
|
19354
|
-
|
|
19355
|
-
|
|
19131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19132
|
+
"div",
|
|
19133
|
+
{
|
|
19134
|
+
style: {
|
|
19135
|
+
display: "flex",
|
|
19136
|
+
alignItems: "center",
|
|
19137
|
+
gap: 6,
|
|
19138
|
+
height: 28,
|
|
19139
|
+
padding: "0 12px",
|
|
19140
|
+
borderRadius: 999,
|
|
19141
|
+
background: "#ffffff",
|
|
19142
|
+
width: "100%",
|
|
19143
|
+
maxWidth: 260,
|
|
19144
|
+
boxSizing: "border-box",
|
|
19145
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19146
|
+
},
|
|
19147
|
+
children: [
|
|
19148
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19149
|
+
"span",
|
|
19150
|
+
{
|
|
19151
|
+
style: {
|
|
19152
|
+
flex: "0 0 auto",
|
|
19153
|
+
color: OHW_BLUE_DARK,
|
|
19154
|
+
fontSize: 10,
|
|
19155
|
+
fontWeight: 700,
|
|
19156
|
+
textTransform: "uppercase",
|
|
19157
|
+
letterSpacing: 0.4
|
|
19158
|
+
},
|
|
19159
|
+
children: "Link"
|
|
19160
|
+
}
|
|
19161
|
+
),
|
|
19162
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19163
|
+
"input",
|
|
19164
|
+
{
|
|
19165
|
+
type: "text",
|
|
19166
|
+
inputMode: "url",
|
|
19167
|
+
value: draft,
|
|
19168
|
+
onChange: (e) => setDraft(e.target.value),
|
|
19169
|
+
onBlur: commit,
|
|
19170
|
+
onKeyDown: (e) => {
|
|
19171
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
19172
|
+
if (e.key === "Escape") {
|
|
19173
|
+
setDraft(value);
|
|
19174
|
+
setInvalid(false);
|
|
19175
|
+
e.currentTarget.blur();
|
|
19176
|
+
}
|
|
19177
|
+
},
|
|
19178
|
+
placeholder: "https://example.com",
|
|
19179
|
+
"aria-label": "Image link URL",
|
|
19180
|
+
"aria-invalid": invalid,
|
|
19181
|
+
style: {
|
|
19182
|
+
flex: 1,
|
|
19183
|
+
minWidth: 0,
|
|
19184
|
+
border: "none",
|
|
19185
|
+
outline: "none",
|
|
19186
|
+
background: "transparent",
|
|
19187
|
+
fontSize: 12,
|
|
19188
|
+
lineHeight: "16px",
|
|
19189
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19190
|
+
color: "#1f2937"
|
|
19191
|
+
}
|
|
19192
|
+
}
|
|
19193
|
+
)
|
|
19194
|
+
]
|
|
19195
|
+
}
|
|
19196
|
+
);
|
|
19356
19197
|
}
|
|
19357
19198
|
function MediaStripToolbar({
|
|
19358
19199
|
entry,
|
|
19359
19200
|
index,
|
|
19360
19201
|
pending,
|
|
19361
19202
|
error,
|
|
19362
|
-
itemEditOn,
|
|
19363
|
-
onToggleItemEdit,
|
|
19364
19203
|
onSetVariant,
|
|
19365
19204
|
onSetAlign,
|
|
19366
19205
|
onSetHover,
|
|
19367
19206
|
onSetTreatment,
|
|
19368
19207
|
onResize,
|
|
19369
|
-
|
|
19208
|
+
onSetAlt,
|
|
19209
|
+
onSetLink,
|
|
19370
19210
|
onAddItem,
|
|
19371
19211
|
onRemoveItem,
|
|
19372
19212
|
onChangeImage,
|
|
@@ -19375,102 +19215,81 @@ function MediaStripToolbar({
|
|
|
19375
19215
|
}) {
|
|
19376
19216
|
const items = mediaStripItems(entry.tree);
|
|
19377
19217
|
const itemCount = items.length;
|
|
19218
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
19219
|
+
const currentHref = items[index]?.href ?? "";
|
|
19220
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
19378
19221
|
const slots = findMediaStripSlots(entry.tree);
|
|
19379
19222
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
19380
19223
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
19381
19224
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
19382
19225
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
19383
19226
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
19384
|
-
const
|
|
19385
|
-
const
|
|
19386
|
-
|
|
19227
|
+
const isMobile = window.innerWidth <= 480;
|
|
19228
|
+
const rowStyle = isMobile ? {
|
|
19229
|
+
display: "flex",
|
|
19230
|
+
gap: 6,
|
|
19231
|
+
flexWrap: "nowrap",
|
|
19232
|
+
justifyContent: "center",
|
|
19233
|
+
overflowX: "auto",
|
|
19234
|
+
WebkitOverflowScrolling: "touch",
|
|
19235
|
+
width: "100%",
|
|
19236
|
+
scrollbarWidth: "none"
|
|
19237
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
19238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19387
19239
|
"div",
|
|
19388
19240
|
{
|
|
19389
19241
|
"data-ohw-bridge": "",
|
|
19390
19242
|
"data-ohw-toolbar": "",
|
|
19391
19243
|
onMouseDown: (e) => e.stopPropagation(),
|
|
19392
|
-
|
|
19393
|
-
|
|
19244
|
+
style: {
|
|
19245
|
+
display: "flex",
|
|
19246
|
+
flexDirection: "column",
|
|
19247
|
+
gap: 6,
|
|
19248
|
+
alignItems: "center",
|
|
19249
|
+
background: OHW_BLUE,
|
|
19250
|
+
padding: 8,
|
|
19251
|
+
borderRadius: 12,
|
|
19252
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
19253
|
+
pointerEvents: pending ? "none" : "auto",
|
|
19254
|
+
opacity: pending ? 0.6 : 1,
|
|
19255
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
19256
|
+
},
|
|
19394
19257
|
children: [
|
|
19395
|
-
/* @__PURE__ */ (0,
|
|
19396
|
-
|
|
19397
|
-
{
|
|
19398
|
-
|
|
19399
|
-
|
|
19400
|
-
|
|
19401
|
-
|
|
19402
|
-
|
|
19403
|
-
|
|
19404
|
-
|
|
19405
|
-
|
|
19406
|
-
|
|
19407
|
-
|
|
19408
|
-
|
|
19409
|
-
|
|
19410
|
-
|
|
19411
|
-
|
|
19412
|
-
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
|
|
19421
|
-
|
|
19422
|
-
|
|
19423
|
-
|
|
19424
|
-
|
|
19425
|
-
|
|
19426
|
-
|
|
19427
|
-
) }),
|
|
19428
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
19429
|
-
] }),
|
|
19430
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19431
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Image, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19432
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Link, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19433
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ArrowLeft, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19434
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19435
|
-
ToolbarAction,
|
|
19436
|
-
{
|
|
19437
|
-
label: gatedLabel("Move right"),
|
|
19438
|
-
onClick: onMoveRight,
|
|
19439
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
19440
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ArrowRight, { size: 16, style: { pointerEvents: "none" } })
|
|
19441
|
-
}
|
|
19442
|
-
),
|
|
19443
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19444
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19445
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
19446
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
19447
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19448
|
-
ToolbarAction,
|
|
19449
|
-
{
|
|
19450
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
19451
|
-
active: treatment === "grayscale",
|
|
19452
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
19453
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
19454
|
-
}
|
|
19455
|
-
),
|
|
19456
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19457
|
-
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
19458
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19459
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19460
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
19461
|
-
sizeValue,
|
|
19462
|
-
"px"
|
|
19463
|
-
] }),
|
|
19464
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19465
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19466
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19467
|
-
]
|
|
19468
|
-
}
|
|
19469
|
-
),
|
|
19470
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19258
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19259
|
+
VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
19260
|
+
ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
19261
|
+
] }),
|
|
19262
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19263
|
+
HOVERS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
19264
|
+
TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
19265
|
+
] }),
|
|
19266
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
19267
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
19268
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
19269
|
+
sizeValue,
|
|
19270
|
+
"px"
|
|
19271
|
+
] }),
|
|
19272
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "+", onClick: () => onResize(8) })
|
|
19273
|
+
] }),
|
|
19274
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
19275
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkInput, { value: currentHref, onCommit: (href) => onSetLink(href, currentTarget) }) }),
|
|
19276
|
+
currentHref && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19277
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
19278
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
19279
|
+
] }),
|
|
19280
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19281
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
19282
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
19283
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
19284
|
+
] }),
|
|
19285
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19286
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
19287
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
19288
|
+
] }),
|
|
19289
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19471
19290
|
]
|
|
19472
19291
|
}
|
|
19473
|
-
)
|
|
19292
|
+
);
|
|
19474
19293
|
}
|
|
19475
19294
|
function findMediaStripSlots(tree) {
|
|
19476
19295
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -19489,23 +19308,31 @@ function AiMediaStripOverlay({
|
|
|
19489
19308
|
}) {
|
|
19490
19309
|
const [hover, setHover] = (0, import_react10.useState)(null);
|
|
19491
19310
|
const [active, setActive] = (0, import_react10.useState)(null);
|
|
19492
|
-
const [itemEditOn, setItemEditOn] = (0, import_react10.useState)(false);
|
|
19493
|
-
const [linkOpen, setLinkOpen] = (0, import_react10.useState)(false);
|
|
19494
19311
|
const [pending, setPending] = (0, import_react10.useState)(false);
|
|
19495
19312
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
19496
19313
|
const activeRef = (0, import_react10.useRef)(null);
|
|
19497
19314
|
activeRef.current = active;
|
|
19498
|
-
const linkOpenRef = (0, import_react10.useRef)(false);
|
|
19499
|
-
linkOpenRef.current = linkOpen;
|
|
19500
19315
|
(0, import_react10.useEffect)(() => {
|
|
19501
19316
|
const onMove = (e) => {
|
|
19502
|
-
const ref = itemRefFromTarget(e.target);
|
|
19503
19317
|
const t = e.target;
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19318
|
+
if (!(t instanceof HTMLElement)) return;
|
|
19319
|
+
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]")) {
|
|
19320
|
+
return;
|
|
19321
|
+
}
|
|
19322
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
19323
|
+
if (!itemEl) {
|
|
19324
|
+
setHover(null);
|
|
19325
|
+
return;
|
|
19326
|
+
}
|
|
19327
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
19328
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
19329
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
19330
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
19331
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
19332
|
+
setHover(null);
|
|
19333
|
+
return;
|
|
19334
|
+
}
|
|
19335
|
+
setHover({ sectionId, index });
|
|
19509
19336
|
};
|
|
19510
19337
|
const onLeave = () => setHover(null);
|
|
19511
19338
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -19517,25 +19344,23 @@ function AiMediaStripOverlay({
|
|
|
19517
19344
|
}, []);
|
|
19518
19345
|
(0, import_react10.useEffect)(() => {
|
|
19519
19346
|
const onClick = (e) => {
|
|
19347
|
+
const current = activeRef.current;
|
|
19348
|
+
if (!current) return;
|
|
19520
19349
|
const t = e.target;
|
|
19521
|
-
if (!(t instanceof
|
|
19522
|
-
if (t.closest(
|
|
19523
|
-
const
|
|
19524
|
-
if (
|
|
19525
|
-
|
|
19526
|
-
setItemEditOn(false);
|
|
19350
|
+
if (!(t instanceof HTMLElement)) return;
|
|
19351
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
19352
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
19353
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
19354
|
+
setActive(null);
|
|
19527
19355
|
setError(null);
|
|
19528
|
-
setActive(ref);
|
|
19529
19356
|
};
|
|
19530
19357
|
document.addEventListener("click", onClick, true);
|
|
19531
19358
|
return () => document.removeEventListener("click", onClick, true);
|
|
19532
|
-
}, [
|
|
19359
|
+
}, []);
|
|
19533
19360
|
(0, import_react10.useEffect)(() => {
|
|
19534
19361
|
const onBlur = () => {
|
|
19535
19362
|
if (!activeRef.current) return;
|
|
19536
19363
|
setActive(null);
|
|
19537
|
-
setItemEditOn(false);
|
|
19538
|
-
setLinkOpen(false);
|
|
19539
19364
|
setError(null);
|
|
19540
19365
|
};
|
|
19541
19366
|
window.addEventListener("blur", onBlur);
|
|
@@ -19545,10 +19370,7 @@ function AiMediaStripOverlay({
|
|
|
19545
19370
|
const onKeyDown = (e) => {
|
|
19546
19371
|
if (e.key !== "Escape") return;
|
|
19547
19372
|
if (!activeRef.current) return;
|
|
19548
|
-
if (linkOpenRef.current) return;
|
|
19549
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
19550
19373
|
setActive(null);
|
|
19551
|
-
setItemEditOn(false);
|
|
19552
19374
|
setError(null);
|
|
19553
19375
|
};
|
|
19554
19376
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -19582,133 +19404,137 @@ function AiMediaStripOverlay({
|
|
|
19582
19404
|
tree: nextTree,
|
|
19583
19405
|
label: entry.label,
|
|
19584
19406
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
19585
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
19586
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
19587
|
-
// on every edit reads as the section jumping around.
|
|
19588
|
-
skipScrollIntoView: true
|
|
19407
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
19589
19408
|
});
|
|
19590
19409
|
return true;
|
|
19591
19410
|
},
|
|
19592
19411
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
19593
19412
|
);
|
|
19594
19413
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19414
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
19595
19415
|
const activeItemRect = useLiveItemRect(active);
|
|
19596
|
-
const
|
|
19597
|
-
const
|
|
19598
|
-
|
|
19599
|
-
|
|
19600
|
-
|
|
19601
|
-
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19614
|
-
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
|
|
19618
|
-
|
|
19619
|
-
|
|
19620
|
-
|
|
19621
|
-
|
|
19622
|
-
|
|
19623
|
-
|
|
19624
|
-
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
19628
|
-
|
|
19629
|
-
|
|
19416
|
+
const TOOLBAR_APPROX_H = 170;
|
|
19417
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
19419
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19420
|
+
"button",
|
|
19421
|
+
{
|
|
19422
|
+
type: "button",
|
|
19423
|
+
"data-ohw-toolbar": "",
|
|
19424
|
+
onClick: () => {
|
|
19425
|
+
clearInteractionChromeRef.current();
|
|
19426
|
+
setActive(hover);
|
|
19427
|
+
},
|
|
19428
|
+
"aria-label": "Configure media item",
|
|
19429
|
+
style: {
|
|
19430
|
+
position: "fixed",
|
|
19431
|
+
top: hoverHandleRect.top + 8,
|
|
19432
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
19433
|
+
width: 28,
|
|
19434
|
+
height: 28,
|
|
19435
|
+
borderRadius: 8,
|
|
19436
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
19437
|
+
background: "#ffffff",
|
|
19438
|
+
color: PRIMARY3,
|
|
19439
|
+
display: "flex",
|
|
19440
|
+
alignItems: "center",
|
|
19441
|
+
justifyContent: "center",
|
|
19442
|
+
cursor: "pointer",
|
|
19443
|
+
zIndex: 2147483643,
|
|
19444
|
+
fontSize: 14,
|
|
19445
|
+
fontWeight: 700
|
|
19446
|
+
},
|
|
19447
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
19448
|
+
}
|
|
19449
|
+
),
|
|
19450
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19451
|
+
ItemInteractionLayer,
|
|
19452
|
+
{
|
|
19453
|
+
rect: activeItemRect,
|
|
19454
|
+
state: toolbarState,
|
|
19455
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19456
|
+
MediaStripToolbar,
|
|
19457
|
+
{
|
|
19458
|
+
entry: activeEntry,
|
|
19459
|
+
index: active.index,
|
|
19460
|
+
pending,
|
|
19461
|
+
error,
|
|
19462
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
19463
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
19464
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
19465
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
19466
|
+
onResize: (delta) => {
|
|
19467
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
19468
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
19469
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
19470
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
19471
|
+
},
|
|
19472
|
+
onSetAlt: (alt) => {
|
|
19473
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
19474
|
+
},
|
|
19475
|
+
onSetLink: (href, linkTarget) => {
|
|
19630
19476
|
void runMutation(
|
|
19631
19477
|
active.sectionId,
|
|
19632
|
-
(tree) =>
|
|
19633
|
-
|
|
19634
|
-
|
|
19635
|
-
|
|
19478
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19479
|
+
);
|
|
19480
|
+
},
|
|
19481
|
+
onAddItem: () => {
|
|
19482
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19483
|
+
if (!picked) return;
|
|
19484
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
19485
|
+
void runMutation(
|
|
19486
|
+
active.sectionId,
|
|
19487
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
19488
|
+
{ [picked.assetId]: picked.url }
|
|
19489
|
+
).then((applied) => {
|
|
19490
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19491
|
+
});
|
|
19636
19492
|
});
|
|
19637
|
-
}
|
|
19638
|
-
|
|
19639
|
-
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19643
|
-
|
|
19644
|
-
|
|
19645
|
-
|
|
19493
|
+
},
|
|
19494
|
+
onChangeImage: () => {
|
|
19495
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19496
|
+
if (!picked) return;
|
|
19497
|
+
void runMutation(
|
|
19498
|
+
active.sectionId,
|
|
19499
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
19500
|
+
{ [picked.assetId]: picked.url }
|
|
19501
|
+
);
|
|
19502
|
+
});
|
|
19503
|
+
},
|
|
19504
|
+
onRemoveItem: () => {
|
|
19505
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
19506
|
+
(applied) => {
|
|
19507
|
+
if (applied) setActive(null);
|
|
19508
|
+
}
|
|
19646
19509
|
);
|
|
19647
|
-
}
|
|
19648
|
-
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
19652
|
-
|
|
19653
|
-
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19660
|
-
|
|
19661
|
-
|
|
19662
|
-
},
|
|
19663
|
-
onMoveRight: () => {
|
|
19664
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19665
|
-
(applied) => {
|
|
19666
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19667
|
-
}
|
|
19668
|
-
);
|
|
19669
|
-
}
|
|
19670
|
-
}
|
|
19671
|
-
) }),
|
|
19672
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19673
|
-
"div",
|
|
19674
|
-
{
|
|
19675
|
-
"data-ohw-bridge": "",
|
|
19676
|
-
"data-ohw-item-interaction": "",
|
|
19677
|
-
"aria-hidden": true,
|
|
19678
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
19679
|
-
style: {
|
|
19680
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
19681
|
-
left: activeItemRect.left - 5,
|
|
19682
|
-
background: PRIMARY3,
|
|
19683
|
-
zIndex: 2147483644
|
|
19684
|
-
},
|
|
19685
|
-
children: "Media item"
|
|
19686
|
-
}
|
|
19687
|
-
),
|
|
19688
|
-
linkOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19689
|
-
LinkModal,
|
|
19690
|
-
{
|
|
19691
|
-
href: activeHref,
|
|
19692
|
-
linkTarget: activeTarget,
|
|
19693
|
-
onClose: () => setLinkOpen(false),
|
|
19694
|
-
onSave: (href, linkTarget) => {
|
|
19695
|
-
void runMutation(
|
|
19696
|
-
active.sectionId,
|
|
19697
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19698
|
-
);
|
|
19510
|
+
},
|
|
19511
|
+
onMoveLeft: () => {
|
|
19512
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
19513
|
+
(applied) => {
|
|
19514
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
19515
|
+
}
|
|
19516
|
+
);
|
|
19517
|
+
},
|
|
19518
|
+
onMoveRight: () => {
|
|
19519
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19520
|
+
(applied) => {
|
|
19521
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19522
|
+
}
|
|
19523
|
+
);
|
|
19524
|
+
}
|
|
19699
19525
|
}
|
|
19700
|
-
|
|
19701
|
-
|
|
19702
|
-
|
|
19526
|
+
)
|
|
19527
|
+
}
|
|
19528
|
+
)
|
|
19703
19529
|
] });
|
|
19704
19530
|
}
|
|
19705
19531
|
|
|
19706
19532
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
19707
19533
|
var import_react11 = require("react");
|
|
19708
|
-
var
|
|
19709
|
-
var
|
|
19534
|
+
var import_lucide_react9 = require("lucide-react");
|
|
19535
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
19710
19536
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
19711
|
-
var
|
|
19537
|
+
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]";
|
|
19712
19538
|
function findPricingCardElement(sectionId, index) {
|
|
19713
19539
|
const sectionEl = findByInstanceId(sectionId);
|
|
19714
19540
|
if (!sectionEl) return null;
|
|
@@ -19720,7 +19546,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19720
19546
|
}
|
|
19721
19547
|
function cardRefFromTarget(target) {
|
|
19722
19548
|
if (!(target instanceof Element)) return null;
|
|
19723
|
-
if (target.closest(
|
|
19549
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19724
19550
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19725
19551
|
if (!cardEl) return null;
|
|
19726
19552
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19730,21 +19556,21 @@ function cardRefFromTarget(target) {
|
|
|
19730
19556
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19731
19557
|
return { sectionId, index };
|
|
19732
19558
|
}
|
|
19733
|
-
function
|
|
19559
|
+
function sameRef(a, b) {
|
|
19734
19560
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19735
19561
|
}
|
|
19736
|
-
function
|
|
19562
|
+
function rectOf(el) {
|
|
19737
19563
|
if (!el) return null;
|
|
19738
19564
|
const r2 = el.getBoundingClientRect();
|
|
19739
19565
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19740
19566
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19741
19567
|
}
|
|
19742
19568
|
function readRect3(ref) {
|
|
19743
|
-
return
|
|
19569
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19744
19570
|
}
|
|
19745
19571
|
function readGridRect(ref) {
|
|
19746
19572
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19747
|
-
return
|
|
19573
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19748
19574
|
}
|
|
19749
19575
|
function useLiveCardRect(ref, grid = false) {
|
|
19750
19576
|
const [rect, setRect] = (0, import_react11.useState)(null);
|
|
@@ -19774,7 +19600,7 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19774
19600
|
}
|
|
19775
19601
|
var TOOLBAR_GRID_GAP = 52;
|
|
19776
19602
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19777
|
-
var
|
|
19603
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19778
19604
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19779
19605
|
const slotRef = (0, import_react11.useRef)(null);
|
|
19780
19606
|
const [shift, setShift] = (0, import_react11.useState)(0);
|
|
@@ -19786,7 +19612,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19786
19612
|
const w = slot.offsetWidth;
|
|
19787
19613
|
if (w <= 0) return;
|
|
19788
19614
|
const half = w / 2;
|
|
19789
|
-
const clamped = Math.max(
|
|
19615
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19790
19616
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19791
19617
|
};
|
|
19792
19618
|
clamp();
|
|
@@ -19795,7 +19621,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19795
19621
|
return () => ro.disconnect();
|
|
19796
19622
|
}, [centerX, children]);
|
|
19797
19623
|
const mobile = window.innerWidth <= 480;
|
|
19798
|
-
return /* @__PURE__ */ (0,
|
|
19624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19799
19625
|
"div",
|
|
19800
19626
|
{
|
|
19801
19627
|
ref: slotRef,
|
|
@@ -19830,7 +19656,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
19830
19656
|
});
|
|
19831
19657
|
}
|
|
19832
19658
|
function StyleSwatch({ style }) {
|
|
19833
|
-
return /* @__PURE__ */ (0,
|
|
19659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19834
19660
|
"span",
|
|
19835
19661
|
{
|
|
19836
19662
|
"aria-hidden": true,
|
|
@@ -19844,35 +19670,35 @@ function StyleSwatch({ style }) {
|
|
|
19844
19670
|
);
|
|
19845
19671
|
}
|
|
19846
19672
|
function ButtonGlyph() {
|
|
19847
|
-
return /* @__PURE__ */ (0,
|
|
19848
|
-
/* @__PURE__ */ (0,
|
|
19849
|
-
/* @__PURE__ */ (0,
|
|
19673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19674
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19675
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19850
19676
|
] });
|
|
19851
19677
|
}
|
|
19852
19678
|
function FeatureGlyph({ mode }) {
|
|
19853
|
-
return /* @__PURE__ */ (0,
|
|
19854
|
-
/* @__PURE__ */ (0,
|
|
19855
|
-
/* @__PURE__ */ (0,
|
|
19856
|
-
/* @__PURE__ */ (0,
|
|
19857
|
-
/* @__PURE__ */ (0,
|
|
19858
|
-
/* @__PURE__ */ (0,
|
|
19859
|
-
mode === "add" && /* @__PURE__ */ (0,
|
|
19679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19680
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19681
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19682
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19683
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19684
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19685
|
+
mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19860
19686
|
] });
|
|
19861
19687
|
}
|
|
19862
|
-
function
|
|
19688
|
+
function ToolbarAction({
|
|
19863
19689
|
label,
|
|
19864
19690
|
onClick,
|
|
19865
19691
|
disabled = false,
|
|
19866
19692
|
children
|
|
19867
19693
|
}) {
|
|
19868
|
-
const button = /* @__PURE__ */ (0,
|
|
19869
|
-
return /* @__PURE__ */ (0,
|
|
19870
|
-
/* @__PURE__ */ (0,
|
|
19871
|
-
/* @__PURE__ */ (0,
|
|
19694
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19696
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
19697
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19872
19698
|
] });
|
|
19873
19699
|
}
|
|
19874
|
-
function
|
|
19875
|
-
return /* @__PURE__ */ (0,
|
|
19700
|
+
function ToolbarSeparator() {
|
|
19701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19876
19702
|
}
|
|
19877
19703
|
function CardStyleMenu({
|
|
19878
19704
|
value,
|
|
@@ -19880,7 +19706,7 @@ function CardStyleMenu({
|
|
|
19880
19706
|
disabled = false
|
|
19881
19707
|
}) {
|
|
19882
19708
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
19883
|
-
const trigger = /* @__PURE__ */ (0,
|
|
19709
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19884
19710
|
"button",
|
|
19885
19711
|
{
|
|
19886
19712
|
type: "button",
|
|
@@ -19891,28 +19717,28 @@ function CardStyleMenu({
|
|
|
19891
19717
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
19892
19718
|
),
|
|
19893
19719
|
children: [
|
|
19894
|
-
/* @__PURE__ */ (0,
|
|
19895
|
-
/* @__PURE__ */ (0,
|
|
19896
|
-
/* @__PURE__ */ (0,
|
|
19720
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: current.value }),
|
|
19721
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
19722
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
19897
19723
|
]
|
|
19898
19724
|
}
|
|
19899
19725
|
);
|
|
19900
19726
|
if (disabled) {
|
|
19901
|
-
return /* @__PURE__ */ (0,
|
|
19902
|
-
/* @__PURE__ */ (0,
|
|
19903
|
-
/* @__PURE__ */ (0,
|
|
19904
|
-
/* @__PURE__ */ (0,
|
|
19905
|
-
/* @__PURE__ */ (0,
|
|
19727
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19728
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19729
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19730
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
19731
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
19906
19732
|
] })
|
|
19907
19733
|
] });
|
|
19908
19734
|
}
|
|
19909
|
-
return /* @__PURE__ */ (0,
|
|
19910
|
-
/* @__PURE__ */ (0,
|
|
19911
|
-
/* @__PURE__ */ (0,
|
|
19912
|
-
/* @__PURE__ */ (0,
|
|
19913
|
-
/* @__PURE__ */ (0,
|
|
19735
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19736
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19737
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenu, { modal: false, children: [
|
|
19738
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19739
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
19914
19740
|
const selected = style.value === value;
|
|
19915
|
-
return /* @__PURE__ */ (0,
|
|
19741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19916
19742
|
DropdownMenuItem,
|
|
19917
19743
|
{
|
|
19918
19744
|
role: "menuitemradio",
|
|
@@ -19920,9 +19746,9 @@ function CardStyleMenu({
|
|
|
19920
19746
|
onSelect: () => onChange(style.value),
|
|
19921
19747
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19922
19748
|
children: [
|
|
19923
|
-
/* @__PURE__ */ (0,
|
|
19924
|
-
/* @__PURE__ */ (0,
|
|
19925
|
-
selected && /* @__PURE__ */ (0,
|
|
19749
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: style.value }),
|
|
19750
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: style.label }),
|
|
19751
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
|
|
19926
19752
|
]
|
|
19927
19753
|
},
|
|
19928
19754
|
style.value
|
|
@@ -19952,7 +19778,7 @@ function PricingCardToolbar({
|
|
|
19952
19778
|
const style = pricingCardStyle(entry.tree, index);
|
|
19953
19779
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19954
19780
|
const mobile = window.innerWidth <= 480;
|
|
19955
|
-
return /* @__PURE__ */ (0,
|
|
19781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19956
19782
|
"div",
|
|
19957
19783
|
{
|
|
19958
19784
|
"data-ohw-bridge": "",
|
|
@@ -19964,7 +19790,7 @@ function PricingCardToolbar({
|
|
|
19964
19790
|
),
|
|
19965
19791
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19966
19792
|
children: [
|
|
19967
|
-
/* @__PURE__ */ (0,
|
|
19793
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19968
19794
|
"div",
|
|
19969
19795
|
{
|
|
19970
19796
|
className: cn(
|
|
@@ -19973,8 +19799,8 @@ function PricingCardToolbar({
|
|
|
19973
19799
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19974
19800
|
),
|
|
19975
19801
|
children: [
|
|
19976
|
-
/* @__PURE__ */ (0,
|
|
19977
|
-
/* @__PURE__ */ (0,
|
|
19802
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19803
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19978
19804
|
CustomToolbarButton,
|
|
19979
19805
|
{
|
|
19980
19806
|
type: "button",
|
|
@@ -19982,8 +19808,8 @@ function PricingCardToolbar({
|
|
|
19982
19808
|
"aria-pressed": featuredTag,
|
|
19983
19809
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19984
19810
|
className: "group size-8",
|
|
19985
|
-
children: /* @__PURE__ */ (0,
|
|
19986
|
-
|
|
19811
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19812
|
+
import_lucide_react9.Star,
|
|
19987
19813
|
{
|
|
19988
19814
|
size: 16,
|
|
19989
19815
|
fill: "currentColor",
|
|
@@ -19997,25 +19823,25 @@ function PricingCardToolbar({
|
|
|
19997
19823
|
)
|
|
19998
19824
|
}
|
|
19999
19825
|
) }),
|
|
20000
|
-
/* @__PURE__ */ (0,
|
|
19826
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
20001
19827
|
] }),
|
|
20002
|
-
/* @__PURE__ */ (0,
|
|
20003
|
-
/* @__PURE__ */ (0,
|
|
20004
|
-
/* @__PURE__ */ (0,
|
|
20005
|
-
/* @__PURE__ */ (0,
|
|
20006
|
-
/* @__PURE__ */ (0,
|
|
20007
|
-
/* @__PURE__ */ (0,
|
|
20008
|
-
/* @__PURE__ */ (0,
|
|
19828
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19829
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19830
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19831
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}) }),
|
|
19832
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "relative inline-flex", children: [
|
|
19833
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}),
|
|
19834
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
20009
19835
|
] }) }),
|
|
20010
|
-
/* @__PURE__ */ (0,
|
|
20011
|
-
/* @__PURE__ */ (0,
|
|
20012
|
-
/* @__PURE__ */ (0,
|
|
20013
|
-
/* @__PURE__ */ (0,
|
|
20014
|
-
/* @__PURE__ */ (0,
|
|
19836
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FeatureGlyph, { mode: "add" }) }),
|
|
19837
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FeatureGlyph, { mode: "remove" }) }),
|
|
19838
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19839
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19840
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
20015
19841
|
]
|
|
20016
19842
|
}
|
|
20017
19843
|
),
|
|
20018
|
-
error && /* @__PURE__ */ (0,
|
|
19844
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
20019
19845
|
]
|
|
20020
19846
|
}
|
|
20021
19847
|
) });
|
|
@@ -20049,7 +19875,7 @@ function AiPricingCardOverlay({
|
|
|
20049
19875
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
20050
19876
|
setHover((prev) => {
|
|
20051
19877
|
const next = ref && !overEditable ? ref : null;
|
|
20052
|
-
return
|
|
19878
|
+
return sameRef(prev, next) ? prev : next;
|
|
20053
19879
|
});
|
|
20054
19880
|
};
|
|
20055
19881
|
const onLeave = () => setHover(null);
|
|
@@ -20064,10 +19890,10 @@ function AiPricingCardOverlay({
|
|
|
20064
19890
|
const onClick = (e) => {
|
|
20065
19891
|
const t = e.target;
|
|
20066
19892
|
if (!(t instanceof Element)) return;
|
|
20067
|
-
if (t.closest(
|
|
19893
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
20068
19894
|
const ref = cardRefFromTarget(t);
|
|
20069
|
-
setActive((prev) =>
|
|
20070
|
-
if (!ref || !
|
|
19895
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19896
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
20071
19897
|
};
|
|
20072
19898
|
document.addEventListener("click", onClick, true);
|
|
20073
19899
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -20132,12 +19958,12 @@ function AiPricingCardOverlay({
|
|
|
20132
19958
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
20133
19959
|
const activeCardRect = useLiveCardRect(active);
|
|
20134
19960
|
const activeGridRect = useLiveCardRect(active, true);
|
|
20135
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
20136
|
-
return /* @__PURE__ */ (0,
|
|
20137
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
20138
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20139
|
-
/* @__PURE__ */ (0,
|
|
20140
|
-
/* @__PURE__ */ (0,
|
|
19961
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19963
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19964
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19965
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19966
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
20141
19967
|
PricingCardToolbar,
|
|
20142
19968
|
{
|
|
20143
19969
|
entry: activeEntry,
|
|
@@ -20165,7 +19991,7 @@ function AiPricingCardOverlay({
|
|
|
20165
19991
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
20166
19992
|
}
|
|
20167
19993
|
) }),
|
|
20168
|
-
/* @__PURE__ */ (0,
|
|
19994
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
20169
19995
|
"div",
|
|
20170
19996
|
{
|
|
20171
19997
|
"data-ohw-bridge": "",
|
|
@@ -20187,7 +20013,7 @@ function AiPricingCardOverlay({
|
|
|
20187
20013
|
|
|
20188
20014
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
20189
20015
|
var import_react12 = require("react");
|
|
20190
|
-
var
|
|
20016
|
+
var import_lucide_react10 = require("lucide-react");
|
|
20191
20017
|
|
|
20192
20018
|
// src/lib/ai-video-tree.ts
|
|
20193
20019
|
function resolveVideoBlock(tree, path) {
|
|
@@ -20258,10 +20084,10 @@ function extractYouTubeId(input) {
|
|
|
20258
20084
|
}
|
|
20259
20085
|
|
|
20260
20086
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
20261
|
-
var
|
|
20087
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
20262
20088
|
var PRIMARY5 = "#0885FE";
|
|
20263
|
-
var
|
|
20264
|
-
var
|
|
20089
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
20090
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
20265
20091
|
function findVideoBlockElement(sectionId, path) {
|
|
20266
20092
|
const sectionEl = findByInstanceId(sectionId);
|
|
20267
20093
|
if (!sectionEl) return null;
|
|
@@ -20321,12 +20147,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
20321
20147
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
20322
20148
|
});
|
|
20323
20149
|
}
|
|
20324
|
-
function
|
|
20150
|
+
function Pill2({
|
|
20325
20151
|
label,
|
|
20326
20152
|
onClick,
|
|
20327
20153
|
disabled
|
|
20328
20154
|
}) {
|
|
20329
|
-
return /* @__PURE__ */ (0,
|
|
20155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20330
20156
|
"button",
|
|
20331
20157
|
{
|
|
20332
20158
|
type: "button",
|
|
@@ -20342,7 +20168,7 @@ function Pill({
|
|
|
20342
20168
|
border: "none",
|
|
20343
20169
|
cursor: disabled ? "default" : "pointer",
|
|
20344
20170
|
background: "#ffffff",
|
|
20345
|
-
color:
|
|
20171
|
+
color: OHW_BLUE_DARK2,
|
|
20346
20172
|
opacity: disabled ? 0.4 : 1,
|
|
20347
20173
|
fontSize: 12,
|
|
20348
20174
|
lineHeight: "16px",
|
|
@@ -20364,7 +20190,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20364
20190
|
setDraft(value ? watchUrl(value) : "");
|
|
20365
20191
|
setInvalid(false);
|
|
20366
20192
|
}, [value]);
|
|
20367
|
-
const
|
|
20193
|
+
const commit = () => {
|
|
20368
20194
|
const next = draft.trim();
|
|
20369
20195
|
if (!next) {
|
|
20370
20196
|
setInvalid(false);
|
|
@@ -20385,8 +20211,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20385
20211
|
onCommit(id);
|
|
20386
20212
|
}
|
|
20387
20213
|
};
|
|
20388
|
-
return /* @__PURE__ */ (0,
|
|
20389
|
-
/* @__PURE__ */ (0,
|
|
20214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
20215
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
20390
20216
|
"div",
|
|
20391
20217
|
{
|
|
20392
20218
|
style: {
|
|
@@ -20402,12 +20228,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20402
20228
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
20403
20229
|
},
|
|
20404
20230
|
children: [
|
|
20405
|
-
/* @__PURE__ */ (0,
|
|
20231
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20406
20232
|
"span",
|
|
20407
20233
|
{
|
|
20408
20234
|
style: {
|
|
20409
20235
|
flex: "0 0 auto",
|
|
20410
|
-
color:
|
|
20236
|
+
color: OHW_BLUE_DARK2,
|
|
20411
20237
|
fontSize: 10,
|
|
20412
20238
|
lineHeight: "16px",
|
|
20413
20239
|
fontWeight: 700,
|
|
@@ -20417,14 +20243,14 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20417
20243
|
children: "Video"
|
|
20418
20244
|
}
|
|
20419
20245
|
),
|
|
20420
|
-
/* @__PURE__ */ (0,
|
|
20246
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20421
20247
|
"input",
|
|
20422
20248
|
{
|
|
20423
20249
|
type: "text",
|
|
20424
20250
|
inputMode: "url",
|
|
20425
20251
|
value: draft,
|
|
20426
20252
|
onChange: (e) => handleChange(e.target.value),
|
|
20427
|
-
onBlur:
|
|
20253
|
+
onBlur: commit,
|
|
20428
20254
|
onKeyDown: (e) => {
|
|
20429
20255
|
if (e.key === "Enter") e.currentTarget.blur();
|
|
20430
20256
|
if (e.key === "Escape") {
|
|
@@ -20454,7 +20280,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20454
20280
|
]
|
|
20455
20281
|
}
|
|
20456
20282
|
),
|
|
20457
|
-
invalid && /* @__PURE__ */ (0,
|
|
20283
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
20458
20284
|
] });
|
|
20459
20285
|
}
|
|
20460
20286
|
function VideoToolbar({
|
|
@@ -20464,7 +20290,7 @@ function VideoToolbar({
|
|
|
20464
20290
|
onSetVideoId,
|
|
20465
20291
|
onRemove
|
|
20466
20292
|
}) {
|
|
20467
|
-
return /* @__PURE__ */ (0,
|
|
20293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
20468
20294
|
"div",
|
|
20469
20295
|
{
|
|
20470
20296
|
"data-ohw-bridge": "",
|
|
@@ -20476,7 +20302,7 @@ function VideoToolbar({
|
|
|
20476
20302
|
gap: 6,
|
|
20477
20303
|
alignItems: "center",
|
|
20478
20304
|
width: 280,
|
|
20479
|
-
background:
|
|
20305
|
+
background: OHW_BLUE2,
|
|
20480
20306
|
padding: 8,
|
|
20481
20307
|
borderRadius: 12,
|
|
20482
20308
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20484,9 +20310,9 @@ function VideoToolbar({
|
|
|
20484
20310
|
opacity: pending ? 0.6 : 1
|
|
20485
20311
|
},
|
|
20486
20312
|
children: [
|
|
20487
|
-
/* @__PURE__ */ (0,
|
|
20488
|
-
/* @__PURE__ */ (0,
|
|
20489
|
-
error && /* @__PURE__ */ (0,
|
|
20313
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
20314
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
20315
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20490
20316
|
]
|
|
20491
20317
|
}
|
|
20492
20318
|
);
|
|
@@ -20606,8 +20432,8 @@ function AiVideoOverlay({
|
|
|
20606
20432
|
const activeBlockRect = useLiveBlockRect(active);
|
|
20607
20433
|
const TOOLBAR_APPROX_H = 90;
|
|
20608
20434
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20609
|
-
return /* @__PURE__ */ (0,
|
|
20610
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
20436
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20611
20437
|
"button",
|
|
20612
20438
|
{
|
|
20613
20439
|
type: "button",
|
|
@@ -20635,15 +20461,15 @@ function AiVideoOverlay({
|
|
|
20635
20461
|
fontSize: 14,
|
|
20636
20462
|
fontWeight: 700
|
|
20637
20463
|
},
|
|
20638
|
-
children: /* @__PURE__ */ (0,
|
|
20464
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20639
20465
|
}
|
|
20640
20466
|
),
|
|
20641
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20467
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20642
20468
|
ItemInteractionLayer,
|
|
20643
20469
|
{
|
|
20644
20470
|
rect: activeBlockRect,
|
|
20645
20471
|
state: toolbarState,
|
|
20646
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20472
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20647
20473
|
VideoToolbar,
|
|
20648
20474
|
{
|
|
20649
20475
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20667,7 +20493,7 @@ function AiVideoOverlay({
|
|
|
20667
20493
|
|
|
20668
20494
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20669
20495
|
var import_react13 = require("react");
|
|
20670
|
-
var
|
|
20496
|
+
var import_lucide_react11 = require("lucide-react");
|
|
20671
20497
|
|
|
20672
20498
|
// src/lib/ai-carousel-tree.ts
|
|
20673
20499
|
function isCarouselBlock(node) {
|
|
@@ -20718,10 +20544,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20718
20544
|
}
|
|
20719
20545
|
|
|
20720
20546
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20721
|
-
var
|
|
20547
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
20722
20548
|
var PRIMARY6 = "#0885FE";
|
|
20723
|
-
var
|
|
20724
|
-
var
|
|
20549
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
20550
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20725
20551
|
function findCarouselItemElement(sectionId, index) {
|
|
20726
20552
|
const sectionEl = findByInstanceId(sectionId);
|
|
20727
20553
|
if (!sectionEl) return null;
|
|
@@ -20800,8 +20626,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20800
20626
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20801
20627
|
});
|
|
20802
20628
|
}
|
|
20803
|
-
function
|
|
20804
|
-
return /* @__PURE__ */ (0,
|
|
20629
|
+
function Pill3({ label, onClick, disabled }) {
|
|
20630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20805
20631
|
"button",
|
|
20806
20632
|
{
|
|
20807
20633
|
type: "button",
|
|
@@ -20817,7 +20643,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20817
20643
|
border: "none",
|
|
20818
20644
|
cursor: disabled ? "default" : "pointer",
|
|
20819
20645
|
background: "#ffffff",
|
|
20820
|
-
color:
|
|
20646
|
+
color: OHW_BLUE_DARK3,
|
|
20821
20647
|
opacity: disabled ? 0.4 : 1,
|
|
20822
20648
|
fontSize: 12,
|
|
20823
20649
|
lineHeight: "16px",
|
|
@@ -20835,7 +20661,7 @@ function TogglePill({
|
|
|
20835
20661
|
onToggle,
|
|
20836
20662
|
disabled
|
|
20837
20663
|
}) {
|
|
20838
|
-
return /* @__PURE__ */ (0,
|
|
20664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20839
20665
|
"button",
|
|
20840
20666
|
{
|
|
20841
20667
|
type: "button",
|
|
@@ -20854,7 +20680,7 @@ function TogglePill({
|
|
|
20854
20680
|
border: "none",
|
|
20855
20681
|
cursor: disabled ? "default" : "pointer",
|
|
20856
20682
|
background: "#ffffff",
|
|
20857
|
-
color:
|
|
20683
|
+
color: OHW_BLUE_DARK3,
|
|
20858
20684
|
opacity: disabled ? 0.4 : 1,
|
|
20859
20685
|
fontSize: 12,
|
|
20860
20686
|
lineHeight: "16px",
|
|
@@ -20864,7 +20690,7 @@ function TogglePill({
|
|
|
20864
20690
|
},
|
|
20865
20691
|
children: [
|
|
20866
20692
|
label,
|
|
20867
|
-
/* @__PURE__ */ (0,
|
|
20693
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20868
20694
|
"span",
|
|
20869
20695
|
{
|
|
20870
20696
|
"aria-hidden": true,
|
|
@@ -20877,10 +20703,10 @@ function TogglePill({
|
|
|
20877
20703
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
20878
20704
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
20879
20705
|
// "disabled control" rather than "switch that is off".
|
|
20880
|
-
background: on ?
|
|
20706
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
20881
20707
|
transition: "background 120ms ease"
|
|
20882
20708
|
},
|
|
20883
|
-
children: /* @__PURE__ */ (0,
|
|
20709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20884
20710
|
"span",
|
|
20885
20711
|
{
|
|
20886
20712
|
style: {
|
|
@@ -20909,7 +20735,7 @@ function CarouselSlideToolbar({
|
|
|
20909
20735
|
onChangeImage,
|
|
20910
20736
|
onToggleAutoplay
|
|
20911
20737
|
}) {
|
|
20912
|
-
return /* @__PURE__ */ (0,
|
|
20738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20913
20739
|
"div",
|
|
20914
20740
|
{
|
|
20915
20741
|
"data-ohw-bridge": "",
|
|
@@ -20920,7 +20746,7 @@ function CarouselSlideToolbar({
|
|
|
20920
20746
|
flexDirection: "column",
|
|
20921
20747
|
gap: 6,
|
|
20922
20748
|
alignItems: "center",
|
|
20923
|
-
background:
|
|
20749
|
+
background: OHW_BLUE3,
|
|
20924
20750
|
padding: 8,
|
|
20925
20751
|
borderRadius: 12,
|
|
20926
20752
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20932,11 +20758,11 @@ function CarouselSlideToolbar({
|
|
|
20932
20758
|
pointerEvents: pending ? "none" : "auto"
|
|
20933
20759
|
},
|
|
20934
20760
|
children: [
|
|
20935
|
-
/* @__PURE__ */ (0,
|
|
20936
|
-
/* @__PURE__ */ (0,
|
|
20937
|
-
/* @__PURE__ */ (0,
|
|
20761
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20762
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20763
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20938
20764
|
] }),
|
|
20939
|
-
error && /* @__PURE__ */ (0,
|
|
20765
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20940
20766
|
]
|
|
20941
20767
|
}
|
|
20942
20768
|
);
|
|
@@ -21076,8 +20902,8 @@ function AiFadeCarouselOverlay({
|
|
|
21076
20902
|
const activeItemRect = useLiveItemRect2(active);
|
|
21077
20903
|
const TOOLBAR_APPROX_H = 90;
|
|
21078
20904
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
21079
|
-
return /* @__PURE__ */ (0,
|
|
21080
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20905
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
20906
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
21081
20907
|
"button",
|
|
21082
20908
|
{
|
|
21083
20909
|
type: "button",
|
|
@@ -21106,10 +20932,10 @@ function AiFadeCarouselOverlay({
|
|
|
21106
20932
|
fontSize: 14,
|
|
21107
20933
|
fontWeight: 700
|
|
21108
20934
|
},
|
|
21109
|
-
children: /* @__PURE__ */ (0,
|
|
20935
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
21110
20936
|
}
|
|
21111
20937
|
),
|
|
21112
|
-
swapping && /* @__PURE__ */ (0,
|
|
20938
|
+
swapping && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
21113
20939
|
"div",
|
|
21114
20940
|
{
|
|
21115
20941
|
ref: skeletonRef,
|
|
@@ -21127,15 +20953,15 @@ function AiFadeCarouselOverlay({
|
|
|
21127
20953
|
zIndex: 2147483646,
|
|
21128
20954
|
pointerEvents: "none"
|
|
21129
20955
|
},
|
|
21130
|
-
children: /* @__PURE__ */ (0,
|
|
20956
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
21131
20957
|
}
|
|
21132
20958
|
),
|
|
21133
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20959
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
21134
20960
|
ItemInteractionLayer,
|
|
21135
20961
|
{
|
|
21136
20962
|
rect: activeItemRect,
|
|
21137
20963
|
state: toolbarState,
|
|
21138
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20964
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
21139
20965
|
CarouselSlideToolbar,
|
|
21140
20966
|
{
|
|
21141
20967
|
pending,
|
|
@@ -21353,6 +21179,113 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
21353
21179
|
// src/ui/link-modal/LinkPopover.tsx
|
|
21354
21180
|
var import_react17 = require("react");
|
|
21355
21181
|
|
|
21182
|
+
// src/ui/dialog.tsx
|
|
21183
|
+
var React9 = __toESM(require("react"), 1);
|
|
21184
|
+
var import_radix_ui6 = require("radix-ui");
|
|
21185
|
+
var import_lucide_react12 = require("lucide-react");
|
|
21186
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
21187
|
+
function Dialog2({
|
|
21188
|
+
...props
|
|
21189
|
+
}) {
|
|
21190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
21191
|
+
}
|
|
21192
|
+
function DialogPortal({
|
|
21193
|
+
...props
|
|
21194
|
+
}) {
|
|
21195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
21196
|
+
}
|
|
21197
|
+
function DialogOverlay({
|
|
21198
|
+
className,
|
|
21199
|
+
...props
|
|
21200
|
+
}) {
|
|
21201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21202
|
+
import_radix_ui6.Dialog.Overlay,
|
|
21203
|
+
{
|
|
21204
|
+
"data-slot": "dialog-overlay",
|
|
21205
|
+
"data-ohw-link-modal-root": "",
|
|
21206
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
21207
|
+
...props
|
|
21208
|
+
}
|
|
21209
|
+
);
|
|
21210
|
+
}
|
|
21211
|
+
var DialogContent = React9.forwardRef(
|
|
21212
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
21213
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
21214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
21215
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
21216
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
21217
|
+
import_radix_ui6.Dialog.Content,
|
|
21218
|
+
{
|
|
21219
|
+
ref,
|
|
21220
|
+
"data-slot": "dialog-content",
|
|
21221
|
+
className: cn(
|
|
21222
|
+
positionMode,
|
|
21223
|
+
"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",
|
|
21224
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
21225
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
21226
|
+
className
|
|
21227
|
+
),
|
|
21228
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
21229
|
+
...props,
|
|
21230
|
+
children: [
|
|
21231
|
+
children,
|
|
21232
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21233
|
+
import_radix_ui6.Dialog.Close,
|
|
21234
|
+
{
|
|
21235
|
+
type: "button",
|
|
21236
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
21237
|
+
"aria-label": "Close",
|
|
21238
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
21239
|
+
}
|
|
21240
|
+
) : null
|
|
21241
|
+
]
|
|
21242
|
+
}
|
|
21243
|
+
)
|
|
21244
|
+
] });
|
|
21245
|
+
}
|
|
21246
|
+
);
|
|
21247
|
+
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
21248
|
+
function DialogHeader({
|
|
21249
|
+
className,
|
|
21250
|
+
...props
|
|
21251
|
+
}) {
|
|
21252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
21253
|
+
}
|
|
21254
|
+
function DialogFooter({
|
|
21255
|
+
className,
|
|
21256
|
+
...props
|
|
21257
|
+
}) {
|
|
21258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21259
|
+
"div",
|
|
21260
|
+
{
|
|
21261
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
21262
|
+
...props
|
|
21263
|
+
}
|
|
21264
|
+
);
|
|
21265
|
+
}
|
|
21266
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21267
|
+
import_radix_ui6.Dialog.Title,
|
|
21268
|
+
{
|
|
21269
|
+
ref,
|
|
21270
|
+
className: cn(
|
|
21271
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
21272
|
+
className
|
|
21273
|
+
),
|
|
21274
|
+
...props
|
|
21275
|
+
}
|
|
21276
|
+
));
|
|
21277
|
+
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
21278
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21279
|
+
import_radix_ui6.Dialog.Description,
|
|
21280
|
+
{
|
|
21281
|
+
ref,
|
|
21282
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
21283
|
+
...props
|
|
21284
|
+
}
|
|
21285
|
+
));
|
|
21286
|
+
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
21287
|
+
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
21288
|
+
|
|
21356
21289
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
21357
21290
|
var import_lucide_react16 = require("lucide-react");
|
|
21358
21291
|
|
|
@@ -22456,7 +22389,6 @@ function shouldUseDevFixtures() {
|
|
|
22456
22389
|
function getLogoElement(el) {
|
|
22457
22390
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
22458
22391
|
if (marked) return marked;
|
|
22459
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
22460
22392
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
22461
22393
|
if (!root) return null;
|
|
22462
22394
|
const anchor = el.closest("a");
|
|
@@ -24151,102 +24083,6 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
24151
24083
|
return false;
|
|
24152
24084
|
}
|
|
24153
24085
|
|
|
24154
|
-
// src/lib/nav-page-sync.ts
|
|
24155
|
-
function labelKeyFor(hrefKey) {
|
|
24156
|
-
return hrefKey.replace(/-href$/, "-label");
|
|
24157
|
-
}
|
|
24158
|
-
function isPageLinkKey(key) {
|
|
24159
|
-
return isNavbarHrefKey(key) || isFooterHrefKey(key);
|
|
24160
|
-
}
|
|
24161
|
-
function currentHref(key, anchor, content) {
|
|
24162
|
-
const stored = content[key];
|
|
24163
|
-
if (typeof stored === "string" && stored.length > 0) return stored;
|
|
24164
|
-
return anchor.getAttribute("href") ?? "";
|
|
24165
|
-
}
|
|
24166
|
-
function normalizePath2(value) {
|
|
24167
|
-
if (value.length > 1 && value.endsWith("/")) return value.slice(0, -1);
|
|
24168
|
-
return value;
|
|
24169
|
-
}
|
|
24170
|
-
function pointsAt(href, path) {
|
|
24171
|
-
const normalized = normalizePath2(href);
|
|
24172
|
-
const target = normalizePath2(path);
|
|
24173
|
-
if (normalized === target) return true;
|
|
24174
|
-
return (normalized.startsWith(`${target}#`) || normalized.startsWith(`${target}?`)) && target !== "/";
|
|
24175
|
-
}
|
|
24176
|
-
function retargetHref(href, oldPath, newPath) {
|
|
24177
|
-
const normalized = normalizePath2(href);
|
|
24178
|
-
const target = normalizePath2(oldPath);
|
|
24179
|
-
if (normalized === target) return newPath;
|
|
24180
|
-
return `${newPath}${normalized.slice(target.length)}`;
|
|
24181
|
-
}
|
|
24182
|
-
function setLabelText(key, text) {
|
|
24183
|
-
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
24184
|
-
el.textContent = text;
|
|
24185
|
-
});
|
|
24186
|
-
}
|
|
24187
|
-
function commit(delta, deps) {
|
|
24188
|
-
if (Object.keys(delta).length === 0) return;
|
|
24189
|
-
deps.setEditContent({ ...deps.getEditContent(), ...delta });
|
|
24190
|
-
deps.postToParent({
|
|
24191
|
-
type: "ow:change",
|
|
24192
|
-
nodes: Object.entries(delta).map(([key, text]) => ({ key, text }))
|
|
24193
|
-
});
|
|
24194
|
-
}
|
|
24195
|
-
function navLinksTo(path, content) {
|
|
24196
|
-
return Array.from(document.querySelectorAll("[data-ohw-href-key]")).filter((anchor) => {
|
|
24197
|
-
const key = anchor.getAttribute("data-ohw-href-key");
|
|
24198
|
-
return isNavbarHrefKey(key) && pointsAt(currentHref(key, anchor, content), path);
|
|
24199
|
-
}).map((anchor) => anchor.getAttribute("data-ohw-href-key"));
|
|
24200
|
-
}
|
|
24201
|
-
function addNavLinkForPage(page, deps) {
|
|
24202
|
-
const content = deps.getEditContent();
|
|
24203
|
-
if (navLinksTo(page.path, content).length > 0) return false;
|
|
24204
|
-
const roots = listNavbarRootItems();
|
|
24205
|
-
const afterAnchor = roots[roots.length - 1] ?? null;
|
|
24206
|
-
let inserted;
|
|
24207
|
-
try {
|
|
24208
|
-
inserted = insertNavbarItem(page.path, page.title, afterAnchor);
|
|
24209
|
-
} catch {
|
|
24210
|
-
return false;
|
|
24211
|
-
}
|
|
24212
|
-
const { hrefKey, labelKey, index } = inserted;
|
|
24213
|
-
deps.applyLinkByKey(hrefKey, page.path);
|
|
24214
|
-
setLabelText(labelKey, page.title);
|
|
24215
|
-
commit(
|
|
24216
|
-
{
|
|
24217
|
-
[hrefKey]: page.path,
|
|
24218
|
-
[labelKey]: page.title,
|
|
24219
|
-
[NAV_COUNT_KEY]: String(index + 1),
|
|
24220
|
-
[NAV_ORDER_KEY]: getNavbarOrderJson()
|
|
24221
|
-
},
|
|
24222
|
-
deps
|
|
24223
|
-
);
|
|
24224
|
-
return true;
|
|
24225
|
-
}
|
|
24226
|
-
function retargetPageLinks(change, deps) {
|
|
24227
|
-
const { oldPath, newPath, oldTitle, newTitle } = change;
|
|
24228
|
-
if (!oldPath || !newPath || normalizePath2(oldPath) === normalizePath2(newPath)) return 0;
|
|
24229
|
-
const content = deps.getEditContent();
|
|
24230
|
-
const delta = {};
|
|
24231
|
-
for (const anchor of Array.from(document.querySelectorAll("[data-ohw-href-key]"))) {
|
|
24232
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
24233
|
-
if (!isPageLinkKey(hrefKey)) continue;
|
|
24234
|
-
const href = currentHref(hrefKey, anchor, content);
|
|
24235
|
-
if (!pointsAt(href, oldPath)) continue;
|
|
24236
|
-
const nextHref = retargetHref(href, oldPath, newPath);
|
|
24237
|
-
deps.applyLinkByKey(hrefKey, nextHref);
|
|
24238
|
-
delta[hrefKey] = nextHref;
|
|
24239
|
-
if (!oldTitle || !newTitle) continue;
|
|
24240
|
-
const labelKey = labelKeyFor(hrefKey);
|
|
24241
|
-
const label = content[labelKey] ?? anchor.querySelector('[data-ohw-editable="text"]')?.textContent ?? "";
|
|
24242
|
-
if (label.trim() !== oldTitle) continue;
|
|
24243
|
-
setLabelText(labelKey, newTitle);
|
|
24244
|
-
delta[labelKey] = newTitle;
|
|
24245
|
-
}
|
|
24246
|
-
commit(delta, deps);
|
|
24247
|
-
return Object.keys(delta).filter((key) => key.endsWith("-href")).length;
|
|
24248
|
-
}
|
|
24249
|
-
|
|
24250
24086
|
// src/ui/navbar-container-chrome.tsx
|
|
24251
24087
|
var import_lucide_react21 = require("lucide-react");
|
|
24252
24088
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
@@ -25134,7 +24970,7 @@ function getNavigationSelectionParent(el) {
|
|
|
25134
24970
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
25135
24971
|
return resolveFooterLinksContainerFrom(el);
|
|
25136
24972
|
}
|
|
25137
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24973
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
25138
24974
|
return getNavigationRoot(el);
|
|
25139
24975
|
}
|
|
25140
24976
|
return null;
|
|
@@ -25356,6 +25192,7 @@ var ICONS = {
|
|
|
25356
25192
|
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"/>',
|
|
25357
25193
|
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"/>'
|
|
25358
25194
|
};
|
|
25195
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
25359
25196
|
var SELECTION_CHROME_GAP2 = 4;
|
|
25360
25197
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
25361
25198
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -25453,7 +25290,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
25453
25290
|
el.style.top = `${top}px`;
|
|
25454
25291
|
el.style.height = `${height}px`;
|
|
25455
25292
|
}
|
|
25456
|
-
var
|
|
25293
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
25457
25294
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
25458
25295
|
const isAbove = transform.includes("translateY(-100%)");
|
|
25459
25296
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -25480,8 +25317,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
25480
25317
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
25481
25318
|
const half = toolbarWidth / 2;
|
|
25482
25319
|
return Math.max(
|
|
25483
|
-
|
|
25484
|
-
Math.min(centerX, window.innerWidth -
|
|
25320
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
25321
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
25485
25322
|
);
|
|
25486
25323
|
}
|
|
25487
25324
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -26361,6 +26198,21 @@ function OhhwellsBridge() {
|
|
|
26361
26198
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
26362
26199
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
26363
26200
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
26201
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
26202
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
26203
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
26204
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
26205
|
+
floatingPanelRef.current = floatingPanel;
|
|
26206
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
26207
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
26208
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
26209
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
26210
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
26211
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
26212
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
26213
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
26214
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
26215
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
26364
26216
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
26365
26217
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
26366
26218
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -26386,21 +26238,6 @@ function OhhwellsBridge() {
|
|
|
26386
26238
|
const stylesRef = (0, import_react21.useRef)("");
|
|
26387
26239
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
26388
26240
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
26389
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
26390
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
26391
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
26392
|
-
floatingPanelRef.current = floatingPanel;
|
|
26393
|
-
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
26394
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
26395
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
26396
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
26397
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
26398
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
26399
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
26400
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
26401
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
26402
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
26403
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
26404
26241
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
26405
26242
|
const collectionItemsRef = (0, import_react21.useRef)(/* @__PURE__ */ new Map());
|
|
26406
26243
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
@@ -26410,18 +26247,7 @@ function OhhwellsBridge() {
|
|
|
26410
26247
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
26411
26248
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
26412
26249
|
setLinkPopoverRef.current = setLinkPopover;
|
|
26413
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
26414
26250
|
linkPopoverSessionRef.current = linkPopover;
|
|
26415
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
26416
|
-
(0, import_react21.useEffect)(() => {
|
|
26417
|
-
const syncViewport = () => {
|
|
26418
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
26419
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
26420
|
-
};
|
|
26421
|
-
syncViewport();
|
|
26422
|
-
window.addEventListener("resize", syncViewport);
|
|
26423
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
26424
|
-
}, []);
|
|
26425
26251
|
(0, import_react21.useEffect)(() => {
|
|
26426
26252
|
setSectionOrderPersistHandler((entries) => {
|
|
26427
26253
|
const currentPath = window.location.pathname;
|
|
@@ -26570,43 +26396,6 @@ function OhhwellsBridge() {
|
|
|
26570
26396
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
26571
26397
|
return () => window.removeEventListener("message", onSitePages);
|
|
26572
26398
|
}, [isEditMode, postToParent2]);
|
|
26573
|
-
(0, import_react21.useEffect)(() => {
|
|
26574
|
-
if (!isEditMode) return;
|
|
26575
|
-
const deps = {
|
|
26576
|
-
getEditContent: () => editContentRef.current,
|
|
26577
|
-
setEditContent: (next) => {
|
|
26578
|
-
editContentRef.current = next;
|
|
26579
|
-
},
|
|
26580
|
-
applyLinkByKey,
|
|
26581
|
-
postToParent: postToParent2
|
|
26582
|
-
};
|
|
26583
|
-
const onPageMessage = (e) => {
|
|
26584
|
-
if (e.data?.type === "ow:page-created") {
|
|
26585
|
-
const { path, title } = e.data;
|
|
26586
|
-
if (typeof path !== "string" || !path) return;
|
|
26587
|
-
if (addNavLinkForPage({ path, title: typeof title === "string" && title ? title : path }, deps)) {
|
|
26588
|
-
enforceLinkHrefs();
|
|
26589
|
-
}
|
|
26590
|
-
return;
|
|
26591
|
-
}
|
|
26592
|
-
if (e.data?.type === "ow:page-renamed") {
|
|
26593
|
-
const { oldPath, newPath, oldTitle, newTitle } = e.data;
|
|
26594
|
-
if (typeof oldPath !== "string" || typeof newPath !== "string") return;
|
|
26595
|
-
const moved = retargetPageLinks(
|
|
26596
|
-
{
|
|
26597
|
-
oldPath,
|
|
26598
|
-
newPath,
|
|
26599
|
-
oldTitle: typeof oldTitle === "string" ? oldTitle : void 0,
|
|
26600
|
-
newTitle: typeof newTitle === "string" ? newTitle : void 0
|
|
26601
|
-
},
|
|
26602
|
-
deps
|
|
26603
|
-
);
|
|
26604
|
-
if (moved > 0) enforceLinkHrefs();
|
|
26605
|
-
}
|
|
26606
|
-
};
|
|
26607
|
-
window.addEventListener("message", onPageMessage);
|
|
26608
|
-
return () => window.removeEventListener("message", onPageMessage);
|
|
26609
|
-
}, [isEditMode, postToParent2]);
|
|
26610
26399
|
(0, import_react21.useEffect)(() => {
|
|
26611
26400
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
26612
26401
|
void loadAllSectionsManifest().then((manifest) => {
|
|
@@ -28155,7 +27944,6 @@ function OhhwellsBridge() {
|
|
|
28155
27944
|
applyAiFooterFromContent(content);
|
|
28156
27945
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28157
27946
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
28158
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28159
27947
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28160
27948
|
}
|
|
28161
27949
|
applyBrandChrome(content);
|
|
@@ -28166,12 +27954,12 @@ function OhhwellsBridge() {
|
|
|
28166
27954
|
if (key === "__ohw_sections") continue;
|
|
28167
27955
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28168
27956
|
if (key === AI_FOOTER_KEY) continue;
|
|
28169
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28170
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28171
27957
|
if (key === BRAND_KIT_KEY) continue;
|
|
28172
27958
|
if (key === STYLE_STORE_KEY) continue;
|
|
28173
27959
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27960
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28174
27961
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27962
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28175
27963
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28176
27964
|
continue;
|
|
28177
27965
|
}
|
|
@@ -28402,18 +28190,17 @@ function OhhwellsBridge() {
|
|
|
28402
28190
|
}
|
|
28403
28191
|
applyAiFooterFromContent(content);
|
|
28404
28192
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28405
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28406
28193
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28407
28194
|
}
|
|
28408
28195
|
for (const [key, val] of Object.entries(content)) {
|
|
28409
28196
|
if (key === "__ohw_sections") continue;
|
|
28410
28197
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28411
28198
|
if (key === AI_FOOTER_KEY) continue;
|
|
28412
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28413
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28414
28199
|
if (key === BRAND_KIT_KEY) continue;
|
|
28415
28200
|
if (key === STYLE_STORE_KEY) continue;
|
|
28416
28201
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
28202
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28203
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28417
28204
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28418
28205
|
continue;
|
|
28419
28206
|
}
|
|
@@ -28680,11 +28467,26 @@ function OhhwellsBridge() {
|
|
|
28680
28467
|
const t2 = setTimeout(measure, 500);
|
|
28681
28468
|
const ro = new ResizeObserver(schedule);
|
|
28682
28469
|
ro.observe(document.body);
|
|
28470
|
+
let lastWidth = window.innerWidth;
|
|
28471
|
+
let resizeTimers = [];
|
|
28472
|
+
const clearResizeTimers = () => {
|
|
28473
|
+
resizeTimers.forEach(clearTimeout);
|
|
28474
|
+
resizeTimers = [];
|
|
28475
|
+
};
|
|
28476
|
+
const handleResize = () => {
|
|
28477
|
+
if (window.innerWidth === lastWidth) return;
|
|
28478
|
+
lastWidth = window.innerWidth;
|
|
28479
|
+
clearResizeTimers();
|
|
28480
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
28481
|
+
};
|
|
28482
|
+
window.addEventListener("resize", handleResize);
|
|
28683
28483
|
return () => {
|
|
28684
28484
|
clearTimeout(t1);
|
|
28685
28485
|
clearTimeout(t2);
|
|
28686
28486
|
if (raf != null) cancelAnimationFrame(raf);
|
|
28687
28487
|
ro.disconnect();
|
|
28488
|
+
clearResizeTimers();
|
|
28489
|
+
window.removeEventListener("resize", handleResize);
|
|
28688
28490
|
};
|
|
28689
28491
|
}, [pathname, isEditMode, postToParent2]);
|
|
28690
28492
|
(0, import_react21.useEffect)(() => {
|
|
@@ -28981,13 +28783,6 @@ function OhhwellsBridge() {
|
|
|
28981
28783
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28982
28784
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28983
28785
|
if (isInsideLinkEditor(target)) return;
|
|
28984
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28985
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28986
|
-
if (target.closest(
|
|
28987
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28988
|
-
)) {
|
|
28989
|
-
return;
|
|
28990
|
-
}
|
|
28991
28786
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28992
28787
|
clearMediaSelectionRef.current();
|
|
28993
28788
|
}
|
|
@@ -29011,6 +28806,8 @@ function OhhwellsBridge() {
|
|
|
29011
28806
|
return;
|
|
29012
28807
|
}
|
|
29013
28808
|
}
|
|
28809
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28810
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
29014
28811
|
const collectionItem = matchCollectionItemClick(target, collectionItemsRef.current);
|
|
29015
28812
|
if (collectionItem) {
|
|
29016
28813
|
e.preventDefault();
|
|
@@ -29022,6 +28819,11 @@ function OhhwellsBridge() {
|
|
|
29022
28819
|
});
|
|
29023
28820
|
return;
|
|
29024
28821
|
}
|
|
28822
|
+
if (target.closest(
|
|
28823
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28824
|
+
)) {
|
|
28825
|
+
return;
|
|
28826
|
+
}
|
|
29025
28827
|
{
|
|
29026
28828
|
const formEl = getFormElement(target);
|
|
29027
28829
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -29175,13 +28977,9 @@ function OhhwellsBridge() {
|
|
|
29175
28977
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
29176
28978
|
e.preventDefault();
|
|
29177
28979
|
e.stopPropagation();
|
|
28980
|
+
selectIconElementRef.current(editable);
|
|
29178
28981
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
29179
28982
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
29180
|
-
if (aiIcon) {
|
|
29181
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
29182
|
-
} else {
|
|
29183
|
-
selectIconElementRef.current(editable);
|
|
29184
|
-
}
|
|
29185
28983
|
postToParentRef.current({
|
|
29186
28984
|
type: "ow:icon-pick",
|
|
29187
28985
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -29409,9 +29207,6 @@ function OhhwellsBridge() {
|
|
|
29409
29207
|
setHoveredItemRect(null);
|
|
29410
29208
|
hoveredNavContainerRef.current = null;
|
|
29411
29209
|
setHoveredNavContainerRect(null);
|
|
29412
|
-
siblingHintElRef.current = null;
|
|
29413
|
-
setSiblingHintRect(null);
|
|
29414
|
-
setSiblingHintRects([]);
|
|
29415
29210
|
return;
|
|
29416
29211
|
}
|
|
29417
29212
|
{
|
|
@@ -29532,6 +29327,7 @@ function OhhwellsBridge() {
|
|
|
29532
29327
|
hoveredNavContainerRef.current = null;
|
|
29533
29328
|
setHoveredNavContainerRect(null);
|
|
29534
29329
|
hoveredItemElRef.current = editable;
|
|
29330
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
29535
29331
|
}
|
|
29536
29332
|
}
|
|
29537
29333
|
}
|
|
@@ -30241,11 +30037,7 @@ function OhhwellsBridge() {
|
|
|
30241
30037
|
};
|
|
30242
30038
|
const handleMouseMove = (e) => {
|
|
30243
30039
|
const { clientX, clientY } = e;
|
|
30244
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
30245
|
-
dismissImageHover();
|
|
30246
|
-
clearImageHover();
|
|
30247
|
-
return;
|
|
30248
|
-
}
|
|
30040
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
30249
30041
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
30250
30042
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
30251
30043
|
formHoverElRef.current = null;
|
|
@@ -30274,12 +30066,7 @@ function OhhwellsBridge() {
|
|
|
30274
30066
|
setHoveredItemRect(null);
|
|
30275
30067
|
hoveredNavContainerRef.current = null;
|
|
30276
30068
|
setHoveredNavContainerRect(null);
|
|
30277
|
-
siblingHintElRef.current = null;
|
|
30278
|
-
setSiblingHintRect(null);
|
|
30279
|
-
setSiblingHintRects([]);
|
|
30280
30069
|
dismissImageHover();
|
|
30281
|
-
clearImageHover();
|
|
30282
|
-
setSectionGap(null);
|
|
30283
30070
|
return;
|
|
30284
30071
|
}
|
|
30285
30072
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -30291,11 +30078,7 @@ function OhhwellsBridge() {
|
|
|
30291
30078
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
30292
30079
|
const { clientX, clientY } = e.data;
|
|
30293
30080
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
30294
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
30295
|
-
dismissImageHover();
|
|
30296
|
-
clearImageHover();
|
|
30297
|
-
return;
|
|
30298
|
-
}
|
|
30081
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
30299
30082
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
30300
30083
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
30301
30084
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -30675,7 +30458,6 @@ function OhhwellsBridge() {
|
|
|
30675
30458
|
applyAiFooterFromContent(content);
|
|
30676
30459
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
30677
30460
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
30678
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
30679
30461
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
30680
30462
|
}
|
|
30681
30463
|
applyBrandChrome(content);
|
|
@@ -30690,12 +30472,12 @@ function OhhwellsBridge() {
|
|
|
30690
30472
|
}
|
|
30691
30473
|
if (key === AI_SECTIONS_KEY) continue;
|
|
30692
30474
|
if (key === AI_FOOTER_KEY) continue;
|
|
30693
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30694
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30695
30475
|
if (key === BRAND_KIT_KEY) continue;
|
|
30696
30476
|
if (key === STYLE_STORE_KEY) continue;
|
|
30697
30477
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
30478
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30698
30479
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
30480
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30699
30481
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
30700
30482
|
continue;
|
|
30701
30483
|
}
|
|
@@ -31331,12 +31113,6 @@ function OhhwellsBridge() {
|
|
|
31331
31113
|
closeLinkPopoverRef.current();
|
|
31332
31114
|
return;
|
|
31333
31115
|
}
|
|
31334
|
-
if (floatingPanelOpenRef.current) {
|
|
31335
|
-
setFloatingPanelRef.current(null);
|
|
31336
|
-
deselectRef.current();
|
|
31337
|
-
deactivateRef.current();
|
|
31338
|
-
return;
|
|
31339
|
-
}
|
|
31340
31116
|
deselectRef.current();
|
|
31341
31117
|
deactivateRef.current();
|
|
31342
31118
|
clearMediaSelectionRef.current();
|
|
@@ -32172,10 +31948,10 @@ function OhhwellsBridge() {
|
|
|
32172
31948
|
window.removeEventListener("message", handleDuplicateSection);
|
|
32173
31949
|
window.removeEventListener("message", handleDeactivate);
|
|
32174
31950
|
window.removeEventListener("message", handleSelectNav);
|
|
31951
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
32175
31952
|
window.removeEventListener("message", handleToastAction);
|
|
32176
31953
|
window.removeEventListener("message", handleFormCount);
|
|
32177
31954
|
window.removeEventListener("message", handleUiEscape);
|
|
32178
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
32179
31955
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
32180
31956
|
autoSaveTimers.current.clear();
|
|
32181
31957
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -32469,7 +32245,7 @@ function OhhwellsBridge() {
|
|
|
32469
32245
|
postToParent2({
|
|
32470
32246
|
type: "ow:ready",
|
|
32471
32247
|
version: "1",
|
|
32472
|
-
bridgeVersion: "0.1.
|
|
32248
|
+
bridgeVersion: "0.1.159",
|
|
32473
32249
|
path: pathname,
|
|
32474
32250
|
nodes: collectEditableNodes(editContentRef.current),
|
|
32475
32251
|
sections
|