@ohhwells/bridge 0.1.158-next.422 → 0.1.158
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
|
@@ -6682,21 +6682,6 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6682
6682
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6683
6683
|
return target ? pricingFeatureList(target).length : 0;
|
|
6684
6684
|
}
|
|
6685
|
-
function prevailingFeatureIcon(features) {
|
|
6686
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6687
|
-
for (const row of features) {
|
|
6688
|
-
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6689
|
-
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6690
|
-
entry.count += 1;
|
|
6691
|
-
counts.set(key, entry);
|
|
6692
|
-
}
|
|
6693
|
-
let best = null;
|
|
6694
|
-
for (const entry of counts.values()) {
|
|
6695
|
-
if (!best || entry.count > best.count) best = entry;
|
|
6696
|
-
}
|
|
6697
|
-
if (!best) return {};
|
|
6698
|
-
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6699
|
-
}
|
|
6700
6685
|
function addPricingCardFeature(tree, index, text) {
|
|
6701
6686
|
return withPricingCollection(tree, (collection) => {
|
|
6702
6687
|
const children = collection.children;
|
|
@@ -6705,7 +6690,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6705
6690
|
const features = pricingFeatureList(target);
|
|
6706
6691
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6707
6692
|
target.slots = target.slots ?? {};
|
|
6708
|
-
target.slots.features = [...features, { text
|
|
6693
|
+
target.slots.features = [...features, { text }];
|
|
6709
6694
|
return true;
|
|
6710
6695
|
});
|
|
6711
6696
|
}
|
|
@@ -7905,7 +7890,7 @@ var AI_MOBILE_CSS = [
|
|
|
7905
7890
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7906
7891
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7907
7892
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7908
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7893
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
7909
7894
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7910
7895
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7911
7896
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7921,10 +7906,8 @@ var AI_MOBILE_CSS = [
|
|
|
7921
7906
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7922
7907
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7923
7908
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7924
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7925
|
-
|
|
7926
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7927
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7909
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7910
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7928
7911
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7929
7912
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7930
7913
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -8129,31 +8112,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
8129
8112
|
function textAttrs(ctx, path) {
|
|
8130
8113
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
8131
8114
|
}
|
|
8132
|
-
var AI_RESPONSIVE_CSS = [
|
|
8133
|
-
"@media (max-width: 960px) {",
|
|
8134
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
8135
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
8136
|
-
"}",
|
|
8137
|
-
"@media (max-width: 640px) {",
|
|
8138
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
8139
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
8140
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
8141
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
8142
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
8143
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
8144
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
8145
|
-
// layered text used to be.
|
|
8146
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
8147
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
8148
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
8149
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
8150
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
8151
|
-
// other rule had already been taught to stand down.
|
|
8152
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
8153
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
8154
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
8155
|
-
"}"
|
|
8156
|
-
].join("\n");
|
|
8157
8115
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8158
8116
|
function MediaBox({
|
|
8159
8117
|
refValue,
|
|
@@ -8208,7 +8166,7 @@ function MediaBox({
|
|
|
8208
8166
|
position: fill ? "absolute" : void 0,
|
|
8209
8167
|
inset: fill ? 0 : void 0,
|
|
8210
8168
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8211
|
-
height: fill ? "100%" :
|
|
8169
|
+
height: fill ? "100%" : void 0,
|
|
8212
8170
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8213
8171
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8214
8172
|
borderRadius: radius,
|
|
@@ -9704,7 +9662,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9704
9662
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9705
9663
|
"div",
|
|
9706
9664
|
{
|
|
9707
|
-
"data-ai-grid":
|
|
9665
|
+
"data-ai-grid": "",
|
|
9708
9666
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9709
9667
|
style: {
|
|
9710
9668
|
display: "grid",
|
|
@@ -10006,7 +9964,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
10006
9964
|
},
|
|
10007
9965
|
children: [
|
|
10008
9966
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
10009
|
-
// The section's `data-ai-
|
|
9967
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
10010
9968
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
10011
9969
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
10012
9970
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10425,7 +10383,6 @@ function AiTreeRenderer({
|
|
|
10425
10383
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10426
10384
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10427
10385
|
...bgAttrs,
|
|
10428
|
-
"data-ai-responsive": "",
|
|
10429
10386
|
style: {
|
|
10430
10387
|
position: "relative",
|
|
10431
10388
|
padding: `${padCss} 0`,
|
|
@@ -10439,13 +10396,12 @@ function AiTreeRenderer({
|
|
|
10439
10396
|
...fillHeight ? { display: "grid" } : {}
|
|
10440
10397
|
},
|
|
10441
10398
|
children: [
|
|
10442
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
10443
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10444
10399
|
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10400
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
10445
10401
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10446
10402
|
"div",
|
|
10447
10403
|
{
|
|
10448
|
-
"data-ai-
|
|
10404
|
+
"data-ai-container": "",
|
|
10449
10405
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10450
10406
|
style: {
|
|
10451
10407
|
position: "relative",
|
|
@@ -10462,7 +10418,7 @@ function AiTreeRenderer({
|
|
|
10462
10418
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10463
10419
|
"div",
|
|
10464
10420
|
{
|
|
10465
|
-
"data-ai-
|
|
10421
|
+
"data-ai-row": "",
|
|
10466
10422
|
style: {
|
|
10467
10423
|
display: "grid",
|
|
10468
10424
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -11124,10 +11080,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
11124
11080
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
11125
11081
|
continue;
|
|
11126
11082
|
}
|
|
11083
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
11127
11084
|
let container = existing?.container;
|
|
11128
|
-
let isNewMount = false;
|
|
11129
11085
|
if (!container || !container.isConnected) {
|
|
11130
|
-
isNewMount = true;
|
|
11131
11086
|
existing?.root.unmount();
|
|
11132
11087
|
container?.remove();
|
|
11133
11088
|
container = document.createElement("div");
|
|
@@ -17286,7 +17241,7 @@ function apiBase() {
|
|
|
17286
17241
|
function bridgeVersion() {
|
|
17287
17242
|
try {
|
|
17288
17243
|
if (true) {
|
|
17289
|
-
return "0.1.158
|
|
17244
|
+
return "0.1.158";
|
|
17290
17245
|
}
|
|
17291
17246
|
} catch {
|
|
17292
17247
|
}
|
|
@@ -17300,7 +17255,7 @@ function stampBridgeVersionOnDocument() {
|
|
|
17300
17255
|
return;
|
|
17301
17256
|
}
|
|
17302
17257
|
try {
|
|
17303
|
-
const v = true ? "0.1.158
|
|
17258
|
+
const v = true ? "0.1.158" : "";
|
|
17304
17259
|
if (v) {
|
|
17305
17260
|
document.documentElement.setAttribute("data-ohw-bridge-version", v);
|
|
17306
17261
|
window.__OHW_BRIDGE_VERSION__ = v;
|
|
@@ -17978,7 +17933,6 @@ function MediaOverlay({
|
|
|
17978
17933
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
17979
17934
|
);
|
|
17980
17935
|
}, [isVideo]);
|
|
17981
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
17982
17936
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
17983
17937
|
const box = {
|
|
17984
17938
|
position: "fixed",
|
|
@@ -18077,10 +18031,11 @@ function MediaOverlay({
|
|
|
18077
18031
|
className: "flex items-center justify-center cursor-pointer",
|
|
18078
18032
|
style: {
|
|
18079
18033
|
...box,
|
|
18080
|
-
//
|
|
18081
|
-
//
|
|
18082
|
-
//
|
|
18083
|
-
|
|
18034
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
18035
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
18036
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
18037
|
+
// Replace still works.
|
|
18038
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
18084
18039
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
18085
18040
|
// than hovered. Hover keeps the existing tinted preview.
|
|
18086
18041
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -18107,17 +18062,17 @@ function MediaOverlay({
|
|
|
18107
18062
|
},
|
|
18108
18063
|
children: [
|
|
18109
18064
|
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 }),
|
|
18110
|
-
|
|
18065
|
+
isVideo ? "Replace video" : "Replace image"
|
|
18111
18066
|
]
|
|
18112
18067
|
}
|
|
18113
18068
|
),
|
|
18114
|
-
|
|
18069
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
18115
18070
|
Button,
|
|
18116
18071
|
{
|
|
18117
18072
|
"data-ohw-media-overlay": "",
|
|
18118
18073
|
variant: "outline",
|
|
18119
18074
|
size: "sm",
|
|
18120
|
-
"aria-label":
|
|
18075
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
18121
18076
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
18122
18077
|
style: {
|
|
18123
18078
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -18140,7 +18095,7 @@ function MediaOverlay({
|
|
|
18140
18095
|
},
|
|
18141
18096
|
children: [
|
|
18142
18097
|
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 }),
|
|
18143
|
-
replaceMode === "full" ?
|
|
18098
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
18144
18099
|
]
|
|
18145
18100
|
}
|
|
18146
18101
|
)
|
|
@@ -18650,7 +18605,7 @@ function AiSectionOverlay({
|
|
|
18650
18605
|
|
|
18651
18606
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18652
18607
|
var import_react10 = require("react");
|
|
18653
|
-
var
|
|
18608
|
+
var import_lucide_react8 = require("lucide-react");
|
|
18654
18609
|
|
|
18655
18610
|
// src/lib/ai-media-strip-tree.ts
|
|
18656
18611
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18764,6 +18719,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18764
18719
|
return true;
|
|
18765
18720
|
});
|
|
18766
18721
|
}
|
|
18722
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18723
|
+
return withMediaStrip(tree, (block) => {
|
|
18724
|
+
const items = block.items;
|
|
18725
|
+
if (index < 0 || index >= items.length) return false;
|
|
18726
|
+
items[index] = { ...items[index], alt };
|
|
18727
|
+
return true;
|
|
18728
|
+
});
|
|
18729
|
+
}
|
|
18767
18730
|
function setMediaStripItemLink(tree, index, link) {
|
|
18768
18731
|
return withMediaStrip(tree, (block) => {
|
|
18769
18732
|
const items = block.items;
|
|
@@ -18781,117 +18744,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18781
18744
|
});
|
|
18782
18745
|
}
|
|
18783
18746
|
|
|
18784
|
-
// src/ui/dialog.tsx
|
|
18785
|
-
var React9 = __toESM(require("react"), 1);
|
|
18786
|
-
var import_radix_ui6 = require("radix-ui");
|
|
18787
|
-
var import_lucide_react8 = require("lucide-react");
|
|
18788
|
-
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18789
|
-
function Dialog2({
|
|
18790
|
-
...props
|
|
18791
|
-
}) {
|
|
18792
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
18793
|
-
}
|
|
18794
|
-
function DialogPortal({
|
|
18795
|
-
...props
|
|
18796
|
-
}) {
|
|
18797
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
18798
|
-
}
|
|
18799
|
-
function DialogOverlay({
|
|
18800
|
-
className,
|
|
18801
|
-
...props
|
|
18802
|
-
}) {
|
|
18803
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18804
|
-
import_radix_ui6.Dialog.Overlay,
|
|
18805
|
-
{
|
|
18806
|
-
"data-slot": "dialog-overlay",
|
|
18807
|
-
"data-ohw-link-modal-root": "",
|
|
18808
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18809
|
-
...props
|
|
18810
|
-
}
|
|
18811
|
-
);
|
|
18812
|
-
}
|
|
18813
|
-
var DialogContent = React9.forwardRef(
|
|
18814
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18815
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
18816
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
18817
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18818
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18819
|
-
import_radix_ui6.Dialog.Content,
|
|
18820
|
-
{
|
|
18821
|
-
ref,
|
|
18822
|
-
"data-slot": "dialog-content",
|
|
18823
|
-
className: cn(
|
|
18824
|
-
positionMode,
|
|
18825
|
-
"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",
|
|
18826
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18827
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18828
|
-
className
|
|
18829
|
-
),
|
|
18830
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
18831
|
-
...props,
|
|
18832
|
-
children: [
|
|
18833
|
-
children,
|
|
18834
|
-
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18835
|
-
import_radix_ui6.Dialog.Close,
|
|
18836
|
-
{
|
|
18837
|
-
type: "button",
|
|
18838
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18839
|
-
"aria-label": "Close",
|
|
18840
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
18841
|
-
}
|
|
18842
|
-
) : null
|
|
18843
|
-
]
|
|
18844
|
-
}
|
|
18845
|
-
)
|
|
18846
|
-
] });
|
|
18847
|
-
}
|
|
18848
|
-
);
|
|
18849
|
-
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
18850
|
-
function DialogHeader({
|
|
18851
|
-
className,
|
|
18852
|
-
...props
|
|
18853
|
-
}) {
|
|
18854
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18855
|
-
}
|
|
18856
|
-
function DialogFooter({
|
|
18857
|
-
className,
|
|
18858
|
-
...props
|
|
18859
|
-
}) {
|
|
18860
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18861
|
-
"div",
|
|
18862
|
-
{
|
|
18863
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
18864
|
-
...props
|
|
18865
|
-
}
|
|
18866
|
-
);
|
|
18867
|
-
}
|
|
18868
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18869
|
-
import_radix_ui6.Dialog.Title,
|
|
18870
|
-
{
|
|
18871
|
-
ref,
|
|
18872
|
-
className: cn(
|
|
18873
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18874
|
-
className
|
|
18875
|
-
),
|
|
18876
|
-
...props
|
|
18877
|
-
}
|
|
18878
|
-
));
|
|
18879
|
-
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
18880
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18881
|
-
import_radix_ui6.Dialog.Description,
|
|
18882
|
-
{
|
|
18883
|
-
ref,
|
|
18884
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
18885
|
-
...props
|
|
18886
|
-
}
|
|
18887
|
-
));
|
|
18888
|
-
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
18889
|
-
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
18890
|
-
|
|
18891
18747
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18892
|
-
var
|
|
18893
|
-
var PRIMARY3 = "
|
|
18894
|
-
var
|
|
18748
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18749
|
+
var PRIMARY3 = "#0885FE";
|
|
18750
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18751
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
18895
18752
|
function findMediaStripItemElement(sectionId, index) {
|
|
18896
18753
|
const sectionEl = findByInstanceId(sectionId);
|
|
18897
18754
|
if (!sectionEl) return null;
|
|
@@ -18901,35 +18758,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18901
18758
|
}
|
|
18902
18759
|
return null;
|
|
18903
18760
|
}
|
|
18904
|
-
function
|
|
18905
|
-
|
|
18906
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18907
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18908
|
-
if (!itemEl) return null;
|
|
18909
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18910
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18911
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18912
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18913
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
18914
|
-
return { sectionId, index };
|
|
18915
|
-
}
|
|
18916
|
-
function sameRef(a, b) {
|
|
18917
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18918
|
-
}
|
|
18919
|
-
function rectOf(el) {
|
|
18761
|
+
function readRect2(ref) {
|
|
18762
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18920
18763
|
if (!el) return null;
|
|
18921
18764
|
const r2 = el.getBoundingClientRect();
|
|
18922
18765
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18923
18766
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18924
18767
|
}
|
|
18925
|
-
function
|
|
18926
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18927
|
-
}
|
|
18928
|
-
function readStripRect(ref) {
|
|
18929
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18930
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18931
|
-
}
|
|
18932
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18768
|
+
function useLiveItemRect(ref) {
|
|
18933
18769
|
const [rect, setRect] = (0, import_react10.useState)(null);
|
|
18934
18770
|
(0, import_react10.useEffect)(() => {
|
|
18935
18771
|
if (!ref) {
|
|
@@ -18937,7 +18773,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18937
18773
|
return;
|
|
18938
18774
|
}
|
|
18939
18775
|
const update = () => {
|
|
18940
|
-
const next =
|
|
18776
|
+
const next = readRect2(ref);
|
|
18941
18777
|
setRect(
|
|
18942
18778
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18943
18779
|
);
|
|
@@ -18952,49 +18788,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
18952
18788
|
window.removeEventListener("resize", update);
|
|
18953
18789
|
clearInterval(interval);
|
|
18954
18790
|
};
|
|
18955
|
-
}, [ref?.sectionId, ref?.index
|
|
18791
|
+
}, [ref?.sectionId, ref?.index]);
|
|
18956
18792
|
return rect;
|
|
18957
18793
|
}
|
|
18958
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
18959
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18960
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18961
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
18962
|
-
const slotRef = (0, import_react10.useRef)(null);
|
|
18963
|
-
const [shift, setShift] = (0, import_react10.useState)(0);
|
|
18964
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
18965
|
-
(0, import_react10.useLayoutEffect)(() => {
|
|
18966
|
-
const slot = slotRef.current;
|
|
18967
|
-
if (!slot) return;
|
|
18968
|
-
const clamp = () => {
|
|
18969
|
-
const w = slot.offsetWidth;
|
|
18970
|
-
if (w <= 0) return;
|
|
18971
|
-
const half = w / 2;
|
|
18972
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18973
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18974
|
-
};
|
|
18975
|
-
clamp();
|
|
18976
|
-
const ro = new ResizeObserver(clamp);
|
|
18977
|
-
ro.observe(slot);
|
|
18978
|
-
return () => ro.disconnect();
|
|
18979
|
-
}, [centerX, children]);
|
|
18980
|
-
const mobile = window.innerWidth <= 480;
|
|
18981
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18982
|
-
"div",
|
|
18983
|
-
{
|
|
18984
|
-
ref: slotRef,
|
|
18985
|
-
"data-ohw-bridge": "",
|
|
18986
|
-
"data-ohw-item-interaction": "",
|
|
18987
|
-
className: "pointer-events-auto fixed",
|
|
18988
|
-
style: {
|
|
18989
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18990
|
-
left: centerX + shift,
|
|
18991
|
-
transform: "translate(-50%, -100%)",
|
|
18992
|
-
zIndex: 2147483645
|
|
18993
|
-
},
|
|
18994
|
-
children
|
|
18995
|
-
}
|
|
18996
|
-
);
|
|
18997
|
-
}
|
|
18998
18794
|
function requestValidateTree(postToParent2, tree) {
|
|
18999
18795
|
return new Promise((resolve) => {
|
|
19000
18796
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -19031,177 +18827,221 @@ function requestAssetPick(postToParent2) {
|
|
|
19031
18827
|
postToParent2({ type: "ow:asset-pick", id });
|
|
19032
18828
|
});
|
|
19033
18829
|
}
|
|
19034
|
-
function
|
|
18830
|
+
function Pill({
|
|
19035
18831
|
label,
|
|
19036
18832
|
onClick,
|
|
19037
|
-
disabled
|
|
19038
|
-
active
|
|
19039
|
-
children
|
|
18833
|
+
disabled,
|
|
18834
|
+
active
|
|
19040
18835
|
}) {
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
18836
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18837
|
+
"button",
|
|
18838
|
+
{
|
|
18839
|
+
type: "button",
|
|
18840
|
+
onClick,
|
|
18841
|
+
disabled,
|
|
18842
|
+
style: {
|
|
18843
|
+
height: 28,
|
|
18844
|
+
padding: "0 10px",
|
|
18845
|
+
display: "inline-flex",
|
|
18846
|
+
alignItems: "center",
|
|
18847
|
+
gap: 4,
|
|
18848
|
+
borderRadius: 999,
|
|
18849
|
+
border: "none",
|
|
18850
|
+
cursor: disabled ? "default" : "pointer",
|
|
18851
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18852
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18853
|
+
opacity: disabled ? 0.4 : 1,
|
|
18854
|
+
fontSize: 12,
|
|
18855
|
+
lineHeight: "16px",
|
|
18856
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18857
|
+
whiteSpace: "nowrap",
|
|
18858
|
+
flex: "0 0 auto"
|
|
18859
|
+
},
|
|
18860
|
+
children: label
|
|
18861
|
+
}
|
|
18862
|
+
);
|
|
19049
18863
|
}
|
|
19050
|
-
function
|
|
19051
|
-
|
|
19052
|
-
value,
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
"
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
) }),
|
|
19072
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
19073
|
-
const selected = option.value === value;
|
|
19074
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19075
|
-
DropdownMenuItem,
|
|
18864
|
+
function AltInput({ value, onCommit }) {
|
|
18865
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
18866
|
+
(0, import_react10.useEffect)(() => setDraft(value), [value]);
|
|
18867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18868
|
+
"div",
|
|
18869
|
+
{
|
|
18870
|
+
style: {
|
|
18871
|
+
display: "flex",
|
|
18872
|
+
alignItems: "center",
|
|
18873
|
+
gap: 6,
|
|
18874
|
+
height: 28,
|
|
18875
|
+
padding: "0 12px",
|
|
18876
|
+
borderRadius: 999,
|
|
18877
|
+
background: "#ffffff",
|
|
18878
|
+
width: "100%",
|
|
18879
|
+
maxWidth: 260,
|
|
18880
|
+
boxSizing: "border-box"
|
|
18881
|
+
},
|
|
18882
|
+
children: [
|
|
18883
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18884
|
+
"span",
|
|
19076
18885
|
{
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
)
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
|
|
19091
|
-
|
|
19092
|
-
|
|
19093
|
-
|
|
19094
|
-
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
|
|
19099
|
-
|
|
19100
|
-
|
|
19101
|
-
|
|
19102
|
-
|
|
19103
|
-
|
|
19104
|
-
|
|
19105
|
-
|
|
19106
|
-
|
|
19107
|
-
|
|
19108
|
-
|
|
19109
|
-
|
|
19110
|
-
|
|
19111
|
-
|
|
19112
|
-
|
|
19113
|
-
|
|
19114
|
-
|
|
19115
|
-
|
|
18886
|
+
style: {
|
|
18887
|
+
flex: "0 0 auto",
|
|
18888
|
+
color: OHW_BLUE_DARK,
|
|
18889
|
+
fontSize: 10,
|
|
18890
|
+
fontWeight: 700,
|
|
18891
|
+
textTransform: "uppercase",
|
|
18892
|
+
letterSpacing: 0.4
|
|
18893
|
+
},
|
|
18894
|
+
children: "Alt"
|
|
18895
|
+
}
|
|
18896
|
+
),
|
|
18897
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18898
|
+
"input",
|
|
18899
|
+
{
|
|
18900
|
+
type: "text",
|
|
18901
|
+
value: draft,
|
|
18902
|
+
onChange: (e) => setDraft(e.target.value),
|
|
18903
|
+
onBlur: () => {
|
|
18904
|
+
if (draft !== value) onCommit(draft);
|
|
18905
|
+
},
|
|
18906
|
+
onKeyDown: (e) => {
|
|
18907
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
18908
|
+
if (e.key === "Escape") {
|
|
18909
|
+
setDraft(value);
|
|
18910
|
+
e.currentTarget.blur();
|
|
18911
|
+
}
|
|
18912
|
+
},
|
|
18913
|
+
placeholder: "Describe this image",
|
|
18914
|
+
"aria-label": "Image alt text",
|
|
18915
|
+
style: {
|
|
18916
|
+
flex: 1,
|
|
18917
|
+
minWidth: 0,
|
|
18918
|
+
border: "none",
|
|
18919
|
+
outline: "none",
|
|
18920
|
+
background: "transparent",
|
|
18921
|
+
fontSize: 12,
|
|
18922
|
+
lineHeight: "16px",
|
|
18923
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18924
|
+
color: "#1f2937"
|
|
18925
|
+
}
|
|
18926
|
+
}
|
|
18927
|
+
)
|
|
18928
|
+
]
|
|
18929
|
+
}
|
|
18930
|
+
);
|
|
18931
|
+
}
|
|
18932
|
+
var VARIANTS = [
|
|
18933
|
+
{ value: "logos", label: "Logos" },
|
|
18934
|
+
{ value: "reel", label: "Reel" }
|
|
18935
|
+
];
|
|
18936
|
+
var ALIGNS = [
|
|
18937
|
+
{ value: "left", label: "Left" },
|
|
18938
|
+
{ value: "center", label: "Center" },
|
|
18939
|
+
{ value: "right", label: "Right" }
|
|
18940
|
+
];
|
|
18941
|
+
var HOVERS = [
|
|
18942
|
+
{ value: "none", label: "None" },
|
|
18943
|
+
{ value: "lift", label: "Lift" },
|
|
18944
|
+
{ value: "zoom", label: "Zoom" },
|
|
18945
|
+
{ value: "fade", label: "Fade" }
|
|
18946
|
+
];
|
|
18947
|
+
var TREATMENTS = [
|
|
18948
|
+
{ value: "color", label: "Color" },
|
|
18949
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
18950
|
+
];
|
|
18951
|
+
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18952
|
+
function LinkInput({ value, onCommit }) {
|
|
18953
|
+
const [draft, setDraft] = (0, import_react10.useState)(value);
|
|
19116
18954
|
const [invalid, setInvalid] = (0, import_react10.useState)(false);
|
|
19117
|
-
|
|
18955
|
+
(0, import_react10.useEffect)(() => {
|
|
18956
|
+
setDraft(value);
|
|
18957
|
+
setInvalid(false);
|
|
18958
|
+
}, [value]);
|
|
18959
|
+
const commit = () => {
|
|
19118
18960
|
const next = draft.trim();
|
|
19119
|
-
if (next
|
|
19120
|
-
|
|
19121
|
-
|
|
19122
|
-
|
|
19123
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
19124
|
-
onClose();
|
|
18961
|
+
if (next === value) return setInvalid(false);
|
|
18962
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
18963
|
+
setInvalid(false);
|
|
18964
|
+
onCommit(next);
|
|
19125
18965
|
};
|
|
19126
|
-
return /* @__PURE__ */ (0,
|
|
19127
|
-
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
"
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
|
|
19138
|
-
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
|
|
19144
|
-
"
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
19148
|
-
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
19152
|
-
|
|
19153
|
-
|
|
19154
|
-
|
|
19155
|
-
|
|
19156
|
-
|
|
19157
|
-
|
|
19158
|
-
|
|
19159
|
-
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
|
|
19169
|
-
|
|
19170
|
-
|
|
19171
|
-
|
|
19172
|
-
|
|
19173
|
-
|
|
19174
|
-
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
19179
|
-
|
|
19180
|
-
|
|
19181
|
-
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
|
|
19185
|
-
|
|
19186
|
-
|
|
19187
|
-
|
|
19188
|
-
|
|
19189
|
-
|
|
19190
|
-
|
|
18966
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18967
|
+
"div",
|
|
18968
|
+
{
|
|
18969
|
+
style: {
|
|
18970
|
+
display: "flex",
|
|
18971
|
+
alignItems: "center",
|
|
18972
|
+
gap: 6,
|
|
18973
|
+
height: 28,
|
|
18974
|
+
padding: "0 12px",
|
|
18975
|
+
borderRadius: 999,
|
|
18976
|
+
background: "#ffffff",
|
|
18977
|
+
width: "100%",
|
|
18978
|
+
maxWidth: 260,
|
|
18979
|
+
boxSizing: "border-box",
|
|
18980
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18981
|
+
},
|
|
18982
|
+
children: [
|
|
18983
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18984
|
+
"span",
|
|
18985
|
+
{
|
|
18986
|
+
style: {
|
|
18987
|
+
flex: "0 0 auto",
|
|
18988
|
+
color: OHW_BLUE_DARK,
|
|
18989
|
+
fontSize: 10,
|
|
18990
|
+
fontWeight: 700,
|
|
18991
|
+
textTransform: "uppercase",
|
|
18992
|
+
letterSpacing: 0.4
|
|
18993
|
+
},
|
|
18994
|
+
children: "Link"
|
|
18995
|
+
}
|
|
18996
|
+
),
|
|
18997
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18998
|
+
"input",
|
|
18999
|
+
{
|
|
19000
|
+
type: "text",
|
|
19001
|
+
inputMode: "url",
|
|
19002
|
+
value: draft,
|
|
19003
|
+
onChange: (e) => setDraft(e.target.value),
|
|
19004
|
+
onBlur: commit,
|
|
19005
|
+
onKeyDown: (e) => {
|
|
19006
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
19007
|
+
if (e.key === "Escape") {
|
|
19008
|
+
setDraft(value);
|
|
19009
|
+
setInvalid(false);
|
|
19010
|
+
e.currentTarget.blur();
|
|
19011
|
+
}
|
|
19012
|
+
},
|
|
19013
|
+
placeholder: "https://example.com",
|
|
19014
|
+
"aria-label": "Image link URL",
|
|
19015
|
+
"aria-invalid": invalid,
|
|
19016
|
+
style: {
|
|
19017
|
+
flex: 1,
|
|
19018
|
+
minWidth: 0,
|
|
19019
|
+
border: "none",
|
|
19020
|
+
outline: "none",
|
|
19021
|
+
background: "transparent",
|
|
19022
|
+
fontSize: 12,
|
|
19023
|
+
lineHeight: "16px",
|
|
19024
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19025
|
+
color: "#1f2937"
|
|
19026
|
+
}
|
|
19027
|
+
}
|
|
19028
|
+
)
|
|
19029
|
+
]
|
|
19030
|
+
}
|
|
19031
|
+
);
|
|
19191
19032
|
}
|
|
19192
19033
|
function MediaStripToolbar({
|
|
19193
19034
|
entry,
|
|
19194
19035
|
index,
|
|
19195
19036
|
pending,
|
|
19196
19037
|
error,
|
|
19197
|
-
itemEditOn,
|
|
19198
|
-
onToggleItemEdit,
|
|
19199
19038
|
onSetVariant,
|
|
19200
19039
|
onSetAlign,
|
|
19201
19040
|
onSetHover,
|
|
19202
19041
|
onSetTreatment,
|
|
19203
19042
|
onResize,
|
|
19204
|
-
|
|
19043
|
+
onSetAlt,
|
|
19044
|
+
onSetLink,
|
|
19205
19045
|
onAddItem,
|
|
19206
19046
|
onRemoveItem,
|
|
19207
19047
|
onChangeImage,
|
|
@@ -19210,102 +19050,81 @@ function MediaStripToolbar({
|
|
|
19210
19050
|
}) {
|
|
19211
19051
|
const items = mediaStripItems(entry.tree);
|
|
19212
19052
|
const itemCount = items.length;
|
|
19053
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
19054
|
+
const currentHref = items[index]?.href ?? "";
|
|
19055
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
19213
19056
|
const slots = findMediaStripSlots(entry.tree);
|
|
19214
19057
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
19215
19058
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
19216
19059
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
19217
19060
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
19218
19061
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
19219
|
-
const
|
|
19220
|
-
const
|
|
19221
|
-
|
|
19062
|
+
const isMobile = window.innerWidth <= 480;
|
|
19063
|
+
const rowStyle = isMobile ? {
|
|
19064
|
+
display: "flex",
|
|
19065
|
+
gap: 6,
|
|
19066
|
+
flexWrap: "nowrap",
|
|
19067
|
+
justifyContent: "center",
|
|
19068
|
+
overflowX: "auto",
|
|
19069
|
+
WebkitOverflowScrolling: "touch",
|
|
19070
|
+
width: "100%",
|
|
19071
|
+
scrollbarWidth: "none"
|
|
19072
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
19073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
19222
19074
|
"div",
|
|
19223
19075
|
{
|
|
19224
19076
|
"data-ohw-bridge": "",
|
|
19225
19077
|
"data-ohw-toolbar": "",
|
|
19226
19078
|
onMouseDown: (e) => e.stopPropagation(),
|
|
19227
|
-
|
|
19228
|
-
|
|
19079
|
+
style: {
|
|
19080
|
+
display: "flex",
|
|
19081
|
+
flexDirection: "column",
|
|
19082
|
+
gap: 6,
|
|
19083
|
+
alignItems: "center",
|
|
19084
|
+
background: OHW_BLUE,
|
|
19085
|
+
padding: 8,
|
|
19086
|
+
borderRadius: 12,
|
|
19087
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
19088
|
+
pointerEvents: pending ? "none" : "auto",
|
|
19089
|
+
opacity: pending ? 0.6 : 1,
|
|
19090
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
19091
|
+
},
|
|
19229
19092
|
children: [
|
|
19230
|
-
/* @__PURE__ */ (0,
|
|
19231
|
-
|
|
19232
|
-
{
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
) }),
|
|
19263
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
19264
|
-
] }),
|
|
19265
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19266
|
-
/* @__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" } }) }),
|
|
19267
|
-
/* @__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" } }) }),
|
|
19268
|
-
/* @__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" } }) }),
|
|
19269
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19270
|
-
ToolbarAction,
|
|
19271
|
-
{
|
|
19272
|
-
label: gatedLabel("Move right"),
|
|
19273
|
-
onClick: onMoveRight,
|
|
19274
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
19275
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ArrowRight, { size: 16, style: { pointerEvents: "none" } })
|
|
19276
|
-
}
|
|
19277
|
-
),
|
|
19278
|
-
/* @__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" } }) }),
|
|
19279
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19280
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
19281
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
19282
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19283
|
-
ToolbarAction,
|
|
19284
|
-
{
|
|
19285
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
19286
|
-
active: treatment === "grayscale",
|
|
19287
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
19288
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
19289
|
-
}
|
|
19290
|
-
),
|
|
19291
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19292
|
-
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)),
|
|
19293
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19294
|
-
/* @__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" } }) }),
|
|
19295
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
19296
|
-
sizeValue,
|
|
19297
|
-
"px"
|
|
19298
|
-
] }),
|
|
19299
|
-
/* @__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" } }) }),
|
|
19300
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19301
|
-
/* @__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" } }) })
|
|
19302
|
-
]
|
|
19303
|
-
}
|
|
19304
|
-
),
|
|
19305
|
-
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 })
|
|
19093
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19094
|
+
VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
19095
|
+
ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
19096
|
+
] }),
|
|
19097
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19098
|
+
HOVERS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
19099
|
+
TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
19100
|
+
] }),
|
|
19101
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
19102
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
19103
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
19104
|
+
sizeValue,
|
|
19105
|
+
"px"
|
|
19106
|
+
] }),
|
|
19107
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "+", onClick: () => onResize(8) })
|
|
19108
|
+
] }),
|
|
19109
|
+
/* @__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 }) }),
|
|
19110
|
+
/* @__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) }) }),
|
|
19111
|
+
currentHref && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19112
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
19113
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
19114
|
+
] }),
|
|
19115
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19116
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
19117
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
19118
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
19119
|
+
] }),
|
|
19120
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: rowStyle, children: [
|
|
19121
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
19122
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
19123
|
+
] }),
|
|
19124
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19306
19125
|
]
|
|
19307
19126
|
}
|
|
19308
|
-
)
|
|
19127
|
+
);
|
|
19309
19128
|
}
|
|
19310
19129
|
function findMediaStripSlots(tree) {
|
|
19311
19130
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -19324,23 +19143,31 @@ function AiMediaStripOverlay({
|
|
|
19324
19143
|
}) {
|
|
19325
19144
|
const [hover, setHover] = (0, import_react10.useState)(null);
|
|
19326
19145
|
const [active, setActive] = (0, import_react10.useState)(null);
|
|
19327
|
-
const [itemEditOn, setItemEditOn] = (0, import_react10.useState)(false);
|
|
19328
|
-
const [linkOpen, setLinkOpen] = (0, import_react10.useState)(false);
|
|
19329
19146
|
const [pending, setPending] = (0, import_react10.useState)(false);
|
|
19330
19147
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
19331
19148
|
const activeRef = (0, import_react10.useRef)(null);
|
|
19332
19149
|
activeRef.current = active;
|
|
19333
|
-
const linkOpenRef = (0, import_react10.useRef)(false);
|
|
19334
|
-
linkOpenRef.current = linkOpen;
|
|
19335
19150
|
(0, import_react10.useEffect)(() => {
|
|
19336
19151
|
const onMove = (e) => {
|
|
19337
|
-
const ref = itemRefFromTarget(e.target);
|
|
19338
19152
|
const t = e.target;
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19153
|
+
if (!(t instanceof HTMLElement)) return;
|
|
19154
|
+
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]")) {
|
|
19155
|
+
return;
|
|
19156
|
+
}
|
|
19157
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
19158
|
+
if (!itemEl) {
|
|
19159
|
+
setHover(null);
|
|
19160
|
+
return;
|
|
19161
|
+
}
|
|
19162
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
19163
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
19164
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
19165
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
19166
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
19167
|
+
setHover(null);
|
|
19168
|
+
return;
|
|
19169
|
+
}
|
|
19170
|
+
setHover({ sectionId, index });
|
|
19344
19171
|
};
|
|
19345
19172
|
const onLeave = () => setHover(null);
|
|
19346
19173
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -19352,25 +19179,23 @@ function AiMediaStripOverlay({
|
|
|
19352
19179
|
}, []);
|
|
19353
19180
|
(0, import_react10.useEffect)(() => {
|
|
19354
19181
|
const onClick = (e) => {
|
|
19182
|
+
const current = activeRef.current;
|
|
19183
|
+
if (!current) return;
|
|
19355
19184
|
const t = e.target;
|
|
19356
|
-
if (!(t instanceof
|
|
19357
|
-
if (t.closest(
|
|
19358
|
-
const
|
|
19359
|
-
if (
|
|
19360
|
-
|
|
19361
|
-
setItemEditOn(false);
|
|
19185
|
+
if (!(t instanceof HTMLElement)) return;
|
|
19186
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
19187
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
19188
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
19189
|
+
setActive(null);
|
|
19362
19190
|
setError(null);
|
|
19363
|
-
setActive(ref);
|
|
19364
19191
|
};
|
|
19365
19192
|
document.addEventListener("click", onClick, true);
|
|
19366
19193
|
return () => document.removeEventListener("click", onClick, true);
|
|
19367
|
-
}, [
|
|
19194
|
+
}, []);
|
|
19368
19195
|
(0, import_react10.useEffect)(() => {
|
|
19369
19196
|
const onBlur = () => {
|
|
19370
19197
|
if (!activeRef.current) return;
|
|
19371
19198
|
setActive(null);
|
|
19372
|
-
setItemEditOn(false);
|
|
19373
|
-
setLinkOpen(false);
|
|
19374
19199
|
setError(null);
|
|
19375
19200
|
};
|
|
19376
19201
|
window.addEventListener("blur", onBlur);
|
|
@@ -19380,10 +19205,7 @@ function AiMediaStripOverlay({
|
|
|
19380
19205
|
const onKeyDown = (e) => {
|
|
19381
19206
|
if (e.key !== "Escape") return;
|
|
19382
19207
|
if (!activeRef.current) return;
|
|
19383
|
-
if (linkOpenRef.current) return;
|
|
19384
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
19385
19208
|
setActive(null);
|
|
19386
|
-
setItemEditOn(false);
|
|
19387
19209
|
setError(null);
|
|
19388
19210
|
};
|
|
19389
19211
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -19417,133 +19239,137 @@ function AiMediaStripOverlay({
|
|
|
19417
19239
|
tree: nextTree,
|
|
19418
19240
|
label: entry.label,
|
|
19419
19241
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
19420
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
19421
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
19422
|
-
// on every edit reads as the section jumping around.
|
|
19423
|
-
skipScrollIntoView: true
|
|
19242
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
19424
19243
|
});
|
|
19425
19244
|
return true;
|
|
19426
19245
|
},
|
|
19427
19246
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
19428
19247
|
);
|
|
19429
19248
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19249
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
19430
19250
|
const activeItemRect = useLiveItemRect(active);
|
|
19431
|
-
const
|
|
19432
|
-
const
|
|
19433
|
-
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19438
|
-
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
|
|
19446
|
-
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
|
|
19251
|
+
const TOOLBAR_APPROX_H = 170;
|
|
19252
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
19254
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19255
|
+
"button",
|
|
19256
|
+
{
|
|
19257
|
+
type: "button",
|
|
19258
|
+
"data-ohw-toolbar": "",
|
|
19259
|
+
onClick: () => {
|
|
19260
|
+
clearInteractionChromeRef.current();
|
|
19261
|
+
setActive(hover);
|
|
19262
|
+
},
|
|
19263
|
+
"aria-label": "Configure media item",
|
|
19264
|
+
style: {
|
|
19265
|
+
position: "fixed",
|
|
19266
|
+
top: hoverHandleRect.top + 8,
|
|
19267
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
19268
|
+
width: 28,
|
|
19269
|
+
height: 28,
|
|
19270
|
+
borderRadius: 8,
|
|
19271
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
19272
|
+
background: "#ffffff",
|
|
19273
|
+
color: PRIMARY3,
|
|
19274
|
+
display: "flex",
|
|
19275
|
+
alignItems: "center",
|
|
19276
|
+
justifyContent: "center",
|
|
19277
|
+
cursor: "pointer",
|
|
19278
|
+
zIndex: 2147483643,
|
|
19279
|
+
fontSize: 14,
|
|
19280
|
+
fontWeight: 700
|
|
19281
|
+
},
|
|
19282
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
19283
|
+
}
|
|
19284
|
+
),
|
|
19285
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19286
|
+
ItemInteractionLayer,
|
|
19287
|
+
{
|
|
19288
|
+
rect: activeItemRect,
|
|
19289
|
+
state: toolbarState,
|
|
19290
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
19291
|
+
MediaStripToolbar,
|
|
19292
|
+
{
|
|
19293
|
+
entry: activeEntry,
|
|
19294
|
+
index: active.index,
|
|
19295
|
+
pending,
|
|
19296
|
+
error,
|
|
19297
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
19298
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
19299
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
19300
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
19301
|
+
onResize: (delta) => {
|
|
19302
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
19303
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
19304
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
19305
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
19306
|
+
},
|
|
19307
|
+
onSetAlt: (alt) => {
|
|
19308
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
19309
|
+
},
|
|
19310
|
+
onSetLink: (href, linkTarget) => {
|
|
19465
19311
|
void runMutation(
|
|
19466
19312
|
active.sectionId,
|
|
19467
|
-
(tree) =>
|
|
19468
|
-
|
|
19469
|
-
|
|
19470
|
-
|
|
19313
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19314
|
+
);
|
|
19315
|
+
},
|
|
19316
|
+
onAddItem: () => {
|
|
19317
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19318
|
+
if (!picked) return;
|
|
19319
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
19320
|
+
void runMutation(
|
|
19321
|
+
active.sectionId,
|
|
19322
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
19323
|
+
{ [picked.assetId]: picked.url }
|
|
19324
|
+
).then((applied) => {
|
|
19325
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19326
|
+
});
|
|
19471
19327
|
});
|
|
19472
|
-
}
|
|
19473
|
-
|
|
19474
|
-
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
|
|
19478
|
-
|
|
19479
|
-
|
|
19480
|
-
|
|
19328
|
+
},
|
|
19329
|
+
onChangeImage: () => {
|
|
19330
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19331
|
+
if (!picked) return;
|
|
19332
|
+
void runMutation(
|
|
19333
|
+
active.sectionId,
|
|
19334
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
19335
|
+
{ [picked.assetId]: picked.url }
|
|
19336
|
+
);
|
|
19337
|
+
});
|
|
19338
|
+
},
|
|
19339
|
+
onRemoveItem: () => {
|
|
19340
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
19341
|
+
(applied) => {
|
|
19342
|
+
if (applied) setActive(null);
|
|
19343
|
+
}
|
|
19481
19344
|
);
|
|
19482
|
-
}
|
|
19483
|
-
|
|
19484
|
-
|
|
19485
|
-
|
|
19486
|
-
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
},
|
|
19498
|
-
onMoveRight: () => {
|
|
19499
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19500
|
-
(applied) => {
|
|
19501
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19502
|
-
}
|
|
19503
|
-
);
|
|
19504
|
-
}
|
|
19505
|
-
}
|
|
19506
|
-
) }),
|
|
19507
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19508
|
-
"div",
|
|
19509
|
-
{
|
|
19510
|
-
"data-ohw-bridge": "",
|
|
19511
|
-
"data-ohw-item-interaction": "",
|
|
19512
|
-
"aria-hidden": true,
|
|
19513
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
19514
|
-
style: {
|
|
19515
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
19516
|
-
left: activeItemRect.left - 5,
|
|
19517
|
-
background: PRIMARY3,
|
|
19518
|
-
zIndex: 2147483644
|
|
19519
|
-
},
|
|
19520
|
-
children: "Media item"
|
|
19521
|
-
}
|
|
19522
|
-
),
|
|
19523
|
-
linkOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19524
|
-
LinkModal,
|
|
19525
|
-
{
|
|
19526
|
-
href: activeHref,
|
|
19527
|
-
linkTarget: activeTarget,
|
|
19528
|
-
onClose: () => setLinkOpen(false),
|
|
19529
|
-
onSave: (href, linkTarget) => {
|
|
19530
|
-
void runMutation(
|
|
19531
|
-
active.sectionId,
|
|
19532
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19533
|
-
);
|
|
19345
|
+
},
|
|
19346
|
+
onMoveLeft: () => {
|
|
19347
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
19348
|
+
(applied) => {
|
|
19349
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
19350
|
+
}
|
|
19351
|
+
);
|
|
19352
|
+
},
|
|
19353
|
+
onMoveRight: () => {
|
|
19354
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19355
|
+
(applied) => {
|
|
19356
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19357
|
+
}
|
|
19358
|
+
);
|
|
19359
|
+
}
|
|
19534
19360
|
}
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19361
|
+
)
|
|
19362
|
+
}
|
|
19363
|
+
)
|
|
19538
19364
|
] });
|
|
19539
19365
|
}
|
|
19540
19366
|
|
|
19541
19367
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
19542
19368
|
var import_react11 = require("react");
|
|
19543
|
-
var
|
|
19544
|
-
var
|
|
19369
|
+
var import_lucide_react9 = require("lucide-react");
|
|
19370
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
19545
19371
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
19546
|
-
var
|
|
19372
|
+
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]";
|
|
19547
19373
|
function findPricingCardElement(sectionId, index) {
|
|
19548
19374
|
const sectionEl = findByInstanceId(sectionId);
|
|
19549
19375
|
if (!sectionEl) return null;
|
|
@@ -19555,7 +19381,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19555
19381
|
}
|
|
19556
19382
|
function cardRefFromTarget(target) {
|
|
19557
19383
|
if (!(target instanceof Element)) return null;
|
|
19558
|
-
if (target.closest(
|
|
19384
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19559
19385
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19560
19386
|
if (!cardEl) return null;
|
|
19561
19387
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19565,21 +19391,21 @@ function cardRefFromTarget(target) {
|
|
|
19565
19391
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19566
19392
|
return { sectionId, index };
|
|
19567
19393
|
}
|
|
19568
|
-
function
|
|
19394
|
+
function sameRef(a, b) {
|
|
19569
19395
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19570
19396
|
}
|
|
19571
|
-
function
|
|
19397
|
+
function rectOf(el) {
|
|
19572
19398
|
if (!el) return null;
|
|
19573
19399
|
const r2 = el.getBoundingClientRect();
|
|
19574
19400
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19575
19401
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19576
19402
|
}
|
|
19577
19403
|
function readRect3(ref) {
|
|
19578
|
-
return
|
|
19404
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19579
19405
|
}
|
|
19580
19406
|
function readGridRect(ref) {
|
|
19581
19407
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19582
|
-
return
|
|
19408
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19583
19409
|
}
|
|
19584
19410
|
function useLiveCardRect(ref, grid = false) {
|
|
19585
19411
|
const [rect, setRect] = (0, import_react11.useState)(null);
|
|
@@ -19609,7 +19435,7 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19609
19435
|
}
|
|
19610
19436
|
var TOOLBAR_GRID_GAP = 52;
|
|
19611
19437
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19612
|
-
var
|
|
19438
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19613
19439
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19614
19440
|
const slotRef = (0, import_react11.useRef)(null);
|
|
19615
19441
|
const [shift, setShift] = (0, import_react11.useState)(0);
|
|
@@ -19621,7 +19447,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19621
19447
|
const w = slot.offsetWidth;
|
|
19622
19448
|
if (w <= 0) return;
|
|
19623
19449
|
const half = w / 2;
|
|
19624
|
-
const clamped = Math.max(
|
|
19450
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19625
19451
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19626
19452
|
};
|
|
19627
19453
|
clamp();
|
|
@@ -19630,7 +19456,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19630
19456
|
return () => ro.disconnect();
|
|
19631
19457
|
}, [centerX, children]);
|
|
19632
19458
|
const mobile = window.innerWidth <= 480;
|
|
19633
|
-
return /* @__PURE__ */ (0,
|
|
19459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19634
19460
|
"div",
|
|
19635
19461
|
{
|
|
19636
19462
|
ref: slotRef,
|
|
@@ -19665,7 +19491,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
19665
19491
|
});
|
|
19666
19492
|
}
|
|
19667
19493
|
function StyleSwatch({ style }) {
|
|
19668
|
-
return /* @__PURE__ */ (0,
|
|
19494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19669
19495
|
"span",
|
|
19670
19496
|
{
|
|
19671
19497
|
"aria-hidden": true,
|
|
@@ -19679,35 +19505,35 @@ function StyleSwatch({ style }) {
|
|
|
19679
19505
|
);
|
|
19680
19506
|
}
|
|
19681
19507
|
function ButtonGlyph() {
|
|
19682
|
-
return /* @__PURE__ */ (0,
|
|
19683
|
-
/* @__PURE__ */ (0,
|
|
19684
|
-
/* @__PURE__ */ (0,
|
|
19508
|
+
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: [
|
|
19509
|
+
/* @__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" }),
|
|
19510
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19685
19511
|
] });
|
|
19686
19512
|
}
|
|
19687
19513
|
function FeatureGlyph({ mode }) {
|
|
19688
|
-
return /* @__PURE__ */ (0,
|
|
19689
|
-
/* @__PURE__ */ (0,
|
|
19690
|
-
/* @__PURE__ */ (0,
|
|
19691
|
-
/* @__PURE__ */ (0,
|
|
19692
|
-
/* @__PURE__ */ (0,
|
|
19693
|
-
/* @__PURE__ */ (0,
|
|
19694
|
-
mode === "add" && /* @__PURE__ */ (0,
|
|
19514
|
+
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: [
|
|
19515
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19516
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19517
|
+
/* @__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" }),
|
|
19518
|
+
/* @__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" }),
|
|
19519
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19520
|
+
mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
19695
19521
|
] });
|
|
19696
19522
|
}
|
|
19697
|
-
function
|
|
19523
|
+
function ToolbarAction({
|
|
19698
19524
|
label,
|
|
19699
19525
|
onClick,
|
|
19700
19526
|
disabled = false,
|
|
19701
19527
|
children
|
|
19702
19528
|
}) {
|
|
19703
|
-
const button = /* @__PURE__ */ (0,
|
|
19704
|
-
return /* @__PURE__ */ (0,
|
|
19705
|
-
/* @__PURE__ */ (0,
|
|
19706
|
-
/* @__PURE__ */ (0,
|
|
19529
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19530
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19531
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
19532
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19707
19533
|
] });
|
|
19708
19534
|
}
|
|
19709
|
-
function
|
|
19710
|
-
return /* @__PURE__ */ (0,
|
|
19535
|
+
function ToolbarSeparator() {
|
|
19536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19711
19537
|
}
|
|
19712
19538
|
function CardStyleMenu({
|
|
19713
19539
|
value,
|
|
@@ -19715,7 +19541,7 @@ function CardStyleMenu({
|
|
|
19715
19541
|
disabled = false
|
|
19716
19542
|
}) {
|
|
19717
19543
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
19718
|
-
const trigger = /* @__PURE__ */ (0,
|
|
19544
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19719
19545
|
"button",
|
|
19720
19546
|
{
|
|
19721
19547
|
type: "button",
|
|
@@ -19726,28 +19552,28 @@ function CardStyleMenu({
|
|
|
19726
19552
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
19727
19553
|
),
|
|
19728
19554
|
children: [
|
|
19729
|
-
/* @__PURE__ */ (0,
|
|
19730
|
-
/* @__PURE__ */ (0,
|
|
19731
|
-
/* @__PURE__ */ (0,
|
|
19555
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: current.value }),
|
|
19556
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
19557
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
19732
19558
|
]
|
|
19733
19559
|
}
|
|
19734
19560
|
);
|
|
19735
19561
|
if (disabled) {
|
|
19736
|
-
return /* @__PURE__ */ (0,
|
|
19737
|
-
/* @__PURE__ */ (0,
|
|
19738
|
-
/* @__PURE__ */ (0,
|
|
19739
|
-
/* @__PURE__ */ (0,
|
|
19740
|
-
/* @__PURE__ */ (0,
|
|
19562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19563
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19564
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19565
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
19566
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
19741
19567
|
] })
|
|
19742
19568
|
] });
|
|
19743
19569
|
}
|
|
19744
|
-
return /* @__PURE__ */ (0,
|
|
19745
|
-
/* @__PURE__ */ (0,
|
|
19746
|
-
/* @__PURE__ */ (0,
|
|
19747
|
-
/* @__PURE__ */ (0,
|
|
19748
|
-
/* @__PURE__ */ (0,
|
|
19570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19571
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19572
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenu, { modal: false, children: [
|
|
19573
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19574
|
+
/* @__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) => {
|
|
19749
19575
|
const selected = style.value === value;
|
|
19750
|
-
return /* @__PURE__ */ (0,
|
|
19576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19751
19577
|
DropdownMenuItem,
|
|
19752
19578
|
{
|
|
19753
19579
|
role: "menuitemradio",
|
|
@@ -19755,9 +19581,9 @@ function CardStyleMenu({
|
|
|
19755
19581
|
onSelect: () => onChange(style.value),
|
|
19756
19582
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
19757
19583
|
children: [
|
|
19758
|
-
/* @__PURE__ */ (0,
|
|
19759
|
-
/* @__PURE__ */ (0,
|
|
19760
|
-
selected && /* @__PURE__ */ (0,
|
|
19584
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: style.value }),
|
|
19585
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: style.label }),
|
|
19586
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
|
|
19761
19587
|
]
|
|
19762
19588
|
},
|
|
19763
19589
|
style.value
|
|
@@ -19787,7 +19613,7 @@ function PricingCardToolbar({
|
|
|
19787
19613
|
const style = pricingCardStyle(entry.tree, index);
|
|
19788
19614
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
19789
19615
|
const mobile = window.innerWidth <= 480;
|
|
19790
|
-
return /* @__PURE__ */ (0,
|
|
19616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19791
19617
|
"div",
|
|
19792
19618
|
{
|
|
19793
19619
|
"data-ohw-bridge": "",
|
|
@@ -19799,7 +19625,7 @@ function PricingCardToolbar({
|
|
|
19799
19625
|
),
|
|
19800
19626
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
19801
19627
|
children: [
|
|
19802
|
-
/* @__PURE__ */ (0,
|
|
19628
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
19803
19629
|
"div",
|
|
19804
19630
|
{
|
|
19805
19631
|
className: cn(
|
|
@@ -19808,8 +19634,8 @@ function PricingCardToolbar({
|
|
|
19808
19634
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
19809
19635
|
),
|
|
19810
19636
|
children: [
|
|
19811
|
-
/* @__PURE__ */ (0,
|
|
19812
|
-
/* @__PURE__ */ (0,
|
|
19637
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19638
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19813
19639
|
CustomToolbarButton,
|
|
19814
19640
|
{
|
|
19815
19641
|
type: "button",
|
|
@@ -19817,8 +19643,8 @@ function PricingCardToolbar({
|
|
|
19817
19643
|
"aria-pressed": featuredTag,
|
|
19818
19644
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19819
19645
|
className: "group size-8",
|
|
19820
|
-
children: /* @__PURE__ */ (0,
|
|
19821
|
-
|
|
19646
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19647
|
+
import_lucide_react9.Star,
|
|
19822
19648
|
{
|
|
19823
19649
|
size: 16,
|
|
19824
19650
|
fill: "currentColor",
|
|
@@ -19832,25 +19658,25 @@ function PricingCardToolbar({
|
|
|
19832
19658
|
)
|
|
19833
19659
|
}
|
|
19834
19660
|
) }),
|
|
19835
|
-
/* @__PURE__ */ (0,
|
|
19661
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19836
19662
|
] }),
|
|
19837
|
-
/* @__PURE__ */ (0,
|
|
19838
|
-
/* @__PURE__ */ (0,
|
|
19839
|
-
/* @__PURE__ */ (0,
|
|
19840
|
-
/* @__PURE__ */ (0,
|
|
19841
|
-
/* @__PURE__ */ (0,
|
|
19842
|
-
/* @__PURE__ */ (0,
|
|
19843
|
-
/* @__PURE__ */ (0,
|
|
19663
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19664
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19665
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19666
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}) }),
|
|
19667
|
+
/* @__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: [
|
|
19668
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}),
|
|
19669
|
+
/* @__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" })
|
|
19844
19670
|
] }) }),
|
|
19845
|
-
/* @__PURE__ */ (0,
|
|
19846
|
-
/* @__PURE__ */ (0,
|
|
19847
|
-
/* @__PURE__ */ (0,
|
|
19848
|
-
/* @__PURE__ */ (0,
|
|
19849
|
-
/* @__PURE__ */ (0,
|
|
19671
|
+
/* @__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" }) }),
|
|
19672
|
+
/* @__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" }) }),
|
|
19673
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator, {}),
|
|
19674
|
+
/* @__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" } }) }),
|
|
19675
|
+
/* @__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" } }) })
|
|
19850
19676
|
]
|
|
19851
19677
|
}
|
|
19852
19678
|
),
|
|
19853
|
-
error && /* @__PURE__ */ (0,
|
|
19679
|
+
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 })
|
|
19854
19680
|
]
|
|
19855
19681
|
}
|
|
19856
19682
|
) });
|
|
@@ -19884,7 +19710,7 @@ function AiPricingCardOverlay({
|
|
|
19884
19710
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19885
19711
|
setHover((prev) => {
|
|
19886
19712
|
const next = ref && !overEditable ? ref : null;
|
|
19887
|
-
return
|
|
19713
|
+
return sameRef(prev, next) ? prev : next;
|
|
19888
19714
|
});
|
|
19889
19715
|
};
|
|
19890
19716
|
const onLeave = () => setHover(null);
|
|
@@ -19899,10 +19725,10 @@ function AiPricingCardOverlay({
|
|
|
19899
19725
|
const onClick = (e) => {
|
|
19900
19726
|
const t = e.target;
|
|
19901
19727
|
if (!(t instanceof Element)) return;
|
|
19902
|
-
if (t.closest(
|
|
19728
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
19903
19729
|
const ref = cardRefFromTarget(t);
|
|
19904
|
-
setActive((prev) =>
|
|
19905
|
-
if (!ref || !
|
|
19730
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19731
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
19906
19732
|
};
|
|
19907
19733
|
document.addEventListener("click", onClick, true);
|
|
19908
19734
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19967,12 +19793,12 @@ function AiPricingCardOverlay({
|
|
|
19967
19793
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19968
19794
|
const activeCardRect = useLiveCardRect(active);
|
|
19969
19795
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19970
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19971
|
-
return /* @__PURE__ */ (0,
|
|
19972
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
19973
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19974
|
-
/* @__PURE__ */ (0,
|
|
19975
|
-
/* @__PURE__ */ (0,
|
|
19796
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19797
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19798
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19799
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19800
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19801
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19976
19802
|
PricingCardToolbar,
|
|
19977
19803
|
{
|
|
19978
19804
|
entry: activeEntry,
|
|
@@ -20000,7 +19826,7 @@ function AiPricingCardOverlay({
|
|
|
20000
19826
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
20001
19827
|
}
|
|
20002
19828
|
) }),
|
|
20003
|
-
/* @__PURE__ */ (0,
|
|
19829
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
20004
19830
|
"div",
|
|
20005
19831
|
{
|
|
20006
19832
|
"data-ohw-bridge": "",
|
|
@@ -20022,7 +19848,7 @@ function AiPricingCardOverlay({
|
|
|
20022
19848
|
|
|
20023
19849
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
20024
19850
|
var import_react12 = require("react");
|
|
20025
|
-
var
|
|
19851
|
+
var import_lucide_react10 = require("lucide-react");
|
|
20026
19852
|
|
|
20027
19853
|
// src/lib/ai-video-tree.ts
|
|
20028
19854
|
function resolveVideoBlock(tree, path) {
|
|
@@ -20093,10 +19919,10 @@ function extractYouTubeId(input) {
|
|
|
20093
19919
|
}
|
|
20094
19920
|
|
|
20095
19921
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
20096
|
-
var
|
|
19922
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
20097
19923
|
var PRIMARY5 = "#0885FE";
|
|
20098
|
-
var
|
|
20099
|
-
var
|
|
19924
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19925
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
20100
19926
|
function findVideoBlockElement(sectionId, path) {
|
|
20101
19927
|
const sectionEl = findByInstanceId(sectionId);
|
|
20102
19928
|
if (!sectionEl) return null;
|
|
@@ -20156,12 +19982,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
20156
19982
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
20157
19983
|
});
|
|
20158
19984
|
}
|
|
20159
|
-
function
|
|
19985
|
+
function Pill2({
|
|
20160
19986
|
label,
|
|
20161
19987
|
onClick,
|
|
20162
19988
|
disabled
|
|
20163
19989
|
}) {
|
|
20164
|
-
return /* @__PURE__ */ (0,
|
|
19990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20165
19991
|
"button",
|
|
20166
19992
|
{
|
|
20167
19993
|
type: "button",
|
|
@@ -20177,7 +20003,7 @@ function Pill({
|
|
|
20177
20003
|
border: "none",
|
|
20178
20004
|
cursor: disabled ? "default" : "pointer",
|
|
20179
20005
|
background: "#ffffff",
|
|
20180
|
-
color:
|
|
20006
|
+
color: OHW_BLUE_DARK2,
|
|
20181
20007
|
opacity: disabled ? 0.4 : 1,
|
|
20182
20008
|
fontSize: 12,
|
|
20183
20009
|
lineHeight: "16px",
|
|
@@ -20199,7 +20025,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20199
20025
|
setDraft(value ? watchUrl(value) : "");
|
|
20200
20026
|
setInvalid(false);
|
|
20201
20027
|
}, [value]);
|
|
20202
|
-
const
|
|
20028
|
+
const commit = () => {
|
|
20203
20029
|
const next = draft.trim();
|
|
20204
20030
|
if (!next) {
|
|
20205
20031
|
setInvalid(false);
|
|
@@ -20220,8 +20046,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20220
20046
|
onCommit(id);
|
|
20221
20047
|
}
|
|
20222
20048
|
};
|
|
20223
|
-
return /* @__PURE__ */ (0,
|
|
20224
|
-
/* @__PURE__ */ (0,
|
|
20049
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
20050
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
20225
20051
|
"div",
|
|
20226
20052
|
{
|
|
20227
20053
|
style: {
|
|
@@ -20237,12 +20063,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20237
20063
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
20238
20064
|
},
|
|
20239
20065
|
children: [
|
|
20240
|
-
/* @__PURE__ */ (0,
|
|
20066
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20241
20067
|
"span",
|
|
20242
20068
|
{
|
|
20243
20069
|
style: {
|
|
20244
20070
|
flex: "0 0 auto",
|
|
20245
|
-
color:
|
|
20071
|
+
color: OHW_BLUE_DARK2,
|
|
20246
20072
|
fontSize: 10,
|
|
20247
20073
|
lineHeight: "16px",
|
|
20248
20074
|
fontWeight: 700,
|
|
@@ -20252,14 +20078,14 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20252
20078
|
children: "Video"
|
|
20253
20079
|
}
|
|
20254
20080
|
),
|
|
20255
|
-
/* @__PURE__ */ (0,
|
|
20081
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20256
20082
|
"input",
|
|
20257
20083
|
{
|
|
20258
20084
|
type: "text",
|
|
20259
20085
|
inputMode: "url",
|
|
20260
20086
|
value: draft,
|
|
20261
20087
|
onChange: (e) => handleChange(e.target.value),
|
|
20262
|
-
onBlur:
|
|
20088
|
+
onBlur: commit,
|
|
20263
20089
|
onKeyDown: (e) => {
|
|
20264
20090
|
if (e.key === "Enter") e.currentTarget.blur();
|
|
20265
20091
|
if (e.key === "Escape") {
|
|
@@ -20289,7 +20115,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20289
20115
|
]
|
|
20290
20116
|
}
|
|
20291
20117
|
),
|
|
20292
|
-
invalid && /* @__PURE__ */ (0,
|
|
20118
|
+
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." })
|
|
20293
20119
|
] });
|
|
20294
20120
|
}
|
|
20295
20121
|
function VideoToolbar({
|
|
@@ -20299,7 +20125,7 @@ function VideoToolbar({
|
|
|
20299
20125
|
onSetVideoId,
|
|
20300
20126
|
onRemove
|
|
20301
20127
|
}) {
|
|
20302
|
-
return /* @__PURE__ */ (0,
|
|
20128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
20303
20129
|
"div",
|
|
20304
20130
|
{
|
|
20305
20131
|
"data-ohw-bridge": "",
|
|
@@ -20311,7 +20137,7 @@ function VideoToolbar({
|
|
|
20311
20137
|
gap: 6,
|
|
20312
20138
|
alignItems: "center",
|
|
20313
20139
|
width: 280,
|
|
20314
|
-
background:
|
|
20140
|
+
background: OHW_BLUE2,
|
|
20315
20141
|
padding: 8,
|
|
20316
20142
|
borderRadius: 12,
|
|
20317
20143
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20319,9 +20145,9 @@ function VideoToolbar({
|
|
|
20319
20145
|
opacity: pending ? 0.6 : 1
|
|
20320
20146
|
},
|
|
20321
20147
|
children: [
|
|
20322
|
-
/* @__PURE__ */ (0,
|
|
20323
|
-
/* @__PURE__ */ (0,
|
|
20324
|
-
error && /* @__PURE__ */ (0,
|
|
20148
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
20149
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
20150
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20325
20151
|
]
|
|
20326
20152
|
}
|
|
20327
20153
|
);
|
|
@@ -20441,8 +20267,8 @@ function AiVideoOverlay({
|
|
|
20441
20267
|
const activeBlockRect = useLiveBlockRect(active);
|
|
20442
20268
|
const TOOLBAR_APPROX_H = 90;
|
|
20443
20269
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20444
|
-
return /* @__PURE__ */ (0,
|
|
20445
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20270
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
20271
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20446
20272
|
"button",
|
|
20447
20273
|
{
|
|
20448
20274
|
type: "button",
|
|
@@ -20470,15 +20296,15 @@ function AiVideoOverlay({
|
|
|
20470
20296
|
fontSize: 14,
|
|
20471
20297
|
fontWeight: 700
|
|
20472
20298
|
},
|
|
20473
|
-
children: /* @__PURE__ */ (0,
|
|
20299
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20474
20300
|
}
|
|
20475
20301
|
),
|
|
20476
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20302
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20477
20303
|
ItemInteractionLayer,
|
|
20478
20304
|
{
|
|
20479
20305
|
rect: activeBlockRect,
|
|
20480
20306
|
state: toolbarState,
|
|
20481
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20307
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
20482
20308
|
VideoToolbar,
|
|
20483
20309
|
{
|
|
20484
20310
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20502,7 +20328,7 @@ function AiVideoOverlay({
|
|
|
20502
20328
|
|
|
20503
20329
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20504
20330
|
var import_react13 = require("react");
|
|
20505
|
-
var
|
|
20331
|
+
var import_lucide_react11 = require("lucide-react");
|
|
20506
20332
|
|
|
20507
20333
|
// src/lib/ai-carousel-tree.ts
|
|
20508
20334
|
function isCarouselBlock(node) {
|
|
@@ -20553,10 +20379,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20553
20379
|
}
|
|
20554
20380
|
|
|
20555
20381
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20556
|
-
var
|
|
20382
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
20557
20383
|
var PRIMARY6 = "#0885FE";
|
|
20558
|
-
var
|
|
20559
|
-
var
|
|
20384
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
20385
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20560
20386
|
function findCarouselItemElement(sectionId, index) {
|
|
20561
20387
|
const sectionEl = findByInstanceId(sectionId);
|
|
20562
20388
|
if (!sectionEl) return null;
|
|
@@ -20635,8 +20461,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20635
20461
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20636
20462
|
});
|
|
20637
20463
|
}
|
|
20638
|
-
function
|
|
20639
|
-
return /* @__PURE__ */ (0,
|
|
20464
|
+
function Pill3({ label, onClick, disabled }) {
|
|
20465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20640
20466
|
"button",
|
|
20641
20467
|
{
|
|
20642
20468
|
type: "button",
|
|
@@ -20652,7 +20478,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20652
20478
|
border: "none",
|
|
20653
20479
|
cursor: disabled ? "default" : "pointer",
|
|
20654
20480
|
background: "#ffffff",
|
|
20655
|
-
color:
|
|
20481
|
+
color: OHW_BLUE_DARK3,
|
|
20656
20482
|
opacity: disabled ? 0.4 : 1,
|
|
20657
20483
|
fontSize: 12,
|
|
20658
20484
|
lineHeight: "16px",
|
|
@@ -20670,7 +20496,7 @@ function TogglePill({
|
|
|
20670
20496
|
onToggle,
|
|
20671
20497
|
disabled
|
|
20672
20498
|
}) {
|
|
20673
|
-
return /* @__PURE__ */ (0,
|
|
20499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20674
20500
|
"button",
|
|
20675
20501
|
{
|
|
20676
20502
|
type: "button",
|
|
@@ -20689,7 +20515,7 @@ function TogglePill({
|
|
|
20689
20515
|
border: "none",
|
|
20690
20516
|
cursor: disabled ? "default" : "pointer",
|
|
20691
20517
|
background: "#ffffff",
|
|
20692
|
-
color:
|
|
20518
|
+
color: OHW_BLUE_DARK3,
|
|
20693
20519
|
opacity: disabled ? 0.4 : 1,
|
|
20694
20520
|
fontSize: 12,
|
|
20695
20521
|
lineHeight: "16px",
|
|
@@ -20699,7 +20525,7 @@ function TogglePill({
|
|
|
20699
20525
|
},
|
|
20700
20526
|
children: [
|
|
20701
20527
|
label,
|
|
20702
|
-
/* @__PURE__ */ (0,
|
|
20528
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20703
20529
|
"span",
|
|
20704
20530
|
{
|
|
20705
20531
|
"aria-hidden": true,
|
|
@@ -20712,10 +20538,10 @@ function TogglePill({
|
|
|
20712
20538
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
20713
20539
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
20714
20540
|
// "disabled control" rather than "switch that is off".
|
|
20715
|
-
background: on ?
|
|
20541
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
20716
20542
|
transition: "background 120ms ease"
|
|
20717
20543
|
},
|
|
20718
|
-
children: /* @__PURE__ */ (0,
|
|
20544
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20719
20545
|
"span",
|
|
20720
20546
|
{
|
|
20721
20547
|
style: {
|
|
@@ -20744,7 +20570,7 @@ function CarouselSlideToolbar({
|
|
|
20744
20570
|
onChangeImage,
|
|
20745
20571
|
onToggleAutoplay
|
|
20746
20572
|
}) {
|
|
20747
|
-
return /* @__PURE__ */ (0,
|
|
20573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20748
20574
|
"div",
|
|
20749
20575
|
{
|
|
20750
20576
|
"data-ohw-bridge": "",
|
|
@@ -20755,7 +20581,7 @@ function CarouselSlideToolbar({
|
|
|
20755
20581
|
flexDirection: "column",
|
|
20756
20582
|
gap: 6,
|
|
20757
20583
|
alignItems: "center",
|
|
20758
|
-
background:
|
|
20584
|
+
background: OHW_BLUE3,
|
|
20759
20585
|
padding: 8,
|
|
20760
20586
|
borderRadius: 12,
|
|
20761
20587
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20767,11 +20593,11 @@ function CarouselSlideToolbar({
|
|
|
20767
20593
|
pointerEvents: pending ? "none" : "auto"
|
|
20768
20594
|
},
|
|
20769
20595
|
children: [
|
|
20770
|
-
/* @__PURE__ */ (0,
|
|
20771
|
-
/* @__PURE__ */ (0,
|
|
20772
|
-
/* @__PURE__ */ (0,
|
|
20596
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20597
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20598
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
20773
20599
|
] }),
|
|
20774
|
-
error && /* @__PURE__ */ (0,
|
|
20600
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20775
20601
|
]
|
|
20776
20602
|
}
|
|
20777
20603
|
);
|
|
@@ -20911,8 +20737,8 @@ function AiFadeCarouselOverlay({
|
|
|
20911
20737
|
const activeItemRect = useLiveItemRect2(active);
|
|
20912
20738
|
const TOOLBAR_APPROX_H = 90;
|
|
20913
20739
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20914
|
-
return /* @__PURE__ */ (0,
|
|
20915
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
20741
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20916
20742
|
"button",
|
|
20917
20743
|
{
|
|
20918
20744
|
type: "button",
|
|
@@ -20941,10 +20767,10 @@ function AiFadeCarouselOverlay({
|
|
|
20941
20767
|
fontSize: 14,
|
|
20942
20768
|
fontWeight: 700
|
|
20943
20769
|
},
|
|
20944
|
-
children: /* @__PURE__ */ (0,
|
|
20770
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20945
20771
|
}
|
|
20946
20772
|
),
|
|
20947
|
-
swapping && /* @__PURE__ */ (0,
|
|
20773
|
+
swapping && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20948
20774
|
"div",
|
|
20949
20775
|
{
|
|
20950
20776
|
ref: skeletonRef,
|
|
@@ -20962,15 +20788,15 @@ function AiFadeCarouselOverlay({
|
|
|
20962
20788
|
zIndex: 2147483646,
|
|
20963
20789
|
pointerEvents: "none"
|
|
20964
20790
|
},
|
|
20965
|
-
children: /* @__PURE__ */ (0,
|
|
20791
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
20966
20792
|
}
|
|
20967
20793
|
),
|
|
20968
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20794
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20969
20795
|
ItemInteractionLayer,
|
|
20970
20796
|
{
|
|
20971
20797
|
rect: activeItemRect,
|
|
20972
20798
|
state: toolbarState,
|
|
20973
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20799
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20974
20800
|
CarouselSlideToolbar,
|
|
20975
20801
|
{
|
|
20976
20802
|
pending,
|
|
@@ -21188,6 +21014,113 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
21188
21014
|
// src/ui/link-modal/LinkPopover.tsx
|
|
21189
21015
|
var import_react17 = require("react");
|
|
21190
21016
|
|
|
21017
|
+
// src/ui/dialog.tsx
|
|
21018
|
+
var React9 = __toESM(require("react"), 1);
|
|
21019
|
+
var import_radix_ui6 = require("radix-ui");
|
|
21020
|
+
var import_lucide_react12 = require("lucide-react");
|
|
21021
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
21022
|
+
function Dialog2({
|
|
21023
|
+
...props
|
|
21024
|
+
}) {
|
|
21025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
21026
|
+
}
|
|
21027
|
+
function DialogPortal({
|
|
21028
|
+
...props
|
|
21029
|
+
}) {
|
|
21030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
21031
|
+
}
|
|
21032
|
+
function DialogOverlay({
|
|
21033
|
+
className,
|
|
21034
|
+
...props
|
|
21035
|
+
}) {
|
|
21036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21037
|
+
import_radix_ui6.Dialog.Overlay,
|
|
21038
|
+
{
|
|
21039
|
+
"data-slot": "dialog-overlay",
|
|
21040
|
+
"data-ohw-link-modal-root": "",
|
|
21041
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
21042
|
+
...props
|
|
21043
|
+
}
|
|
21044
|
+
);
|
|
21045
|
+
}
|
|
21046
|
+
var DialogContent = React9.forwardRef(
|
|
21047
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
21048
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
21049
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
21050
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
21051
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
21052
|
+
import_radix_ui6.Dialog.Content,
|
|
21053
|
+
{
|
|
21054
|
+
ref,
|
|
21055
|
+
"data-slot": "dialog-content",
|
|
21056
|
+
className: cn(
|
|
21057
|
+
positionMode,
|
|
21058
|
+
"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",
|
|
21059
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
21060
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
21061
|
+
className
|
|
21062
|
+
),
|
|
21063
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
21064
|
+
...props,
|
|
21065
|
+
children: [
|
|
21066
|
+
children,
|
|
21067
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21068
|
+
import_radix_ui6.Dialog.Close,
|
|
21069
|
+
{
|
|
21070
|
+
type: "button",
|
|
21071
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
21072
|
+
"aria-label": "Close",
|
|
21073
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
21074
|
+
}
|
|
21075
|
+
) : null
|
|
21076
|
+
]
|
|
21077
|
+
}
|
|
21078
|
+
)
|
|
21079
|
+
] });
|
|
21080
|
+
}
|
|
21081
|
+
);
|
|
21082
|
+
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
21083
|
+
function DialogHeader({
|
|
21084
|
+
className,
|
|
21085
|
+
...props
|
|
21086
|
+
}) {
|
|
21087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
21088
|
+
}
|
|
21089
|
+
function DialogFooter({
|
|
21090
|
+
className,
|
|
21091
|
+
...props
|
|
21092
|
+
}) {
|
|
21093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21094
|
+
"div",
|
|
21095
|
+
{
|
|
21096
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
21097
|
+
...props
|
|
21098
|
+
}
|
|
21099
|
+
);
|
|
21100
|
+
}
|
|
21101
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21102
|
+
import_radix_ui6.Dialog.Title,
|
|
21103
|
+
{
|
|
21104
|
+
ref,
|
|
21105
|
+
className: cn(
|
|
21106
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
21107
|
+
className
|
|
21108
|
+
),
|
|
21109
|
+
...props
|
|
21110
|
+
}
|
|
21111
|
+
));
|
|
21112
|
+
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
21113
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
21114
|
+
import_radix_ui6.Dialog.Description,
|
|
21115
|
+
{
|
|
21116
|
+
ref,
|
|
21117
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
21118
|
+
...props
|
|
21119
|
+
}
|
|
21120
|
+
));
|
|
21121
|
+
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
21122
|
+
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
21123
|
+
|
|
21191
21124
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
21192
21125
|
var import_lucide_react16 = require("lucide-react");
|
|
21193
21126
|
|
|
@@ -22291,7 +22224,6 @@ function shouldUseDevFixtures() {
|
|
|
22291
22224
|
function getLogoElement(el) {
|
|
22292
22225
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
22293
22226
|
if (marked) return marked;
|
|
22294
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
22295
22227
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
22296
22228
|
if (!root) return null;
|
|
22297
22229
|
const anchor = el.closest("a");
|
|
@@ -23986,102 +23918,6 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
23986
23918
|
return false;
|
|
23987
23919
|
}
|
|
23988
23920
|
|
|
23989
|
-
// src/lib/nav-page-sync.ts
|
|
23990
|
-
function labelKeyFor(hrefKey) {
|
|
23991
|
-
return hrefKey.replace(/-href$/, "-label");
|
|
23992
|
-
}
|
|
23993
|
-
function isPageLinkKey(key) {
|
|
23994
|
-
return isNavbarHrefKey(key) || isFooterHrefKey(key);
|
|
23995
|
-
}
|
|
23996
|
-
function currentHref(key, anchor, content) {
|
|
23997
|
-
const stored = content[key];
|
|
23998
|
-
if (typeof stored === "string" && stored.length > 0) return stored;
|
|
23999
|
-
return anchor.getAttribute("href") ?? "";
|
|
24000
|
-
}
|
|
24001
|
-
function normalizePath2(value) {
|
|
24002
|
-
if (value.length > 1 && value.endsWith("/")) return value.slice(0, -1);
|
|
24003
|
-
return value;
|
|
24004
|
-
}
|
|
24005
|
-
function pointsAt(href, path) {
|
|
24006
|
-
const normalized = normalizePath2(href);
|
|
24007
|
-
const target = normalizePath2(path);
|
|
24008
|
-
if (normalized === target) return true;
|
|
24009
|
-
return (normalized.startsWith(`${target}#`) || normalized.startsWith(`${target}?`)) && target !== "/";
|
|
24010
|
-
}
|
|
24011
|
-
function retargetHref(href, oldPath, newPath) {
|
|
24012
|
-
const normalized = normalizePath2(href);
|
|
24013
|
-
const target = normalizePath2(oldPath);
|
|
24014
|
-
if (normalized === target) return newPath;
|
|
24015
|
-
return `${newPath}${normalized.slice(target.length)}`;
|
|
24016
|
-
}
|
|
24017
|
-
function setLabelText(key, text) {
|
|
24018
|
-
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
24019
|
-
el.textContent = text;
|
|
24020
|
-
});
|
|
24021
|
-
}
|
|
24022
|
-
function commit(delta, deps) {
|
|
24023
|
-
if (Object.keys(delta).length === 0) return;
|
|
24024
|
-
deps.setEditContent({ ...deps.getEditContent(), ...delta });
|
|
24025
|
-
deps.postToParent({
|
|
24026
|
-
type: "ow:change",
|
|
24027
|
-
nodes: Object.entries(delta).map(([key, text]) => ({ key, text }))
|
|
24028
|
-
});
|
|
24029
|
-
}
|
|
24030
|
-
function navLinksTo(path, content) {
|
|
24031
|
-
return Array.from(document.querySelectorAll("[data-ohw-href-key]")).filter((anchor) => {
|
|
24032
|
-
const key = anchor.getAttribute("data-ohw-href-key");
|
|
24033
|
-
return isNavbarHrefKey(key) && pointsAt(currentHref(key, anchor, content), path);
|
|
24034
|
-
}).map((anchor) => anchor.getAttribute("data-ohw-href-key"));
|
|
24035
|
-
}
|
|
24036
|
-
function addNavLinkForPage(page, deps) {
|
|
24037
|
-
const content = deps.getEditContent();
|
|
24038
|
-
if (navLinksTo(page.path, content).length > 0) return false;
|
|
24039
|
-
const roots = listNavbarRootItems();
|
|
24040
|
-
const afterAnchor = roots[roots.length - 1] ?? null;
|
|
24041
|
-
let inserted;
|
|
24042
|
-
try {
|
|
24043
|
-
inserted = insertNavbarItem(page.path, page.title, afterAnchor);
|
|
24044
|
-
} catch {
|
|
24045
|
-
return false;
|
|
24046
|
-
}
|
|
24047
|
-
const { hrefKey, labelKey, index } = inserted;
|
|
24048
|
-
deps.applyLinkByKey(hrefKey, page.path);
|
|
24049
|
-
setLabelText(labelKey, page.title);
|
|
24050
|
-
commit(
|
|
24051
|
-
{
|
|
24052
|
-
[hrefKey]: page.path,
|
|
24053
|
-
[labelKey]: page.title,
|
|
24054
|
-
[NAV_COUNT_KEY]: String(index + 1),
|
|
24055
|
-
[NAV_ORDER_KEY]: getNavbarOrderJson()
|
|
24056
|
-
},
|
|
24057
|
-
deps
|
|
24058
|
-
);
|
|
24059
|
-
return true;
|
|
24060
|
-
}
|
|
24061
|
-
function retargetPageLinks(change, deps) {
|
|
24062
|
-
const { oldPath, newPath, oldTitle, newTitle } = change;
|
|
24063
|
-
if (!oldPath || !newPath || normalizePath2(oldPath) === normalizePath2(newPath)) return 0;
|
|
24064
|
-
const content = deps.getEditContent();
|
|
24065
|
-
const delta = {};
|
|
24066
|
-
for (const anchor of Array.from(document.querySelectorAll("[data-ohw-href-key]"))) {
|
|
24067
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
24068
|
-
if (!isPageLinkKey(hrefKey)) continue;
|
|
24069
|
-
const href = currentHref(hrefKey, anchor, content);
|
|
24070
|
-
if (!pointsAt(href, oldPath)) continue;
|
|
24071
|
-
const nextHref = retargetHref(href, oldPath, newPath);
|
|
24072
|
-
deps.applyLinkByKey(hrefKey, nextHref);
|
|
24073
|
-
delta[hrefKey] = nextHref;
|
|
24074
|
-
if (!oldTitle || !newTitle) continue;
|
|
24075
|
-
const labelKey = labelKeyFor(hrefKey);
|
|
24076
|
-
const label = content[labelKey] ?? anchor.querySelector('[data-ohw-editable="text"]')?.textContent ?? "";
|
|
24077
|
-
if (label.trim() !== oldTitle) continue;
|
|
24078
|
-
setLabelText(labelKey, newTitle);
|
|
24079
|
-
delta[labelKey] = newTitle;
|
|
24080
|
-
}
|
|
24081
|
-
commit(delta, deps);
|
|
24082
|
-
return Object.keys(delta).filter((key) => key.endsWith("-href")).length;
|
|
24083
|
-
}
|
|
24084
|
-
|
|
24085
23921
|
// src/ui/navbar-container-chrome.tsx
|
|
24086
23922
|
var import_lucide_react21 = require("lucide-react");
|
|
24087
23923
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
@@ -24969,7 +24805,7 @@ function getNavigationSelectionParent(el) {
|
|
|
24969
24805
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
24970
24806
|
return resolveFooterLinksContainerFrom(el);
|
|
24971
24807
|
}
|
|
24972
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24808
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24973
24809
|
return getNavigationRoot(el);
|
|
24974
24810
|
}
|
|
24975
24811
|
return null;
|
|
@@ -25191,6 +25027,7 @@ var ICONS = {
|
|
|
25191
25027
|
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"/>',
|
|
25192
25028
|
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"/>'
|
|
25193
25029
|
};
|
|
25030
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
25194
25031
|
var SELECTION_CHROME_GAP2 = 4;
|
|
25195
25032
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
25196
25033
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -25288,7 +25125,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
25288
25125
|
el.style.top = `${top}px`;
|
|
25289
25126
|
el.style.height = `${height}px`;
|
|
25290
25127
|
}
|
|
25291
|
-
var
|
|
25128
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
25292
25129
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
25293
25130
|
const isAbove = transform.includes("translateY(-100%)");
|
|
25294
25131
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -25315,8 +25152,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
25315
25152
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
25316
25153
|
const half = toolbarWidth / 2;
|
|
25317
25154
|
return Math.max(
|
|
25318
|
-
|
|
25319
|
-
Math.min(centerX, window.innerWidth -
|
|
25155
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
25156
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
25320
25157
|
);
|
|
25321
25158
|
}
|
|
25322
25159
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -26196,6 +26033,21 @@ function OhhwellsBridge() {
|
|
|
26196
26033
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
26197
26034
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
26198
26035
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
26036
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
26037
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
26038
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
26039
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
26040
|
+
floatingPanelRef.current = floatingPanel;
|
|
26041
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
26042
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
26043
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
26044
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
26045
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
26046
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
26047
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
26048
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
26049
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
26050
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
26199
26051
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
26200
26052
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
26201
26053
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -26221,21 +26073,6 @@ function OhhwellsBridge() {
|
|
|
26221
26073
|
const stylesRef = (0, import_react21.useRef)("");
|
|
26222
26074
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
26223
26075
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
26224
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
26225
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
26226
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
26227
|
-
floatingPanelRef.current = floatingPanel;
|
|
26228
|
-
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
26229
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
26230
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
26231
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
26232
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
26233
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
26234
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
26235
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
26236
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
26237
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
26238
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
26239
26076
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
26240
26077
|
const collectionItemsRef = (0, import_react21.useRef)(/* @__PURE__ */ new Map());
|
|
26241
26078
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
@@ -26245,18 +26082,7 @@ function OhhwellsBridge() {
|
|
|
26245
26082
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
26246
26083
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
26247
26084
|
setLinkPopoverRef.current = setLinkPopover;
|
|
26248
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
26249
26085
|
linkPopoverSessionRef.current = linkPopover;
|
|
26250
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
26251
|
-
(0, import_react21.useEffect)(() => {
|
|
26252
|
-
const syncViewport = () => {
|
|
26253
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
26254
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
26255
|
-
};
|
|
26256
|
-
syncViewport();
|
|
26257
|
-
window.addEventListener("resize", syncViewport);
|
|
26258
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
26259
|
-
}, []);
|
|
26260
26086
|
(0, import_react21.useEffect)(() => {
|
|
26261
26087
|
setSectionOrderPersistHandler((entries) => {
|
|
26262
26088
|
const currentPath = window.location.pathname;
|
|
@@ -26405,43 +26231,6 @@ function OhhwellsBridge() {
|
|
|
26405
26231
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
26406
26232
|
return () => window.removeEventListener("message", onSitePages);
|
|
26407
26233
|
}, [isEditMode, postToParent2]);
|
|
26408
|
-
(0, import_react21.useEffect)(() => {
|
|
26409
|
-
if (!isEditMode) return;
|
|
26410
|
-
const deps = {
|
|
26411
|
-
getEditContent: () => editContentRef.current,
|
|
26412
|
-
setEditContent: (next) => {
|
|
26413
|
-
editContentRef.current = next;
|
|
26414
|
-
},
|
|
26415
|
-
applyLinkByKey,
|
|
26416
|
-
postToParent: postToParent2
|
|
26417
|
-
};
|
|
26418
|
-
const onPageMessage = (e) => {
|
|
26419
|
-
if (e.data?.type === "ow:page-created") {
|
|
26420
|
-
const { path, title } = e.data;
|
|
26421
|
-
if (typeof path !== "string" || !path) return;
|
|
26422
|
-
if (addNavLinkForPage({ path, title: typeof title === "string" && title ? title : path }, deps)) {
|
|
26423
|
-
enforceLinkHrefs();
|
|
26424
|
-
}
|
|
26425
|
-
return;
|
|
26426
|
-
}
|
|
26427
|
-
if (e.data?.type === "ow:page-renamed") {
|
|
26428
|
-
const { oldPath, newPath, oldTitle, newTitle } = e.data;
|
|
26429
|
-
if (typeof oldPath !== "string" || typeof newPath !== "string") return;
|
|
26430
|
-
const moved = retargetPageLinks(
|
|
26431
|
-
{
|
|
26432
|
-
oldPath,
|
|
26433
|
-
newPath,
|
|
26434
|
-
oldTitle: typeof oldTitle === "string" ? oldTitle : void 0,
|
|
26435
|
-
newTitle: typeof newTitle === "string" ? newTitle : void 0
|
|
26436
|
-
},
|
|
26437
|
-
deps
|
|
26438
|
-
);
|
|
26439
|
-
if (moved > 0) enforceLinkHrefs();
|
|
26440
|
-
}
|
|
26441
|
-
};
|
|
26442
|
-
window.addEventListener("message", onPageMessage);
|
|
26443
|
-
return () => window.removeEventListener("message", onPageMessage);
|
|
26444
|
-
}, [isEditMode, postToParent2]);
|
|
26445
26234
|
(0, import_react21.useEffect)(() => {
|
|
26446
26235
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
26447
26236
|
void loadAllSectionsManifest().then((manifest) => {
|
|
@@ -27990,7 +27779,6 @@ function OhhwellsBridge() {
|
|
|
27990
27779
|
applyAiFooterFromContent(content);
|
|
27991
27780
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27992
27781
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
27993
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27994
27782
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27995
27783
|
}
|
|
27996
27784
|
applyBrandChrome(content);
|
|
@@ -28001,12 +27789,12 @@ function OhhwellsBridge() {
|
|
|
28001
27789
|
if (key === "__ohw_sections") continue;
|
|
28002
27790
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28003
27791
|
if (key === AI_FOOTER_KEY) continue;
|
|
28004
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28005
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28006
27792
|
if (key === BRAND_KIT_KEY) continue;
|
|
28007
27793
|
if (key === STYLE_STORE_KEY) continue;
|
|
28008
27794
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27795
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28009
27796
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27797
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28010
27798
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28011
27799
|
continue;
|
|
28012
27800
|
}
|
|
@@ -28237,18 +28025,17 @@ function OhhwellsBridge() {
|
|
|
28237
28025
|
}
|
|
28238
28026
|
applyAiFooterFromContent(content);
|
|
28239
28027
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28240
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28241
28028
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28242
28029
|
}
|
|
28243
28030
|
for (const [key, val] of Object.entries(content)) {
|
|
28244
28031
|
if (key === "__ohw_sections") continue;
|
|
28245
28032
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28246
28033
|
if (key === AI_FOOTER_KEY) continue;
|
|
28247
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28248
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28249
28034
|
if (key === BRAND_KIT_KEY) continue;
|
|
28250
28035
|
if (key === STYLE_STORE_KEY) continue;
|
|
28251
28036
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
28037
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28038
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28252
28039
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28253
28040
|
continue;
|
|
28254
28041
|
}
|
|
@@ -28515,11 +28302,26 @@ function OhhwellsBridge() {
|
|
|
28515
28302
|
const t2 = setTimeout(measure, 500);
|
|
28516
28303
|
const ro = new ResizeObserver(schedule);
|
|
28517
28304
|
ro.observe(document.body);
|
|
28305
|
+
let lastWidth = window.innerWidth;
|
|
28306
|
+
let resizeTimers = [];
|
|
28307
|
+
const clearResizeTimers = () => {
|
|
28308
|
+
resizeTimers.forEach(clearTimeout);
|
|
28309
|
+
resizeTimers = [];
|
|
28310
|
+
};
|
|
28311
|
+
const handleResize = () => {
|
|
28312
|
+
if (window.innerWidth === lastWidth) return;
|
|
28313
|
+
lastWidth = window.innerWidth;
|
|
28314
|
+
clearResizeTimers();
|
|
28315
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
28316
|
+
};
|
|
28317
|
+
window.addEventListener("resize", handleResize);
|
|
28518
28318
|
return () => {
|
|
28519
28319
|
clearTimeout(t1);
|
|
28520
28320
|
clearTimeout(t2);
|
|
28521
28321
|
if (raf != null) cancelAnimationFrame(raf);
|
|
28522
28322
|
ro.disconnect();
|
|
28323
|
+
clearResizeTimers();
|
|
28324
|
+
window.removeEventListener("resize", handleResize);
|
|
28523
28325
|
};
|
|
28524
28326
|
}, [pathname, isEditMode, postToParent2]);
|
|
28525
28327
|
(0, import_react21.useEffect)(() => {
|
|
@@ -28816,13 +28618,6 @@ function OhhwellsBridge() {
|
|
|
28816
28618
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
28817
28619
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
28818
28620
|
if (isInsideLinkEditor(target)) return;
|
|
28819
|
-
if (isInsideFloatingPanel(target)) return;
|
|
28820
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28821
|
-
if (target.closest(
|
|
28822
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28823
|
-
)) {
|
|
28824
|
-
return;
|
|
28825
|
-
}
|
|
28826
28621
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
28827
28622
|
clearMediaSelectionRef.current();
|
|
28828
28623
|
}
|
|
@@ -28846,6 +28641,8 @@ function OhhwellsBridge() {
|
|
|
28846
28641
|
return;
|
|
28847
28642
|
}
|
|
28848
28643
|
}
|
|
28644
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28645
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
28849
28646
|
const collectionItem = matchCollectionItemClick(target, collectionItemsRef.current);
|
|
28850
28647
|
if (collectionItem) {
|
|
28851
28648
|
e.preventDefault();
|
|
@@ -28857,6 +28654,11 @@ function OhhwellsBridge() {
|
|
|
28857
28654
|
});
|
|
28858
28655
|
return;
|
|
28859
28656
|
}
|
|
28657
|
+
if (target.closest(
|
|
28658
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28659
|
+
)) {
|
|
28660
|
+
return;
|
|
28661
|
+
}
|
|
28860
28662
|
{
|
|
28861
28663
|
const formEl = getFormElement(target);
|
|
28862
28664
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -29010,13 +28812,9 @@ function OhhwellsBridge() {
|
|
|
29010
28812
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
29011
28813
|
e.preventDefault();
|
|
29012
28814
|
e.stopPropagation();
|
|
28815
|
+
selectIconElementRef.current(editable);
|
|
29013
28816
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
29014
28817
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
29015
|
-
if (aiIcon) {
|
|
29016
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
29017
|
-
} else {
|
|
29018
|
-
selectIconElementRef.current(editable);
|
|
29019
|
-
}
|
|
29020
28818
|
postToParentRef.current({
|
|
29021
28819
|
type: "ow:icon-pick",
|
|
29022
28820
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -29244,9 +29042,6 @@ function OhhwellsBridge() {
|
|
|
29244
29042
|
setHoveredItemRect(null);
|
|
29245
29043
|
hoveredNavContainerRef.current = null;
|
|
29246
29044
|
setHoveredNavContainerRect(null);
|
|
29247
|
-
siblingHintElRef.current = null;
|
|
29248
|
-
setSiblingHintRect(null);
|
|
29249
|
-
setSiblingHintRects([]);
|
|
29250
29045
|
return;
|
|
29251
29046
|
}
|
|
29252
29047
|
{
|
|
@@ -29367,6 +29162,7 @@ function OhhwellsBridge() {
|
|
|
29367
29162
|
hoveredNavContainerRef.current = null;
|
|
29368
29163
|
setHoveredNavContainerRect(null);
|
|
29369
29164
|
hoveredItemElRef.current = editable;
|
|
29165
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
29370
29166
|
}
|
|
29371
29167
|
}
|
|
29372
29168
|
}
|
|
@@ -30076,11 +29872,7 @@ function OhhwellsBridge() {
|
|
|
30076
29872
|
};
|
|
30077
29873
|
const handleMouseMove = (e) => {
|
|
30078
29874
|
const { clientX, clientY } = e;
|
|
30079
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
30080
|
-
dismissImageHover();
|
|
30081
|
-
clearImageHover();
|
|
30082
|
-
return;
|
|
30083
|
-
}
|
|
29875
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
30084
29876
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
30085
29877
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
30086
29878
|
formHoverElRef.current = null;
|
|
@@ -30109,12 +29901,7 @@ function OhhwellsBridge() {
|
|
|
30109
29901
|
setHoveredItemRect(null);
|
|
30110
29902
|
hoveredNavContainerRef.current = null;
|
|
30111
29903
|
setHoveredNavContainerRect(null);
|
|
30112
|
-
siblingHintElRef.current = null;
|
|
30113
|
-
setSiblingHintRect(null);
|
|
30114
|
-
setSiblingHintRects([]);
|
|
30115
29904
|
dismissImageHover();
|
|
30116
|
-
clearImageHover();
|
|
30117
|
-
setSectionGap(null);
|
|
30118
29905
|
return;
|
|
30119
29906
|
}
|
|
30120
29907
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -30126,11 +29913,7 @@ function OhhwellsBridge() {
|
|
|
30126
29913
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
30127
29914
|
const { clientX, clientY } = e.data;
|
|
30128
29915
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
30129
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
30130
|
-
dismissImageHover();
|
|
30131
|
-
clearImageHover();
|
|
30132
|
-
return;
|
|
30133
|
-
}
|
|
29916
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
30134
29917
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
30135
29918
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
30136
29919
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -30510,7 +30293,6 @@ function OhhwellsBridge() {
|
|
|
30510
30293
|
applyAiFooterFromContent(content);
|
|
30511
30294
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
30512
30295
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
30513
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
30514
30296
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
30515
30297
|
}
|
|
30516
30298
|
applyBrandChrome(content);
|
|
@@ -30525,12 +30307,12 @@ function OhhwellsBridge() {
|
|
|
30525
30307
|
}
|
|
30526
30308
|
if (key === AI_SECTIONS_KEY) continue;
|
|
30527
30309
|
if (key === AI_FOOTER_KEY) continue;
|
|
30528
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30529
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30530
30310
|
if (key === BRAND_KIT_KEY) continue;
|
|
30531
30311
|
if (key === STYLE_STORE_KEY) continue;
|
|
30532
30312
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
30313
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30533
30314
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
30315
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30534
30316
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
30535
30317
|
continue;
|
|
30536
30318
|
}
|
|
@@ -31166,12 +30948,6 @@ function OhhwellsBridge() {
|
|
|
31166
30948
|
closeLinkPopoverRef.current();
|
|
31167
30949
|
return;
|
|
31168
30950
|
}
|
|
31169
|
-
if (floatingPanelOpenRef.current) {
|
|
31170
|
-
setFloatingPanelRef.current(null);
|
|
31171
|
-
deselectRef.current();
|
|
31172
|
-
deactivateRef.current();
|
|
31173
|
-
return;
|
|
31174
|
-
}
|
|
31175
30951
|
deselectRef.current();
|
|
31176
30952
|
deactivateRef.current();
|
|
31177
30953
|
clearMediaSelectionRef.current();
|
|
@@ -32001,10 +31777,10 @@ function OhhwellsBridge() {
|
|
|
32001
31777
|
window.removeEventListener("message", handleDuplicateSection);
|
|
32002
31778
|
window.removeEventListener("message", handleDeactivate);
|
|
32003
31779
|
window.removeEventListener("message", handleSelectNav);
|
|
31780
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
32004
31781
|
window.removeEventListener("message", handleToastAction);
|
|
32005
31782
|
window.removeEventListener("message", handleFormCount);
|
|
32006
31783
|
window.removeEventListener("message", handleUiEscape);
|
|
32007
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
32008
31784
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
32009
31785
|
autoSaveTimers.current.clear();
|
|
32010
31786
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -32298,7 +32074,7 @@ function OhhwellsBridge() {
|
|
|
32298
32074
|
postToParent2({
|
|
32299
32075
|
type: "ow:ready",
|
|
32300
32076
|
version: "1",
|
|
32301
|
-
bridgeVersion: "0.1.158
|
|
32077
|
+
bridgeVersion: "0.1.158",
|
|
32302
32078
|
path: pathname,
|
|
32303
32079
|
nodes: collectEditableNodes(editContentRef.current),
|
|
32304
32080
|
sections
|