@frontlit/page-builder 0.1.0-alpha.1

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/LICENSE +21 -0
  2. package/README.md +97 -0
  3. package/dist/alignment-dZDzN96G.d.ts +5 -0
  4. package/dist/blocks/index.d.ts +255 -0
  5. package/dist/blocks/index.js +6 -0
  6. package/dist/blocks/index.js.map +1 -0
  7. package/dist/builder/index.d.ts +240 -0
  8. package/dist/builder/index.js +8 -0
  9. package/dist/builder/index.js.map +1 -0
  10. package/dist/button-C3VrMJkr.d.ts +20 -0
  11. package/dist/chunk-7KIX4WAO.js +4229 -0
  12. package/dist/chunk-7KIX4WAO.js.map +1 -0
  13. package/dist/chunk-7W6Q4WA7.js +515 -0
  14. package/dist/chunk-7W6Q4WA7.js.map +1 -0
  15. package/dist/chunk-GTY75HW2.js +22 -0
  16. package/dist/chunk-GTY75HW2.js.map +1 -0
  17. package/dist/chunk-MO76KZY2.js +3580 -0
  18. package/dist/chunk-MO76KZY2.js.map +1 -0
  19. package/dist/chunk-RBJBODQP.js +2011 -0
  20. package/dist/chunk-RBJBODQP.js.map +1 -0
  21. package/dist/chunk-RUYOL7JZ.js +4 -0
  22. package/dist/chunk-RUYOL7JZ.js.map +1 -0
  23. package/dist/chunk-SSQWYMQR.js +393 -0
  24. package/dist/chunk-SSQWYMQR.js.map +1 -0
  25. package/dist/color-mode-DIEEt9WP.d.ts +3 -0
  26. package/dist/components/index.d.ts +36 -0
  27. package/dist/components/index.js +5 -0
  28. package/dist/components/index.js.map +1 -0
  29. package/dist/data-slots.d.ts +25 -0
  30. package/dist/data-slots.js +3 -0
  31. package/dist/data-slots.js.map +1 -0
  32. package/dist/fonts/alegreya/alegreya-latin-variable.woff2 +0 -0
  33. package/dist/fonts/bebas-neue/bebas-neue-latin-400-normal.woff2 +0 -0
  34. package/dist/fonts/inter/inter-latin-variable.woff2 +0 -0
  35. package/dist/fonts/lato/lato-latin-100-normal.woff2 +0 -0
  36. package/dist/fonts/lato/lato-latin-300-normal.woff2 +0 -0
  37. package/dist/fonts/lato/lato-latin-400-normal.woff2 +0 -0
  38. package/dist/fonts/lato/lato-latin-700-normal.woff2 +0 -0
  39. package/dist/fonts/lato/lato-latin-900-normal.woff2 +0 -0
  40. package/dist/fonts/merriweather/merriweather-latin-variable.woff2 +0 -0
  41. package/dist/fonts/montserrat/montserrat-latin-100-normal.woff2 +0 -0
  42. package/dist/fonts/montserrat/montserrat-latin-200-normal.woff2 +0 -0
  43. package/dist/fonts/montserrat/montserrat-latin-300-normal.woff2 +0 -0
  44. package/dist/fonts/montserrat/montserrat-latin-400-normal.woff2 +0 -0
  45. package/dist/fonts/montserrat/montserrat-latin-500-normal.woff2 +0 -0
  46. package/dist/fonts/montserrat/montserrat-latin-600-normal.woff2 +0 -0
  47. package/dist/fonts/montserrat/montserrat-latin-700-normal.woff2 +0 -0
  48. package/dist/fonts/montserrat/montserrat-latin-800-normal.woff2 +0 -0
  49. package/dist/fonts/montserrat/montserrat-latin-900-normal.woff2 +0 -0
  50. package/dist/fonts/montserrat/montserrat-latin-variable.woff2 +0 -0
  51. package/dist/fonts/mulish/mulish-latin-variable.woff2 +0 -0
  52. package/dist/fonts/noto-sans/noto-sans-latin-variable.woff2 +0 -0
  53. package/dist/fonts/nunito/nunito-latin-variable.woff2 +0 -0
  54. package/dist/fonts/open-sans/open-sans-latin-variable.woff2 +0 -0
  55. package/dist/fonts/oswald/oswald-latin-variable.woff2 +0 -0
  56. package/dist/fonts/playfair-display/playfair-display-latin-variable.woff2 +0 -0
  57. package/dist/fonts/poppins/poppins-latin-100-normal.woff2 +0 -0
  58. package/dist/fonts/poppins/poppins-latin-200-normal.woff2 +0 -0
  59. package/dist/fonts/poppins/poppins-latin-300-normal.woff2 +0 -0
  60. package/dist/fonts/poppins/poppins-latin-400-normal.woff2 +0 -0
  61. package/dist/fonts/poppins/poppins-latin-500-normal.woff2 +0 -0
  62. package/dist/fonts/poppins/poppins-latin-600-normal.woff2 +0 -0
  63. package/dist/fonts/poppins/poppins-latin-700-normal.woff2 +0 -0
  64. package/dist/fonts/poppins/poppins-latin-800-normal.woff2 +0 -0
  65. package/dist/fonts/poppins/poppins-latin-900-normal.woff2 +0 -0
  66. package/dist/fonts/pt-sans/pt-sans-latin-400-normal.woff2 +0 -0
  67. package/dist/fonts/pt-sans/pt-sans-latin-700-normal.woff2 +0 -0
  68. package/dist/fonts/quicksand/quicksand-latin-variable.woff2 +0 -0
  69. package/dist/fonts/raleway/raleway-latin-variable.woff2 +0 -0
  70. package/dist/fonts/roboto/roboto-latin-variable.woff2 +0 -0
  71. package/dist/fonts/roboto-slab/roboto-slab-latin-variable.woff2 +0 -0
  72. package/dist/fonts/rubik/rubik-latin-variable.woff2 +0 -0
  73. package/dist/fonts/source-sans-3/source-sans-3-latin-400-normal.woff2 +0 -0
  74. package/dist/fonts/source-sans-3/source-sans-3-latin-variable.woff2 +0 -0
  75. package/dist/fonts/source-serif-4/source-serif-4-latin-variable.woff2 +0 -0
  76. package/dist/fonts/work-sans/work-sans-latin-variable.woff2 +0 -0
  77. package/dist/image-D7GlnOio.d.ts +30 -0
  78. package/dist/index.d.ts +59 -0
  79. package/dist/index.js +10 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/media-Njv378j7.d.ts +13 -0
  82. package/dist/models/index.d.ts +8 -0
  83. package/dist/models/index.js +4 -0
  84. package/dist/models/index.js.map +1 -0
  85. package/dist/nav-link-BfxvQ1s6.d.ts +37 -0
  86. package/dist/page-DfVl_aHX.d.ts +26 -0
  87. package/dist/primitives/index.d.ts +140 -0
  88. package/dist/primitives/index.js +4 -0
  89. package/dist/primitives/index.js.map +1 -0
  90. package/dist/renderer/index.d.ts +81 -0
  91. package/dist/renderer/index.js +7 -0
  92. package/dist/renderer/index.js.map +1 -0
  93. package/dist/section-background-BgOCp5l3.d.ts +50 -0
  94. package/dist/styles.css +15322 -0
  95. package/dist/theme-style-39nxXQy0.d.ts +141 -0
  96. package/dist/theme.css +242 -0
  97. package/dist/widget--uEOpdq3.d.ts +105 -0
  98. package/package.json +142 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FrontLit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @frontlit/page-builder
2
+
3
+ Block-based page builder and renderer for React. Self-contained — no backend and no framework lock-in. Themes, blocks, and the WYSIWYG builder all run client-side.
4
+
5
+ Rich text editing and rendering live in [`@frontlit/text-editor`](https://www.npmjs.com/package/@frontlit/text-editor), which this package depends on and installs automatically.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm i @frontlit/page-builder
11
+ # or
12
+ pnpm add @frontlit/page-builder
13
+ ```
14
+
15
+ Peer dependencies: `react` and `react-dom` (^18 or ^19). Next.js is **not** required. Tailwind is **not** required — import the compiled stylesheet:
16
+
17
+ ```ts
18
+ import "@frontlit/page-builder/styles.css";
19
+ ```
20
+
21
+ That file includes the utilities, default tokens, the theme-picker fonts (Inter, Playfair, and the rest), and the TipTap prose styles from `@frontlit/text-editor`. Hosts that already inject those faces via `next/font` keep working: `--font-inter` on the document still wins.
22
+
23
+ If the host already runs Tailwind CSS v4, you can skip `styles.css` and scan the packages instead. Import the prose sheet so rich-text lists and code blocks survive Tailwind preflight:
24
+
25
+ ```css
26
+ @import "@frontlit/page-builder/theme.css";
27
+ @import "@frontlit/text-editor/prose.css";
28
+ @source "./node_modules/@frontlit/page-builder";
29
+ @source "./node_modules/@frontlit/text-editor";
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```tsx
35
+ import {
36
+ PageRenderer,
37
+ PageBuilder,
38
+ createDefaultLayout,
39
+ getDefaultTheme,
40
+ } from "@frontlit/page-builder";
41
+ import "@frontlit/page-builder/styles.css";
42
+
43
+
44
+ // Read-only rendering (a published page, a marketing site, a preview):
45
+ <PageRenderer
46
+ layout={createDefaultLayout()}
47
+ theme={getDefaultTheme()}
48
+ pageData={{ pageType: "landing" }}
49
+ />;
50
+
51
+ // The interactive editor — persist however you like:
52
+ <PageBuilder
53
+ onChange={({ layout, theme }) => {
54
+ /* save */
55
+ }}
56
+ />;
57
+ ```
58
+
59
+ Both `PageRenderer` and `PageBuilder` are client components (this package ships with a `"use client"` directive on UI entries).
60
+
61
+ ### Optional: client-side routing
62
+
63
+ Internal `/...` links render as native `<a>` tags by default, so the package works in Vite, Remix, Astro, or any other React host. Next.js (or any other router) can inject its own link:
64
+
65
+ ```tsx
66
+ import Link from "next/link";
67
+ import { PageRenderer, type PageBuilderLinkProps } from "@frontlit/page-builder";
68
+
69
+ function AppLink(props: PageBuilderLinkProps) {
70
+ return <Link {...props} />;
71
+ }
72
+
73
+ <PageRenderer layout={layout} theme={theme} linkComponent={AppLink} />;
74
+ ```
75
+
76
+ `PageBuilder` accepts the same `linkComponent` prop and forwards it to the live preview.
77
+
78
+ ## What's inside
79
+
80
+ | Subpath | What it exports |
81
+ | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
82
+ | `@frontlit/page-builder` | Everything below, re-exported from one place |
83
+ | `@frontlit/page-builder/models` | `Theme`, `WidgetInstance`, `Widget<T>`, `Page`, `Media`, etc. (re-exports `TextEditorContent` from `@frontlit/text-editor`) |
84
+ | `@frontlit/page-builder/primitives` | Themed UI atoms (`Button`, `Header1-4`, `Section`, `PageCard`, ...) + built-in themes |
85
+ | `@frontlit/page-builder/components` | Shared presentational bits: `Image`, `NavLink`, `VideoWithPreview` (re-exports `TextRenderer` from `@frontlit/text-editor`) |
86
+ | `@frontlit/page-builder/blocks` | The block library: Header, Hero, Content, Featured, Faq, Pricing, Banner, EmailForm, Footer, … |
87
+ | `@frontlit/page-builder/renderer` | `PageRenderer` — renders a page's `WidgetInstance[]` layout, with an `editing` mode for use inside the builder |
88
+ | `@frontlit/page-builder/builder` | `PageBuilder` — the full WYSIWYG editor (add/remove/reorder blocks, edit settings, switch themes) |
89
+ | `@frontlit/page-builder/data-slots` | Server-safe helper for hosts to resolve named data slots before rendering |
90
+
91
+ `createDefaultLayout()` / `getDefaultTheme()` (exported from the root) build a ready-to-render starter landing page.
92
+
93
+ `header` and `footer` are required layout-level blocks. The builder repairs legacy or empty initial layouts by adding them, keeps them at the outer edges, and never permits moving or deleting them.
94
+
95
+ ## License
96
+
97
+ MIT
@@ -0,0 +1,5 @@
1
+ type HorizontalAlignment = "center" | "left" | "right";
2
+ type VerticalAlignment = "top" | "bottom";
3
+ type Alignment = HorizontalAlignment | VerticalAlignment;
4
+
5
+ export type { Alignment as A, HorizontalAlignment as H, VerticalAlignment as V };
@@ -0,0 +1,255 @@
1
+ import { b as WidgetDefaultSettings, W as Widget } from '../widget--uEOpdq3.js';
2
+ import { M as Media } from '../media-Njv378j7.js';
3
+ import { A as Alignment, H as HorizontalAlignment } from '../alignment-dZDzN96G.js';
4
+ import { TextEditorContent } from '@frontlit/text-editor';
5
+ import { A as AspectRatio, a as ImageObjectFit } from '../image-D7GlnOio.js';
6
+ import 'react';
7
+ import '../section-background-BgOCp5l3.js';
8
+ import '../theme-style-39nxXQy0.js';
9
+
10
+ interface HeaderNavLink {
11
+ id: string;
12
+ label: string;
13
+ href: string;
14
+ isButton?: boolean;
15
+ }
16
+ interface HeaderSettings extends WidgetDefaultSettings {
17
+ logoText?: string;
18
+ logoImage?: string;
19
+ links?: HeaderNavLink[];
20
+ ctaLabel?: string;
21
+ ctaHref?: string;
22
+ linkAlignment?: "left" | "center" | "right";
23
+ layout?: "fixed" | "floating" | "centered";
24
+ backdropBlur?: boolean;
25
+ showThemeSwitcher?: boolean;
26
+ }
27
+
28
+ declare const Header: Widget<HeaderSettings>;
29
+
30
+ interface HeroSettings extends WidgetDefaultSettings {
31
+ /** Small label rendered above the title, e.g. a section eyebrow like "Careers". */
32
+ preTitle?: string;
33
+ title?: string;
34
+ description?: TextEditorContent;
35
+ buttonCaption?: string;
36
+ buttonAction?: string;
37
+ secondaryButtonCaption?: string;
38
+ secondaryButtonAction?: string;
39
+ media?: Media;
40
+ youtubeLink?: string;
41
+ alignment?: Alignment | "right";
42
+ contentAlignment?: Alignment;
43
+ mediaRadius?: number;
44
+ layout?: "normal" | "card" | "centered" | "media-below";
45
+ }
46
+
47
+ declare const Hero: Widget<HeroSettings>;
48
+
49
+ interface ContentSettings extends WidgetDefaultSettings {
50
+ title?: string;
51
+ body?: TextEditorContent;
52
+ media?: Media;
53
+ alignment?: "left" | "right";
54
+ headerAlignment?: Alignment;
55
+ mediaRadius?: number;
56
+ layout?: "side" | "stacked" | "overlay";
57
+ }
58
+
59
+ declare const Content: Widget<ContentSettings>;
60
+
61
+ interface FeatureItem {
62
+ title: string;
63
+ description?: string;
64
+ /** Name of a lucide-react icon, e.g. "Globe" or "Mail". */
65
+ icon?: string;
66
+ }
67
+ interface FeaturedSettings extends WidgetDefaultSettings {
68
+ title?: string;
69
+ description?: TextEditorContent;
70
+ headerAlignment?: Alignment;
71
+ items?: FeatureItem[];
72
+ layout?: "grid" | "list" | "compact" | "numbered";
73
+ }
74
+
75
+ declare const Featured: Widget<FeaturedSettings>;
76
+
77
+ interface FaqItem {
78
+ id: string;
79
+ question: string;
80
+ answer: string;
81
+ }
82
+ interface FaqSettings extends WidgetDefaultSettings {
83
+ title?: string;
84
+ headerAlignment?: Alignment;
85
+ items?: FaqItem[];
86
+ layout?: "list" | "cards" | "columns";
87
+ }
88
+
89
+ declare const Faq: Widget<FaqSettings>;
90
+
91
+ interface PricingTier {
92
+ name: string;
93
+ /** Plain display string, e.g. "$29/mo". No currency/period logic. */
94
+ price: string;
95
+ description?: string;
96
+ features: string[];
97
+ buttonCaption?: string;
98
+ buttonAction?: string;
99
+ highlighted?: boolean;
100
+ }
101
+ interface PricingSettings extends WidgetDefaultSettings {
102
+ title?: string;
103
+ description?: TextEditorContent;
104
+ headerAlignment?: Alignment;
105
+ tiers?: PricingTier[];
106
+ layout?: "grid" | "stacked" | "highlight";
107
+ }
108
+
109
+ declare const Pricing: Widget<PricingSettings>;
110
+
111
+ interface BannerSettings extends WidgetDefaultSettings {
112
+ title?: string;
113
+ description?: TextEditorContent;
114
+ buttonCaption?: string;
115
+ buttonAction?: string;
116
+ secondaryButtonCaption?: string;
117
+ secondaryButtonAction?: string;
118
+ contentAlignment?: Alignment;
119
+ layout?: "stacked" | "split" | "boxed";
120
+ }
121
+
122
+ declare const Banner: Widget<BannerSettings>;
123
+
124
+ interface EmailFormSettings extends WidgetDefaultSettings {
125
+ title?: string;
126
+ description?: TextEditorContent;
127
+ buttonCaption?: string;
128
+ successMessage?: string;
129
+ alignment?: Alignment;
130
+ layout?: "stacked" | "split" | "inline";
131
+ }
132
+
133
+ declare const EmailForm: Widget<EmailFormSettings>;
134
+
135
+ interface SupportFormSettings extends WidgetDefaultSettings {
136
+ title?: string;
137
+ description?: TextEditorContent;
138
+ buttonCaption?: string;
139
+ successMessage?: string;
140
+ alignment?: Alignment;
141
+ }
142
+
143
+ declare const SupportForm: Widget<SupportFormSettings>;
144
+
145
+ interface FooterLink {
146
+ id: string;
147
+ label: string;
148
+ href: string;
149
+ }
150
+ interface FooterColumn {
151
+ id: string;
152
+ title: string;
153
+ links: FooterLink[];
154
+ }
155
+ interface FooterSettings extends WidgetDefaultSettings {
156
+ logoText?: string;
157
+ tagline?: string;
158
+ columns?: FooterColumn[];
159
+ copyrightText?: string;
160
+ layout?: "columns" | "centered" | "minimal";
161
+ }
162
+
163
+ declare const Footer: Widget<FooterSettings>;
164
+
165
+ interface RichTextSettings extends WidgetDefaultSettings {
166
+ text?: TextEditorContent;
167
+ alignment?: HorizontalAlignment;
168
+ }
169
+
170
+ declare const RichText: Widget<RichTextSettings>;
171
+
172
+ interface GridItem {
173
+ title: string;
174
+ description?: string;
175
+ /** Name of a lucide-react icon; ignored when `media` is set. */
176
+ icon?: string;
177
+ media?: Media;
178
+ /**
179
+ * Whether the image renders above or below the title/description, or
180
+ * as a full-bleed background with the title overlaid on top of it
181
+ * (a "photo card" pattern — team/role/portfolio grids).
182
+ */
183
+ mediaAlignment?: "top" | "bottom" | "overlay";
184
+ buttonCaption?: string;
185
+ /** Card destination. In the "overlay" layout the whole card becomes a link when this is set, even without a caption. */
186
+ buttonAction?: string;
187
+ }
188
+ interface GridSettings extends WidgetDefaultSettings {
189
+ title?: string;
190
+ description?: TextEditorContent;
191
+ headerAlignment?: Alignment;
192
+ buttonCaption?: string;
193
+ buttonAction?: string;
194
+ items?: GridItem[];
195
+ columns?: 2 | 3;
196
+ }
197
+
198
+ declare const Grid: Widget<GridSettings>;
199
+
200
+ interface MediaSettings extends WidgetDefaultSettings {
201
+ media?: Media;
202
+ youtubeLink?: string;
203
+ mediaRadius?: number;
204
+ aspectRatio?: AspectRatio;
205
+ objectFit?: ImageObjectFit;
206
+ hasBorder?: boolean;
207
+ playVideoInModal?: boolean;
208
+ }
209
+
210
+ declare const MediaBlock: Widget<MediaSettings>;
211
+
212
+ interface MarqueeItem {
213
+ id: string;
214
+ text?: string;
215
+ href?: string;
216
+ /** Name of a lucide-react icon, e.g. "Globe" — overrides `text` when set. */
217
+ icon?: string;
218
+ }
219
+ interface MarqueeSettings extends WidgetDefaultSettings {
220
+ items?: MarqueeItem[];
221
+ direction?: "left" | "right";
222
+ /** Scroll speed in pixels per second. */
223
+ speed?: number;
224
+ pauseOnHover?: boolean;
225
+ /** Width in px of the edge fade-out effect; 0 disables it. */
226
+ fadeWidth?: number;
227
+ itemBackgroundColor?: string;
228
+ itemForegroundColor?: string;
229
+ itemBorderColor?: string;
230
+ itemBorderRadius?: number;
231
+ itemBorderWidth?: number;
232
+ itemBorderStyle?: "solid" | "dashed" | "dotted" | "double" | "none";
233
+ }
234
+
235
+ declare const Marquee: Widget<MarqueeSettings>;
236
+
237
+ interface EmbedSettings extends WidgetDefaultSettings {
238
+ contentType?: "url" | "script";
239
+ content?: string;
240
+ /** Colon-separated, matching common video-embed aspect ratio labels. */
241
+ aspectRatio?: "16:9" | "4:3" | "1:1" | "default";
242
+ /** Fixed height in px, used only when `aspectRatio` is "default". */
243
+ height?: number;
244
+ }
245
+
246
+ declare const Embed: Widget<EmbedSettings>;
247
+
248
+ interface DataSlotSettings extends WidgetDefaultSettings {
249
+ /** Name matched against the host application's data-slot loaders. */
250
+ slot: string;
251
+ }
252
+
253
+ declare const DataSlot: Widget<DataSlotSettings>;
254
+
255
+ export { Banner, type BannerSettings, Content, type ContentSettings, DataSlot, type DataSlotSettings, EmailForm, type EmailFormSettings, Embed, type EmbedSettings, Faq, type FaqItem, type FaqSettings, type FeatureItem, Featured, type FeaturedSettings, Footer, type FooterColumn, type FooterLink, type FooterSettings, Grid, type GridItem, type GridSettings, Header, type HeaderNavLink, type HeaderSettings, Hero, type HeroSettings, Marquee, type MarqueeItem, type MarqueeSettings, MediaBlock, type MediaSettings, Pricing, type PricingSettings, type PricingTier, RichText, type RichTextSettings, SupportForm, type SupportFormSettings };
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ export { Banner, Content, DataSlot, EmailForm, Embed, Faq, Featured, Footer, Grid, Header, Hero, Marquee, MediaBlock, Pricing, RichText, SupportForm } from '../chunk-7KIX4WAO.js';
3
+ import '../chunk-7W6Q4WA7.js';
4
+ import '../chunk-RBJBODQP.js';
5
+ //# sourceMappingURL=index.js.map
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,240 @@
1
+ import React__default from 'react';
2
+ import { T as Theme, S as SectionBackground } from '../section-background-BgOCp5l3.js';
3
+ import { d as WidgetInstance, P as PageData, W as Widget } from '../widget--uEOpdq3.js';
4
+ import { a as PageSeo } from '../page-DfVl_aHX.js';
5
+ import { P as PageBuilderLinkComponent } from '../nav-link-BfxvQ1s6.js';
6
+ import { LucideIcon } from 'lucide-react';
7
+ import { R as ResolvedColorMode } from '../color-mode-DIEEt9WP.js';
8
+ import { T as ThemeStyle } from '../theme-style-39nxXQy0.js';
9
+ import '../media-Njv378j7.js';
10
+
11
+ interface PageBuilderState {
12
+ layout: WidgetInstance[];
13
+ theme: Theme;
14
+ seo: PageSeo;
15
+ /** The user's own themes, created/edited from the theme panel. */
16
+ customThemes: Theme[];
17
+ }
18
+ interface PageBuilderProps {
19
+ initialLayout?: WidgetInstance[];
20
+ initialTheme?: Theme;
21
+ initialSeo?: PageSeo;
22
+ /**
23
+ * Themes offered in the theme panel, categorized like CourseLit's
24
+ * backend sends them: read-only `system` themes and the user's own
25
+ * `custom` themes. Defaults to the built-in presets and no custom
26
+ * themes. Editing a system theme copies it into the custom collection,
27
+ * which flows back to the host via `onChange`.
28
+ */
29
+ themes?: {
30
+ system?: Theme[];
31
+ custom?: Theme[];
32
+ };
33
+ pageData?: PageData;
34
+ onChange?: (state: PageBuilderState) => void;
35
+ /** Whether the editor may alter team-wide theme data. */
36
+ allowThemeEditing?: boolean;
37
+ /**
38
+ * Optional host link (e.g. Next.js `Link`) forwarded to the live
39
+ * preview's `PageRenderer`. Omit it to render native `<a>` tags.
40
+ */
41
+ linkComponent?: PageBuilderLinkComponent;
42
+ className?: string;
43
+ }
44
+ /**
45
+ * A self-contained, client-side WYSIWYG page builder: pick a theme, add/
46
+ * remove/reorder blocks, and edit each block's settings from the side
47
+ * panel. Holds all state in memory (via `onChange`, the host app decides
48
+ * whether/how to persist it) — there is no backend dependency.
49
+ */
50
+ declare function PageBuilder({ initialLayout, initialTheme, initialSeo, themes: providedThemes, pageData, onChange, allowThemeEditing, linkComponent, className, }: PageBuilderProps): React__default.JSX.Element;
51
+
52
+ declare function SettingsPanel({ title, onClose, children, eyebrow, description, icon, }: {
53
+ title: string;
54
+ onClose: () => void;
55
+ children: React__default.ReactNode;
56
+ eyebrow?: string;
57
+ description?: string;
58
+ icon?: LucideIcon;
59
+ }): React__default.JSX.Element;
60
+
61
+ declare function BlockPicker({ blocks, onPick, onClose, }: {
62
+ blocks: Widget<any>[];
63
+ onPick: (name: string) => void;
64
+ onClose: () => void;
65
+ }): React__default.JSX.Element;
66
+
67
+ type PreviewDevice = "mobile" | "tablet" | "desktop";
68
+ declare function BuilderTopBar({ resolvedMode, onModeChange, device, onDeviceChange, onOpenTheme, onOpenSeo, onAddBlock, allowThemeEditing, }: {
69
+ resolvedMode: ResolvedColorMode;
70
+ onModeChange: (mode: ResolvedColorMode) => void;
71
+ device: PreviewDevice;
72
+ onDeviceChange: (device: PreviewDevice) => void;
73
+ onOpenTheme: () => void;
74
+ onOpenSeo: () => void;
75
+ onAddBlock: () => void;
76
+ allowThemeEditing?: boolean;
77
+ }): React__default.JSX.Element;
78
+
79
+ /**
80
+ * Label row for a page-builder design control. Ported from CourseLit's
81
+ * PageBuilderPropertyHeader; the tooltip is rendered via the native `title`
82
+ * attribute so no tooltip dependency is needed.
83
+ */
84
+ declare function PageBuilderPropertyHeader({ label, tooltip, }: {
85
+ label: string;
86
+ tooltip?: string;
87
+ }): React__default.JSX.Element;
88
+
89
+ /**
90
+ * Slider with a paired numeric input, ported from CourseLit's
91
+ * PageBuilderSlider. Uses a native range input instead of Radix Slider so it
92
+ * adds no dependencies.
93
+ */
94
+ declare function PageBuilderSlider({ title, min, max, value, onChange, tooltip, className, allowsReset, unit, }: {
95
+ title: string;
96
+ min: number;
97
+ max: number;
98
+ value: number;
99
+ onChange: (value?: number) => void;
100
+ tooltip?: string;
101
+ className?: string;
102
+ allowsReset?: boolean;
103
+ unit?: string;
104
+ }): React__default.JSX.Element;
105
+
106
+ /**
107
+ * Color picker ported from CourseLit's ColorSelector. Uses a native
108
+ * `<input type="color">` swatch paired with a hex text input — no
109
+ * dependencies on a color-picker library.
110
+ */
111
+ declare function ColorSelector({ title, value, onChange, tooltip, className, allowReset, description, }: {
112
+ title: string;
113
+ value: string;
114
+ onChange: (value?: string) => void;
115
+ tooltip?: string;
116
+ className?: string;
117
+ allowReset?: boolean;
118
+ description?: string;
119
+ }): React__default.JSX.Element;
120
+
121
+ type PageWidth = ThemeStyle["structure"]["page"]["width"];
122
+ declare function getMaxWidthTWClass(value: number): PageWidth;
123
+ interface MaxWidthSelectorProps {
124
+ value?: PageWidth;
125
+ onChange: (width?: PageWidth) => void;
126
+ className?: string;
127
+ /**
128
+ * The value actually applied when `value` is unset — the active
129
+ * theme's own page width. Without this the slider could display a
130
+ * width that doesn't match what's really rendered.
131
+ */
132
+ themeDefault?: PageWidth;
133
+ }
134
+ declare function MaxWidthSelector({ value, onChange, className, themeDefault, }: MaxWidthSelectorProps): React__default.JSX.Element;
135
+
136
+ type VerticalPadding = ThemeStyle["structure"]["section"]["padding"]["y"];
137
+ declare function getVerticalPaddingTWClass(value: number): VerticalPadding;
138
+ interface VerticalPaddingSelectorProps {
139
+ value?: VerticalPadding;
140
+ onChange: (padding?: VerticalPadding) => void;
141
+ className?: string;
142
+ /**
143
+ * The value actually applied when `value` is unset — the active
144
+ * theme's own section padding. Without this the slider would default
145
+ * to displaying 0 regardless of the real (usually much larger) padding
146
+ * in effect, misleading the user into thinking nothing is applied.
147
+ */
148
+ themeDefault?: VerticalPadding;
149
+ }
150
+ declare function VerticalPaddingSelector({ value, onChange, className, themeDefault, }: VerticalPaddingSelectorProps): React__default.JSX.Element;
151
+
152
+ interface ContentPaddingProps {
153
+ value: number;
154
+ onChange: (padding?: number) => void;
155
+ className?: string;
156
+ min?: number;
157
+ max?: number;
158
+ variant?: "vertical" | "horizontal";
159
+ }
160
+ declare function ContentPaddingSelector({ value, onChange, className, variant, min, max, }: ContentPaddingProps): React__default.JSX.Element;
161
+
162
+ interface SectionBackgroundPanelProps {
163
+ value?: SectionBackground;
164
+ onChange: (value: SectionBackground) => void;
165
+ className?: string;
166
+ }
167
+ /**
168
+ * Section background editor for the Design tab. Segmented type switcher,
169
+ * live preview, and card-grouped controls that write into the same
170
+ * `SectionBackground` model as before.
171
+ */
172
+ declare function SectionBackgroundPanel({ value, onChange, className, }: SectionBackgroundPanelProps): React__default.JSX.Element;
173
+
174
+ type PatternPresetCategory = "tile" | "glow";
175
+ interface PatternPreset {
176
+ id: string;
177
+ label: string;
178
+ /** Grouping for the preset filter chips in the background panel. */
179
+ category: PatternPresetCategory;
180
+ /** Short blurb for tooltips / a11y. */
181
+ description?: string;
182
+ /**
183
+ * Fields merged into the background's "gradient" (pattern) settings.
184
+ * Light-mode pattern first; dark variants use lower-opacity white
185
+ * strokes so the same tile reads on dark section colors.
186
+ */
187
+ apply: Pick<SectionBackground, "backgroundImage" | "backgroundImageDark" | "gradientBackgroundSize" | "gradientBackgroundPosition" | "gradientBackgroundRepeat" | "gradientMaskImage">;
188
+ }
189
+ /**
190
+ * Ready-made background patterns for the "Pattern" tab of the section
191
+ * background panel — a preset picker over the same free-CSS
192
+ * `backgroundImage` / size / repeat fields, so choosing one is a single
193
+ * click instead of hand-writing an SVG data URI. Tiled patterns include
194
+ * dark-mode twins; mesh/glow presets use full-bleed CSS gradients.
195
+ *
196
+ * Tune any field afterwards under Advanced, or bring your own CSS.
197
+ */
198
+ declare const PATTERN_PRESETS: PatternPreset[];
199
+
200
+ interface ThemeEditorProps {
201
+ /** Theme currently painted on the canvas (applied, or a local preview). */
202
+ theme: Theme;
203
+ /** Id of the theme actually applied to the site. */
204
+ appliedThemeId: string;
205
+ /** Built-in themes; read-only, editing one creates a custom copy. */
206
+ systemThemes: Theme[];
207
+ /** The user's own themes; edited in place. */
208
+ customThemes: Theme[];
209
+ colorMode: "light" | "dark";
210
+ onColorModeChange: (mode: "light" | "dark") => void;
211
+ /** Paint a theme on the canvas without applying it. */
212
+ onPreview: (theme: Theme) => void;
213
+ /** Apply a theme to the page. */
214
+ onApply: (theme: Theme) => void;
215
+ /** Persist a change to the custom themes collection. */
216
+ onCustomThemesChange: (themes: Theme[]) => void;
217
+ }
218
+ /**
219
+ * Visual theme editor ported from CourseLit's page-editor theme editor.
220
+ * Themes are listed in two groups — system and custom. Clicking a card
221
+ * previews it on the canvas without applying it. Each card also offers
222
+ * "use" (check) and "edit" (pencil). Editing a system theme first copies
223
+ * it into the custom collection ("X - Copy"), so system themes stay
224
+ * pristine; custom themes are edited in place. The host app persists both
225
+ * the applied theme and the custom collection via the builder's `onChange`.
226
+ */
227
+ declare function ThemeEditor({ theme, appliedThemeId, systemThemes, customThemes, colorMode, onColorModeChange, onPreview, onApply, onCustomThemesChange, }: ThemeEditorProps): React__default.JSX.Element;
228
+
229
+ /**
230
+ * Page-level SEO settings panel. Like the block and theme editors, changes
231
+ * apply live — the host app persists them via the builder's `onChange`.
232
+ * Adapted from CourseLit's SeoEditor, minus the media library (images are
233
+ * referenced by URL, matching the rest of this package).
234
+ */
235
+ declare function SeoEditor({ seo, onChange, }: {
236
+ seo: PageSeo;
237
+ onChange: (seo: PageSeo) => void;
238
+ }): React__default.JSX.Element;
239
+
240
+ export { BlockPicker, BuilderTopBar, ColorSelector, ContentPaddingSelector, MaxWidthSelector, PATTERN_PRESETS, PageBuilder, PageBuilderPropertyHeader, type PageBuilderProps, PageBuilderSlider, type PageBuilderState, type PatternPreset, type PatternPresetCategory, type PreviewDevice, SectionBackgroundPanel, SeoEditor, SettingsPanel, ThemeEditor, type ThemeEditorProps, VerticalPaddingSelector, getMaxWidthTWClass, getVerticalPaddingTWClass };
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ export { BlockPicker, BuilderTopBar, ColorSelector, ContentPaddingSelector, MaxWidthSelector, PATTERN_PRESETS, PageBuilder, PageBuilderPropertyHeader, PageBuilderSlider, SectionBackgroundPanel, SeoEditor, SettingsPanel, ThemeEditor, VerticalPaddingSelector, getMaxWidthTWClass, getVerticalPaddingTWClass } from '../chunk-MO76KZY2.js';
3
+ import '../chunk-SSQWYMQR.js';
4
+ import '../chunk-7KIX4WAO.js';
5
+ import '../chunk-7W6Q4WA7.js';
6
+ import '../chunk-RBJBODQP.js';
7
+ //# sourceMappingURL=index.js.map
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+ import * as class_variance_authority_types from 'class-variance-authority/types';
4
+ import { VariantProps } from 'class-variance-authority';
5
+ import { T as ThemeStyle } from './theme-style-39nxXQy0.js';
6
+
7
+ declare const buttonVariants: (props?: {
8
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost";
9
+ size?: "default" | "icon" | "sm" | "lg";
10
+ } & class_variance_authority_types.ClassProp) => string;
11
+ interface ButtonProps$1 extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
12
+ asChild?: boolean;
13
+ }
14
+
15
+ interface ButtonProps extends ButtonProps$1 {
16
+ theme?: ThemeStyle;
17
+ }
18
+ declare const Button: React__default.FC<ButtonProps>;
19
+
20
+ export { type ButtonProps as B, Button as a };