@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.
- package/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/alignment-dZDzN96G.d.ts +5 -0
- package/dist/blocks/index.d.ts +255 -0
- package/dist/blocks/index.js +6 -0
- package/dist/blocks/index.js.map +1 -0
- package/dist/builder/index.d.ts +240 -0
- package/dist/builder/index.js +8 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/button-C3VrMJkr.d.ts +20 -0
- package/dist/chunk-7KIX4WAO.js +4229 -0
- package/dist/chunk-7KIX4WAO.js.map +1 -0
- package/dist/chunk-7W6Q4WA7.js +515 -0
- package/dist/chunk-7W6Q4WA7.js.map +1 -0
- package/dist/chunk-GTY75HW2.js +22 -0
- package/dist/chunk-GTY75HW2.js.map +1 -0
- package/dist/chunk-MO76KZY2.js +3580 -0
- package/dist/chunk-MO76KZY2.js.map +1 -0
- package/dist/chunk-RBJBODQP.js +2011 -0
- package/dist/chunk-RBJBODQP.js.map +1 -0
- package/dist/chunk-RUYOL7JZ.js +4 -0
- package/dist/chunk-RUYOL7JZ.js.map +1 -0
- package/dist/chunk-SSQWYMQR.js +393 -0
- package/dist/chunk-SSQWYMQR.js.map +1 -0
- package/dist/color-mode-DIEEt9WP.d.ts +3 -0
- package/dist/components/index.d.ts +36 -0
- package/dist/components/index.js +5 -0
- package/dist/components/index.js.map +1 -0
- package/dist/data-slots.d.ts +25 -0
- package/dist/data-slots.js +3 -0
- package/dist/data-slots.js.map +1 -0
- package/dist/fonts/alegreya/alegreya-latin-variable.woff2 +0 -0
- package/dist/fonts/bebas-neue/bebas-neue-latin-400-normal.woff2 +0 -0
- package/dist/fonts/inter/inter-latin-variable.woff2 +0 -0
- package/dist/fonts/lato/lato-latin-100-normal.woff2 +0 -0
- package/dist/fonts/lato/lato-latin-300-normal.woff2 +0 -0
- package/dist/fonts/lato/lato-latin-400-normal.woff2 +0 -0
- package/dist/fonts/lato/lato-latin-700-normal.woff2 +0 -0
- package/dist/fonts/lato/lato-latin-900-normal.woff2 +0 -0
- package/dist/fonts/merriweather/merriweather-latin-variable.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-100-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-200-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-300-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-600-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-700-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-800-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-900-normal.woff2 +0 -0
- package/dist/fonts/montserrat/montserrat-latin-variable.woff2 +0 -0
- package/dist/fonts/mulish/mulish-latin-variable.woff2 +0 -0
- package/dist/fonts/noto-sans/noto-sans-latin-variable.woff2 +0 -0
- package/dist/fonts/nunito/nunito-latin-variable.woff2 +0 -0
- package/dist/fonts/open-sans/open-sans-latin-variable.woff2 +0 -0
- package/dist/fonts/oswald/oswald-latin-variable.woff2 +0 -0
- package/dist/fonts/playfair-display/playfair-display-latin-variable.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-100-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-200-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-300-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-400-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-500-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-600-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-700-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-800-normal.woff2 +0 -0
- package/dist/fonts/poppins/poppins-latin-900-normal.woff2 +0 -0
- package/dist/fonts/pt-sans/pt-sans-latin-400-normal.woff2 +0 -0
- package/dist/fonts/pt-sans/pt-sans-latin-700-normal.woff2 +0 -0
- package/dist/fonts/quicksand/quicksand-latin-variable.woff2 +0 -0
- package/dist/fonts/raleway/raleway-latin-variable.woff2 +0 -0
- package/dist/fonts/roboto/roboto-latin-variable.woff2 +0 -0
- package/dist/fonts/roboto-slab/roboto-slab-latin-variable.woff2 +0 -0
- package/dist/fonts/rubik/rubik-latin-variable.woff2 +0 -0
- package/dist/fonts/source-sans-3/source-sans-3-latin-400-normal.woff2 +0 -0
- package/dist/fonts/source-sans-3/source-sans-3-latin-variable.woff2 +0 -0
- package/dist/fonts/source-serif-4/source-serif-4-latin-variable.woff2 +0 -0
- package/dist/fonts/work-sans/work-sans-latin-variable.woff2 +0 -0
- package/dist/image-D7GlnOio.d.ts +30 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/media-Njv378j7.d.ts +13 -0
- package/dist/models/index.d.ts +8 -0
- package/dist/models/index.js +4 -0
- package/dist/models/index.js.map +1 -0
- package/dist/nav-link-BfxvQ1s6.d.ts +37 -0
- package/dist/page-DfVl_aHX.d.ts +26 -0
- package/dist/primitives/index.d.ts +140 -0
- package/dist/primitives/index.js +4 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/renderer/index.d.ts +81 -0
- package/dist/renderer/index.js +7 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/section-background-BgOCp5l3.d.ts +50 -0
- package/dist/styles.css +15322 -0
- package/dist/theme-style-39nxXQy0.d.ts +141 -0
- package/dist/theme.css +242 -0
- package/dist/widget--uEOpdq3.d.ts +105 -0
- 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,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 };
|