@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.
Files changed (98) hide show
  1. package/README.md +32 -0
  2. package/dist/blocks/index.d.ts +33 -21
  3. package/dist/blocks/index.js +3 -3
  4. package/dist/builder/index.d.ts +7 -8
  5. package/dist/builder/index.js +6 -5
  6. package/dist/{button-Bzt1GDO-.d.ts → button-OLKN3wPf.d.ts} +2 -2
  7. package/dist/{chunk-H4P5MFJI.js → chunk-36QHCIPM.js} +205 -251
  8. package/dist/chunk-36QHCIPM.js.map +1 -0
  9. package/dist/chunk-BBI7UHOA.js +56 -0
  10. package/dist/chunk-BBI7UHOA.js.map +1 -0
  11. package/dist/{chunk-KQKSLI3L.js → chunk-GIKTOAQS.js} +335 -122
  12. package/dist/chunk-GIKTOAQS.js.map +1 -0
  13. package/dist/chunk-HWOVSHIW.js +4 -0
  14. package/dist/{chunk-RUYOL7JZ.js.map → chunk-HWOVSHIW.js.map} +1 -1
  15. package/dist/{chunk-HDINUNI2.js → chunk-IU4KATI2.js} +69 -96
  16. package/dist/chunk-IU4KATI2.js.map +1 -0
  17. package/dist/{chunk-SGNRWWG3.js → chunk-J7Z4UW45.js} +530 -135
  18. package/dist/chunk-J7Z4UW45.js.map +1 -0
  19. package/dist/{chunk-UO7XGBGM.js → chunk-K4WCLHMS.js} +1182 -1033
  20. package/dist/chunk-K4WCLHMS.js.map +1 -0
  21. package/dist/components/index.d.ts +33 -8
  22. package/dist/components/index.js +42 -2
  23. package/dist/components/index.js.map +1 -1
  24. package/dist/data-slots.d.ts +3 -3
  25. package/dist/fonts/archivo/archivo-latin-variable.woff2 +0 -0
  26. package/dist/fonts/hanken-grotesk/hanken-grotesk-latin-variable.woff2 +0 -0
  27. package/dist/fonts/jetbrains-mono/jetbrains-mono-latin-variable.woff2 +0 -0
  28. package/dist/fonts/spline-sans-mono/spline-sans-mono-latin-variable.woff2 +0 -0
  29. package/dist/heading-DQCxQt38.d.ts +20 -0
  30. package/dist/image-Bk8kPXwP.d.ts +52 -0
  31. package/dist/index.d.ts +17 -10
  32. package/dist/index.js +7 -6
  33. package/dist/models/index.d.ts +5 -5
  34. package/dist/models/index.js +1 -1
  35. package/dist/{page-W3hQga4w.d.ts → page-B5Gmm-Ys.d.ts} +1 -1
  36. package/dist/primitives/index.d.ts +44 -9
  37. package/dist/primitives/index.js +1 -1
  38. package/dist/renderer/index.d.ts +12 -8
  39. package/dist/renderer/index.js +5 -4
  40. package/dist/{section-background-MsdE40Rk.d.ts → section-background-6V_LCi5e.d.ts} +1 -1
  41. package/dist/server/index.d.ts +103 -0
  42. package/dist/server/index.js +2649 -0
  43. package/dist/server/index.js.map +1 -0
  44. package/dist/server/islands/code-snippet.d.ts +17 -0
  45. package/dist/server/islands/code-snippet.js +72 -0
  46. package/dist/server/islands/code-snippet.js.map +1 -0
  47. package/dist/server/islands/email-form.d.ts +50 -0
  48. package/dist/server/islands/email-form.js +406 -0
  49. package/dist/server/islands/email-form.js.map +1 -0
  50. package/dist/server/islands/header-mobile-menu.d.ts +22 -0
  51. package/dist/server/islands/header-mobile-menu.js +422 -0
  52. package/dist/server/islands/header-mobile-menu.js.map +1 -0
  53. package/dist/server/islands/inline-embed.d.ts +28 -0
  54. package/dist/server/islands/inline-embed.js +84 -0
  55. package/dist/server/islands/inline-embed.js.map +1 -0
  56. package/dist/server/islands/marquee-track.d.ts +18 -0
  57. package/dist/server/islands/marquee-track.js +67 -0
  58. package/dist/server/islands/marquee-track.js.map +1 -0
  59. package/dist/server/islands/nav-link.d.ts +37 -0
  60. package/dist/server/islands/nav-link.js +67 -0
  61. package/dist/server/islands/nav-link.js.map +1 -0
  62. package/dist/server/islands/support-form.d.ts +17 -0
  63. package/dist/server/islands/support-form.js +469 -0
  64. package/dist/server/islands/support-form.js.map +1 -0
  65. package/dist/server/islands/theme-mode-switcher.d.ts +38 -0
  66. package/dist/server/islands/theme-mode-switcher.js +169 -0
  67. package/dist/server/islands/theme-mode-switcher.js.map +1 -0
  68. package/dist/server/islands/video-with-preview.d.ts +13 -0
  69. package/dist/server/islands/video-with-preview.js +269 -0
  70. package/dist/server/islands/video-with-preview.js.map +1 -0
  71. package/dist/server/primitives.d.ts +200 -0
  72. package/dist/server/primitives.js +888 -0
  73. package/dist/server/primitives.js.map +1 -0
  74. package/dist/server/schema.d.ts +11308 -0
  75. package/dist/server/schema.js +6179 -0
  76. package/dist/server/schema.js.map +1 -0
  77. package/dist/server/theme-CF3fIKvw.d.ts +9 -0
  78. package/dist/server/theme-style-5_AGy-4V.d.ts +183 -0
  79. package/dist/server/theme-style-BPaMwk88.d.ts +183 -0
  80. package/dist/server/theme.d.ts +28 -0
  81. package/dist/server/theme.js +1671 -0
  82. package/dist/server/theme.js.map +1 -0
  83. package/dist/server/widget-YH9BrOwY.d.ts +77 -0
  84. package/dist/styles.css +121 -15
  85. package/dist/{theme-style-Cbl7NM-T.d.ts → theme-style-BVd5tOsc.d.ts} +20 -0
  86. package/dist/theme.css +12 -0
  87. package/dist/{widget-B_RoG6se.d.ts → widget-CpE2HdgU.d.ts} +17 -14
  88. package/package.json +60 -11
  89. package/schema/page.v1.json +3855 -0
  90. package/schema/site.v1.json +3811 -0
  91. package/dist/alignment-dZDzN96G.d.ts +0 -5
  92. package/dist/chunk-H4P5MFJI.js.map +0 -1
  93. package/dist/chunk-HDINUNI2.js.map +0 -1
  94. package/dist/chunk-KQKSLI3L.js.map +0 -1
  95. package/dist/chunk-RUYOL7JZ.js +0 -4
  96. package/dist/chunk-SGNRWWG3.js.map +0 -1
  97. package/dist/chunk-UO7XGBGM.js.map +0 -1
  98. package/dist/image-DAWVx1zQ.d.ts +0 -31
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import { NavLink, VideoWithPreview, Image, TextRenderer, SandboxedEmbed, ThemeModeSwitcher } from './chunk-H4P5MFJI.js';
3
- import { Button2, Drawer, Section, cn, Preheader, Header1, Subheader1, PageCard, PageCardContent, Header2, Header4, Text2, Badge, PageCardHeader, Text1, Input, Label, Link, Caption, Header3 } from './chunk-SGNRWWG3.js';
2
+ import { NavLink, VideoWithPreview, Image, TextRenderer, InlineEmbed } from './chunk-36QHCIPM.js';
3
+ import { Button2, Section, cn, Preheader, Display, Subheader1, CodeSnippet, Caption, PageCard, PageCardContent, Header2, Header1, Header4, Text2, Badge, PageCardHeader, Text1, Link, Header3, Drawer, Input, Label } from './chunk-J7Z4UW45.js';
4
4
  import { getMediaUrl, getMediaAlt } from './chunk-XU7ALPGQ.js';
5
- import React7, { useState, useId, useRef, useEffect } from 'react';
6
5
  import clsx3 from 'clsx';
7
- import * as Icons from 'lucide-react';
8
- import { MenuIcon, Code2, LockKeyhole, ChevronDown, ImageIcon, Plus } from 'lucide-react';
9
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
+ import React2, { useId, useState, useRef, useEffect } from 'react';
8
+ import * as Icons from 'lucide-react';
9
+ import { Code2, LockKeyhole, ChevronDown, MenuIcon, Plus, ImageIcon } from 'lucide-react';
10
10
  import { ImageUploadDialog } from '@frontlit/media-uploader';
11
11
  import { Editor, emptyDoc } from '@frontlit/text-editor';
12
12
 
@@ -17,63 +17,88 @@ var headerMetadata = {
17
17
  description: "The site navigation bar, pinned to the top of every page.",
18
18
  compatibleWith: ["site", "landing", "blog", "post", "custom"]
19
19
  };
20
-
21
- // src/utils/is-video.ts
22
- function isVideo(youtubeLink, media) {
23
- return Boolean(
24
- youtubeLink || media && RegExp("video/").test(media?.mimeType || "")
25
- );
26
- }
27
-
28
- // src/utils/generate-unique-id.ts
29
- function generateUniqueId() {
30
- return Math.random().toString(36).slice(2) + Date.now().toString(36);
31
- }
32
20
  function HeaderLink({
33
21
  link,
34
22
  theme,
35
- onClick
23
+ onClick,
24
+ fullWidth = false
36
25
  }) {
37
26
  if (link.isButton) {
38
- return /* @__PURE__ */ jsx(NavLink, { href: link.href, onClick, children: /* @__PURE__ */ jsx(Button2, { size: "sm", theme, children: link.label }) });
27
+ return /* @__PURE__ */ jsx(NavLink, { href: link.href, onClick, children: /* @__PURE__ */ jsx(
28
+ Button2,
29
+ {
30
+ size: fullWidth ? void 0 : "sm",
31
+ theme,
32
+ className: fullWidth ? "w-full" : void 0,
33
+ children: link.label
34
+ }
35
+ ) });
39
36
  }
40
37
  return /* @__PURE__ */ jsx(NavLink, { href: link.href, onClick, className: "no-underline", children: /* @__PURE__ */ jsx(Link, { theme, className: "no-underline", children: link.label }) });
41
38
  }
39
+ function HeaderMobileMenu({
40
+ links,
41
+ ctaLabel,
42
+ ctaHref,
43
+ theme
44
+ }) {
45
+ const [open, setOpen] = useState(false);
46
+ return /* @__PURE__ */ jsx(
47
+ Drawer,
48
+ {
49
+ open,
50
+ setOpen,
51
+ side: "right",
52
+ theme,
53
+ trigger: /* @__PURE__ */ jsxs(Button2, { variant: "outline", size: "sm", theme, children: [
54
+ /* @__PURE__ */ jsx(MenuIcon, { className: "h-4 w-4" }),
55
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Toggle menu" })
56
+ ] }),
57
+ children: /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-col gap-4", children: [
58
+ links.map((link) => /* @__PURE__ */ jsx(
59
+ HeaderLink,
60
+ {
61
+ link,
62
+ theme,
63
+ onClick: () => setOpen(false),
64
+ fullWidth: true
65
+ },
66
+ link.id
67
+ )),
68
+ ctaLabel && ctaHref && /* @__PURE__ */ jsx(NavLink, { href: ctaHref, onClick: () => setOpen(false), children: /* @__PURE__ */ jsx(Button2, { theme, className: "w-full", children: ctaLabel }) })
69
+ ] })
70
+ }
71
+ );
72
+ }
42
73
  function HeaderWidget({
43
74
  settings: {
44
- logoText,
45
- logoImage,
46
75
  logoCorners,
47
- logoRadius,
48
76
  links = [],
49
77
  ctaLabel,
50
78
  ctaHref,
51
79
  linkAlignment = "left",
52
80
  layout = "fixed",
53
81
  backdropBlur = false,
54
- showThemeSwitcher = true,
55
82
  cssId,
56
83
  maxWidth,
57
84
  verticalPadding,
58
85
  background
59
86
  },
60
87
  state: { theme },
61
- pageData,
62
- nextTheme,
63
- toggleTheme
88
+ pageData
64
89
  }) {
65
90
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
66
91
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
67
92
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
68
- const [mobileNavOpen, setMobileNavOpen] = useState(false);
69
93
  const isFloating = layout === "floating";
70
94
  const isCentered = layout === "centered";
71
95
  const isFixed = !isFloating;
72
96
  const primaryLinks = links.filter((link) => !link.isButton);
73
97
  const buttonLinks = links.filter((link) => link.isButton);
74
- const resolvedLogoImage = pageData.siteLogoUrl || logoImage;
75
- const resolvedLogoAlt = pageData.siteLogoAlt || logoText || "";
76
- const effectiveLogoCorners = logoCorners ?? logoRadius ?? 2;
98
+ const resolvedLogoImage = pageData.siteLogoUrl;
99
+ const resolvedLogoText = pageData.siteTitle;
100
+ const resolvedLogoAlt = pageData.siteLogoAlt || resolvedLogoText || "";
101
+ const effectiveLogoCorners = logoCorners ?? 2;
77
102
  const logo = /* @__PURE__ */ jsx(NavLink, { href: "/", className: "no-underline", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
78
103
  resolvedLogoImage && /* @__PURE__ */ jsx(
79
104
  Image,
@@ -82,49 +107,23 @@ function HeaderWidget({
82
107
  alt: resolvedLogoAlt,
83
108
  width: "w-8",
84
109
  height: "h-8",
110
+ sizes: "32px",
85
111
  className: "aspect-square shrink-0",
86
112
  borderRadius: effectiveLogoCorners
87
113
  }
88
114
  ),
89
- logoText && /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, children: logoText })
115
+ resolvedLogoText && /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, as: "span", children: resolvedLogoText })
90
116
  ] }) });
91
- const colorModeControl = showThemeSwitcher && toggleTheme ? /* @__PURE__ */ jsx(
92
- ThemeModeSwitcher,
93
- {
94
- resolved: nextTheme ?? "light",
95
- onToggle: toggleTheme,
96
- theme: overriddenTheme,
97
- size: "sm",
98
- variant: "outline"
99
- }
100
- ) : null;
101
117
  const ctaAndMenu = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
102
- colorModeControl,
103
118
  buttonLinks.map((link) => /* @__PURE__ */ jsx("div", { className: "hidden lg:!block", children: /* @__PURE__ */ jsx(HeaderLink, { link, theme: overriddenTheme }) }, link.id)),
104
119
  ctaLabel && ctaHref && /* @__PURE__ */ jsx("div", { className: "hidden lg:!block", children: /* @__PURE__ */ jsx(NavLink, { href: ctaHref, children: /* @__PURE__ */ jsx(Button2, { theme: overriddenTheme, size: "sm", children: ctaLabel }) }) }),
105
120
  /* @__PURE__ */ jsx("div", { className: "lg:hidden", children: /* @__PURE__ */ jsx(
106
- Drawer,
121
+ HeaderMobileMenu,
107
122
  {
108
- open: mobileNavOpen,
109
- setOpen: setMobileNavOpen,
110
- side: "right",
111
- theme: overriddenTheme,
112
- trigger: /* @__PURE__ */ jsxs(Button2, { variant: "outline", size: "sm", theme: overriddenTheme, children: [
113
- /* @__PURE__ */ jsx(MenuIcon, { className: "h-4 w-4" }),
114
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Toggle menu" })
115
- ] }),
116
- children: /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-col gap-4", children: [
117
- links.map((link) => /* @__PURE__ */ jsx(
118
- HeaderLink,
119
- {
120
- link,
121
- theme: overriddenTheme,
122
- onClick: () => setMobileNavOpen(false)
123
- },
124
- link.id
125
- )),
126
- ctaLabel && ctaHref && /* @__PURE__ */ jsx(NavLink, { href: ctaHref, onClick: () => setMobileNavOpen(false), children: /* @__PURE__ */ jsx(Button2, { theme: overriddenTheme, className: "w-full", children: ctaLabel }) })
127
- ] })
123
+ links,
124
+ ctaLabel,
125
+ ctaHref,
126
+ theme: overriddenTheme
128
127
  }
129
128
  ) })
130
129
  ] });
@@ -164,7 +163,6 @@ function HeaderWidget({
164
163
  component: "header",
165
164
  id: cssId,
166
165
  background,
167
- nextTheme,
168
166
  className: clsx3(
169
167
  "sticky top-0 z-20",
170
168
  isFixed && "border-b",
@@ -189,6 +187,18 @@ function HeaderWidget({
189
187
  }
190
188
  );
191
189
  }
190
+
191
+ // src/utils/is-video.ts
192
+ function isVideo(youtubeLink, media) {
193
+ return Boolean(
194
+ youtubeLink || media && RegExp("video/").test(media?.mimeType || "")
195
+ );
196
+ }
197
+
198
+ // src/utils/generate-unique-id.ts
199
+ function generateUniqueId() {
200
+ return Math.random().toString(36).slice(2) + Date.now().toString(36);
201
+ }
192
202
  function FieldGroup({
193
203
  title,
194
204
  children
@@ -206,7 +216,8 @@ function TextField({
206
216
  value,
207
217
  onChange,
208
218
  placeholder,
209
- multiline
219
+ multiline,
220
+ hint
210
221
  }) {
211
222
  const generatedId = useId();
212
223
  const inputId = `field-${generatedId.replace(/:/g, "")}`;
@@ -230,9 +241,90 @@ function TextField({
230
241
  placeholder,
231
242
  onChange: (e) => onChange(e.target.value)
232
243
  }
244
+ ),
245
+ hint && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: hint })
246
+ ] });
247
+ }
248
+ var RICH_TEXT_MIN_HEIGHT = {
249
+ 80: "min-h-[80px]",
250
+ 100: "min-h-[100px]",
251
+ 160: "min-h-[160px]"
252
+ };
253
+ function RichTextField({
254
+ label,
255
+ value,
256
+ onChange,
257
+ showToolbar = true,
258
+ minHeight = 80
259
+ }) {
260
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
261
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: label }),
262
+ /* @__PURE__ */ jsx(
263
+ Editor,
264
+ {
265
+ profile: "documentation",
266
+ initialContent: value ?? emptyDoc,
267
+ onChange,
268
+ debounceMs: 150,
269
+ showToolbar,
270
+ editorClassName: RICH_TEXT_MIN_HEIGHT[minHeight]
271
+ }
233
272
  )
234
273
  ] });
235
274
  }
275
+ var TITLE_SIZE_FIELDS = [
276
+ { key: "mobile", label: "Phone" },
277
+ { key: "tablet", label: "Tablet" },
278
+ { key: "desktop", label: "Desktop" }
279
+ ];
280
+ function TitleLevelField({
281
+ settings,
282
+ defaultLevel = "h2",
283
+ onChange
284
+ }) {
285
+ return /* @__PURE__ */ jsx(
286
+ SelectField,
287
+ {
288
+ label: "Title heading level",
289
+ value: settings.titleLevel ?? defaultLevel,
290
+ onChange: (titleLevel) => onChange({ titleLevel }),
291
+ options: [
292
+ { label: "H1 \u2014 the page's main heading", value: "h1" },
293
+ { label: "H2 \u2014 section heading", value: "h2" },
294
+ { label: "H3 \u2014 sub-section heading", value: "h3" }
295
+ ]
296
+ }
297
+ );
298
+ }
299
+ function TitleSizeField({
300
+ settings,
301
+ onChange
302
+ }) {
303
+ const size = settings.titleSize ?? {};
304
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 text-sm", children: [
305
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground", children: "Title size (px)" }),
306
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2", children: TITLE_SIZE_FIELDS.map(({ key, label }) => /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 flex-col gap-1", children: [
307
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: label }),
308
+ /* @__PURE__ */ jsx(
309
+ "input",
310
+ {
311
+ type: "number",
312
+ min: 8,
313
+ max: 200,
314
+ placeholder: "Theme",
315
+ className: "h-9 min-w-0 rounded-lg border border-input bg-muted/20 px-2 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground/70 focus:border-ring focus:bg-background focus:ring-2 focus:ring-ring/20",
316
+ value: size[key] ?? "",
317
+ onChange: (e) => onChange({
318
+ titleSize: {
319
+ ...size,
320
+ [key]: e.target.value ? Number(e.target.value) : void 0
321
+ }
322
+ })
323
+ }
324
+ )
325
+ ] }, key)) })
326
+ ] });
327
+ }
236
328
  function NumberField({
237
329
  label,
238
330
  value,
@@ -345,28 +437,33 @@ function ToggleField({
345
437
  value,
346
438
  onChange
347
439
  }) {
348
- return /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center justify-between gap-3 rounded-lg border border-border/80 bg-muted/20 px-3 py-2.5 text-sm transition-colors hover:bg-muted/50", children: [
349
- /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground", children: label }),
350
- /* @__PURE__ */ jsx(
351
- "input",
352
- {
353
- type: "checkbox",
354
- className: "peer sr-only",
355
- checked: Boolean(value),
356
- onChange: (e) => onChange(e.target.checked)
357
- }
358
- ),
359
- /* @__PURE__ */ jsx(
360
- "span",
361
- {
362
- "aria-hidden": "true",
363
- className: cn(
364
- "relative h-5 w-9 shrink-0 rounded-full bg-muted-foreground/25 transition-colors after:absolute after:left-0.5 after:top-0.5 after:h-4 after:w-4 after:rounded-full after:bg-background after:shadow-sm after:transition-transform peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2",
365
- value && "bg-primary after:translate-x-4"
366
- )
367
- }
368
- )
369
- ] });
440
+ return (
441
+ // `relative` anchors the sr-only checkbox here. Without it the checkbox
442
+ // is positioned against an ancestor outside the settings panel, and
443
+ // focusing it scrolls the whole builder out of place.
444
+ /* @__PURE__ */ jsxs("label", { className: "relative flex cursor-pointer items-center justify-between gap-3 rounded-lg border border-border/80 bg-muted/20 px-3 py-2.5 text-sm transition-colors hover:bg-muted/50", children: [
445
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground", children: label }),
446
+ /* @__PURE__ */ jsx(
447
+ "input",
448
+ {
449
+ type: "checkbox",
450
+ className: "peer sr-only",
451
+ checked: Boolean(value),
452
+ onChange: (e) => onChange(e.target.checked)
453
+ }
454
+ ),
455
+ /* @__PURE__ */ jsx(
456
+ "span",
457
+ {
458
+ "aria-hidden": "true",
459
+ className: cn(
460
+ "relative h-5 w-9 shrink-0 rounded-full bg-muted-foreground/25 transition-colors after:absolute after:left-0.5 after:top-0.5 after:h-4 after:w-4 after:rounded-full after:bg-background after:shadow-sm after:transition-transform peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2",
461
+ value && "bg-primary after:translate-x-4"
462
+ )
463
+ }
464
+ )
465
+ ] })
466
+ );
370
467
  }
371
468
  function ListField({
372
469
  label,
@@ -434,14 +531,7 @@ function ImageField({
434
531
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
435
532
  /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground", children: label }),
436
533
  imageUrl ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
437
- /* @__PURE__ */ jsx("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg border border-border bg-muted/40", children: /* @__PURE__ */ jsx(
438
- "img",
439
- {
440
- src: imageUrl,
441
- alt: "Preview",
442
- className: "h-full w-full object-cover"
443
- }
444
- ) }),
534
+ /* @__PURE__ */ jsx("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg border border-border bg-muted/40", children: /* @__PURE__ */ jsx("img", { src: imageUrl, alt: "Preview", className: "h-full w-full object-cover" }) }),
445
535
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
446
536
  /* @__PURE__ */ jsx(
447
537
  ImageUploadDialog,
@@ -544,24 +634,6 @@ function HeaderEditor({
544
634
  }) {
545
635
  const update = (partial) => onChange({ ...settings, ...partial });
546
636
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
547
- /* @__PURE__ */ jsxs(FieldGroup, { title: "Logo", children: [
548
- /* @__PURE__ */ jsx(
549
- TextField,
550
- {
551
- label: "Logo text",
552
- value: settings.logoText,
553
- onChange: (logoText) => update({ logoText })
554
- }
555
- ),
556
- /* @__PURE__ */ jsx(
557
- ImageField,
558
- {
559
- label: "Logo image",
560
- value: settings.logoImage ? typeof settings.logoImage === "string" ? { url: settings.logoImage, file: settings.logoImage } : settings.logoImage : void 0,
561
- onChange: (media) => update({ logoImage: getMediaUrl(media) || void 0 })
562
- }
563
- )
564
- ] }),
565
637
  /* @__PURE__ */ jsx(FieldGroup, { title: "Navigation links", children: /* @__PURE__ */ jsx(
566
638
  ListField,
567
639
  {
@@ -650,14 +722,6 @@ function HeaderEditor({
650
722
  value: settings.backdropBlur,
651
723
  onChange: (backdropBlur) => update({ backdropBlur })
652
724
  }
653
- ),
654
- /* @__PURE__ */ jsx(
655
- ToggleField,
656
- {
657
- label: "Color mode switcher",
658
- value: settings.showThemeSwitcher !== false,
659
- onChange: (showThemeSwitcher) => update({ showThemeSwitcher })
660
- }
661
725
  )
662
726
  ] })
663
727
  ] });
@@ -667,7 +731,7 @@ function HeaderDesignEditor({
667
731
  onChange
668
732
  }) {
669
733
  const update = (partial) => onChange({ ...settings, ...partial });
670
- const logoCorners = settings.logoCorners ?? settings.logoRadius ?? 2;
734
+ const logoCorners = settings.logoCorners ?? 2;
671
735
  return /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: /* @__PURE__ */ jsx(FieldGroup, { title: "Logo styling", children: /* @__PURE__ */ jsx(
672
736
  SliderField,
673
737
  {
@@ -686,7 +750,6 @@ function HeaderDesignEditor({
686
750
 
687
751
  // src/blocks/header/defaults.ts
688
752
  var headerDefaults = {
689
- logoText: "FrontLit",
690
753
  logoCorners: 2,
691
754
  links: [
692
755
  { id: generateUniqueId(), label: "Features", href: "/#features" },
@@ -699,7 +762,6 @@ var headerDefaults = {
699
762
  linkAlignment: "left",
700
763
  layout: "fixed",
701
764
  backdropBlur: false,
702
- showThemeSwitcher: true,
703
765
  // Slider value 1. Keeps a new header compact instead of inheriting the
704
766
  // theme's content-section padding (`py-12` / slider 5 on most themes).
705
767
  verticalPadding: "py-4"
@@ -726,6 +788,38 @@ var heroMetadata = {
726
788
  description: "A large introductory section with a title, copy and CTAs.",
727
789
  compatibleWith: ["site", "landing", "blog", "post", "custom"]
728
790
  };
791
+ function titleProps({
792
+ titleLevel,
793
+ titleSize
794
+ }, defaultLevel = "h2", baseSizeClassName) {
795
+ const { mobile, tablet, desktop } = titleSize ?? {};
796
+ const size = (value) => value ? `${value}px` : "var(--pb-theme-size, 1em)";
797
+ return {
798
+ as: titleLevel ?? defaultLevel,
799
+ sizeClassName: cn(
800
+ baseSizeClassName,
801
+ mobile && "text-[length:var(--pb-title-mobile)]",
802
+ (mobile || tablet) && "md:text-[length:var(--pb-title-tablet)]",
803
+ (tablet || desktop) && "lg:text-[length:var(--pb-title-desktop)]"
804
+ ),
805
+ style: {
806
+ "--pb-title-mobile": mobile ? size(mobile) : void 0,
807
+ "--pb-title-tablet": mobile || tablet ? size(tablet) : void 0,
808
+ "--pb-title-desktop": tablet || desktop ? size(desktop) : void 0
809
+ }
810
+ };
811
+ }
812
+ var HIGHLIGHT_CLASSES = {
813
+ color: "text-primary",
814
+ marker: "bg-primary px-[0.15em] text-primary-foreground [box-decoration-break:clone]"
815
+ };
816
+ function renderTitle(title, theme) {
817
+ if (!title?.includes("*")) return title;
818
+ const className = HIGHLIGHT_CLASSES[theme?.highlight ?? "color"];
819
+ return title.split(/(\*[^*]+\*)/).map(
820
+ (part, index) => /^\*[^*]+\*$/.test(part) ? React2.createElement("span", { key: index, className }, part.slice(1, -1)) : part
821
+ );
822
+ }
729
823
  var roundedMap = {
730
824
  0: "rounded-none",
731
825
  1: "rounded-sm",
@@ -751,14 +845,17 @@ function HeroWidget({
751
845
  contentAlignment = "left",
752
846
  secondaryButtonAction,
753
847
  secondaryButtonCaption,
848
+ smallPrint,
849
+ command,
850
+ titleLevel,
851
+ titleSize,
754
852
  cssId,
755
853
  maxWidth,
756
854
  verticalPadding,
757
855
  background,
758
856
  layout = "normal"
759
857
  },
760
- state: { theme },
761
- nextTheme
858
+ state: { theme }
762
859
  }) {
763
860
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
764
861
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
@@ -783,7 +880,8 @@ function HeroWidget({
783
880
  {
784
881
  src: mediaUrl || "",
785
882
  alt: getMediaAlt(media),
786
- borderRadius: mediaRadius
883
+ borderRadius: mediaRadius,
884
+ priority: true
787
885
  }
788
886
  )
789
887
  }
@@ -797,7 +895,7 @@ function HeroWidget({
797
895
  ),
798
896
  children: [
799
897
  preTitle && /* @__PURE__ */ jsx(Preheader, { theme: overriddenTheme, className: "text-muted-foreground", children: preTitle }),
800
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
898
+ /* @__PURE__ */ jsx(Display, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }, "h1"), children: renderTitle(title, overriddenTheme) }),
801
899
  description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) }),
802
900
  /* @__PURE__ */ jsxs(
803
901
  "div",
@@ -819,7 +917,17 @@ function HeroWidget({
819
917
  ) })
820
918
  ]
821
919
  }
822
- )
920
+ ),
921
+ command && /* @__PURE__ */ jsx(
922
+ CodeSnippet,
923
+ {
924
+ code: command,
925
+ prompt: "$",
926
+ theme: overriddenTheme,
927
+ className: "max-w-xl"
928
+ }
929
+ ),
930
+ smallPrint && /* @__PURE__ */ jsx(Caption, { theme: overriddenTheme, children: smallPrint })
823
931
  ]
824
932
  }
825
933
  );
@@ -837,16 +945,7 @@ function HeroWidget({
837
945
  /* @__PURE__ */ jsx("div", { className: `w-full ${hasHeroGraphic ? "md:w-1/2" : ""}`, children: textContent })
838
946
  ] });
839
947
  }
840
- return /* @__PURE__ */ jsx(
841
- Section,
842
- {
843
- theme: overriddenTheme,
844
- id: cssId,
845
- background,
846
- nextTheme,
847
- children: layout === "card" ? /* @__PURE__ */ jsx(PageCard, { theme: overriddenTheme, children: /* @__PURE__ */ jsx(PageCardContent, { theme: overriddenTheme, children: mainContent }) }) : mainContent
848
- }
849
- );
948
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: layout === "card" ? /* @__PURE__ */ jsx(PageCard, { theme: overriddenTheme, children: /* @__PURE__ */ jsx(PageCardContent, { theme: overriddenTheme, children: mainContent }) }) : mainContent });
850
949
  }
851
950
  function HeroEditor({ settings, onChange }) {
852
951
  const update = (partial) => onChange({ ...settings, ...partial });
@@ -865,22 +964,22 @@ function HeroEditor({ settings, onChange }) {
865
964
  TextField,
866
965
  {
867
966
  label: "Title",
967
+ hint: "Wrap words in *asterisks* to highlight them.",
868
968
  value: settings.title,
869
969
  onChange: (title) => update({ title })
870
970
  }
871
971
  ),
872
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
873
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
874
- /* @__PURE__ */ jsx(
875
- Editor,
876
- {
877
- initialContent: settings.description ?? emptyDoc,
878
- onChange: (description) => update({ description }),
879
- showToolbar: false,
880
- editorClassName: "min-h-[100px]"
881
- }
882
- )
883
- ] })
972
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, defaultLevel: "h1", onChange: update }),
973
+ /* @__PURE__ */ jsx(
974
+ RichTextField,
975
+ {
976
+ label: "Description",
977
+ value: settings.description,
978
+ onChange: (description) => update({ description }),
979
+ showToolbar: false,
980
+ minHeight: 100
981
+ }
982
+ )
884
983
  ] }),
885
984
  /* @__PURE__ */ jsxs(FieldGroup, { title: "Media", children: [
886
985
  /* @__PURE__ */ jsx(
@@ -933,6 +1032,24 @@ function HeroEditor({ settings, onChange }) {
933
1032
  value: settings.secondaryButtonAction,
934
1033
  onChange: (secondaryButtonAction) => update({ secondaryButtonAction })
935
1034
  }
1035
+ ),
1036
+ /* @__PURE__ */ jsx(
1037
+ TextField,
1038
+ {
1039
+ label: "Install command",
1040
+ value: settings.command,
1041
+ placeholder: "e.g. curl -fsSL https://example.com/install.sh | sh",
1042
+ onChange: (command) => update({ command })
1043
+ }
1044
+ ),
1045
+ /* @__PURE__ */ jsx(
1046
+ TextField,
1047
+ {
1048
+ label: "Small print",
1049
+ value: settings.smallPrint,
1050
+ placeholder: "e.g. No credit card required",
1051
+ onChange: (smallPrint) => update({ smallPrint })
1052
+ }
936
1053
  )
937
1054
  ] }),
938
1055
  /* @__PURE__ */ jsxs(FieldGroup, { title: "Layout", children: [
@@ -982,6 +1099,7 @@ var Hero = {
982
1099
  metadata: heroMetadata,
983
1100
  widget: HeroWidget,
984
1101
  editor: HeroEditor,
1102
+ titleSize: true,
985
1103
  getDefaultSettings: () => heroDefaults,
986
1104
  layouts: [
987
1105
  { id: "normal", name: "Standard" },
@@ -1012,6 +1130,8 @@ var roundedMap2 = {
1012
1130
  function ContentWidget({
1013
1131
  settings: {
1014
1132
  title,
1133
+ titleLevel,
1134
+ titleSize,
1015
1135
  body,
1016
1136
  media,
1017
1137
  alignment = "left",
@@ -1023,8 +1143,7 @@ function ContentWidget({
1023
1143
  verticalPadding,
1024
1144
  background
1025
1145
  },
1026
- state: { theme },
1027
- nextTheme
1146
+ state: { theme }
1028
1147
  }) {
1029
1148
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
1030
1149
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
@@ -1036,81 +1155,70 @@ function ContentWidget({
1036
1155
  const direction = alignment === "right" ? "md:!flex-row-reverse" : "md:!flex-row";
1037
1156
  if (layout === "overlay") {
1038
1157
  const textPosition = alignment === "right" ? "items-end text-right" : "items-start text-left";
1039
- return /* @__PURE__ */ jsx(
1040
- Section,
1158
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "relative min-h-[420px] w-full overflow-hidden rounded-xl", children: [
1159
+ hasMedia && /* @__PURE__ */ jsx(
1160
+ Image,
1161
+ {
1162
+ src: mediaUrl || "",
1163
+ alt: mediaAlt,
1164
+ width: "w-full",
1165
+ height: "h-full",
1166
+ className: "absolute inset-0",
1167
+ borderRadius: 0
1168
+ }
1169
+ ),
1170
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent" }),
1171
+ /* @__PURE__ */ jsx(
1172
+ "div",
1173
+ {
1174
+ className: clsx3(
1175
+ "relative flex h-full flex-col justify-end gap-4 p-6 md:p-10",
1176
+ textPosition
1177
+ ),
1178
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-lg text-white", children: [
1179
+ title && /* @__PURE__ */ jsx(
1180
+ Header2,
1181
+ {
1182
+ theme: overriddenTheme,
1183
+ ...titleProps({ titleLevel, titleSize }),
1184
+ children: renderTitle(title, overriddenTheme)
1185
+ }
1186
+ ),
1187
+ body && /* @__PURE__ */ jsx(TextRenderer, { json: body, theme: overriddenTheme })
1188
+ ] })
1189
+ }
1190
+ )
1191
+ ] }) });
1192
+ }
1193
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: clsx3("flex flex-col gap-8", sideBySide && direction), children: [
1194
+ hasMedia && /* @__PURE__ */ jsx("div", { className: clsx3("flex w-full items-center", sideBySide && "md:w-1/2"), children: /* @__PURE__ */ jsx(
1195
+ "div",
1041
1196
  {
1042
- theme: overriddenTheme,
1043
- id: cssId,
1044
- background,
1045
- nextTheme,
1046
- children: /* @__PURE__ */ jsxs("div", { className: "relative min-h-[420px] w-full overflow-hidden rounded-xl", children: [
1047
- hasMedia && /* @__PURE__ */ jsx(
1048
- Image,
1197
+ className: `w-full overflow-hidden ${roundedMap2[mediaRadius] ?? "rounded-md"}`,
1198
+ children: /* @__PURE__ */ jsx(Image, { src: mediaUrl || "", alt: mediaAlt, borderRadius: mediaRadius })
1199
+ }
1200
+ ) }),
1201
+ /* @__PURE__ */ jsx("div", { className: clsx3("w-full", hasMedia && sideBySide && "md:w-1/2"), children: /* @__PURE__ */ jsxs(
1202
+ "div",
1203
+ {
1204
+ className: clsx3(
1205
+ "flex h-full flex-col justify-center gap-4",
1206
+ headerAlignment === "center" ? "items-center text-center" : "items-start"
1207
+ ),
1208
+ children: [
1209
+ title && /* @__PURE__ */ jsx(
1210
+ Header2,
1049
1211
  {
1050
- src: mediaUrl || "",
1051
- alt: mediaAlt,
1052
- width: "w-full",
1053
- height: "h-full",
1054
- className: "absolute inset-0",
1055
- borderRadius: 0
1212
+ theme: overriddenTheme,
1213
+ ...titleProps({ titleLevel, titleSize }),
1214
+ children: renderTitle(title, overriddenTheme)
1056
1215
  }
1057
1216
  ),
1058
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent" }),
1059
- /* @__PURE__ */ jsx(
1060
- "div",
1061
- {
1062
- className: clsx3(
1063
- "relative flex h-full flex-col justify-end gap-4 p-6 md:p-10",
1064
- textPosition
1065
- ),
1066
- children: /* @__PURE__ */ jsxs("div", { className: "max-w-lg text-white", children: [
1067
- title && /* @__PURE__ */ jsx(Header2, { theme: overriddenTheme, children: title }),
1068
- body && /* @__PURE__ */ jsx(TextRenderer, { json: body, theme: overriddenTheme })
1069
- ] })
1070
- }
1071
- )
1072
- ] })
1217
+ body && /* @__PURE__ */ jsx(TextRenderer, { json: body, theme: overriddenTheme })
1218
+ ]
1073
1219
  }
1074
- );
1075
- }
1076
- return /* @__PURE__ */ jsx(
1077
- Section,
1078
- {
1079
- theme: overriddenTheme,
1080
- id: cssId,
1081
- background,
1082
- nextTheme,
1083
- children: /* @__PURE__ */ jsxs("div", { className: clsx3("flex flex-col gap-8", sideBySide && direction), children: [
1084
- hasMedia && /* @__PURE__ */ jsx("div", { className: clsx3("flex w-full items-center", sideBySide && "md:w-1/2"), children: /* @__PURE__ */ jsx(
1085
- "div",
1086
- {
1087
- className: `w-full overflow-hidden ${roundedMap2[mediaRadius] ?? "rounded-md"}`,
1088
- children: /* @__PURE__ */ jsx(
1089
- Image,
1090
- {
1091
- src: mediaUrl || "",
1092
- alt: mediaAlt,
1093
- borderRadius: mediaRadius
1094
- }
1095
- )
1096
- }
1097
- ) }),
1098
- /* @__PURE__ */ jsx("div", { className: clsx3("w-full", hasMedia && sideBySide && "md:w-1/2"), children: /* @__PURE__ */ jsxs(
1099
- "div",
1100
- {
1101
- className: clsx3(
1102
- "flex h-full flex-col justify-center gap-4",
1103
- headerAlignment === "center" ? "items-center text-center" : "items-start"
1104
- ),
1105
- children: [
1106
- title && /* @__PURE__ */ jsx(Header2, { theme: overriddenTheme, children: title }),
1107
- body && /* @__PURE__ */ jsx(TextRenderer, { json: body, theme: overriddenTheme })
1108
- ]
1109
- }
1110
- ) })
1111
- ] })
1112
- }
1113
- );
1220
+ ) })
1221
+ ] }) });
1114
1222
  }
1115
1223
  function ContentEditor({
1116
1224
  settings,
@@ -1123,21 +1231,21 @@ function ContentEditor({
1123
1231
  TextField,
1124
1232
  {
1125
1233
  label: "Title",
1234
+ hint: "Wrap words in *asterisks* to highlight them.",
1126
1235
  value: settings.title,
1127
1236
  onChange: (title) => update({ title })
1128
1237
  }
1129
1238
  ),
1130
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
1131
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Body" }),
1132
- /* @__PURE__ */ jsx(
1133
- Editor,
1134
- {
1135
- initialContent: settings.body ?? emptyDoc,
1136
- onChange: (body) => update({ body }),
1137
- editorClassName: "min-h-[160px]"
1138
- }
1139
- )
1140
- ] })
1239
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
1240
+ /* @__PURE__ */ jsx(
1241
+ RichTextField,
1242
+ {
1243
+ label: "Body",
1244
+ value: settings.body,
1245
+ onChange: (body) => update({ body }),
1246
+ minHeight: 160
1247
+ }
1248
+ )
1141
1249
  ] }),
1142
1250
  /* @__PURE__ */ jsxs(FieldGroup, { title: "Media", children: [
1143
1251
  /* @__PURE__ */ jsx(
@@ -1215,6 +1323,7 @@ var Content = {
1215
1323
  metadata: contentMetadata,
1216
1324
  widget: ContentWidget,
1217
1325
  editor: ContentEditor,
1326
+ titleSize: true,
1218
1327
  getDefaultSettings: () => contentDefaults,
1219
1328
  layouts: [
1220
1329
  { id: "side", name: "Media beside" },
@@ -1238,6 +1347,8 @@ function resolveIcon(name) {
1238
1347
  function FeaturedWidget({
1239
1348
  settings: {
1240
1349
  title,
1350
+ titleLevel,
1351
+ titleSize,
1241
1352
  description,
1242
1353
  headerAlignment = "center",
1243
1354
  items,
@@ -1247,90 +1358,80 @@ function FeaturedWidget({
1247
1358
  verticalPadding,
1248
1359
  background
1249
1360
  },
1250
- state: { theme },
1251
- nextTheme
1361
+ state: { theme }
1252
1362
  }) {
1253
1363
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
1254
1364
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
1255
1365
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
1256
- return /* @__PURE__ */ jsx(
1257
- Section,
1258
- {
1259
- theme: overriddenTheme,
1260
- id: cssId,
1261
- background,
1262
- nextTheme,
1263
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
1264
- /* @__PURE__ */ jsxs(
1265
- "div",
1266
- {
1267
- className: clsx3(
1268
- "flex flex-col gap-4",
1269
- headerAlignment === "center" ? "items-center text-center" : "items-start"
1270
- ),
1271
- children: [
1272
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
1273
- description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
1274
- ]
1275
- }
1366
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
1367
+ /* @__PURE__ */ jsxs(
1368
+ "div",
1369
+ {
1370
+ className: clsx3(
1371
+ "flex flex-col gap-4",
1372
+ headerAlignment === "center" ? "items-center text-center" : "items-start"
1276
1373
  ),
1277
- items && items.length > 0 && layout === "numbered" && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8", children: items.map((item, index) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1278
- /* @__PURE__ */ jsx("span", { className: "text-3xl font-bold text-primary/30", children: String(index + 1).padStart(2, "0") }),
1279
- /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, children: item.title }),
1280
- item.description && /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: item.description })
1281
- ] }, index)) }),
1282
- items && items.length > 0 && layout !== "numbered" && /* @__PURE__ */ jsx(
1283
- "div",
1284
- {
1285
- className: clsx3(
1286
- layout === "list" && "flex flex-col gap-4",
1287
- layout === "compact" && "grid grid-cols-2 md:grid-cols-4 gap-4 items-stretch",
1288
- layout !== "list" && layout !== "compact" && "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 items-stretch"
1289
- ),
1290
- children: items.map((item, index) => {
1291
- const Icon = resolveIcon(item.icon);
1292
- return /* @__PURE__ */ jsx(PageCard, { theme: overriddenTheme, children: /* @__PURE__ */ jsxs(
1293
- PageCardContent,
1294
- {
1295
- theme: overriddenTheme,
1296
- className: clsx3(
1297
- "h-full flex gap-3",
1298
- layout === "list" ? "flex-row items-start" : "flex-col",
1299
- layout === "compact" && "items-center text-center gap-2"
1300
- ),
1301
- children: [
1302
- /* @__PURE__ */ jsx(
1303
- "div",
1304
- {
1305
- className: clsx3(
1306
- "flex shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary",
1307
- layout === "compact" ? "h-8 w-8" : "h-10 w-10"
1308
- ),
1309
- children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5" })
1310
- }
1374
+ children: [
1375
+ /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) }),
1376
+ description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
1377
+ ]
1378
+ }
1379
+ ),
1380
+ items && items.length > 0 && layout === "numbered" && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8", children: items.map((item, index) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1381
+ /* @__PURE__ */ jsx("span", { className: "text-3xl font-bold text-primary/30", children: String(index + 1).padStart(2, "0") }),
1382
+ /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, children: item.title }),
1383
+ item.description && /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: item.description })
1384
+ ] }, index)) }),
1385
+ items && items.length > 0 && layout !== "numbered" && /* @__PURE__ */ jsx(
1386
+ "div",
1387
+ {
1388
+ className: clsx3(
1389
+ layout === "list" && "flex flex-col gap-4",
1390
+ layout === "compact" && "grid grid-cols-2 md:grid-cols-4 gap-4 items-stretch",
1391
+ layout !== "list" && layout !== "compact" && "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 items-stretch"
1392
+ ),
1393
+ children: items.map((item, index) => {
1394
+ const Icon = resolveIcon(item.icon);
1395
+ return /* @__PURE__ */ jsx(PageCard, { theme: overriddenTheme, children: /* @__PURE__ */ jsxs(
1396
+ PageCardContent,
1397
+ {
1398
+ theme: overriddenTheme,
1399
+ className: clsx3(
1400
+ "h-full flex gap-3",
1401
+ layout === "list" ? "flex-row items-start" : "flex-col",
1402
+ layout === "compact" && "items-center text-center gap-2"
1403
+ ),
1404
+ children: [
1405
+ /* @__PURE__ */ jsx(
1406
+ "div",
1407
+ {
1408
+ className: clsx3(
1409
+ "flex shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary",
1410
+ layout === "compact" ? "h-8 w-8" : "h-10 w-10"
1311
1411
  ),
1312
- /* @__PURE__ */ jsxs(
1313
- "div",
1314
- {
1315
- className: clsx3(
1316
- "flex flex-col gap-2",
1317
- layout === "compact" && "items-center gap-1"
1318
- ),
1319
- children: [
1320
- /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, children: item.title }),
1321
- item.description && layout !== "compact" && /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: item.description })
1322
- ]
1323
- }
1324
- )
1325
- ]
1326
- }
1327
- ) }, index);
1328
- })
1329
- }
1330
- )
1331
- ] })
1332
- }
1333
- );
1412
+ children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5" })
1413
+ }
1414
+ ),
1415
+ /* @__PURE__ */ jsxs(
1416
+ "div",
1417
+ {
1418
+ className: clsx3(
1419
+ "flex flex-col gap-2",
1420
+ layout === "compact" && "items-center gap-1"
1421
+ ),
1422
+ children: [
1423
+ /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, children: item.title }),
1424
+ item.description && layout !== "compact" && /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: item.description })
1425
+ ]
1426
+ }
1427
+ )
1428
+ ]
1429
+ }
1430
+ ) }, index);
1431
+ })
1432
+ }
1433
+ )
1434
+ ] }) });
1334
1435
  }
1335
1436
  var createItem = () => ({
1336
1437
  title: "New feature",
@@ -1348,22 +1449,22 @@ function FeaturedEditor({
1348
1449
  TextField,
1349
1450
  {
1350
1451
  label: "Title",
1452
+ hint: "Wrap words in *asterisks* to highlight them.",
1351
1453
  value: settings.title,
1352
1454
  onChange: (title) => update({ title })
1353
1455
  }
1354
1456
  ),
1355
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
1356
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
1357
- /* @__PURE__ */ jsx(
1358
- Editor,
1359
- {
1360
- initialContent: settings.description ?? emptyDoc,
1361
- onChange: (description) => update({ description }),
1362
- showToolbar: false,
1363
- editorClassName: "min-h-[80px]"
1364
- }
1365
- )
1366
- ] }),
1457
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
1458
+ /* @__PURE__ */ jsx(
1459
+ RichTextField,
1460
+ {
1461
+ label: "Description",
1462
+ value: settings.description,
1463
+ onChange: (description) => update({ description }),
1464
+ showToolbar: false,
1465
+ minHeight: 80
1466
+ }
1467
+ ),
1367
1468
  /* @__PURE__ */ jsx(
1368
1469
  SelectField,
1369
1470
  {
@@ -1460,6 +1561,7 @@ var Featured = {
1460
1561
  metadata: featuredMetadata,
1461
1562
  widget: FeaturedWidget,
1462
1563
  editor: FeaturedEditor,
1564
+ titleSize: true,
1463
1565
  getDefaultSettings: () => featuredDefaults,
1464
1566
  layouts: [
1465
1567
  { id: "grid", name: "Grid" },
@@ -1479,6 +1581,8 @@ var faqMetadata = {
1479
1581
  function FaqWidget({
1480
1582
  settings: {
1481
1583
  title,
1584
+ titleLevel,
1585
+ titleSize,
1482
1586
  headerAlignment = "left",
1483
1587
  items = [],
1484
1588
  layout = "list",
@@ -1487,88 +1591,61 @@ function FaqWidget({
1487
1591
  verticalPadding,
1488
1592
  background
1489
1593
  },
1490
- state: { theme },
1491
- nextTheme
1594
+ state: { theme }
1492
1595
  }) {
1493
1596
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
1494
1597
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
1495
1598
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
1496
- const [expandedIndex, setExpandedIndex] = useState(
1497
- items.length > 0 ? 0 : null
1498
- );
1499
- return /* @__PURE__ */ jsx(
1500
- Section,
1501
- {
1502
- theme: overriddenTheme,
1503
- id: cssId,
1504
- background,
1505
- nextTheme,
1506
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
1507
- title && /* @__PURE__ */ jsx(
1508
- "div",
1509
- {
1510
- className: clsx3(
1511
- "flex flex-col",
1512
- headerAlignment === "center" ? "items-center text-center" : "items-start"
1513
- ),
1514
- children: /* @__PURE__ */ jsx(Header2, { theme: overriddenTheme, children: title })
1515
- }
1599
+ const groupName = useId();
1600
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
1601
+ title && /* @__PURE__ */ jsx(
1602
+ "div",
1603
+ {
1604
+ className: clsx3(
1605
+ "flex flex-col",
1606
+ headerAlignment === "center" ? "items-center text-center" : "items-start"
1516
1607
  ),
1517
- items.length > 0 && (() => {
1518
- const renderItem = (item, index) => {
1519
- const isOpen = expandedIndex === index;
1520
- return /* @__PURE__ */ jsxs(
1521
- "div",
1522
- {
1523
- className: layout === "cards" ? "rounded-lg border border-border bg-card px-4 py-4" : layout === "columns" ? "border-b border-border py-4" : "py-4",
1524
- children: [
1525
- /* @__PURE__ */ jsxs(
1526
- "button",
1527
- {
1528
- type: "button",
1529
- className: "flex w-full items-center justify-between gap-4 text-left",
1530
- onClick: () => setExpandedIndex(isOpen ? null : index),
1531
- "aria-expanded": isOpen,
1532
- children: [
1533
- /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, className: "font-medium", children: item.question }),
1534
- /* @__PURE__ */ jsx(
1535
- ChevronDown,
1536
- {
1537
- className: clsx3(
1538
- "h-4 w-4 shrink-0 transition-transform",
1539
- isOpen && "rotate-180"
1540
- )
1541
- }
1542
- )
1543
- ]
1544
- }
1545
- ),
1546
- isOpen && /* @__PURE__ */ jsx("div", { className: "pt-3", children: /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, className: "text-muted-foreground", children: item.answer }) })
1547
- ]
1548
- },
1549
- item.id
1550
- );
1551
- };
1552
- if (layout === "columns") {
1553
- const half = Math.ceil(items.length / 2);
1554
- const left = items.slice(0, half);
1555
- const right = items.slice(half);
1556
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-x-10 md:grid-cols-2", children: [
1557
- /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: left.map((item, i) => renderItem(item, i)) }),
1558
- /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: right.map((item, i) => renderItem(item, half + i)) })
1559
- ] });
1560
- }
1561
- return /* @__PURE__ */ jsx(
1562
- "div",
1563
- {
1564
- className: layout === "cards" ? "flex flex-col gap-3" : "flex flex-col divide-y divide-border border-b border-t border-border",
1565
- children: items.map((item, index) => renderItem(item, index))
1566
- }
1567
- );
1568
- })()
1569
- ] })
1570
- }
1571
- );
1608
+ children: /* @__PURE__ */ jsx(Header2, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) })
1609
+ }
1610
+ ),
1611
+ items.length > 0 && (() => {
1612
+ const renderItem = (item, index) => /* @__PURE__ */ jsxs(
1613
+ "details",
1614
+ {
1615
+ name: groupName,
1616
+ open: index === 0,
1617
+ className: clsx3(
1618
+ "group",
1619
+ layout === "cards" ? "rounded-lg border border-border bg-card px-4 py-4" : layout === "columns" ? "border-b border-border py-4" : "py-4"
1620
+ ),
1621
+ children: [
1622
+ /* @__PURE__ */ jsxs("summary", { className: "flex w-full cursor-pointer list-none items-center justify-between gap-4 text-left [&::-webkit-details-marker]:hidden", children: [
1623
+ /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, className: "font-medium", children: item.question }),
1624
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 transition-transform group-open:rotate-180" })
1625
+ ] }),
1626
+ /* @__PURE__ */ jsx("div", { className: "pt-3", children: /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, className: "text-muted-foreground", children: item.answer }) })
1627
+ ]
1628
+ },
1629
+ item.id
1630
+ );
1631
+ if (layout === "columns") {
1632
+ const half = Math.ceil(items.length / 2);
1633
+ const left = items.slice(0, half);
1634
+ const right = items.slice(half);
1635
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-x-10 md:grid-cols-2", children: [
1636
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: left.map((item, i) => renderItem(item, i)) }),
1637
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: right.map((item, i) => renderItem(item, half + i)) })
1638
+ ] });
1639
+ }
1640
+ return /* @__PURE__ */ jsx(
1641
+ "div",
1642
+ {
1643
+ className: layout === "cards" ? "flex flex-col gap-3" : "flex flex-col divide-y divide-border border-b border-t border-border",
1644
+ children: items.map((item, index) => renderItem(item, index))
1645
+ }
1646
+ );
1647
+ })()
1648
+ ] }) });
1572
1649
  }
1573
1650
  function FaqEditor({ settings, onChange }) {
1574
1651
  const update = (partial) => onChange({ ...settings, ...partial });
@@ -1578,10 +1655,12 @@ function FaqEditor({ settings, onChange }) {
1578
1655
  TextField,
1579
1656
  {
1580
1657
  label: "Title",
1658
+ hint: "Wrap words in *asterisks* to highlight them.",
1581
1659
  value: settings.title,
1582
1660
  onChange: (title) => update({ title })
1583
1661
  }
1584
1662
  ),
1663
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
1585
1664
  /* @__PURE__ */ jsx(
1586
1665
  SelectField,
1587
1666
  {
@@ -1673,6 +1752,7 @@ var Faq = {
1673
1752
  metadata: faqMetadata,
1674
1753
  widget: FaqWidget,
1675
1754
  editor: FaqEditor,
1755
+ titleSize: true,
1676
1756
  getDefaultSettings: () => faqDefaults,
1677
1757
  layouts: [
1678
1758
  { id: "list", name: "List" },
@@ -1691,6 +1771,8 @@ var pricingMetadata = {
1691
1771
  function PricingWidget({
1692
1772
  settings: {
1693
1773
  title,
1774
+ titleLevel,
1775
+ titleSize,
1694
1776
  description,
1695
1777
  headerAlignment = "center",
1696
1778
  tiers,
@@ -1700,78 +1782,68 @@ function PricingWidget({
1700
1782
  verticalPadding,
1701
1783
  background
1702
1784
  },
1703
- state: { theme },
1704
- nextTheme
1785
+ state: { theme }
1705
1786
  }) {
1706
1787
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
1707
1788
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
1708
1789
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
1709
- return /* @__PURE__ */ jsx(
1710
- Section,
1711
- {
1712
- theme: overriddenTheme,
1713
- id: cssId,
1714
- background,
1715
- nextTheme,
1716
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
1717
- /* @__PURE__ */ jsxs(
1718
- "div",
1790
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
1791
+ /* @__PURE__ */ jsxs(
1792
+ "div",
1793
+ {
1794
+ className: clsx3(
1795
+ "flex flex-col gap-4",
1796
+ headerAlignment === "center" ? "items-center text-center" : "items-start"
1797
+ ),
1798
+ children: [
1799
+ /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) }),
1800
+ description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
1801
+ ]
1802
+ }
1803
+ ),
1804
+ tiers && tiers.length > 0 && /* @__PURE__ */ jsx(
1805
+ "div",
1806
+ {
1807
+ className: layout === "stacked" ? "mx-auto flex w-full max-w-xl flex-col gap-6" : "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 items-stretch",
1808
+ children: tiers.map((tier, index) => /* @__PURE__ */ jsx(
1809
+ PageCard,
1719
1810
  {
1811
+ theme: overriddenTheme,
1720
1812
  className: clsx3(
1721
- "flex flex-col gap-4",
1722
- headerAlignment === "center" ? "items-center text-center" : "items-start"
1813
+ tier.highlighted && "ring-2 ring-primary",
1814
+ layout === "highlight" && tier.highlighted && "relative z-10 shadow-xl md:-translate-y-3"
1723
1815
  ),
1724
- children: [
1725
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
1726
- description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
1727
- ]
1728
- }
1729
- ),
1730
- tiers && tiers.length > 0 && /* @__PURE__ */ jsx(
1731
- "div",
1732
- {
1733
- className: layout === "stacked" ? "mx-auto flex w-full max-w-xl flex-col gap-6" : "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 items-stretch",
1734
- children: tiers.map((tier, index) => /* @__PURE__ */ jsx(
1735
- PageCard,
1816
+ children: /* @__PURE__ */ jsxs(
1817
+ PageCardContent,
1736
1818
  {
1737
1819
  theme: overriddenTheme,
1738
- className: clsx3(
1739
- tier.highlighted && "ring-2 ring-primary",
1740
- layout === "highlight" && tier.highlighted && "relative z-10 shadow-xl md:-translate-y-3"
1741
- ),
1742
- children: /* @__PURE__ */ jsxs(
1743
- PageCardContent,
1744
- {
1745
- theme: overriddenTheme,
1746
- className: "h-full flex flex-col gap-4",
1747
- children: [
1748
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1749
- /* @__PURE__ */ jsx(Preheader, { theme: overriddenTheme, children: tier.name }),
1750
- tier.highlighted && /* @__PURE__ */ jsx(Badge, { theme: overriddenTheme, children: "Most popular" })
1751
- ] }),
1752
- /* @__PURE__ */ jsx(PageCardHeader, { theme: overriddenTheme, children: tier.price }),
1753
- tier.description && /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, children: tier.description }),
1754
- tier.features && tier.features.length > 0 && /* @__PURE__ */ jsx("div", { className: "grow flex flex-col gap-2", children: tier.features.map((feature, i) => /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: feature }, i)) }),
1755
- tier.buttonAction && tier.buttonCaption && /* @__PURE__ */ jsx(NavLink, { href: tier.buttonAction, className: "w-full mt-auto", children: /* @__PURE__ */ jsx(
1756
- Button2,
1757
- {
1758
- theme: overriddenTheme,
1759
- variant: tier.highlighted ? "default" : "secondary",
1760
- className: "w-full",
1761
- children: tier.buttonCaption
1762
- }
1763
- ) })
1764
- ]
1765
- }
1766
- )
1767
- },
1768
- index
1769
- ))
1770
- }
1771
- )
1772
- ] })
1773
- }
1774
- );
1820
+ className: "h-full flex flex-col gap-4",
1821
+ children: [
1822
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1823
+ /* @__PURE__ */ jsx(Preheader, { theme: overriddenTheme, children: tier.name }),
1824
+ tier.highlighted && /* @__PURE__ */ jsx(Badge, { theme: overriddenTheme, children: "Most popular" })
1825
+ ] }),
1826
+ /* @__PURE__ */ jsx(PageCardHeader, { theme: overriddenTheme, children: tier.price }),
1827
+ tier.description && /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, children: tier.description }),
1828
+ tier.features && tier.features.length > 0 && /* @__PURE__ */ jsx("div", { className: "grow flex flex-col gap-2", children: tier.features.map((feature, i) => /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: feature }, i)) }),
1829
+ tier.buttonAction && tier.buttonCaption && /* @__PURE__ */ jsx(NavLink, { href: tier.buttonAction, className: "w-full mt-auto", children: /* @__PURE__ */ jsx(
1830
+ Button2,
1831
+ {
1832
+ theme: overriddenTheme,
1833
+ variant: tier.highlighted ? "default" : "secondary",
1834
+ className: "w-full",
1835
+ children: tier.buttonCaption
1836
+ }
1837
+ ) })
1838
+ ]
1839
+ }
1840
+ )
1841
+ },
1842
+ index
1843
+ ))
1844
+ }
1845
+ )
1846
+ ] }) });
1775
1847
  }
1776
1848
  var createTier = () => ({
1777
1849
  name: "New plan",
@@ -1792,22 +1864,22 @@ function PricingEditor({
1792
1864
  TextField,
1793
1865
  {
1794
1866
  label: "Title",
1867
+ hint: "Wrap words in *asterisks* to highlight them.",
1795
1868
  value: settings.title,
1796
1869
  onChange: (title) => update({ title })
1797
1870
  }
1798
1871
  ),
1799
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
1800
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
1801
- /* @__PURE__ */ jsx(
1802
- Editor,
1803
- {
1804
- initialContent: settings.description ?? emptyDoc,
1805
- onChange: (description) => update({ description }),
1806
- showToolbar: false,
1807
- editorClassName: "min-h-[80px]"
1808
- }
1809
- )
1810
- ] }),
1872
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
1873
+ /* @__PURE__ */ jsx(
1874
+ RichTextField,
1875
+ {
1876
+ label: "Description",
1877
+ value: settings.description,
1878
+ onChange: (description) => update({ description }),
1879
+ showToolbar: false,
1880
+ minHeight: 80
1881
+ }
1882
+ ),
1811
1883
  /* @__PURE__ */ jsx(
1812
1884
  SelectField,
1813
1885
  {
@@ -1949,6 +2021,7 @@ var Pricing = {
1949
2021
  metadata: pricingMetadata,
1950
2022
  widget: PricingWidget,
1951
2023
  editor: PricingEditor,
2024
+ titleSize: true,
1952
2025
  getDefaultSettings: () => pricingDefaults,
1953
2026
  layouts: [
1954
2027
  { id: "grid", name: "Grid" },
@@ -1967,6 +2040,8 @@ var bannerMetadata = {
1967
2040
  function BannerWidget({
1968
2041
  settings: {
1969
2042
  title,
2043
+ titleLevel,
2044
+ titleSize,
1970
2045
  description,
1971
2046
  buttonCaption,
1972
2047
  buttonAction,
@@ -1979,8 +2054,7 @@ function BannerWidget({
1979
2054
  verticalPadding,
1980
2055
  background
1981
2056
  },
1982
- state: { theme },
1983
- nextTheme
2057
+ state: { theme }
1984
2058
  }) {
1985
2059
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
1986
2060
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
@@ -1989,7 +2063,7 @@ function BannerWidget({
1989
2063
  const isSplit = layout === "split";
1990
2064
  const isBoxed = layout === "boxed";
1991
2065
  const heading = /* @__PURE__ */ jsxs(Fragment, { children: [
1992
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
2066
+ /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) }),
1993
2067
  description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
1994
2068
  ] });
1995
2069
  const buttons = (buttonAction || secondaryButtonAction) && /* @__PURE__ */ jsxs(
@@ -2030,23 +2104,14 @@ function BannerWidget({
2030
2104
  ]
2031
2105
  }
2032
2106
  );
2033
- return /* @__PURE__ */ jsx(
2034
- Section,
2107
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: isBoxed ? /* @__PURE__ */ jsx(PageCard, { theme: overriddenTheme, className: "mx-auto max-w-3xl", children: /* @__PURE__ */ jsx(
2108
+ PageCardContent,
2035
2109
  {
2036
2110
  theme: overriddenTheme,
2037
- id: cssId,
2038
- background,
2039
- nextTheme,
2040
- children: isBoxed ? /* @__PURE__ */ jsx(PageCard, { theme: overriddenTheme, className: "mx-auto max-w-3xl", children: /* @__PURE__ */ jsx(
2041
- PageCardContent,
2042
- {
2043
- theme: overriddenTheme,
2044
- className: "items-center p-8 text-center md:p-12",
2045
- children: content
2046
- }
2047
- ) }) : content
2111
+ className: "items-center p-8 text-center md:p-12",
2112
+ children: content
2048
2113
  }
2049
- );
2114
+ ) }) : content });
2050
2115
  }
2051
2116
  function BannerEditor({
2052
2117
  settings,
@@ -2059,22 +2124,22 @@ function BannerEditor({
2059
2124
  TextField,
2060
2125
  {
2061
2126
  label: "Title",
2127
+ hint: "Wrap words in *asterisks* to highlight them.",
2062
2128
  value: settings.title,
2063
2129
  onChange: (title) => update({ title })
2064
2130
  }
2065
2131
  ),
2066
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
2067
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
2068
- /* @__PURE__ */ jsx(
2069
- Editor,
2070
- {
2071
- initialContent: settings.description ?? emptyDoc,
2072
- onChange: (description) => update({ description }),
2073
- showToolbar: false,
2074
- editorClassName: "min-h-[80px]"
2075
- }
2076
- )
2077
- ] })
2132
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
2133
+ /* @__PURE__ */ jsx(
2134
+ RichTextField,
2135
+ {
2136
+ label: "Description",
2137
+ value: settings.description,
2138
+ onChange: (description) => update({ description }),
2139
+ showToolbar: false,
2140
+ minHeight: 80
2141
+ }
2142
+ )
2078
2143
  ] }),
2079
2144
  /* @__PURE__ */ jsxs(FieldGroup, { title: "Calls to action", children: [
2080
2145
  /* @__PURE__ */ jsx(
@@ -2140,6 +2205,7 @@ var Banner = {
2140
2205
  metadata: bannerMetadata,
2141
2206
  widget: BannerWidget,
2142
2207
  editor: BannerEditor,
2208
+ titleSize: true,
2143
2209
  getDefaultSettings: () => bannerDefaults,
2144
2210
  layouts: [
2145
2211
  { id: "stacked", name: "Stacked" },
@@ -2179,27 +2245,16 @@ async function subscribeEmail(email, pageData) {
2179
2245
  return { success: false };
2180
2246
  }
2181
2247
  }
2182
- function EmailFormWidget({
2183
- settings: {
2184
- title,
2185
- description,
2186
- buttonCaption = "Subscribe",
2187
- successMessage = "Thanks for subscribing!",
2188
- alignment = "left",
2189
- layout = "stacked",
2190
- cssId,
2191
- maxWidth,
2192
- verticalPadding,
2193
- background
2194
- },
2195
- state: { theme },
2248
+ function EmailForm({
2249
+ theme: overriddenTheme,
2250
+ layout,
2251
+ alignment,
2252
+ buttonCaption,
2253
+ successMessage,
2196
2254
  pageData,
2197
2255
  editing,
2198
- nextTheme
2256
+ heading
2199
2257
  }) {
2200
- const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
2201
- overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
2202
- overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
2203
2258
  const [email, setEmail] = useState("");
2204
2259
  const [isSubmitting, setIsSubmitting] = useState(false);
2205
2260
  const [success, setSuccess] = useState(false);
@@ -2219,24 +2274,62 @@ function EmailFormWidget({
2219
2274
  }
2220
2275
  };
2221
2276
  if (layout === "inline") {
2222
- return /* @__PURE__ */ jsx(
2223
- Section,
2277
+ return /* @__PURE__ */ jsxs(
2278
+ "form",
2224
2279
  {
2225
- theme: overriddenTheme,
2226
- id: cssId,
2227
- background,
2228
- nextTheme,
2229
- children: /* @__PURE__ */ jsxs(
2230
- "form",
2280
+ onSubmit,
2281
+ className: "flex flex-col items-start gap-4 md:!flex-row md:items-center md:justify-between",
2282
+ children: [
2283
+ heading,
2284
+ success ? /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: successMessage }) : /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-2 sm:!flex-row md:w-auto md:shrink-0", children: [
2285
+ /* @__PURE__ */ jsx(
2286
+ Input,
2287
+ {
2288
+ theme: overriddenTheme,
2289
+ id: "email",
2290
+ value: email,
2291
+ onChange: (e) => setEmail(e.target.value),
2292
+ placeholder: "Enter your email",
2293
+ type: "email",
2294
+ required: true,
2295
+ className: "md:w-64"
2296
+ }
2297
+ ),
2298
+ /* @__PURE__ */ jsx(
2299
+ Button2,
2300
+ {
2301
+ theme: overriddenTheme,
2302
+ type: "submit",
2303
+ disabled: !editing && (isSubmitting || !email),
2304
+ children: buttonCaption
2305
+ }
2306
+ )
2307
+ ] })
2308
+ ]
2309
+ }
2310
+ );
2311
+ }
2312
+ return /* @__PURE__ */ jsxs(
2313
+ "form",
2314
+ {
2315
+ onSubmit,
2316
+ className: clsx3(
2317
+ "flex gap-4",
2318
+ layout === "split" ? "flex-col md:!flex-row md:items-center md:justify-between md:gap-10" : clsx3("flex-col", isCentered ? "items-center text-center" : "items-start")
2319
+ ),
2320
+ children: [
2321
+ heading,
2322
+ success ? /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: successMessage }) : /* @__PURE__ */ jsxs(
2323
+ "div",
2231
2324
  {
2232
- onSubmit,
2233
- className: "flex flex-col items-start gap-4 md:!flex-row md:items-center md:justify-between",
2325
+ className: clsx3(
2326
+ "flex flex-col md:!flex-row md:!items-end gap-2",
2327
+ layout === "split" ? "md:shrink-0" : "w-full",
2328
+ layout !== "split" && isCentered ? "md:!justify-center" : ""
2329
+ ),
2234
2330
  children: [
2235
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2236
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, className: "text-xl", children: title }),
2237
- description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
2238
- ] }),
2239
- success ? /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: successMessage }) : /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-2 sm:!flex-row md:w-auto md:shrink-0", children: [
2331
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
2332
+ /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "email", children: "Email" }),
2240
2333
  /* @__PURE__ */ jsx(
2241
2334
  Input,
2242
2335
  {
@@ -2246,96 +2339,85 @@ function EmailFormWidget({
2246
2339
  onChange: (e) => setEmail(e.target.value),
2247
2340
  placeholder: "Enter your email",
2248
2341
  type: "email",
2249
- required: true,
2250
- className: "md:w-64"
2251
- }
2252
- ),
2253
- /* @__PURE__ */ jsx(
2254
- Button2,
2255
- {
2256
- theme: overriddenTheme,
2257
- type: "submit",
2258
- disabled: !editing && (isSubmitting || !email),
2259
- children: buttonCaption
2342
+ required: true
2260
2343
  }
2261
2344
  )
2262
- ] })
2345
+ ] }),
2346
+ /* @__PURE__ */ jsx(
2347
+ Button2,
2348
+ {
2349
+ theme: overriddenTheme,
2350
+ type: "submit",
2351
+ disabled: !editing && (isSubmitting || !email),
2352
+ children: buttonCaption
2353
+ }
2354
+ )
2263
2355
  ]
2264
2356
  }
2265
2357
  )
2358
+ ]
2359
+ }
2360
+ );
2361
+ }
2362
+ function EmailFormWidget({
2363
+ settings: {
2364
+ title,
2365
+ titleLevel,
2366
+ titleSize,
2367
+ description,
2368
+ buttonCaption = "Subscribe",
2369
+ successMessage = "Thanks for subscribing!",
2370
+ alignment = "left",
2371
+ layout = "stacked",
2372
+ cssId,
2373
+ maxWidth,
2374
+ verticalPadding,
2375
+ background
2376
+ },
2377
+ state: { theme },
2378
+ pageData,
2379
+ editing
2380
+ }) {
2381
+ const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
2382
+ overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
2383
+ overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
2384
+ const descriptionNode = description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) });
2385
+ const heading = layout === "inline" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2386
+ /* @__PURE__ */ jsx(
2387
+ Header1,
2388
+ {
2389
+ theme: overriddenTheme,
2390
+ ...titleProps({ titleLevel, titleSize }, "h2", "text-xl"),
2391
+ children: renderTitle(title, overriddenTheme)
2266
2392
  }
2267
- );
2268
- }
2269
- return /* @__PURE__ */ jsx(
2270
- Section,
2393
+ ),
2394
+ descriptionNode
2395
+ ] }) : /* @__PURE__ */ jsxs(
2396
+ "div",
2271
2397
  {
2272
- theme: overriddenTheme,
2273
- id: cssId,
2274
- background,
2275
- nextTheme,
2276
- children: /* @__PURE__ */ jsxs(
2277
- "form",
2278
- {
2279
- onSubmit,
2280
- className: clsx3(
2281
- "flex gap-4",
2282
- layout === "split" ? "flex-col md:!flex-row md:items-center md:justify-between md:gap-10" : clsx3("flex-col", isCentered ? "items-center text-center" : "items-start")
2283
- ),
2284
- children: [
2285
- /* @__PURE__ */ jsxs(
2286
- "div",
2287
- {
2288
- className: clsx3(
2289
- "flex flex-col gap-4",
2290
- layout === "split" ? "items-start" : "contents"
2291
- ),
2292
- children: [
2293
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
2294
- description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
2295
- ]
2296
- }
2297
- ),
2298
- success ? /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: successMessage }) : /* @__PURE__ */ jsxs(
2299
- "div",
2300
- {
2301
- className: clsx3(
2302
- "flex flex-col md:!flex-row md:!items-end gap-2",
2303
- layout === "split" ? "md:shrink-0" : "w-full",
2304
- layout !== "split" && isCentered ? "md:!justify-center" : ""
2305
- ),
2306
- children: [
2307
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
2308
- /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "email", children: "Email" }),
2309
- /* @__PURE__ */ jsx(
2310
- Input,
2311
- {
2312
- theme: overriddenTheme,
2313
- id: "email",
2314
- value: email,
2315
- onChange: (e) => setEmail(e.target.value),
2316
- placeholder: "Enter your email",
2317
- type: "email",
2318
- required: true
2319
- }
2320
- )
2321
- ] }),
2322
- /* @__PURE__ */ jsx(
2323
- Button2,
2324
- {
2325
- theme: overriddenTheme,
2326
- type: "submit",
2327
- disabled: !editing && (isSubmitting || !email),
2328
- children: buttonCaption
2329
- }
2330
- )
2331
- ]
2332
- }
2333
- )
2334
- ]
2335
- }
2336
- )
2398
+ className: clsx3(
2399
+ "flex flex-col gap-4",
2400
+ layout === "split" ? "items-start" : "contents"
2401
+ ),
2402
+ children: [
2403
+ /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) }),
2404
+ descriptionNode
2405
+ ]
2337
2406
  }
2338
2407
  );
2408
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsx(
2409
+ EmailForm,
2410
+ {
2411
+ theme: overriddenTheme,
2412
+ layout,
2413
+ alignment,
2414
+ buttonCaption,
2415
+ successMessage,
2416
+ pageData,
2417
+ editing,
2418
+ heading
2419
+ }
2420
+ ) });
2339
2421
  }
2340
2422
  function EmailFormEditor({
2341
2423
  settings,
@@ -2348,22 +2430,22 @@ function EmailFormEditor({
2348
2430
  TextField,
2349
2431
  {
2350
2432
  label: "Title",
2433
+ hint: "Wrap words in *asterisks* to highlight them.",
2351
2434
  value: settings.title,
2352
2435
  onChange: (title) => update({ title })
2353
2436
  }
2354
2437
  ),
2355
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
2356
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
2357
- /* @__PURE__ */ jsx(
2358
- Editor,
2359
- {
2360
- initialContent: settings.description ?? emptyDoc,
2361
- onChange: (description) => update({ description }),
2362
- showToolbar: false,
2363
- editorClassName: "min-h-[80px]"
2364
- }
2365
- )
2366
- ] })
2438
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
2439
+ /* @__PURE__ */ jsx(
2440
+ RichTextField,
2441
+ {
2442
+ label: "Description",
2443
+ value: settings.description,
2444
+ onChange: (description) => update({ description }),
2445
+ showToolbar: false,
2446
+ minHeight: 80
2447
+ }
2448
+ )
2367
2449
  ] }),
2368
2450
  /* @__PURE__ */ jsxs(FieldGroup, { title: "Form", children: [
2369
2451
  /* @__PURE__ */ jsx(
@@ -2407,10 +2489,11 @@ var emailFormDefaults = {
2407
2489
  };
2408
2490
 
2409
2491
  // src/blocks/email-form/index.ts
2410
- var EmailForm = {
2492
+ var EmailForm2 = {
2411
2493
  metadata: emailFormMetadata,
2412
2494
  widget: EmailFormWidget,
2413
2495
  editor: EmailFormEditor,
2496
+ titleSize: true,
2414
2497
  getDefaultSettings: () => emailFormDefaults,
2415
2498
  layouts: [
2416
2499
  { id: "stacked", name: "Stacked" },
@@ -2467,26 +2550,13 @@ async function submitTicket(input, pageData) {
2467
2550
  return { success: false };
2468
2551
  }
2469
2552
  }
2470
- function SupportFormWidget({
2471
- settings: {
2472
- title,
2473
- description,
2474
- buttonCaption = "Submit ticket",
2475
- successMessage = "Thanks \u2014 we've got your ticket and will reply by email soon.",
2476
- alignment = "left",
2477
- cssId,
2478
- maxWidth,
2479
- verticalPadding,
2480
- background
2481
- },
2482
- state: { theme },
2553
+ function SupportForm({
2554
+ theme: overriddenTheme,
2555
+ buttonCaption,
2556
+ successMessage,
2483
2557
  pageData,
2484
- editing,
2485
- nextTheme
2558
+ editing
2486
2559
  }) {
2487
- const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
2488
- overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
2489
- overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
2490
2560
  const [subject, setSubject] = useState("");
2491
2561
  const [message, setMessage] = useState("");
2492
2562
  const [email, setEmail] = useState("");
@@ -2526,145 +2596,168 @@ function SupportFormWidget({
2526
2596
  setIsSubmitting(false);
2527
2597
  }
2528
2598
  };
2529
- const isCentered = alignment === "center";
2530
2599
  const inputStyles = overriddenTheme.interactives.input;
2531
2600
  const inputTypography = overriddenTheme.typography.input;
2532
2601
  const cardStyles = overriddenTheme.interactives.card;
2533
- return /* @__PURE__ */ jsxs(
2534
- Section,
2535
- {
2536
- theme: overriddenTheme,
2537
- id: cssId,
2538
- background,
2539
- nextTheme,
2540
- children: [
2541
- /* @__PURE__ */ jsxs(
2542
- "div",
2543
- {
2544
- className: clsx3(
2545
- "flex flex-col gap-4",
2546
- isCentered ? "items-center text-center" : "items-start"
2547
- ),
2548
- children: [
2549
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
2550
- description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
2551
- ]
2552
- }
2602
+ return success ? /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, className: "mt-4", children: successMessage }) : /* @__PURE__ */ jsxs("form", { onSubmit, className: "mt-4 flex w-full max-w-lg flex-col gap-3", children: [
2603
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
2604
+ /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "subject", children: "Subject" }),
2605
+ /* @__PURE__ */ jsx(
2606
+ Input,
2607
+ {
2608
+ theme: overriddenTheme,
2609
+ id: "subject",
2610
+ value: subject,
2611
+ onChange: (e) => setSubject(e.target.value),
2612
+ placeholder: "What do you need help with?",
2613
+ required: true,
2614
+ className: "w-full"
2615
+ }
2616
+ )
2617
+ ] }),
2618
+ suggestions.length > 0 && /* @__PURE__ */ jsxs(
2619
+ "div",
2620
+ {
2621
+ className: cn(
2622
+ "rounded-lg border border-border bg-card p-3 text-sm text-card-foreground shadow-sm",
2623
+ cardStyles.border?.width,
2624
+ cardStyles.border?.radius,
2625
+ cardStyles.border?.style,
2626
+ cardStyles.shadow
2553
2627
  ),
2554
- success ? /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, className: "mt-4", children: successMessage }) : /* @__PURE__ */ jsxs("form", { onSubmit, className: "mt-4 flex w-full max-w-lg flex-col gap-3", children: [
2555
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
2556
- /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "subject", children: "Subject" }),
2557
- /* @__PURE__ */ jsx(
2558
- Input,
2559
- {
2560
- theme: overriddenTheme,
2561
- id: "subject",
2562
- value: subject,
2563
- onChange: (e) => setSubject(e.target.value),
2564
- placeholder: "What do you need help with?",
2565
- required: true,
2566
- className: "w-full"
2567
- }
2568
- )
2569
- ] }),
2570
- suggestions.length > 0 && /* @__PURE__ */ jsxs(
2571
- "div",
2572
- {
2573
- className: cn(
2574
- "rounded-lg border border-border bg-card p-3 text-sm text-card-foreground shadow-sm",
2575
- cardStyles.border?.width,
2576
- cardStyles.border?.radius,
2577
- cardStyles.border?.style,
2578
- cardStyles.shadow
2579
- ),
2580
- children: [
2581
- /* @__PURE__ */ jsx("p", { className: "mb-1 font-medium", children: "This might help:" }),
2582
- /* @__PURE__ */ jsx("ul", { className: "list-inside list-disc", children: suggestions.map((doc) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
2583
- "a",
2584
- {
2585
- href: suggestionHref(doc),
2586
- target: "_blank",
2587
- rel: "noreferrer",
2588
- className: "underline",
2589
- children: doc.title ?? doc.slug
2590
- }
2591
- ) }, doc.documentId)) })
2592
- ]
2593
- }
2594
- ),
2595
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
2596
- /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "message", children: "Message" }),
2597
- /* @__PURE__ */ jsx(
2598
- "textarea",
2599
- {
2600
- id: "message",
2601
- value: message,
2602
- onChange: (e) => setMessage(e.target.value),
2603
- placeholder: "Describe the issue\u2026",
2604
- required: true,
2605
- rows: 4,
2606
- className: cn(
2607
- "w-full border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2608
- inputTypography.fontFamily,
2609
- inputTypography.fontSize,
2610
- inputTypography.fontWeight,
2611
- inputTypography.lineHeight,
2612
- inputTypography.letterSpacing,
2613
- inputStyles.border?.width,
2614
- inputStyles.border?.style,
2615
- inputStyles.border?.radius,
2616
- inputStyles.shadow,
2617
- inputStyles.custom
2618
- )
2619
- }
2620
- )
2621
- ] }),
2622
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:!flex-row", children: [
2623
- /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1 items-start", children: [
2624
- /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "email", children: "Email" }),
2625
- /* @__PURE__ */ jsx(
2626
- Input,
2627
- {
2628
- theme: overriddenTheme,
2629
- id: "email",
2630
- type: "email",
2631
- value: email,
2632
- onChange: (e) => setEmail(e.target.value),
2633
- placeholder: "you@example.com",
2634
- required: true,
2635
- className: "w-full"
2636
- }
2637
- )
2638
- ] }),
2639
- /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1 items-start", children: [
2640
- /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "name", children: "Name (optional)" }),
2641
- /* @__PURE__ */ jsx(
2642
- Input,
2643
- {
2644
- theme: overriddenTheme,
2645
- id: "name",
2646
- value: name,
2647
- onChange: (e) => setName(e.target.value),
2648
- placeholder: "Your name",
2649
- className: "w-full"
2650
- }
2651
- )
2652
- ] })
2653
- ] }),
2654
- /* @__PURE__ */ jsx(
2655
- Button2,
2628
+ children: [
2629
+ /* @__PURE__ */ jsx("p", { className: "mb-1 font-medium", children: "This might help:" }),
2630
+ /* @__PURE__ */ jsx("ul", { className: "list-inside list-disc", children: suggestions.map((doc) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
2631
+ "a",
2656
2632
  {
2657
- theme: overriddenTheme,
2658
- type: "submit",
2659
- disabled: !editing && (isSubmitting || !subject || !message || !email),
2660
- className: "self-start",
2661
- children: buttonCaption
2633
+ href: suggestionHref(doc),
2634
+ target: "_blank",
2635
+ rel: "noreferrer",
2636
+ className: "underline",
2637
+ children: doc.title ?? doc.slug
2662
2638
  }
2639
+ ) }, doc.documentId)) })
2640
+ ]
2641
+ }
2642
+ ),
2643
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
2644
+ /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "message", children: "Message" }),
2645
+ /* @__PURE__ */ jsx(
2646
+ "textarea",
2647
+ {
2648
+ id: "message",
2649
+ value: message,
2650
+ onChange: (e) => setMessage(e.target.value),
2651
+ placeholder: "Describe the issue\u2026",
2652
+ required: true,
2653
+ rows: 4,
2654
+ className: cn(
2655
+ "w-full border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2656
+ inputTypography.fontFamily,
2657
+ inputTypography.fontSize,
2658
+ inputTypography.fontWeight,
2659
+ inputTypography.lineHeight,
2660
+ inputTypography.letterSpacing,
2661
+ inputStyles.border?.width,
2662
+ inputStyles.border?.style,
2663
+ inputStyles.border?.radius,
2664
+ inputStyles.shadow,
2665
+ inputStyles.custom
2663
2666
  )
2664
- ] })
2665
- ]
2666
- }
2667
- );
2667
+ }
2668
+ )
2669
+ ] }),
2670
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:!flex-row", children: [
2671
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1 items-start", children: [
2672
+ /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "email", children: "Email" }),
2673
+ /* @__PURE__ */ jsx(
2674
+ Input,
2675
+ {
2676
+ theme: overriddenTheme,
2677
+ id: "email",
2678
+ type: "email",
2679
+ value: email,
2680
+ onChange: (e) => setEmail(e.target.value),
2681
+ placeholder: "you@example.com",
2682
+ required: true,
2683
+ className: "w-full"
2684
+ }
2685
+ )
2686
+ ] }),
2687
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1 items-start", children: [
2688
+ /* @__PURE__ */ jsx(Label, { theme: overriddenTheme, htmlFor: "name", children: "Name (optional)" }),
2689
+ /* @__PURE__ */ jsx(
2690
+ Input,
2691
+ {
2692
+ theme: overriddenTheme,
2693
+ id: "name",
2694
+ value: name,
2695
+ onChange: (e) => setName(e.target.value),
2696
+ placeholder: "Your name",
2697
+ className: "w-full"
2698
+ }
2699
+ )
2700
+ ] })
2701
+ ] }),
2702
+ /* @__PURE__ */ jsx(
2703
+ Button2,
2704
+ {
2705
+ theme: overriddenTheme,
2706
+ type: "submit",
2707
+ disabled: !editing && (isSubmitting || !subject || !message || !email),
2708
+ className: "self-start",
2709
+ children: buttonCaption
2710
+ }
2711
+ )
2712
+ ] });
2713
+ }
2714
+ function SupportFormWidget({
2715
+ settings: {
2716
+ title,
2717
+ titleLevel,
2718
+ titleSize,
2719
+ description,
2720
+ buttonCaption = "Submit ticket",
2721
+ successMessage = "Thanks \u2014 we've got your ticket and will reply by email soon.",
2722
+ alignment = "left",
2723
+ cssId,
2724
+ maxWidth,
2725
+ verticalPadding,
2726
+ background
2727
+ },
2728
+ state: { theme },
2729
+ pageData,
2730
+ editing
2731
+ }) {
2732
+ const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
2733
+ overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
2734
+ overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
2735
+ const isCentered = alignment === "center";
2736
+ return /* @__PURE__ */ jsxs(Section, { theme: overriddenTheme, id: cssId, background, children: [
2737
+ /* @__PURE__ */ jsxs(
2738
+ "div",
2739
+ {
2740
+ className: clsx3(
2741
+ "flex flex-col gap-4",
2742
+ isCentered ? "items-center text-center" : "items-start"
2743
+ ),
2744
+ children: [
2745
+ /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) }),
2746
+ description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) })
2747
+ ]
2748
+ }
2749
+ ),
2750
+ /* @__PURE__ */ jsx(
2751
+ SupportForm,
2752
+ {
2753
+ theme: overriddenTheme,
2754
+ buttonCaption,
2755
+ successMessage,
2756
+ pageData,
2757
+ editing
2758
+ }
2759
+ )
2760
+ ] });
2668
2761
  }
2669
2762
  function SupportFormEditor({
2670
2763
  settings,
@@ -2677,22 +2770,22 @@ function SupportFormEditor({
2677
2770
  TextField,
2678
2771
  {
2679
2772
  label: "Title",
2773
+ hint: "Wrap words in *asterisks* to highlight them.",
2680
2774
  value: settings.title,
2681
2775
  onChange: (title) => update({ title })
2682
2776
  }
2683
2777
  ),
2684
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
2685
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
2686
- /* @__PURE__ */ jsx(
2687
- Editor,
2688
- {
2689
- initialContent: settings.description ?? emptyDoc,
2690
- onChange: (description) => update({ description }),
2691
- showToolbar: false,
2692
- editorClassName: "min-h-[80px]"
2693
- }
2694
- )
2695
- ] })
2778
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
2779
+ /* @__PURE__ */ jsx(
2780
+ RichTextField,
2781
+ {
2782
+ label: "Description",
2783
+ value: settings.description,
2784
+ onChange: (description) => update({ description }),
2785
+ showToolbar: false,
2786
+ minHeight: 80
2787
+ }
2788
+ )
2696
2789
  ] }),
2697
2790
  /* @__PURE__ */ jsxs(FieldGroup, { title: "Form", children: [
2698
2791
  /* @__PURE__ */ jsx(
@@ -2736,10 +2829,11 @@ var supportFormDefaults = {
2736
2829
  };
2737
2830
 
2738
2831
  // src/blocks/support-form/index.ts
2739
- var SupportForm = {
2832
+ var SupportForm2 = {
2740
2833
  metadata: supportFormMetadata,
2741
2834
  widget: SupportFormWidget,
2742
2835
  editor: SupportFormEditor,
2836
+ titleSize: true,
2743
2837
  getDefaultSettings: () => supportFormDefaults,
2744
2838
  layouts: [{ id: "stacked", name: "Stacked" }]
2745
2839
  };
@@ -2753,22 +2847,26 @@ var footerMetadata = {
2753
2847
  };
2754
2848
  function FooterWidget({
2755
2849
  settings: {
2756
- logoText,
2757
- tagline,
2850
+ tagline: ownTagline,
2758
2851
  columns = [],
2759
2852
  copyrightText,
2760
2853
  layout = "columns",
2854
+ showThemeSwitcher = true,
2761
2855
  cssId,
2762
2856
  maxWidth,
2763
2857
  verticalPadding,
2764
2858
  background
2765
2859
  },
2766
2860
  state: { theme },
2767
- nextTheme
2861
+ pageData,
2862
+ themeSwitcher
2768
2863
  }) {
2864
+ const logoText = pageData.siteTitle;
2865
+ const tagline = ownTagline || pageData.siteSubtitle;
2769
2866
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
2770
2867
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
2771
2868
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
2869
+ const colorModeControl = showThemeSwitcher ? themeSwitcher : null;
2772
2870
  return /* @__PURE__ */ jsxs(
2773
2871
  Section,
2774
2872
  {
@@ -2776,11 +2874,10 @@ function FooterWidget({
2776
2874
  component: "footer",
2777
2875
  id: cssId,
2778
2876
  background,
2779
- nextTheme,
2780
2877
  className: "border-t",
2781
2878
  children: [
2782
2879
  layout === "minimal" ? /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-wrap items-center justify-between gap-4", children: [
2783
- logoText && /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, children: logoText }),
2880
+ logoText && /* @__PURE__ */ jsx(Header4, { theme: overriddenTheme, as: "p", children: logoText }),
2784
2881
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2", children: [
2785
2882
  columns.flatMap(
2786
2883
  (column) => column.links.map((link) => /* @__PURE__ */ jsx(
@@ -2793,11 +2890,12 @@ function FooterWidget({
2793
2890
  `${column.id}-${link.id}`
2794
2891
  ))
2795
2892
  ),
2796
- copyrightText && /* @__PURE__ */ jsx(Caption, { theme: overriddenTheme, children: copyrightText })
2893
+ copyrightText && /* @__PURE__ */ jsx(Caption, { theme: overriddenTheme, children: copyrightText }),
2894
+ colorModeControl
2797
2895
  ] })
2798
2896
  ] }) : layout === "centered" ? /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-center gap-6 text-center", children: [
2799
2897
  /* @__PURE__ */ jsxs("div", { className: "flex max-w-sm flex-col items-center gap-3", children: [
2800
- logoText && /* @__PURE__ */ jsx(Header3, { theme: overriddenTheme, children: logoText }),
2898
+ logoText && /* @__PURE__ */ jsx(Header3, { theme: overriddenTheme, as: "p", children: logoText }),
2801
2899
  tagline && /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: tagline })
2802
2900
  ] }),
2803
2901
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-center gap-x-6 gap-y-2", children: columns.flatMap(
@@ -2813,7 +2911,7 @@ function FooterWidget({
2813
2911
  ) })
2814
2912
  ] }) : /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-8 lg:!flex-row lg:justify-between", children: [
2815
2913
  /* @__PURE__ */ jsxs("div", { className: "flex max-w-sm flex-col gap-3", children: [
2816
- logoText && /* @__PURE__ */ jsx(Header3, { theme: overriddenTheme, children: logoText }),
2914
+ logoText && /* @__PURE__ */ jsx(Header3, { theme: overriddenTheme, as: "p", children: logoText }),
2817
2915
  tagline && /* @__PURE__ */ jsx(Text2, { theme: overriddenTheme, children: tagline })
2818
2916
  ] }),
2819
2917
  /* @__PURE__ */ jsx("div", { className: "flex flex-col flex-wrap gap-8 lg:!flex-row", children: columns.map((column) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:min-w-[140px]", children: [
@@ -2821,11 +2919,14 @@ function FooterWidget({
2821
2919
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: column.links.map((link) => /* @__PURE__ */ jsx(NavLink, { href: link.href, className: "no-underline", children: /* @__PURE__ */ jsx(Link, { theme: overriddenTheme, className: "text-xs", children: link.label }) }, link.id)) })
2822
2920
  ] }, column.id)) })
2823
2921
  ] }),
2824
- copyrightText && layout !== "minimal" && /* @__PURE__ */ jsx(
2922
+ (copyrightText || colorModeControl) && layout !== "minimal" && /* @__PURE__ */ jsxs(
2825
2923
  "div",
2826
2924
  {
2827
- className: layout === "centered" ? "mt-8 border-t pt-6 text-center" : "mt-8 border-t pt-6",
2828
- children: /* @__PURE__ */ jsx(Caption, { theme: overriddenTheme, children: copyrightText })
2925
+ className: layout === "centered" ? "mt-8 flex flex-col items-center gap-4 border-t pt-6 text-center" : "mt-8 flex items-center justify-between gap-4 border-t pt-6",
2926
+ children: [
2927
+ copyrightText && /* @__PURE__ */ jsx(Caption, { theme: overriddenTheme, children: copyrightText }),
2928
+ colorModeControl && /* @__PURE__ */ jsx("div", { className: layout === "centered" ? void 0 : "ml-auto", children: colorModeControl })
2929
+ ]
2829
2930
  }
2830
2931
  )
2831
2932
  ]
@@ -2838,25 +2939,16 @@ function FooterEditor({
2838
2939
  }) {
2839
2940
  const update = (partial) => onChange({ ...settings, ...partial });
2840
2941
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
2841
- /* @__PURE__ */ jsxs(FieldGroup, { title: "Brand", children: [
2842
- /* @__PURE__ */ jsx(
2843
- TextField,
2844
- {
2845
- label: "Logo text",
2846
- value: settings.logoText,
2847
- onChange: (logoText) => update({ logoText })
2848
- }
2849
- ),
2850
- /* @__PURE__ */ jsx(
2851
- TextField,
2852
- {
2853
- label: "Tagline",
2854
- value: settings.tagline,
2855
- multiline: true,
2856
- onChange: (tagline) => update({ tagline })
2857
- }
2858
- )
2859
- ] }),
2942
+ /* @__PURE__ */ jsx(FieldGroup, { title: "Brand", children: /* @__PURE__ */ jsx(
2943
+ TextField,
2944
+ {
2945
+ label: "Tagline",
2946
+ value: settings.tagline,
2947
+ multiline: true,
2948
+ hint: "Leave empty to use the subtitle from Branding.",
2949
+ onChange: (tagline) => update({ tagline: tagline || void 0 })
2950
+ }
2951
+ ) }),
2860
2952
  /* @__PURE__ */ jsx(FieldGroup, { title: "Link columns", children: /* @__PURE__ */ jsx(
2861
2953
  ListField,
2862
2954
  {
@@ -2931,21 +3023,30 @@ function FooterEditor({
2931
3023
  ] })
2932
3024
  }
2933
3025
  ) }),
2934
- /* @__PURE__ */ jsx(FieldGroup, { title: "Copyright", children: /* @__PURE__ */ jsx(
2935
- TextField,
2936
- {
2937
- label: "Copyright text",
2938
- value: settings.copyrightText,
2939
- onChange: (copyrightText) => update({ copyrightText })
2940
- }
2941
- ) })
3026
+ /* @__PURE__ */ jsxs(FieldGroup, { title: "Copyright", children: [
3027
+ /* @__PURE__ */ jsx(
3028
+ TextField,
3029
+ {
3030
+ label: "Copyright text",
3031
+ value: settings.copyrightText,
3032
+ onChange: (copyrightText) => update({ copyrightText })
3033
+ }
3034
+ ),
3035
+ /* @__PURE__ */ jsx(
3036
+ ToggleField,
3037
+ {
3038
+ label: "Color mode switcher",
3039
+ value: settings.showThemeSwitcher !== false,
3040
+ onChange: (showThemeSwitcher) => update({ showThemeSwitcher })
3041
+ }
3042
+ )
3043
+ ] })
2942
3044
  ] });
2943
3045
  }
2944
3046
 
2945
3047
  // src/blocks/footer/defaults.ts
2946
3048
  var footerDefaults = {
2947
- logoText: "FrontLit",
2948
- tagline: "Build your website, publish content, support users, and grow your audience from one dashboard.",
3049
+ showThemeSwitcher: true,
2949
3050
  columns: [
2950
3051
  {
2951
3052
  id: generateUniqueId(),
@@ -3015,23 +3116,13 @@ var richTextMetadata = {
3015
3116
  };
3016
3117
  function RichTextWidget({
3017
3118
  settings: { text, alignment = "left", cssId, maxWidth, verticalPadding, background },
3018
- state: { theme },
3019
- nextTheme
3119
+ state: { theme }
3020
3120
  }) {
3021
3121
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
3022
3122
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
3023
3123
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
3024
3124
  if (!text) return null;
3025
- return /* @__PURE__ */ jsx(
3026
- Section,
3027
- {
3028
- theme: overriddenTheme,
3029
- id: cssId,
3030
- background,
3031
- nextTheme,
3032
- children: /* @__PURE__ */ jsx("div", { style: { textAlign: alignment }, children: /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: text, theme: overriddenTheme }) }) })
3033
- }
3034
- );
3125
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsx("div", { style: { textAlign: alignment }, children: /* @__PURE__ */ jsx(Text1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: text, theme: overriddenTheme }) }) }) });
3035
3126
  }
3036
3127
  function RichTextEditor({
3037
3128
  settings,
@@ -3039,17 +3130,15 @@ function RichTextEditor({
3039
3130
  }) {
3040
3131
  const update = (partial) => onChange({ ...settings, ...partial });
3041
3132
  return /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: /* @__PURE__ */ jsxs(FieldGroup, { title: "Content", children: [
3042
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
3043
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Text" }),
3044
- /* @__PURE__ */ jsx(
3045
- Editor,
3046
- {
3047
- initialContent: settings.text ?? emptyDoc,
3048
- onChange: (text) => update({ text }),
3049
- editorClassName: "min-h-[160px]"
3050
- }
3051
- )
3052
- ] }),
3133
+ /* @__PURE__ */ jsx(
3134
+ RichTextField,
3135
+ {
3136
+ label: "Text",
3137
+ value: settings.text,
3138
+ onChange: (text) => update({ text }),
3139
+ minHeight: 160
3140
+ }
3141
+ ),
3053
3142
  /* @__PURE__ */ jsx(
3054
3143
  SelectField,
3055
3144
  {
@@ -3147,6 +3236,8 @@ function GridItemCard({ item, theme }) {
3147
3236
  function GridWidget({
3148
3237
  settings: {
3149
3238
  title,
3239
+ titleLevel,
3240
+ titleSize,
3150
3241
  description,
3151
3242
  headerAlignment = "center",
3152
3243
  buttonCaption,
@@ -3158,47 +3249,37 @@ function GridWidget({
3158
3249
  verticalPadding,
3159
3250
  background
3160
3251
  },
3161
- state: { theme },
3162
- nextTheme
3252
+ state: { theme }
3163
3253
  }) {
3164
3254
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
3165
3255
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
3166
3256
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
3167
- return /* @__PURE__ */ jsx(
3168
- Section,
3169
- {
3170
- theme: overriddenTheme,
3171
- id: cssId,
3172
- background,
3173
- nextTheme,
3174
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
3175
- /* @__PURE__ */ jsxs(
3176
- "div",
3177
- {
3178
- className: clsx3(
3179
- "flex flex-col gap-4",
3180
- headerAlignment === "center" ? "items-center text-center" : "items-start"
3181
- ),
3182
- children: [
3183
- /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, children: title }),
3184
- description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) }),
3185
- buttonAction && buttonCaption && /* @__PURE__ */ jsx(NavLink, { href: buttonAction, className: "mt-2", children: /* @__PURE__ */ jsx(Button2, { theme: overriddenTheme, children: buttonCaption }) })
3186
- ]
3187
- }
3257
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
3258
+ /* @__PURE__ */ jsxs(
3259
+ "div",
3260
+ {
3261
+ className: clsx3(
3262
+ "flex flex-col gap-4",
3263
+ headerAlignment === "center" ? "items-center text-center" : "items-start"
3188
3264
  ),
3189
- items && items.length > 0 && /* @__PURE__ */ jsx(
3190
- "div",
3191
- {
3192
- className: clsx3(
3193
- "grid grid-cols-1 md:grid-cols-2 gap-6 items-stretch",
3194
- columns === 3 ? "lg:grid-cols-3" : "lg:grid-cols-2"
3195
- ),
3196
- children: items.map((item, index) => /* @__PURE__ */ jsx(GridItemCard, { item, theme: overriddenTheme }, index))
3197
- }
3198
- )
3199
- ] })
3200
- }
3201
- );
3265
+ children: [
3266
+ /* @__PURE__ */ jsx(Header1, { theme: overriddenTheme, ...titleProps({ titleLevel, titleSize }), children: renderTitle(title, overriddenTheme) }),
3267
+ description && /* @__PURE__ */ jsx(Subheader1, { theme: overriddenTheme, component: "span", children: /* @__PURE__ */ jsx(TextRenderer, { json: description, theme: overriddenTheme }) }),
3268
+ buttonAction && buttonCaption && /* @__PURE__ */ jsx(NavLink, { href: buttonAction, className: "mt-2", children: /* @__PURE__ */ jsx(Button2, { theme: overriddenTheme, children: buttonCaption }) })
3269
+ ]
3270
+ }
3271
+ ),
3272
+ items && items.length > 0 && /* @__PURE__ */ jsx(
3273
+ "div",
3274
+ {
3275
+ className: clsx3(
3276
+ "grid grid-cols-1 md:grid-cols-2 gap-6 items-stretch",
3277
+ columns === 3 ? "lg:grid-cols-3" : "lg:grid-cols-2"
3278
+ ),
3279
+ children: items.map((item, index) => /* @__PURE__ */ jsx(GridItemCard, { item, theme: overriddenTheme }, index))
3280
+ }
3281
+ )
3282
+ ] }) });
3202
3283
  }
3203
3284
  function GridEditor({ settings, onChange }) {
3204
3285
  const update = (partial) => onChange({ ...settings, ...partial });
@@ -3208,21 +3289,21 @@ function GridEditor({ settings, onChange }) {
3208
3289
  TextField,
3209
3290
  {
3210
3291
  label: "Title",
3292
+ hint: "Wrap words in *asterisks* to highlight them.",
3211
3293
  value: settings.title,
3212
3294
  onChange: (title) => update({ title })
3213
3295
  }
3214
3296
  ),
3215
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
3216
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Description" }),
3217
- /* @__PURE__ */ jsx(
3218
- Editor,
3219
- {
3220
- initialContent: settings.description ?? emptyDoc,
3221
- onChange: (description) => update({ description }),
3222
- editorClassName: "min-h-[100px]"
3223
- }
3224
- )
3225
- ] }),
3297
+ /* @__PURE__ */ jsx(TitleLevelField, { settings, onChange: update }),
3298
+ /* @__PURE__ */ jsx(
3299
+ RichTextField,
3300
+ {
3301
+ label: "Description",
3302
+ value: settings.description,
3303
+ onChange: (description) => update({ description }),
3304
+ minHeight: 100
3305
+ }
3306
+ ),
3226
3307
  /* @__PURE__ */ jsx(
3227
3308
  SelectField,
3228
3309
  {
@@ -3399,6 +3480,7 @@ var Grid = {
3399
3480
  metadata: gridMetadata,
3400
3481
  widget: GridWidget,
3401
3482
  editor: GridEditor,
3483
+ titleSize: true,
3402
3484
  getDefaultSettings: () => gridDefaults
3403
3485
  };
3404
3486
 
@@ -3434,50 +3516,40 @@ function MediaWidget({
3434
3516
  verticalPadding,
3435
3517
  background
3436
3518
  },
3437
- state: { theme },
3438
- nextTheme
3519
+ state: { theme }
3439
3520
  }) {
3440
3521
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
3441
3522
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
3442
3523
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
3443
3524
  const isVideoContent = isVideo(youtubeLink, media);
3444
- return /* @__PURE__ */ jsx(
3445
- Section,
3525
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsx(
3526
+ "div",
3446
3527
  {
3447
- theme: overriddenTheme,
3448
- id: cssId,
3449
- background,
3450
- nextTheme,
3451
- children: /* @__PURE__ */ jsx(
3452
- "div",
3528
+ className: cn(
3529
+ "overflow-hidden",
3530
+ roundedMap3[mediaRadius] ?? "rounded",
3531
+ hasBorder && (overriddenTheme.interactives?.card?.border?.width || "border")
3532
+ ),
3533
+ children: isVideoContent ? /* @__PURE__ */ jsx(
3534
+ VideoWithPreview,
3453
3535
  {
3454
- className: cn(
3455
- "overflow-hidden",
3456
- roundedMap3[mediaRadius] ?? "rounded",
3457
- hasBorder && (overriddenTheme.interactives?.card?.border?.width || "border")
3458
- ),
3459
- children: isVideoContent ? /* @__PURE__ */ jsx(
3460
- VideoWithPreview,
3461
- {
3462
- videoUrl: youtubeLink || getMediaUrl(media) || "",
3463
- title: getMediaAlt(media) || media?.caption || "",
3464
- thumbnailUrl: media?.thumbnail || media?.thumbnailUrl || "",
3465
- aspectRatio,
3466
- modal: playVideoInModal
3467
- }
3468
- ) : /* @__PURE__ */ jsx(
3469
- Image,
3470
- {
3471
- src: getMediaUrl(media) || "",
3472
- alt: getMediaAlt(media),
3473
- objectFit,
3474
- borderRadius: mediaRadius
3475
- }
3476
- )
3536
+ videoUrl: youtubeLink || getMediaUrl(media) || "",
3537
+ title: getMediaAlt(media) || media?.caption || "",
3538
+ thumbnailUrl: media?.thumbnail || media?.thumbnailUrl || "",
3539
+ aspectRatio,
3540
+ modal: playVideoInModal
3541
+ }
3542
+ ) : /* @__PURE__ */ jsx(
3543
+ Image,
3544
+ {
3545
+ src: getMediaUrl(media) || "",
3546
+ alt: getMediaAlt(media),
3547
+ objectFit,
3548
+ borderRadius: mediaRadius
3477
3549
  }
3478
3550
  )
3479
3551
  }
3480
- );
3552
+ ) });
3481
3553
  }
3482
3554
  function MediaEditor({ settings, onChange }) {
3483
3555
  const update = (partial) => onChange({ ...settings, ...partial });
@@ -3657,8 +3729,7 @@ function MarqueeWidget({
3657
3729
  verticalPadding,
3658
3730
  background
3659
3731
  },
3660
- state: { theme },
3661
- nextTheme
3732
+ state: { theme }
3662
3733
  }) {
3663
3734
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
3664
3735
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
@@ -3682,42 +3753,33 @@ function MarqueeWidget({
3682
3753
  children: Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-8 w-8" }) : /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-sm font-medium", children: item.text })
3683
3754
  }
3684
3755
  );
3685
- return item.href ? /* @__PURE__ */ jsx(NavLink, { href: item.href, openInSameTab: false, children: content }, item.id) : /* @__PURE__ */ jsx(React7.Fragment, { children: content }, item.id);
3756
+ return item.href ? /* @__PURE__ */ jsx(NavLink, { href: item.href, openInSameTab: false, children: content }, item.id) : /* @__PURE__ */ jsx(React2.Fragment, { children: content }, item.id);
3686
3757
  };
3687
- return /* @__PURE__ */ jsx(
3688
- Section,
3689
- {
3690
- theme: overriddenTheme,
3691
- id: cssId,
3692
- background,
3693
- nextTheme,
3694
- children: /* @__PURE__ */ jsxs("div", { className: "relative", "aria-hidden": "true", children: [
3695
- /* @__PURE__ */ jsx(MarqueeTrack, { speed, direction, pauseOnHover, children: items.map(renderItem) }),
3696
- fadeWidth > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
3697
- /* @__PURE__ */ jsx(
3698
- "div",
3699
- {
3700
- className: "pointer-events-none absolute inset-y-0 left-0 z-10",
3701
- style: {
3702
- width: fadeWidth,
3703
- background: "linear-gradient(to right, var(--background), transparent)"
3704
- }
3705
- }
3706
- ),
3707
- /* @__PURE__ */ jsx(
3708
- "div",
3709
- {
3710
- className: "pointer-events-none absolute inset-y-0 right-0 z-10",
3711
- style: {
3712
- width: fadeWidth,
3713
- background: "linear-gradient(to left, var(--background), transparent)"
3714
- }
3715
- }
3716
- )
3717
- ] })
3718
- ] })
3719
- }
3720
- );
3758
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "relative", "aria-hidden": "true", children: [
3759
+ /* @__PURE__ */ jsx(MarqueeTrack, { speed, direction, pauseOnHover, children: items.map(renderItem) }),
3760
+ fadeWidth > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
3761
+ /* @__PURE__ */ jsx(
3762
+ "div",
3763
+ {
3764
+ className: "pointer-events-none absolute inset-y-0 left-0 z-10",
3765
+ style: {
3766
+ width: fadeWidth,
3767
+ background: "linear-gradient(to right, var(--background), transparent)"
3768
+ }
3769
+ }
3770
+ ),
3771
+ /* @__PURE__ */ jsx(
3772
+ "div",
3773
+ {
3774
+ className: "pointer-events-none absolute inset-y-0 right-0 z-10",
3775
+ style: {
3776
+ width: fadeWidth,
3777
+ background: "linear-gradient(to left, var(--background), transparent)"
3778
+ }
3779
+ }
3780
+ )
3781
+ ] })
3782
+ ] }) });
3721
3783
  }
3722
3784
  function MarqueeEditor({
3723
3785
  settings,
@@ -3936,54 +3998,38 @@ function EmbedWidget({
3936
3998
  background
3937
3999
  },
3938
4000
  state: { theme },
3939
- editing,
3940
- nextTheme
4001
+ editing
3941
4002
  }) {
3942
4003
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
3943
4004
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
3944
4005
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
3945
4006
  if (!content) {
3946
4007
  if (!editing) return null;
3947
- return /* @__PURE__ */ jsx(
3948
- Section,
3949
- {
3950
- theme: overriddenTheme,
3951
- id: cssId,
3952
- background,
3953
- nextTheme,
3954
- children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-48 flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-border bg-muted/30 px-6 py-12 text-center", children: [
3955
- /* @__PURE__ */ jsx("span", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-border bg-background text-muted-foreground", children: /* @__PURE__ */ jsx(Code2, { className: "h-4 w-4" }) }),
3956
- /* @__PURE__ */ jsxs("div", { children: [
3957
- /* @__PURE__ */ jsx("p", { className: "font-semibold text-foreground", children: "Embed external content" }),
3958
- /* @__PURE__ */ jsx("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: "Paste an embed URL or script snippet in the block settings." })
3959
- ] })
3960
- ] })
3961
- }
3962
- );
4008
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-48 flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-border bg-muted/30 px-6 py-12 text-center", children: [
4009
+ /* @__PURE__ */ jsx("span", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-border bg-background text-muted-foreground", children: /* @__PURE__ */ jsx(Code2, { className: "h-4 w-4" }) }),
4010
+ /* @__PURE__ */ jsxs("div", { children: [
4011
+ /* @__PURE__ */ jsx("p", { className: "font-semibold text-foreground", children: "Embed external content" }),
4012
+ /* @__PURE__ */ jsx("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: "Paste an embed URL or script snippet in the block settings." })
4013
+ ] })
4014
+ ] }) });
3963
4015
  }
3964
4016
  const isScript = contentType === "script";
3965
4017
  const ratio = aspectRatio !== "default" ? aspectRatioMap[aspectRatio] : void 0;
3966
- const containerStyle = ratio ? { position: "relative", paddingTop: `${100 / ratio}%` } : !isScript ? { height } : {};
3967
- const iframeStyle = ratio ? { position: "absolute", inset: 0, width: "100%", height: "100%" } : isScript ? { width: "100%", height } : { width: "100%", height: "100%" };
3968
- return /* @__PURE__ */ jsx(
3969
- Section,
3970
- {
3971
- theme: overriddenTheme,
3972
- id: cssId,
3973
- background,
3974
- nextTheme,
3975
- children: /* @__PURE__ */ jsx("div", { style: containerStyle, children: isScript ? /* @__PURE__ */ jsx(SandboxedEmbed, { content, style: iframeStyle }) : /* @__PURE__ */ jsx(
3976
- "iframe",
3977
- {
3978
- src: content,
3979
- style: iframeStyle,
3980
- allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
3981
- allowFullScreen: true,
3982
- title: "Embedded content"
3983
- }
3984
- ) })
3985
- }
3986
- );
4018
+ const containerStyle = ratio ? { position: "relative", paddingTop: `${100 / ratio}%` } : { position: "relative", height: isScript ? void 0 : height };
4019
+ const fillStyle = ratio ? { position: "absolute", inset: 0, width: "100%", height: "100%" } : { width: "100%", height: "100%" };
4020
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
4021
+ isScript ? /* @__PURE__ */ jsx(InlineEmbed, { content, style: ratio ? fillStyle : void 0 }) : /* @__PURE__ */ jsx(
4022
+ "iframe",
4023
+ {
4024
+ src: content,
4025
+ style: fillStyle,
4026
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
4027
+ allowFullScreen: true,
4028
+ title: "Embedded content"
4029
+ }
4030
+ ),
4031
+ editing && /* @__PURE__ */ jsx("div", { className: "absolute inset-0" })
4032
+ ] }) });
3987
4033
  }
3988
4034
  function EmbedEditor({ settings, onChange }) {
3989
4035
  const update = (partial) => onChange({ ...settings, ...partial });
@@ -4031,14 +4077,17 @@ function EmbedEditor({ settings, onChange }) {
4031
4077
  value: aspectRatio,
4032
4078
  onChange: (value) => update({ aspectRatio: value }),
4033
4079
  options: [
4034
- { label: "Default (fixed height)", value: "default" },
4080
+ {
4081
+ label: contentType === "url" ? "Default (fixed height)" : "Default (fit content)",
4082
+ value: "default"
4083
+ },
4035
4084
  { label: "Widescreen (16:9)", value: "16:9" },
4036
4085
  { label: "Standard (4:3)", value: "4:3" },
4037
4086
  { label: "Square (1:1)", value: "1:1" }
4038
4087
  ]
4039
4088
  }
4040
4089
  ),
4041
- aspectRatio === "default" && /* @__PURE__ */ jsx(
4090
+ aspectRatio === "default" && contentType === "url" && /* @__PURE__ */ jsx(
4042
4091
  NumberField,
4043
4092
  {
4044
4093
  label: "Height (px)",
@@ -4068,6 +4117,117 @@ var Embed = {
4068
4117
  getDefaultSettings: () => embedDefaults
4069
4118
  };
4070
4119
 
4120
+ // src/blocks/code-snippet/metadata.ts
4121
+ var codeSnippetMetadata = {
4122
+ name: "code-snippet",
4123
+ displayName: "Code snippet",
4124
+ description: "A command or short code sample with a copy button, like an install command.",
4125
+ compatibleWith: ["site", "landing", "blog", "post", "custom"],
4126
+ icon: "SquareTerminal"
4127
+ };
4128
+ function CodeSnippetWidget({
4129
+ settings: {
4130
+ code,
4131
+ showPrompt = true,
4132
+ caption,
4133
+ contentAlignment = "center",
4134
+ cssId,
4135
+ maxWidth,
4136
+ verticalPadding,
4137
+ background
4138
+ },
4139
+ state: { theme }
4140
+ }) {
4141
+ const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
4142
+ overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
4143
+ overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
4144
+ if (!code) return null;
4145
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: /* @__PURE__ */ jsxs(
4146
+ "div",
4147
+ {
4148
+ className: clsx3(
4149
+ "flex w-full max-w-2xl flex-col gap-3",
4150
+ contentAlignment === "center" ? "mx-auto items-center" : "items-start"
4151
+ ),
4152
+ children: [
4153
+ /* @__PURE__ */ jsx(
4154
+ CodeSnippet,
4155
+ {
4156
+ code,
4157
+ prompt: showPrompt ? "$" : void 0,
4158
+ theme: overriddenTheme
4159
+ }
4160
+ ),
4161
+ caption && /* @__PURE__ */ jsx(Caption, { theme: overriddenTheme, children: caption })
4162
+ ]
4163
+ }
4164
+ ) });
4165
+ }
4166
+ function CodeSnippetEditor({
4167
+ settings,
4168
+ onChange
4169
+ }) {
4170
+ const update = (partial) => onChange({ ...settings, ...partial });
4171
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
4172
+ /* @__PURE__ */ jsxs(FieldGroup, { title: "Content", children: [
4173
+ /* @__PURE__ */ jsx(
4174
+ TextField,
4175
+ {
4176
+ label: "Code",
4177
+ value: settings.code,
4178
+ placeholder: "curl -fsSL https://example.com/install.sh | sh",
4179
+ multiline: true,
4180
+ onChange: (code) => update({ code })
4181
+ }
4182
+ ),
4183
+ /* @__PURE__ */ jsx(
4184
+ ToggleField,
4185
+ {
4186
+ label: "Show $ prompt",
4187
+ value: settings.showPrompt ?? true,
4188
+ onChange: (showPrompt) => update({ showPrompt })
4189
+ }
4190
+ ),
4191
+ /* @__PURE__ */ jsx(
4192
+ TextField,
4193
+ {
4194
+ label: "Caption",
4195
+ value: settings.caption,
4196
+ placeholder: "e.g. macOS \xB7 Linux \xB7 Windows",
4197
+ onChange: (caption) => update({ caption })
4198
+ }
4199
+ )
4200
+ ] }),
4201
+ /* @__PURE__ */ jsx(FieldGroup, { title: "Layout", children: /* @__PURE__ */ jsx(
4202
+ SelectField,
4203
+ {
4204
+ label: "Alignment",
4205
+ value: settings.contentAlignment ?? "center",
4206
+ onChange: (contentAlignment) => update({ contentAlignment }),
4207
+ options: [
4208
+ { label: "Left", value: "left" },
4209
+ { label: "Center", value: "center" }
4210
+ ]
4211
+ }
4212
+ ) })
4213
+ ] });
4214
+ }
4215
+
4216
+ // src/blocks/code-snippet/defaults.ts
4217
+ var codeSnippetDefaults = {
4218
+ code: "curl -fsSL https://example.com/install.sh | sh",
4219
+ showPrompt: true,
4220
+ contentAlignment: "center"
4221
+ };
4222
+
4223
+ // src/blocks/code-snippet/index.ts
4224
+ var CodeSnippetBlock = {
4225
+ metadata: codeSnippetMetadata,
4226
+ widget: CodeSnippetWidget,
4227
+ editor: CodeSnippetEditor,
4228
+ getDefaultSettings: () => codeSnippetDefaults
4229
+ };
4230
+
4071
4231
  // src/blocks/data-slot/metadata.ts
4072
4232
  var dataSlotMetadata = {
4073
4233
  name: "data-slot",
@@ -4079,23 +4239,13 @@ function DataSlotWidget({
4079
4239
  data,
4080
4240
  editing,
4081
4241
  settings: { slot, cssId, maxWidth, verticalPadding, background },
4082
- state: { theme },
4083
- nextTheme
4242
+ state: { theme }
4084
4243
  }) {
4085
4244
  const overriddenTheme = JSON.parse(JSON.stringify(theme.theme));
4086
4245
  overriddenTheme.structure.page.width = maxWidth || theme.theme.structure.page.width;
4087
4246
  overriddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y;
4088
4247
  if (data !== void 0) {
4089
- return /* @__PURE__ */ jsx(
4090
- Section,
4091
- {
4092
- theme: overriddenTheme,
4093
- id: cssId,
4094
- background,
4095
- nextTheme,
4096
- children: data
4097
- }
4098
- );
4248
+ return /* @__PURE__ */ jsx(Section, { theme: overriddenTheme, id: cssId, background, children: data });
4099
4249
  }
4100
4250
  if (!editing) return null;
4101
4251
  return /* @__PURE__ */ jsx(
@@ -4104,7 +4254,6 @@ function DataSlotWidget({
4104
4254
  theme: overriddenTheme,
4105
4255
  id: cssId,
4106
4256
  background,
4107
- nextTheme,
4108
4257
  className: "border-y border-dashed border-border bg-muted/30",
4109
4258
  children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4110
4259
  /* @__PURE__ */ jsx("span", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-border bg-background text-muted-foreground", children: /* @__PURE__ */ jsx(LockKeyhole, { className: "h-4 w-4" }) }),
@@ -4128,6 +4277,6 @@ var DataSlot = {
4128
4277
  widget: DataSlotWidget
4129
4278
  };
4130
4279
 
4131
- export { Banner, Content, DataSlot, EmailForm, Embed, Faq, Featured, FieldGroup, Footer, Grid, Header, Hero, Marquee, MediaBlock, Pricing, RichText, SupportForm, TextField, ToggleField, generateUniqueId };
4132
- //# sourceMappingURL=chunk-UO7XGBGM.js.map
4133
- //# sourceMappingURL=chunk-UO7XGBGM.js.map
4280
+ export { Banner, CodeSnippetBlock, Content, DataSlot, EmailForm2 as EmailForm, Embed, Faq, Featured, FieldGroup, Footer, Grid, Header, Hero, Marquee, MediaBlock, Pricing, RichText, SupportForm2 as SupportForm, TextField, TitleSizeField, ToggleField, generateUniqueId };
4281
+ //# sourceMappingURL=chunk-K4WCLHMS.js.map
4282
+ //# sourceMappingURL=chunk-K4WCLHMS.js.map