@ohhwells/bridge 0.1.160-next.429 → 0.1.161
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 +747 -1092
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +770 -1131
- 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.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React12, { useCallback as useCallback12, useEffect as useEffect19, useLayoutEffect as
|
|
4
|
+
import React12, { useCallback as useCallback12, useEffect as useEffect19, useLayoutEffect as useLayoutEffect6, useRef as useRef14, useState as useState18 } from "react";
|
|
5
5
|
import { createRoot as createRoot3 } from "react-dom/client";
|
|
6
6
|
import { flushSync as flushSync3 } from "react-dom";
|
|
7
7
|
|
|
@@ -1094,21 +1094,21 @@ function chromeFrom(sample) {
|
|
|
1094
1094
|
};
|
|
1095
1095
|
}
|
|
1096
1096
|
function filledPrimary(seed) {
|
|
1097
|
-
const
|
|
1098
|
-
const luminance = relativeLuminance(
|
|
1097
|
+
const paint = parseColor(paintColor(seed)) ?? { r: 15, g: 15, b: 15, a: 1 };
|
|
1098
|
+
const luminance = relativeLuminance(paint);
|
|
1099
1099
|
return {
|
|
1100
|
-
background: toCss({ ...
|
|
1100
|
+
background: toCss({ ...paint, a: 1 }),
|
|
1101
1101
|
color: luminance > 0.55 ? "rgb(15, 15, 15)" : "rgb(255, 255, 255)",
|
|
1102
1102
|
borderColor: TRANSPARENT,
|
|
1103
1103
|
borderWidth: "0px"
|
|
1104
1104
|
};
|
|
1105
1105
|
}
|
|
1106
1106
|
function generatedSecondary(primary) {
|
|
1107
|
-
const
|
|
1107
|
+
const paint = accentColor(primary);
|
|
1108
1108
|
return {
|
|
1109
1109
|
background: TRANSPARENT,
|
|
1110
|
-
color:
|
|
1111
|
-
borderColor:
|
|
1110
|
+
color: paint,
|
|
1111
|
+
borderColor: paint,
|
|
1112
1112
|
borderWidth: "1px"
|
|
1113
1113
|
};
|
|
1114
1114
|
}
|
|
@@ -1121,9 +1121,9 @@ function generatedGhost(primary) {
|
|
|
1121
1121
|
};
|
|
1122
1122
|
}
|
|
1123
1123
|
function normalizeOutlineChrome(outline, primary) {
|
|
1124
|
-
const
|
|
1124
|
+
const paint = accentColor(primary);
|
|
1125
1125
|
const text = parseColor(outline.color);
|
|
1126
|
-
const paintRgb = parseColor(
|
|
1126
|
+
const paintRgb = parseColor(paint);
|
|
1127
1127
|
const primaryLabel = parseColor(primary.color);
|
|
1128
1128
|
const matchesOnPrimary = Boolean(text && primaryLabel) && colorKey(outline.color) === colorKey(primary.color);
|
|
1129
1129
|
const textTooLight = text ? relativeLuminance(text) > 0.7 : false;
|
|
@@ -1132,8 +1132,8 @@ function normalizeOutlineChrome(outline, primary) {
|
|
|
1132
1132
|
const hasBorder = parseFloat(outline.borderWidth) > 0;
|
|
1133
1133
|
return {
|
|
1134
1134
|
...outline,
|
|
1135
|
-
color:
|
|
1136
|
-
borderColor: hasBorder ?
|
|
1135
|
+
color: paint,
|
|
1136
|
+
borderColor: hasBorder ? paint : outline.borderColor
|
|
1137
1137
|
};
|
|
1138
1138
|
}
|
|
1139
1139
|
function generateButtonVariants(samples) {
|
|
@@ -6649,21 +6649,6 @@ function pricingCardFeatureCount(tree, index) {
|
|
|
6649
6649
|
const target = findPricingCollection(tree)?.children?.[index];
|
|
6650
6650
|
return target ? pricingFeatureList(target).length : 0;
|
|
6651
6651
|
}
|
|
6652
|
-
function prevailingFeatureIcon(features) {
|
|
6653
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6654
|
-
for (const row of features) {
|
|
6655
|
-
const key = `${row.icon ?? ""}|${row.iconColor ?? ""}`;
|
|
6656
|
-
const entry = counts.get(key) ?? { count: 0, ...row.icon ? { icon: row.icon } : {}, ...row.iconColor ? { iconColor: row.iconColor } : {} };
|
|
6657
|
-
entry.count += 1;
|
|
6658
|
-
counts.set(key, entry);
|
|
6659
|
-
}
|
|
6660
|
-
let best = null;
|
|
6661
|
-
for (const entry of counts.values()) {
|
|
6662
|
-
if (!best || entry.count > best.count) best = entry;
|
|
6663
|
-
}
|
|
6664
|
-
if (!best) return {};
|
|
6665
|
-
return { ...best.icon ? { icon: best.icon } : {}, ...best.iconColor ? { iconColor: best.iconColor } : {} };
|
|
6666
|
-
}
|
|
6667
6652
|
function addPricingCardFeature(tree, index, text) {
|
|
6668
6653
|
return withPricingCollection(tree, (collection) => {
|
|
6669
6654
|
const children = collection.children;
|
|
@@ -6672,7 +6657,7 @@ function addPricingCardFeature(tree, index, text) {
|
|
|
6672
6657
|
const features = pricingFeatureList(target);
|
|
6673
6658
|
if (features.length >= PRICING_FEATURES_MAX) return false;
|
|
6674
6659
|
target.slots = target.slots ?? {};
|
|
6675
|
-
target.slots.features = [...features, { text
|
|
6660
|
+
target.slots.features = [...features, { text }];
|
|
6676
6661
|
return true;
|
|
6677
6662
|
});
|
|
6678
6663
|
}
|
|
@@ -7316,120 +7301,6 @@ function findSelectableNavContainer(doc = document) {
|
|
|
7316
7301
|
);
|
|
7317
7302
|
}
|
|
7318
7303
|
|
|
7319
|
-
// src/lib/youtube.ts
|
|
7320
|
-
var YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
|
|
7321
|
-
function extractYouTubeId(input) {
|
|
7322
|
-
const trimmed = input.trim();
|
|
7323
|
-
if (!trimmed) return null;
|
|
7324
|
-
if (YOUTUBE_ID_PATTERN.test(trimmed)) return trimmed;
|
|
7325
|
-
let url;
|
|
7326
|
-
try {
|
|
7327
|
-
url = new URL(trimmed);
|
|
7328
|
-
} catch {
|
|
7329
|
-
return null;
|
|
7330
|
-
}
|
|
7331
|
-
const host = url.hostname.replace(/^www\./, "");
|
|
7332
|
-
if (host !== "youtube.com" && host !== "m.youtube.com" && host !== "youtu.be" && host !== "youtube-nocookie.com") {
|
|
7333
|
-
return null;
|
|
7334
|
-
}
|
|
7335
|
-
let candidate = null;
|
|
7336
|
-
if (host === "youtu.be") {
|
|
7337
|
-
candidate = url.pathname.slice(1).split("/")[0] ?? null;
|
|
7338
|
-
} else if (url.pathname === "/watch") {
|
|
7339
|
-
candidate = url.searchParams.get("v");
|
|
7340
|
-
} else {
|
|
7341
|
-
const match = url.pathname.match(/^\/(?:embed|shorts)\/([^/]+)/);
|
|
7342
|
-
candidate = match ? match[1] : null;
|
|
7343
|
-
}
|
|
7344
|
-
return candidate && YOUTUBE_ID_PATTERN.test(candidate) ? candidate : null;
|
|
7345
|
-
}
|
|
7346
|
-
|
|
7347
|
-
// src/lib/section-embed.ts
|
|
7348
|
-
var SECTION_EMBED_SUFFIX = "__ohw_embed";
|
|
7349
|
-
function readStoredEmbed(value) {
|
|
7350
|
-
if (value.startsWith("start\n")) {
|
|
7351
|
-
return { raw: value.slice("start\n".length), at: "start" };
|
|
7352
|
-
}
|
|
7353
|
-
return { raw: value, at: "end" };
|
|
7354
|
-
}
|
|
7355
|
-
function embedFrameSrc(value) {
|
|
7356
|
-
const videoId = extractYouTubeId(value);
|
|
7357
|
-
if (videoId) {
|
|
7358
|
-
return { src: `https://www.youtube-nocookie.com/embed/${videoId}?rel=0`, title: "YouTube video" };
|
|
7359
|
-
}
|
|
7360
|
-
let url;
|
|
7361
|
-
try {
|
|
7362
|
-
url = new URL(value);
|
|
7363
|
-
} catch {
|
|
7364
|
-
return null;
|
|
7365
|
-
}
|
|
7366
|
-
const host = url.hostname.replace(/^www\./, "").toLowerCase();
|
|
7367
|
-
if (host === "google.com" && url.pathname.startsWith("/maps") || host === "maps.google.com") {
|
|
7368
|
-
const query = url.searchParams.get("q") || url.searchParams.get("query") || "";
|
|
7369
|
-
const src = query ? `https://maps.google.com/maps?q=${encodeURIComponent(query)}&output=embed` : `https://maps.google.com/maps?output=embed`;
|
|
7370
|
-
return { src, title: "Map" };
|
|
7371
|
-
}
|
|
7372
|
-
if (host === "maps.app.goo.gl") {
|
|
7373
|
-
return { src: value, title: "Map" };
|
|
7374
|
-
}
|
|
7375
|
-
if (host === "calendly.com" || host.endsWith(".calendly.com") || host === "calendar.google.com") {
|
|
7376
|
-
return { src: value, title: "Calendar" };
|
|
7377
|
-
}
|
|
7378
|
-
if (host === "docs.google.com" && url.pathname.includes("/forms/")) {
|
|
7379
|
-
return { src: value.replace(/\/edit(?:\?.*)?$/i, "/viewform"), title: "Form" };
|
|
7380
|
-
}
|
|
7381
|
-
if (host === "forms.gle") {
|
|
7382
|
-
return { src: value, title: "Form" };
|
|
7383
|
-
}
|
|
7384
|
-
return null;
|
|
7385
|
-
}
|
|
7386
|
-
function place(section, box, at) {
|
|
7387
|
-
if (at === "start") {
|
|
7388
|
-
section.insertBefore(box, section.firstChild);
|
|
7389
|
-
return;
|
|
7390
|
-
}
|
|
7391
|
-
section.appendChild(box);
|
|
7392
|
-
}
|
|
7393
|
-
function paint(section, key, src, title, at) {
|
|
7394
|
-
const existing = section.querySelector(`[data-ohw-section-embed="${CSS.escape(key)}"]`);
|
|
7395
|
-
const frame = existing?.querySelector("iframe");
|
|
7396
|
-
if (existing && frame) {
|
|
7397
|
-
if (frame.getAttribute("src") !== src) frame.setAttribute("src", src);
|
|
7398
|
-
frame.title = title;
|
|
7399
|
-
place(section, existing, at);
|
|
7400
|
-
return;
|
|
7401
|
-
}
|
|
7402
|
-
existing?.remove();
|
|
7403
|
-
const box = document.createElement("div");
|
|
7404
|
-
box.setAttribute("data-ohw-section-embed", key);
|
|
7405
|
-
box.style.cssText = at === "start" ? "width:100%;max-width:960px;margin:0 auto 32px;padding:32px 24px 0;box-sizing:border-box;" : "width:100%;max-width:960px;margin:32px auto 0;padding:0 24px 32px;box-sizing:border-box;";
|
|
7406
|
-
const frameWrap = document.createElement("div");
|
|
7407
|
-
frameWrap.style.cssText = "position:relative;width:100%;aspect-ratio:16/9;min-height:250px;border-radius:12px;overflow:hidden;background:#0f172a;";
|
|
7408
|
-
const iframe = document.createElement("iframe");
|
|
7409
|
-
iframe.src = src;
|
|
7410
|
-
iframe.title = title;
|
|
7411
|
-
iframe.style.cssText = "position:absolute;inset:0;width:100%;height:100%;border:0;";
|
|
7412
|
-
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture";
|
|
7413
|
-
iframe.setAttribute("allowfullscreen", "");
|
|
7414
|
-
frameWrap.appendChild(iframe);
|
|
7415
|
-
box.appendChild(frameWrap);
|
|
7416
|
-
place(section, box, at);
|
|
7417
|
-
}
|
|
7418
|
-
function applySectionEmbeds(content) {
|
|
7419
|
-
for (const [key, val] of Object.entries(content)) {
|
|
7420
|
-
if (!key.endsWith(SECTION_EMBED_SUFFIX)) continue;
|
|
7421
|
-
const sectionId = key.slice(0, -SECTION_EMBED_SUFFIX.length);
|
|
7422
|
-
const section = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
|
|
7423
|
-
const stored = typeof val === "string" ? readStoredEmbed(val) : null;
|
|
7424
|
-
const frame = stored ? embedFrameSrc(stored.raw) : null;
|
|
7425
|
-
if (!section || !stored || !frame) {
|
|
7426
|
-
section?.querySelector(`[data-ohw-section-embed="${CSS.escape(key)}"]`)?.remove();
|
|
7427
|
-
continue;
|
|
7428
|
-
}
|
|
7429
|
-
paint(section, key, frame.src, frame.title, stored.at);
|
|
7430
|
-
}
|
|
7431
|
-
}
|
|
7432
|
-
|
|
7433
7304
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
7434
7305
|
import { flushSync } from "react-dom";
|
|
7435
7306
|
import { createRoot } from "react-dom/client";
|
|
@@ -8003,7 +7874,7 @@ var AI_MOBILE_CSS = [
|
|
|
8003
7874
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
8004
7875
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
8005
7876
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
8006
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7877
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-container`.
|
|
8007
7878
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
8008
7879
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
8009
7880
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -8019,10 +7890,8 @@ var AI_MOBILE_CSS = [
|
|
|
8019
7890
|
"[data-ai-section]{overflow-x:hidden}",
|
|
8020
7891
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
8021
7892
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
8022
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
8023
|
-
|
|
8024
|
-
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
8025
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
7893
|
+
// still got a 20px band of section background down both sides on a phone.
|
|
7894
|
+
"[data-ai-container]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
8026
7895
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
8027
7896
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
8028
7897
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -8227,31 +8096,6 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
8227
8096
|
function textAttrs(ctx, path) {
|
|
8228
8097
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
8229
8098
|
}
|
|
8230
|
-
var AI_RESPONSIVE_CSS = [
|
|
8231
|
-
"@media (max-width: 960px) {",
|
|
8232
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
8233
|
-
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
8234
|
-
"}",
|
|
8235
|
-
"@media (max-width: 640px) {",
|
|
8236
|
-
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
8237
|
-
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
8238
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
8239
|
-
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
8240
|
-
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
8241
|
-
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
8242
|
-
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
8243
|
-
// layered text used to be.
|
|
8244
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
8245
|
-
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
8246
|
-
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
8247
|
-
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
8248
|
-
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
8249
|
-
// other rule had already been taught to stand down.
|
|
8250
|
-
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
8251
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
8252
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
8253
|
-
"}"
|
|
8254
|
-
].join("\n");
|
|
8255
8099
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8256
8100
|
function MediaBox({
|
|
8257
8101
|
refValue,
|
|
@@ -8306,7 +8150,7 @@ function MediaBox({
|
|
|
8306
8150
|
position: fill ? "absolute" : void 0,
|
|
8307
8151
|
inset: fill ? 0 : void 0,
|
|
8308
8152
|
width: fill ? "100%" : fixedSize ? "auto" : "100%",
|
|
8309
|
-
height: fill ? "100%" :
|
|
8153
|
+
height: fill ? "100%" : void 0,
|
|
8310
8154
|
aspectRatio: fill ? void 0 : aspectRatio,
|
|
8311
8155
|
minHeight: fill || fixedSize ? void 0 : height ?? (aspectRatio ? void 0 : 180),
|
|
8312
8156
|
borderRadius: radius,
|
|
@@ -9802,7 +9646,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9802
9646
|
return /* @__PURE__ */ jsx(
|
|
9803
9647
|
"div",
|
|
9804
9648
|
{
|
|
9805
|
-
"data-ai-grid":
|
|
9649
|
+
"data-ai-grid": "",
|
|
9806
9650
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9807
9651
|
style: {
|
|
9808
9652
|
display: "grid",
|
|
@@ -10104,7 +9948,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
10104
9948
|
},
|
|
10105
9949
|
children: [
|
|
10106
9950
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
10107
|
-
// The section's `data-ai-
|
|
9951
|
+
// The section's `data-ai-container` gave up its max-width/gutter so the base
|
|
10108
9952
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
10109
9953
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
10110
9954
|
// the full section width instead of reading at the usual content width.
|
|
@@ -10523,7 +10367,6 @@ function AiTreeRenderer({
|
|
|
10523
10367
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
10524
10368
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
10525
10369
|
...bgAttrs,
|
|
10526
|
-
"data-ai-responsive": "",
|
|
10527
10370
|
style: {
|
|
10528
10371
|
position: "relative",
|
|
10529
10372
|
padding: `${padCss} 0`,
|
|
@@ -10537,13 +10380,12 @@ function AiTreeRenderer({
|
|
|
10537
10380
|
...fillHeight ? { display: "grid" } : {}
|
|
10538
10381
|
},
|
|
10539
10382
|
children: [
|
|
10540
|
-
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
10541
|
-
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10542
10383
|
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
10384
|
+
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
10543
10385
|
/* @__PURE__ */ jsx(
|
|
10544
10386
|
"div",
|
|
10545
10387
|
{
|
|
10546
|
-
"data-ai-
|
|
10388
|
+
"data-ai-container": "",
|
|
10547
10389
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
10548
10390
|
style: {
|
|
10549
10391
|
position: "relative",
|
|
@@ -10560,7 +10402,7 @@ function AiTreeRenderer({
|
|
|
10560
10402
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
10561
10403
|
"div",
|
|
10562
10404
|
{
|
|
10563
|
-
"data-ai-
|
|
10405
|
+
"data-ai-row": "",
|
|
10564
10406
|
style: {
|
|
10565
10407
|
display: "grid",
|
|
10566
10408
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -11222,10 +11064,9 @@ function applyAiSectionsToDom(state, options) {
|
|
|
11222
11064
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
11223
11065
|
continue;
|
|
11224
11066
|
}
|
|
11067
|
+
const isNewMount = !existing || !existing.container.isConnected;
|
|
11225
11068
|
let container = existing?.container;
|
|
11226
|
-
let isNewMount = false;
|
|
11227
11069
|
if (!container || !container.isConnected) {
|
|
11228
|
-
isNewMount = true;
|
|
11229
11070
|
existing?.root.unmount();
|
|
11230
11071
|
container?.remove();
|
|
11231
11072
|
container = document.createElement("div");
|
|
@@ -11563,34 +11404,6 @@ function minSpanForFooterBlock(type) {
|
|
|
11563
11404
|
return 3;
|
|
11564
11405
|
}
|
|
11565
11406
|
}
|
|
11566
|
-
function readLiveSocialItems() {
|
|
11567
|
-
const root = getFooterRoot();
|
|
11568
|
-
const row = root?.querySelector("[data-ohw-socials-row]");
|
|
11569
|
-
if (!row) return [];
|
|
11570
|
-
const items = [];
|
|
11571
|
-
for (const anchor of Array.from(row.querySelectorAll("a[href]"))) {
|
|
11572
|
-
const href = anchor.getAttribute("href")?.trim() ?? "";
|
|
11573
|
-
const aria = anchor.getAttribute("aria-label")?.trim().toLowerCase() ?? "";
|
|
11574
|
-
const platform = FOOTER_SOCIAL_PLATFORMS.find((name) => aria === name) ?? FOOTER_SOCIAL_PLATFORMS.find((name) => href.toLowerCase().includes(name));
|
|
11575
|
-
if (!platform || !/^https?:\/\//i.test(href)) continue;
|
|
11576
|
-
items.push({ platform, href });
|
|
11577
|
-
}
|
|
11578
|
-
return items;
|
|
11579
|
-
}
|
|
11580
|
-
function syncSocialRowsFromDom(tree) {
|
|
11581
|
-
const root = getFooterRoot();
|
|
11582
|
-
if (!root) return;
|
|
11583
|
-
const row = root.querySelector("[data-ohw-socials-row]");
|
|
11584
|
-
const live = readLiveSocialItems();
|
|
11585
|
-
if (row && live.length === 0) return;
|
|
11586
|
-
for (const col of tree.columns) {
|
|
11587
|
-
col.blocks = col.blocks.flatMap((block) => {
|
|
11588
|
-
if (block.type !== "social-row") return [block];
|
|
11589
|
-
if (!row) return [];
|
|
11590
|
-
return [{ ...block, items: live.map((item) => ({ platform: item.platform, href: item.href })) }];
|
|
11591
|
-
});
|
|
11592
|
-
}
|
|
11593
|
-
}
|
|
11594
11407
|
function collectBrandBlocks(tree) {
|
|
11595
11408
|
const brand = [];
|
|
11596
11409
|
for (const col of tree.columns) {
|
|
@@ -11836,7 +11649,6 @@ function textOf2(el) {
|
|
|
11836
11649
|
}
|
|
11837
11650
|
function syncFooterTreeLinksFromDom(tree) {
|
|
11838
11651
|
const next = cloneTree(tree);
|
|
11839
|
-
syncSocialRowsFromDom(next);
|
|
11840
11652
|
const domCols = listFooterColumns().map((col) => {
|
|
11841
11653
|
const heading = getFooterColumnHeadingEl(col);
|
|
11842
11654
|
const title = heading ? textOf2(heading) : void 0;
|
|
@@ -17541,7 +17353,7 @@ function apiBase() {
|
|
|
17541
17353
|
function bridgeVersion() {
|
|
17542
17354
|
try {
|
|
17543
17355
|
if (true) {
|
|
17544
|
-
return "0.1.
|
|
17356
|
+
return "0.1.161";
|
|
17545
17357
|
}
|
|
17546
17358
|
} catch {
|
|
17547
17359
|
}
|
|
@@ -17555,7 +17367,7 @@ function stampBridgeVersionOnDocument() {
|
|
|
17555
17367
|
return;
|
|
17556
17368
|
}
|
|
17557
17369
|
try {
|
|
17558
|
-
const v = true ? "0.1.
|
|
17370
|
+
const v = true ? "0.1.161" : "";
|
|
17559
17371
|
if (v) {
|
|
17560
17372
|
document.documentElement.setAttribute("data-ohw-bridge-version", v);
|
|
17561
17373
|
window.__OHW_BRIDGE_VERSION__ = v;
|
|
@@ -18233,7 +18045,6 @@ function MediaOverlay({
|
|
|
18233
18045
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
18234
18046
|
);
|
|
18235
18047
|
}, [isVideo]);
|
|
18236
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
18237
18048
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
18238
18049
|
const box = {
|
|
18239
18050
|
position: "fixed",
|
|
@@ -18332,10 +18143,11 @@ function MediaOverlay({
|
|
|
18332
18143
|
className: "flex items-center justify-center cursor-pointer",
|
|
18333
18144
|
style: {
|
|
18334
18145
|
...box,
|
|
18335
|
-
//
|
|
18336
|
-
//
|
|
18337
|
-
//
|
|
18338
|
-
|
|
18146
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
18147
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
18148
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
18149
|
+
// Replace still works.
|
|
18150
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
18339
18151
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
18340
18152
|
// than hovered. Hover keeps the existing tinted preview.
|
|
18341
18153
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -18362,17 +18174,17 @@ function MediaOverlay({
|
|
|
18362
18174
|
},
|
|
18363
18175
|
children: [
|
|
18364
18176
|
isVideo ? /* @__PURE__ */ jsx17(Film, { size: 14 }) : /* @__PURE__ */ jsx17(ImageIcon, { size: 14 }),
|
|
18365
|
-
|
|
18177
|
+
isVideo ? "Replace video" : "Replace image"
|
|
18366
18178
|
]
|
|
18367
18179
|
}
|
|
18368
18180
|
),
|
|
18369
|
-
|
|
18181
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ jsxs8(
|
|
18370
18182
|
Button,
|
|
18371
18183
|
{
|
|
18372
18184
|
"data-ohw-media-overlay": "",
|
|
18373
18185
|
variant: "outline",
|
|
18374
18186
|
size: "sm",
|
|
18375
|
-
"aria-label":
|
|
18187
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
18376
18188
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
18377
18189
|
style: {
|
|
18378
18190
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -18395,7 +18207,7 @@ function MediaOverlay({
|
|
|
18395
18207
|
},
|
|
18396
18208
|
children: [
|
|
18397
18209
|
isVideo ? /* @__PURE__ */ jsx17(Film, { size: 14 }) : /* @__PURE__ */ jsx17(ImageIcon, { size: 14 }),
|
|
18398
|
-
replaceMode === "full" ?
|
|
18210
|
+
replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
|
|
18399
18211
|
]
|
|
18400
18212
|
}
|
|
18401
18213
|
)
|
|
@@ -18988,24 +18800,8 @@ function AiSectionOverlay({
|
|
|
18988
18800
|
}
|
|
18989
18801
|
|
|
18990
18802
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18991
|
-
import { useCallback as useCallback3, useEffect as useEffect8,
|
|
18992
|
-
import {
|
|
18993
|
-
AlignCenter,
|
|
18994
|
-
AlignLeft,
|
|
18995
|
-
AlignRight,
|
|
18996
|
-
ArrowLeft as ArrowLeft2,
|
|
18997
|
-
ArrowRight as ArrowRight2,
|
|
18998
|
-
Check as Check2,
|
|
18999
|
-
ChevronDown as ChevronDown3,
|
|
19000
|
-
Image as ImageIcon2,
|
|
19001
|
-
ImageMinus,
|
|
19002
|
-
ImagePlus,
|
|
19003
|
-
Link as LinkIcon,
|
|
19004
|
-
Minus,
|
|
19005
|
-
Palette,
|
|
19006
|
-
Plus as Plus2,
|
|
19007
|
-
Star
|
|
19008
|
-
} from "lucide-react";
|
|
18803
|
+
import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef5, useState as useState8 } from "react";
|
|
18804
|
+
import { Star } from "lucide-react";
|
|
19009
18805
|
|
|
19010
18806
|
// src/lib/ai-media-strip-tree.ts
|
|
19011
18807
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -19119,6 +18915,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
19119
18915
|
return true;
|
|
19120
18916
|
});
|
|
19121
18917
|
}
|
|
18918
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
18919
|
+
return withMediaStrip(tree, (block) => {
|
|
18920
|
+
const items = block.items;
|
|
18921
|
+
if (index < 0 || index >= items.length) return false;
|
|
18922
|
+
items[index] = { ...items[index], alt };
|
|
18923
|
+
return true;
|
|
18924
|
+
});
|
|
18925
|
+
}
|
|
19122
18926
|
function setMediaStripItemLink(tree, index, link) {
|
|
19123
18927
|
return withMediaStrip(tree, (block) => {
|
|
19124
18928
|
const items = block.items;
|
|
@@ -19136,117 +18940,11 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
19136
18940
|
});
|
|
19137
18941
|
}
|
|
19138
18942
|
|
|
19139
|
-
// src/ui/dialog.tsx
|
|
19140
|
-
import * as React9 from "react";
|
|
19141
|
-
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
19142
|
-
import { X as X2 } from "lucide-react";
|
|
19143
|
-
import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
19144
|
-
function Dialog2({
|
|
19145
|
-
...props
|
|
19146
|
-
}) {
|
|
19147
|
-
return /* @__PURE__ */ jsx20(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
19148
|
-
}
|
|
19149
|
-
function DialogPortal({
|
|
19150
|
-
...props
|
|
19151
|
-
}) {
|
|
19152
|
-
return /* @__PURE__ */ jsx20(DialogPrimitive.Portal, { ...props });
|
|
19153
|
-
}
|
|
19154
|
-
function DialogOverlay({
|
|
19155
|
-
className,
|
|
19156
|
-
...props
|
|
19157
|
-
}) {
|
|
19158
|
-
return /* @__PURE__ */ jsx20(
|
|
19159
|
-
DialogPrimitive.Overlay,
|
|
19160
|
-
{
|
|
19161
|
-
"data-slot": "dialog-overlay",
|
|
19162
|
-
"data-ohw-link-modal-root": "",
|
|
19163
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
19164
|
-
...props
|
|
19165
|
-
}
|
|
19166
|
-
);
|
|
19167
|
-
}
|
|
19168
|
-
var DialogContent = React9.forwardRef(
|
|
19169
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
19170
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
19171
|
-
return /* @__PURE__ */ jsxs11(DialogPortal, { container: container ?? void 0, children: [
|
|
19172
|
-
/* @__PURE__ */ jsx20(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
19173
|
-
/* @__PURE__ */ jsxs11(
|
|
19174
|
-
DialogPrimitive.Content,
|
|
19175
|
-
{
|
|
19176
|
-
ref,
|
|
19177
|
-
"data-slot": "dialog-content",
|
|
19178
|
-
className: cn(
|
|
19179
|
-
positionMode,
|
|
19180
|
-
"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",
|
|
19181
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
19182
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
19183
|
-
className
|
|
19184
|
-
),
|
|
19185
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
19186
|
-
...props,
|
|
19187
|
-
children: [
|
|
19188
|
-
children,
|
|
19189
|
-
showCloseButton ? /* @__PURE__ */ jsx20(
|
|
19190
|
-
DialogPrimitive.Close,
|
|
19191
|
-
{
|
|
19192
|
-
type: "button",
|
|
19193
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
19194
|
-
"aria-label": "Close",
|
|
19195
|
-
children: /* @__PURE__ */ jsx20(X2, { size: 16, "aria-hidden": true })
|
|
19196
|
-
}
|
|
19197
|
-
) : null
|
|
19198
|
-
]
|
|
19199
|
-
}
|
|
19200
|
-
)
|
|
19201
|
-
] });
|
|
19202
|
-
}
|
|
19203
|
-
);
|
|
19204
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
19205
|
-
function DialogHeader({
|
|
19206
|
-
className,
|
|
19207
|
-
...props
|
|
19208
|
-
}) {
|
|
19209
|
-
return /* @__PURE__ */ jsx20("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
19210
|
-
}
|
|
19211
|
-
function DialogFooter({
|
|
19212
|
-
className,
|
|
19213
|
-
...props
|
|
19214
|
-
}) {
|
|
19215
|
-
return /* @__PURE__ */ jsx20(
|
|
19216
|
-
"div",
|
|
19217
|
-
{
|
|
19218
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
19219
|
-
...props
|
|
19220
|
-
}
|
|
19221
|
-
);
|
|
19222
|
-
}
|
|
19223
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
|
|
19224
|
-
DialogPrimitive.Title,
|
|
19225
|
-
{
|
|
19226
|
-
ref,
|
|
19227
|
-
className: cn(
|
|
19228
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
19229
|
-
className
|
|
19230
|
-
),
|
|
19231
|
-
...props
|
|
19232
|
-
}
|
|
19233
|
-
));
|
|
19234
|
-
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
19235
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
|
|
19236
|
-
DialogPrimitive.Description,
|
|
19237
|
-
{
|
|
19238
|
-
ref,
|
|
19239
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
19240
|
-
...props
|
|
19241
|
-
}
|
|
19242
|
-
));
|
|
19243
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
19244
|
-
var DialogClose = DialogPrimitive.Close;
|
|
19245
|
-
|
|
19246
18943
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
19247
|
-
import { Fragment as Fragment7, jsx as
|
|
19248
|
-
var PRIMARY3 = "
|
|
19249
|
-
var
|
|
18944
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
18945
|
+
var PRIMARY3 = "#0885FE";
|
|
18946
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY3})`;
|
|
18947
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY3}) 60%, #000000)`;
|
|
19250
18948
|
function findMediaStripItemElement(sectionId, index) {
|
|
19251
18949
|
const sectionEl = findByInstanceId(sectionId);
|
|
19252
18950
|
if (!sectionEl) return null;
|
|
@@ -19256,35 +18954,14 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
19256
18954
|
}
|
|
19257
18955
|
return null;
|
|
19258
18956
|
}
|
|
19259
|
-
function
|
|
19260
|
-
|
|
19261
|
-
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19262
|
-
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
19263
|
-
if (!itemEl) return null;
|
|
19264
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
19265
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
19266
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
19267
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
19268
|
-
if (!sectionId || Number.isNaN(index)) return null;
|
|
19269
|
-
return { sectionId, index };
|
|
19270
|
-
}
|
|
19271
|
-
function sameRef(a, b) {
|
|
19272
|
-
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19273
|
-
}
|
|
19274
|
-
function rectOf(el) {
|
|
18957
|
+
function readRect2(ref) {
|
|
18958
|
+
const el = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
19275
18959
|
if (!el) return null;
|
|
19276
18960
|
const r2 = el.getBoundingClientRect();
|
|
19277
18961
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19278
18962
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19279
18963
|
}
|
|
19280
|
-
function
|
|
19281
|
-
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
19282
|
-
}
|
|
19283
|
-
function readStripRect(ref) {
|
|
19284
|
-
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
19285
|
-
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
19286
|
-
}
|
|
19287
|
-
function useLiveItemRect(ref, strip = false) {
|
|
18964
|
+
function useLiveItemRect(ref) {
|
|
19288
18965
|
const [rect, setRect] = useState8(null);
|
|
19289
18966
|
useEffect8(() => {
|
|
19290
18967
|
if (!ref) {
|
|
@@ -19292,7 +18969,7 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
19292
18969
|
return;
|
|
19293
18970
|
}
|
|
19294
18971
|
const update = () => {
|
|
19295
|
-
const next =
|
|
18972
|
+
const next = readRect2(ref);
|
|
19296
18973
|
setRect(
|
|
19297
18974
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
19298
18975
|
);
|
|
@@ -19307,49 +18984,9 @@ function useLiveItemRect(ref, strip = false) {
|
|
|
19307
18984
|
window.removeEventListener("resize", update);
|
|
19308
18985
|
clearInterval(interval);
|
|
19309
18986
|
};
|
|
19310
|
-
}, [ref?.sectionId, ref?.index
|
|
18987
|
+
}, [ref?.sectionId, ref?.index]);
|
|
19311
18988
|
return rect;
|
|
19312
18989
|
}
|
|
19313
|
-
var TOOLBAR_STRIP_GAP = 52;
|
|
19314
|
-
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
19315
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19316
|
-
function StripToolbarSlot({ stripRect, children }) {
|
|
19317
|
-
const slotRef = useRef5(null);
|
|
19318
|
-
const [shift, setShift] = useState8(0);
|
|
19319
|
-
const centerX = stripRect.left + stripRect.width / 2;
|
|
19320
|
-
useLayoutEffect4(() => {
|
|
19321
|
-
const slot = slotRef.current;
|
|
19322
|
-
if (!slot) return;
|
|
19323
|
-
const clamp = () => {
|
|
19324
|
-
const w = slot.offsetWidth;
|
|
19325
|
-
if (w <= 0) return;
|
|
19326
|
-
const half = w / 2;
|
|
19327
|
-
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19328
|
-
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19329
|
-
};
|
|
19330
|
-
clamp();
|
|
19331
|
-
const ro = new ResizeObserver(clamp);
|
|
19332
|
-
ro.observe(slot);
|
|
19333
|
-
return () => ro.disconnect();
|
|
19334
|
-
}, [centerX, children]);
|
|
19335
|
-
const mobile = window.innerWidth <= 480;
|
|
19336
|
-
return /* @__PURE__ */ jsx21(
|
|
19337
|
-
"div",
|
|
19338
|
-
{
|
|
19339
|
-
ref: slotRef,
|
|
19340
|
-
"data-ohw-bridge": "",
|
|
19341
|
-
"data-ohw-item-interaction": "",
|
|
19342
|
-
className: "pointer-events-auto fixed",
|
|
19343
|
-
style: {
|
|
19344
|
-
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
19345
|
-
left: centerX + shift,
|
|
19346
|
-
transform: "translate(-50%, -100%)",
|
|
19347
|
-
zIndex: 2147483645
|
|
19348
|
-
},
|
|
19349
|
-
children
|
|
19350
|
-
}
|
|
19351
|
-
);
|
|
19352
|
-
}
|
|
19353
18990
|
function requestValidateTree(postToParent2, tree) {
|
|
19354
18991
|
return new Promise((resolve) => {
|
|
19355
18992
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -19386,72 +19023,116 @@ function requestAssetPick(postToParent2) {
|
|
|
19386
19023
|
postToParent2({ type: "ow:asset-pick", id });
|
|
19387
19024
|
});
|
|
19388
19025
|
}
|
|
19389
|
-
function
|
|
19026
|
+
function Pill({
|
|
19390
19027
|
label,
|
|
19391
19028
|
onClick,
|
|
19392
|
-
disabled
|
|
19393
|
-
active
|
|
19394
|
-
children
|
|
19395
|
-
}) {
|
|
19396
|
-
const button = /* @__PURE__ */ jsx21(CustomToolbarButton, { type: "button", "aria-label": label, disabled, active, onClick, className: "size-8", children });
|
|
19397
|
-
return /* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19398
|
-
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: button }) : button }),
|
|
19399
|
-
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
19400
|
-
] });
|
|
19401
|
-
}
|
|
19402
|
-
function ToolbarSeparator() {
|
|
19403
|
-
return /* @__PURE__ */ jsx21("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
19404
|
-
}
|
|
19405
|
-
function OptionMenu({
|
|
19406
|
-
label,
|
|
19407
|
-
value,
|
|
19408
|
-
options,
|
|
19409
|
-
onChange
|
|
19029
|
+
disabled,
|
|
19030
|
+
active
|
|
19410
19031
|
}) {
|
|
19411
|
-
|
|
19412
|
-
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
|
|
19421
|
-
|
|
19422
|
-
|
|
19423
|
-
|
|
19424
|
-
|
|
19425
|
-
|
|
19426
|
-
|
|
19427
|
-
|
|
19428
|
-
|
|
19429
|
-
|
|
19430
|
-
|
|
19431
|
-
|
|
19432
|
-
|
|
19433
|
-
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19438
|
-
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
|
|
19032
|
+
return /* @__PURE__ */ jsx20(
|
|
19033
|
+
"button",
|
|
19034
|
+
{
|
|
19035
|
+
type: "button",
|
|
19036
|
+
onClick,
|
|
19037
|
+
disabled,
|
|
19038
|
+
style: {
|
|
19039
|
+
height: 28,
|
|
19040
|
+
padding: "0 10px",
|
|
19041
|
+
display: "inline-flex",
|
|
19042
|
+
alignItems: "center",
|
|
19043
|
+
gap: 4,
|
|
19044
|
+
borderRadius: 999,
|
|
19045
|
+
border: "none",
|
|
19046
|
+
cursor: disabled ? "default" : "pointer",
|
|
19047
|
+
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
19048
|
+
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
19049
|
+
opacity: disabled ? 0.4 : 1,
|
|
19050
|
+
fontSize: 12,
|
|
19051
|
+
lineHeight: "16px",
|
|
19052
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19053
|
+
whiteSpace: "nowrap",
|
|
19054
|
+
flex: "0 0 auto"
|
|
19055
|
+
},
|
|
19056
|
+
children: label
|
|
19057
|
+
}
|
|
19058
|
+
);
|
|
19059
|
+
}
|
|
19060
|
+
function AltInput({ value, onCommit }) {
|
|
19061
|
+
const [draft, setDraft] = useState8(value);
|
|
19062
|
+
useEffect8(() => setDraft(value), [value]);
|
|
19063
|
+
return /* @__PURE__ */ jsxs11(
|
|
19064
|
+
"div",
|
|
19065
|
+
{
|
|
19066
|
+
style: {
|
|
19067
|
+
display: "flex",
|
|
19068
|
+
alignItems: "center",
|
|
19069
|
+
gap: 6,
|
|
19070
|
+
height: 28,
|
|
19071
|
+
padding: "0 12px",
|
|
19072
|
+
borderRadius: 999,
|
|
19073
|
+
background: "#ffffff",
|
|
19074
|
+
width: "100%",
|
|
19075
|
+
maxWidth: 260,
|
|
19076
|
+
boxSizing: "border-box"
|
|
19077
|
+
},
|
|
19078
|
+
children: [
|
|
19079
|
+
/* @__PURE__ */ jsx20(
|
|
19080
|
+
"span",
|
|
19081
|
+
{
|
|
19082
|
+
style: {
|
|
19083
|
+
flex: "0 0 auto",
|
|
19084
|
+
color: OHW_BLUE_DARK,
|
|
19085
|
+
fontSize: 10,
|
|
19086
|
+
fontWeight: 700,
|
|
19087
|
+
textTransform: "uppercase",
|
|
19088
|
+
letterSpacing: 0.4
|
|
19089
|
+
},
|
|
19090
|
+
children: "Alt"
|
|
19091
|
+
}
|
|
19092
|
+
),
|
|
19093
|
+
/* @__PURE__ */ jsx20(
|
|
19094
|
+
"input",
|
|
19095
|
+
{
|
|
19096
|
+
type: "text",
|
|
19097
|
+
value: draft,
|
|
19098
|
+
onChange: (e) => setDraft(e.target.value),
|
|
19099
|
+
onBlur: () => {
|
|
19100
|
+
if (draft !== value) onCommit(draft);
|
|
19101
|
+
},
|
|
19102
|
+
onKeyDown: (e) => {
|
|
19103
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
19104
|
+
if (e.key === "Escape") {
|
|
19105
|
+
setDraft(value);
|
|
19106
|
+
e.currentTarget.blur();
|
|
19107
|
+
}
|
|
19108
|
+
},
|
|
19109
|
+
placeholder: "Describe this image",
|
|
19110
|
+
"aria-label": "Image alt text",
|
|
19111
|
+
style: {
|
|
19112
|
+
flex: 1,
|
|
19113
|
+
minWidth: 0,
|
|
19114
|
+
border: "none",
|
|
19115
|
+
outline: "none",
|
|
19116
|
+
background: "transparent",
|
|
19117
|
+
fontSize: 12,
|
|
19118
|
+
lineHeight: "16px",
|
|
19119
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19120
|
+
color: "#1f2937"
|
|
19121
|
+
}
|
|
19122
|
+
}
|
|
19123
|
+
)
|
|
19124
|
+
]
|
|
19125
|
+
}
|
|
19126
|
+
);
|
|
19446
19127
|
}
|
|
19447
19128
|
var VARIANTS = [
|
|
19448
19129
|
{ value: "logos", label: "Logos" },
|
|
19449
19130
|
{ value: "reel", label: "Reel" }
|
|
19450
19131
|
];
|
|
19451
19132
|
var ALIGNS = [
|
|
19452
|
-
{ value: "left", label: "
|
|
19453
|
-
{ value: "center", label: "
|
|
19454
|
-
{ value: "right", label: "
|
|
19133
|
+
{ value: "left", label: "Left" },
|
|
19134
|
+
{ value: "center", label: "Center" },
|
|
19135
|
+
{ value: "right", label: "Right" }
|
|
19455
19136
|
];
|
|
19456
19137
|
var HOVERS = [
|
|
19457
19138
|
{ value: "none", label: "None" },
|
|
@@ -19459,104 +19140,104 @@ var HOVERS = [
|
|
|
19459
19140
|
{ value: "zoom", label: "Zoom" },
|
|
19460
19141
|
{ value: "fade", label: "Fade" }
|
|
19461
19142
|
];
|
|
19143
|
+
var TREATMENTS = [
|
|
19144
|
+
{ value: "color", label: "Color" },
|
|
19145
|
+
{ value: "grayscale", label: "Grayscale" }
|
|
19146
|
+
];
|
|
19462
19147
|
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
19463
|
-
function
|
|
19464
|
-
|
|
19465
|
-
linkTarget,
|
|
19466
|
-
onClose,
|
|
19467
|
-
onSave
|
|
19468
|
-
}) {
|
|
19469
|
-
const [draft, setDraft] = useState8(href);
|
|
19470
|
-
const [newTab, setNewTab] = useState8(linkTarget !== "same-tab");
|
|
19148
|
+
function LinkInput({ value, onCommit }) {
|
|
19149
|
+
const [draft, setDraft] = useState8(value);
|
|
19471
19150
|
const [invalid, setInvalid] = useState8(false);
|
|
19472
|
-
|
|
19151
|
+
useEffect8(() => {
|
|
19152
|
+
setDraft(value);
|
|
19153
|
+
setInvalid(false);
|
|
19154
|
+
}, [value]);
|
|
19155
|
+
const commit = () => {
|
|
19473
19156
|
const next = draft.trim();
|
|
19474
|
-
if (next
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
|
|
19478
|
-
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
19479
|
-
onClose();
|
|
19157
|
+
if (next === value) return setInvalid(false);
|
|
19158
|
+
if (next && !HTTP_URL_RE.test(next)) return setInvalid(true);
|
|
19159
|
+
setInvalid(false);
|
|
19160
|
+
onCommit(next);
|
|
19480
19161
|
};
|
|
19481
|
-
return /* @__PURE__ */
|
|
19482
|
-
|
|
19483
|
-
|
|
19484
|
-
|
|
19485
|
-
"
|
|
19486
|
-
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
|
|
19498
|
-
|
|
19499
|
-
"
|
|
19500
|
-
|
|
19501
|
-
|
|
19502
|
-
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
|
|
19515
|
-
|
|
19516
|
-
|
|
19517
|
-
|
|
19518
|
-
|
|
19519
|
-
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
|
|
19524
|
-
|
|
19525
|
-
|
|
19526
|
-
|
|
19527
|
-
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
19545
|
-
|
|
19162
|
+
return /* @__PURE__ */ jsxs11(
|
|
19163
|
+
"div",
|
|
19164
|
+
{
|
|
19165
|
+
style: {
|
|
19166
|
+
display: "flex",
|
|
19167
|
+
alignItems: "center",
|
|
19168
|
+
gap: 6,
|
|
19169
|
+
height: 28,
|
|
19170
|
+
padding: "0 12px",
|
|
19171
|
+
borderRadius: 999,
|
|
19172
|
+
background: "#ffffff",
|
|
19173
|
+
width: "100%",
|
|
19174
|
+
maxWidth: 260,
|
|
19175
|
+
boxSizing: "border-box",
|
|
19176
|
+
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19177
|
+
},
|
|
19178
|
+
children: [
|
|
19179
|
+
/* @__PURE__ */ jsx20(
|
|
19180
|
+
"span",
|
|
19181
|
+
{
|
|
19182
|
+
style: {
|
|
19183
|
+
flex: "0 0 auto",
|
|
19184
|
+
color: OHW_BLUE_DARK,
|
|
19185
|
+
fontSize: 10,
|
|
19186
|
+
fontWeight: 700,
|
|
19187
|
+
textTransform: "uppercase",
|
|
19188
|
+
letterSpacing: 0.4
|
|
19189
|
+
},
|
|
19190
|
+
children: "Link"
|
|
19191
|
+
}
|
|
19192
|
+
),
|
|
19193
|
+
/* @__PURE__ */ jsx20(
|
|
19194
|
+
"input",
|
|
19195
|
+
{
|
|
19196
|
+
type: "text",
|
|
19197
|
+
inputMode: "url",
|
|
19198
|
+
value: draft,
|
|
19199
|
+
onChange: (e) => setDraft(e.target.value),
|
|
19200
|
+
onBlur: commit,
|
|
19201
|
+
onKeyDown: (e) => {
|
|
19202
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
19203
|
+
if (e.key === "Escape") {
|
|
19204
|
+
setDraft(value);
|
|
19205
|
+
setInvalid(false);
|
|
19206
|
+
e.currentTarget.blur();
|
|
19207
|
+
}
|
|
19208
|
+
},
|
|
19209
|
+
placeholder: "https://example.com",
|
|
19210
|
+
"aria-label": "Image link URL",
|
|
19211
|
+
"aria-invalid": invalid,
|
|
19212
|
+
style: {
|
|
19213
|
+
flex: 1,
|
|
19214
|
+
minWidth: 0,
|
|
19215
|
+
border: "none",
|
|
19216
|
+
outline: "none",
|
|
19217
|
+
background: "transparent",
|
|
19218
|
+
fontSize: 12,
|
|
19219
|
+
lineHeight: "16px",
|
|
19220
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
19221
|
+
color: "#1f2937"
|
|
19222
|
+
}
|
|
19223
|
+
}
|
|
19224
|
+
)
|
|
19225
|
+
]
|
|
19226
|
+
}
|
|
19227
|
+
);
|
|
19546
19228
|
}
|
|
19547
19229
|
function MediaStripToolbar({
|
|
19548
19230
|
entry,
|
|
19549
19231
|
index,
|
|
19550
19232
|
pending,
|
|
19551
19233
|
error,
|
|
19552
|
-
itemEditOn,
|
|
19553
|
-
onToggleItemEdit,
|
|
19554
19234
|
onSetVariant,
|
|
19555
19235
|
onSetAlign,
|
|
19556
19236
|
onSetHover,
|
|
19557
19237
|
onSetTreatment,
|
|
19558
19238
|
onResize,
|
|
19559
|
-
|
|
19239
|
+
onSetAlt,
|
|
19240
|
+
onSetLink,
|
|
19560
19241
|
onAddItem,
|
|
19561
19242
|
onRemoveItem,
|
|
19562
19243
|
onChangeImage,
|
|
@@ -19565,102 +19246,81 @@ function MediaStripToolbar({
|
|
|
19565
19246
|
}) {
|
|
19566
19247
|
const items = mediaStripItems(entry.tree);
|
|
19567
19248
|
const itemCount = items.length;
|
|
19249
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
19250
|
+
const currentHref = items[index]?.href ?? "";
|
|
19251
|
+
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
19568
19252
|
const slots = findMediaStripSlots(entry.tree);
|
|
19569
19253
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
19570
19254
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
19571
19255
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
19572
19256
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
19573
19257
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
19574
|
-
const
|
|
19575
|
-
const
|
|
19576
|
-
|
|
19258
|
+
const isMobile = window.innerWidth <= 480;
|
|
19259
|
+
const rowStyle = isMobile ? {
|
|
19260
|
+
display: "flex",
|
|
19261
|
+
gap: 6,
|
|
19262
|
+
flexWrap: "nowrap",
|
|
19263
|
+
justifyContent: "center",
|
|
19264
|
+
overflowX: "auto",
|
|
19265
|
+
WebkitOverflowScrolling: "touch",
|
|
19266
|
+
width: "100%",
|
|
19267
|
+
scrollbarWidth: "none"
|
|
19268
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
19269
|
+
return /* @__PURE__ */ jsxs11(
|
|
19577
19270
|
"div",
|
|
19578
19271
|
{
|
|
19579
19272
|
"data-ohw-bridge": "",
|
|
19580
19273
|
"data-ohw-toolbar": "",
|
|
19581
19274
|
onMouseDown: (e) => e.stopPropagation(),
|
|
19582
|
-
|
|
19583
|
-
|
|
19275
|
+
style: {
|
|
19276
|
+
display: "flex",
|
|
19277
|
+
flexDirection: "column",
|
|
19278
|
+
gap: 6,
|
|
19279
|
+
alignItems: "center",
|
|
19280
|
+
background: OHW_BLUE,
|
|
19281
|
+
padding: 8,
|
|
19282
|
+
borderRadius: 12,
|
|
19283
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
19284
|
+
pointerEvents: pending ? "none" : "auto",
|
|
19285
|
+
opacity: pending ? 0.6 : 1,
|
|
19286
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
19287
|
+
},
|
|
19584
19288
|
children: [
|
|
19585
|
-
/* @__PURE__ */
|
|
19586
|
-
|
|
19587
|
-
{
|
|
19588
|
-
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
|
|
19596
|
-
|
|
19597
|
-
|
|
19598
|
-
|
|
19599
|
-
|
|
19600
|
-
|
|
19601
|
-
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19614
|
-
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
) }),
|
|
19618
|
-
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
19619
|
-
] }),
|
|
19620
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19621
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ jsx21(ImageIcon2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19622
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ jsx21(LinkIcon, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19623
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ jsx21(ArrowLeft2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19624
|
-
/* @__PURE__ */ jsx21(
|
|
19625
|
-
ToolbarAction,
|
|
19626
|
-
{
|
|
19627
|
-
label: gatedLabel("Move right"),
|
|
19628
|
-
onClick: onMoveRight,
|
|
19629
|
-
disabled: !itemEditOn || index >= itemCount - 1,
|
|
19630
|
-
children: /* @__PURE__ */ jsx21(ArrowRight2, { size: 16, style: { pointerEvents: "none" } })
|
|
19631
|
-
}
|
|
19632
|
-
),
|
|
19633
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ jsx21(ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19634
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19635
|
-
/* @__PURE__ */ jsx21(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
19636
|
-
/* @__PURE__ */ jsx21(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
19637
|
-
/* @__PURE__ */ jsx21(
|
|
19638
|
-
ToolbarAction,
|
|
19639
|
-
{
|
|
19640
|
-
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
19641
|
-
active: treatment === "grayscale",
|
|
19642
|
-
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
19643
|
-
children: /* @__PURE__ */ jsx21(Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
19644
|
-
}
|
|
19645
|
-
),
|
|
19646
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19647
|
-
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx21(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ jsx21(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
19648
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19649
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ jsx21(Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19650
|
-
/* @__PURE__ */ jsxs12("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
19651
|
-
sizeValue,
|
|
19652
|
-
"px"
|
|
19653
|
-
] }),
|
|
19654
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ jsx21(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19655
|
-
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19656
|
-
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ jsx21(ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19657
|
-
]
|
|
19658
|
-
}
|
|
19659
|
-
),
|
|
19660
|
-
error && /* @__PURE__ */ jsx21("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19289
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
19290
|
+
VARIANTS.map((v) => /* @__PURE__ */ jsx20(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
19291
|
+
ALIGNS.map((a) => /* @__PURE__ */ jsx20(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
19292
|
+
] }),
|
|
19293
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
19294
|
+
HOVERS.map((h) => /* @__PURE__ */ jsx20(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
19295
|
+
TREATMENTS.map((t) => /* @__PURE__ */ jsx20(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
19296
|
+
] }),
|
|
19297
|
+
/* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
19298
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2212", onClick: () => onResize(-8) }),
|
|
19299
|
+
/* @__PURE__ */ jsxs11("span", { style: { color: "#ffffff", fontSize: 12, minWidth: 34, textAlign: "center" }, children: [
|
|
19300
|
+
sizeValue,
|
|
19301
|
+
"px"
|
|
19302
|
+
] }),
|
|
19303
|
+
/* @__PURE__ */ jsx20(Pill, { label: "+", onClick: () => onResize(8) })
|
|
19304
|
+
] }),
|
|
19305
|
+
/* @__PURE__ */ jsx20("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ jsx20(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
19306
|
+
/* @__PURE__ */ jsx20("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ jsx20(LinkInput, { value: currentHref, onCommit: (href) => onSetLink(href, currentTarget) }) }),
|
|
19307
|
+
currentHref && /* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
19308
|
+
/* @__PURE__ */ jsx20(Pill, { label: "New tab", active: currentTarget === "new-tab", onClick: () => onSetLink(currentHref, "new-tab") }),
|
|
19309
|
+
/* @__PURE__ */ jsx20(Pill, { label: "Same tab", active: currentTarget === "same-tab", onClick: () => onSetLink(currentHref, "same-tab") })
|
|
19310
|
+
] }),
|
|
19311
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
19312
|
+
/* @__PURE__ */ jsx20(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
19313
|
+
/* @__PURE__ */ jsx20(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
19314
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
19315
|
+
] }),
|
|
19316
|
+
/* @__PURE__ */ jsxs11("div", { style: rowStyle, children: [
|
|
19317
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
19318
|
+
/* @__PURE__ */ jsx20(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
19319
|
+
] }),
|
|
19320
|
+
error && /* @__PURE__ */ jsx20("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19661
19321
|
]
|
|
19662
19322
|
}
|
|
19663
|
-
)
|
|
19323
|
+
);
|
|
19664
19324
|
}
|
|
19665
19325
|
function findMediaStripSlots(tree) {
|
|
19666
19326
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -19679,23 +19339,31 @@ function AiMediaStripOverlay({
|
|
|
19679
19339
|
}) {
|
|
19680
19340
|
const [hover, setHover] = useState8(null);
|
|
19681
19341
|
const [active, setActive] = useState8(null);
|
|
19682
|
-
const [itemEditOn, setItemEditOn] = useState8(false);
|
|
19683
|
-
const [linkOpen, setLinkOpen] = useState8(false);
|
|
19684
19342
|
const [pending, setPending] = useState8(false);
|
|
19685
19343
|
const [error, setError] = useState8(null);
|
|
19686
19344
|
const activeRef = useRef5(null);
|
|
19687
19345
|
activeRef.current = active;
|
|
19688
|
-
const linkOpenRef = useRef5(false);
|
|
19689
|
-
linkOpenRef.current = linkOpen;
|
|
19690
19346
|
useEffect8(() => {
|
|
19691
19347
|
const onMove = (e) => {
|
|
19692
|
-
const ref = itemRefFromTarget(e.target);
|
|
19693
19348
|
const t = e.target;
|
|
19694
|
-
|
|
19695
|
-
|
|
19696
|
-
|
|
19697
|
-
|
|
19698
|
-
|
|
19349
|
+
if (!(t instanceof HTMLElement)) return;
|
|
19350
|
+
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]")) {
|
|
19351
|
+
return;
|
|
19352
|
+
}
|
|
19353
|
+
const itemEl = t.closest("[data-ohw-media-strip-item]");
|
|
19354
|
+
if (!itemEl) {
|
|
19355
|
+
setHover(null);
|
|
19356
|
+
return;
|
|
19357
|
+
}
|
|
19358
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
19359
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
19360
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
19361
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
19362
|
+
if (!sectionId || Number.isNaN(index)) {
|
|
19363
|
+
setHover(null);
|
|
19364
|
+
return;
|
|
19365
|
+
}
|
|
19366
|
+
setHover({ sectionId, index });
|
|
19699
19367
|
};
|
|
19700
19368
|
const onLeave = () => setHover(null);
|
|
19701
19369
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -19707,25 +19375,23 @@ function AiMediaStripOverlay({
|
|
|
19707
19375
|
}, []);
|
|
19708
19376
|
useEffect8(() => {
|
|
19709
19377
|
const onClick = (e) => {
|
|
19378
|
+
const current = activeRef.current;
|
|
19379
|
+
if (!current) return;
|
|
19710
19380
|
const t = e.target;
|
|
19711
|
-
if (!(t instanceof
|
|
19712
|
-
if (t.closest(
|
|
19713
|
-
const
|
|
19714
|
-
if (
|
|
19715
|
-
|
|
19716
|
-
setItemEditOn(false);
|
|
19381
|
+
if (!(t instanceof HTMLElement)) return;
|
|
19382
|
+
if (t.closest("[data-ohw-item-interaction]")) return;
|
|
19383
|
+
const itemEl = findMediaStripItemElement(current.sectionId, current.index);
|
|
19384
|
+
if (itemEl && itemEl.contains(t)) return;
|
|
19385
|
+
setActive(null);
|
|
19717
19386
|
setError(null);
|
|
19718
|
-
setActive(ref);
|
|
19719
19387
|
};
|
|
19720
19388
|
document.addEventListener("click", onClick, true);
|
|
19721
19389
|
return () => document.removeEventListener("click", onClick, true);
|
|
19722
|
-
}, [
|
|
19390
|
+
}, []);
|
|
19723
19391
|
useEffect8(() => {
|
|
19724
19392
|
const onBlur = () => {
|
|
19725
19393
|
if (!activeRef.current) return;
|
|
19726
19394
|
setActive(null);
|
|
19727
|
-
setItemEditOn(false);
|
|
19728
|
-
setLinkOpen(false);
|
|
19729
19395
|
setError(null);
|
|
19730
19396
|
};
|
|
19731
19397
|
window.addEventListener("blur", onBlur);
|
|
@@ -19735,10 +19401,7 @@ function AiMediaStripOverlay({
|
|
|
19735
19401
|
const onKeyDown = (e) => {
|
|
19736
19402
|
if (e.key !== "Escape") return;
|
|
19737
19403
|
if (!activeRef.current) return;
|
|
19738
|
-
if (linkOpenRef.current) return;
|
|
19739
|
-
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
19740
19404
|
setActive(null);
|
|
19741
|
-
setItemEditOn(false);
|
|
19742
19405
|
setError(null);
|
|
19743
19406
|
};
|
|
19744
19407
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -19772,133 +19435,137 @@ function AiMediaStripOverlay({
|
|
|
19772
19435
|
tree: nextTree,
|
|
19773
19436
|
label: entry.label,
|
|
19774
19437
|
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
19775
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
19776
|
-
// The user is already looking at the strip they just edited — recentering the viewport
|
|
19777
|
-
// on every edit reads as the section jumping around.
|
|
19778
|
-
skipScrollIntoView: true
|
|
19438
|
+
...entry.brand ? { brand: entry.brand } : {}
|
|
19779
19439
|
});
|
|
19780
19440
|
return true;
|
|
19781
19441
|
},
|
|
19782
19442
|
[findEntry, postToParent2, applyTreeLocalRef]
|
|
19783
19443
|
);
|
|
19784
19444
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19445
|
+
const hoverHandleRect = useLiveItemRect(!active && hover ? hover : null);
|
|
19785
19446
|
const activeItemRect = useLiveItemRect(active);
|
|
19786
|
-
const
|
|
19787
|
-
const
|
|
19788
|
-
|
|
19789
|
-
|
|
19790
|
-
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
19801
|
-
|
|
19802
|
-
|
|
19803
|
-
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
|
|
19807
|
-
|
|
19808
|
-
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
|
|
19819
|
-
|
|
19447
|
+
const TOOLBAR_APPROX_H = 170;
|
|
19448
|
+
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19449
|
+
return /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
19450
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx20(
|
|
19451
|
+
"button",
|
|
19452
|
+
{
|
|
19453
|
+
type: "button",
|
|
19454
|
+
"data-ohw-toolbar": "",
|
|
19455
|
+
onClick: () => {
|
|
19456
|
+
clearInteractionChromeRef.current();
|
|
19457
|
+
setActive(hover);
|
|
19458
|
+
},
|
|
19459
|
+
"aria-label": "Configure media item",
|
|
19460
|
+
style: {
|
|
19461
|
+
position: "fixed",
|
|
19462
|
+
top: hoverHandleRect.top + 8,
|
|
19463
|
+
left: hoverHandleRect.left + hoverHandleRect.width - 36,
|
|
19464
|
+
width: 28,
|
|
19465
|
+
height: 28,
|
|
19466
|
+
borderRadius: 8,
|
|
19467
|
+
border: `1.5px dashed ${PRIMARY3}`,
|
|
19468
|
+
background: "#ffffff",
|
|
19469
|
+
color: PRIMARY3,
|
|
19470
|
+
display: "flex",
|
|
19471
|
+
alignItems: "center",
|
|
19472
|
+
justifyContent: "center",
|
|
19473
|
+
cursor: "pointer",
|
|
19474
|
+
zIndex: 2147483643,
|
|
19475
|
+
fontSize: 14,
|
|
19476
|
+
fontWeight: 700
|
|
19477
|
+
},
|
|
19478
|
+
children: /* @__PURE__ */ jsx20(Star, { size: 14, style: { pointerEvents: "none" } })
|
|
19479
|
+
}
|
|
19480
|
+
),
|
|
19481
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx20(
|
|
19482
|
+
ItemInteractionLayer,
|
|
19483
|
+
{
|
|
19484
|
+
rect: activeItemRect,
|
|
19485
|
+
state: toolbarState,
|
|
19486
|
+
toolbar: /* @__PURE__ */ jsx20(
|
|
19487
|
+
MediaStripToolbar,
|
|
19488
|
+
{
|
|
19489
|
+
entry: activeEntry,
|
|
19490
|
+
index: active.index,
|
|
19491
|
+
pending,
|
|
19492
|
+
error,
|
|
19493
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
19494
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
19495
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
19496
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
19497
|
+
onResize: (delta) => {
|
|
19498
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
19499
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
19500
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
19501
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
19502
|
+
},
|
|
19503
|
+
onSetAlt: (alt) => {
|
|
19504
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
19505
|
+
},
|
|
19506
|
+
onSetLink: (href, linkTarget) => {
|
|
19820
19507
|
void runMutation(
|
|
19821
19508
|
active.sectionId,
|
|
19822
|
-
(tree) =>
|
|
19823
|
-
|
|
19824
|
-
|
|
19825
|
-
|
|
19509
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19510
|
+
);
|
|
19511
|
+
},
|
|
19512
|
+
onAddItem: () => {
|
|
19513
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19514
|
+
if (!picked) return;
|
|
19515
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
19516
|
+
void runMutation(
|
|
19517
|
+
active.sectionId,
|
|
19518
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
19519
|
+
{ [picked.assetId]: picked.url }
|
|
19520
|
+
).then((applied) => {
|
|
19521
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19522
|
+
});
|
|
19826
19523
|
});
|
|
19827
|
-
}
|
|
19828
|
-
|
|
19829
|
-
|
|
19830
|
-
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
19834
|
-
|
|
19835
|
-
|
|
19524
|
+
},
|
|
19525
|
+
onChangeImage: () => {
|
|
19526
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
19527
|
+
if (!picked) return;
|
|
19528
|
+
void runMutation(
|
|
19529
|
+
active.sectionId,
|
|
19530
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
19531
|
+
{ [picked.assetId]: picked.url }
|
|
19532
|
+
);
|
|
19533
|
+
});
|
|
19534
|
+
},
|
|
19535
|
+
onRemoveItem: () => {
|
|
19536
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
19537
|
+
(applied) => {
|
|
19538
|
+
if (applied) setActive(null);
|
|
19539
|
+
}
|
|
19836
19540
|
);
|
|
19837
|
-
}
|
|
19838
|
-
|
|
19839
|
-
|
|
19840
|
-
|
|
19841
|
-
|
|
19842
|
-
|
|
19843
|
-
|
|
19844
|
-
|
|
19845
|
-
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
|
|
19849
|
-
|
|
19850
|
-
|
|
19851
|
-
|
|
19852
|
-
},
|
|
19853
|
-
onMoveRight: () => {
|
|
19854
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19855
|
-
(applied) => {
|
|
19856
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19857
|
-
}
|
|
19858
|
-
);
|
|
19859
|
-
}
|
|
19860
|
-
}
|
|
19861
|
-
) }),
|
|
19862
|
-
/* @__PURE__ */ jsx21(
|
|
19863
|
-
"div",
|
|
19864
|
-
{
|
|
19865
|
-
"data-ohw-bridge": "",
|
|
19866
|
-
"data-ohw-item-interaction": "",
|
|
19867
|
-
"aria-hidden": true,
|
|
19868
|
-
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
19869
|
-
style: {
|
|
19870
|
-
top: activeItemRect.top + activeItemRect.height + 10,
|
|
19871
|
-
left: activeItemRect.left - 5,
|
|
19872
|
-
background: PRIMARY3,
|
|
19873
|
-
zIndex: 2147483644
|
|
19874
|
-
},
|
|
19875
|
-
children: "Media item"
|
|
19876
|
-
}
|
|
19877
|
-
),
|
|
19878
|
-
linkOpen && /* @__PURE__ */ jsx21(
|
|
19879
|
-
LinkModal,
|
|
19880
|
-
{
|
|
19881
|
-
href: activeHref,
|
|
19882
|
-
linkTarget: activeTarget,
|
|
19883
|
-
onClose: () => setLinkOpen(false),
|
|
19884
|
-
onSave: (href, linkTarget) => {
|
|
19885
|
-
void runMutation(
|
|
19886
|
-
active.sectionId,
|
|
19887
|
-
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
19888
|
-
);
|
|
19541
|
+
},
|
|
19542
|
+
onMoveLeft: () => {
|
|
19543
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
19544
|
+
(applied) => {
|
|
19545
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
19546
|
+
}
|
|
19547
|
+
);
|
|
19548
|
+
},
|
|
19549
|
+
onMoveRight: () => {
|
|
19550
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
19551
|
+
(applied) => {
|
|
19552
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
19553
|
+
}
|
|
19554
|
+
);
|
|
19555
|
+
}
|
|
19889
19556
|
}
|
|
19890
|
-
|
|
19891
|
-
|
|
19892
|
-
|
|
19557
|
+
)
|
|
19558
|
+
}
|
|
19559
|
+
)
|
|
19893
19560
|
] });
|
|
19894
19561
|
}
|
|
19895
19562
|
|
|
19896
19563
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
19897
|
-
import { useCallback as useCallback4, useEffect as useEffect9, useLayoutEffect as
|
|
19898
|
-
import { Check as
|
|
19899
|
-
import { Fragment as Fragment8, jsx as
|
|
19564
|
+
import { useCallback as useCallback4, useEffect as useEffect9, useLayoutEffect as useLayoutEffect4, useRef as useRef6, useState as useState9 } from "react";
|
|
19565
|
+
import { Check as Check2, ChevronDown as ChevronDown3, Minus, Plus as Plus2, Star as Star2 } from "lucide-react";
|
|
19566
|
+
import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
19900
19567
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
19901
|
-
var
|
|
19568
|
+
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]";
|
|
19902
19569
|
function findPricingCardElement(sectionId, index) {
|
|
19903
19570
|
const sectionEl = findByInstanceId(sectionId);
|
|
19904
19571
|
if (!sectionEl) return null;
|
|
@@ -19910,7 +19577,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
19910
19577
|
}
|
|
19911
19578
|
function cardRefFromTarget(target) {
|
|
19912
19579
|
if (!(target instanceof Element)) return null;
|
|
19913
|
-
if (target.closest(
|
|
19580
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
19914
19581
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
19915
19582
|
if (!cardEl) return null;
|
|
19916
19583
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -19920,21 +19587,21 @@ function cardRefFromTarget(target) {
|
|
|
19920
19587
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
19921
19588
|
return { sectionId, index };
|
|
19922
19589
|
}
|
|
19923
|
-
function
|
|
19590
|
+
function sameRef(a, b) {
|
|
19924
19591
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
19925
19592
|
}
|
|
19926
|
-
function
|
|
19593
|
+
function rectOf(el) {
|
|
19927
19594
|
if (!el) return null;
|
|
19928
19595
|
const r2 = el.getBoundingClientRect();
|
|
19929
19596
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
19930
19597
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
19931
19598
|
}
|
|
19932
19599
|
function readRect3(ref) {
|
|
19933
|
-
return
|
|
19600
|
+
return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
19934
19601
|
}
|
|
19935
19602
|
function readGridRect(ref) {
|
|
19936
19603
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
19937
|
-
return
|
|
19604
|
+
return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
19938
19605
|
}
|
|
19939
19606
|
function useLiveCardRect(ref, grid = false) {
|
|
19940
19607
|
const [rect, setRect] = useState9(null);
|
|
@@ -19964,19 +19631,19 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
19964
19631
|
}
|
|
19965
19632
|
var TOOLBAR_GRID_GAP = 52;
|
|
19966
19633
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
19967
|
-
var
|
|
19634
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
19968
19635
|
function GridToolbarSlot({ gridRect, children }) {
|
|
19969
19636
|
const slotRef = useRef6(null);
|
|
19970
19637
|
const [shift, setShift] = useState9(0);
|
|
19971
19638
|
const centerX = gridRect.left + gridRect.width / 2;
|
|
19972
|
-
|
|
19639
|
+
useLayoutEffect4(() => {
|
|
19973
19640
|
const slot = slotRef.current;
|
|
19974
19641
|
if (!slot) return;
|
|
19975
19642
|
const clamp = () => {
|
|
19976
19643
|
const w = slot.offsetWidth;
|
|
19977
19644
|
if (w <= 0) return;
|
|
19978
19645
|
const half = w / 2;
|
|
19979
|
-
const clamped = Math.max(
|
|
19646
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
19980
19647
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
19981
19648
|
};
|
|
19982
19649
|
clamp();
|
|
@@ -19985,7 +19652,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
19985
19652
|
return () => ro.disconnect();
|
|
19986
19653
|
}, [centerX, children]);
|
|
19987
19654
|
const mobile = window.innerWidth <= 480;
|
|
19988
|
-
return /* @__PURE__ */
|
|
19655
|
+
return /* @__PURE__ */ jsx21(
|
|
19989
19656
|
"div",
|
|
19990
19657
|
{
|
|
19991
19658
|
ref: slotRef,
|
|
@@ -20020,7 +19687,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
20020
19687
|
});
|
|
20021
19688
|
}
|
|
20022
19689
|
function StyleSwatch({ style }) {
|
|
20023
|
-
return /* @__PURE__ */
|
|
19690
|
+
return /* @__PURE__ */ jsx21(
|
|
20024
19691
|
"span",
|
|
20025
19692
|
{
|
|
20026
19693
|
"aria-hidden": true,
|
|
@@ -20034,35 +19701,35 @@ function StyleSwatch({ style }) {
|
|
|
20034
19701
|
);
|
|
20035
19702
|
}
|
|
20036
19703
|
function ButtonGlyph() {
|
|
20037
|
-
return /* @__PURE__ */
|
|
20038
|
-
/* @__PURE__ */
|
|
20039
|
-
/* @__PURE__ */
|
|
19704
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19705
|
+
/* @__PURE__ */ jsx21("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19706
|
+
/* @__PURE__ */ jsx21("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
20040
19707
|
] });
|
|
20041
19708
|
}
|
|
20042
19709
|
function FeatureGlyph({ mode }) {
|
|
20043
|
-
return /* @__PURE__ */
|
|
20044
|
-
/* @__PURE__ */
|
|
20045
|
-
/* @__PURE__ */
|
|
20046
|
-
/* @__PURE__ */
|
|
20047
|
-
/* @__PURE__ */
|
|
20048
|
-
/* @__PURE__ */
|
|
20049
|
-
mode === "add" && /* @__PURE__ */
|
|
19710
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
19711
|
+
/* @__PURE__ */ jsx21("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19712
|
+
/* @__PURE__ */ jsx21("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19713
|
+
/* @__PURE__ */ jsx21("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19714
|
+
/* @__PURE__ */ jsx21("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19715
|
+
/* @__PURE__ */ jsx21("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19716
|
+
mode === "add" && /* @__PURE__ */ jsx21("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
20050
19717
|
] });
|
|
20051
19718
|
}
|
|
20052
|
-
function
|
|
19719
|
+
function ToolbarAction({
|
|
20053
19720
|
label,
|
|
20054
19721
|
onClick,
|
|
20055
19722
|
disabled = false,
|
|
20056
19723
|
children
|
|
20057
19724
|
}) {
|
|
20058
|
-
const button = /* @__PURE__ */
|
|
20059
|
-
return /* @__PURE__ */
|
|
20060
|
-
/* @__PURE__ */
|
|
20061
|
-
/* @__PURE__ */
|
|
19725
|
+
const button = /* @__PURE__ */ jsx21(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19726
|
+
return /* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19727
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: button }) : button }),
|
|
19728
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
20062
19729
|
] });
|
|
20063
19730
|
}
|
|
20064
|
-
function
|
|
20065
|
-
return /* @__PURE__ */
|
|
19731
|
+
function ToolbarSeparator() {
|
|
19732
|
+
return /* @__PURE__ */ jsx21("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
20066
19733
|
}
|
|
20067
19734
|
function CardStyleMenu({
|
|
20068
19735
|
value,
|
|
@@ -20070,7 +19737,7 @@ function CardStyleMenu({
|
|
|
20070
19737
|
disabled = false
|
|
20071
19738
|
}) {
|
|
20072
19739
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
20073
|
-
const trigger = /* @__PURE__ */
|
|
19740
|
+
const trigger = /* @__PURE__ */ jsxs12(
|
|
20074
19741
|
"button",
|
|
20075
19742
|
{
|
|
20076
19743
|
type: "button",
|
|
@@ -20081,28 +19748,28 @@ function CardStyleMenu({
|
|
|
20081
19748
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
20082
19749
|
),
|
|
20083
19750
|
children: [
|
|
20084
|
-
/* @__PURE__ */
|
|
20085
|
-
/* @__PURE__ */
|
|
20086
|
-
/* @__PURE__ */
|
|
19751
|
+
/* @__PURE__ */ jsx21(StyleSwatch, { style: current.value }),
|
|
19752
|
+
/* @__PURE__ */ jsx21("span", { className: "flex-1 text-left", children: current.label }),
|
|
19753
|
+
/* @__PURE__ */ jsx21(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
20087
19754
|
]
|
|
20088
19755
|
}
|
|
20089
19756
|
);
|
|
20090
19757
|
if (disabled) {
|
|
20091
|
-
return /* @__PURE__ */
|
|
20092
|
-
/* @__PURE__ */
|
|
20093
|
-
/* @__PURE__ */
|
|
20094
|
-
/* @__PURE__ */
|
|
20095
|
-
/* @__PURE__ */
|
|
19758
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19759
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19760
|
+
/* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19761
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21("span", { className: "inline-flex", children: trigger }) }),
|
|
19762
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
20096
19763
|
] })
|
|
20097
19764
|
] });
|
|
20098
19765
|
}
|
|
20099
|
-
return /* @__PURE__ */
|
|
20100
|
-
/* @__PURE__ */
|
|
20101
|
-
/* @__PURE__ */
|
|
20102
|
-
/* @__PURE__ */
|
|
20103
|
-
/* @__PURE__ */
|
|
19766
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19767
|
+
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19768
|
+
/* @__PURE__ */ jsxs12(DropdownMenu, { modal: false, children: [
|
|
19769
|
+
/* @__PURE__ */ jsx21(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19770
|
+
/* @__PURE__ */ jsx21(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
20104
19771
|
const selected = style.value === value;
|
|
20105
|
-
return /* @__PURE__ */
|
|
19772
|
+
return /* @__PURE__ */ jsxs12(
|
|
20106
19773
|
DropdownMenuItem,
|
|
20107
19774
|
{
|
|
20108
19775
|
role: "menuitemradio",
|
|
@@ -20110,9 +19777,9 @@ function CardStyleMenu({
|
|
|
20110
19777
|
onSelect: () => onChange(style.value),
|
|
20111
19778
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
20112
19779
|
children: [
|
|
20113
|
-
/* @__PURE__ */
|
|
20114
|
-
/* @__PURE__ */
|
|
20115
|
-
selected && /* @__PURE__ */
|
|
19780
|
+
/* @__PURE__ */ jsx21(StyleSwatch, { style: style.value }),
|
|
19781
|
+
/* @__PURE__ */ jsx21("span", { children: style.label }),
|
|
19782
|
+
selected && /* @__PURE__ */ jsx21(Check2, { size: 16, className: "text-bridge-primary" })
|
|
20116
19783
|
]
|
|
20117
19784
|
},
|
|
20118
19785
|
style.value
|
|
@@ -20142,7 +19809,7 @@ function PricingCardToolbar({
|
|
|
20142
19809
|
const style = pricingCardStyle(entry.tree, index);
|
|
20143
19810
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
20144
19811
|
const mobile = window.innerWidth <= 480;
|
|
20145
|
-
return /* @__PURE__ */
|
|
19812
|
+
return /* @__PURE__ */ jsx21(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs12(
|
|
20146
19813
|
"div",
|
|
20147
19814
|
{
|
|
20148
19815
|
"data-ohw-bridge": "",
|
|
@@ -20154,7 +19821,7 @@ function PricingCardToolbar({
|
|
|
20154
19821
|
),
|
|
20155
19822
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
20156
19823
|
children: [
|
|
20157
|
-
/* @__PURE__ */
|
|
19824
|
+
/* @__PURE__ */ jsxs12(
|
|
20158
19825
|
"div",
|
|
20159
19826
|
{
|
|
20160
19827
|
className: cn(
|
|
@@ -20163,8 +19830,8 @@ function PricingCardToolbar({
|
|
|
20163
19830
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
20164
19831
|
),
|
|
20165
19832
|
children: [
|
|
20166
|
-
/* @__PURE__ */
|
|
20167
|
-
/* @__PURE__ */
|
|
19833
|
+
/* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
19834
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
|
|
20168
19835
|
CustomToolbarButton,
|
|
20169
19836
|
{
|
|
20170
19837
|
type: "button",
|
|
@@ -20172,7 +19839,7 @@ function PricingCardToolbar({
|
|
|
20172
19839
|
"aria-pressed": featuredTag,
|
|
20173
19840
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
20174
19841
|
className: "group size-8",
|
|
20175
|
-
children: /* @__PURE__ */
|
|
19842
|
+
children: /* @__PURE__ */ jsx21(
|
|
20176
19843
|
Star2,
|
|
20177
19844
|
{
|
|
20178
19845
|
size: 16,
|
|
@@ -20187,25 +19854,25 @@ function PricingCardToolbar({
|
|
|
20187
19854
|
)
|
|
20188
19855
|
}
|
|
20189
19856
|
) }),
|
|
20190
|
-
/* @__PURE__ */
|
|
19857
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
20191
19858
|
] }),
|
|
20192
|
-
/* @__PURE__ */
|
|
20193
|
-
/* @__PURE__ */
|
|
20194
|
-
/* @__PURE__ */
|
|
20195
|
-
/* @__PURE__ */
|
|
20196
|
-
/* @__PURE__ */
|
|
20197
|
-
/* @__PURE__ */
|
|
20198
|
-
/* @__PURE__ */
|
|
19859
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19860
|
+
/* @__PURE__ */ jsx21(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19861
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19862
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx21(ButtonGlyph, {}) }),
|
|
19863
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs12("span", { className: "relative inline-flex", children: [
|
|
19864
|
+
/* @__PURE__ */ jsx21(ButtonGlyph, {}),
|
|
19865
|
+
/* @__PURE__ */ jsx21(Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
20199
19866
|
] }) }),
|
|
20200
|
-
/* @__PURE__ */
|
|
20201
|
-
/* @__PURE__ */
|
|
20202
|
-
/* @__PURE__ */
|
|
20203
|
-
/* @__PURE__ */
|
|
20204
|
-
/* @__PURE__ */
|
|
19867
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ jsx21(FeatureGlyph, { mode: "add" }) }),
|
|
19868
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ jsx21(FeatureGlyph, { mode: "remove" }) }),
|
|
19869
|
+
/* @__PURE__ */ jsx21(ToolbarSeparator, {}),
|
|
19870
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ jsx21(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19871
|
+
/* @__PURE__ */ jsx21(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ jsx21(Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
20205
19872
|
]
|
|
20206
19873
|
}
|
|
20207
19874
|
),
|
|
20208
|
-
error && /* @__PURE__ */
|
|
19875
|
+
error && /* @__PURE__ */ jsx21("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
20209
19876
|
]
|
|
20210
19877
|
}
|
|
20211
19878
|
) });
|
|
@@ -20239,7 +19906,7 @@ function AiPricingCardOverlay({
|
|
|
20239
19906
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
20240
19907
|
setHover((prev) => {
|
|
20241
19908
|
const next = ref && !overEditable ? ref : null;
|
|
20242
|
-
return
|
|
19909
|
+
return sameRef(prev, next) ? prev : next;
|
|
20243
19910
|
});
|
|
20244
19911
|
};
|
|
20245
19912
|
const onLeave = () => setHover(null);
|
|
@@ -20254,10 +19921,10 @@ function AiPricingCardOverlay({
|
|
|
20254
19921
|
const onClick = (e) => {
|
|
20255
19922
|
const t = e.target;
|
|
20256
19923
|
if (!(t instanceof Element)) return;
|
|
20257
|
-
if (t.closest(
|
|
19924
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
20258
19925
|
const ref = cardRefFromTarget(t);
|
|
20259
|
-
setActive((prev) =>
|
|
20260
|
-
if (!ref || !
|
|
19926
|
+
setActive((prev) => sameRef(prev, ref) ? prev : ref);
|
|
19927
|
+
if (!ref || !sameRef(activeRef.current, ref)) setError(null);
|
|
20261
19928
|
};
|
|
20262
19929
|
document.addEventListener("click", onClick, true);
|
|
20263
19930
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -20322,12 +19989,12 @@ function AiPricingCardOverlay({
|
|
|
20322
19989
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
20323
19990
|
const activeCardRect = useLiveCardRect(active);
|
|
20324
19991
|
const activeGridRect = useLiveCardRect(active, true);
|
|
20325
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
20326
|
-
return /* @__PURE__ */
|
|
20327
|
-
hoverRect && /* @__PURE__ */
|
|
20328
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */
|
|
20329
|
-
/* @__PURE__ */
|
|
20330
|
-
/* @__PURE__ */
|
|
19992
|
+
const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
|
|
19993
|
+
return /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
19994
|
+
hoverRect && /* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19995
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
19996
|
+
/* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19997
|
+
/* @__PURE__ */ jsx21(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ jsx21(
|
|
20331
19998
|
PricingCardToolbar,
|
|
20332
19999
|
{
|
|
20333
20000
|
entry: activeEntry,
|
|
@@ -20355,7 +20022,7 @@ function AiPricingCardOverlay({
|
|
|
20355
20022
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
20356
20023
|
}
|
|
20357
20024
|
) }),
|
|
20358
|
-
/* @__PURE__ */
|
|
20025
|
+
/* @__PURE__ */ jsx21(
|
|
20359
20026
|
"div",
|
|
20360
20027
|
{
|
|
20361
20028
|
"data-ohw-bridge": "",
|
|
@@ -20419,11 +20086,39 @@ function clearVideo(tree, path) {
|
|
|
20419
20086
|
});
|
|
20420
20087
|
}
|
|
20421
20088
|
|
|
20089
|
+
// src/lib/youtube.ts
|
|
20090
|
+
var YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
|
|
20091
|
+
function extractYouTubeId(input) {
|
|
20092
|
+
const trimmed = input.trim();
|
|
20093
|
+
if (!trimmed) return null;
|
|
20094
|
+
if (YOUTUBE_ID_PATTERN.test(trimmed)) return trimmed;
|
|
20095
|
+
let url;
|
|
20096
|
+
try {
|
|
20097
|
+
url = new URL(trimmed);
|
|
20098
|
+
} catch {
|
|
20099
|
+
return null;
|
|
20100
|
+
}
|
|
20101
|
+
const host = url.hostname.replace(/^www\./, "");
|
|
20102
|
+
if (host !== "youtube.com" && host !== "m.youtube.com" && host !== "youtu.be" && host !== "youtube-nocookie.com") {
|
|
20103
|
+
return null;
|
|
20104
|
+
}
|
|
20105
|
+
let candidate = null;
|
|
20106
|
+
if (host === "youtu.be") {
|
|
20107
|
+
candidate = url.pathname.slice(1).split("/")[0] ?? null;
|
|
20108
|
+
} else if (url.pathname === "/watch") {
|
|
20109
|
+
candidate = url.searchParams.get("v");
|
|
20110
|
+
} else {
|
|
20111
|
+
const match = url.pathname.match(/^\/(?:embed|shorts)\/([^/]+)/);
|
|
20112
|
+
candidate = match ? match[1] : null;
|
|
20113
|
+
}
|
|
20114
|
+
return candidate && YOUTUBE_ID_PATTERN.test(candidate) ? candidate : null;
|
|
20115
|
+
}
|
|
20116
|
+
|
|
20422
20117
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
20423
|
-
import { Fragment as Fragment9, jsx as
|
|
20118
|
+
import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
20424
20119
|
var PRIMARY5 = "#0885FE";
|
|
20425
|
-
var
|
|
20426
|
-
var
|
|
20120
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
|
|
20121
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
20427
20122
|
function findVideoBlockElement(sectionId, path) {
|
|
20428
20123
|
const sectionEl = findByInstanceId(sectionId);
|
|
20429
20124
|
if (!sectionEl) return null;
|
|
@@ -20483,12 +20178,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
20483
20178
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
20484
20179
|
});
|
|
20485
20180
|
}
|
|
20486
|
-
function
|
|
20181
|
+
function Pill2({
|
|
20487
20182
|
label,
|
|
20488
20183
|
onClick,
|
|
20489
20184
|
disabled
|
|
20490
20185
|
}) {
|
|
20491
|
-
return /* @__PURE__ */
|
|
20186
|
+
return /* @__PURE__ */ jsx22(
|
|
20492
20187
|
"button",
|
|
20493
20188
|
{
|
|
20494
20189
|
type: "button",
|
|
@@ -20504,7 +20199,7 @@ function Pill({
|
|
|
20504
20199
|
border: "none",
|
|
20505
20200
|
cursor: disabled ? "default" : "pointer",
|
|
20506
20201
|
background: "#ffffff",
|
|
20507
|
-
color:
|
|
20202
|
+
color: OHW_BLUE_DARK2,
|
|
20508
20203
|
opacity: disabled ? 0.4 : 1,
|
|
20509
20204
|
fontSize: 12,
|
|
20510
20205
|
lineHeight: "16px",
|
|
@@ -20526,7 +20221,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20526
20221
|
setDraft(value ? watchUrl(value) : "");
|
|
20527
20222
|
setInvalid(false);
|
|
20528
20223
|
}, [value]);
|
|
20529
|
-
const
|
|
20224
|
+
const commit = () => {
|
|
20530
20225
|
const next = draft.trim();
|
|
20531
20226
|
if (!next) {
|
|
20532
20227
|
setInvalid(false);
|
|
@@ -20547,8 +20242,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20547
20242
|
onCommit(id);
|
|
20548
20243
|
}
|
|
20549
20244
|
};
|
|
20550
|
-
return /* @__PURE__ */
|
|
20551
|
-
/* @__PURE__ */
|
|
20245
|
+
return /* @__PURE__ */ jsxs13("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
20246
|
+
/* @__PURE__ */ jsxs13(
|
|
20552
20247
|
"div",
|
|
20553
20248
|
{
|
|
20554
20249
|
style: {
|
|
@@ -20564,12 +20259,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20564
20259
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
20565
20260
|
},
|
|
20566
20261
|
children: [
|
|
20567
|
-
/* @__PURE__ */
|
|
20262
|
+
/* @__PURE__ */ jsx22(
|
|
20568
20263
|
"span",
|
|
20569
20264
|
{
|
|
20570
20265
|
style: {
|
|
20571
20266
|
flex: "0 0 auto",
|
|
20572
|
-
color:
|
|
20267
|
+
color: OHW_BLUE_DARK2,
|
|
20573
20268
|
fontSize: 10,
|
|
20574
20269
|
lineHeight: "16px",
|
|
20575
20270
|
fontWeight: 700,
|
|
@@ -20579,14 +20274,14 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20579
20274
|
children: "Video"
|
|
20580
20275
|
}
|
|
20581
20276
|
),
|
|
20582
|
-
/* @__PURE__ */
|
|
20277
|
+
/* @__PURE__ */ jsx22(
|
|
20583
20278
|
"input",
|
|
20584
20279
|
{
|
|
20585
20280
|
type: "text",
|
|
20586
20281
|
inputMode: "url",
|
|
20587
20282
|
value: draft,
|
|
20588
20283
|
onChange: (e) => handleChange(e.target.value),
|
|
20589
|
-
onBlur:
|
|
20284
|
+
onBlur: commit,
|
|
20590
20285
|
onKeyDown: (e) => {
|
|
20591
20286
|
if (e.key === "Enter") e.currentTarget.blur();
|
|
20592
20287
|
if (e.key === "Escape") {
|
|
@@ -20616,7 +20311,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
20616
20311
|
]
|
|
20617
20312
|
}
|
|
20618
20313
|
),
|
|
20619
|
-
invalid && /* @__PURE__ */
|
|
20314
|
+
invalid && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
20620
20315
|
] });
|
|
20621
20316
|
}
|
|
20622
20317
|
function VideoToolbar({
|
|
@@ -20626,7 +20321,7 @@ function VideoToolbar({
|
|
|
20626
20321
|
onSetVideoId,
|
|
20627
20322
|
onRemove
|
|
20628
20323
|
}) {
|
|
20629
|
-
return /* @__PURE__ */
|
|
20324
|
+
return /* @__PURE__ */ jsxs13(
|
|
20630
20325
|
"div",
|
|
20631
20326
|
{
|
|
20632
20327
|
"data-ohw-bridge": "",
|
|
@@ -20638,7 +20333,7 @@ function VideoToolbar({
|
|
|
20638
20333
|
gap: 6,
|
|
20639
20334
|
alignItems: "center",
|
|
20640
20335
|
width: 280,
|
|
20641
|
-
background:
|
|
20336
|
+
background: OHW_BLUE2,
|
|
20642
20337
|
padding: 8,
|
|
20643
20338
|
borderRadius: 12,
|
|
20644
20339
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -20646,9 +20341,9 @@ function VideoToolbar({
|
|
|
20646
20341
|
opacity: pending ? 0.6 : 1
|
|
20647
20342
|
},
|
|
20648
20343
|
children: [
|
|
20649
|
-
/* @__PURE__ */
|
|
20650
|
-
/* @__PURE__ */
|
|
20651
|
-
error && /* @__PURE__ */
|
|
20344
|
+
/* @__PURE__ */ jsx22(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
20345
|
+
/* @__PURE__ */ jsx22(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
20346
|
+
error && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
20652
20347
|
]
|
|
20653
20348
|
}
|
|
20654
20349
|
);
|
|
@@ -20768,8 +20463,8 @@ function AiVideoOverlay({
|
|
|
20768
20463
|
const activeBlockRect = useLiveBlockRect(active);
|
|
20769
20464
|
const TOOLBAR_APPROX_H = 90;
|
|
20770
20465
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20771
|
-
return /* @__PURE__ */
|
|
20772
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
20466
|
+
return /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
20467
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx22(
|
|
20773
20468
|
"button",
|
|
20774
20469
|
{
|
|
20775
20470
|
type: "button",
|
|
@@ -20797,15 +20492,15 @@ function AiVideoOverlay({
|
|
|
20797
20492
|
fontSize: 14,
|
|
20798
20493
|
fontWeight: 700
|
|
20799
20494
|
},
|
|
20800
|
-
children: /* @__PURE__ */
|
|
20495
|
+
children: /* @__PURE__ */ jsx22(Star3, { size: 14, style: { pointerEvents: "none" } })
|
|
20801
20496
|
}
|
|
20802
20497
|
),
|
|
20803
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */
|
|
20498
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ jsx22(
|
|
20804
20499
|
ItemInteractionLayer,
|
|
20805
20500
|
{
|
|
20806
20501
|
rect: activeBlockRect,
|
|
20807
20502
|
state: toolbarState,
|
|
20808
|
-
toolbar: /* @__PURE__ */
|
|
20503
|
+
toolbar: /* @__PURE__ */ jsx22(
|
|
20809
20504
|
VideoToolbar,
|
|
20810
20505
|
{
|
|
20811
20506
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -20880,10 +20575,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
20880
20575
|
}
|
|
20881
20576
|
|
|
20882
20577
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
20883
|
-
import { Fragment as Fragment10, jsx as
|
|
20578
|
+
import { Fragment as Fragment10, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
20884
20579
|
var PRIMARY6 = "#0885FE";
|
|
20885
|
-
var
|
|
20886
|
-
var
|
|
20580
|
+
var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
20581
|
+
var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
20887
20582
|
function findCarouselItemElement(sectionId, index) {
|
|
20888
20583
|
const sectionEl = findByInstanceId(sectionId);
|
|
20889
20584
|
if (!sectionEl) return null;
|
|
@@ -20962,8 +20657,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
20962
20657
|
postToParent2({ type: "ow:asset-pick", id });
|
|
20963
20658
|
});
|
|
20964
20659
|
}
|
|
20965
|
-
function
|
|
20966
|
-
return /* @__PURE__ */
|
|
20660
|
+
function Pill3({ label, onClick, disabled }) {
|
|
20661
|
+
return /* @__PURE__ */ jsx23(
|
|
20967
20662
|
"button",
|
|
20968
20663
|
{
|
|
20969
20664
|
type: "button",
|
|
@@ -20979,7 +20674,7 @@ function Pill2({ label, onClick, disabled }) {
|
|
|
20979
20674
|
border: "none",
|
|
20980
20675
|
cursor: disabled ? "default" : "pointer",
|
|
20981
20676
|
background: "#ffffff",
|
|
20982
|
-
color:
|
|
20677
|
+
color: OHW_BLUE_DARK3,
|
|
20983
20678
|
opacity: disabled ? 0.4 : 1,
|
|
20984
20679
|
fontSize: 12,
|
|
20985
20680
|
lineHeight: "16px",
|
|
@@ -20997,7 +20692,7 @@ function TogglePill({
|
|
|
20997
20692
|
onToggle,
|
|
20998
20693
|
disabled
|
|
20999
20694
|
}) {
|
|
21000
|
-
return /* @__PURE__ */
|
|
20695
|
+
return /* @__PURE__ */ jsxs14(
|
|
21001
20696
|
"button",
|
|
21002
20697
|
{
|
|
21003
20698
|
type: "button",
|
|
@@ -21016,7 +20711,7 @@ function TogglePill({
|
|
|
21016
20711
|
border: "none",
|
|
21017
20712
|
cursor: disabled ? "default" : "pointer",
|
|
21018
20713
|
background: "#ffffff",
|
|
21019
|
-
color:
|
|
20714
|
+
color: OHW_BLUE_DARK3,
|
|
21020
20715
|
opacity: disabled ? 0.4 : 1,
|
|
21021
20716
|
fontSize: 12,
|
|
21022
20717
|
lineHeight: "16px",
|
|
@@ -21026,7 +20721,7 @@ function TogglePill({
|
|
|
21026
20721
|
},
|
|
21027
20722
|
children: [
|
|
21028
20723
|
label,
|
|
21029
|
-
/* @__PURE__ */
|
|
20724
|
+
/* @__PURE__ */ jsx23(
|
|
21030
20725
|
"span",
|
|
21031
20726
|
{
|
|
21032
20727
|
"aria-hidden": true,
|
|
@@ -21039,10 +20734,10 @@ function TogglePill({
|
|
|
21039
20734
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
21040
20735
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
21041
20736
|
// "disabled control" rather than "switch that is off".
|
|
21042
|
-
background: on ?
|
|
20737
|
+
background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
|
|
21043
20738
|
transition: "background 120ms ease"
|
|
21044
20739
|
},
|
|
21045
|
-
children: /* @__PURE__ */
|
|
20740
|
+
children: /* @__PURE__ */ jsx23(
|
|
21046
20741
|
"span",
|
|
21047
20742
|
{
|
|
21048
20743
|
style: {
|
|
@@ -21071,7 +20766,7 @@ function CarouselSlideToolbar({
|
|
|
21071
20766
|
onChangeImage,
|
|
21072
20767
|
onToggleAutoplay
|
|
21073
20768
|
}) {
|
|
21074
|
-
return /* @__PURE__ */
|
|
20769
|
+
return /* @__PURE__ */ jsxs14(
|
|
21075
20770
|
"div",
|
|
21076
20771
|
{
|
|
21077
20772
|
"data-ohw-bridge": "",
|
|
@@ -21082,7 +20777,7 @@ function CarouselSlideToolbar({
|
|
|
21082
20777
|
flexDirection: "column",
|
|
21083
20778
|
gap: 6,
|
|
21084
20779
|
alignItems: "center",
|
|
21085
|
-
background:
|
|
20780
|
+
background: OHW_BLUE3,
|
|
21086
20781
|
padding: 8,
|
|
21087
20782
|
borderRadius: 12,
|
|
21088
20783
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -21094,11 +20789,11 @@ function CarouselSlideToolbar({
|
|
|
21094
20789
|
pointerEvents: pending ? "none" : "auto"
|
|
21095
20790
|
},
|
|
21096
20791
|
children: [
|
|
21097
|
-
/* @__PURE__ */
|
|
21098
|
-
/* @__PURE__ */
|
|
21099
|
-
/* @__PURE__ */
|
|
20792
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20793
|
+
/* @__PURE__ */ jsx23(Pill3, { label: "Change Image", onClick: onChangeImage }),
|
|
20794
|
+
/* @__PURE__ */ jsx23(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
21100
20795
|
] }),
|
|
21101
|
-
error && /* @__PURE__ */
|
|
20796
|
+
error && /* @__PURE__ */ jsx23("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
21102
20797
|
]
|
|
21103
20798
|
}
|
|
21104
20799
|
);
|
|
@@ -21238,8 +20933,8 @@ function AiFadeCarouselOverlay({
|
|
|
21238
20933
|
const activeItemRect = useLiveItemRect2(active);
|
|
21239
20934
|
const TOOLBAR_APPROX_H = 90;
|
|
21240
20935
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
21241
|
-
return /* @__PURE__ */
|
|
21242
|
-
hoverHandleRect && hover && /* @__PURE__ */
|
|
20936
|
+
return /* @__PURE__ */ jsxs14(Fragment10, { children: [
|
|
20937
|
+
hoverHandleRect && hover && /* @__PURE__ */ jsx23(
|
|
21243
20938
|
"button",
|
|
21244
20939
|
{
|
|
21245
20940
|
type: "button",
|
|
@@ -21268,10 +20963,10 @@ function AiFadeCarouselOverlay({
|
|
|
21268
20963
|
fontSize: 14,
|
|
21269
20964
|
fontWeight: 700
|
|
21270
20965
|
},
|
|
21271
|
-
children: /* @__PURE__ */
|
|
20966
|
+
children: /* @__PURE__ */ jsx23(Star4, { size: 14, style: { pointerEvents: "none" } })
|
|
21272
20967
|
}
|
|
21273
20968
|
),
|
|
21274
|
-
swapping && /* @__PURE__ */
|
|
20969
|
+
swapping && /* @__PURE__ */ jsx23(
|
|
21275
20970
|
"div",
|
|
21276
20971
|
{
|
|
21277
20972
|
ref: skeletonRef,
|
|
@@ -21289,15 +20984,15 @@ function AiFadeCarouselOverlay({
|
|
|
21289
20984
|
zIndex: 2147483646,
|
|
21290
20985
|
pointerEvents: "none"
|
|
21291
20986
|
},
|
|
21292
|
-
children: /* @__PURE__ */
|
|
20987
|
+
children: /* @__PURE__ */ jsx23("style", { children: MEDIA_SKELETON_CSS })
|
|
21293
20988
|
}
|
|
21294
20989
|
),
|
|
21295
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */
|
|
20990
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ jsx23(
|
|
21296
20991
|
ItemInteractionLayer,
|
|
21297
20992
|
{
|
|
21298
20993
|
rect: activeItemRect,
|
|
21299
20994
|
state: toolbarState,
|
|
21300
|
-
toolbar: /* @__PURE__ */
|
|
20995
|
+
toolbar: /* @__PURE__ */ jsx23(
|
|
21301
20996
|
CarouselSlideToolbar,
|
|
21302
20997
|
{
|
|
21303
20998
|
pending,
|
|
@@ -21488,11 +21183,118 @@ function mergePrefetchedSections(prev, fetched, livePath, liveSections) {
|
|
|
21488
21183
|
// src/ui/link-modal/LinkPopover.tsx
|
|
21489
21184
|
import { useEffect as useEffect15 } from "react";
|
|
21490
21185
|
|
|
21186
|
+
// src/ui/dialog.tsx
|
|
21187
|
+
import * as React9 from "react";
|
|
21188
|
+
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
21189
|
+
import { X as X2 } from "lucide-react";
|
|
21190
|
+
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
21191
|
+
function Dialog2({
|
|
21192
|
+
...props
|
|
21193
|
+
}) {
|
|
21194
|
+
return /* @__PURE__ */ jsx24(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
21195
|
+
}
|
|
21196
|
+
function DialogPortal({
|
|
21197
|
+
...props
|
|
21198
|
+
}) {
|
|
21199
|
+
return /* @__PURE__ */ jsx24(DialogPrimitive.Portal, { ...props });
|
|
21200
|
+
}
|
|
21201
|
+
function DialogOverlay({
|
|
21202
|
+
className,
|
|
21203
|
+
...props
|
|
21204
|
+
}) {
|
|
21205
|
+
return /* @__PURE__ */ jsx24(
|
|
21206
|
+
DialogPrimitive.Overlay,
|
|
21207
|
+
{
|
|
21208
|
+
"data-slot": "dialog-overlay",
|
|
21209
|
+
"data-ohw-link-modal-root": "",
|
|
21210
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
21211
|
+
...props
|
|
21212
|
+
}
|
|
21213
|
+
);
|
|
21214
|
+
}
|
|
21215
|
+
var DialogContent = React9.forwardRef(
|
|
21216
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
21217
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
21218
|
+
return /* @__PURE__ */ jsxs15(DialogPortal, { container: container ?? void 0, children: [
|
|
21219
|
+
/* @__PURE__ */ jsx24(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
21220
|
+
/* @__PURE__ */ jsxs15(
|
|
21221
|
+
DialogPrimitive.Content,
|
|
21222
|
+
{
|
|
21223
|
+
ref,
|
|
21224
|
+
"data-slot": "dialog-content",
|
|
21225
|
+
className: cn(
|
|
21226
|
+
positionMode,
|
|
21227
|
+
"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",
|
|
21228
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
21229
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
21230
|
+
className
|
|
21231
|
+
),
|
|
21232
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
21233
|
+
...props,
|
|
21234
|
+
children: [
|
|
21235
|
+
children,
|
|
21236
|
+
showCloseButton ? /* @__PURE__ */ jsx24(
|
|
21237
|
+
DialogPrimitive.Close,
|
|
21238
|
+
{
|
|
21239
|
+
type: "button",
|
|
21240
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
21241
|
+
"aria-label": "Close",
|
|
21242
|
+
children: /* @__PURE__ */ jsx24(X2, { size: 16, "aria-hidden": true })
|
|
21243
|
+
}
|
|
21244
|
+
) : null
|
|
21245
|
+
]
|
|
21246
|
+
}
|
|
21247
|
+
)
|
|
21248
|
+
] });
|
|
21249
|
+
}
|
|
21250
|
+
);
|
|
21251
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
21252
|
+
function DialogHeader({
|
|
21253
|
+
className,
|
|
21254
|
+
...props
|
|
21255
|
+
}) {
|
|
21256
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
21257
|
+
}
|
|
21258
|
+
function DialogFooter({
|
|
21259
|
+
className,
|
|
21260
|
+
...props
|
|
21261
|
+
}) {
|
|
21262
|
+
return /* @__PURE__ */ jsx24(
|
|
21263
|
+
"div",
|
|
21264
|
+
{
|
|
21265
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
21266
|
+
...props
|
|
21267
|
+
}
|
|
21268
|
+
);
|
|
21269
|
+
}
|
|
21270
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
21271
|
+
DialogPrimitive.Title,
|
|
21272
|
+
{
|
|
21273
|
+
ref,
|
|
21274
|
+
className: cn(
|
|
21275
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
21276
|
+
className
|
|
21277
|
+
),
|
|
21278
|
+
...props
|
|
21279
|
+
}
|
|
21280
|
+
));
|
|
21281
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
21282
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
21283
|
+
DialogPrimitive.Description,
|
|
21284
|
+
{
|
|
21285
|
+
ref,
|
|
21286
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
21287
|
+
...props
|
|
21288
|
+
}
|
|
21289
|
+
));
|
|
21290
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
21291
|
+
var DialogClose = DialogPrimitive.Close;
|
|
21292
|
+
|
|
21491
21293
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
21492
21294
|
import { Info, X as X4 } from "lucide-react";
|
|
21493
21295
|
|
|
21494
21296
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
21495
|
-
import { ArrowRight as
|
|
21297
|
+
import { ArrowRight as ArrowRight2, File, GalleryVertical } from "lucide-react";
|
|
21496
21298
|
import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
21497
21299
|
function DestinationBreadcrumb({
|
|
21498
21300
|
pageTitle,
|
|
@@ -21506,7 +21308,7 @@ function DestinationBreadcrumb({
|
|
|
21506
21308
|
/* @__PURE__ */ jsx25("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
21507
21309
|
] }),
|
|
21508
21310
|
/* @__PURE__ */ jsx25(
|
|
21509
|
-
|
|
21311
|
+
ArrowRight2,
|
|
21510
21312
|
{
|
|
21511
21313
|
size: 16,
|
|
21512
21314
|
className: "shrink-0 text-muted-foreground",
|
|
@@ -21618,7 +21420,7 @@ function Label({ className, ...props }) {
|
|
|
21618
21420
|
}
|
|
21619
21421
|
|
|
21620
21422
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
21621
|
-
import { ChevronDown as
|
|
21423
|
+
import { ChevronDown as ChevronDown4, File as File2, X as X3 } from "lucide-react";
|
|
21622
21424
|
import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
21623
21425
|
function FieldChevron({
|
|
21624
21426
|
onClick
|
|
@@ -21631,7 +21433,7 @@ function FieldChevron({
|
|
|
21631
21433
|
onClick,
|
|
21632
21434
|
"aria-label": "Open page list",
|
|
21633
21435
|
tabIndex: -1,
|
|
21634
|
-
children: /* @__PURE__ */ jsx29(
|
|
21436
|
+
children: /* @__PURE__ */ jsx29(ChevronDown4, { size: 16 })
|
|
21635
21437
|
}
|
|
21636
21438
|
);
|
|
21637
21439
|
}
|
|
@@ -21861,7 +21663,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
21861
21663
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
21862
21664
|
import { useCallback as useCallback7, useEffect as useEffect13, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
|
|
21863
21665
|
import { createPortal as createPortal2 } from "react-dom";
|
|
21864
|
-
import { ArrowLeft as
|
|
21666
|
+
import { ArrowLeft as ArrowLeft2, Check as Check3 } from "lucide-react";
|
|
21865
21667
|
import { usePathname as usePathname2, useRouter as useRouter2 } from "next/navigation";
|
|
21866
21668
|
|
|
21867
21669
|
// src/lib/parent-scroll.ts
|
|
@@ -22138,7 +21940,7 @@ function SectionPickerOverlay({
|
|
|
22138
21940
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
22139
21941
|
onClick: onBack,
|
|
22140
21942
|
children: [
|
|
22141
|
-
/* @__PURE__ */ jsx31(
|
|
21943
|
+
/* @__PURE__ */ jsx31(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
22142
21944
|
"Back"
|
|
22143
21945
|
]
|
|
22144
21946
|
}
|
|
@@ -22207,7 +22009,7 @@ function SectionPickerOverlay({
|
|
|
22207
22009
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
22208
22010
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
22209
22011
|
"aria-hidden": true,
|
|
22210
|
-
children: /* @__PURE__ */ jsx31(
|
|
22012
|
+
children: /* @__PURE__ */ jsx31(Check3, { className: "size-5" })
|
|
22211
22013
|
}
|
|
22212
22014
|
) : null
|
|
22213
22015
|
]
|
|
@@ -22591,7 +22393,6 @@ function shouldUseDevFixtures() {
|
|
|
22591
22393
|
function getLogoElement(el) {
|
|
22592
22394
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
22593
22395
|
if (marked) return marked;
|
|
22594
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
22595
22396
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
22596
22397
|
if (!root) return null;
|
|
22597
22398
|
const anchor = el.closest("a");
|
|
@@ -22661,7 +22462,7 @@ function addFooterColumnWithPersist({
|
|
|
22661
22462
|
import {
|
|
22662
22463
|
useCallback as useCallback9,
|
|
22663
22464
|
useEffect as useEffect16,
|
|
22664
|
-
useLayoutEffect as
|
|
22465
|
+
useLayoutEffect as useLayoutEffect5,
|
|
22665
22466
|
useRef as useRef11,
|
|
22666
22467
|
useState as useState15
|
|
22667
22468
|
} from "react";
|
|
@@ -22758,7 +22559,7 @@ function FloatingPanel({
|
|
|
22758
22559
|
return () => window.removeEventListener("message", onParentScroll);
|
|
22759
22560
|
}, [open]);
|
|
22760
22561
|
const positionRef = useRef11(position);
|
|
22761
|
-
|
|
22562
|
+
useLayoutEffect5(() => {
|
|
22762
22563
|
if (!open) {
|
|
22763
22564
|
positionRef.current = position;
|
|
22764
22565
|
return;
|
|
@@ -22768,7 +22569,7 @@ function FloatingPanel({
|
|
|
22768
22569
|
}
|
|
22769
22570
|
positionRef.current = position;
|
|
22770
22571
|
}, [open, position, liveScroll, parentScroll]);
|
|
22771
|
-
|
|
22572
|
+
useLayoutEffect5(() => {
|
|
22772
22573
|
if (!open || !panelRef.current) return;
|
|
22773
22574
|
const el = panelRef.current;
|
|
22774
22575
|
const header = el.querySelector("[data-ohw-floating-panel-header]");
|
|
@@ -22977,7 +22778,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
22977
22778
|
}
|
|
22978
22779
|
|
|
22979
22780
|
// src/ui/button-style-panel.tsx
|
|
22980
|
-
import { Check as
|
|
22781
|
+
import { Check as Check4 } from "lucide-react";
|
|
22981
22782
|
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
22982
22783
|
var SIZE_LABEL = { s: "S", m: "M", l: "L" };
|
|
22983
22784
|
function ButtonStylePanel({
|
|
@@ -23048,7 +22849,7 @@ function ButtonStylePanel({
|
|
|
23048
22849
|
{
|
|
23049
22850
|
className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
23050
22851
|
"aria-hidden": true,
|
|
23051
|
-
children: /* @__PURE__ */ jsx35(
|
|
22852
|
+
children: /* @__PURE__ */ jsx35(Check4, { className: "size-3", strokeWidth: 3 })
|
|
23052
22853
|
}
|
|
23053
22854
|
) : null
|
|
23054
22855
|
]
|
|
@@ -24073,7 +23874,7 @@ function useSectionDrag({
|
|
|
24073
23874
|
}
|
|
24074
23875
|
|
|
24075
23876
|
// src/ui/footer-container-chrome.tsx
|
|
24076
|
-
import { Plus as
|
|
23877
|
+
import { Plus as Plus3 } from "lucide-react";
|
|
24077
23878
|
import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
24078
23879
|
function FooterContainerChrome({
|
|
24079
23880
|
rect,
|
|
@@ -24114,7 +23915,7 @@ function FooterContainerChrome({
|
|
|
24114
23915
|
if (addDisabled) return;
|
|
24115
23916
|
onAdd();
|
|
24116
23917
|
},
|
|
24117
|
-
children: /* @__PURE__ */ jsx36(
|
|
23918
|
+
children: /* @__PURE__ */ jsx36(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
24118
23919
|
}
|
|
24119
23920
|
) }),
|
|
24120
23921
|
/* @__PURE__ */ jsx36(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
@@ -24292,104 +24093,8 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
24292
24093
|
return false;
|
|
24293
24094
|
}
|
|
24294
24095
|
|
|
24295
|
-
// src/lib/nav-page-sync.ts
|
|
24296
|
-
function labelKeyFor(hrefKey) {
|
|
24297
|
-
return hrefKey.replace(/-href$/, "-label");
|
|
24298
|
-
}
|
|
24299
|
-
function isPageLinkKey(key) {
|
|
24300
|
-
return isNavbarHrefKey(key) || isFooterHrefKey(key);
|
|
24301
|
-
}
|
|
24302
|
-
function currentHref(key, anchor, content) {
|
|
24303
|
-
const stored = content[key];
|
|
24304
|
-
if (typeof stored === "string" && stored.length > 0) return stored;
|
|
24305
|
-
return anchor.getAttribute("href") ?? "";
|
|
24306
|
-
}
|
|
24307
|
-
function normalizePath2(value) {
|
|
24308
|
-
if (value.length > 1 && value.endsWith("/")) return value.slice(0, -1);
|
|
24309
|
-
return value;
|
|
24310
|
-
}
|
|
24311
|
-
function pointsAt(href, path) {
|
|
24312
|
-
const normalized = normalizePath2(href);
|
|
24313
|
-
const target = normalizePath2(path);
|
|
24314
|
-
if (normalized === target) return true;
|
|
24315
|
-
return (normalized.startsWith(`${target}#`) || normalized.startsWith(`${target}?`)) && target !== "/";
|
|
24316
|
-
}
|
|
24317
|
-
function retargetHref(href, oldPath, newPath) {
|
|
24318
|
-
const normalized = normalizePath2(href);
|
|
24319
|
-
const target = normalizePath2(oldPath);
|
|
24320
|
-
if (normalized === target) return newPath;
|
|
24321
|
-
return `${newPath}${normalized.slice(target.length)}`;
|
|
24322
|
-
}
|
|
24323
|
-
function setLabelText(key, text) {
|
|
24324
|
-
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
24325
|
-
el.textContent = text;
|
|
24326
|
-
});
|
|
24327
|
-
}
|
|
24328
|
-
function commit(delta, deps) {
|
|
24329
|
-
if (Object.keys(delta).length === 0) return;
|
|
24330
|
-
deps.setEditContent({ ...deps.getEditContent(), ...delta });
|
|
24331
|
-
deps.postToParent({
|
|
24332
|
-
type: "ow:change",
|
|
24333
|
-
nodes: Object.entries(delta).map(([key, text]) => ({ key, text }))
|
|
24334
|
-
});
|
|
24335
|
-
}
|
|
24336
|
-
function navLinksTo(path, content) {
|
|
24337
|
-
return Array.from(document.querySelectorAll("[data-ohw-href-key]")).filter((anchor) => {
|
|
24338
|
-
const key = anchor.getAttribute("data-ohw-href-key");
|
|
24339
|
-
return isNavbarHrefKey(key) && pointsAt(currentHref(key, anchor, content), path);
|
|
24340
|
-
}).map((anchor) => anchor.getAttribute("data-ohw-href-key"));
|
|
24341
|
-
}
|
|
24342
|
-
function addNavLinkForPage(page, deps) {
|
|
24343
|
-
const content = deps.getEditContent();
|
|
24344
|
-
if (navLinksTo(page.path, content).length > 0) return false;
|
|
24345
|
-
const roots = listNavbarRootItems();
|
|
24346
|
-
const afterAnchor = roots[roots.length - 1] ?? null;
|
|
24347
|
-
let inserted;
|
|
24348
|
-
try {
|
|
24349
|
-
inserted = insertNavbarItem(page.path, page.title, afterAnchor);
|
|
24350
|
-
} catch {
|
|
24351
|
-
return false;
|
|
24352
|
-
}
|
|
24353
|
-
const { hrefKey, labelKey, index } = inserted;
|
|
24354
|
-
deps.applyLinkByKey(hrefKey, page.path);
|
|
24355
|
-
setLabelText(labelKey, page.title);
|
|
24356
|
-
commit(
|
|
24357
|
-
{
|
|
24358
|
-
[hrefKey]: page.path,
|
|
24359
|
-
[labelKey]: page.title,
|
|
24360
|
-
[NAV_COUNT_KEY]: String(index + 1),
|
|
24361
|
-
[NAV_ORDER_KEY]: getNavbarOrderJson()
|
|
24362
|
-
},
|
|
24363
|
-
deps
|
|
24364
|
-
);
|
|
24365
|
-
return true;
|
|
24366
|
-
}
|
|
24367
|
-
function retargetPageLinks(change, deps) {
|
|
24368
|
-
const { oldPath, newPath, oldTitle, newTitle } = change;
|
|
24369
|
-
if (!oldPath || !newPath || normalizePath2(oldPath) === normalizePath2(newPath)) return 0;
|
|
24370
|
-
const content = deps.getEditContent();
|
|
24371
|
-
const delta = {};
|
|
24372
|
-
for (const anchor of Array.from(document.querySelectorAll("[data-ohw-href-key]"))) {
|
|
24373
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
24374
|
-
if (!isPageLinkKey(hrefKey)) continue;
|
|
24375
|
-
const href = currentHref(hrefKey, anchor, content);
|
|
24376
|
-
if (!pointsAt(href, oldPath)) continue;
|
|
24377
|
-
const nextHref = retargetHref(href, oldPath, newPath);
|
|
24378
|
-
deps.applyLinkByKey(hrefKey, nextHref);
|
|
24379
|
-
delta[hrefKey] = nextHref;
|
|
24380
|
-
if (!oldTitle || !newTitle) continue;
|
|
24381
|
-
const labelKey = labelKeyFor(hrefKey);
|
|
24382
|
-
const label = content[labelKey] ?? anchor.querySelector('[data-ohw-editable="text"]')?.textContent ?? "";
|
|
24383
|
-
if (label.trim() !== oldTitle) continue;
|
|
24384
|
-
setLabelText(labelKey, newTitle);
|
|
24385
|
-
delta[labelKey] = newTitle;
|
|
24386
|
-
}
|
|
24387
|
-
commit(delta, deps);
|
|
24388
|
-
return Object.keys(delta).filter((key) => key.endsWith("-href")).length;
|
|
24389
|
-
}
|
|
24390
|
-
|
|
24391
24096
|
// src/ui/navbar-container-chrome.tsx
|
|
24392
|
-
import { Plus as
|
|
24097
|
+
import { Plus as Plus4 } from "lucide-react";
|
|
24393
24098
|
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
24394
24099
|
function NavbarContainerChrome({
|
|
24395
24100
|
rect,
|
|
@@ -24425,7 +24130,7 @@ function NavbarContainerChrome({
|
|
|
24425
24130
|
e.stopPropagation();
|
|
24426
24131
|
onAdd();
|
|
24427
24132
|
},
|
|
24428
|
-
children: /* @__PURE__ */ jsx37(
|
|
24133
|
+
children: /* @__PURE__ */ jsx37(Plus4, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
24429
24134
|
}
|
|
24430
24135
|
)
|
|
24431
24136
|
}
|
|
@@ -24497,7 +24202,7 @@ function Badge({ className, variant, ...props }) {
|
|
|
24497
24202
|
}
|
|
24498
24203
|
|
|
24499
24204
|
// src/OhhwellsBridge.tsx
|
|
24500
|
-
import { Brush as Brush2, Link as Link2, Plus as
|
|
24205
|
+
import { Brush as Brush2, Link as Link2, Plus as Plus5, Settings } from "lucide-react";
|
|
24501
24206
|
import { Fragment as Fragment13, jsx as jsx40, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
24502
24207
|
var PRIMARY7 = "#0885FE";
|
|
24503
24208
|
var IMAGE_FADE_MS = 300;
|
|
@@ -25275,7 +24980,7 @@ function getNavigationSelectionParent(el) {
|
|
|
25275
24980
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
25276
24981
|
return resolveFooterLinksContainerFrom(el);
|
|
25277
24982
|
}
|
|
25278
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
24983
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
25279
24984
|
return getNavigationRoot(el);
|
|
25280
24985
|
}
|
|
25281
24986
|
return null;
|
|
@@ -25497,6 +25202,7 @@ var ICONS = {
|
|
|
25497
25202
|
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"/>',
|
|
25498
25203
|
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"/>'
|
|
25499
25204
|
};
|
|
25205
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
25500
25206
|
var SELECTION_CHROME_GAP2 = 4;
|
|
25501
25207
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
25502
25208
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -25594,7 +25300,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
25594
25300
|
el.style.top = `${top}px`;
|
|
25595
25301
|
el.style.height = `${height}px`;
|
|
25596
25302
|
}
|
|
25597
|
-
var
|
|
25303
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
25598
25304
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
25599
25305
|
const isAbove = transform.includes("translateY(-100%)");
|
|
25600
25306
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -25621,8 +25327,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
25621
25327
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
25622
25328
|
const half = toolbarWidth / 2;
|
|
25623
25329
|
return Math.max(
|
|
25624
|
-
|
|
25625
|
-
Math.min(centerX, window.innerWidth -
|
|
25330
|
+
TOOLBAR_EDGE_MARGIN3 + half,
|
|
25331
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
|
|
25626
25332
|
);
|
|
25627
25333
|
}
|
|
25628
25334
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
@@ -26023,7 +25729,7 @@ function OhhwellsBridge() {
|
|
|
26023
25729
|
}, []);
|
|
26024
25730
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
26025
25731
|
const [subdomain, setSubdomain] = useState18(() => resolveSubdomain(subdomainFromQuery));
|
|
26026
|
-
|
|
25732
|
+
useLayoutEffect6(() => {
|
|
26027
25733
|
const next = resolveSubdomain(subdomainFromQuery);
|
|
26028
25734
|
if (next !== subdomain) setSubdomain(next);
|
|
26029
25735
|
if (next) return;
|
|
@@ -26504,6 +26210,21 @@ function OhhwellsBridge() {
|
|
|
26504
26210
|
const [isItemDragging, setIsItemDragging] = useState18(false);
|
|
26505
26211
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState18(false);
|
|
26506
26212
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
26213
|
+
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
26214
|
+
const floatingPanelOpenRef = useRef14(false);
|
|
26215
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
26216
|
+
const floatingPanelRef = useRef14(null);
|
|
26217
|
+
floatingPanelRef.current = floatingPanel;
|
|
26218
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
26219
|
+
const buttonCollectionDragRef = useRef14(null);
|
|
26220
|
+
const buttonDropInsertIndexRef = useRef14(null);
|
|
26221
|
+
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
26222
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
26223
|
+
const buttonPointerDragRef = useRef14(null);
|
|
26224
|
+
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
26225
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
26226
|
+
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
26227
|
+
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
26507
26228
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState18(null);
|
|
26508
26229
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState18(null);
|
|
26509
26230
|
const footerDragRef = useRef14(null);
|
|
@@ -26529,21 +26250,6 @@ function OhhwellsBridge() {
|
|
|
26529
26250
|
const stylesRef = useRef14("");
|
|
26530
26251
|
const appliedDrawerRef = useRef14(null);
|
|
26531
26252
|
const pendingDeleteUndoRef = useRef14(null);
|
|
26532
|
-
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
26533
|
-
const floatingPanelOpenRef = useRef14(false);
|
|
26534
|
-
const floatingPanelRef = useRef14(null);
|
|
26535
|
-
floatingPanelRef.current = floatingPanel;
|
|
26536
|
-
const setFloatingPanelRef = useRef14(setFloatingPanel);
|
|
26537
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
26538
|
-
const buttonCollectionDragRef = useRef14(null);
|
|
26539
|
-
const buttonDropInsertIndexRef = useRef14(null);
|
|
26540
|
-
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
26541
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
26542
|
-
const buttonPointerDragRef = useRef14(null);
|
|
26543
|
-
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
26544
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
26545
|
-
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
26546
|
-
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
26547
26253
|
const [sitePages, setSitePages] = useState18([]);
|
|
26548
26254
|
const collectionItemsRef = useRef14(/* @__PURE__ */ new Map());
|
|
26549
26255
|
const [sectionsByPath, setSectionsByPath] = useState18({});
|
|
@@ -26553,18 +26259,7 @@ function OhhwellsBridge() {
|
|
|
26553
26259
|
const linkPopoverOpenRef = useRef14(false);
|
|
26554
26260
|
const linkPopoverGraceUntilRef = useRef14(0);
|
|
26555
26261
|
setLinkPopoverRef.current = setLinkPopover;
|
|
26556
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
26557
26262
|
linkPopoverSessionRef.current = linkPopover;
|
|
26558
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
26559
|
-
useEffect19(() => {
|
|
26560
|
-
const syncViewport = () => {
|
|
26561
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
26562
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
26563
|
-
};
|
|
26564
|
-
syncViewport();
|
|
26565
|
-
window.addEventListener("resize", syncViewport);
|
|
26566
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
26567
|
-
}, []);
|
|
26568
26263
|
useEffect19(() => {
|
|
26569
26264
|
setSectionOrderPersistHandler((entries) => {
|
|
26570
26265
|
const currentPath = window.location.pathname;
|
|
@@ -26713,43 +26408,6 @@ function OhhwellsBridge() {
|
|
|
26713
26408
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
26714
26409
|
return () => window.removeEventListener("message", onSitePages);
|
|
26715
26410
|
}, [isEditMode, postToParent2]);
|
|
26716
|
-
useEffect19(() => {
|
|
26717
|
-
if (!isEditMode) return;
|
|
26718
|
-
const deps = {
|
|
26719
|
-
getEditContent: () => editContentRef.current,
|
|
26720
|
-
setEditContent: (next) => {
|
|
26721
|
-
editContentRef.current = next;
|
|
26722
|
-
},
|
|
26723
|
-
applyLinkByKey,
|
|
26724
|
-
postToParent: postToParent2
|
|
26725
|
-
};
|
|
26726
|
-
const onPageMessage = (e) => {
|
|
26727
|
-
if (e.data?.type === "ow:page-created") {
|
|
26728
|
-
const { path, title } = e.data;
|
|
26729
|
-
if (typeof path !== "string" || !path) return;
|
|
26730
|
-
if (addNavLinkForPage({ path, title: typeof title === "string" && title ? title : path }, deps)) {
|
|
26731
|
-
enforceLinkHrefs();
|
|
26732
|
-
}
|
|
26733
|
-
return;
|
|
26734
|
-
}
|
|
26735
|
-
if (e.data?.type === "ow:page-renamed") {
|
|
26736
|
-
const { oldPath, newPath, oldTitle, newTitle } = e.data;
|
|
26737
|
-
if (typeof oldPath !== "string" || typeof newPath !== "string") return;
|
|
26738
|
-
const moved = retargetPageLinks(
|
|
26739
|
-
{
|
|
26740
|
-
oldPath,
|
|
26741
|
-
newPath,
|
|
26742
|
-
oldTitle: typeof oldTitle === "string" ? oldTitle : void 0,
|
|
26743
|
-
newTitle: typeof newTitle === "string" ? newTitle : void 0
|
|
26744
|
-
},
|
|
26745
|
-
deps
|
|
26746
|
-
);
|
|
26747
|
-
if (moved > 0) enforceLinkHrefs();
|
|
26748
|
-
}
|
|
26749
|
-
};
|
|
26750
|
-
window.addEventListener("message", onPageMessage);
|
|
26751
|
-
return () => window.removeEventListener("message", onPageMessage);
|
|
26752
|
-
}, [isEditMode, postToParent2]);
|
|
26753
26411
|
useEffect19(() => {
|
|
26754
26412
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
26755
26413
|
void loadAllSectionsManifest().then((manifest) => {
|
|
@@ -28271,7 +27929,7 @@ function OhhwellsBridge() {
|
|
|
28271
27929
|
isFooterFrameSelection,
|
|
28272
27930
|
postToParent2
|
|
28273
27931
|
]);
|
|
28274
|
-
|
|
27932
|
+
useLayoutEffect6(() => {
|
|
28275
27933
|
if (!subdomain || isEditMode) {
|
|
28276
27934
|
setFetchState("done");
|
|
28277
27935
|
return;
|
|
@@ -28298,7 +27956,6 @@ function OhhwellsBridge() {
|
|
|
28298
27956
|
applyAiFooterFromContent(content);
|
|
28299
27957
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28300
27958
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
28301
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28302
27959
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28303
27960
|
}
|
|
28304
27961
|
applyBrandChrome(content);
|
|
@@ -28309,16 +27966,15 @@ function OhhwellsBridge() {
|
|
|
28309
27966
|
if (key === "__ohw_sections") continue;
|
|
28310
27967
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28311
27968
|
if (key === AI_FOOTER_KEY) continue;
|
|
28312
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28313
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28314
27969
|
if (key === BRAND_KIT_KEY) continue;
|
|
28315
27970
|
if (key === STYLE_STORE_KEY) continue;
|
|
28316
27971
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27972
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28317
27973
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
27974
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28318
27975
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28319
27976
|
continue;
|
|
28320
27977
|
}
|
|
28321
|
-
if (key.endsWith(SECTION_EMBED_SUFFIX)) continue;
|
|
28322
27978
|
if (applyVideoSettingNode(key, val)) continue;
|
|
28323
27979
|
if (applyCarouselNode(key, val)) continue;
|
|
28324
27980
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -28358,7 +28014,6 @@ function OhhwellsBridge() {
|
|
|
28358
28014
|
});
|
|
28359
28015
|
applyLinkByKey(key, val);
|
|
28360
28016
|
}
|
|
28361
|
-
applySectionEmbeds(content);
|
|
28362
28017
|
applyLogoFromContent(content);
|
|
28363
28018
|
applyLogoSizes(content);
|
|
28364
28019
|
reconcileNavbarItemsFromContent(content);
|
|
@@ -28547,22 +28202,20 @@ function OhhwellsBridge() {
|
|
|
28547
28202
|
}
|
|
28548
28203
|
applyAiFooterFromContent(content);
|
|
28549
28204
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28550
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28551
28205
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28552
28206
|
}
|
|
28553
28207
|
for (const [key, val] of Object.entries(content)) {
|
|
28554
28208
|
if (key === "__ohw_sections") continue;
|
|
28555
28209
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28556
28210
|
if (key === AI_FOOTER_KEY) continue;
|
|
28557
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28558
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28559
28211
|
if (key === BRAND_KIT_KEY) continue;
|
|
28560
28212
|
if (key === STYLE_STORE_KEY) continue;
|
|
28561
28213
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
28214
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28215
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
28562
28216
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28563
28217
|
continue;
|
|
28564
28218
|
}
|
|
28565
|
-
if (key.endsWith(SECTION_EMBED_SUFFIX)) continue;
|
|
28566
28219
|
if (applyVideoSettingNode(key, val)) continue;
|
|
28567
28220
|
if (applyCarouselNode(key, val)) continue;
|
|
28568
28221
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -28587,7 +28240,6 @@ function OhhwellsBridge() {
|
|
|
28587
28240
|
});
|
|
28588
28241
|
applyLinkByKey(key, val);
|
|
28589
28242
|
}
|
|
28590
|
-
applySectionEmbeds(content);
|
|
28591
28243
|
applyLogoFromContent(content);
|
|
28592
28244
|
reconcileNavbarItemsFromContent(content);
|
|
28593
28245
|
reconcileFooterOrderFromContent(content);
|
|
@@ -28643,7 +28295,7 @@ function OhhwellsBridge() {
|
|
|
28643
28295
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
28644
28296
|
};
|
|
28645
28297
|
}, [subdomain, isEditMode, pathname]);
|
|
28646
|
-
|
|
28298
|
+
useLayoutEffect6(() => {
|
|
28647
28299
|
const el = document.getElementById("ohw-loader");
|
|
28648
28300
|
if (!el) return;
|
|
28649
28301
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
@@ -28827,11 +28479,26 @@ function OhhwellsBridge() {
|
|
|
28827
28479
|
const t2 = setTimeout(measure, 500);
|
|
28828
28480
|
const ro = new ResizeObserver(schedule);
|
|
28829
28481
|
ro.observe(document.body);
|
|
28482
|
+
let lastWidth = window.innerWidth;
|
|
28483
|
+
let resizeTimers = [];
|
|
28484
|
+
const clearResizeTimers = () => {
|
|
28485
|
+
resizeTimers.forEach(clearTimeout);
|
|
28486
|
+
resizeTimers = [];
|
|
28487
|
+
};
|
|
28488
|
+
const handleResize = () => {
|
|
28489
|
+
if (window.innerWidth === lastWidth) return;
|
|
28490
|
+
lastWidth = window.innerWidth;
|
|
28491
|
+
clearResizeTimers();
|
|
28492
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
28493
|
+
};
|
|
28494
|
+
window.addEventListener("resize", handleResize);
|
|
28830
28495
|
return () => {
|
|
28831
28496
|
clearTimeout(t1);
|
|
28832
28497
|
clearTimeout(t2);
|
|
28833
28498
|
if (raf != null) cancelAnimationFrame(raf);
|
|
28834
28499
|
ro.disconnect();
|
|
28500
|
+
clearResizeTimers();
|
|
28501
|
+
window.removeEventListener("resize", handleResize);
|
|
28835
28502
|
};
|
|
28836
28503
|
}, [pathname, isEditMode, postToParent2]);
|
|
28837
28504
|
useEffect19(() => {
|
|
@@ -29128,13 +28795,6 @@ function OhhwellsBridge() {
|
|
|
29128
28795
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
29129
28796
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
29130
28797
|
if (isInsideLinkEditor(target)) return;
|
|
29131
|
-
if (isInsideFloatingPanel(target)) return;
|
|
29132
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
29133
|
-
if (target.closest(
|
|
29134
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
29135
|
-
)) {
|
|
29136
|
-
return;
|
|
29137
|
-
}
|
|
29138
28798
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
29139
28799
|
clearMediaSelectionRef.current();
|
|
29140
28800
|
}
|
|
@@ -29158,6 +28818,8 @@ function OhhwellsBridge() {
|
|
|
29158
28818
|
return;
|
|
29159
28819
|
}
|
|
29160
28820
|
}
|
|
28821
|
+
if (isInsideFloatingPanel(target)) return;
|
|
28822
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
29161
28823
|
const collectionItem = matchCollectionItemClick(target, collectionItemsRef.current);
|
|
29162
28824
|
if (collectionItem) {
|
|
29163
28825
|
e.preventDefault();
|
|
@@ -29169,6 +28831,11 @@ function OhhwellsBridge() {
|
|
|
29169
28831
|
});
|
|
29170
28832
|
return;
|
|
29171
28833
|
}
|
|
28834
|
+
if (target.closest(
|
|
28835
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
28836
|
+
)) {
|
|
28837
|
+
return;
|
|
28838
|
+
}
|
|
29172
28839
|
{
|
|
29173
28840
|
const formEl = getFormElement(target);
|
|
29174
28841
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -29322,13 +28989,9 @@ function OhhwellsBridge() {
|
|
|
29322
28989
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
29323
28990
|
e.preventDefault();
|
|
29324
28991
|
e.stopPropagation();
|
|
28992
|
+
selectIconElementRef.current(editable);
|
|
29325
28993
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
29326
28994
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
29327
|
-
if (aiIcon) {
|
|
29328
|
-
aiSectionApiRef.current?.selectFromElement(editable);
|
|
29329
|
-
} else {
|
|
29330
|
-
selectIconElementRef.current(editable);
|
|
29331
|
-
}
|
|
29332
28995
|
postToParentRef.current({
|
|
29333
28996
|
type: "ow:icon-pick",
|
|
29334
28997
|
key: editable.dataset.ohwKey ?? "",
|
|
@@ -29556,9 +29219,6 @@ function OhhwellsBridge() {
|
|
|
29556
29219
|
setHoveredItemRect(null);
|
|
29557
29220
|
hoveredNavContainerRef.current = null;
|
|
29558
29221
|
setHoveredNavContainerRect(null);
|
|
29559
|
-
siblingHintElRef.current = null;
|
|
29560
|
-
setSiblingHintRect(null);
|
|
29561
|
-
setSiblingHintRects([]);
|
|
29562
29222
|
return;
|
|
29563
29223
|
}
|
|
29564
29224
|
{
|
|
@@ -29679,6 +29339,7 @@ function OhhwellsBridge() {
|
|
|
29679
29339
|
hoveredNavContainerRef.current = null;
|
|
29680
29340
|
setHoveredNavContainerRect(null);
|
|
29681
29341
|
hoveredItemElRef.current = editable;
|
|
29342
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
29682
29343
|
}
|
|
29683
29344
|
}
|
|
29684
29345
|
}
|
|
@@ -30388,11 +30049,7 @@ function OhhwellsBridge() {
|
|
|
30388
30049
|
};
|
|
30389
30050
|
const handleMouseMove = (e) => {
|
|
30390
30051
|
const { clientX, clientY } = e;
|
|
30391
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
30392
|
-
dismissImageHover();
|
|
30393
|
-
clearImageHover();
|
|
30394
|
-
return;
|
|
30395
|
-
}
|
|
30052
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
30396
30053
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
30397
30054
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
30398
30055
|
formHoverElRef.current = null;
|
|
@@ -30421,12 +30078,7 @@ function OhhwellsBridge() {
|
|
|
30421
30078
|
setHoveredItemRect(null);
|
|
30422
30079
|
hoveredNavContainerRef.current = null;
|
|
30423
30080
|
setHoveredNavContainerRect(null);
|
|
30424
|
-
siblingHintElRef.current = null;
|
|
30425
|
-
setSiblingHintRect(null);
|
|
30426
|
-
setSiblingHintRects([]);
|
|
30427
30081
|
dismissImageHover();
|
|
30428
|
-
clearImageHover();
|
|
30429
|
-
setSectionGap(null);
|
|
30430
30082
|
return;
|
|
30431
30083
|
}
|
|
30432
30084
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -30438,11 +30090,7 @@ function OhhwellsBridge() {
|
|
|
30438
30090
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
30439
30091
|
const { clientX, clientY } = e.data;
|
|
30440
30092
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
30441
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
30442
|
-
dismissImageHover();
|
|
30443
|
-
clearImageHover();
|
|
30444
|
-
return;
|
|
30445
|
-
}
|
|
30093
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
30446
30094
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
30447
30095
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
30448
30096
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -30822,7 +30470,6 @@ function OhhwellsBridge() {
|
|
|
30822
30470
|
applyAiFooterFromContent(content);
|
|
30823
30471
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
30824
30472
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
30825
|
-
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
30826
30473
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
30827
30474
|
}
|
|
30828
30475
|
applyBrandChrome(content);
|
|
@@ -30837,16 +30484,15 @@ function OhhwellsBridge() {
|
|
|
30837
30484
|
}
|
|
30838
30485
|
if (key === AI_SECTIONS_KEY) continue;
|
|
30839
30486
|
if (key === AI_FOOTER_KEY) continue;
|
|
30840
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30841
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30842
30487
|
if (key === BRAND_KIT_KEY) continue;
|
|
30843
30488
|
if (key === STYLE_STORE_KEY) continue;
|
|
30844
30489
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
30490
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
30845
30491
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
30492
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
30846
30493
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
30847
30494
|
continue;
|
|
30848
30495
|
}
|
|
30849
|
-
if (key.endsWith(SECTION_EMBED_SUFFIX)) continue;
|
|
30850
30496
|
if (applyVideoSettingNode(key, val)) continue;
|
|
30851
30497
|
if (applyCarouselNode(key, val)) continue;
|
|
30852
30498
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -30872,7 +30518,6 @@ function OhhwellsBridge() {
|
|
|
30872
30518
|
});
|
|
30873
30519
|
applyLinkByKey(key, val);
|
|
30874
30520
|
}
|
|
30875
|
-
applySectionEmbeds(content);
|
|
30876
30521
|
applyLogoFromContent(content);
|
|
30877
30522
|
applyLogoSizes(content);
|
|
30878
30523
|
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
@@ -31480,12 +31125,6 @@ function OhhwellsBridge() {
|
|
|
31480
31125
|
closeLinkPopoverRef.current();
|
|
31481
31126
|
return;
|
|
31482
31127
|
}
|
|
31483
|
-
if (floatingPanelOpenRef.current) {
|
|
31484
|
-
setFloatingPanelRef.current(null);
|
|
31485
|
-
deselectRef.current();
|
|
31486
|
-
deactivateRef.current();
|
|
31487
|
-
return;
|
|
31488
|
-
}
|
|
31489
31128
|
deselectRef.current();
|
|
31490
31129
|
deactivateRef.current();
|
|
31491
31130
|
clearMediaSelectionRef.current();
|
|
@@ -32321,10 +31960,10 @@ function OhhwellsBridge() {
|
|
|
32321
31960
|
window.removeEventListener("message", handleDuplicateSection);
|
|
32322
31961
|
window.removeEventListener("message", handleDeactivate);
|
|
32323
31962
|
window.removeEventListener("message", handleSelectNav);
|
|
31963
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
32324
31964
|
window.removeEventListener("message", handleToastAction);
|
|
32325
31965
|
window.removeEventListener("message", handleFormCount);
|
|
32326
31966
|
window.removeEventListener("message", handleUiEscape);
|
|
32327
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
32328
31967
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
32329
31968
|
autoSaveTimers.current.clear();
|
|
32330
31969
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -32618,7 +32257,7 @@ function OhhwellsBridge() {
|
|
|
32618
32257
|
postToParent2({
|
|
32619
32258
|
type: "ow:ready",
|
|
32620
32259
|
version: "1",
|
|
32621
|
-
bridgeVersion: "0.1.
|
|
32260
|
+
bridgeVersion: "0.1.161",
|
|
32622
32261
|
path: pathname,
|
|
32623
32262
|
nodes: collectEditableNodes(editContentRef.current),
|
|
32624
32263
|
sections
|
|
@@ -33353,7 +32992,7 @@ function OhhwellsBridge() {
|
|
|
33353
32992
|
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
|
|
33354
32993
|
onClick: () => setFieldTypePickerOpen((open) => !open),
|
|
33355
32994
|
"data-ohw-add-field": "",
|
|
33356
|
-
children: /* @__PURE__ */ jsx40(
|
|
32995
|
+
children: /* @__PURE__ */ jsx40(Plus5, { size: 15, "aria-hidden": true })
|
|
33357
32996
|
}
|
|
33358
32997
|
),
|
|
33359
32998
|
/* @__PURE__ */ jsx40("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|