@frontlit/page-builder 0.1.0-alpha.2 → 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 +32 -0
- package/dist/blocks/index.d.ts +33 -21
- package/dist/blocks/index.js +3 -3
- package/dist/builder/index.d.ts +7 -8
- package/dist/builder/index.js +6 -5
- package/dist/{button-Bzt1GDO-.d.ts → button-OLKN3wPf.d.ts} +2 -2
- package/dist/{chunk-H4P5MFJI.js → chunk-36QHCIPM.js} +205 -251
- package/dist/chunk-36QHCIPM.js.map +1 -0
- package/dist/chunk-BBI7UHOA.js +56 -0
- package/dist/chunk-BBI7UHOA.js.map +1 -0
- package/dist/{chunk-KQKSLI3L.js → chunk-GIKTOAQS.js} +335 -122
- 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-HDINUNI2.js → chunk-IU4KATI2.js} +69 -96
- package/dist/chunk-IU4KATI2.js.map +1 -0
- package/dist/{chunk-SGNRWWG3.js → chunk-J7Z4UW45.js} +530 -135
- package/dist/chunk-J7Z4UW45.js.map +1 -0
- package/dist/{chunk-UO7XGBGM.js → chunk-K4WCLHMS.js} +1182 -1033
- package/dist/chunk-K4WCLHMS.js.map +1 -0
- package/dist/components/index.d.ts +33 -8
- package/dist/components/index.js +42 -2
- package/dist/components/index.js.map +1 -1
- package/dist/data-slots.d.ts +3 -3
- 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 +17 -10
- package/dist/index.js +7 -6
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +1 -1
- package/dist/{page-W3hQga4w.d.ts → page-B5Gmm-Ys.d.ts} +1 -1
- package/dist/primitives/index.d.ts +44 -9
- package/dist/primitives/index.js +1 -1
- package/dist/renderer/index.d.ts +12 -8
- package/dist/renderer/index.js +5 -4
- package/dist/{section-background-MsdE40Rk.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/server/theme-style-5_AGy-4V.d.ts +183 -0
- package/dist/server/theme-style-BPaMwk88.d.ts +183 -0
- package/dist/server/theme.d.ts +28 -0
- package/dist/server/theme.js +1671 -0
- package/dist/server/theme.js.map +1 -0
- package/dist/server/widget-YH9BrOwY.d.ts +77 -0
- package/dist/styles.css +121 -15
- package/dist/{theme-style-Cbl7NM-T.d.ts → theme-style-BVd5tOsc.d.ts} +20 -0
- package/dist/theme.css +12 -0
- package/dist/{widget-B_RoG6se.d.ts → widget-CpE2HdgU.d.ts} +17 -14
- package/package.json +60 -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-H4P5MFJI.js.map +0 -1
- package/dist/chunk-HDINUNI2.js.map +0 -1
- package/dist/chunk-KQKSLI3L.js.map +0 -1
- package/dist/chunk-RUYOL7JZ.js +0 -4
- package/dist/chunk-SGNRWWG3.js.map +0 -1
- package/dist/chunk-UO7XGBGM.js.map +0 -1
- package/dist/image-DAWVx1zQ.d.ts +0 -31
|
@@ -1,10 +1,10 @@
|
|
|
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-
|
|
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
6
|
import { getMediaUrl } from './chunk-XU7ALPGQ.js';
|
|
7
|
-
import
|
|
7
|
+
import React3, { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
8
8
|
import * as Icons from 'lucide-react';
|
|
9
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';
|
|
10
10
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -14,12 +14,20 @@ import { ImageUploadDialog } from '@frontlit/media-uploader';
|
|
|
14
14
|
// src/utils/debounce.ts
|
|
15
15
|
function debounce(fn, wait) {
|
|
16
16
|
let timeout;
|
|
17
|
-
|
|
17
|
+
let pending = null;
|
|
18
|
+
const debounced = function(...args) {
|
|
19
|
+
pending = args;
|
|
18
20
|
clearTimeout(timeout);
|
|
19
|
-
timeout = setTimeout(
|
|
20
|
-
fn(...args);
|
|
21
|
-
}, wait);
|
|
21
|
+
timeout = setTimeout(debounced.flush, wait);
|
|
22
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;
|
|
23
31
|
}
|
|
24
32
|
|
|
25
33
|
// src/utils/color-mode.ts
|
|
@@ -46,6 +54,12 @@ function createWidgetInstance(name, overrides) {
|
|
|
46
54
|
}
|
|
47
55
|
};
|
|
48
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
|
+
}
|
|
49
63
|
function ensureRequiredSharedWidgets(layout) {
|
|
50
64
|
const header = layout.find((widget) => widget.name === "header") ?? createWidgetInstance("header");
|
|
51
65
|
const footer = layout.find((widget) => widget.name === "footer") ?? createWidgetInstance("footer");
|
|
@@ -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,14 +539,15 @@ 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
552
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center justify-between gap-2", className), children: [
|
|
477
553
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
@@ -494,9 +570,14 @@ function ColorSelector({
|
|
|
494
570
|
{
|
|
495
571
|
type: "text",
|
|
496
572
|
value: localValue ?? "",
|
|
497
|
-
placeholder: "#000000",
|
|
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,
|
|
498
576
|
onChange: (e) => handleChange(e.currentTarget.value),
|
|
499
|
-
className:
|
|
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"
|
|
580
|
+
),
|
|
500
581
|
"aria-label": `${title} hex value`
|
|
501
582
|
}
|
|
502
583
|
),
|
|
@@ -538,10 +619,6 @@ function MaxWidthSelector({
|
|
|
538
619
|
([_, v]) => v === (value ?? themeDefault)
|
|
539
620
|
)?.[0] || "5";
|
|
540
621
|
const handleChange = (newValue) => {
|
|
541
|
-
if (newValue === void 0) {
|
|
542
|
-
onChange();
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
622
|
onChange(getMaxWidthTWClass(newValue));
|
|
546
623
|
};
|
|
547
624
|
return /* @__PURE__ */ jsx(
|
|
@@ -554,7 +631,6 @@ function MaxWidthSelector({
|
|
|
554
631
|
value: parseInt(numericValue),
|
|
555
632
|
tooltip: "Maximum width of the content",
|
|
556
633
|
className,
|
|
557
|
-
allowsReset: true,
|
|
558
634
|
unit: ""
|
|
559
635
|
}
|
|
560
636
|
);
|
|
@@ -587,10 +663,6 @@ function VerticalPaddingSelector({
|
|
|
587
663
|
}) {
|
|
588
664
|
const numericValue = Object.entries(PADDING_MAP).find(([_, v]) => v === (value ?? themeDefault))?.[0] || "6";
|
|
589
665
|
const handleChange = (newValue) => {
|
|
590
|
-
if (newValue === void 0) {
|
|
591
|
-
onChange();
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
666
|
onChange(getVerticalPaddingTWClass(newValue));
|
|
595
667
|
};
|
|
596
668
|
return /* @__PURE__ */ jsx(
|
|
@@ -2099,6 +2171,13 @@ function BlockSettings({
|
|
|
2099
2171
|
onChange
|
|
2100
2172
|
}
|
|
2101
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
|
+
) }),
|
|
2102
2181
|
/* @__PURE__ */ jsx(
|
|
2103
2182
|
DesignFieldGroup,
|
|
2104
2183
|
{
|
|
@@ -2368,7 +2447,8 @@ var fontFamilyOptions = {
|
|
|
2368
2447
|
{ label: "Roboto", value: "font-roboto" },
|
|
2369
2448
|
{ label: "Mulish", value: "font-mulish" },
|
|
2370
2449
|
{ label: "Nunito", value: "font-nunito" },
|
|
2371
|
-
{ label: "Work Sans", value: "font-work-sans" }
|
|
2450
|
+
{ label: "Work Sans", value: "font-work-sans" },
|
|
2451
|
+
{ label: "Hanken Grotesk", value: "font-hanken-grotesk" }
|
|
2372
2452
|
],
|
|
2373
2453
|
Serif: [
|
|
2374
2454
|
{ label: "Merriweather", value: "font-merriweather" },
|
|
@@ -2383,16 +2463,30 @@ var fontFamilyOptions = {
|
|
|
2383
2463
|
{ label: "Raleway", value: "font-raleway" },
|
|
2384
2464
|
{ label: "Rubik", value: "font-rubik" },
|
|
2385
2465
|
{ label: "Oswald", value: "font-oswald" },
|
|
2386
|
-
{ label: "Bebas Neue", value: "font-bebas-neue" }
|
|
2466
|
+
{ label: "Bebas Neue", value: "font-bebas-neue" },
|
|
2467
|
+
{ label: "Archivo", value: "font-archivo" }
|
|
2387
2468
|
],
|
|
2388
2469
|
Modern: [
|
|
2389
2470
|
{ label: "Lato", value: "font-lato" },
|
|
2390
2471
|
{ label: "PT Sans", value: "font-pt-sans" },
|
|
2391
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" }
|
|
2392
2477
|
]
|
|
2393
2478
|
};
|
|
2394
|
-
function
|
|
2479
|
+
function defaultFluid(fontSize) {
|
|
2480
|
+
const max = TAILWIND_TEXT_PX[fontSize ?? ""] ?? 48;
|
|
2481
|
+
return { min: Math.round(max * 0.66), max };
|
|
2482
|
+
}
|
|
2483
|
+
function TypographySelector({
|
|
2484
|
+
value,
|
|
2485
|
+
onChange,
|
|
2486
|
+
allowFluid
|
|
2487
|
+
}) {
|
|
2395
2488
|
const update = (patch) => onChange({ ...value, ...patch });
|
|
2489
|
+
const fluid = value?.fluid;
|
|
2396
2490
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6 p-2", children: [
|
|
2397
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: [
|
|
2398
2492
|
/* @__PURE__ */ jsx(PanelLabel, { children: "Preview" }),
|
|
@@ -2407,6 +2501,7 @@ function TypographySelector({ value, onChange }) {
|
|
|
2407
2501
|
value?.letterSpacing || "",
|
|
2408
2502
|
value?.textTransform || "normal-case"
|
|
2409
2503
|
),
|
|
2504
|
+
style: fluid ? { fontSize: fluidFontSize(fluid) } : void 0,
|
|
2410
2505
|
children: "The quick brown fox jumps over the lazy dog"
|
|
2411
2506
|
}
|
|
2412
2507
|
)
|
|
@@ -2427,11 +2522,56 @@ function TypographySelector({ value, onChange }) {
|
|
|
2427
2522
|
}
|
|
2428
2523
|
)
|
|
2429
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
|
+
] }),
|
|
2430
2570
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
2431
2571
|
/* @__PURE__ */ jsx(
|
|
2432
2572
|
PanelSelect2,
|
|
2433
2573
|
{
|
|
2434
|
-
title: "Font Size",
|
|
2574
|
+
title: fluid ? "Font Size (unused while scaling)" : "Font Size",
|
|
2435
2575
|
value: value?.fontSize || "",
|
|
2436
2576
|
onChange: (v) => update({ fontSize: v }),
|
|
2437
2577
|
options: fontSizeOptions,
|
|
@@ -2772,7 +2912,24 @@ function StructureSelector({ type, theme, onChange }) {
|
|
|
2772
2912
|
updatePadding({ y });
|
|
2773
2913
|
}
|
|
2774
2914
|
}
|
|
2775
|
-
)
|
|
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
|
+
] })
|
|
2776
2933
|
] });
|
|
2777
2934
|
}
|
|
2778
2935
|
var sections = [
|
|
@@ -2798,6 +2955,7 @@ var sections = [
|
|
|
2798
2955
|
}
|
|
2799
2956
|
];
|
|
2800
2957
|
var typographyDisplayNames = {
|
|
2958
|
+
display: "Display (hero)",
|
|
2801
2959
|
header1: "Header 1",
|
|
2802
2960
|
header2: "Header 2",
|
|
2803
2961
|
header3: "Header 3",
|
|
@@ -2810,12 +2968,26 @@ var typographyDisplayNames = {
|
|
|
2810
2968
|
caption: "Caption",
|
|
2811
2969
|
link: "Link",
|
|
2812
2970
|
button: "Button Text",
|
|
2813
|
-
input: "Input Text"
|
|
2971
|
+
input: "Input Text",
|
|
2972
|
+
code: "Code"
|
|
2814
2973
|
};
|
|
2974
|
+
var DEFAULT_CODE_TYPOGRAPHY = {
|
|
2975
|
+
fontFamily: "font-jetbrains-mono",
|
|
2976
|
+
fontSize: "text-sm",
|
|
2977
|
+
fontWeight: "font-normal",
|
|
2978
|
+
lineHeight: "leading-relaxed"
|
|
2979
|
+
};
|
|
2980
|
+
var fluidTypography = /* @__PURE__ */ new Set([
|
|
2981
|
+
"display",
|
|
2982
|
+
"header1",
|
|
2983
|
+
"header2",
|
|
2984
|
+
"header3",
|
|
2985
|
+
"header4"
|
|
2986
|
+
]);
|
|
2815
2987
|
var typographyCategories = [
|
|
2816
2988
|
{
|
|
2817
2989
|
name: "Headers",
|
|
2818
|
-
items: ["header1", "header2", "header3", "header4", "preheader"]
|
|
2990
|
+
items: ["display", "header1", "header2", "header3", "header4", "preheader"]
|
|
2819
2991
|
},
|
|
2820
2992
|
{
|
|
2821
2993
|
name: "Subheaders",
|
|
@@ -2827,7 +2999,7 @@ var typographyCategories = [
|
|
|
2827
2999
|
},
|
|
2828
3000
|
{
|
|
2829
3001
|
name: "Interactive Elements",
|
|
2830
|
-
items: ["link", "button", "input"]
|
|
3002
|
+
items: ["link", "button", "input", "code"]
|
|
2831
3003
|
}
|
|
2832
3004
|
];
|
|
2833
3005
|
var colorCategories = [
|
|
@@ -2941,34 +3113,28 @@ function ThemeEditor({
|
|
|
2941
3113
|
onCustomThemesChange
|
|
2942
3114
|
}) {
|
|
2943
3115
|
const [navigationStack, setNavigationStack] = useState([]);
|
|
2944
|
-
const [collapsedCategories, setCollapsedCategories] = useState(() => {
|
|
2945
|
-
const initial = {};
|
|
2946
|
-
typographyCategories.forEach((category) => {
|
|
2947
|
-
initial[category.name] = true;
|
|
2948
|
-
});
|
|
2949
|
-
return initial;
|
|
2950
|
-
});
|
|
2951
3116
|
const navigateTo = useCallback((item) => {
|
|
2952
3117
|
setNavigationStack((prev) => [...prev, item]);
|
|
2953
3118
|
}, []);
|
|
2954
3119
|
const navigateBack = useCallback(() => {
|
|
2955
3120
|
setNavigationStack((prev) => prev.slice(0, -1));
|
|
2956
3121
|
}, []);
|
|
2957
|
-
const
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
(style) => {
|
|
2965
|
-
const updated = { ...theme, theme: style };
|
|
2966
|
-
onApply(updated);
|
|
3122
|
+
const commitTheme = useCallback(
|
|
3123
|
+
(updated) => {
|
|
3124
|
+
if (updated.id === appliedThemeId) {
|
|
3125
|
+
onApply(updated);
|
|
3126
|
+
} else {
|
|
3127
|
+
onPreview(updated);
|
|
3128
|
+
}
|
|
2967
3129
|
onCustomThemesChange(
|
|
2968
3130
|
customThemes.map((t) => t.id === updated.id ? updated : t)
|
|
2969
3131
|
);
|
|
2970
3132
|
},
|
|
2971
|
-
[
|
|
3133
|
+
[appliedThemeId, customThemes, onApply, onPreview, onCustomThemesChange]
|
|
3134
|
+
);
|
|
3135
|
+
const applyStyle = useCallback(
|
|
3136
|
+
(style) => commitTheme({ ...theme, theme: style }),
|
|
3137
|
+
[theme, commitTheme]
|
|
2972
3138
|
);
|
|
2973
3139
|
const startEditing = useCallback(
|
|
2974
3140
|
(themeItem, isSystem) => {
|
|
@@ -2982,10 +3148,10 @@ function ThemeEditor({
|
|
|
2982
3148
|
};
|
|
2983
3149
|
onCustomThemesChange([...customThemes, target]);
|
|
2984
3150
|
}
|
|
2985
|
-
|
|
3151
|
+
onPreview(target);
|
|
2986
3152
|
setNavigationStack([{ id: "categories", label: target.name }]);
|
|
2987
3153
|
},
|
|
2988
|
-
[systemThemes, customThemes,
|
|
3154
|
+
[systemThemes, customThemes, onPreview, onCustomThemesChange]
|
|
2989
3155
|
);
|
|
2990
3156
|
const renderDrillButton = (label, onClick) => /* @__PURE__ */ jsxs(
|
|
2991
3157
|
"button",
|
|
@@ -3097,37 +3263,49 @@ function ThemeEditor({
|
|
|
3097
3263
|
) }) }, category.key)) })
|
|
3098
3264
|
] });
|
|
3099
3265
|
};
|
|
3100
|
-
const
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
{
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
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,
|
|
3110
3292
|
{
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
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
|
+
}
|
|
3114
3301
|
)
|
|
3115
|
-
}
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
]
|
|
3119
|
-
}
|
|
3120
|
-
),
|
|
3121
|
-
!collapsedCategories[category.name] && /* @__PURE__ */ jsx("div", { children: category.items.map(
|
|
3122
|
-
(typography) => renderDrillButton(
|
|
3123
|
-
typographyDisplayNames[typography] || capitalize(typography),
|
|
3124
|
-
() => navigateTo({
|
|
3125
|
-
id: typography,
|
|
3126
|
-
label: typographyDisplayNames[typography] || capitalize(typography)
|
|
3302
|
+
},
|
|
3303
|
+
typography
|
|
3304
|
+
);
|
|
3127
3305
|
})
|
|
3128
|
-
)
|
|
3129
|
-
|
|
3130
|
-
|
|
3306
|
+
] }, category.name))
|
|
3307
|
+
] });
|
|
3308
|
+
};
|
|
3131
3309
|
const renderInteractivesList = () => /* @__PURE__ */ jsx("div", { className: "space-y-1", children: Object.keys(interactiveDisplayNames).map(
|
|
3132
3310
|
(interactive) => renderDrillButton(
|
|
3133
3311
|
interactiveDisplayNames[interactive] || capitalize(interactive),
|
|
@@ -3152,22 +3330,6 @@ function ThemeEditor({
|
|
|
3152
3330
|
if (!currentItem) {
|
|
3153
3331
|
return renderRootView();
|
|
3154
3332
|
}
|
|
3155
|
-
if (parentItem?.id === "typography" && currentItem.id in theme.theme.typography) {
|
|
3156
|
-
const key = currentItem.id;
|
|
3157
|
-
return /* @__PURE__ */ jsx(
|
|
3158
|
-
TypographySelector,
|
|
3159
|
-
{
|
|
3160
|
-
value: theme.theme.typography[key],
|
|
3161
|
-
onChange: (value) => applyStyle({
|
|
3162
|
-
...theme.theme,
|
|
3163
|
-
typography: {
|
|
3164
|
-
...theme.theme.typography,
|
|
3165
|
-
[key]: value
|
|
3166
|
-
}
|
|
3167
|
-
})
|
|
3168
|
-
}
|
|
3169
|
-
);
|
|
3170
|
-
}
|
|
3171
3333
|
if (parentItem?.id === "interactives" && currentItem.id in theme.theme.interactives) {
|
|
3172
3334
|
return /* @__PURE__ */ jsx(
|
|
3173
3335
|
InteractiveSelector,
|
|
@@ -3194,7 +3356,7 @@ function ThemeEditor({
|
|
|
3194
3356
|
case "colors":
|
|
3195
3357
|
return renderColorsView();
|
|
3196
3358
|
case "typography":
|
|
3197
|
-
return
|
|
3359
|
+
return renderTypographyView();
|
|
3198
3360
|
case "interactives":
|
|
3199
3361
|
return renderInteractivesList();
|
|
3200
3362
|
case "structure":
|
|
@@ -3216,7 +3378,35 @@ function ThemeEditor({
|
|
|
3216
3378
|
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
3217
3379
|
}
|
|
3218
3380
|
),
|
|
3219
|
-
/* @__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
|
+
)
|
|
3220
3410
|
] }),
|
|
3221
3411
|
/* @__PURE__ */ jsx("div", { className: "py-2", children: getCurrentView() })
|
|
3222
3412
|
] })
|
|
@@ -3370,7 +3560,7 @@ function PageBuilder({
|
|
|
3370
3560
|
className
|
|
3371
3561
|
}) {
|
|
3372
3562
|
const [layout, setLayout] = useState(
|
|
3373
|
-
() => initialLayout ? ensureRequiredSharedWidgets(initialLayout) : createDefaultLayout()
|
|
3563
|
+
() => initialLayout ? ensureRequiredSharedWidgets(withDefaultSettings(initialLayout)) : createDefaultLayout()
|
|
3374
3564
|
);
|
|
3375
3565
|
const [theme, setTheme] = useState(() => initialTheme ?? getDefaultTheme());
|
|
3376
3566
|
const [previewTheme, setPreviewTheme] = useState(null);
|
|
@@ -3385,6 +3575,7 @@ function PageBuilder({
|
|
|
3385
3575
|
const [device, setDevice] = useState("desktop");
|
|
3386
3576
|
const [panel, setPanel] = useState(null);
|
|
3387
3577
|
const [insertAfter, setInsertAfter] = useState(null);
|
|
3578
|
+
const [pendingDeleteId, setPendingDeleteId] = useState(null);
|
|
3388
3579
|
const [movedWidgetId, setMovedWidgetId] = useState(null);
|
|
3389
3580
|
const movedTimeoutRef = useRef(null);
|
|
3390
3581
|
useEffect(() => {
|
|
@@ -3409,6 +3600,7 @@ function PageBuilder({
|
|
|
3409
3600
|
useEffect(() => {
|
|
3410
3601
|
emitChange({ layout, theme, seo, customThemes });
|
|
3411
3602
|
}, [layout, theme, seo, customThemes]);
|
|
3603
|
+
useEffect(() => emitChange.flush, [emitChange]);
|
|
3412
3604
|
const addableBlocks = useMemo(() => getAddableBlocks(), []);
|
|
3413
3605
|
function updateWidgetSettings(widgetId, settings) {
|
|
3414
3606
|
setLayout(
|
|
@@ -3431,6 +3623,9 @@ function PageBuilder({
|
|
|
3431
3623
|
[next[index], next[targetIndex]] = [next[targetIndex], next[index]];
|
|
3432
3624
|
return next;
|
|
3433
3625
|
});
|
|
3626
|
+
highlightWidget(widgetId);
|
|
3627
|
+
}
|
|
3628
|
+
function highlightWidget(widgetId) {
|
|
3434
3629
|
if (movedTimeoutRef.current) clearTimeout(movedTimeoutRef.current);
|
|
3435
3630
|
setMovedWidgetId(widgetId);
|
|
3436
3631
|
movedTimeoutRef.current = setTimeout(() => setMovedWidgetId(null), 1500);
|
|
@@ -3456,7 +3651,11 @@ function PageBuilder({
|
|
|
3456
3651
|
return [...prev.slice(0, footerIndex), instance, ...prev.slice(footerIndex)];
|
|
3457
3652
|
}
|
|
3458
3653
|
const afterIndex = prev.findIndex((w) => w.widgetId === insertAfter);
|
|
3459
|
-
if (afterIndex === -1
|
|
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)];
|
|
3658
|
+
}
|
|
3460
3659
|
return [
|
|
3461
3660
|
...prev.slice(0, afterIndex + 1),
|
|
3462
3661
|
instance,
|
|
@@ -3464,6 +3663,7 @@ function PageBuilder({
|
|
|
3464
3663
|
];
|
|
3465
3664
|
});
|
|
3466
3665
|
setInsertAfter(null);
|
|
3666
|
+
highlightWidget(instance.widgetId);
|
|
3467
3667
|
setPanel({ mode: "block", widgetId: instance.widgetId });
|
|
3468
3668
|
}
|
|
3469
3669
|
const selectedWidgetId = panel?.mode === "block" ? panel.widgetId : null;
|
|
@@ -3500,7 +3700,7 @@ function PageBuilder({
|
|
|
3500
3700
|
onDeviceChange: setDevice,
|
|
3501
3701
|
onOpenTheme: () => setPanel({ mode: "theme" }),
|
|
3502
3702
|
onOpenSeo: () => setPanel({ mode: "seo" }),
|
|
3503
|
-
onAddBlock: () => setInsertAfter("end"),
|
|
3703
|
+
onAddBlock: () => setInsertAfter(selectedWidgetId ?? "end"),
|
|
3504
3704
|
allowThemeEditing
|
|
3505
3705
|
}
|
|
3506
3706
|
),
|
|
@@ -3521,8 +3721,9 @@ function PageBuilder({
|
|
|
3521
3721
|
{
|
|
3522
3722
|
className: cn(
|
|
3523
3723
|
"h-full w-full max-w-full transition-[max-width] duration-300",
|
|
3524
|
-
|
|
3525
|
-
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"
|
|
3526
3727
|
),
|
|
3527
3728
|
children: /* @__PURE__ */ jsx(
|
|
3528
3729
|
PageRenderer,
|
|
@@ -3531,7 +3732,6 @@ function PageBuilder({
|
|
|
3531
3732
|
theme: paintedTheme,
|
|
3532
3733
|
pageData,
|
|
3533
3734
|
nextTheme: resolvedMode,
|
|
3534
|
-
themeMode: mode,
|
|
3535
3735
|
onThemeModeChange: setMode,
|
|
3536
3736
|
editing: true,
|
|
3537
3737
|
selectedWidgetId: selectedWidgetId ?? void 0,
|
|
@@ -3539,7 +3739,7 @@ function PageBuilder({
|
|
|
3539
3739
|
onSelectWidget: (id) => setPanel({ mode: "block", widgetId: id }),
|
|
3540
3740
|
onMoveWidgetUp: (id) => moveWidget(id, -1),
|
|
3541
3741
|
onMoveWidgetDown: (id) => moveWidget(id, 1),
|
|
3542
|
-
onDeleteWidget:
|
|
3742
|
+
onDeleteWidget: setPendingDeleteId,
|
|
3543
3743
|
onAddWidgetBelow: (id) => setInsertAfter(id),
|
|
3544
3744
|
linkComponent
|
|
3545
3745
|
}
|
|
@@ -3587,6 +3787,19 @@ function PageBuilder({
|
|
|
3587
3787
|
) }),
|
|
3588
3788
|
showSeoPanel && /* @__PURE__ */ jsx(SettingsPanel, { title: "SEO", onClose: closePanel, children: /* @__PURE__ */ jsx(SeoEditor, { seo, onChange: setSeo }) })
|
|
3589
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
|
+
),
|
|
3590
3803
|
insertAfter !== null && /* @__PURE__ */ jsx(
|
|
3591
3804
|
BlockPicker,
|
|
3592
3805
|
{
|
|
@@ -3600,6 +3813,6 @@ function PageBuilder({
|
|
|
3600
3813
|
);
|
|
3601
3814
|
}
|
|
3602
3815
|
|
|
3603
|
-
export { BlockPicker, BuilderTopBar, ColorSelector, ContentPaddingSelector, MaxWidthSelector, PATTERN_PRESETS, PageBuilder, PageBuilderPropertyHeader, PageBuilderSlider, SectionBackgroundPanel, SeoEditor, SettingsPanel, ThemeEditor, VerticalPaddingSelector, createDefaultLayout, createWidgetInstance, ensureRequiredSharedWidgets, getDefaultTheme, getMaxWidthTWClass, getVerticalPaddingTWClass };
|
|
3604
|
-
//# sourceMappingURL=chunk-
|
|
3605
|
-
//# 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
|