@ohhwells/bridge 0.1.139-next.382 → 0.1.139-next.383
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +667 -645
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +716 -678
- package/dist/index.js.map +1 -1
- package/dist/styles.css +73 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -17960,7 +17960,7 @@ function AiSectionOverlay({
|
|
|
17960
17960
|
|
|
17961
17961
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
17962
17962
|
var import_react10 = require("react");
|
|
17963
|
-
var
|
|
17963
|
+
var import_lucide_react9 = require("lucide-react");
|
|
17964
17964
|
|
|
17965
17965
|
// src/lib/ai-media-strip-tree.ts
|
|
17966
17966
|
var MEDIA_STRIP_ITEM_MIN = 1;
|
|
@@ -18074,14 +18074,6 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
18074
18074
|
return true;
|
|
18075
18075
|
});
|
|
18076
18076
|
}
|
|
18077
|
-
function setMediaStripItemAlt(tree, index, alt) {
|
|
18078
|
-
return withMediaStrip(tree, (block) => {
|
|
18079
|
-
const items = block.items;
|
|
18080
|
-
if (index < 0 || index >= items.length) return false;
|
|
18081
|
-
items[index] = { ...items[index], alt };
|
|
18082
|
-
return true;
|
|
18083
|
-
});
|
|
18084
|
-
}
|
|
18085
18077
|
function setMediaStripItemLink(tree, index, link) {
|
|
18086
18078
|
return withMediaStrip(tree, (block) => {
|
|
18087
18079
|
const items = block.items;
|
|
@@ -18099,11 +18091,117 @@ function setMediaStripItemLink(tree, index, link) {
|
|
|
18099
18091
|
});
|
|
18100
18092
|
}
|
|
18101
18093
|
|
|
18102
|
-
// src/ui/
|
|
18094
|
+
// src/ui/dialog.tsx
|
|
18095
|
+
var React9 = __toESM(require("react"), 1);
|
|
18096
|
+
var import_radix_ui6 = require("radix-ui");
|
|
18097
|
+
var import_lucide_react8 = require("lucide-react");
|
|
18103
18098
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
18104
|
-
|
|
18105
|
-
|
|
18106
|
-
|
|
18099
|
+
function Dialog2({
|
|
18100
|
+
...props
|
|
18101
|
+
}) {
|
|
18102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
18103
|
+
}
|
|
18104
|
+
function DialogPortal({
|
|
18105
|
+
...props
|
|
18106
|
+
}) {
|
|
18107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
18108
|
+
}
|
|
18109
|
+
function DialogOverlay({
|
|
18110
|
+
className,
|
|
18111
|
+
...props
|
|
18112
|
+
}) {
|
|
18113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18114
|
+
import_radix_ui6.Dialog.Overlay,
|
|
18115
|
+
{
|
|
18116
|
+
"data-slot": "dialog-overlay",
|
|
18117
|
+
"data-ohw-link-modal-root": "",
|
|
18118
|
+
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
18119
|
+
...props
|
|
18120
|
+
}
|
|
18121
|
+
);
|
|
18122
|
+
}
|
|
18123
|
+
var DialogContent = React9.forwardRef(
|
|
18124
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
18125
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
18126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
18127
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
18128
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18129
|
+
import_radix_ui6.Dialog.Content,
|
|
18130
|
+
{
|
|
18131
|
+
ref,
|
|
18132
|
+
"data-slot": "dialog-content",
|
|
18133
|
+
className: cn(
|
|
18134
|
+
positionMode,
|
|
18135
|
+
"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",
|
|
18136
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
18137
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
18138
|
+
className
|
|
18139
|
+
),
|
|
18140
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
18141
|
+
...props,
|
|
18142
|
+
children: [
|
|
18143
|
+
children,
|
|
18144
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18145
|
+
import_radix_ui6.Dialog.Close,
|
|
18146
|
+
{
|
|
18147
|
+
type: "button",
|
|
18148
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
18149
|
+
"aria-label": "Close",
|
|
18150
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
18151
|
+
}
|
|
18152
|
+
) : null
|
|
18153
|
+
]
|
|
18154
|
+
}
|
|
18155
|
+
)
|
|
18156
|
+
] });
|
|
18157
|
+
}
|
|
18158
|
+
);
|
|
18159
|
+
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
18160
|
+
function DialogHeader({
|
|
18161
|
+
className,
|
|
18162
|
+
...props
|
|
18163
|
+
}) {
|
|
18164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
18165
|
+
}
|
|
18166
|
+
function DialogFooter({
|
|
18167
|
+
className,
|
|
18168
|
+
...props
|
|
18169
|
+
}) {
|
|
18170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18171
|
+
"div",
|
|
18172
|
+
{
|
|
18173
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
18174
|
+
...props
|
|
18175
|
+
}
|
|
18176
|
+
);
|
|
18177
|
+
}
|
|
18178
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18179
|
+
import_radix_ui6.Dialog.Title,
|
|
18180
|
+
{
|
|
18181
|
+
ref,
|
|
18182
|
+
className: cn(
|
|
18183
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
18184
|
+
className
|
|
18185
|
+
),
|
|
18186
|
+
...props
|
|
18187
|
+
}
|
|
18188
|
+
));
|
|
18189
|
+
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
18190
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18191
|
+
import_radix_ui6.Dialog.Description,
|
|
18192
|
+
{
|
|
18193
|
+
ref,
|
|
18194
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
18195
|
+
...props
|
|
18196
|
+
}
|
|
18197
|
+
));
|
|
18198
|
+
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
18199
|
+
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
18200
|
+
|
|
18201
|
+
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
18202
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
18203
|
+
var PRIMARY3 = "var(--ohw-primary, #0885FE)";
|
|
18204
|
+
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]";
|
|
18107
18205
|
function findMediaStripItemElement(sectionId, index) {
|
|
18108
18206
|
const sectionEl = findByInstanceId(sectionId);
|
|
18109
18207
|
if (!sectionEl) return null;
|
|
@@ -18113,14 +18211,35 @@ function findMediaStripItemElement(sectionId, index) {
|
|
|
18113
18211
|
}
|
|
18114
18212
|
return null;
|
|
18115
18213
|
}
|
|
18116
|
-
function
|
|
18117
|
-
|
|
18214
|
+
function itemRefFromTarget(target) {
|
|
18215
|
+
if (!(target instanceof Element)) return null;
|
|
18216
|
+
if (target.closest(CHROME_SELECTOR)) return null;
|
|
18217
|
+
const itemEl = target.closest("[data-ohw-media-strip-item]");
|
|
18218
|
+
if (!itemEl) return null;
|
|
18219
|
+
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18220
|
+
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18221
|
+
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18222
|
+
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18223
|
+
if (!sectionId || Number.isNaN(index)) return null;
|
|
18224
|
+
return { sectionId, index };
|
|
18225
|
+
}
|
|
18226
|
+
function sameRef(a, b) {
|
|
18227
|
+
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18228
|
+
}
|
|
18229
|
+
function rectOf(el) {
|
|
18118
18230
|
if (!el) return null;
|
|
18119
18231
|
const r2 = el.getBoundingClientRect();
|
|
18120
18232
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18121
18233
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18122
18234
|
}
|
|
18123
|
-
function
|
|
18235
|
+
function readRect2(ref) {
|
|
18236
|
+
return rectOf(ref && findMediaStripItemElement(ref.sectionId, ref.index));
|
|
18237
|
+
}
|
|
18238
|
+
function readStripRect(ref) {
|
|
18239
|
+
const item = ref && findMediaStripItemElement(ref.sectionId, ref.index);
|
|
18240
|
+
return rectOf(item?.closest("[data-ohw-media-strip]") ?? item);
|
|
18241
|
+
}
|
|
18242
|
+
function useLiveItemRect(ref, strip = false) {
|
|
18124
18243
|
const [rect, setRect] = (0, import_react10.useState)(null);
|
|
18125
18244
|
(0, import_react10.useEffect)(() => {
|
|
18126
18245
|
if (!ref) {
|
|
@@ -18128,7 +18247,7 @@ function useLiveItemRect(ref) {
|
|
|
18128
18247
|
return;
|
|
18129
18248
|
}
|
|
18130
18249
|
const update = () => {
|
|
18131
|
-
const next = readRect2(ref);
|
|
18250
|
+
const next = strip ? readStripRect(ref) : readRect2(ref);
|
|
18132
18251
|
setRect(
|
|
18133
18252
|
(prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
18134
18253
|
);
|
|
@@ -18143,9 +18262,49 @@ function useLiveItemRect(ref) {
|
|
|
18143
18262
|
window.removeEventListener("resize", update);
|
|
18144
18263
|
clearInterval(interval);
|
|
18145
18264
|
};
|
|
18146
|
-
}, [ref?.sectionId, ref?.index]);
|
|
18265
|
+
}, [ref?.sectionId, ref?.index, strip]);
|
|
18147
18266
|
return rect;
|
|
18148
18267
|
}
|
|
18268
|
+
var TOOLBAR_STRIP_GAP = 52;
|
|
18269
|
+
var TOOLBAR_STRIP_GAP_MOBILE = 42;
|
|
18270
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
18271
|
+
function StripToolbarSlot({ stripRect, children }) {
|
|
18272
|
+
const slotRef = (0, import_react10.useRef)(null);
|
|
18273
|
+
const [shift, setShift] = (0, import_react10.useState)(0);
|
|
18274
|
+
const centerX = stripRect.left + stripRect.width / 2;
|
|
18275
|
+
(0, import_react10.useLayoutEffect)(() => {
|
|
18276
|
+
const slot = slotRef.current;
|
|
18277
|
+
if (!slot) return;
|
|
18278
|
+
const clamp = () => {
|
|
18279
|
+
const w = slot.offsetWidth;
|
|
18280
|
+
if (w <= 0) return;
|
|
18281
|
+
const half = w / 2;
|
|
18282
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
|
|
18283
|
+
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18284
|
+
};
|
|
18285
|
+
clamp();
|
|
18286
|
+
const ro = new ResizeObserver(clamp);
|
|
18287
|
+
ro.observe(slot);
|
|
18288
|
+
return () => ro.disconnect();
|
|
18289
|
+
}, [centerX, children]);
|
|
18290
|
+
const mobile = window.innerWidth <= 480;
|
|
18291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18292
|
+
"div",
|
|
18293
|
+
{
|
|
18294
|
+
ref: slotRef,
|
|
18295
|
+
"data-ohw-bridge": "",
|
|
18296
|
+
"data-ohw-item-interaction": "",
|
|
18297
|
+
className: "pointer-events-auto fixed",
|
|
18298
|
+
style: {
|
|
18299
|
+
top: stripRect.top - (mobile ? TOOLBAR_STRIP_GAP_MOBILE : TOOLBAR_STRIP_GAP),
|
|
18300
|
+
left: centerX + shift,
|
|
18301
|
+
transform: "translate(-50%, -100%)",
|
|
18302
|
+
zIndex: 2147483645
|
|
18303
|
+
},
|
|
18304
|
+
children
|
|
18305
|
+
}
|
|
18306
|
+
);
|
|
18307
|
+
}
|
|
18149
18308
|
function requestValidateTree(postToParent2, tree) {
|
|
18150
18309
|
return new Promise((resolve) => {
|
|
18151
18310
|
const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -18182,116 +18341,72 @@ function requestAssetPick(postToParent2) {
|
|
|
18182
18341
|
postToParent2({ type: "ow:asset-pick", id });
|
|
18183
18342
|
});
|
|
18184
18343
|
}
|
|
18185
|
-
function
|
|
18344
|
+
function ToolbarAction({
|
|
18186
18345
|
label,
|
|
18187
18346
|
onClick,
|
|
18188
|
-
disabled,
|
|
18189
|
-
active
|
|
18347
|
+
disabled = false,
|
|
18348
|
+
active = false,
|
|
18349
|
+
children
|
|
18190
18350
|
}) {
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
{
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
disabled,
|
|
18197
|
-
style: {
|
|
18198
|
-
height: 28,
|
|
18199
|
-
padding: "0 10px",
|
|
18200
|
-
display: "inline-flex",
|
|
18201
|
-
alignItems: "center",
|
|
18202
|
-
gap: 4,
|
|
18203
|
-
borderRadius: 999,
|
|
18204
|
-
border: "none",
|
|
18205
|
-
cursor: disabled ? "default" : "pointer",
|
|
18206
|
-
background: active ? OHW_BLUE_DARK : "#ffffff",
|
|
18207
|
-
color: active ? "#ffffff" : OHW_BLUE_DARK,
|
|
18208
|
-
opacity: disabled ? 0.4 : 1,
|
|
18209
|
-
fontSize: 12,
|
|
18210
|
-
lineHeight: "16px",
|
|
18211
|
-
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18212
|
-
whiteSpace: "nowrap",
|
|
18213
|
-
flex: "0 0 auto"
|
|
18214
|
-
},
|
|
18215
|
-
children: label
|
|
18216
|
-
}
|
|
18217
|
-
);
|
|
18351
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, active, onClick, className: "size-8", children });
|
|
18352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18353
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
18354
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
18355
|
+
] });
|
|
18218
18356
|
}
|
|
18219
|
-
function
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
},
|
|
18249
|
-
children: "Alt"
|
|
18250
|
-
}
|
|
18251
|
-
),
|
|
18252
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18253
|
-
"input",
|
|
18357
|
+
function ToolbarSeparator() {
|
|
18358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
18359
|
+
}
|
|
18360
|
+
function OptionMenu({
|
|
18361
|
+
label,
|
|
18362
|
+
value,
|
|
18363
|
+
options,
|
|
18364
|
+
onChange
|
|
18365
|
+
}) {
|
|
18366
|
+
const current = options.find((o) => o.value === value) ?? options[0];
|
|
18367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18368
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: label }),
|
|
18369
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
|
|
18370
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18371
|
+
"button",
|
|
18372
|
+
{
|
|
18373
|
+
type: "button",
|
|
18374
|
+
"aria-label": label,
|
|
18375
|
+
className: "inline-flex h-8 min-w-[76px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
|
|
18376
|
+
children: [
|
|
18377
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
18378
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18379
|
+
]
|
|
18380
|
+
}
|
|
18381
|
+
) }),
|
|
18382
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[132px] min-w-[132px] p-1", children: options.map((option) => {
|
|
18383
|
+
const selected = option.value === value;
|
|
18384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18385
|
+
DropdownMenuItem,
|
|
18254
18386
|
{
|
|
18255
|
-
|
|
18256
|
-
|
|
18257
|
-
|
|
18258
|
-
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
"aria-label": "Image alt text",
|
|
18270
|
-
style: {
|
|
18271
|
-
flex: 1,
|
|
18272
|
-
minWidth: 0,
|
|
18273
|
-
border: "none",
|
|
18274
|
-
outline: "none",
|
|
18275
|
-
background: "transparent",
|
|
18276
|
-
fontSize: 12,
|
|
18277
|
-
lineHeight: "16px",
|
|
18278
|
-
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18279
|
-
color: "#1f2937"
|
|
18280
|
-
}
|
|
18281
|
-
}
|
|
18282
|
-
)
|
|
18283
|
-
]
|
|
18284
|
-
}
|
|
18285
|
-
);
|
|
18387
|
+
role: "menuitemradio",
|
|
18388
|
+
"aria-checked": selected,
|
|
18389
|
+
onSelect: () => onChange(option.value),
|
|
18390
|
+
className: cn("grid grid-cols-[1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
18391
|
+
children: [
|
|
18392
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: option.label }),
|
|
18393
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
|
|
18394
|
+
]
|
|
18395
|
+
},
|
|
18396
|
+
option.value
|
|
18397
|
+
);
|
|
18398
|
+
}) })
|
|
18399
|
+
] })
|
|
18400
|
+
] });
|
|
18286
18401
|
}
|
|
18287
18402
|
var VARIANTS = [
|
|
18288
18403
|
{ value: "logos", label: "Logos" },
|
|
18289
18404
|
{ value: "reel", label: "Reel" }
|
|
18290
18405
|
];
|
|
18291
18406
|
var ALIGNS = [
|
|
18292
|
-
{ value: "left", label: "
|
|
18293
|
-
{ value: "center", label: "
|
|
18294
|
-
{ value: "right", label: "
|
|
18407
|
+
{ value: "left", label: "Align left", Icon: import_lucide_react9.AlignLeft },
|
|
18408
|
+
{ value: "center", label: "Align center", Icon: import_lucide_react9.AlignCenter },
|
|
18409
|
+
{ value: "right", label: "Align right", Icon: import_lucide_react9.AlignRight }
|
|
18295
18410
|
];
|
|
18296
18411
|
var HOVERS = [
|
|
18297
18412
|
{ value: "none", label: "None" },
|
|
@@ -18299,104 +18414,104 @@ var HOVERS = [
|
|
|
18299
18414
|
{ value: "zoom", label: "Zoom" },
|
|
18300
18415
|
{ value: "fade", label: "Fade" }
|
|
18301
18416
|
];
|
|
18302
|
-
var TREATMENTS = [
|
|
18303
|
-
{ value: "color", label: "Color" },
|
|
18304
|
-
{ value: "grayscale", label: "Grayscale" }
|
|
18305
|
-
];
|
|
18306
18417
|
var HTTP_URL_RE = /^https?:\/\/\S+$/i;
|
|
18307
|
-
function
|
|
18308
|
-
|
|
18418
|
+
function LinkModal({
|
|
18419
|
+
href,
|
|
18420
|
+
linkTarget,
|
|
18421
|
+
onClose,
|
|
18422
|
+
onSave
|
|
18423
|
+
}) {
|
|
18424
|
+
const [draft, setDraft] = (0, import_react10.useState)(href);
|
|
18425
|
+
const [newTab, setNewTab] = (0, import_react10.useState)(linkTarget !== "same-tab");
|
|
18309
18426
|
const [invalid, setInvalid] = (0, import_react10.useState)(false);
|
|
18310
|
-
|
|
18311
|
-
setDraft(value);
|
|
18312
|
-
setInvalid(false);
|
|
18313
|
-
}, [value]);
|
|
18314
|
-
const commit = () => {
|
|
18427
|
+
const save = () => {
|
|
18315
18428
|
const next = draft.trim();
|
|
18316
|
-
if (next
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
onCommit(next);
|
|
18320
|
-
};
|
|
18321
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18322
|
-
"div",
|
|
18323
|
-
{
|
|
18324
|
-
style: {
|
|
18325
|
-
display: "flex",
|
|
18326
|
-
alignItems: "center",
|
|
18327
|
-
gap: 6,
|
|
18328
|
-
height: 28,
|
|
18329
|
-
padding: "0 12px",
|
|
18330
|
-
borderRadius: 999,
|
|
18331
|
-
background: "#ffffff",
|
|
18332
|
-
width: "100%",
|
|
18333
|
-
maxWidth: 260,
|
|
18334
|
-
boxSizing: "border-box",
|
|
18335
|
-
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
18336
|
-
},
|
|
18337
|
-
children: [
|
|
18338
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18339
|
-
"span",
|
|
18340
|
-
{
|
|
18341
|
-
style: {
|
|
18342
|
-
flex: "0 0 auto",
|
|
18343
|
-
color: OHW_BLUE_DARK,
|
|
18344
|
-
fontSize: 10,
|
|
18345
|
-
fontWeight: 700,
|
|
18346
|
-
textTransform: "uppercase",
|
|
18347
|
-
letterSpacing: 0.4
|
|
18348
|
-
},
|
|
18349
|
-
children: "Link"
|
|
18350
|
-
}
|
|
18351
|
-
),
|
|
18352
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18353
|
-
"input",
|
|
18354
|
-
{
|
|
18355
|
-
type: "text",
|
|
18356
|
-
inputMode: "url",
|
|
18357
|
-
value: draft,
|
|
18358
|
-
onChange: (e) => setDraft(e.target.value),
|
|
18359
|
-
onBlur: commit,
|
|
18360
|
-
onKeyDown: (e) => {
|
|
18361
|
-
if (e.key === "Enter") e.currentTarget.blur();
|
|
18362
|
-
if (e.key === "Escape") {
|
|
18363
|
-
setDraft(value);
|
|
18364
|
-
setInvalid(false);
|
|
18365
|
-
e.currentTarget.blur();
|
|
18366
|
-
}
|
|
18367
|
-
},
|
|
18368
|
-
placeholder: "https://example.com",
|
|
18369
|
-
"aria-label": "Image link URL",
|
|
18370
|
-
"aria-invalid": invalid,
|
|
18371
|
-
style: {
|
|
18372
|
-
flex: 1,
|
|
18373
|
-
minWidth: 0,
|
|
18374
|
-
border: "none",
|
|
18375
|
-
outline: "none",
|
|
18376
|
-
background: "transparent",
|
|
18377
|
-
fontSize: 12,
|
|
18378
|
-
lineHeight: "16px",
|
|
18379
|
-
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
18380
|
-
color: "#1f2937"
|
|
18381
|
-
}
|
|
18382
|
-
}
|
|
18383
|
-
)
|
|
18384
|
-
]
|
|
18429
|
+
if (next && !HTTP_URL_RE.test(next)) {
|
|
18430
|
+
setInvalid(true);
|
|
18431
|
+
return;
|
|
18385
18432
|
}
|
|
18386
|
-
|
|
18433
|
+
onSave(next, newTab ? "new-tab" : "same-tab");
|
|
18434
|
+
onClose();
|
|
18435
|
+
};
|
|
18436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog2, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogContent, { "data-ohw-link-modal-root": "", className: "max-w-[400px] gap-4 p-5", children: [
|
|
18437
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogTitle, { className: "text-base", children: "Image link" }) }),
|
|
18438
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-3", children: [
|
|
18439
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18440
|
+
"input",
|
|
18441
|
+
{
|
|
18442
|
+
autoFocus: true,
|
|
18443
|
+
type: "text",
|
|
18444
|
+
inputMode: "url",
|
|
18445
|
+
value: draft,
|
|
18446
|
+
onChange: (e) => {
|
|
18447
|
+
setDraft(e.target.value);
|
|
18448
|
+
setInvalid(false);
|
|
18449
|
+
},
|
|
18450
|
+
onKeyDown: (e) => {
|
|
18451
|
+
if (e.key === "Enter") save();
|
|
18452
|
+
},
|
|
18453
|
+
placeholder: "https://example.com",
|
|
18454
|
+
"aria-label": "Image link URL",
|
|
18455
|
+
"aria-invalid": invalid,
|
|
18456
|
+
className: cn(
|
|
18457
|
+
"h-9 w-full rounded-[6px] border border-border bg-background px-3 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/70 focus:border-bridge-primary",
|
|
18458
|
+
invalid && "border-destructive focus:border-destructive"
|
|
18459
|
+
)
|
|
18460
|
+
}
|
|
18461
|
+
),
|
|
18462
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-xs text-destructive", children: "Enter a full URL starting with http:// or https://" }),
|
|
18463
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: "flex items-center gap-2 text-[13px] text-foreground", children: [
|
|
18464
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { type: "checkbox", checked: newTab, onChange: (e) => setNewTab(e.target.checked) }),
|
|
18465
|
+
"Open in new tab"
|
|
18466
|
+
] })
|
|
18467
|
+
] }),
|
|
18468
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogFooter, { children: [
|
|
18469
|
+
href && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18470
|
+
"button",
|
|
18471
|
+
{
|
|
18472
|
+
type: "button",
|
|
18473
|
+
onClick: () => {
|
|
18474
|
+
onSave("", "new-tab");
|
|
18475
|
+
onClose();
|
|
18476
|
+
},
|
|
18477
|
+
className: "mr-auto rounded-[6px] px-3 py-2 text-[13px] font-medium text-destructive transition-colors hover:bg-muted",
|
|
18478
|
+
children: "Remove link"
|
|
18479
|
+
}
|
|
18480
|
+
),
|
|
18481
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18482
|
+
"button",
|
|
18483
|
+
{
|
|
18484
|
+
type: "button",
|
|
18485
|
+
onClick: onClose,
|
|
18486
|
+
className: "rounded-[6px] px-3 py-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted",
|
|
18487
|
+
children: "Cancel"
|
|
18488
|
+
}
|
|
18489
|
+
),
|
|
18490
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18491
|
+
"button",
|
|
18492
|
+
{
|
|
18493
|
+
type: "button",
|
|
18494
|
+
onClick: save,
|
|
18495
|
+
className: "rounded-[6px] bg-bridge-primary px-3 py-2 text-[13px] font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
18496
|
+
children: "Save"
|
|
18497
|
+
}
|
|
18498
|
+
)
|
|
18499
|
+
] })
|
|
18500
|
+
] }) });
|
|
18387
18501
|
}
|
|
18388
18502
|
function MediaStripToolbar({
|
|
18389
18503
|
entry,
|
|
18390
18504
|
index,
|
|
18391
18505
|
pending,
|
|
18392
18506
|
error,
|
|
18507
|
+
itemEditOn,
|
|
18508
|
+
onToggleItemEdit,
|
|
18393
18509
|
onSetVariant,
|
|
18394
18510
|
onSetAlign,
|
|
18395
18511
|
onSetHover,
|
|
18396
18512
|
onSetTreatment,
|
|
18397
18513
|
onResize,
|
|
18398
|
-
|
|
18399
|
-
onSetLink,
|
|
18514
|
+
onOpenLink,
|
|
18400
18515
|
onAddItem,
|
|
18401
18516
|
onRemoveItem,
|
|
18402
18517
|
onChangeImage,
|
|
@@ -18405,81 +18520,102 @@ function MediaStripToolbar({
|
|
|
18405
18520
|
}) {
|
|
18406
18521
|
const items = mediaStripItems(entry.tree);
|
|
18407
18522
|
const itemCount = items.length;
|
|
18408
|
-
const currentAlt = items[index]?.alt ?? "";
|
|
18409
|
-
const currentHref = items[index]?.href ?? "";
|
|
18410
|
-
const currentTarget = items[index]?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18411
18523
|
const slots = findMediaStripSlots(entry.tree);
|
|
18412
18524
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18413
18525
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
18414
18526
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "lift";
|
|
18415
18527
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
18416
18528
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18417
|
-
const
|
|
18418
|
-
const
|
|
18419
|
-
|
|
18420
|
-
gap: 6,
|
|
18421
|
-
flexWrap: "nowrap",
|
|
18422
|
-
justifyContent: "center",
|
|
18423
|
-
overflowX: "auto",
|
|
18424
|
-
WebkitOverflowScrolling: "touch",
|
|
18425
|
-
width: "100%",
|
|
18426
|
-
scrollbarWidth: "none"
|
|
18427
|
-
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
18428
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
18529
|
+
const mobile = window.innerWidth <= 480;
|
|
18530
|
+
const gatedLabel = (label) => itemEditOn ? label : "Turn on the star to edit this image";
|
|
18531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18429
18532
|
"div",
|
|
18430
18533
|
{
|
|
18431
18534
|
"data-ohw-bridge": "",
|
|
18432
18535
|
"data-ohw-toolbar": "",
|
|
18433
18536
|
onMouseDown: (e) => e.stopPropagation(),
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
flexDirection: "column",
|
|
18437
|
-
gap: 6,
|
|
18438
|
-
alignItems: "center",
|
|
18439
|
-
background: OHW_BLUE,
|
|
18440
|
-
padding: 8,
|
|
18441
|
-
borderRadius: 12,
|
|
18442
|
-
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
18443
|
-
pointerEvents: pending ? "none" : "auto",
|
|
18444
|
-
opacity: pending ? 0.6 : 1,
|
|
18445
|
-
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
18446
|
-
},
|
|
18537
|
+
className: cn("flex flex-col items-center gap-1.5 font-sans", pending && "pointer-events-none opacity-60"),
|
|
18538
|
+
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
18447
18539
|
children: [
|
|
18448
|
-
/* @__PURE__ */ (0,
|
|
18449
|
-
|
|
18450
|
-
|
|
18451
|
-
|
|
18452
|
-
|
|
18453
|
-
|
|
18454
|
-
|
|
18455
|
-
|
|
18456
|
-
|
|
18457
|
-
|
|
18458
|
-
|
|
18459
|
-
|
|
18460
|
-
|
|
18461
|
-
|
|
18462
|
-
|
|
18463
|
-
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18471
|
-
|
|
18472
|
-
|
|
18473
|
-
|
|
18474
|
-
|
|
18475
|
-
|
|
18476
|
-
|
|
18477
|
-
|
|
18478
|
-
|
|
18479
|
-
|
|
18540
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18541
|
+
"div",
|
|
18542
|
+
{
|
|
18543
|
+
className: cn(
|
|
18544
|
+
"flex items-center gap-1 rounded-[10px] border border-border bg-background p-1 whitespace-nowrap",
|
|
18545
|
+
"shadow-[0px_10px_15px_-3px_rgba(0,0,0,0.1),0px_4px_6px_-4px_rgba(0,0,0,0.1)]",
|
|
18546
|
+
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18547
|
+
),
|
|
18548
|
+
children: [
|
|
18549
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
|
|
18550
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18551
|
+
CustomToolbarButton,
|
|
18552
|
+
{
|
|
18553
|
+
type: "button",
|
|
18554
|
+
"aria-label": itemEditOn ? "Done editing this image" : "Edit this image",
|
|
18555
|
+
"aria-pressed": itemEditOn,
|
|
18556
|
+
onClick: onToggleItemEdit,
|
|
18557
|
+
className: "group size-8",
|
|
18558
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18559
|
+
import_lucide_react9.Star,
|
|
18560
|
+
{
|
|
18561
|
+
size: 16,
|
|
18562
|
+
fill: "currentColor",
|
|
18563
|
+
strokeWidth: 0,
|
|
18564
|
+
className: cn(
|
|
18565
|
+
"transition-colors",
|
|
18566
|
+
itemEditOn ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
|
|
18567
|
+
),
|
|
18568
|
+
style: { pointerEvents: "none" }
|
|
18569
|
+
}
|
|
18570
|
+
)
|
|
18571
|
+
}
|
|
18572
|
+
) }),
|
|
18573
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: itemEditOn ? "Done editing this image" : "Edit this image" })
|
|
18574
|
+
] }),
|
|
18575
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18576
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Change image"), onClick: onChangeImage, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Image, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18577
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Link"), onClick: onOpenLink, disabled: !itemEditOn, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Link, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18578
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Move left"), onClick: onMoveLeft, disabled: !itemEditOn || index <= 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ArrowLeft, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18579
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18580
|
+
ToolbarAction,
|
|
18581
|
+
{
|
|
18582
|
+
label: gatedLabel("Move right"),
|
|
18583
|
+
onClick: onMoveRight,
|
|
18584
|
+
disabled: !itemEditOn || index >= itemCount - 1,
|
|
18585
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ArrowRight, { size: 16, style: { pointerEvents: "none" } })
|
|
18586
|
+
}
|
|
18587
|
+
),
|
|
18588
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: gatedLabel("Remove image"), onClick: onRemoveItem, disabled: !itemEditOn || itemCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ImageMinus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18589
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18590
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(OptionMenu, { label: "Layout", value: variant, options: VARIANTS, onChange: onSetVariant }),
|
|
18591
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(OptionMenu, { label: "Hover", value: hover, options: HOVERS, onChange: onSetHover }),
|
|
18592
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18593
|
+
ToolbarAction,
|
|
18594
|
+
{
|
|
18595
|
+
label: treatment === "grayscale" ? "Show in color" : "Show grayscale",
|
|
18596
|
+
active: treatment === "grayscale",
|
|
18597
|
+
onClick: () => onSetTreatment(treatment === "grayscale" ? "color" : "grayscale"),
|
|
18598
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Palette, { size: 16, style: { pointerEvents: "none" } })
|
|
18599
|
+
}
|
|
18600
|
+
),
|
|
18601
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18602
|
+
ALIGNS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label, active: align === value, onClick: () => onSetAlign(value), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { size: 16, style: { pointerEvents: "none" } }) }, value)),
|
|
18603
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18604
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Smaller", onClick: () => onResize(-8), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18605
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "min-w-[40px] text-center text-xs tabular-nums text-muted-foreground", children: [
|
|
18606
|
+
sizeValue,
|
|
18607
|
+
"px"
|
|
18608
|
+
] }),
|
|
18609
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Larger", onClick: () => onResize(8), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
18610
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
|
|
18611
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add image", onClick: onAddItem, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ImagePlus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
18612
|
+
]
|
|
18613
|
+
}
|
|
18614
|
+
),
|
|
18615
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
18480
18616
|
]
|
|
18481
18617
|
}
|
|
18482
|
-
);
|
|
18618
|
+
) });
|
|
18483
18619
|
}
|
|
18484
18620
|
function findMediaStripSlots(tree) {
|
|
18485
18621
|
const stack = tree.rows.flatMap((row) => row.blocks);
|
|
@@ -18498,31 +18634,23 @@ function AiMediaStripOverlay({
|
|
|
18498
18634
|
}) {
|
|
18499
18635
|
const [hover, setHover] = (0, import_react10.useState)(null);
|
|
18500
18636
|
const [active, setActive] = (0, import_react10.useState)(null);
|
|
18637
|
+
const [itemEditOn, setItemEditOn] = (0, import_react10.useState)(false);
|
|
18638
|
+
const [linkOpen, setLinkOpen] = (0, import_react10.useState)(false);
|
|
18501
18639
|
const [pending, setPending] = (0, import_react10.useState)(false);
|
|
18502
18640
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
18503
18641
|
const activeRef = (0, import_react10.useRef)(null);
|
|
18504
18642
|
activeRef.current = active;
|
|
18643
|
+
const linkOpenRef = (0, import_react10.useRef)(false);
|
|
18644
|
+
linkOpenRef.current = linkOpen;
|
|
18505
18645
|
(0, import_react10.useEffect)(() => {
|
|
18506
18646
|
const onMove = (e) => {
|
|
18647
|
+
const ref = itemRefFromTarget(e.target);
|
|
18507
18648
|
const t = e.target;
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
if (!itemEl) {
|
|
18514
|
-
setHover(null);
|
|
18515
|
-
return;
|
|
18516
|
-
}
|
|
18517
|
-
const sectionEl = itemEl.closest("[data-ohw-section]");
|
|
18518
|
-
const unit = sectionEl ? movableUnit(sectionEl) : null;
|
|
18519
|
-
const sectionId = unit ? instanceIdOf(unit) || null : null;
|
|
18520
|
-
const index = Number(itemEl.dataset.ohwMediaStripIndex);
|
|
18521
|
-
if (!sectionId || Number.isNaN(index)) {
|
|
18522
|
-
setHover(null);
|
|
18523
|
-
return;
|
|
18524
|
-
}
|
|
18525
|
-
setHover({ sectionId, index });
|
|
18649
|
+
const overEditable = Boolean(t?.closest?.("[data-ohw-editable]"));
|
|
18650
|
+
setHover((prev) => {
|
|
18651
|
+
const next = ref && !overEditable ? ref : null;
|
|
18652
|
+
return sameRef(prev, next) ? prev : next;
|
|
18653
|
+
});
|
|
18526
18654
|
};
|
|
18527
18655
|
const onLeave = () => setHover(null);
|
|
18528
18656
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -18534,23 +18662,25 @@ function AiMediaStripOverlay({
|
|
|
18534
18662
|
}, []);
|
|
18535
18663
|
(0, import_react10.useEffect)(() => {
|
|
18536
18664
|
const onClick = (e) => {
|
|
18537
|
-
const current = activeRef.current;
|
|
18538
|
-
if (!current) return;
|
|
18539
18665
|
const t = e.target;
|
|
18540
|
-
if (!(t instanceof
|
|
18541
|
-
if (t.closest(
|
|
18542
|
-
const
|
|
18543
|
-
if (
|
|
18544
|
-
|
|
18666
|
+
if (!(t instanceof Element)) return;
|
|
18667
|
+
if (t.closest(CHROME_SELECTOR)) return;
|
|
18668
|
+
const ref = itemRefFromTarget(t);
|
|
18669
|
+
if (sameRef(activeRef.current, ref)) return;
|
|
18670
|
+
if (ref) clearInteractionChromeRef.current();
|
|
18671
|
+
setItemEditOn(false);
|
|
18545
18672
|
setError(null);
|
|
18673
|
+
setActive(ref);
|
|
18546
18674
|
};
|
|
18547
18675
|
document.addEventListener("click", onClick, true);
|
|
18548
18676
|
return () => document.removeEventListener("click", onClick, true);
|
|
18549
|
-
}, []);
|
|
18677
|
+
}, [clearInteractionChromeRef]);
|
|
18550
18678
|
(0, import_react10.useEffect)(() => {
|
|
18551
18679
|
const onBlur = () => {
|
|
18552
18680
|
if (!activeRef.current) return;
|
|
18553
18681
|
setActive(null);
|
|
18682
|
+
setItemEditOn(false);
|
|
18683
|
+
setLinkOpen(false);
|
|
18554
18684
|
setError(null);
|
|
18555
18685
|
};
|
|
18556
18686
|
window.addEventListener("blur", onBlur);
|
|
@@ -18560,7 +18690,10 @@ function AiMediaStripOverlay({
|
|
|
18560
18690
|
const onKeyDown = (e) => {
|
|
18561
18691
|
if (e.key !== "Escape") return;
|
|
18562
18692
|
if (!activeRef.current) return;
|
|
18693
|
+
if (linkOpenRef.current) return;
|
|
18694
|
+
if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
|
|
18563
18695
|
setActive(null);
|
|
18696
|
+
setItemEditOn(false);
|
|
18564
18697
|
setError(null);
|
|
18565
18698
|
};
|
|
18566
18699
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -18589,142 +18722,138 @@ function AiMediaStripOverlay({
|
|
|
18589
18722
|
}
|
|
18590
18723
|
applyTreeLocalRef.current?.({
|
|
18591
18724
|
id: sectionId,
|
|
18592
|
-
mode: "replace",
|
|
18593
|
-
targetSectionId: sectionId,
|
|
18594
|
-
tree: nextTree,
|
|
18595
|
-
label: entry.label,
|
|
18596
|
-
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
18597
|
-
...entry.brand ? { brand: entry.brand } : {}
|
|
18598
|
-
|
|
18599
|
-
|
|
18600
|
-
|
|
18601
|
-
|
|
18602
|
-
|
|
18603
|
-
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
const
|
|
18607
|
-
const
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18641
|
-
|
|
18642
|
-
{
|
|
18643
|
-
rect: activeItemRect,
|
|
18644
|
-
state: toolbarState,
|
|
18645
|
-
toolbar: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18646
|
-
MediaStripToolbar,
|
|
18647
|
-
{
|
|
18648
|
-
entry: activeEntry,
|
|
18649
|
-
index: active.index,
|
|
18650
|
-
pending,
|
|
18651
|
-
error,
|
|
18652
|
-
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18653
|
-
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18654
|
-
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18655
|
-
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18656
|
-
onResize: (delta) => {
|
|
18657
|
-
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18658
|
-
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18659
|
-
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18660
|
-
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18661
|
-
},
|
|
18662
|
-
onSetAlt: (alt) => {
|
|
18663
|
-
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
18664
|
-
},
|
|
18665
|
-
onSetLink: (href, linkTarget) => {
|
|
18725
|
+
mode: "replace",
|
|
18726
|
+
targetSectionId: sectionId,
|
|
18727
|
+
tree: nextTree,
|
|
18728
|
+
label: entry.label,
|
|
18729
|
+
media: extraMedia ? { ...entry.media, ...extraMedia } : entry.media,
|
|
18730
|
+
...entry.brand ? { brand: entry.brand } : {},
|
|
18731
|
+
// The user is already looking at the strip they just edited — recentering the viewport
|
|
18732
|
+
// on every edit reads as the section jumping around.
|
|
18733
|
+
skipScrollIntoView: true
|
|
18734
|
+
});
|
|
18735
|
+
return true;
|
|
18736
|
+
},
|
|
18737
|
+
[findEntry, postToParent2, applyTreeLocalRef]
|
|
18738
|
+
);
|
|
18739
|
+
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
18740
|
+
const activeItemRect = useLiveItemRect(active);
|
|
18741
|
+
const activeStripRect = useLiveItemRect(active, true);
|
|
18742
|
+
const hoverRect = useLiveItemRect(hover && !sameRef(hover, active) ? hover : null);
|
|
18743
|
+
const activeItems = activeEntry ? mediaStripItems(activeEntry.tree) : [];
|
|
18744
|
+
const activeItem = active ? activeItems[active.index] : void 0;
|
|
18745
|
+
const activeHref = activeItem?.href ?? "";
|
|
18746
|
+
const activeTarget = activeItem?.linkTarget === "same-tab" ? "same-tab" : "new-tab";
|
|
18747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
18748
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
18749
|
+
activeItemRect && activeStripRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
18750
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: activeItemRect, state: "active-top" }),
|
|
18751
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StripToolbarSlot, { stripRect: activeStripRect, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18752
|
+
MediaStripToolbar,
|
|
18753
|
+
{
|
|
18754
|
+
entry: activeEntry,
|
|
18755
|
+
index: active.index,
|
|
18756
|
+
pending,
|
|
18757
|
+
error,
|
|
18758
|
+
itemEditOn,
|
|
18759
|
+
onToggleItemEdit: () => setItemEditOn((on) => !on),
|
|
18760
|
+
onSetVariant: (variant) => runMutation(active.sectionId, (tree) => setMediaStripVariant(tree, variant)),
|
|
18761
|
+
onSetAlign: (align) => runMutation(active.sectionId, (tree) => setMediaStripAlign(tree, align)),
|
|
18762
|
+
onSetHover: (hoverPreset) => runMutation(active.sectionId, (tree) => setMediaStripHover(tree, hoverPreset)),
|
|
18763
|
+
onSetTreatment: (treatment) => runMutation(active.sectionId, (tree) => setMediaStripTreatment(tree, treatment)),
|
|
18764
|
+
onResize: (delta) => {
|
|
18765
|
+
const slots = findMediaStripSlots(activeEntry.tree);
|
|
18766
|
+
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
18767
|
+
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
18768
|
+
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
18769
|
+
},
|
|
18770
|
+
onOpenLink: () => setLinkOpen(true),
|
|
18771
|
+
onAddItem: () => {
|
|
18772
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18773
|
+
if (!picked) return;
|
|
18774
|
+
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18666
18775
|
void runMutation(
|
|
18667
18776
|
active.sectionId,
|
|
18668
|
-
(tree) =>
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
void requestAssetPick(postToParent2).then((picked) => {
|
|
18673
|
-
if (!picked) return;
|
|
18674
|
-
const item = { assetId: picked.assetId, alt: "Logo" };
|
|
18675
|
-
void runMutation(
|
|
18676
|
-
active.sectionId,
|
|
18677
|
-
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18678
|
-
{ [picked.assetId]: picked.url }
|
|
18679
|
-
).then((applied) => {
|
|
18680
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18681
|
-
});
|
|
18682
|
-
});
|
|
18683
|
-
},
|
|
18684
|
-
onChangeImage: () => {
|
|
18685
|
-
void requestAssetPick(postToParent2).then((picked) => {
|
|
18686
|
-
if (!picked) return;
|
|
18687
|
-
void runMutation(
|
|
18688
|
-
active.sectionId,
|
|
18689
|
-
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
18690
|
-
{ [picked.assetId]: picked.url }
|
|
18691
|
-
);
|
|
18777
|
+
(tree) => addMediaStripItem(tree, item, active.index),
|
|
18778
|
+
{ [picked.assetId]: picked.url }
|
|
18779
|
+
).then((applied) => {
|
|
18780
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18692
18781
|
});
|
|
18693
|
-
}
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18702
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18703
|
-
(applied) => {
|
|
18704
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18705
|
-
}
|
|
18706
|
-
);
|
|
18707
|
-
},
|
|
18708
|
-
onMoveRight: () => {
|
|
18709
|
-
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18710
|
-
(applied) => {
|
|
18711
|
-
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18712
|
-
}
|
|
18782
|
+
});
|
|
18783
|
+
},
|
|
18784
|
+
onChangeImage: () => {
|
|
18785
|
+
void requestAssetPick(postToParent2).then((picked) => {
|
|
18786
|
+
if (!picked) return;
|
|
18787
|
+
void runMutation(
|
|
18788
|
+
active.sectionId,
|
|
18789
|
+
(tree) => setMediaStripItemAsset(tree, active.index, picked.assetId),
|
|
18790
|
+
{ [picked.assetId]: picked.url }
|
|
18713
18791
|
);
|
|
18714
|
-
}
|
|
18792
|
+
});
|
|
18793
|
+
},
|
|
18794
|
+
onRemoveItem: () => {
|
|
18795
|
+
void runMutation(active.sectionId, (tree) => removeMediaStripItem(tree, active.index)).then(
|
|
18796
|
+
(applied) => {
|
|
18797
|
+
if (applied) setActive(null);
|
|
18798
|
+
}
|
|
18799
|
+
);
|
|
18800
|
+
},
|
|
18801
|
+
onMoveLeft: () => {
|
|
18802
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, -1)).then(
|
|
18803
|
+
(applied) => {
|
|
18804
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index - 1 });
|
|
18805
|
+
}
|
|
18806
|
+
);
|
|
18807
|
+
},
|
|
18808
|
+
onMoveRight: () => {
|
|
18809
|
+
void runMutation(active.sectionId, (tree) => reorderMediaStripItem(tree, active.index, 1)).then(
|
|
18810
|
+
(applied) => {
|
|
18811
|
+
if (applied) setActive({ sectionId: active.sectionId, index: active.index + 1 });
|
|
18812
|
+
}
|
|
18813
|
+
);
|
|
18715
18814
|
}
|
|
18716
|
-
|
|
18717
|
-
}
|
|
18718
|
-
|
|
18815
|
+
}
|
|
18816
|
+
) }),
|
|
18817
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18818
|
+
"div",
|
|
18819
|
+
{
|
|
18820
|
+
"data-ohw-bridge": "",
|
|
18821
|
+
"data-ohw-item-interaction": "",
|
|
18822
|
+
"aria-hidden": true,
|
|
18823
|
+
className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
|
|
18824
|
+
style: {
|
|
18825
|
+
top: activeItemRect.top + activeItemRect.height + 10,
|
|
18826
|
+
left: activeItemRect.left - 5,
|
|
18827
|
+
background: PRIMARY3,
|
|
18828
|
+
zIndex: 2147483644
|
|
18829
|
+
},
|
|
18830
|
+
children: "Media item"
|
|
18831
|
+
}
|
|
18832
|
+
),
|
|
18833
|
+
linkOpen && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18834
|
+
LinkModal,
|
|
18835
|
+
{
|
|
18836
|
+
href: activeHref,
|
|
18837
|
+
linkTarget: activeTarget,
|
|
18838
|
+
onClose: () => setLinkOpen(false),
|
|
18839
|
+
onSave: (href, linkTarget) => {
|
|
18840
|
+
void runMutation(
|
|
18841
|
+
active.sectionId,
|
|
18842
|
+
(tree) => setMediaStripItemLink(tree, active.index, href ? { href, linkTarget } : {})
|
|
18843
|
+
);
|
|
18844
|
+
}
|
|
18845
|
+
}
|
|
18846
|
+
)
|
|
18847
|
+
] })
|
|
18719
18848
|
] });
|
|
18720
18849
|
}
|
|
18721
18850
|
|
|
18722
18851
|
// src/ui/ai-section/AiPricingCardOverlay.tsx
|
|
18723
18852
|
var import_react11 = require("react");
|
|
18724
|
-
var
|
|
18725
|
-
var
|
|
18853
|
+
var import_lucide_react10 = require("lucide-react");
|
|
18854
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
18726
18855
|
var PRIMARY4 = "var(--ohw-primary, #0885FE)";
|
|
18727
|
-
var
|
|
18856
|
+
var CHROME_SELECTOR2 = "[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]";
|
|
18728
18857
|
function findPricingCardElement(sectionId, index) {
|
|
18729
18858
|
const sectionEl = findByInstanceId(sectionId);
|
|
18730
18859
|
if (!sectionEl) return null;
|
|
@@ -18736,7 +18865,7 @@ function findPricingCardElement(sectionId, index) {
|
|
|
18736
18865
|
}
|
|
18737
18866
|
function cardRefFromTarget(target) {
|
|
18738
18867
|
if (!(target instanceof Element)) return null;
|
|
18739
|
-
if (target.closest(
|
|
18868
|
+
if (target.closest(CHROME_SELECTOR2)) return null;
|
|
18740
18869
|
const cardEl = target.closest("[data-ohw-pricing-card]");
|
|
18741
18870
|
if (!cardEl) return null;
|
|
18742
18871
|
const sectionEl = cardEl.closest("[data-ohw-section]");
|
|
@@ -18746,21 +18875,21 @@ function cardRefFromTarget(target) {
|
|
|
18746
18875
|
if (!sectionId || Number.isNaN(index)) return null;
|
|
18747
18876
|
return { sectionId, index };
|
|
18748
18877
|
}
|
|
18749
|
-
function
|
|
18878
|
+
function sameRef2(a, b) {
|
|
18750
18879
|
return a?.sectionId === b?.sectionId && a?.index === b?.index;
|
|
18751
18880
|
}
|
|
18752
|
-
function
|
|
18881
|
+
function rectOf2(el) {
|
|
18753
18882
|
if (!el) return null;
|
|
18754
18883
|
const r2 = el.getBoundingClientRect();
|
|
18755
18884
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
18756
18885
|
return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
|
|
18757
18886
|
}
|
|
18758
18887
|
function readRect3(ref) {
|
|
18759
|
-
return
|
|
18888
|
+
return rectOf2(ref && findPricingCardElement(ref.sectionId, ref.index));
|
|
18760
18889
|
}
|
|
18761
18890
|
function readGridRect(ref) {
|
|
18762
18891
|
const card = ref && findPricingCardElement(ref.sectionId, ref.index);
|
|
18763
|
-
return
|
|
18892
|
+
return rectOf2(card?.closest("[data-ohw-pricing-collection]") ?? card);
|
|
18764
18893
|
}
|
|
18765
18894
|
function useLiveCardRect(ref, grid = false) {
|
|
18766
18895
|
const [rect, setRect] = (0, import_react11.useState)(null);
|
|
@@ -18790,7 +18919,7 @@ function useLiveCardRect(ref, grid = false) {
|
|
|
18790
18919
|
}
|
|
18791
18920
|
var TOOLBAR_GRID_GAP = 52;
|
|
18792
18921
|
var TOOLBAR_GRID_GAP_MOBILE = 42;
|
|
18793
|
-
var
|
|
18922
|
+
var TOOLBAR_EDGE_MARGIN3 = 4;
|
|
18794
18923
|
function GridToolbarSlot({ gridRect, children }) {
|
|
18795
18924
|
const slotRef = (0, import_react11.useRef)(null);
|
|
18796
18925
|
const [shift, setShift] = (0, import_react11.useState)(0);
|
|
@@ -18802,7 +18931,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
18802
18931
|
const w = slot.offsetWidth;
|
|
18803
18932
|
if (w <= 0) return;
|
|
18804
18933
|
const half = w / 2;
|
|
18805
|
-
const clamped = Math.max(
|
|
18934
|
+
const clamped = Math.max(TOOLBAR_EDGE_MARGIN3 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half));
|
|
18806
18935
|
setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
|
|
18807
18936
|
};
|
|
18808
18937
|
clamp();
|
|
@@ -18811,7 +18940,7 @@ function GridToolbarSlot({ gridRect, children }) {
|
|
|
18811
18940
|
return () => ro.disconnect();
|
|
18812
18941
|
}, [centerX, children]);
|
|
18813
18942
|
const mobile = window.innerWidth <= 480;
|
|
18814
|
-
return /* @__PURE__ */ (0,
|
|
18943
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18815
18944
|
"div",
|
|
18816
18945
|
{
|
|
18817
18946
|
ref: slotRef,
|
|
@@ -18846,7 +18975,7 @@ function requestValidateTree2(postToParent2, tree) {
|
|
|
18846
18975
|
});
|
|
18847
18976
|
}
|
|
18848
18977
|
function StyleSwatch({ style }) {
|
|
18849
|
-
return /* @__PURE__ */ (0,
|
|
18978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18850
18979
|
"span",
|
|
18851
18980
|
{
|
|
18852
18981
|
"aria-hidden": true,
|
|
@@ -18860,35 +18989,35 @@ function StyleSwatch({ style }) {
|
|
|
18860
18989
|
);
|
|
18861
18990
|
}
|
|
18862
18991
|
function ButtonGlyph() {
|
|
18863
|
-
return /* @__PURE__ */ (0,
|
|
18864
|
-
/* @__PURE__ */ (0,
|
|
18865
|
-
/* @__PURE__ */ (0,
|
|
18992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
18993
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
18994
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
18866
18995
|
] });
|
|
18867
18996
|
}
|
|
18868
18997
|
function FeatureGlyph({ mode }) {
|
|
18869
|
-
return /* @__PURE__ */ (0,
|
|
18870
|
-
/* @__PURE__ */ (0,
|
|
18871
|
-
/* @__PURE__ */ (0,
|
|
18872
|
-
/* @__PURE__ */ (0,
|
|
18873
|
-
/* @__PURE__ */ (0,
|
|
18874
|
-
/* @__PURE__ */ (0,
|
|
18875
|
-
mode === "add" && /* @__PURE__ */ (0,
|
|
18998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
|
|
18999
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
19000
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
19001
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
|
|
19002
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
|
|
19003
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
19004
|
+
mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
|
|
18876
19005
|
] });
|
|
18877
19006
|
}
|
|
18878
|
-
function
|
|
19007
|
+
function ToolbarAction2({
|
|
18879
19008
|
label,
|
|
18880
19009
|
onClick,
|
|
18881
19010
|
disabled = false,
|
|
18882
19011
|
children
|
|
18883
19012
|
}) {
|
|
18884
|
-
const button = /* @__PURE__ */ (0,
|
|
18885
|
-
return /* @__PURE__ */ (0,
|
|
18886
|
-
/* @__PURE__ */ (0,
|
|
18887
|
-
/* @__PURE__ */ (0,
|
|
19013
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
|
|
19014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19015
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
19016
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
|
|
18888
19017
|
] });
|
|
18889
19018
|
}
|
|
18890
|
-
function
|
|
18891
|
-
return /* @__PURE__ */ (0,
|
|
19019
|
+
function ToolbarSeparator2() {
|
|
19020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
|
|
18892
19021
|
}
|
|
18893
19022
|
function CardStyleMenu({
|
|
18894
19023
|
value,
|
|
@@ -18896,7 +19025,7 @@ function CardStyleMenu({
|
|
|
18896
19025
|
disabled = false
|
|
18897
19026
|
}) {
|
|
18898
19027
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18899
|
-
const trigger = /* @__PURE__ */ (0,
|
|
19028
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
18900
19029
|
"button",
|
|
18901
19030
|
{
|
|
18902
19031
|
type: "button",
|
|
@@ -18907,28 +19036,28 @@ function CardStyleMenu({
|
|
|
18907
19036
|
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
18908
19037
|
),
|
|
18909
19038
|
children: [
|
|
18910
|
-
/* @__PURE__ */ (0,
|
|
18911
|
-
/* @__PURE__ */ (0,
|
|
18912
|
-
/* @__PURE__ */ (0,
|
|
19039
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: current.value }),
|
|
19040
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex-1 text-left", children: current.label }),
|
|
19041
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
|
|
18913
19042
|
]
|
|
18914
19043
|
}
|
|
18915
19044
|
);
|
|
18916
19045
|
if (disabled) {
|
|
18917
|
-
return /* @__PURE__ */ (0,
|
|
18918
|
-
/* @__PURE__ */ (0,
|
|
18919
|
-
/* @__PURE__ */ (0,
|
|
18920
|
-
/* @__PURE__ */ (0,
|
|
18921
|
-
/* @__PURE__ */ (0,
|
|
19046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19047
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
19048
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19049
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "inline-flex", children: trigger }) }),
|
|
19050
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
18922
19051
|
] })
|
|
18923
19052
|
] });
|
|
18924
19053
|
}
|
|
18925
|
-
return /* @__PURE__ */ (0,
|
|
18926
|
-
/* @__PURE__ */ (0,
|
|
18927
|
-
/* @__PURE__ */ (0,
|
|
18928
|
-
/* @__PURE__ */ (0,
|
|
18929
|
-
/* @__PURE__ */ (0,
|
|
19054
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
19055
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
19056
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenu, { modal: false, children: [
|
|
19057
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
19058
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
18930
19059
|
const selected = style.value === value;
|
|
18931
|
-
return /* @__PURE__ */ (0,
|
|
19060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
18932
19061
|
DropdownMenuItem,
|
|
18933
19062
|
{
|
|
18934
19063
|
role: "menuitemradio",
|
|
@@ -18936,9 +19065,9 @@ function CardStyleMenu({
|
|
|
18936
19065
|
onSelect: () => onChange(style.value),
|
|
18937
19066
|
className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
|
|
18938
19067
|
children: [
|
|
18939
|
-
/* @__PURE__ */ (0,
|
|
18940
|
-
/* @__PURE__ */ (0,
|
|
18941
|
-
selected && /* @__PURE__ */ (0,
|
|
19068
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyleSwatch, { style: style.value }),
|
|
19069
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: style.label }),
|
|
19070
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Check, { size: 16, className: "text-bridge-primary" })
|
|
18942
19071
|
]
|
|
18943
19072
|
},
|
|
18944
19073
|
style.value
|
|
@@ -18968,7 +19097,7 @@ function PricingCardToolbar({
|
|
|
18968
19097
|
const style = pricingCardStyle(entry.tree, index);
|
|
18969
19098
|
const featuredTag = pricingCardFeaturedTag(entry.tree, index);
|
|
18970
19099
|
const mobile = window.innerWidth <= 480;
|
|
18971
|
-
return /* @__PURE__ */ (0,
|
|
19100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
18972
19101
|
"div",
|
|
18973
19102
|
{
|
|
18974
19103
|
"data-ohw-bridge": "",
|
|
@@ -18980,7 +19109,7 @@ function PricingCardToolbar({
|
|
|
18980
19109
|
),
|
|
18981
19110
|
style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
|
|
18982
19111
|
children: [
|
|
18983
|
-
/* @__PURE__ */ (0,
|
|
19112
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
18984
19113
|
"div",
|
|
18985
19114
|
{
|
|
18986
19115
|
className: cn(
|
|
@@ -18989,8 +19118,8 @@ function PricingCardToolbar({
|
|
|
18989
19118
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18990
19119
|
),
|
|
18991
19120
|
children: [
|
|
18992
|
-
/* @__PURE__ */ (0,
|
|
18993
|
-
/* @__PURE__ */ (0,
|
|
19121
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
19122
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
18994
19123
|
CustomToolbarButton,
|
|
18995
19124
|
{
|
|
18996
19125
|
type: "button",
|
|
@@ -18998,8 +19127,8 @@ function PricingCardToolbar({
|
|
|
18998
19127
|
"aria-pressed": featuredTag,
|
|
18999
19128
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
19000
19129
|
className: "group size-8",
|
|
19001
|
-
children: /* @__PURE__ */ (0,
|
|
19002
|
-
|
|
19130
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19131
|
+
import_lucide_react10.Star,
|
|
19003
19132
|
{
|
|
19004
19133
|
size: 16,
|
|
19005
19134
|
fill: "currentColor",
|
|
@@ -19013,25 +19142,25 @@ function PricingCardToolbar({
|
|
|
19013
19142
|
)
|
|
19014
19143
|
}
|
|
19015
19144
|
) }),
|
|
19016
|
-
/* @__PURE__ */ (0,
|
|
19145
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
19017
19146
|
] }),
|
|
19018
|
-
/* @__PURE__ */ (0,
|
|
19019
|
-
/* @__PURE__ */ (0,
|
|
19020
|
-
/* @__PURE__ */ (0,
|
|
19021
|
-
/* @__PURE__ */ (0,
|
|
19022
|
-
/* @__PURE__ */ (0,
|
|
19023
|
-
/* @__PURE__ */ (0,
|
|
19024
|
-
/* @__PURE__ */ (0,
|
|
19147
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator2, {}),
|
|
19148
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
19149
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator2, {}),
|
|
19150
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction2, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}) }),
|
|
19151
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction2, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "relative inline-flex", children: [
|
|
19152
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ButtonGlyph, {}),
|
|
19153
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
|
|
19025
19154
|
] }) }),
|
|
19026
|
-
/* @__PURE__ */ (0,
|
|
19027
|
-
/* @__PURE__ */ (0,
|
|
19028
|
-
/* @__PURE__ */ (0,
|
|
19029
|
-
/* @__PURE__ */ (0,
|
|
19030
|
-
/* @__PURE__ */ (0,
|
|
19155
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction2, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FeatureGlyph, { mode: "add" }) }),
|
|
19156
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction2, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FeatureGlyph, { mode: "remove" }) }),
|
|
19157
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarSeparator2, {}),
|
|
19158
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction2, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
|
|
19159
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToolbarAction2, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Minus, { size: 16, style: { pointerEvents: "none" } }) })
|
|
19031
19160
|
]
|
|
19032
19161
|
}
|
|
19033
19162
|
),
|
|
19034
|
-
error && /* @__PURE__ */ (0,
|
|
19163
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
|
|
19035
19164
|
]
|
|
19036
19165
|
}
|
|
19037
19166
|
) });
|
|
@@ -19065,7 +19194,7 @@ function AiPricingCardOverlay({
|
|
|
19065
19194
|
const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
|
|
19066
19195
|
setHover((prev) => {
|
|
19067
19196
|
const next = ref && !overEditable ? ref : null;
|
|
19068
|
-
return
|
|
19197
|
+
return sameRef2(prev, next) ? prev : next;
|
|
19069
19198
|
});
|
|
19070
19199
|
};
|
|
19071
19200
|
const onLeave = () => setHover(null);
|
|
@@ -19080,10 +19209,10 @@ function AiPricingCardOverlay({
|
|
|
19080
19209
|
const onClick = (e) => {
|
|
19081
19210
|
const t = e.target;
|
|
19082
19211
|
if (!(t instanceof Element)) return;
|
|
19083
|
-
if (t.closest(
|
|
19212
|
+
if (t.closest(CHROME_SELECTOR2)) return;
|
|
19084
19213
|
const ref = cardRefFromTarget(t);
|
|
19085
|
-
setActive((prev) =>
|
|
19086
|
-
if (!ref || !
|
|
19214
|
+
setActive((prev) => sameRef2(prev, ref) ? prev : ref);
|
|
19215
|
+
if (!ref || !sameRef2(activeRef.current, ref)) setError(null);
|
|
19087
19216
|
};
|
|
19088
19217
|
document.addEventListener("click", onClick, true);
|
|
19089
19218
|
return () => document.removeEventListener("click", onClick, true);
|
|
@@ -19148,12 +19277,12 @@ function AiPricingCardOverlay({
|
|
|
19148
19277
|
const activeEntry = active ? findEntry(active.sectionId) : null;
|
|
19149
19278
|
const activeCardRect = useLiveCardRect(active);
|
|
19150
19279
|
const activeGridRect = useLiveCardRect(active, true);
|
|
19151
|
-
const hoverRect = useLiveCardRect(hover && !
|
|
19152
|
-
return /* @__PURE__ */ (0,
|
|
19153
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
19154
|
-
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19155
|
-
/* @__PURE__ */ (0,
|
|
19156
|
-
/* @__PURE__ */ (0,
|
|
19280
|
+
const hoverRect = useLiveCardRect(hover && !sameRef2(hover, active) ? hover : null);
|
|
19281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19282
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
|
|
19283
|
+
activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
19284
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
|
|
19285
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19157
19286
|
PricingCardToolbar,
|
|
19158
19287
|
{
|
|
19159
19288
|
entry: activeEntry,
|
|
@@ -19181,7 +19310,7 @@ function AiPricingCardOverlay({
|
|
|
19181
19310
|
onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
|
|
19182
19311
|
}
|
|
19183
19312
|
) }),
|
|
19184
|
-
/* @__PURE__ */ (0,
|
|
19313
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
19185
19314
|
"div",
|
|
19186
19315
|
{
|
|
19187
19316
|
"data-ohw-bridge": "",
|
|
@@ -19203,7 +19332,7 @@ function AiPricingCardOverlay({
|
|
|
19203
19332
|
|
|
19204
19333
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19205
19334
|
var import_react12 = require("react");
|
|
19206
|
-
var
|
|
19335
|
+
var import_lucide_react11 = require("lucide-react");
|
|
19207
19336
|
|
|
19208
19337
|
// src/lib/ai-video-tree.ts
|
|
19209
19338
|
function resolveVideoBlock(tree, path) {
|
|
@@ -19274,10 +19403,10 @@ function extractYouTubeId(input) {
|
|
|
19274
19403
|
}
|
|
19275
19404
|
|
|
19276
19405
|
// src/ui/ai-section/AiVideoOverlay.tsx
|
|
19277
|
-
var
|
|
19406
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
19278
19407
|
var PRIMARY5 = "#0885FE";
|
|
19279
|
-
var
|
|
19280
|
-
var
|
|
19408
|
+
var OHW_BLUE = `var(--ohw-primary, ${PRIMARY5})`;
|
|
19409
|
+
var OHW_BLUE_DARK = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
|
|
19281
19410
|
function findVideoBlockElement(sectionId, path) {
|
|
19282
19411
|
const sectionEl = findByInstanceId(sectionId);
|
|
19283
19412
|
if (!sectionEl) return null;
|
|
@@ -19337,12 +19466,12 @@ function requestValidateTree3(postToParent2, tree) {
|
|
|
19337
19466
|
postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
|
|
19338
19467
|
});
|
|
19339
19468
|
}
|
|
19340
|
-
function
|
|
19469
|
+
function Pill({
|
|
19341
19470
|
label,
|
|
19342
19471
|
onClick,
|
|
19343
19472
|
disabled
|
|
19344
19473
|
}) {
|
|
19345
|
-
return /* @__PURE__ */ (0,
|
|
19474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19346
19475
|
"button",
|
|
19347
19476
|
{
|
|
19348
19477
|
type: "button",
|
|
@@ -19358,7 +19487,7 @@ function Pill2({
|
|
|
19358
19487
|
border: "none",
|
|
19359
19488
|
cursor: disabled ? "default" : "pointer",
|
|
19360
19489
|
background: "#ffffff",
|
|
19361
|
-
color:
|
|
19490
|
+
color: OHW_BLUE_DARK,
|
|
19362
19491
|
opacity: disabled ? 0.4 : 1,
|
|
19363
19492
|
fontSize: 12,
|
|
19364
19493
|
lineHeight: "16px",
|
|
@@ -19401,8 +19530,8 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19401
19530
|
onCommit(id);
|
|
19402
19531
|
}
|
|
19403
19532
|
};
|
|
19404
|
-
return /* @__PURE__ */ (0,
|
|
19405
|
-
/* @__PURE__ */ (0,
|
|
19533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
|
|
19534
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
19406
19535
|
"div",
|
|
19407
19536
|
{
|
|
19408
19537
|
style: {
|
|
@@ -19418,12 +19547,12 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19418
19547
|
boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
|
|
19419
19548
|
},
|
|
19420
19549
|
children: [
|
|
19421
|
-
/* @__PURE__ */ (0,
|
|
19550
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19422
19551
|
"span",
|
|
19423
19552
|
{
|
|
19424
19553
|
style: {
|
|
19425
19554
|
flex: "0 0 auto",
|
|
19426
|
-
color:
|
|
19555
|
+
color: OHW_BLUE_DARK,
|
|
19427
19556
|
fontSize: 10,
|
|
19428
19557
|
lineHeight: "16px",
|
|
19429
19558
|
fontWeight: 700,
|
|
@@ -19433,7 +19562,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19433
19562
|
children: "Video"
|
|
19434
19563
|
}
|
|
19435
19564
|
),
|
|
19436
|
-
/* @__PURE__ */ (0,
|
|
19565
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19437
19566
|
"input",
|
|
19438
19567
|
{
|
|
19439
19568
|
type: "text",
|
|
@@ -19470,7 +19599,7 @@ function VideoUrlInput({ value, onCommit }) {
|
|
|
19470
19599
|
]
|
|
19471
19600
|
}
|
|
19472
19601
|
),
|
|
19473
|
-
invalid && /* @__PURE__ */ (0,
|
|
19602
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
|
|
19474
19603
|
] });
|
|
19475
19604
|
}
|
|
19476
19605
|
function VideoToolbar({
|
|
@@ -19480,7 +19609,7 @@ function VideoToolbar({
|
|
|
19480
19609
|
onSetVideoId,
|
|
19481
19610
|
onRemove
|
|
19482
19611
|
}) {
|
|
19483
|
-
return /* @__PURE__ */ (0,
|
|
19612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
19484
19613
|
"div",
|
|
19485
19614
|
{
|
|
19486
19615
|
"data-ohw-bridge": "",
|
|
@@ -19492,7 +19621,7 @@ function VideoToolbar({
|
|
|
19492
19621
|
gap: 6,
|
|
19493
19622
|
alignItems: "center",
|
|
19494
19623
|
width: 280,
|
|
19495
|
-
background:
|
|
19624
|
+
background: OHW_BLUE,
|
|
19496
19625
|
padding: 8,
|
|
19497
19626
|
borderRadius: 12,
|
|
19498
19627
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19500,9 +19629,9 @@ function VideoToolbar({
|
|
|
19500
19629
|
opacity: pending ? 0.6 : 1
|
|
19501
19630
|
},
|
|
19502
19631
|
children: [
|
|
19503
|
-
/* @__PURE__ */ (0,
|
|
19504
|
-
/* @__PURE__ */ (0,
|
|
19505
|
-
error && /* @__PURE__ */ (0,
|
|
19632
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
|
|
19633
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
|
|
19634
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19506
19635
|
]
|
|
19507
19636
|
}
|
|
19508
19637
|
);
|
|
@@ -19622,8 +19751,8 @@ function AiVideoOverlay({
|
|
|
19622
19751
|
const activeBlockRect = useLiveBlockRect(active);
|
|
19623
19752
|
const TOOLBAR_APPROX_H = 90;
|
|
19624
19753
|
const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
19625
|
-
return /* @__PURE__ */ (0,
|
|
19626
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
19754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
19755
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19627
19756
|
"button",
|
|
19628
19757
|
{
|
|
19629
19758
|
type: "button",
|
|
@@ -19651,15 +19780,15 @@ function AiVideoOverlay({
|
|
|
19651
19780
|
fontSize: 14,
|
|
19652
19781
|
fontWeight: 700
|
|
19653
19782
|
},
|
|
19654
|
-
children: /* @__PURE__ */ (0,
|
|
19783
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
19655
19784
|
}
|
|
19656
19785
|
),
|
|
19657
|
-
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
19786
|
+
activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19658
19787
|
ItemInteractionLayer,
|
|
19659
19788
|
{
|
|
19660
19789
|
rect: activeBlockRect,
|
|
19661
19790
|
state: toolbarState,
|
|
19662
|
-
toolbar: /* @__PURE__ */ (0,
|
|
19791
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
19663
19792
|
VideoToolbar,
|
|
19664
19793
|
{
|
|
19665
19794
|
videoId: videoIdAt(activeEntry.tree, active.path),
|
|
@@ -19683,7 +19812,7 @@ function AiVideoOverlay({
|
|
|
19683
19812
|
|
|
19684
19813
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
19685
19814
|
var import_react13 = require("react");
|
|
19686
|
-
var
|
|
19815
|
+
var import_lucide_react12 = require("lucide-react");
|
|
19687
19816
|
|
|
19688
19817
|
// src/lib/ai-carousel-tree.ts
|
|
19689
19818
|
function isCarouselBlock(node) {
|
|
@@ -19734,10 +19863,10 @@ function setCarouselAutoplay(tree, on) {
|
|
|
19734
19863
|
}
|
|
19735
19864
|
|
|
19736
19865
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
19737
|
-
var
|
|
19866
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
19738
19867
|
var PRIMARY6 = "#0885FE";
|
|
19739
|
-
var
|
|
19740
|
-
var
|
|
19868
|
+
var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY6})`;
|
|
19869
|
+
var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
|
|
19741
19870
|
function findCarouselItemElement(sectionId, index) {
|
|
19742
19871
|
const sectionEl = findByInstanceId(sectionId);
|
|
19743
19872
|
if (!sectionEl) return null;
|
|
@@ -19816,8 +19945,8 @@ function requestAssetPick2(postToParent2) {
|
|
|
19816
19945
|
postToParent2({ type: "ow:asset-pick", id });
|
|
19817
19946
|
});
|
|
19818
19947
|
}
|
|
19819
|
-
function
|
|
19820
|
-
return /* @__PURE__ */ (0,
|
|
19948
|
+
function Pill2({ label, onClick, disabled }) {
|
|
19949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
19821
19950
|
"button",
|
|
19822
19951
|
{
|
|
19823
19952
|
type: "button",
|
|
@@ -19833,7 +19962,7 @@ function Pill3({ label, onClick, disabled }) {
|
|
|
19833
19962
|
border: "none",
|
|
19834
19963
|
cursor: disabled ? "default" : "pointer",
|
|
19835
19964
|
background: "#ffffff",
|
|
19836
|
-
color:
|
|
19965
|
+
color: OHW_BLUE_DARK2,
|
|
19837
19966
|
opacity: disabled ? 0.4 : 1,
|
|
19838
19967
|
fontSize: 12,
|
|
19839
19968
|
lineHeight: "16px",
|
|
@@ -19851,7 +19980,7 @@ function TogglePill({
|
|
|
19851
19980
|
onToggle,
|
|
19852
19981
|
disabled
|
|
19853
19982
|
}) {
|
|
19854
|
-
return /* @__PURE__ */ (0,
|
|
19983
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
19855
19984
|
"button",
|
|
19856
19985
|
{
|
|
19857
19986
|
type: "button",
|
|
@@ -19870,7 +19999,7 @@ function TogglePill({
|
|
|
19870
19999
|
border: "none",
|
|
19871
20000
|
cursor: disabled ? "default" : "pointer",
|
|
19872
20001
|
background: "#ffffff",
|
|
19873
|
-
color:
|
|
20002
|
+
color: OHW_BLUE_DARK2,
|
|
19874
20003
|
opacity: disabled ? 0.4 : 1,
|
|
19875
20004
|
fontSize: 12,
|
|
19876
20005
|
lineHeight: "16px",
|
|
@@ -19880,7 +20009,7 @@ function TogglePill({
|
|
|
19880
20009
|
},
|
|
19881
20010
|
children: [
|
|
19882
20011
|
label,
|
|
19883
|
-
/* @__PURE__ */ (0,
|
|
20012
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
19884
20013
|
"span",
|
|
19885
20014
|
{
|
|
19886
20015
|
"aria-hidden": true,
|
|
@@ -19893,10 +20022,10 @@ function TogglePill({
|
|
|
19893
20022
|
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
19894
20023
|
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
19895
20024
|
// "disabled control" rather than "switch that is off".
|
|
19896
|
-
background: on ?
|
|
20025
|
+
background: on ? OHW_BLUE_DARK2 : "#CBD5E1",
|
|
19897
20026
|
transition: "background 120ms ease"
|
|
19898
20027
|
},
|
|
19899
|
-
children: /* @__PURE__ */ (0,
|
|
20028
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
19900
20029
|
"span",
|
|
19901
20030
|
{
|
|
19902
20031
|
style: {
|
|
@@ -19925,7 +20054,7 @@ function CarouselSlideToolbar({
|
|
|
19925
20054
|
onChangeImage,
|
|
19926
20055
|
onToggleAutoplay
|
|
19927
20056
|
}) {
|
|
19928
|
-
return /* @__PURE__ */ (0,
|
|
20057
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
19929
20058
|
"div",
|
|
19930
20059
|
{
|
|
19931
20060
|
"data-ohw-bridge": "",
|
|
@@ -19936,7 +20065,7 @@ function CarouselSlideToolbar({
|
|
|
19936
20065
|
flexDirection: "column",
|
|
19937
20066
|
gap: 6,
|
|
19938
20067
|
alignItems: "center",
|
|
19939
|
-
background:
|
|
20068
|
+
background: OHW_BLUE2,
|
|
19940
20069
|
padding: 8,
|
|
19941
20070
|
borderRadius: 12,
|
|
19942
20071
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
@@ -19948,11 +20077,11 @@ function CarouselSlideToolbar({
|
|
|
19948
20077
|
pointerEvents: pending ? "none" : "auto"
|
|
19949
20078
|
},
|
|
19950
20079
|
children: [
|
|
19951
|
-
/* @__PURE__ */ (0,
|
|
19952
|
-
/* @__PURE__ */ (0,
|
|
19953
|
-
/* @__PURE__ */ (0,
|
|
20080
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
20081
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Pill2, { label: "Change Image", onClick: onChangeImage }),
|
|
20082
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
19954
20083
|
] }),
|
|
19955
|
-
error && /* @__PURE__ */ (0,
|
|
20084
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
19956
20085
|
]
|
|
19957
20086
|
}
|
|
19958
20087
|
);
|
|
@@ -20092,8 +20221,8 @@ function AiFadeCarouselOverlay({
|
|
|
20092
20221
|
const activeItemRect = useLiveItemRect2(active);
|
|
20093
20222
|
const TOOLBAR_APPROX_H = 90;
|
|
20094
20223
|
const toolbarState = activeItemRect && activeItemRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
|
|
20095
|
-
return /* @__PURE__ */ (0,
|
|
20096
|
-
hoverHandleRect && hover && /* @__PURE__ */ (0,
|
|
20224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
20225
|
+
hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20097
20226
|
"button",
|
|
20098
20227
|
{
|
|
20099
20228
|
type: "button",
|
|
@@ -20122,10 +20251,10 @@ function AiFadeCarouselOverlay({
|
|
|
20122
20251
|
fontSize: 14,
|
|
20123
20252
|
fontWeight: 700
|
|
20124
20253
|
},
|
|
20125
|
-
children: /* @__PURE__ */ (0,
|
|
20254
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
20126
20255
|
}
|
|
20127
20256
|
),
|
|
20128
|
-
swapping && /* @__PURE__ */ (0,
|
|
20257
|
+
swapping && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20129
20258
|
"div",
|
|
20130
20259
|
{
|
|
20131
20260
|
ref: skeletonRef,
|
|
@@ -20143,15 +20272,15 @@ function AiFadeCarouselOverlay({
|
|
|
20143
20272
|
zIndex: 2147483646,
|
|
20144
20273
|
pointerEvents: "none"
|
|
20145
20274
|
},
|
|
20146
|
-
children: /* @__PURE__ */ (0,
|
|
20275
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
20147
20276
|
}
|
|
20148
20277
|
),
|
|
20149
|
-
activeItemRect && active && activeEntry && /* @__PURE__ */ (0,
|
|
20278
|
+
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20150
20279
|
ItemInteractionLayer,
|
|
20151
20280
|
{
|
|
20152
20281
|
rect: activeItemRect,
|
|
20153
20282
|
state: toolbarState,
|
|
20154
|
-
toolbar: /* @__PURE__ */ (0,
|
|
20283
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20155
20284
|
CarouselSlideToolbar,
|
|
20156
20285
|
{
|
|
20157
20286
|
pending,
|
|
@@ -20504,113 +20633,6 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
20504
20633
|
// src/ui/link-modal/LinkPopover.tsx
|
|
20505
20634
|
var import_react17 = require("react");
|
|
20506
20635
|
|
|
20507
|
-
// src/ui/dialog.tsx
|
|
20508
|
-
var React9 = __toESM(require("react"), 1);
|
|
20509
|
-
var import_radix_ui6 = require("radix-ui");
|
|
20510
|
-
var import_lucide_react12 = require("lucide-react");
|
|
20511
|
-
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
20512
|
-
function Dialog2({
|
|
20513
|
-
...props
|
|
20514
|
-
}) {
|
|
20515
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
20516
|
-
}
|
|
20517
|
-
function DialogPortal({
|
|
20518
|
-
...props
|
|
20519
|
-
}) {
|
|
20520
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
20521
|
-
}
|
|
20522
|
-
function DialogOverlay({
|
|
20523
|
-
className,
|
|
20524
|
-
...props
|
|
20525
|
-
}) {
|
|
20526
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20527
|
-
import_radix_ui6.Dialog.Overlay,
|
|
20528
|
-
{
|
|
20529
|
-
"data-slot": "dialog-overlay",
|
|
20530
|
-
"data-ohw-link-modal-root": "",
|
|
20531
|
-
className: cn("fixed inset-0 z-[2147483646] bg-black/50", className),
|
|
20532
|
-
...props
|
|
20533
|
-
}
|
|
20534
|
-
);
|
|
20535
|
-
}
|
|
20536
|
-
var DialogContent = React9.forwardRef(
|
|
20537
|
-
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
20538
|
-
const positionMode = container ? "absolute" : "fixed";
|
|
20539
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
20540
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
20541
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
20542
|
-
import_radix_ui6.Dialog.Content,
|
|
20543
|
-
{
|
|
20544
|
-
ref,
|
|
20545
|
-
"data-slot": "dialog-content",
|
|
20546
|
-
className: cn(
|
|
20547
|
-
positionMode,
|
|
20548
|
-
"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",
|
|
20549
|
-
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
20550
|
-
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
20551
|
-
className
|
|
20552
|
-
),
|
|
20553
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
20554
|
-
...props,
|
|
20555
|
-
children: [
|
|
20556
|
-
children,
|
|
20557
|
-
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20558
|
-
import_radix_ui6.Dialog.Close,
|
|
20559
|
-
{
|
|
20560
|
-
type: "button",
|
|
20561
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
20562
|
-
"aria-label": "Close",
|
|
20563
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
20564
|
-
}
|
|
20565
|
-
) : null
|
|
20566
|
-
]
|
|
20567
|
-
}
|
|
20568
|
-
)
|
|
20569
|
-
] });
|
|
20570
|
-
}
|
|
20571
|
-
);
|
|
20572
|
-
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
20573
|
-
function DialogHeader({
|
|
20574
|
-
className,
|
|
20575
|
-
...props
|
|
20576
|
-
}) {
|
|
20577
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
20578
|
-
}
|
|
20579
|
-
function DialogFooter({
|
|
20580
|
-
className,
|
|
20581
|
-
...props
|
|
20582
|
-
}) {
|
|
20583
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20584
|
-
"div",
|
|
20585
|
-
{
|
|
20586
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
20587
|
-
...props
|
|
20588
|
-
}
|
|
20589
|
-
);
|
|
20590
|
-
}
|
|
20591
|
-
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20592
|
-
import_radix_ui6.Dialog.Title,
|
|
20593
|
-
{
|
|
20594
|
-
ref,
|
|
20595
|
-
className: cn(
|
|
20596
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
20597
|
-
className
|
|
20598
|
-
),
|
|
20599
|
-
...props
|
|
20600
|
-
}
|
|
20601
|
-
));
|
|
20602
|
-
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
20603
|
-
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
20604
|
-
import_radix_ui6.Dialog.Description,
|
|
20605
|
-
{
|
|
20606
|
-
ref,
|
|
20607
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
20608
|
-
...props
|
|
20609
|
-
}
|
|
20610
|
-
));
|
|
20611
|
-
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
20612
|
-
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
20613
|
-
|
|
20614
20636
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
20615
20637
|
var import_lucide_react16 = require("lucide-react");
|
|
20616
20638
|
|
|
@@ -24614,7 +24636,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
24614
24636
|
el.style.top = `${top}px`;
|
|
24615
24637
|
el.style.height = `${height}px`;
|
|
24616
24638
|
}
|
|
24617
|
-
var
|
|
24639
|
+
var TOOLBAR_EDGE_MARGIN4 = 4;
|
|
24618
24640
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
24619
24641
|
const isAbove = transform.includes("translateY(-100%)");
|
|
24620
24642
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -24641,8 +24663,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
24641
24663
|
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
24642
24664
|
const half = toolbarWidth / 2;
|
|
24643
24665
|
return Math.max(
|
|
24644
|
-
|
|
24645
|
-
Math.min(centerX, window.innerWidth -
|
|
24666
|
+
TOOLBAR_EDGE_MARGIN4 + half,
|
|
24667
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN4 - half)
|
|
24646
24668
|
);
|
|
24647
24669
|
}
|
|
24648
24670
|
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|