@frontlit/page-builder 0.1.0-alpha.1 → 0.1.0-alpha.3
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 +38 -2
- package/dist/blocks/index.d.ts +35 -21
- package/dist/blocks/index.js +4 -3
- package/dist/builder/index.d.ts +8 -11
- package/dist/builder/index.js +7 -5
- package/dist/{button-C3VrMJkr.d.ts → button-OLKN3wPf.d.ts} +3 -3
- package/dist/{chunk-7W6Q4WA7.js → chunk-36QHCIPM.js} +252 -282
- package/dist/chunk-36QHCIPM.js.map +1 -0
- package/dist/{chunk-GTY75HW2.js → chunk-ATNM5JHI.js} +2 -2
- package/dist/chunk-ATNM5JHI.js.map +1 -0
- package/dist/chunk-BBI7UHOA.js +56 -0
- package/dist/chunk-BBI7UHOA.js.map +1 -0
- package/dist/{chunk-MO76KZY2.js → chunk-GIKTOAQS.js} +661 -423
- package/dist/chunk-GIKTOAQS.js.map +1 -0
- package/dist/chunk-HWOVSHIW.js +4 -0
- package/dist/{chunk-RUYOL7JZ.js.map → chunk-HWOVSHIW.js.map} +1 -1
- package/dist/{chunk-SSQWYMQR.js → chunk-IU4KATI2.js} +74 -129
- package/dist/chunk-IU4KATI2.js.map +1 -0
- package/dist/chunk-J7Z4UW45.js +3418 -0
- package/dist/chunk-J7Z4UW45.js.map +1 -0
- package/dist/{chunk-7KIX4WAO.js → chunk-K4WCLHMS.js} +1435 -1382
- package/dist/chunk-K4WCLHMS.js.map +1 -0
- package/dist/chunk-XU7ALPGQ.js +22 -0
- package/dist/chunk-XU7ALPGQ.js.map +1 -0
- package/dist/components/index.d.ts +33 -8
- package/dist/components/index.js +43 -2
- package/dist/components/index.js.map +1 -1
- package/dist/data-slots.d.ts +3 -3
- package/dist/data-slots.js +1 -1
- package/dist/fonts/archivo/archivo-latin-variable.woff2 +0 -0
- package/dist/fonts/hanken-grotesk/hanken-grotesk-latin-variable.woff2 +0 -0
- package/dist/fonts/jetbrains-mono/jetbrains-mono-latin-variable.woff2 +0 -0
- package/dist/fonts/spline-sans-mono/spline-sans-mono-latin-variable.woff2 +0 -0
- package/dist/heading-DQCxQt38.d.ts +20 -0
- package/dist/image-Bk8kPXwP.d.ts +52 -0
- package/dist/index.d.ts +18 -11
- package/dist/index.js +9 -7
- package/dist/media-CnLImjVC.d.ts +21 -0
- package/dist/models/index.d.ts +6 -6
- package/dist/models/index.js +2 -1
- package/dist/{page-DfVl_aHX.d.ts → page-B5Gmm-Ys.d.ts} +2 -3
- package/dist/primitives/index.d.ts +287 -61
- package/dist/primitives/index.js +2 -1
- package/dist/renderer/index.d.ts +12 -8
- package/dist/renderer/index.js +6 -4
- package/dist/{section-background-BgOCp5l3.d.ts → section-background-6V_LCi5e.d.ts} +1 -1
- package/dist/server/index.d.ts +103 -0
- package/dist/server/index.js +2649 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/islands/code-snippet.d.ts +17 -0
- package/dist/server/islands/code-snippet.js +72 -0
- package/dist/server/islands/code-snippet.js.map +1 -0
- package/dist/server/islands/email-form.d.ts +50 -0
- package/dist/server/islands/email-form.js +406 -0
- package/dist/server/islands/email-form.js.map +1 -0
- package/dist/server/islands/header-mobile-menu.d.ts +22 -0
- package/dist/server/islands/header-mobile-menu.js +422 -0
- package/dist/server/islands/header-mobile-menu.js.map +1 -0
- package/dist/server/islands/inline-embed.d.ts +28 -0
- package/dist/server/islands/inline-embed.js +84 -0
- package/dist/server/islands/inline-embed.js.map +1 -0
- package/dist/server/islands/marquee-track.d.ts +18 -0
- package/dist/server/islands/marquee-track.js +67 -0
- package/dist/server/islands/marquee-track.js.map +1 -0
- package/dist/server/islands/nav-link.d.ts +37 -0
- package/dist/server/islands/nav-link.js +67 -0
- package/dist/server/islands/nav-link.js.map +1 -0
- package/dist/server/islands/support-form.d.ts +17 -0
- package/dist/server/islands/support-form.js +469 -0
- package/dist/server/islands/support-form.js.map +1 -0
- package/dist/server/islands/theme-mode-switcher.d.ts +38 -0
- package/dist/server/islands/theme-mode-switcher.js +169 -0
- package/dist/server/islands/theme-mode-switcher.js.map +1 -0
- package/dist/server/islands/video-with-preview.d.ts +13 -0
- package/dist/server/islands/video-with-preview.js +269 -0
- package/dist/server/islands/video-with-preview.js.map +1 -0
- package/dist/server/primitives.d.ts +200 -0
- package/dist/server/primitives.js +888 -0
- package/dist/server/primitives.js.map +1 -0
- package/dist/server/schema.d.ts +11308 -0
- package/dist/server/schema.js +6179 -0
- package/dist/server/schema.js.map +1 -0
- package/dist/server/theme-CF3fIKvw.d.ts +9 -0
- package/dist/{theme-style-39nxXQy0.d.ts → server/theme-style-5_AGy-4V.d.ts} +43 -1
- package/dist/server/theme-style-BPaMwk88.d.ts +183 -0
- package/dist/server/theme.d.ts +28 -0
- package/dist/{chunk-RBJBODQP.js → server/theme.js} +903 -1243
- package/dist/server/theme.js.map +1 -0
- package/dist/server/widget-YH9BrOwY.d.ts +77 -0
- package/dist/styles.css +4016 -8317
- package/dist/theme-style-BVd5tOsc.d.ts +183 -0
- package/dist/theme.css +186 -191
- package/dist/{widget--uEOpdq3.d.ts → widget-CpE2HdgU.d.ts} +25 -18
- package/package.json +71 -11
- package/schema/page.v1.json +3855 -0
- package/schema/site.v1.json +3811 -0
- package/dist/alignment-dZDzN96G.d.ts +0 -5
- package/dist/chunk-7KIX4WAO.js.map +0 -1
- package/dist/chunk-7W6Q4WA7.js.map +0 -1
- package/dist/chunk-GTY75HW2.js.map +0 -1
- package/dist/chunk-MO76KZY2.js.map +0 -1
- package/dist/chunk-RBJBODQP.js.map +0 -1
- package/dist/chunk-RUYOL7JZ.js +0 -4
- package/dist/chunk-SSQWYMQR.js.map +0 -1
- package/dist/fonts/montserrat/montserrat-latin-100-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-200-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-300-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-600-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-700-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-800-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-900-normal.woff2 +0 -0
- package/dist/fonts/source-sans-3/source-sans-3-latin-400-normal.woff2 +0 -0
- package/dist/image-D7GlnOio.d.ts +0 -30
- package/dist/media-Njv378j7.d.ts +0 -13
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { blockRegistry, getAddableBlocks, getWidget, PageRenderer } from './chunk-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { themes, cn, Button, Switch, Input, PageCard, PageCardContent, PageCardHeader, Link, Button2 } from './chunk-
|
|
6
|
-
import
|
|
2
|
+
import { blockRegistry, resolveThemeColor, getAddableBlocks, getWidget, PageRenderer } from './chunk-IU4KATI2.js';
|
|
3
|
+
import { ThemeModeSwitcher } from './chunk-BBI7UHOA.js';
|
|
4
|
+
import { generateUniqueId, FieldGroup, TextField, ToggleField, TitleSizeField } from './chunk-K4WCLHMS.js';
|
|
5
|
+
import { themes, cn, Button, Switch, Input, PageCard, PageCardContent, PageCardHeader, Link, Button2, fluidFontSize, TAILWIND_TEXT_PX } from './chunk-J7Z4UW45.js';
|
|
6
|
+
import { getMediaUrl } from './chunk-XU7ALPGQ.js';
|
|
7
|
+
import React3, { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
7
8
|
import * as Icons from 'lucide-react';
|
|
8
9
|
import { Smartphone, Tablet, Monitor, Palette, Globe, Plus, HelpCircle, X, ImageIcon, Sparkles, ExternalLink, Check, ChevronLeft, LayoutTemplate, Layers3, Pin, ChevronDown, FilePenLine, Brush, ChevronRight, Type, SquareMousePointer, Columns3, Pencil, Info } from 'lucide-react';
|
|
9
10
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
11
|
import { createPortal } from 'react-dom';
|
|
12
|
+
import { ImageUploadDialog } from '@frontlit/media-uploader';
|
|
11
13
|
|
|
12
14
|
// src/utils/debounce.ts
|
|
13
15
|
function debounce(fn, wait) {
|
|
14
16
|
let timeout;
|
|
15
|
-
|
|
17
|
+
let pending = null;
|
|
18
|
+
const debounced = function(...args) {
|
|
19
|
+
pending = args;
|
|
16
20
|
clearTimeout(timeout);
|
|
17
|
-
timeout = setTimeout(
|
|
18
|
-
fn(...args);
|
|
19
|
-
}, wait);
|
|
21
|
+
timeout = setTimeout(debounced.flush, wait);
|
|
20
22
|
};
|
|
23
|
+
debounced.flush = () => {
|
|
24
|
+
clearTimeout(timeout);
|
|
25
|
+
if (!pending) return;
|
|
26
|
+
const args = pending;
|
|
27
|
+
pending = null;
|
|
28
|
+
fn(...args);
|
|
29
|
+
};
|
|
30
|
+
return debounced;
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
// src/utils/color-mode.ts
|
|
@@ -44,12 +54,16 @@ function createWidgetInstance(name, overrides) {
|
|
|
44
54
|
}
|
|
45
55
|
};
|
|
46
56
|
}
|
|
57
|
+
function withDefaultSettings(layout) {
|
|
58
|
+
return layout.map((widget) => {
|
|
59
|
+
const defaults = blockRegistry[widget.name]?.getDefaultSettings?.();
|
|
60
|
+
return defaults ? { ...widget, settings: { ...defaults, ...widget.settings } } : widget;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
47
63
|
function ensureRequiredSharedWidgets(layout) {
|
|
48
64
|
const header = layout.find((widget) => widget.name === "header") ?? createWidgetInstance("header");
|
|
49
65
|
const footer = layout.find((widget) => widget.name === "footer") ?? createWidgetInstance("footer");
|
|
50
|
-
const body = layout.filter(
|
|
51
|
-
(widget) => !["header", "footer"].includes(widget.name)
|
|
52
|
-
);
|
|
66
|
+
const body = layout.filter((widget) => !["header", "footer"].includes(widget.name));
|
|
53
67
|
return [
|
|
54
68
|
{
|
|
55
69
|
...header,
|
|
@@ -213,7 +227,11 @@ var THEME_FONT_VARS = [
|
|
|
213
227
|
"--font-bebas-neue",
|
|
214
228
|
"--font-lato",
|
|
215
229
|
"--font-pt-sans",
|
|
216
|
-
"--font-quicksand"
|
|
230
|
+
"--font-quicksand",
|
|
231
|
+
"--font-archivo",
|
|
232
|
+
"--font-jetbrains-mono",
|
|
233
|
+
"--font-hanken-grotesk",
|
|
234
|
+
"--font-spline-sans-mono"
|
|
217
235
|
];
|
|
218
236
|
function readCssVar(sourceDoc, name) {
|
|
219
237
|
const view = sourceDoc.defaultView;
|
|
@@ -250,6 +268,7 @@ function PreviewFrame({
|
|
|
250
268
|
const iframe = iframeRef.current;
|
|
251
269
|
if (!iframe) return;
|
|
252
270
|
let observer;
|
|
271
|
+
let resizeObserver;
|
|
253
272
|
const init = () => {
|
|
254
273
|
const doc = iframe.contentDocument;
|
|
255
274
|
if (!doc) return;
|
|
@@ -268,12 +287,21 @@ function PreviewFrame({
|
|
|
268
287
|
characterData: true
|
|
269
288
|
});
|
|
270
289
|
setMountNode(doc.body);
|
|
290
|
+
resizeObserver?.disconnect();
|
|
291
|
+
const measure = () => iframe.style.setProperty(
|
|
292
|
+
"--pb-scrollbar",
|
|
293
|
+
`${Math.max(0, iframe.clientWidth - doc.documentElement.clientWidth)}px`
|
|
294
|
+
);
|
|
295
|
+
resizeObserver = new ResizeObserver(measure);
|
|
296
|
+
resizeObserver.observe(doc.documentElement);
|
|
297
|
+
measure();
|
|
271
298
|
};
|
|
272
299
|
if (iframe.contentDocument?.readyState === "complete") init();
|
|
273
300
|
iframe.addEventListener("load", init);
|
|
274
301
|
return () => {
|
|
275
302
|
iframe.removeEventListener("load", init);
|
|
276
303
|
observer?.disconnect();
|
|
304
|
+
resizeObserver?.disconnect();
|
|
277
305
|
};
|
|
278
306
|
}, []);
|
|
279
307
|
return /* @__PURE__ */ jsx("iframe", { ref: iframeRef, title, className, children: mountNode ? createPortal(children, mountNode) : null });
|
|
@@ -335,6 +363,67 @@ function BlockPicker({
|
|
|
335
363
|
}
|
|
336
364
|
);
|
|
337
365
|
}
|
|
366
|
+
function ConfirmDialog({
|
|
367
|
+
title,
|
|
368
|
+
description,
|
|
369
|
+
confirmLabel,
|
|
370
|
+
onConfirm,
|
|
371
|
+
onClose
|
|
372
|
+
}) {
|
|
373
|
+
const cancelRef = useRef(null);
|
|
374
|
+
useEffect(() => {
|
|
375
|
+
cancelRef.current?.focus();
|
|
376
|
+
const onKeyDown = (event) => {
|
|
377
|
+
if (event.key === "Escape") onClose();
|
|
378
|
+
};
|
|
379
|
+
document.addEventListener("keydown", onKeyDown);
|
|
380
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
381
|
+
}, [onClose]);
|
|
382
|
+
return /* @__PURE__ */ jsx(
|
|
383
|
+
"div",
|
|
384
|
+
{
|
|
385
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",
|
|
386
|
+
onClick: onClose,
|
|
387
|
+
children: /* @__PURE__ */ jsxs(
|
|
388
|
+
"div",
|
|
389
|
+
{
|
|
390
|
+
role: "alertdialog",
|
|
391
|
+
"aria-modal": "true",
|
|
392
|
+
"aria-label": title,
|
|
393
|
+
className: "flex w-full max-w-sm flex-col gap-4 rounded-lg border border-border bg-background p-5 shadow-xl",
|
|
394
|
+
onClick: (e) => e.stopPropagation(),
|
|
395
|
+
children: [
|
|
396
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
397
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
398
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs leading-5 text-muted-foreground", children: description })
|
|
399
|
+
] }),
|
|
400
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
401
|
+
/* @__PURE__ */ jsx(
|
|
402
|
+
"button",
|
|
403
|
+
{
|
|
404
|
+
ref: cancelRef,
|
|
405
|
+
type: "button",
|
|
406
|
+
className: "inline-flex h-8 items-center justify-center rounded-lg border border-input bg-background px-3 text-xs font-medium text-foreground hover:bg-muted",
|
|
407
|
+
onClick: onClose,
|
|
408
|
+
children: "Cancel"
|
|
409
|
+
}
|
|
410
|
+
),
|
|
411
|
+
/* @__PURE__ */ jsx(
|
|
412
|
+
"button",
|
|
413
|
+
{
|
|
414
|
+
type: "button",
|
|
415
|
+
className: "inline-flex h-8 items-center justify-center rounded-lg bg-destructive px-3 text-xs font-medium text-destructive-foreground hover:bg-destructive/90",
|
|
416
|
+
onClick: onConfirm,
|
|
417
|
+
children: confirmLabel
|
|
418
|
+
}
|
|
419
|
+
)
|
|
420
|
+
] })
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
}
|
|
338
427
|
function PanelHeader({
|
|
339
428
|
title,
|
|
340
429
|
onClose,
|
|
@@ -401,7 +490,6 @@ function PageBuilderSlider({
|
|
|
401
490
|
onChange,
|
|
402
491
|
tooltip,
|
|
403
492
|
className,
|
|
404
|
-
allowsReset = false,
|
|
405
493
|
unit = "px"
|
|
406
494
|
}) {
|
|
407
495
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2.5", className), children: [
|
|
@@ -424,20 +512,7 @@ function PageBuilderSlider({
|
|
|
424
512
|
className: "h-7 w-12 rounded-md border border-input bg-muted/20 px-1.5 py-1 text-center text-xs font-semibold text-foreground outline-none transition-colors focus:border-ring focus:bg-background focus:ring-2 focus:ring-ring/20"
|
|
425
513
|
}
|
|
426
514
|
),
|
|
427
|
-
unit && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground", children: unit })
|
|
428
|
-
allowsReset && /* @__PURE__ */ jsx(
|
|
429
|
-
"button",
|
|
430
|
-
{
|
|
431
|
-
type: "button",
|
|
432
|
-
title: "Reset",
|
|
433
|
-
className: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
434
|
-
onClick: (e) => {
|
|
435
|
-
e.preventDefault();
|
|
436
|
-
onChange();
|
|
437
|
-
},
|
|
438
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3 text-muted-foreground hover:text-foreground" })
|
|
439
|
-
}
|
|
440
|
-
)
|
|
515
|
+
unit && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground", children: unit })
|
|
441
516
|
] })
|
|
442
517
|
] }),
|
|
443
518
|
/* @__PURE__ */ jsx(
|
|
@@ -464,67 +539,64 @@ function ColorSelector({
|
|
|
464
539
|
allowReset = true,
|
|
465
540
|
description
|
|
466
541
|
}) {
|
|
467
|
-
const [localValue, setLocalValue] =
|
|
468
|
-
|
|
542
|
+
const [localValue, setLocalValue] = React3.useState(value);
|
|
543
|
+
React3.useEffect(() => {
|
|
469
544
|
setLocalValue(value);
|
|
470
545
|
}, [value]);
|
|
471
546
|
const handleChange = (newValue) => {
|
|
472
547
|
setLocalValue(newValue);
|
|
473
548
|
onChange(newValue);
|
|
474
549
|
};
|
|
550
|
+
const invalid = Boolean(localValue) && !resolveThemeColor(localValue);
|
|
475
551
|
const swatchValue = /^#[0-9a-fA-F]{6}$/.test(localValue) ? localValue : "#000000";
|
|
476
|
-
return /* @__PURE__ */ jsxs(
|
|
477
|
-
"div",
|
|
478
|
-
|
|
479
|
-
className:
|
|
480
|
-
|
|
481
|
-
|
|
552
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center justify-between gap-2", className), children: [
|
|
553
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
554
|
+
/* @__PURE__ */ jsx(PageBuilderPropertyHeader, { label: title, tooltip }),
|
|
555
|
+
description && /* @__PURE__ */ jsx("p", { className: "break-words text-xs text-muted-foreground", children: description })
|
|
556
|
+
] }),
|
|
557
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
558
|
+
/* @__PURE__ */ jsx(
|
|
559
|
+
"input",
|
|
560
|
+
{
|
|
561
|
+
type: "color",
|
|
562
|
+
value: swatchValue,
|
|
563
|
+
onChange: (e) => handleChange(e.currentTarget.value),
|
|
564
|
+
className: "h-7 w-9 shrink-0 cursor-pointer rounded-md border border-input bg-background p-0.5",
|
|
565
|
+
"aria-label": `${title} swatch`
|
|
566
|
+
}
|
|
482
567
|
),
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
className: "h-7 w-9 shrink-0 cursor-pointer rounded-md border border-input bg-background p-0.5",
|
|
496
|
-
"aria-label": `${title} swatch`
|
|
497
|
-
}
|
|
498
|
-
),
|
|
499
|
-
/* @__PURE__ */ jsx(
|
|
500
|
-
"input",
|
|
501
|
-
{
|
|
502
|
-
type: "text",
|
|
503
|
-
value: localValue ?? "",
|
|
504
|
-
placeholder: "#000000",
|
|
505
|
-
onChange: (e) => handleChange(e.currentTarget.value),
|
|
506
|
-
className: "h-7 w-20 min-w-0 rounded-md border border-input bg-background px-2 py-1 text-xs text-foreground outline-none focus:ring-2 focus:ring-ring/20",
|
|
507
|
-
"aria-label": `${title} hex value`
|
|
508
|
-
}
|
|
568
|
+
/* @__PURE__ */ jsx(
|
|
569
|
+
"input",
|
|
570
|
+
{
|
|
571
|
+
type: "text",
|
|
572
|
+
value: localValue ?? "",
|
|
573
|
+
placeholder: "#000000 or oklch(\u2026)",
|
|
574
|
+
title: "A hex colour, or a CSS colour such as oklch(0.6 0.2 30)",
|
|
575
|
+
"aria-invalid": invalid || void 0,
|
|
576
|
+
onChange: (e) => handleChange(e.currentTarget.value),
|
|
577
|
+
className: cn(
|
|
578
|
+
"h-7 w-28 min-w-0 rounded-md border border-input bg-background px-2 py-1 text-xs text-foreground outline-none focus:ring-2 focus:ring-ring/20",
|
|
579
|
+
invalid && "border-destructive focus:ring-destructive/30"
|
|
509
580
|
),
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
581
|
+
"aria-label": `${title} hex value`
|
|
582
|
+
}
|
|
583
|
+
),
|
|
584
|
+
allowReset && /* @__PURE__ */ jsx(
|
|
585
|
+
"button",
|
|
586
|
+
{
|
|
587
|
+
type: "button",
|
|
588
|
+
title: "Reset",
|
|
589
|
+
className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md hover:bg-muted/50",
|
|
590
|
+
onClick: (e) => {
|
|
591
|
+
e.preventDefault();
|
|
592
|
+
setLocalValue("");
|
|
593
|
+
onChange();
|
|
594
|
+
},
|
|
595
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3 text-muted-foreground hover:text-foreground" })
|
|
596
|
+
}
|
|
597
|
+
)
|
|
598
|
+
] })
|
|
599
|
+
] });
|
|
528
600
|
}
|
|
529
601
|
var MAX_WIDTH_MAP = {
|
|
530
602
|
1: "max-w-2xl",
|
|
@@ -547,10 +619,6 @@ function MaxWidthSelector({
|
|
|
547
619
|
([_, v]) => v === (value ?? themeDefault)
|
|
548
620
|
)?.[0] || "5";
|
|
549
621
|
const handleChange = (newValue) => {
|
|
550
|
-
if (newValue === void 0) {
|
|
551
|
-
onChange();
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
622
|
onChange(getMaxWidthTWClass(newValue));
|
|
555
623
|
};
|
|
556
624
|
return /* @__PURE__ */ jsx(
|
|
@@ -563,7 +631,6 @@ function MaxWidthSelector({
|
|
|
563
631
|
value: parseInt(numericValue),
|
|
564
632
|
tooltip: "Maximum width of the content",
|
|
565
633
|
className,
|
|
566
|
-
allowsReset: true,
|
|
567
634
|
unit: ""
|
|
568
635
|
}
|
|
569
636
|
);
|
|
@@ -594,14 +661,8 @@ function VerticalPaddingSelector({
|
|
|
594
661
|
className = "",
|
|
595
662
|
themeDefault
|
|
596
663
|
}) {
|
|
597
|
-
const numericValue = Object.entries(PADDING_MAP).find(
|
|
598
|
-
([_, v]) => v === (value ?? themeDefault)
|
|
599
|
-
)?.[0] || "6";
|
|
664
|
+
const numericValue = Object.entries(PADDING_MAP).find(([_, v]) => v === (value ?? themeDefault))?.[0] || "6";
|
|
600
665
|
const handleChange = (newValue) => {
|
|
601
|
-
if (newValue === void 0) {
|
|
602
|
-
onChange();
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
666
|
onChange(getVerticalPaddingTWClass(newValue));
|
|
606
667
|
};
|
|
607
668
|
return /* @__PURE__ */ jsx(
|
|
@@ -1145,10 +1206,7 @@ function PanelSelect({
|
|
|
1145
1206
|
"select",
|
|
1146
1207
|
{
|
|
1147
1208
|
id,
|
|
1148
|
-
className: cn(
|
|
1149
|
-
controlClass,
|
|
1150
|
-
"cursor-pointer appearance-none pr-8"
|
|
1151
|
-
),
|
|
1209
|
+
className: cn(controlClass, "cursor-pointer appearance-none pr-8"),
|
|
1152
1210
|
value,
|
|
1153
1211
|
onChange: (e) => onChange(e.target.value),
|
|
1154
1212
|
children: options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
@@ -1255,7 +1313,7 @@ function FixedBackgroundToggle({
|
|
|
1255
1313
|
] }) });
|
|
1256
1314
|
}
|
|
1257
1315
|
function BackgroundPreview({ value }) {
|
|
1258
|
-
const imageUrl = value.type === "image"
|
|
1316
|
+
const imageUrl = value.type === "image" ? getMediaUrl(value.media) ?? void 0 : void 0;
|
|
1259
1317
|
const previewStyle = (() => {
|
|
1260
1318
|
if (value.type === "color") {
|
|
1261
1319
|
return {
|
|
@@ -1283,43 +1341,36 @@ function BackgroundPreview({ value }) {
|
|
|
1283
1341
|
})();
|
|
1284
1342
|
const typeLabel = BG_TYPES.find((t) => t.type === value.type)?.label ?? "Background";
|
|
1285
1343
|
return /* @__PURE__ */ jsxs("div", { className: "min-w-0 max-w-full overflow-hidden rounded-xl border border-border/70 shadow-sm", children: [
|
|
1286
|
-
/* @__PURE__ */ jsxs(
|
|
1287
|
-
"
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
value.type === "gradient" && !value.backgroundImage ? /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 flex items-center justify-center gap-1.5 text-[11px] text-muted-foreground", children: [
|
|
1317
|
-
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
1318
|
-
"Choose a pattern"
|
|
1319
|
-
] }) : null
|
|
1320
|
-
]
|
|
1321
|
-
}
|
|
1322
|
-
),
|
|
1344
|
+
/* @__PURE__ */ jsxs("div", { className: "relative h-14 w-full max-w-full", style: previewStyle, children: [
|
|
1345
|
+
value.type === "image" && imageUrl && (value.blur || 0) > 0 ? /* @__PURE__ */ jsx(
|
|
1346
|
+
"div",
|
|
1347
|
+
{
|
|
1348
|
+
className: "absolute inset-0",
|
|
1349
|
+
style: {
|
|
1350
|
+
backdropFilter: `blur(${value.blur}px)`
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
) : null,
|
|
1354
|
+
value.type === "image" && value.overlay?.color ? /* @__PURE__ */ jsx(
|
|
1355
|
+
"div",
|
|
1356
|
+
{
|
|
1357
|
+
className: "absolute inset-0",
|
|
1358
|
+
style: {
|
|
1359
|
+
backgroundColor: value.overlay.color,
|
|
1360
|
+
opacity: (value.overlay.opacity || 0) / 10,
|
|
1361
|
+
mixBlendMode: value.overlay.blendMode || "normal"
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
) : null,
|
|
1365
|
+
value.type === "image" && !imageUrl ? /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 flex items-center justify-center gap-1.5 text-[11px] text-muted-foreground", children: [
|
|
1366
|
+
/* @__PURE__ */ jsx(ImageIcon, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
1367
|
+
"No image yet"
|
|
1368
|
+
] }) : null,
|
|
1369
|
+
value.type === "gradient" && !value.backgroundImage ? /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 flex items-center justify-center gap-1.5 text-[11px] text-muted-foreground", children: [
|
|
1370
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
1371
|
+
"Choose a pattern"
|
|
1372
|
+
] }) : null
|
|
1373
|
+
] }),
|
|
1323
1374
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-border/60 bg-muted/20 px-3 py-1.5", children: [
|
|
1324
1375
|
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Preview" }),
|
|
1325
1376
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-foreground", children: typeLabel })
|
|
@@ -1331,7 +1382,9 @@ function SectionBackgroundPanel({
|
|
|
1331
1382
|
onChange,
|
|
1332
1383
|
className
|
|
1333
1384
|
}) {
|
|
1334
|
-
const [patternFilter, setPatternFilter] = useState(
|
|
1385
|
+
const [patternFilter, setPatternFilter] = useState(
|
|
1386
|
+
"all"
|
|
1387
|
+
);
|
|
1335
1388
|
const handleTypeChange = (type) => {
|
|
1336
1389
|
onChange({ ...value, type });
|
|
1337
1390
|
};
|
|
@@ -1453,29 +1506,115 @@ function SectionBackgroundPanel({
|
|
|
1453
1506
|
SectionCard,
|
|
1454
1507
|
{
|
|
1455
1508
|
title: "Source",
|
|
1456
|
-
description: "
|
|
1457
|
-
children: /* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
1458
|
-
/* @__PURE__ */
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
ImageIcon,
|
|
1509
|
+
description: "Upload an image or paste a public URL for the section backdrop.",
|
|
1510
|
+
children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1511
|
+
getMediaUrl(value.media) ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1512
|
+
/* @__PURE__ */ jsx("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg border border-border bg-muted/40", children: /* @__PURE__ */ jsx(
|
|
1513
|
+
"img",
|
|
1462
1514
|
{
|
|
1463
|
-
|
|
1464
|
-
"
|
|
1465
|
-
|
|
1466
|
-
),
|
|
1467
|
-
/* @__PURE__ */ jsx(
|
|
1468
|
-
PanelInput,
|
|
1469
|
-
{
|
|
1470
|
-
id: "background-image-url",
|
|
1471
|
-
value: value.media?.file || "",
|
|
1472
|
-
onChange: (e) => handleBackgroundChange({
|
|
1473
|
-
media: e.target.value ? { file: e.target.value } : {}
|
|
1474
|
-
}),
|
|
1475
|
-
placeholder: "https://example.com/background.jpg",
|
|
1476
|
-
className: "pl-9"
|
|
1515
|
+
src: getMediaUrl(value.media),
|
|
1516
|
+
alt: "Background preview",
|
|
1517
|
+
className: "h-full w-full object-cover"
|
|
1477
1518
|
}
|
|
1478
|
-
)
|
|
1519
|
+
) }),
|
|
1520
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1521
|
+
/* @__PURE__ */ jsx(
|
|
1522
|
+
ImageUploadDialog,
|
|
1523
|
+
{
|
|
1524
|
+
title: "Change background image",
|
|
1525
|
+
description: "Upload an image or select one from your library.",
|
|
1526
|
+
onSelect: (selected) => {
|
|
1527
|
+
const selMedia = selected.media;
|
|
1528
|
+
const mediaLitId = selMedia?.mediaLitId ?? selMedia?.mediaId ?? void 0;
|
|
1529
|
+
handleBackgroundChange({
|
|
1530
|
+
media: {
|
|
1531
|
+
...mediaLitId ? { mediaId: mediaLitId, mediaLitId } : {},
|
|
1532
|
+
url: selected.src,
|
|
1533
|
+
file: selected.src,
|
|
1534
|
+
thumbnailUrl: selMedia?.thumbnailUrl ?? selected.src,
|
|
1535
|
+
thumbnail: selMedia?.thumbnailUrl ?? selected.src,
|
|
1536
|
+
alt: selected.alt
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
},
|
|
1540
|
+
children: /* @__PURE__ */ jsxs(
|
|
1541
|
+
"button",
|
|
1542
|
+
{
|
|
1543
|
+
type: "button",
|
|
1544
|
+
className: "inline-flex h-8 items-center justify-center rounded-lg border border-input bg-background px-3 text-xs font-medium text-foreground hover:bg-muted",
|
|
1545
|
+
children: [
|
|
1546
|
+
/* @__PURE__ */ jsx(ImageIcon, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
1547
|
+
"Change image"
|
|
1548
|
+
]
|
|
1549
|
+
}
|
|
1550
|
+
)
|
|
1551
|
+
}
|
|
1552
|
+
),
|
|
1553
|
+
/* @__PURE__ */ jsx(
|
|
1554
|
+
"button",
|
|
1555
|
+
{
|
|
1556
|
+
type: "button",
|
|
1557
|
+
className: "inline-flex h-8 items-center justify-center rounded-lg border border-destructive/30 bg-background px-3 text-xs font-medium text-destructive hover:bg-destructive/10",
|
|
1558
|
+
onClick: () => handleBackgroundChange({ media: void 0 }),
|
|
1559
|
+
children: "Remove"
|
|
1560
|
+
}
|
|
1561
|
+
)
|
|
1562
|
+
] })
|
|
1563
|
+
] }) : /* @__PURE__ */ jsx(
|
|
1564
|
+
ImageUploadDialog,
|
|
1565
|
+
{
|
|
1566
|
+
title: "Choose background image",
|
|
1567
|
+
description: "Upload an image or select one from your library.",
|
|
1568
|
+
onSelect: (selected) => {
|
|
1569
|
+
const selMedia = selected.media;
|
|
1570
|
+
const mediaLitId = selMedia?.mediaLitId ?? selMedia?.mediaId ?? void 0;
|
|
1571
|
+
handleBackgroundChange({
|
|
1572
|
+
media: {
|
|
1573
|
+
...mediaLitId ? { mediaId: mediaLitId, mediaLitId } : {},
|
|
1574
|
+
url: selected.src,
|
|
1575
|
+
file: selected.src,
|
|
1576
|
+
thumbnailUrl: selMedia?.thumbnailUrl ?? selected.src,
|
|
1577
|
+
thumbnail: selMedia?.thumbnailUrl ?? selected.src,
|
|
1578
|
+
alt: selected.alt
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
},
|
|
1582
|
+
children: /* @__PURE__ */ jsxs(
|
|
1583
|
+
"button",
|
|
1584
|
+
{
|
|
1585
|
+
type: "button",
|
|
1586
|
+
className: "flex w-full items-center justify-center gap-2 rounded-lg border border-dashed border-border bg-muted/20 py-3 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:bg-muted/40 hover:text-foreground",
|
|
1587
|
+
children: [
|
|
1588
|
+
/* @__PURE__ */ jsx(ImageIcon, { className: "h-4 w-4" }),
|
|
1589
|
+
"Upload or choose image"
|
|
1590
|
+
]
|
|
1591
|
+
}
|
|
1592
|
+
)
|
|
1593
|
+
}
|
|
1594
|
+
),
|
|
1595
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5 pt-1", children: [
|
|
1596
|
+
/* @__PURE__ */ jsx(FieldLabel, { htmlFor: "background-image-url", children: "Or paste image URL" }),
|
|
1597
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1598
|
+
/* @__PURE__ */ jsx(
|
|
1599
|
+
ImageIcon,
|
|
1600
|
+
{
|
|
1601
|
+
className: "pointer-events-none absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground",
|
|
1602
|
+
"aria-hidden": true
|
|
1603
|
+
}
|
|
1604
|
+
),
|
|
1605
|
+
/* @__PURE__ */ jsx(
|
|
1606
|
+
PanelInput,
|
|
1607
|
+
{
|
|
1608
|
+
id: "background-image-url",
|
|
1609
|
+
value: getMediaUrl(value.media) || "",
|
|
1610
|
+
onChange: (e) => handleBackgroundChange({
|
|
1611
|
+
media: e.target.value ? { file: e.target.value, url: e.target.value } : void 0
|
|
1612
|
+
}),
|
|
1613
|
+
placeholder: "https://example.com/background.jpg",
|
|
1614
|
+
className: "pl-9"
|
|
1615
|
+
}
|
|
1616
|
+
)
|
|
1617
|
+
] })
|
|
1479
1618
|
] })
|
|
1480
1619
|
] })
|
|
1481
1620
|
}
|
|
@@ -1618,13 +1757,7 @@ function SectionBackgroundPanel({
|
|
|
1618
1757
|
className: "inline-flex items-center gap-1 text-[10px] font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
|
|
1619
1758
|
children: [
|
|
1620
1759
|
"Docs",
|
|
1621
|
-
/* @__PURE__ */ jsx(
|
|
1622
|
-
ExternalLink,
|
|
1623
|
-
{
|
|
1624
|
-
className: "h-3 w-3",
|
|
1625
|
-
"aria-hidden": true
|
|
1626
|
-
}
|
|
1627
|
-
)
|
|
1760
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3", "aria-hidden": true })
|
|
1628
1761
|
]
|
|
1629
1762
|
}
|
|
1630
1763
|
),
|
|
@@ -1707,13 +1840,7 @@ function SectionBackgroundPanel({
|
|
|
1707
1840
|
maskImage: preset.apply.gradientMaskImage
|
|
1708
1841
|
},
|
|
1709
1842
|
"aria-hidden": true,
|
|
1710
|
-
children: isSelected ? /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm", children: /* @__PURE__ */ jsx(
|
|
1711
|
-
Check,
|
|
1712
|
-
{
|
|
1713
|
-
className: "h-2.5 w-2.5",
|
|
1714
|
-
"aria-hidden": true
|
|
1715
|
-
}
|
|
1716
|
-
) }) : null
|
|
1843
|
+
children: isSelected ? /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm", children: /* @__PURE__ */ jsx(Check, { className: "h-2.5 w-2.5", "aria-hidden": true }) }) : null
|
|
1717
1844
|
}
|
|
1718
1845
|
),
|
|
1719
1846
|
/* @__PURE__ */ jsx("span", { className: "truncate border-t border-border/60 px-1 py-1 text-[10px] font-semibold leading-tight text-foreground", children: preset.label })
|
|
@@ -1853,13 +1980,7 @@ function SectionBackgroundPanel({
|
|
|
1853
1980
|
className: "inline-flex items-center gap-1 text-[10px] font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
|
|
1854
1981
|
children: [
|
|
1855
1982
|
"Docs",
|
|
1856
|
-
/* @__PURE__ */ jsx(
|
|
1857
|
-
ExternalLink,
|
|
1858
|
-
{
|
|
1859
|
-
className: "h-3 w-3",
|
|
1860
|
-
"aria-hidden": true
|
|
1861
|
-
}
|
|
1862
|
-
)
|
|
1983
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3", "aria-hidden": true })
|
|
1863
1984
|
]
|
|
1864
1985
|
}
|
|
1865
1986
|
),
|
|
@@ -1966,6 +2087,7 @@ function BlockSettings({
|
|
|
1966
2087
|
}) {
|
|
1967
2088
|
const [tab, setTab] = useState("data");
|
|
1968
2089
|
const Editor = definition.editor;
|
|
2090
|
+
const DesignEditor = definition.designEditor;
|
|
1969
2091
|
const settings = instance.settings ?? {};
|
|
1970
2092
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col", children: [
|
|
1971
2093
|
/* @__PURE__ */ jsx(
|
|
@@ -1997,14 +2119,7 @@ function BlockSettings({
|
|
|
1997
2119
|
})
|
|
1998
2120
|
}
|
|
1999
2121
|
),
|
|
2000
|
-
/* @__PURE__ */ jsx("div", { className: "pt-5", children: tab === "data" && Editor && /* @__PURE__ */ jsx(
|
|
2001
|
-
Editor,
|
|
2002
|
-
{
|
|
2003
|
-
settings,
|
|
2004
|
-
theme,
|
|
2005
|
-
onChange
|
|
2006
|
-
}
|
|
2007
|
-
) }),
|
|
2122
|
+
/* @__PURE__ */ jsx("div", { className: "pt-5", children: tab === "data" && Editor && /* @__PURE__ */ jsx(Editor, { settings, theme, onChange }) }),
|
|
2008
2123
|
tab === "design" && /* @__PURE__ */ jsxs("div", { className: "min-w-0 max-w-full space-y-5 pt-5", children: [
|
|
2009
2124
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2010
2125
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Refine the look" }),
|
|
@@ -2039,13 +2154,7 @@ function BlockSettings({
|
|
|
2039
2154
|
}),
|
|
2040
2155
|
children: [
|
|
2041
2156
|
/* @__PURE__ */ jsx("span", { children: layout.name }),
|
|
2042
|
-
active && /* @__PURE__ */ jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx(
|
|
2043
|
-
Check,
|
|
2044
|
-
{
|
|
2045
|
-
className: "h-3 w-3",
|
|
2046
|
-
"aria-hidden": "true"
|
|
2047
|
-
}
|
|
2048
|
-
) })
|
|
2157
|
+
active && /* @__PURE__ */ jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx(Check, { className: "h-3 w-3", "aria-hidden": "true" }) })
|
|
2049
2158
|
]
|
|
2050
2159
|
},
|
|
2051
2160
|
layout.id
|
|
@@ -2054,6 +2163,21 @@ function BlockSettings({
|
|
|
2054
2163
|
}
|
|
2055
2164
|
)
|
|
2056
2165
|
] }),
|
|
2166
|
+
DesignEditor && /* @__PURE__ */ jsx(
|
|
2167
|
+
DesignEditor,
|
|
2168
|
+
{
|
|
2169
|
+
settings,
|
|
2170
|
+
theme,
|
|
2171
|
+
onChange
|
|
2172
|
+
}
|
|
2173
|
+
),
|
|
2174
|
+
definition.titleSize && /* @__PURE__ */ jsx(FieldGroup, { title: "Title", children: /* @__PURE__ */ jsx(
|
|
2175
|
+
TitleSizeField,
|
|
2176
|
+
{
|
|
2177
|
+
settings,
|
|
2178
|
+
onChange: (partial) => onChange({ ...settings, ...partial })
|
|
2179
|
+
}
|
|
2180
|
+
) }),
|
|
2057
2181
|
/* @__PURE__ */ jsx(
|
|
2058
2182
|
DesignFieldGroup,
|
|
2059
2183
|
{
|
|
@@ -2124,15 +2248,7 @@ function ThemeCard({
|
|
|
2124
2248
|
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-foreground", children: name }),
|
|
2125
2249
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
2126
2250
|
onEdit && /* @__PURE__ */ jsx(CardButton, { label: `Edit ${name}`, onClick: onEdit, children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" }) }),
|
|
2127
|
-
onUse && /* @__PURE__ */ jsx(
|
|
2128
|
-
CardButton,
|
|
2129
|
-
{
|
|
2130
|
-
label: `Use ${name}`,
|
|
2131
|
-
disabled: active,
|
|
2132
|
-
onClick: onUse,
|
|
2133
|
-
children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
|
|
2134
|
-
}
|
|
2135
|
-
)
|
|
2251
|
+
onUse && /* @__PURE__ */ jsx(CardButton, { label: `Use ${name}`, disabled: active, onClick: onUse, children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) })
|
|
2136
2252
|
] })
|
|
2137
2253
|
] }),
|
|
2138
2254
|
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: palette.map((color, i) => /* @__PURE__ */ jsx(
|
|
@@ -2151,14 +2267,7 @@ function PanelLabel({
|
|
|
2151
2267
|
htmlFor,
|
|
2152
2268
|
children
|
|
2153
2269
|
}) {
|
|
2154
|
-
return /* @__PURE__ */ jsx(
|
|
2155
|
-
"label",
|
|
2156
|
-
{
|
|
2157
|
-
htmlFor,
|
|
2158
|
-
className: "text-xs font-medium text-foreground",
|
|
2159
|
-
children
|
|
2160
|
-
}
|
|
2161
|
-
);
|
|
2270
|
+
return /* @__PURE__ */ jsx("label", { htmlFor, className: "text-xs font-medium text-foreground", children });
|
|
2162
2271
|
}
|
|
2163
2272
|
function PanelInput2(props) {
|
|
2164
2273
|
const { className, ...rest } = props;
|
|
@@ -2338,7 +2447,8 @@ var fontFamilyOptions = {
|
|
|
2338
2447
|
{ label: "Roboto", value: "font-roboto" },
|
|
2339
2448
|
{ label: "Mulish", value: "font-mulish" },
|
|
2340
2449
|
{ label: "Nunito", value: "font-nunito" },
|
|
2341
|
-
{ label: "Work Sans", value: "font-work-sans" }
|
|
2450
|
+
{ label: "Work Sans", value: "font-work-sans" },
|
|
2451
|
+
{ label: "Hanken Grotesk", value: "font-hanken-grotesk" }
|
|
2342
2452
|
],
|
|
2343
2453
|
Serif: [
|
|
2344
2454
|
{ label: "Merriweather", value: "font-merriweather" },
|
|
@@ -2353,19 +2463,30 @@ var fontFamilyOptions = {
|
|
|
2353
2463
|
{ label: "Raleway", value: "font-raleway" },
|
|
2354
2464
|
{ label: "Rubik", value: "font-rubik" },
|
|
2355
2465
|
{ label: "Oswald", value: "font-oswald" },
|
|
2356
|
-
{ label: "Bebas Neue", value: "font-bebas-neue" }
|
|
2466
|
+
{ label: "Bebas Neue", value: "font-bebas-neue" },
|
|
2467
|
+
{ label: "Archivo", value: "font-archivo" }
|
|
2357
2468
|
],
|
|
2358
2469
|
Modern: [
|
|
2359
2470
|
{ label: "Lato", value: "font-lato" },
|
|
2360
2471
|
{ label: "PT Sans", value: "font-pt-sans" },
|
|
2361
2472
|
{ label: "Quicksand", value: "font-quicksand" }
|
|
2473
|
+
],
|
|
2474
|
+
Mono: [
|
|
2475
|
+
{ label: "JetBrains Mono", value: "font-jetbrains-mono" },
|
|
2476
|
+
{ label: "Spline Sans Mono", value: "font-spline-sans-mono" }
|
|
2362
2477
|
]
|
|
2363
2478
|
};
|
|
2479
|
+
function defaultFluid(fontSize) {
|
|
2480
|
+
const max = TAILWIND_TEXT_PX[fontSize ?? ""] ?? 48;
|
|
2481
|
+
return { min: Math.round(max * 0.66), max };
|
|
2482
|
+
}
|
|
2364
2483
|
function TypographySelector({
|
|
2365
2484
|
value,
|
|
2366
|
-
onChange
|
|
2485
|
+
onChange,
|
|
2486
|
+
allowFluid
|
|
2367
2487
|
}) {
|
|
2368
2488
|
const update = (patch) => onChange({ ...value, ...patch });
|
|
2489
|
+
const fluid = value?.fluid;
|
|
2369
2490
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6 p-2", children: [
|
|
2370
2491
|
/* @__PURE__ */ jsx("div", { className: "h-[100px] overflow-auto rounded-lg border p-2", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-2", children: [
|
|
2371
2492
|
/* @__PURE__ */ jsx(PanelLabel, { children: "Preview" }),
|
|
@@ -2380,6 +2501,7 @@ function TypographySelector({
|
|
|
2380
2501
|
value?.letterSpacing || "",
|
|
2381
2502
|
value?.textTransform || "normal-case"
|
|
2382
2503
|
),
|
|
2504
|
+
style: fluid ? { fontSize: fluidFontSize(fluid) } : void 0,
|
|
2383
2505
|
children: "The quick brown fox jumps over the lazy dog"
|
|
2384
2506
|
}
|
|
2385
2507
|
)
|
|
@@ -2395,25 +2517,61 @@ function TypographySelector({
|
|
|
2395
2517
|
onChange: (e) => update({ fontFamily: e.target.value }),
|
|
2396
2518
|
children: [
|
|
2397
2519
|
!value?.fontFamily && /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select font family" }),
|
|
2398
|
-
Object.entries(fontFamilyOptions).map(
|
|
2399
|
-
([category, fonts]) => /* @__PURE__ */ jsx("optgroup", { label: category, children: fonts.map((font) => /* @__PURE__ */ jsx(
|
|
2400
|
-
"option",
|
|
2401
|
-
{
|
|
2402
|
-
value: font.value,
|
|
2403
|
-
children: font.label
|
|
2404
|
-
},
|
|
2405
|
-
font.value
|
|
2406
|
-
)) }, category)
|
|
2407
|
-
)
|
|
2520
|
+
Object.entries(fontFamilyOptions).map(([category, fonts]) => /* @__PURE__ */ jsx("optgroup", { label: category, children: fonts.map((font) => /* @__PURE__ */ jsx("option", { value: font.value, children: font.label }, font.value)) }, category))
|
|
2408
2521
|
]
|
|
2409
2522
|
}
|
|
2410
2523
|
)
|
|
2411
2524
|
] }),
|
|
2525
|
+
allowFluid && /* @__PURE__ */ jsxs("div", { className: "space-y-3 rounded-md border p-2", children: [
|
|
2526
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-3 text-xs font-medium text-foreground", children: [
|
|
2527
|
+
"Scale with screen size",
|
|
2528
|
+
/* @__PURE__ */ jsx(
|
|
2529
|
+
"input",
|
|
2530
|
+
{
|
|
2531
|
+
type: "checkbox",
|
|
2532
|
+
checked: Boolean(fluid),
|
|
2533
|
+
onChange: (e) => update({
|
|
2534
|
+
fluid: e.target.checked ? defaultFluid(value.fontSize) : void 0
|
|
2535
|
+
})
|
|
2536
|
+
}
|
|
2537
|
+
)
|
|
2538
|
+
] }),
|
|
2539
|
+
fluid && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
2540
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
2541
|
+
/* @__PURE__ */ jsx(PanelLabel, { htmlFor: "fluid-min", children: "Phone size (px)" }),
|
|
2542
|
+
/* @__PURE__ */ jsx(
|
|
2543
|
+
PanelInput2,
|
|
2544
|
+
{
|
|
2545
|
+
id: "fluid-min",
|
|
2546
|
+
type: "number",
|
|
2547
|
+
min: 8,
|
|
2548
|
+
max: 200,
|
|
2549
|
+
value: fluid.min,
|
|
2550
|
+
onChange: (e) => update({ fluid: { ...fluid, min: Number(e.target.value) || 0 } })
|
|
2551
|
+
}
|
|
2552
|
+
)
|
|
2553
|
+
] }),
|
|
2554
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
2555
|
+
/* @__PURE__ */ jsx(PanelLabel, { htmlFor: "fluid-max", children: "Desktop size (px)" }),
|
|
2556
|
+
/* @__PURE__ */ jsx(
|
|
2557
|
+
PanelInput2,
|
|
2558
|
+
{
|
|
2559
|
+
id: "fluid-max",
|
|
2560
|
+
type: "number",
|
|
2561
|
+
min: 8,
|
|
2562
|
+
max: 200,
|
|
2563
|
+
value: fluid.max,
|
|
2564
|
+
onChange: (e) => update({ fluid: { ...fluid, max: Number(e.target.value) || 0 } })
|
|
2565
|
+
}
|
|
2566
|
+
)
|
|
2567
|
+
] })
|
|
2568
|
+
] })
|
|
2569
|
+
] }),
|
|
2412
2570
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
2413
2571
|
/* @__PURE__ */ jsx(
|
|
2414
2572
|
PanelSelect2,
|
|
2415
2573
|
{
|
|
2416
|
-
title: "Font Size",
|
|
2574
|
+
title: fluid ? "Font Size (unused while scaling)" : "Font Size",
|
|
2417
2575
|
value: value?.fontSize || "",
|
|
2418
2576
|
onChange: (v) => update({ fontSize: v }),
|
|
2419
2577
|
options: fontSizeOptions,
|
|
@@ -2510,25 +2668,14 @@ function InteractiveSelector({
|
|
|
2510
2668
|
/* @__PURE__ */ jsx("div", { children: "Card content goes here" })
|
|
2511
2669
|
] }) });
|
|
2512
2670
|
case "input":
|
|
2513
|
-
return /* @__PURE__ */ jsx(
|
|
2514
|
-
Input,
|
|
2515
|
-
{
|
|
2516
|
-
theme,
|
|
2517
|
-
type: "text",
|
|
2518
|
-
placeholder: "Demo Input"
|
|
2519
|
-
}
|
|
2520
|
-
);
|
|
2671
|
+
return /* @__PURE__ */ jsx(Input, { theme, type: "text", placeholder: "Demo Input" });
|
|
2521
2672
|
default:
|
|
2522
2673
|
return null;
|
|
2523
2674
|
}
|
|
2524
2675
|
};
|
|
2525
2676
|
const renderPaddingConfig = (allowedPaddingX, allowedPaddingY) => {
|
|
2526
|
-
const filteredPaddingX = allowedPaddingX ? paddingOptions.x.filter(
|
|
2527
|
-
|
|
2528
|
-
) : paddingOptions.x;
|
|
2529
|
-
const filteredPaddingY = allowedPaddingY ? paddingOptions.y.filter(
|
|
2530
|
-
(option) => allowedPaddingY.includes(option.value)
|
|
2531
|
-
) : paddingOptions.y;
|
|
2677
|
+
const filteredPaddingX = allowedPaddingX ? paddingOptions.x.filter((option) => allowedPaddingX.includes(option.value)) : paddingOptions.x;
|
|
2678
|
+
const filteredPaddingY = allowedPaddingY ? paddingOptions.y.filter((option) => allowedPaddingY.includes(option.value)) : paddingOptions.y;
|
|
2532
2679
|
return /* @__PURE__ */ jsx(AccordionSection, { title: "Padding", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
2533
2680
|
/* @__PURE__ */ jsx(
|
|
2534
2681
|
PanelSelect2,
|
|
@@ -2709,11 +2856,7 @@ var structureDisplayNames = {
|
|
|
2709
2856
|
page: "Page",
|
|
2710
2857
|
section: "Section"
|
|
2711
2858
|
};
|
|
2712
|
-
function StructureSelector({
|
|
2713
|
-
type,
|
|
2714
|
-
theme,
|
|
2715
|
-
onChange
|
|
2716
|
-
}) {
|
|
2859
|
+
function StructureSelector({ type, theme, onChange }) {
|
|
2717
2860
|
if (type === "page") {
|
|
2718
2861
|
const pageValue = theme.structure.page;
|
|
2719
2862
|
return /* @__PURE__ */ jsx("div", { className: "space-y-6 p-2", children: /* @__PURE__ */ jsx(
|
|
@@ -2769,7 +2912,24 @@ function StructureSelector({
|
|
|
2769
2912
|
updatePadding({ y });
|
|
2770
2913
|
}
|
|
2771
2914
|
}
|
|
2772
|
-
)
|
|
2915
|
+
),
|
|
2916
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-3 text-xs font-medium text-foreground", children: [
|
|
2917
|
+
"Hairline between sections",
|
|
2918
|
+
/* @__PURE__ */ jsx(
|
|
2919
|
+
"input",
|
|
2920
|
+
{
|
|
2921
|
+
type: "checkbox",
|
|
2922
|
+
checked: Boolean(sectionValue?.dividers),
|
|
2923
|
+
onChange: (e) => onChange({
|
|
2924
|
+
...theme,
|
|
2925
|
+
structure: {
|
|
2926
|
+
...theme.structure,
|
|
2927
|
+
section: { ...sectionValue, dividers: e.target.checked || void 0 }
|
|
2928
|
+
}
|
|
2929
|
+
})
|
|
2930
|
+
}
|
|
2931
|
+
)
|
|
2932
|
+
] })
|
|
2773
2933
|
] });
|
|
2774
2934
|
}
|
|
2775
2935
|
var sections = [
|
|
@@ -2795,6 +2955,7 @@ var sections = [
|
|
|
2795
2955
|
}
|
|
2796
2956
|
];
|
|
2797
2957
|
var typographyDisplayNames = {
|
|
2958
|
+
display: "Display (hero)",
|
|
2798
2959
|
header1: "Header 1",
|
|
2799
2960
|
header2: "Header 2",
|
|
2800
2961
|
header3: "Header 3",
|
|
@@ -2807,12 +2968,26 @@ var typographyDisplayNames = {
|
|
|
2807
2968
|
caption: "Caption",
|
|
2808
2969
|
link: "Link",
|
|
2809
2970
|
button: "Button Text",
|
|
2810
|
-
input: "Input Text"
|
|
2971
|
+
input: "Input Text",
|
|
2972
|
+
code: "Code"
|
|
2973
|
+
};
|
|
2974
|
+
var DEFAULT_CODE_TYPOGRAPHY = {
|
|
2975
|
+
fontFamily: "font-jetbrains-mono",
|
|
2976
|
+
fontSize: "text-sm",
|
|
2977
|
+
fontWeight: "font-normal",
|
|
2978
|
+
lineHeight: "leading-relaxed"
|
|
2811
2979
|
};
|
|
2980
|
+
var fluidTypography = /* @__PURE__ */ new Set([
|
|
2981
|
+
"display",
|
|
2982
|
+
"header1",
|
|
2983
|
+
"header2",
|
|
2984
|
+
"header3",
|
|
2985
|
+
"header4"
|
|
2986
|
+
]);
|
|
2812
2987
|
var typographyCategories = [
|
|
2813
2988
|
{
|
|
2814
2989
|
name: "Headers",
|
|
2815
|
-
items: ["header1", "header2", "header3", "header4", "preheader"]
|
|
2990
|
+
items: ["display", "header1", "header2", "header3", "header4", "preheader"]
|
|
2816
2991
|
},
|
|
2817
2992
|
{
|
|
2818
2993
|
name: "Subheaders",
|
|
@@ -2824,7 +2999,7 @@ var typographyCategories = [
|
|
|
2824
2999
|
},
|
|
2825
3000
|
{
|
|
2826
3001
|
name: "Interactive Elements",
|
|
2827
|
-
items: ["link", "button", "input"]
|
|
3002
|
+
items: ["link", "button", "input", "code"]
|
|
2828
3003
|
}
|
|
2829
3004
|
];
|
|
2830
3005
|
var colorCategories = [
|
|
@@ -2915,12 +3090,7 @@ var colorCategories = [
|
|
|
2915
3090
|
]
|
|
2916
3091
|
}
|
|
2917
3092
|
];
|
|
2918
|
-
var paletteColorOrder = [
|
|
2919
|
-
"primary",
|
|
2920
|
-
"accent",
|
|
2921
|
-
"secondary",
|
|
2922
|
-
"border"
|
|
2923
|
-
];
|
|
3093
|
+
var paletteColorOrder = ["primary", "accent", "secondary", "border"];
|
|
2924
3094
|
function capitalize(value) {
|
|
2925
3095
|
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
2926
3096
|
}
|
|
@@ -2942,45 +3112,35 @@ function ThemeEditor({
|
|
|
2942
3112
|
onApply,
|
|
2943
3113
|
onCustomThemesChange
|
|
2944
3114
|
}) {
|
|
2945
|
-
const [navigationStack, setNavigationStack] = useState(
|
|
2946
|
-
[]
|
|
2947
|
-
);
|
|
2948
|
-
const [collapsedCategories, setCollapsedCategories] = useState(() => {
|
|
2949
|
-
const initial = {};
|
|
2950
|
-
typographyCategories.forEach((category) => {
|
|
2951
|
-
initial[category.name] = true;
|
|
2952
|
-
});
|
|
2953
|
-
return initial;
|
|
2954
|
-
});
|
|
3115
|
+
const [navigationStack, setNavigationStack] = useState([]);
|
|
2955
3116
|
const navigateTo = useCallback((item) => {
|
|
2956
3117
|
setNavigationStack((prev) => [...prev, item]);
|
|
2957
3118
|
}, []);
|
|
2958
3119
|
const navigateBack = useCallback(() => {
|
|
2959
3120
|
setNavigationStack((prev) => prev.slice(0, -1));
|
|
2960
3121
|
}, []);
|
|
2961
|
-
const
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
(style) => {
|
|
2969
|
-
const updated = { ...theme, theme: style };
|
|
2970
|
-
onApply(updated);
|
|
3122
|
+
const commitTheme = useCallback(
|
|
3123
|
+
(updated) => {
|
|
3124
|
+
if (updated.id === appliedThemeId) {
|
|
3125
|
+
onApply(updated);
|
|
3126
|
+
} else {
|
|
3127
|
+
onPreview(updated);
|
|
3128
|
+
}
|
|
2971
3129
|
onCustomThemesChange(
|
|
2972
3130
|
customThemes.map((t) => t.id === updated.id ? updated : t)
|
|
2973
3131
|
);
|
|
2974
3132
|
},
|
|
2975
|
-
[
|
|
3133
|
+
[appliedThemeId, customThemes, onApply, onPreview, onCustomThemesChange]
|
|
3134
|
+
);
|
|
3135
|
+
const applyStyle = useCallback(
|
|
3136
|
+
(style) => commitTheme({ ...theme, theme: style }),
|
|
3137
|
+
[theme, commitTheme]
|
|
2976
3138
|
);
|
|
2977
3139
|
const startEditing = useCallback(
|
|
2978
3140
|
(themeItem, isSystem) => {
|
|
2979
3141
|
let target = themeItem;
|
|
2980
3142
|
if (isSystem) {
|
|
2981
|
-
const takenNames = [...systemThemes, ...customThemes].map(
|
|
2982
|
-
(t) => t.name
|
|
2983
|
-
);
|
|
3143
|
+
const takenNames = [...systemThemes, ...customThemes].map((t) => t.name);
|
|
2984
3144
|
target = {
|
|
2985
3145
|
id: generateUniqueId(),
|
|
2986
3146
|
name: copyName(themeItem.name, takenNames),
|
|
@@ -2988,10 +3148,10 @@ function ThemeEditor({
|
|
|
2988
3148
|
};
|
|
2989
3149
|
onCustomThemesChange([...customThemes, target]);
|
|
2990
3150
|
}
|
|
2991
|
-
|
|
3151
|
+
onPreview(target);
|
|
2992
3152
|
setNavigationStack([{ id: "categories", label: target.name }]);
|
|
2993
3153
|
},
|
|
2994
|
-
[systemThemes, customThemes,
|
|
3154
|
+
[systemThemes, customThemes, onPreview, onCustomThemesChange]
|
|
2995
3155
|
);
|
|
2996
3156
|
const renderDrillButton = (label, onClick) => /* @__PURE__ */ jsxs(
|
|
2997
3157
|
"button",
|
|
@@ -3020,14 +3180,10 @@ function ThemeEditor({
|
|
|
3020
3180
|
);
|
|
3021
3181
|
const renderRootView = () => /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
3022
3182
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "System Themes" }),
|
|
3023
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: systemThemes.map(
|
|
3024
|
-
(themeItem) => renderThemeCard(themeItem, true)
|
|
3025
|
-
) }),
|
|
3183
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: systemThemes.map((themeItem) => renderThemeCard(themeItem, true)) }),
|
|
3026
3184
|
/* @__PURE__ */ jsx("hr", { className: "my-4 border-muted" }),
|
|
3027
3185
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "Custom Themes" }),
|
|
3028
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: customThemes.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "No custom themes yet" }) : customThemes.map(
|
|
3029
|
-
(themeItem) => renderThemeCard(themeItem, false)
|
|
3030
|
-
) })
|
|
3186
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: customThemes.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "No custom themes yet" }) : customThemes.map((themeItem) => renderThemeCard(themeItem, false)) })
|
|
3031
3187
|
] });
|
|
3032
3188
|
const renderCategoriesView = () => /* @__PURE__ */ jsx("div", { className: "space-y-1", children: sections.map((section) => /* @__PURE__ */ jsxs(
|
|
3033
3189
|
"button",
|
|
@@ -3084,80 +3240,72 @@ function ThemeEditor({
|
|
|
3084
3240
|
))
|
|
3085
3241
|
}
|
|
3086
3242
|
),
|
|
3087
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-4", children: colorCategories.map((category) => /* @__PURE__ */ jsx(
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
]
|
|
3109
|
-
},
|
|
3110
|
-
color.name
|
|
3111
|
-
) : /* @__PURE__ */ jsx(
|
|
3112
|
-
ColorSelector,
|
|
3113
|
-
{
|
|
3114
|
-
title: color.displayName,
|
|
3115
|
-
value: colors[color.name],
|
|
3116
|
-
onChange: (value) => updateColor(
|
|
3117
|
-
color.name,
|
|
3118
|
-
value ?? ""
|
|
3119
|
-
),
|
|
3120
|
-
allowReset: false
|
|
3121
|
-
},
|
|
3122
|
-
color.name
|
|
3123
|
-
)
|
|
3124
|
-
) })
|
|
3125
|
-
},
|
|
3126
|
-
category.key
|
|
3127
|
-
)) })
|
|
3243
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-4", children: colorCategories.map((category) => /* @__PURE__ */ jsx(AccordionSection, { title: category.label, children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: category.colors.map(
|
|
3244
|
+
(color) => category.key === "shadows" ? /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
3245
|
+
/* @__PURE__ */ jsx(PanelLabel, { children: color.displayName }),
|
|
3246
|
+
/* @__PURE__ */ jsx(
|
|
3247
|
+
PanelInput2,
|
|
3248
|
+
{
|
|
3249
|
+
value: colors[color.name],
|
|
3250
|
+
onChange: (e) => updateColor(color.name, e.target.value)
|
|
3251
|
+
}
|
|
3252
|
+
)
|
|
3253
|
+
] }, color.name) : /* @__PURE__ */ jsx(
|
|
3254
|
+
ColorSelector,
|
|
3255
|
+
{
|
|
3256
|
+
title: color.displayName,
|
|
3257
|
+
value: colors[color.name],
|
|
3258
|
+
onChange: (value) => updateColor(color.name, value ?? ""),
|
|
3259
|
+
allowReset: false
|
|
3260
|
+
},
|
|
3261
|
+
color.name
|
|
3262
|
+
)
|
|
3263
|
+
) }) }, category.key)) })
|
|
3128
3264
|
] });
|
|
3129
3265
|
};
|
|
3130
|
-
const
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
{
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3266
|
+
const renderTypographyView = () => {
|
|
3267
|
+
const updateTypography = (key, value) => applyStyle({
|
|
3268
|
+
...theme.theme,
|
|
3269
|
+
typography: { ...theme.theme.typography, [key]: value }
|
|
3270
|
+
});
|
|
3271
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
3272
|
+
/* @__PURE__ */ jsx(
|
|
3273
|
+
PanelSelect2,
|
|
3274
|
+
{
|
|
3275
|
+
title: "Highlighted title words (*like this*)",
|
|
3276
|
+
value: theme.theme.highlight ?? "color",
|
|
3277
|
+
onChange: (highlight) => applyStyle({ ...theme.theme, highlight }),
|
|
3278
|
+
options: [
|
|
3279
|
+
{ label: "Primary colour text", value: "color" },
|
|
3280
|
+
{ label: "Marker in primary colour", value: "marker" }
|
|
3281
|
+
]
|
|
3282
|
+
}
|
|
3283
|
+
),
|
|
3284
|
+
typographyCategories.map((category) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
3285
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-muted-foreground", children: category.name }),
|
|
3286
|
+
category.items.map((typography) => {
|
|
3287
|
+
const key = typography;
|
|
3288
|
+
const value = theme.theme.typography[key] ?? (key === "display" ? theme.theme.typography.header1 : void 0) ?? (key === "code" ? DEFAULT_CODE_TYPOGRAPHY : void 0);
|
|
3289
|
+
if (!value) return null;
|
|
3290
|
+
return /* @__PURE__ */ jsx(
|
|
3291
|
+
AccordionSection,
|
|
3140
3292
|
{
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3293
|
+
title: typographyDisplayNames[typography] || capitalize(typography),
|
|
3294
|
+
children: /* @__PURE__ */ jsx(
|
|
3295
|
+
TypographySelector,
|
|
3296
|
+
{
|
|
3297
|
+
value,
|
|
3298
|
+
allowFluid: fluidTypography.has(typography),
|
|
3299
|
+
onChange: (value2) => updateTypography(key, value2)
|
|
3300
|
+
}
|
|
3144
3301
|
)
|
|
3145
|
-
}
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
]
|
|
3149
|
-
}
|
|
3150
|
-
),
|
|
3151
|
-
!collapsedCategories[category.name] && /* @__PURE__ */ jsx("div", { children: category.items.map(
|
|
3152
|
-
(typography) => renderDrillButton(
|
|
3153
|
-
typographyDisplayNames[typography] || capitalize(typography),
|
|
3154
|
-
() => navigateTo({
|
|
3155
|
-
id: typography,
|
|
3156
|
-
label: typographyDisplayNames[typography] || capitalize(typography)
|
|
3302
|
+
},
|
|
3303
|
+
typography
|
|
3304
|
+
);
|
|
3157
3305
|
})
|
|
3158
|
-
)
|
|
3159
|
-
|
|
3160
|
-
|
|
3306
|
+
] }, category.name))
|
|
3307
|
+
] });
|
|
3308
|
+
};
|
|
3161
3309
|
const renderInteractivesList = () => /* @__PURE__ */ jsx("div", { className: "space-y-1", children: Object.keys(interactiveDisplayNames).map(
|
|
3162
3310
|
(interactive) => renderDrillButton(
|
|
3163
3311
|
interactiveDisplayNames[interactive] || capitalize(interactive),
|
|
@@ -3182,22 +3330,6 @@ function ThemeEditor({
|
|
|
3182
3330
|
if (!currentItem) {
|
|
3183
3331
|
return renderRootView();
|
|
3184
3332
|
}
|
|
3185
|
-
if (parentItem?.id === "typography" && currentItem.id in theme.theme.typography) {
|
|
3186
|
-
const key = currentItem.id;
|
|
3187
|
-
return /* @__PURE__ */ jsx(
|
|
3188
|
-
TypographySelector,
|
|
3189
|
-
{
|
|
3190
|
-
value: theme.theme.typography[key],
|
|
3191
|
-
onChange: (value) => applyStyle({
|
|
3192
|
-
...theme.theme,
|
|
3193
|
-
typography: {
|
|
3194
|
-
...theme.theme.typography,
|
|
3195
|
-
[key]: value
|
|
3196
|
-
}
|
|
3197
|
-
})
|
|
3198
|
-
}
|
|
3199
|
-
);
|
|
3200
|
-
}
|
|
3201
3333
|
if (parentItem?.id === "interactives" && currentItem.id in theme.theme.interactives) {
|
|
3202
3334
|
return /* @__PURE__ */ jsx(
|
|
3203
3335
|
InteractiveSelector,
|
|
@@ -3224,7 +3356,7 @@ function ThemeEditor({
|
|
|
3224
3356
|
case "colors":
|
|
3225
3357
|
return renderColorsView();
|
|
3226
3358
|
case "typography":
|
|
3227
|
-
return
|
|
3359
|
+
return renderTypographyView();
|
|
3228
3360
|
case "interactives":
|
|
3229
3361
|
return renderInteractivesList();
|
|
3230
3362
|
case "structure":
|
|
@@ -3246,7 +3378,35 @@ function ThemeEditor({
|
|
|
3246
3378
|
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
3247
3379
|
}
|
|
3248
3380
|
),
|
|
3249
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-muted-foreground", children: navigationStack[navigationStack.length - 1].label })
|
|
3381
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-muted-foreground", children: navigationStack.length === 1 ? theme.name : navigationStack[navigationStack.length - 1].label })
|
|
3382
|
+
] }),
|
|
3383
|
+
navigationStack.length === 1 && /* @__PURE__ */ jsxs("div", { className: "space-y-3 pb-2", children: [
|
|
3384
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
3385
|
+
/* @__PURE__ */ jsx(PanelLabel, { htmlFor: "theme-name", children: "Theme name" }),
|
|
3386
|
+
/* @__PURE__ */ jsx(
|
|
3387
|
+
PanelInput2,
|
|
3388
|
+
{
|
|
3389
|
+
id: "theme-name",
|
|
3390
|
+
value: theme.name,
|
|
3391
|
+
onChange: (e) => commitTheme({ ...theme, name: e.target.value })
|
|
3392
|
+
}
|
|
3393
|
+
)
|
|
3394
|
+
] }),
|
|
3395
|
+
theme.id === appliedThemeId ? /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
3396
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
3397
|
+
"This is your site theme"
|
|
3398
|
+
] }) : /* @__PURE__ */ jsxs(
|
|
3399
|
+
"button",
|
|
3400
|
+
{
|
|
3401
|
+
type: "button",
|
|
3402
|
+
className: "inline-flex h-8 w-full items-center justify-center gap-1.5 rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground hover:bg-primary/90",
|
|
3403
|
+
onClick: () => onApply(theme),
|
|
3404
|
+
children: [
|
|
3405
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
3406
|
+
"Use this theme"
|
|
3407
|
+
]
|
|
3408
|
+
}
|
|
3409
|
+
)
|
|
3250
3410
|
] }),
|
|
3251
3411
|
/* @__PURE__ */ jsx("div", { className: "py-2", children: getCurrentView() })
|
|
3252
3412
|
] })
|
|
@@ -3257,7 +3417,7 @@ function SeoEditor({
|
|
|
3257
3417
|
onChange
|
|
3258
3418
|
}) {
|
|
3259
3419
|
const update = (next) => onChange({ ...seo, ...next });
|
|
3260
|
-
const imageUrl = seo.socialImage
|
|
3420
|
+
const imageUrl = getMediaUrl(seo.socialImage);
|
|
3261
3421
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
3262
3422
|
/* @__PURE__ */ jsxs(FieldGroup, { title: "Search results", children: [
|
|
3263
3423
|
/* @__PURE__ */ jsx(
|
|
@@ -3289,25 +3449,101 @@ function SeoEditor({
|
|
|
3289
3449
|
)
|
|
3290
3450
|
] }),
|
|
3291
3451
|
/* @__PURE__ */ jsxs(FieldGroup, { title: "Social card image", children: [
|
|
3452
|
+
imageUrl ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
3453
|
+
/* @__PURE__ */ jsx(
|
|
3454
|
+
"img",
|
|
3455
|
+
{
|
|
3456
|
+
src: imageUrl,
|
|
3457
|
+
alt: "Social card preview",
|
|
3458
|
+
className: "aspect-[1200/630] w-full rounded-md border border-border object-cover"
|
|
3459
|
+
}
|
|
3460
|
+
),
|
|
3461
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3462
|
+
/* @__PURE__ */ jsx(
|
|
3463
|
+
ImageUploadDialog,
|
|
3464
|
+
{
|
|
3465
|
+
title: "Change social card image",
|
|
3466
|
+
description: "Upload an image or pick one from your library.",
|
|
3467
|
+
onSelect: (selected) => {
|
|
3468
|
+
const selMedia = selected.media;
|
|
3469
|
+
const mediaLitId = selMedia?.mediaLitId ?? selMedia?.mediaId ?? void 0;
|
|
3470
|
+
update({
|
|
3471
|
+
socialImage: {
|
|
3472
|
+
...mediaLitId ? { mediaId: mediaLitId, mediaLitId } : {},
|
|
3473
|
+
url: selected.src,
|
|
3474
|
+
file: selected.src,
|
|
3475
|
+
thumbnailUrl: selMedia?.thumbnailUrl ?? selected.src,
|
|
3476
|
+
thumbnail: selMedia?.thumbnailUrl ?? selected.src,
|
|
3477
|
+
alt: selected.alt
|
|
3478
|
+
}
|
|
3479
|
+
});
|
|
3480
|
+
},
|
|
3481
|
+
children: /* @__PURE__ */ jsxs(
|
|
3482
|
+
"button",
|
|
3483
|
+
{
|
|
3484
|
+
type: "button",
|
|
3485
|
+
className: "inline-flex h-8 items-center justify-center rounded-lg border border-input bg-background px-3 text-xs font-medium text-foreground hover:bg-muted",
|
|
3486
|
+
children: [
|
|
3487
|
+
/* @__PURE__ */ jsx(ImageIcon, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
3488
|
+
"Change image"
|
|
3489
|
+
]
|
|
3490
|
+
}
|
|
3491
|
+
)
|
|
3492
|
+
}
|
|
3493
|
+
),
|
|
3494
|
+
/* @__PURE__ */ jsx(
|
|
3495
|
+
"button",
|
|
3496
|
+
{
|
|
3497
|
+
type: "button",
|
|
3498
|
+
className: "inline-flex h-8 items-center justify-center rounded-lg border border-destructive/30 bg-background px-3 text-xs font-medium text-destructive hover:bg-destructive/10",
|
|
3499
|
+
onClick: () => update({ socialImage: void 0 }),
|
|
3500
|
+
children: "Remove"
|
|
3501
|
+
}
|
|
3502
|
+
)
|
|
3503
|
+
] })
|
|
3504
|
+
] }) : /* @__PURE__ */ jsx(
|
|
3505
|
+
ImageUploadDialog,
|
|
3506
|
+
{
|
|
3507
|
+
title: "Choose social card image",
|
|
3508
|
+
description: "Upload an image or pick one from your library.",
|
|
3509
|
+
onSelect: (selected) => {
|
|
3510
|
+
const selMedia = selected.media;
|
|
3511
|
+
const mediaLitId = selMedia?.mediaLitId ?? selMedia?.mediaId ?? void 0;
|
|
3512
|
+
update({
|
|
3513
|
+
socialImage: {
|
|
3514
|
+
...mediaLitId ? { mediaId: mediaLitId, mediaLitId } : {},
|
|
3515
|
+
url: selected.src,
|
|
3516
|
+
file: selected.src,
|
|
3517
|
+
thumbnailUrl: selMedia?.thumbnailUrl ?? selected.src,
|
|
3518
|
+
thumbnail: selMedia?.thumbnailUrl ?? selected.src,
|
|
3519
|
+
alt: selected.alt
|
|
3520
|
+
}
|
|
3521
|
+
});
|
|
3522
|
+
},
|
|
3523
|
+
children: /* @__PURE__ */ jsxs(
|
|
3524
|
+
"button",
|
|
3525
|
+
{
|
|
3526
|
+
type: "button",
|
|
3527
|
+
className: "flex w-full items-center justify-center gap-2 rounded-lg border border-dashed border-border bg-muted/20 py-3 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:bg-muted/40 hover:text-foreground",
|
|
3528
|
+
children: [
|
|
3529
|
+
/* @__PURE__ */ jsx(ImageIcon, { className: "h-4 w-4" }),
|
|
3530
|
+
"Upload or choose image"
|
|
3531
|
+
]
|
|
3532
|
+
}
|
|
3533
|
+
)
|
|
3534
|
+
}
|
|
3535
|
+
),
|
|
3292
3536
|
/* @__PURE__ */ jsx(
|
|
3293
3537
|
TextField,
|
|
3294
3538
|
{
|
|
3295
|
-
label: "
|
|
3296
|
-
value: imageUrl,
|
|
3539
|
+
label: "Or paste image URL",
|
|
3540
|
+
value: imageUrl ?? "",
|
|
3297
3541
|
placeholder: "https://...",
|
|
3298
|
-
onChange: (
|
|
3299
|
-
socialImage:
|
|
3542
|
+
onChange: (url) => update({
|
|
3543
|
+
socialImage: url ? { url, file: url } : void 0
|
|
3300
3544
|
})
|
|
3301
3545
|
}
|
|
3302
3546
|
),
|
|
3303
|
-
imageUrl && /* @__PURE__ */ jsx(
|
|
3304
|
-
"img",
|
|
3305
|
-
{
|
|
3306
|
-
src: imageUrl,
|
|
3307
|
-
alt: "Social card preview",
|
|
3308
|
-
className: "aspect-[1200/630] w-full rounded-md border border-border object-cover"
|
|
3309
|
-
}
|
|
3310
|
-
),
|
|
3311
3547
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Shown when the page is shared on social networks. Recommended size 1200\xD7630." })
|
|
3312
3548
|
] })
|
|
3313
3549
|
] });
|
|
@@ -3324,16 +3560,12 @@ function PageBuilder({
|
|
|
3324
3560
|
className
|
|
3325
3561
|
}) {
|
|
3326
3562
|
const [layout, setLayout] = useState(
|
|
3327
|
-
() => initialLayout ? ensureRequiredSharedWidgets(initialLayout) : createDefaultLayout()
|
|
3328
|
-
);
|
|
3329
|
-
const [theme, setTheme] = useState(
|
|
3330
|
-
() => initialTheme ?? getDefaultTheme()
|
|
3563
|
+
() => initialLayout ? ensureRequiredSharedWidgets(withDefaultSettings(initialLayout)) : createDefaultLayout()
|
|
3331
3564
|
);
|
|
3565
|
+
const [theme, setTheme] = useState(() => initialTheme ?? getDefaultTheme());
|
|
3332
3566
|
const [previewTheme, setPreviewTheme] = useState(null);
|
|
3333
3567
|
const paintedTheme = previewTheme ?? theme;
|
|
3334
|
-
const [seo, setSeo] = useState(
|
|
3335
|
-
() => initialSeo ?? { robotsAllowed: true }
|
|
3336
|
-
);
|
|
3568
|
+
const [seo, setSeo] = useState(() => initialSeo ?? { robotsAllowed: true });
|
|
3337
3569
|
const systemThemes = providedThemes?.system ?? themes;
|
|
3338
3570
|
const [customThemes, setCustomThemes] = useState(
|
|
3339
3571
|
() => providedThemes?.custom ?? []
|
|
@@ -3343,6 +3575,7 @@ function PageBuilder({
|
|
|
3343
3575
|
const [device, setDevice] = useState("desktop");
|
|
3344
3576
|
const [panel, setPanel] = useState(null);
|
|
3345
3577
|
const [insertAfter, setInsertAfter] = useState(null);
|
|
3578
|
+
const [pendingDeleteId, setPendingDeleteId] = useState(null);
|
|
3346
3579
|
const [movedWidgetId, setMovedWidgetId] = useState(null);
|
|
3347
3580
|
const movedTimeoutRef = useRef(null);
|
|
3348
3581
|
useEffect(() => {
|
|
@@ -3361,15 +3594,13 @@ function PageBuilder({
|
|
|
3361
3594
|
const onChangeRef = useRef(onChange);
|
|
3362
3595
|
onChangeRef.current = onChange;
|
|
3363
3596
|
const emitChange = useMemo(
|
|
3364
|
-
() => debounce(
|
|
3365
|
-
(state) => onChangeRef.current?.(state),
|
|
3366
|
-
500
|
|
3367
|
-
),
|
|
3597
|
+
() => debounce((state) => onChangeRef.current?.(state), 500),
|
|
3368
3598
|
[]
|
|
3369
3599
|
);
|
|
3370
3600
|
useEffect(() => {
|
|
3371
3601
|
emitChange({ layout, theme, seo, customThemes });
|
|
3372
3602
|
}, [layout, theme, seo, customThemes]);
|
|
3603
|
+
useEffect(() => emitChange.flush, [emitChange]);
|
|
3373
3604
|
const addableBlocks = useMemo(() => getAddableBlocks(), []);
|
|
3374
3605
|
function updateWidgetSettings(widgetId, settings) {
|
|
3375
3606
|
setLayout(
|
|
@@ -3392,12 +3623,12 @@ function PageBuilder({
|
|
|
3392
3623
|
[next[index], next[targetIndex]] = [next[targetIndex], next[index]];
|
|
3393
3624
|
return next;
|
|
3394
3625
|
});
|
|
3626
|
+
highlightWidget(widgetId);
|
|
3627
|
+
}
|
|
3628
|
+
function highlightWidget(widgetId) {
|
|
3395
3629
|
if (movedTimeoutRef.current) clearTimeout(movedTimeoutRef.current);
|
|
3396
3630
|
setMovedWidgetId(widgetId);
|
|
3397
|
-
movedTimeoutRef.current = setTimeout(
|
|
3398
|
-
() => setMovedWidgetId(null),
|
|
3399
|
-
1500
|
|
3400
|
-
);
|
|
3631
|
+
movedTimeoutRef.current = setTimeout(() => setMovedWidgetId(null), 1500);
|
|
3401
3632
|
}
|
|
3402
3633
|
function deleteWidget(widgetId) {
|
|
3403
3634
|
setLayout((prev) => {
|
|
@@ -3417,16 +3648,14 @@ function PageBuilder({
|
|
|
3417
3648
|
if (insertAfter === "end" || insertAfter === null) {
|
|
3418
3649
|
const footerIndex = prev.findIndex((w) => w.name === "footer");
|
|
3419
3650
|
if (footerIndex === -1) return [...prev, instance];
|
|
3420
|
-
return [
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3651
|
+
return [...prev.slice(0, footerIndex), instance, ...prev.slice(footerIndex)];
|
|
3652
|
+
}
|
|
3653
|
+
const afterIndex = prev.findIndex((w) => w.widgetId === insertAfter);
|
|
3654
|
+
if (afterIndex === -1 || prev[afterIndex].name === "footer") {
|
|
3655
|
+
const footerIndex = prev.findIndex((w) => w.name === "footer");
|
|
3656
|
+
if (footerIndex === -1) return [...prev, instance];
|
|
3657
|
+
return [...prev.slice(0, footerIndex), instance, ...prev.slice(footerIndex)];
|
|
3425
3658
|
}
|
|
3426
|
-
const afterIndex = prev.findIndex(
|
|
3427
|
-
(w) => w.widgetId === insertAfter
|
|
3428
|
-
);
|
|
3429
|
-
if (afterIndex === -1) return [...prev, instance];
|
|
3430
3659
|
return [
|
|
3431
3660
|
...prev.slice(0, afterIndex + 1),
|
|
3432
3661
|
instance,
|
|
@@ -3434,12 +3663,11 @@ function PageBuilder({
|
|
|
3434
3663
|
];
|
|
3435
3664
|
});
|
|
3436
3665
|
setInsertAfter(null);
|
|
3666
|
+
highlightWidget(instance.widgetId);
|
|
3437
3667
|
setPanel({ mode: "block", widgetId: instance.widgetId });
|
|
3438
3668
|
}
|
|
3439
3669
|
const selectedWidgetId = panel?.mode === "block" ? panel.widgetId : null;
|
|
3440
|
-
const selectedInstance = layout.find(
|
|
3441
|
-
(w) => w.widgetId === selectedWidgetId
|
|
3442
|
-
);
|
|
3670
|
+
const selectedInstance = layout.find((w) => w.widgetId === selectedWidgetId);
|
|
3443
3671
|
const selectedDefinition = selectedInstance ? getWidget(selectedInstance.name) : void 0;
|
|
3444
3672
|
const showBlockPanel = Boolean(
|
|
3445
3673
|
panel?.mode === "block" && selectedInstance && selectedDefinition?.editor
|
|
@@ -3472,7 +3700,7 @@ function PageBuilder({
|
|
|
3472
3700
|
onDeviceChange: setDevice,
|
|
3473
3701
|
onOpenTheme: () => setPanel({ mode: "theme" }),
|
|
3474
3702
|
onOpenSeo: () => setPanel({ mode: "seo" }),
|
|
3475
|
-
onAddBlock: () => setInsertAfter("end"),
|
|
3703
|
+
onAddBlock: () => setInsertAfter(selectedWidgetId ?? "end"),
|
|
3476
3704
|
allowThemeEditing
|
|
3477
3705
|
}
|
|
3478
3706
|
),
|
|
@@ -3493,8 +3721,9 @@ function PageBuilder({
|
|
|
3493
3721
|
{
|
|
3494
3722
|
className: cn(
|
|
3495
3723
|
"h-full w-full max-w-full transition-[max-width] duration-300",
|
|
3496
|
-
|
|
3497
|
-
device === "
|
|
3724
|
+
// Device width plus the 2px border and the measured scrollbar.
|
|
3725
|
+
device === "mobile" && "max-w-[calc(392px_+_var(--pb-scrollbar,0px))] border-x",
|
|
3726
|
+
device === "tablet" && "max-w-[calc(770px_+_var(--pb-scrollbar,0px))] border-x"
|
|
3498
3727
|
),
|
|
3499
3728
|
children: /* @__PURE__ */ jsx(
|
|
3500
3729
|
PageRenderer,
|
|
@@ -3503,7 +3732,6 @@ function PageBuilder({
|
|
|
3503
3732
|
theme: paintedTheme,
|
|
3504
3733
|
pageData,
|
|
3505
3734
|
nextTheme: resolvedMode,
|
|
3506
|
-
themeMode: mode,
|
|
3507
3735
|
onThemeModeChange: setMode,
|
|
3508
3736
|
editing: true,
|
|
3509
3737
|
selectedWidgetId: selectedWidgetId ?? void 0,
|
|
@@ -3511,7 +3739,7 @@ function PageBuilder({
|
|
|
3511
3739
|
onSelectWidget: (id) => setPanel({ mode: "block", widgetId: id }),
|
|
3512
3740
|
onMoveWidgetUp: (id) => moveWidget(id, -1),
|
|
3513
3741
|
onMoveWidgetDown: (id) => moveWidget(id, 1),
|
|
3514
|
-
onDeleteWidget:
|
|
3742
|
+
onDeleteWidget: setPendingDeleteId,
|
|
3515
3743
|
onAddWidgetBelow: (id) => setInsertAfter(id),
|
|
3516
3744
|
linkComponent
|
|
3517
3745
|
}
|
|
@@ -3534,10 +3762,7 @@ function PageBuilder({
|
|
|
3534
3762
|
instance: selectedInstance,
|
|
3535
3763
|
definition: selectedDefinition,
|
|
3536
3764
|
theme,
|
|
3537
|
-
onChange: (settings) => updateWidgetSettings(
|
|
3538
|
-
selectedInstance.widgetId,
|
|
3539
|
-
settings
|
|
3540
|
-
)
|
|
3765
|
+
onChange: (settings) => updateWidgetSettings(selectedInstance.widgetId, settings)
|
|
3541
3766
|
},
|
|
3542
3767
|
selectedInstance.widgetId
|
|
3543
3768
|
)
|
|
@@ -3562,6 +3787,19 @@ function PageBuilder({
|
|
|
3562
3787
|
) }),
|
|
3563
3788
|
showSeoPanel && /* @__PURE__ */ jsx(SettingsPanel, { title: "SEO", onClose: closePanel, children: /* @__PURE__ */ jsx(SeoEditor, { seo, onChange: setSeo }) })
|
|
3564
3789
|
] }),
|
|
3790
|
+
pendingDeleteId !== null && /* @__PURE__ */ jsx(
|
|
3791
|
+
ConfirmDialog,
|
|
3792
|
+
{
|
|
3793
|
+
title: `Delete ${getWidget(layout.find((w) => w.widgetId === pendingDeleteId)?.name ?? "")?.metadata.displayName ?? "block"}?`,
|
|
3794
|
+
description: "This block and its content will be removed from the page draft.",
|
|
3795
|
+
confirmLabel: "Delete",
|
|
3796
|
+
onConfirm: () => {
|
|
3797
|
+
deleteWidget(pendingDeleteId);
|
|
3798
|
+
setPendingDeleteId(null);
|
|
3799
|
+
},
|
|
3800
|
+
onClose: () => setPendingDeleteId(null)
|
|
3801
|
+
}
|
|
3802
|
+
),
|
|
3565
3803
|
insertAfter !== null && /* @__PURE__ */ jsx(
|
|
3566
3804
|
BlockPicker,
|
|
3567
3805
|
{
|
|
@@ -3575,6 +3813,6 @@ function PageBuilder({
|
|
|
3575
3813
|
);
|
|
3576
3814
|
}
|
|
3577
3815
|
|
|
3578
|
-
export { BlockPicker, BuilderTopBar, ColorSelector, ContentPaddingSelector, MaxWidthSelector, PATTERN_PRESETS, PageBuilder, PageBuilderPropertyHeader, PageBuilderSlider, SectionBackgroundPanel, SeoEditor, SettingsPanel, ThemeEditor, VerticalPaddingSelector, createDefaultLayout, createWidgetInstance, ensureRequiredSharedWidgets, getDefaultTheme, getMaxWidthTWClass, getVerticalPaddingTWClass };
|
|
3579
|
-
//# sourceMappingURL=chunk-
|
|
3580
|
-
//# sourceMappingURL=chunk-
|
|
3816
|
+
export { BlockPicker, BuilderTopBar, ColorSelector, ContentPaddingSelector, MaxWidthSelector, PATTERN_PRESETS, PageBuilder, PageBuilderPropertyHeader, PageBuilderSlider, SectionBackgroundPanel, SeoEditor, SettingsPanel, ThemeEditor, VerticalPaddingSelector, createDefaultLayout, createWidgetInstance, ensureRequiredSharedWidgets, getDefaultTheme, getMaxWidthTWClass, getVerticalPaddingTWClass, withDefaultSettings };
|
|
3817
|
+
//# sourceMappingURL=chunk-GIKTOAQS.js.map
|
|
3818
|
+
//# sourceMappingURL=chunk-GIKTOAQS.js.map
|