@siteable/core 0.1.0
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/NOTICE +4 -0
- package/README.md +82 -0
- package/dist/index.d.ts +401 -0
- package/dist/index.js +5389 -0
- package/package.json +66 -0
- package/src/blocks/BlockWrapper.tsx +149 -0
- package/src/blocks/banner/BannerBlock.tsx +38 -0
- package/src/blocks/contact/ContactBlock.tsx +63 -0
- package/src/blocks/content/ContentBlock.tsx +38 -0
- package/src/blocks/cta/CtaBlock.tsx +67 -0
- package/src/blocks/divider/DividerBlock.tsx +30 -0
- package/src/blocks/faq/FaqBlock.tsx +82 -0
- package/src/blocks/features/FeaturesBlock.tsx +170 -0
- package/src/blocks/footer/FooterBlock.tsx +136 -0
- package/src/blocks/gallery/GalleryBlock.tsx +67 -0
- package/src/blocks/hero/HeroBlock.tsx +163 -0
- package/src/blocks/image/ImageBlock.tsx +78 -0
- package/src/blocks/logocloud/LogoCloudBlock.tsx +70 -0
- package/src/blocks/navbar/NavbarBlock.tsx +102 -0
- package/src/blocks/newsletter/NewsletterBlock.tsx +51 -0
- package/src/blocks/pricing/PricingBlock.tsx +173 -0
- package/src/blocks/registry.tsx +90 -0
- package/src/blocks/stats/StatsBlock.tsx +96 -0
- package/src/blocks/team/TeamBlock.tsx +50 -0
- package/src/blocks/testimonials/TestimonialsBlock.tsx +203 -0
- package/src/blocks/types.ts +72 -0
- package/src/blocks/video/VideoBlock.tsx +58 -0
- package/src/editor/AgentPanel.tsx +318 -0
- package/src/editor/Canvas.tsx +95 -0
- package/src/editor/CanvasEmpty.tsx +40 -0
- package/src/editor/CanvasToolbar.tsx +366 -0
- package/src/editor/DesignPanel.tsx +224 -0
- package/src/editor/EditorLayout.tsx +196 -0
- package/src/editor/GenerationOverlay.tsx +201 -0
- package/src/editor/JsonDrawer.tsx +139 -0
- package/src/editor/LayersPanel.tsx +259 -0
- package/src/editor/LeftSidebar.tsx +136 -0
- package/src/editor/PropertiesPanel.tsx +564 -0
- package/src/editor/RightSidebar.tsx +85 -0
- package/src/editor/ShortcutsModal.tsx +126 -0
- package/src/editor/VersionHistory.tsx +110 -0
- package/src/index.ts +133 -0
- package/src/lib/block-metadata.ts +167 -0
- package/src/lib/export-html.ts +1424 -0
- package/src/lib/generate-site.ts +206 -0
- package/src/lib/generation-prompt.ts +64 -0
- package/src/lib/markdown.ts +88 -0
- package/src/lib/templates.ts +139 -0
- package/src/lib/theme-presets.ts +330 -0
- package/src/lib/useGoogleFonts.ts +49 -0
- package/src/lib/useScrollReveal.ts +28 -0
- package/src/settings/GeminiKeyInputField.tsx +82 -0
- package/src/store/configStore.ts +344 -0
- package/src/store/editorStore.ts +50 -0
- package/src/styles.css +210 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Federico De Ponte
|
|
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/NOTICE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @siteable/core
|
|
2
|
+
|
|
3
|
+
A visual website builder engine: 19 typed block components, a drag-edit canvas, theme
|
|
4
|
+
presets, AI generation, and a one-click HTML export. JSON is the source of truth — every
|
|
5
|
+
edit produces clean, diffable JSON that humans and AI agents can both read and write.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @siteable/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Peer Dependencies
|
|
14
|
+
|
|
15
|
+
The host app supplies these — `@siteable/core` declares them as peerDependencies but does
|
|
16
|
+
not bundle them. Install with caret ranges matching the package's own peer spec:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install react@^19.2.0 react-dom@^19.2.0 zustand@^5.0.11 immer@^11.1.4 \
|
|
20
|
+
@dnd-kit/core@^6.3.1 @dnd-kit/sortable@^10.0.0 @dnd-kit/utilities@^3.2.2 \
|
|
21
|
+
sonner@^2.0.7 lucide-react@^0.575.0 tailwindcss@^4.2.1
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`react-router-dom` is **not** a peer — the engine is router-agnostic.
|
|
25
|
+
|
|
26
|
+
## Tailwind v4 Setup
|
|
27
|
+
|
|
28
|
+
Add `@source` and `@import` to your app's global CSS so Tailwind v4's scanner picks up the
|
|
29
|
+
package's block component classes:
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
/* app.css */
|
|
33
|
+
@import "tailwindcss";
|
|
34
|
+
|
|
35
|
+
@source "./node_modules/@siteable/core/src/**/*.{ts,tsx}";
|
|
36
|
+
@import "@siteable/core/src/styles.css";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The package ships raw, unbuilt Tailwind v4 source (no precompiled CSS in `dist/`).
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { EditorLayout } from '@siteable/core'
|
|
45
|
+
|
|
46
|
+
function App() {
|
|
47
|
+
return <EditorLayout />
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`validateSiteConfig`, `generateSiteConfig`, `exportSiteToHTML`, `themePresets`, and the
|
|
52
|
+
two zustand stores (`useConfigStore`, `useEditorStore`) are all available from the package
|
|
53
|
+
entry.
|
|
54
|
+
|
|
55
|
+
## Single-store invariant
|
|
56
|
+
|
|
57
|
+
`useConfigStore` and `useEditorStore` are zustand module singletons. Always import through
|
|
58
|
+
the package entry (`@siteable/core`) — never deep-import `@siteable/core/src/...` in an app
|
|
59
|
+
that also imports the package's main entry. Two copies of the same store in one app silently
|
|
60
|
+
produce divergent state.
|
|
61
|
+
|
|
62
|
+
## Browser Support
|
|
63
|
+
|
|
64
|
+
Modern evergreen browsers (last 2 Chrome / Firefox / Safari / Edge versions). No IE.
|
|
65
|
+
|
|
66
|
+
## Contributing
|
|
67
|
+
|
|
68
|
+
Issues and PRs welcome via [GitHub](https://github.com/Siteable/siteable-core/issues).
|
|
69
|
+
|
|
70
|
+
## License
|
|
71
|
+
|
|
72
|
+
MIT — see [LICENSE](./LICENSE) and [NOTICE](./NOTICE).
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Provenance
|
|
77
|
+
|
|
78
|
+
This is the engine subset extracted from
|
|
79
|
+
[OpenPage](https://github.com/buildingopen/openpage). The MIT body, attribution, and
|
|
80
|
+
adopted-conventions headers carry over from that codebase; the package is maintained
|
|
81
|
+
independently under the `@siteable` npm scope with `Siteable Contributors` as the copyright
|
|
82
|
+
holder (see NOTICE for the full lineage statement).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import { JSX } from 'react';
|
|
2
|
+
import { PersistOptions } from 'zustand/middleware';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { RefObject } from 'react';
|
|
5
|
+
import { StoreApi } from 'zustand';
|
|
6
|
+
import { UseBoundStore } from 'zustand';
|
|
7
|
+
|
|
8
|
+
export declare function AgentPanel(): JSX.Element;
|
|
9
|
+
|
|
10
|
+
export declare function BannerBlock({ block }: {
|
|
11
|
+
block: BlockConfig;
|
|
12
|
+
}): JSX.Element;
|
|
13
|
+
|
|
14
|
+
export declare interface BlockConfig {
|
|
15
|
+
id: string;
|
|
16
|
+
type: BlockType;
|
|
17
|
+
variant: BlockVariant;
|
|
18
|
+
props: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export declare interface BlockMeta {
|
|
22
|
+
type: BlockType;
|
|
23
|
+
label: string;
|
|
24
|
+
description: string;
|
|
25
|
+
category: string;
|
|
26
|
+
variants: string[];
|
|
27
|
+
defaultProps: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export declare const blockMetadata: BlockMeta[];
|
|
31
|
+
|
|
32
|
+
export declare type BlockType = 'navbar' | 'hero' | 'features' | 'pricing' | 'cta' | 'footer' | 'testimonials' | 'stats' | 'faq' | 'team' | 'contact' | 'newsletter' | 'logocloud' | 'divider' | 'banner' | 'content' | 'image' | 'video' | 'gallery';
|
|
33
|
+
|
|
34
|
+
export declare type BlockVariant = string;
|
|
35
|
+
|
|
36
|
+
export declare function BlockWrapper({ block, isSelected, onSelect, children }: Props): JSX.Element;
|
|
37
|
+
|
|
38
|
+
export declare function buildTemplate(id: string, name: string): SiteConfig;
|
|
39
|
+
|
|
40
|
+
export declare function Canvas(): JSX.Element;
|
|
41
|
+
|
|
42
|
+
export declare function CanvasEmpty(): JSX.Element;
|
|
43
|
+
|
|
44
|
+
export declare function CanvasToolbar({ activeProject, onExit }?: CanvasToolbarProps): JSX.Element;
|
|
45
|
+
|
|
46
|
+
export declare interface CanvasToolbarProps {
|
|
47
|
+
activeProject?: {
|
|
48
|
+
name: string;
|
|
49
|
+
settings?: ExportSiteSettings;
|
|
50
|
+
};
|
|
51
|
+
onExit?: () => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export declare const categories: string[];
|
|
55
|
+
|
|
56
|
+
declare interface ConfigState {
|
|
57
|
+
config: SiteConfig;
|
|
58
|
+
activePageId: string;
|
|
59
|
+
undoStack: UndoEntry[];
|
|
60
|
+
redoStack: UndoEntry[];
|
|
61
|
+
setConfig: (config: SiteConfig) => void;
|
|
62
|
+
setActivePage: (id: string) => void;
|
|
63
|
+
getActivePageBlocks: () => BlockConfig[];
|
|
64
|
+
updateBlock: (id: string, updates: Partial<BlockConfig>) => void;
|
|
65
|
+
updateBlockProps: (id: string, props: Record<string, unknown>) => void;
|
|
66
|
+
addBlock: (block: BlockConfig, index?: number) => void;
|
|
67
|
+
removeBlock: (id: string) => void;
|
|
68
|
+
duplicateBlock: (id: string) => void;
|
|
69
|
+
moveBlock: (fromIndex: number, toIndex: number) => void;
|
|
70
|
+
addPage: (name: string, path: string) => string;
|
|
71
|
+
removePage: (id: string) => void;
|
|
72
|
+
renamePage: (id: string, name: string) => void;
|
|
73
|
+
setTheme: (theme: Partial<ThemeConfig>) => void;
|
|
74
|
+
updateTheme: (partial: Partial<ThemeConfig>) => void;
|
|
75
|
+
previewTheme: (partial: Partial<ThemeConfig>) => void;
|
|
76
|
+
undo: () => void;
|
|
77
|
+
redo: () => void;
|
|
78
|
+
canUndo: () => boolean;
|
|
79
|
+
canRedo: () => boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export declare function ContactBlock({ block }: {
|
|
83
|
+
block: BlockConfig;
|
|
84
|
+
}): JSX.Element;
|
|
85
|
+
|
|
86
|
+
export declare function ContentBlock({ block }: {
|
|
87
|
+
block: BlockConfig;
|
|
88
|
+
}): JSX.Element;
|
|
89
|
+
|
|
90
|
+
export declare function CtaBlock({ block }: {
|
|
91
|
+
block: BlockConfig;
|
|
92
|
+
}): JSX.Element;
|
|
93
|
+
|
|
94
|
+
export declare const defaultConfig: SiteConfig;
|
|
95
|
+
|
|
96
|
+
export declare const defaultTheme: ThemeConfig;
|
|
97
|
+
|
|
98
|
+
export declare function DesignPanel(): JSX.Element;
|
|
99
|
+
|
|
100
|
+
export declare function DividerBlock({ block }: {
|
|
101
|
+
block: BlockConfig;
|
|
102
|
+
}): JSX.Element;
|
|
103
|
+
|
|
104
|
+
export declare function downloadHTML(html: string, filename: string): void;
|
|
105
|
+
|
|
106
|
+
export declare function EditorLayout({ onConfigChange, onRename, onCreate, activeProject, onExit, onServerFallback }?: EditorLayoutProps): JSX.Element;
|
|
107
|
+
|
|
108
|
+
export declare interface EditorLayoutProps {
|
|
109
|
+
onConfigChange?: (id: string, config: SiteConfig) => void;
|
|
110
|
+
onRename?: (id: string, name: string) => void;
|
|
111
|
+
onCreate?: (name: string) => string;
|
|
112
|
+
activeProject?: {
|
|
113
|
+
name: string;
|
|
114
|
+
settings?: ExportSiteSettings;
|
|
115
|
+
};
|
|
116
|
+
onExit?: () => void;
|
|
117
|
+
onServerFallback?: (prompt: string, signal?: AbortSignal) => Promise<SiteConfig>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
declare interface EditorState {
|
|
121
|
+
selectedBlockId: string | null;
|
|
122
|
+
viewport: Viewport;
|
|
123
|
+
jsonDrawerOpen: boolean;
|
|
124
|
+
historyOpen: boolean;
|
|
125
|
+
shortcutsModalOpen: boolean;
|
|
126
|
+
previewMode: boolean;
|
|
127
|
+
activeProjectId: string | null;
|
|
128
|
+
isGenerating: boolean;
|
|
129
|
+
generationPrompt: string | null;
|
|
130
|
+
generationError: string | null;
|
|
131
|
+
selectBlock: (id: string | null) => void;
|
|
132
|
+
setViewport: (vp: Viewport) => void;
|
|
133
|
+
toggleJsonDrawer: () => void;
|
|
134
|
+
toggleHistory: () => void;
|
|
135
|
+
toggleShortcutsModal: () => void;
|
|
136
|
+
togglePreview: () => void;
|
|
137
|
+
setActiveProject: (id: string | null) => void;
|
|
138
|
+
setGenerating: (prompt: string | null) => void;
|
|
139
|
+
setGenerationError: (err: string | null) => void;
|
|
140
|
+
clearGeneration: () => void;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export declare interface ExportSiteOptions {
|
|
144
|
+
settings?: ExportSiteSettings;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export declare interface ExportSiteSettings {
|
|
148
|
+
siteName?: string;
|
|
149
|
+
siteDescription?: string;
|
|
150
|
+
faviconUrl?: string;
|
|
151
|
+
language?: string;
|
|
152
|
+
seoTitle?: string;
|
|
153
|
+
seoDescription?: string;
|
|
154
|
+
ogImageUrl?: string;
|
|
155
|
+
gaId?: string;
|
|
156
|
+
posthogKey?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export declare function exportSiteToHTML(config: SiteConfig, options?: ExportSiteOptions): string;
|
|
160
|
+
|
|
161
|
+
export declare function exportToHTML(config: SiteConfig, options?: ExportSiteOptions): Promise<string>;
|
|
162
|
+
|
|
163
|
+
export declare function FaqBlock({ block }: {
|
|
164
|
+
block: BlockConfig;
|
|
165
|
+
}): JSX.Element;
|
|
166
|
+
|
|
167
|
+
export declare function FeaturesBlock({ block }: {
|
|
168
|
+
block: BlockConfig;
|
|
169
|
+
}): JSX.Element;
|
|
170
|
+
|
|
171
|
+
export declare function FooterBlock({ block }: {
|
|
172
|
+
block: BlockConfig;
|
|
173
|
+
}): JSX.Element;
|
|
174
|
+
|
|
175
|
+
export declare function GalleryBlock({ block }: {
|
|
176
|
+
block: BlockConfig;
|
|
177
|
+
}): JSX.Element;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Gemini API Key FieldGroup — BYOK (bring-your-own-key) input with show/hide and a
|
|
181
|
+
* live validation button that pings the Google Gemini REST API.
|
|
182
|
+
*
|
|
183
|
+
* Extracted from src/routes/Settings.tsx ApiPanel (Gemini FieldGroup only).
|
|
184
|
+
* - Local state for show/hide + testing in-flight flag.
|
|
185
|
+
* - Persists the key in localStorage under `openpage-gemini-key`; cleared when empty.
|
|
186
|
+
* - Validates by GET https://generativelanguage.googleapis.com/v1beta/models?key=...
|
|
187
|
+
* - `toast` (sonner) is the only external dependency preserved from the inline source.
|
|
188
|
+
*/
|
|
189
|
+
export declare function GeminiKeyInputField(): JSX.Element;
|
|
190
|
+
|
|
191
|
+
export declare function generateSiteConfig(prompt: string, signal?: AbortSignal, onServerFallback?: (prompt: string, signal?: AbortSignal) => Promise<SiteConfig>): Promise<GenerationResult>;
|
|
192
|
+
|
|
193
|
+
export declare const GENERATION_PROMPT = "You are a website configuration generator for OpenPage, a visual website builder.\n\nGiven a user's description, generate a complete JSON site configuration.\n\n## Output Schema\n\nReturn a JSON object matching this exact schema:\n\n{\n \"name\": \"Site Name\",\n \"theme\": {\n \"bg0\": \"#hex\", \"bg1\": \"#hex\", \"bg2\": \"#hex\", \"bg3\": \"#hex\", \"bg4\": \"#hex\", \"bg5\": \"#hex\",\n \"text0\": \"#hex\", \"text1\": \"#hex\", \"text2\": \"#hex\", \"text3\": \"#hex\",\n \"accent\": \"#hex\", \"accentDim\": \"#hex\",\n \"borderDefault\": \"#hex\", \"borderSubtle\": \"#hex\", \"borderHover\": \"#hex\",\n \"fontSans\": \"Font Name\", \"fontDisplay\": \"Font Name\", \"fontMono\": \"Font Name\",\n \"radius\": 8, \"radiusLg\": 12\n },\n \"pages\": [\n { \"id\": \"page-home\", \"name\": \"Home\", \"path\": \"/\", \"blocks\": [...] },\n { \"id\": \"page-about\", \"name\": \"About\", \"path\": \"/about\", \"blocks\": [...] }\n ],\n \"blocks\": []\n}\n\nEach page has its own blocks array. Generate at least 2 pages: Home and one additional page (About, Pricing, or Features depending on the site type). The top-level \"blocks\" array should be empty (blocks live inside pages).\n\n## Available Block Types\n\n1. navbar (variants: default, centered) - Props: { logo, links[], ctaText }\n2. hero (variants: centered, split, gradient, minimal) - Props: { badge?, headline, subheadline, primaryCta, secondaryCta? }\n3. features (variants: grid, list, alternating) - Props: { label?, title, subtitle?, items: [{ icon?, title, description }] }\n4. pricing (variants: simple, comparison) - Props: { title, subtitle?, tiers?: [{ name, price, period?, description?, features[], cta, featured? }] }\n5. cta (variants: simple, split) - Props: { headline, subheadline?, buttonText }\n6. footer (variants: simple, multi-column, minimal) - Props: { logo, copyright, links[] }\n7. testimonials (variants: cards, carousel, spotlight) - Props: { title?, items?: [{ name, role?, quote, rating? }] }\n8. stats (variants: grid, bar, counter) - Props: { title?, items?: [{ value, label }] }\n9. faq (variants: accordion) - Props: { title?, items?: [{ question, answer }] }\n10. team (variants: grid) - Props: { title?, subtitle?, members?: [{ name, role }] }\n11. contact (variants: form) - Props: { title?, subtitle? }\n12. newsletter (variants: simple) - Props: { title?, subtitle?, buttonText? }\n13. logocloud (variants: default) - Props: { title? }\n14. content (variants: prose, columns, highlight) - Props: { body } (markdown: **bold**, *italic*, ## headers, - lists)\n15. image (variants: hero-image, side-by-side, grid) - Props: { src?, alt?, title?, subtitle?, images?: [{ src, alt }], imageSide? }\n16. video (variants: youtube, vimeo) - Props: { url, title? }\n17. gallery (variants: grid, masonry) - Props: { title?, images?: [{ src?, alt?, caption? }] }\n18. divider (variants: line, space, dots) - Props: { height?, width? }\n19. banner (variants: ribbon, bar) - Props: { text, linkText?, linkUrl? }\n\nIcons: Blocks, Code, Bot, Zap, Shield, Globe, Layers, Palette, Rocket, Star, Lock, Settings\nFonts: DM Sans, Inter, Space Grotesk, Poppins, Manrope, Outfit, Plus Jakarta Sans, Sora, Nunito Sans, Work Sans, Rubik, Raleway\n\n## Rules\n\n1. ALWAYS generate at least 2 pages. The Home page MUST include: navbar, hero, at least 2 content sections, a CTA, and a footer\n2. Generate 6-10 blocks per page\n3. Write specific, realistic copy matching the user's description\n4. Pick a theme that fits the vibe (dark for tech, warm for food, clean for agencies)\n5. Use unique block IDs (format: block-type-1, block-hero-1, etc.)\n6. Do NOT use placeholder text like \"Lorem ipsum\"\n7. Make copy compelling and specific to the described business\n8. Each page needs a unique id (page-home, page-about, etc.), a name, and a path (/, /about, etc.)\n\nReturn ONLY valid JSON. No markdown, no code fences, no explanation.";
|
|
194
|
+
|
|
195
|
+
export declare function GenerationOverlay(): JSX.Element | null;
|
|
196
|
+
|
|
197
|
+
export declare interface GenerationResult {
|
|
198
|
+
config: SiteConfig;
|
|
199
|
+
source: 'ai' | 'template';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export declare function getTemplateForPrompt(prompt: string): SiteConfig;
|
|
203
|
+
|
|
204
|
+
export declare const googleFontOptions: string[];
|
|
205
|
+
|
|
206
|
+
export declare function HeroBlock({ block }: {
|
|
207
|
+
block: BlockConfig;
|
|
208
|
+
}): JSX.Element;
|
|
209
|
+
|
|
210
|
+
export declare function hexToRgb(hex: string): string;
|
|
211
|
+
|
|
212
|
+
export declare function ImageBlock({ block }: {
|
|
213
|
+
block: BlockConfig;
|
|
214
|
+
}): JSX.Element;
|
|
215
|
+
|
|
216
|
+
export declare function JsonDrawer(): JSX.Element;
|
|
217
|
+
|
|
218
|
+
export declare function LayersPanel(): JSX.Element;
|
|
219
|
+
|
|
220
|
+
export declare function LeftSidebar(): JSX.Element;
|
|
221
|
+
|
|
222
|
+
export declare function LogoCloudBlock({ block }: {
|
|
223
|
+
block: BlockConfig;
|
|
224
|
+
}): JSX.Element;
|
|
225
|
+
|
|
226
|
+
export declare function NavbarBlock({ block }: {
|
|
227
|
+
block: BlockConfig;
|
|
228
|
+
}): JSX.Element;
|
|
229
|
+
|
|
230
|
+
export declare function NewsletterBlock({ block }: {
|
|
231
|
+
block: BlockConfig;
|
|
232
|
+
}): JSX.Element;
|
|
233
|
+
|
|
234
|
+
export declare interface PageConfig {
|
|
235
|
+
id: string;
|
|
236
|
+
name: string;
|
|
237
|
+
path: string;
|
|
238
|
+
blocks: BlockConfig[];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export declare function previewHTML(html: string): void;
|
|
242
|
+
|
|
243
|
+
export declare function PricingBlock({ block }: {
|
|
244
|
+
block: BlockConfig;
|
|
245
|
+
}): JSX.Element;
|
|
246
|
+
|
|
247
|
+
export declare function PropertiesPanel({ block }: {
|
|
248
|
+
block: BlockConfig;
|
|
249
|
+
}): JSX.Element;
|
|
250
|
+
|
|
251
|
+
declare interface Props {
|
|
252
|
+
block: BlockConfig;
|
|
253
|
+
isSelected: boolean;
|
|
254
|
+
onSelect: () => void;
|
|
255
|
+
children: ReactNode;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export declare function RenderBlock({ block }: {
|
|
259
|
+
block: BlockConfig;
|
|
260
|
+
}): ReactNode;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Simple markdown-to-React renderer. No dangerouslySetInnerHTML, no XSS surface.
|
|
264
|
+
* Supports: ## headers, **bold**, *italic*, - lists, line breaks.
|
|
265
|
+
*/
|
|
266
|
+
export declare function renderMarkdown(text: string): ReactNode[];
|
|
267
|
+
|
|
268
|
+
export declare function resolveTheme(partial?: Partial<ThemeConfig>): ThemeConfig;
|
|
269
|
+
|
|
270
|
+
export declare function RightSidebar(): JSX.Element;
|
|
271
|
+
|
|
272
|
+
export declare function ShortcutsModal(): JSX.Element | null;
|
|
273
|
+
|
|
274
|
+
export declare interface SiteConfig {
|
|
275
|
+
name: string;
|
|
276
|
+
pages?: PageConfig[];
|
|
277
|
+
blocks: BlockConfig[];
|
|
278
|
+
theme?: Partial<ThemeConfig>;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export declare function StatsBlock({ block }: {
|
|
282
|
+
block: BlockConfig;
|
|
283
|
+
}): JSX.Element;
|
|
284
|
+
|
|
285
|
+
export declare function TeamBlock({ block }: {
|
|
286
|
+
block: BlockConfig;
|
|
287
|
+
}): JSX.Element;
|
|
288
|
+
|
|
289
|
+
export declare const templateMeta: readonly [{
|
|
290
|
+
readonly id: "portfolio";
|
|
291
|
+
readonly name: "Portfolio";
|
|
292
|
+
readonly description: "Showcase your work and skills";
|
|
293
|
+
readonly accent: "#06b6d4";
|
|
294
|
+
readonly blockCount: 7;
|
|
295
|
+
readonly templateIndex: 0;
|
|
296
|
+
readonly icon: "Briefcase";
|
|
297
|
+
}, {
|
|
298
|
+
readonly id: "restaurant";
|
|
299
|
+
readonly name: "Restaurant";
|
|
300
|
+
readonly description: "Menu, reservations, and ambiance";
|
|
301
|
+
readonly accent: "#e8a838";
|
|
302
|
+
readonly blockCount: 7;
|
|
303
|
+
readonly templateIndex: 1;
|
|
304
|
+
readonly icon: "UtensilsCrossed";
|
|
305
|
+
}, {
|
|
306
|
+
readonly id: "agency";
|
|
307
|
+
readonly name: "Agency";
|
|
308
|
+
readonly description: "Services, case studies, and team";
|
|
309
|
+
readonly accent: "#228be6";
|
|
310
|
+
readonly blockCount: 8;
|
|
311
|
+
readonly templateIndex: 2;
|
|
312
|
+
readonly icon: "Building2";
|
|
313
|
+
}, {
|
|
314
|
+
readonly id: "blog";
|
|
315
|
+
readonly name: "Blog";
|
|
316
|
+
readonly description: "Articles, topics, and subscribers";
|
|
317
|
+
readonly accent: "#4f46e5";
|
|
318
|
+
readonly blockCount: 7;
|
|
319
|
+
readonly templateIndex: 3;
|
|
320
|
+
readonly icon: "BookOpen";
|
|
321
|
+
}];
|
|
322
|
+
|
|
323
|
+
export declare function TestimonialsBlock({ block }: {
|
|
324
|
+
block: BlockConfig;
|
|
325
|
+
}): JSX.Element;
|
|
326
|
+
|
|
327
|
+
export declare interface ThemeConfig {
|
|
328
|
+
bg0: string;
|
|
329
|
+
bg1: string;
|
|
330
|
+
bg2: string;
|
|
331
|
+
bg3: string;
|
|
332
|
+
bg4: string;
|
|
333
|
+
bg5: string;
|
|
334
|
+
text0: string;
|
|
335
|
+
text1: string;
|
|
336
|
+
text2: string;
|
|
337
|
+
text3: string;
|
|
338
|
+
accent: string;
|
|
339
|
+
accentDim: string;
|
|
340
|
+
borderDefault: string;
|
|
341
|
+
borderSubtle: string;
|
|
342
|
+
borderHover: string;
|
|
343
|
+
fontSans: string;
|
|
344
|
+
fontDisplay: string;
|
|
345
|
+
fontMono: string;
|
|
346
|
+
radius: number;
|
|
347
|
+
radiusLg: number;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export declare interface ThemePreset {
|
|
351
|
+
id: string;
|
|
352
|
+
name: string;
|
|
353
|
+
theme: ThemeConfig;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export declare const themePresets: ThemePreset[];
|
|
357
|
+
|
|
358
|
+
export declare function themeToCSS(theme: ThemeConfig): Record<string, string>;
|
|
359
|
+
|
|
360
|
+
declare interface UndoEntry {
|
|
361
|
+
pages?: PageConfig[];
|
|
362
|
+
blocks: BlockConfig[];
|
|
363
|
+
theme?: Partial<ThemeConfig>;
|
|
364
|
+
label: string;
|
|
365
|
+
timestamp: number;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export declare const useConfigStore: UseBoundStore<Omit<StoreApi<ConfigState>, "setState" | "persist"> & {
|
|
369
|
+
setState(partial: ConfigState | Partial<ConfigState> | ((state: ConfigState) => ConfigState | Partial<ConfigState>), replace?: false | undefined): unknown;
|
|
370
|
+
setState(state: ConfigState | ((state: ConfigState) => ConfigState), replace: true): unknown;
|
|
371
|
+
persist: {
|
|
372
|
+
setOptions: (options: Partial<PersistOptions<ConfigState, Record<string, unknown>, unknown>>) => void;
|
|
373
|
+
clearStorage: () => void;
|
|
374
|
+
rehydrate: () => Promise<void> | void;
|
|
375
|
+
hasHydrated: () => boolean;
|
|
376
|
+
onHydrate: (fn: (state: ConfigState) => void) => () => void;
|
|
377
|
+
onFinishHydration: (fn: (state: ConfigState) => void) => () => void;
|
|
378
|
+
getOptions: () => Partial<PersistOptions<ConfigState, Record<string, unknown>, unknown>>;
|
|
379
|
+
};
|
|
380
|
+
}>;
|
|
381
|
+
|
|
382
|
+
export declare const useEditorStore: UseBoundStore<StoreApi<EditorState>>;
|
|
383
|
+
|
|
384
|
+
export declare function useGoogleFonts(fonts: string[]): void;
|
|
385
|
+
|
|
386
|
+
export declare function useScrollReveal(disabled?: boolean): {
|
|
387
|
+
ref: RefObject<HTMLDivElement | null>;
|
|
388
|
+
isRevealed: boolean;
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
export declare function validateSiteConfig(raw: unknown, prompt?: string): SiteConfig;
|
|
392
|
+
|
|
393
|
+
export declare function VersionHistory(): JSX.Element;
|
|
394
|
+
|
|
395
|
+
export declare function VideoBlock({ block }: {
|
|
396
|
+
block: BlockConfig;
|
|
397
|
+
}): JSX.Element;
|
|
398
|
+
|
|
399
|
+
export declare type Viewport = 'desktop' | 'tablet' | 'mobile';
|
|
400
|
+
|
|
401
|
+
export { }
|