@delmaredigital/payload-puck 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 +73 -0
- package/README.md +1580 -0
- package/dist/AccordionClient.d.mts +24 -0
- package/dist/AccordionClient.d.ts +24 -0
- package/dist/AccordionClient.js +786 -0
- package/dist/AccordionClient.js.map +1 -0
- package/dist/AccordionClient.mjs +784 -0
- package/dist/AccordionClient.mjs.map +1 -0
- package/dist/AnimatedWrapper.d.mts +30 -0
- package/dist/AnimatedWrapper.d.ts +30 -0
- package/dist/AnimatedWrapper.js +379 -0
- package/dist/AnimatedWrapper.js.map +1 -0
- package/dist/AnimatedWrapper.mjs +377 -0
- package/dist/AnimatedWrapper.mjs.map +1 -0
- package/dist/admin/client.d.mts +108 -0
- package/dist/admin/client.d.ts +108 -0
- package/dist/admin/client.js +177 -0
- package/dist/admin/client.js.map +1 -0
- package/dist/admin/client.mjs +173 -0
- package/dist/admin/client.mjs.map +1 -0
- package/dist/admin/index.d.mts +157 -0
- package/dist/admin/index.d.ts +157 -0
- package/dist/admin/index.js +31 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +29 -0
- package/dist/admin/index.mjs.map +1 -0
- package/dist/api/index.d.mts +460 -0
- package/dist/api/index.d.ts +460 -0
- package/dist/api/index.js +588 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +578 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/components/index.css +339 -0
- package/dist/components/index.css.map +1 -0
- package/dist/components/index.d.mts +222 -0
- package/dist/components/index.d.ts +222 -0
- package/dist/components/index.js +9177 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +9130 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/config.editor.css +339 -0
- package/dist/config/config.editor.css.map +1 -0
- package/dist/config/config.editor.d.mts +153 -0
- package/dist/config/config.editor.d.ts +153 -0
- package/dist/config/config.editor.js +9400 -0
- package/dist/config/config.editor.js.map +1 -0
- package/dist/config/config.editor.mjs +9368 -0
- package/dist/config/config.editor.mjs.map +1 -0
- package/dist/config/index.d.mts +68 -0
- package/dist/config/index.d.ts +68 -0
- package/dist/config/index.js +2017 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +1991 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/editor/index.d.mts +784 -0
- package/dist/editor/index.d.ts +784 -0
- package/dist/editor/index.js +4517 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/index.mjs +4483 -0
- package/dist/editor/index.mjs.map +1 -0
- package/dist/fields/index.css +339 -0
- package/dist/fields/index.css.map +1 -0
- package/dist/fields/index.d.mts +600 -0
- package/dist/fields/index.d.ts +600 -0
- package/dist/fields/index.js +7739 -0
- package/dist/fields/index.js.map +1 -0
- package/dist/fields/index.mjs +7590 -0
- package/dist/fields/index.mjs.map +1 -0
- package/dist/index-CQu6SzDg.d.mts +327 -0
- package/dist/index-CoUQnyC3.d.ts +327 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +569 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +555 -0
- package/dist/index.mjs.map +1 -0
- package/dist/layouts/index.d.mts +96 -0
- package/dist/layouts/index.d.ts +96 -0
- package/dist/layouts/index.js +394 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/layouts/index.mjs +378 -0
- package/dist/layouts/index.mjs.map +1 -0
- package/dist/plugin/index.d.mts +289 -0
- package/dist/plugin/index.d.ts +289 -0
- package/dist/plugin/index.js +569 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/index.mjs +555 -0
- package/dist/plugin/index.mjs.map +1 -0
- package/dist/render/index.d.mts +109 -0
- package/dist/render/index.d.ts +109 -0
- package/dist/render/index.js +2146 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/index.mjs +2123 -0
- package/dist/render/index.mjs.map +1 -0
- package/dist/shared-DMAF1AcH.d.mts +545 -0
- package/dist/shared-DMAF1AcH.d.ts +545 -0
- package/dist/theme/index.d.mts +155 -0
- package/dist/theme/index.d.ts +155 -0
- package/dist/theme/index.js +201 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/index.mjs +186 -0
- package/dist/theme/index.mjs.map +1 -0
- package/dist/types-D7D3rZ1J.d.mts +116 -0
- package/dist/types-D7D3rZ1J.d.ts +116 -0
- package/dist/types-_6MvjyKv.d.mts +104 -0
- package/dist/types-_6MvjyKv.d.ts +104 -0
- package/dist/utils/index.d.mts +267 -0
- package/dist/utils/index.d.ts +267 -0
- package/dist/utils/index.js +426 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +412 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils-DaRs9t0J.d.mts +85 -0
- package/dist/utils-gAvt0Vhw.d.ts +85 -0
- package/examples/README.md +240 -0
- package/examples/api/puck/pages/[id]/route.ts +64 -0
- package/examples/api/puck/pages/[id]/versions/route.ts +47 -0
- package/examples/api/puck/pages/route.ts +45 -0
- package/examples/app/(frontend)/page.tsx +94 -0
- package/examples/app/[...slug]/page.tsx +101 -0
- package/examples/app/pages/[id]/edit/page.tsx +148 -0
- package/examples/components/CustomBanner.tsx +368 -0
- package/examples/config/custom-config.ts +223 -0
- package/examples/config/payload.config.example.ts +64 -0
- package/examples/lib/puck-layouts.ts +258 -0
- package/examples/lib/puck-theme.ts +94 -0
- package/examples/styles/puck-theme.css +171 -0
- package/package.json +157 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Puck Configuration Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to:
|
|
5
|
+
* - Import the base payload-puck configuration
|
|
6
|
+
* - Add your own custom components using mergeConfigs
|
|
7
|
+
* - Exclude unwanted built-in components
|
|
8
|
+
* - Organize components into categories
|
|
9
|
+
*
|
|
10
|
+
* Copy and adapt this file for your project's needs.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { Config as PuckConfig } from '@measured/puck'
|
|
14
|
+
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Import the base configuration and merge utility
|
|
17
|
+
// =============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The editorConfig is the full payload-puck configuration with all built-in
|
|
21
|
+
* components. It includes:
|
|
22
|
+
* - Layout: Container, Flex, Grid, Section, Spacer
|
|
23
|
+
* - Typography: Heading, Text, RichText
|
|
24
|
+
* - Media: Image, TextImageSplit
|
|
25
|
+
* - Interactive: Button, Card, Divider, Accordion, CallToAction
|
|
26
|
+
*
|
|
27
|
+
* mergeConfigs is a utility that helps combine configurations while:
|
|
28
|
+
* - Preserving base component configurations
|
|
29
|
+
* - Adding new custom components
|
|
30
|
+
* - Merging categories appropriately
|
|
31
|
+
* - Excluding components you don't need
|
|
32
|
+
*/
|
|
33
|
+
import { editorConfig, mergeConfigs } from '@delmaredigital/payload-puck/config'
|
|
34
|
+
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// Import your custom components
|
|
37
|
+
// =============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Import your custom component configurations.
|
|
41
|
+
* Each should export a ComponentConfig object.
|
|
42
|
+
*
|
|
43
|
+
* See examples/components/CustomBanner.tsx for how to create these.
|
|
44
|
+
*/
|
|
45
|
+
import { CustomBannerConfig } from '../components/CustomBanner'
|
|
46
|
+
|
|
47
|
+
// You might also have other custom components:
|
|
48
|
+
// import { HeroConfig } from '../components/Hero'
|
|
49
|
+
// import { TestimonialConfig } from '../components/Testimonial'
|
|
50
|
+
// import { PricingTableConfig } from '../components/PricingTable'
|
|
51
|
+
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// Create your merged configuration
|
|
54
|
+
// =============================================================================
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Use mergeConfigs to combine the base config with your customizations.
|
|
58
|
+
*
|
|
59
|
+
* Options:
|
|
60
|
+
* - base: The configuration to extend (typically editorConfig)
|
|
61
|
+
* - components: Object mapping component names to their configs
|
|
62
|
+
* - categories: Object to define/extend component categories
|
|
63
|
+
* - root: Optional root configuration overrides
|
|
64
|
+
* - exclude: Array of component names to remove from base
|
|
65
|
+
*/
|
|
66
|
+
export const customConfig = mergeConfigs({
|
|
67
|
+
// Start with the full payload-puck configuration
|
|
68
|
+
base: editorConfig,
|
|
69
|
+
|
|
70
|
+
// Add your custom components
|
|
71
|
+
// The key becomes the component's identifier in the editor
|
|
72
|
+
components: {
|
|
73
|
+
// Add the Banner component
|
|
74
|
+
Banner: CustomBannerConfig,
|
|
75
|
+
|
|
76
|
+
// Add more custom components as needed:
|
|
77
|
+
// Hero: HeroConfig,
|
|
78
|
+
// Testimonial: TestimonialConfig,
|
|
79
|
+
// PricingTable: PricingTableConfig,
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
// Organize components into categories
|
|
83
|
+
// Categories appear as collapsible sections in Puck's component picker
|
|
84
|
+
categories: {
|
|
85
|
+
// Add Banner to the existing 'interactive' category
|
|
86
|
+
// The components array is merged with existing components in that category
|
|
87
|
+
interactive: {
|
|
88
|
+
title: 'Interactive',
|
|
89
|
+
components: ['Banner'],
|
|
90
|
+
// Note: Banner will be added alongside existing interactive components
|
|
91
|
+
// (Button, Card, Divider, Accordion, CallToAction)
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// You can also create entirely new categories:
|
|
95
|
+
// marketing: {
|
|
96
|
+
// title: 'Marketing',
|
|
97
|
+
// components: ['Hero', 'Testimonial', 'PricingTable'],
|
|
98
|
+
// defaultExpanded: false, // Collapsed by default
|
|
99
|
+
// },
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// Exclude components you don't need
|
|
103
|
+
// This removes them from both the component list and categories
|
|
104
|
+
exclude: [
|
|
105
|
+
// Example: Remove CallToAction if you have your own marketing components
|
|
106
|
+
// 'CallToAction',
|
|
107
|
+
|
|
108
|
+
// Example: Remove TextImageSplit if you prefer custom layouts
|
|
109
|
+
// 'TextImageSplit',
|
|
110
|
+
],
|
|
111
|
+
|
|
112
|
+
// Optional: Override root configuration
|
|
113
|
+
// The root defines page-level fields and the wrapper render function
|
|
114
|
+
// root: {
|
|
115
|
+
// fields: {
|
|
116
|
+
// // Add custom page-level fields
|
|
117
|
+
// pageDescription: {
|
|
118
|
+
// type: 'textarea',
|
|
119
|
+
// label: 'Meta Description',
|
|
120
|
+
// },
|
|
121
|
+
// headerStyle: {
|
|
122
|
+
// type: 'select',
|
|
123
|
+
// label: 'Header Style',
|
|
124
|
+
// options: [
|
|
125
|
+
// { label: 'Default', value: 'default' },
|
|
126
|
+
// { label: 'Transparent', value: 'transparent' },
|
|
127
|
+
// { label: 'Dark', value: 'dark' },
|
|
128
|
+
// ],
|
|
129
|
+
// },
|
|
130
|
+
// },
|
|
131
|
+
// defaultProps: {
|
|
132
|
+
// pageDescription: '',
|
|
133
|
+
// headerStyle: 'default',
|
|
134
|
+
// },
|
|
135
|
+
// },
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// =============================================================================
|
|
139
|
+
// Alternative: Minimal configuration with only your components
|
|
140
|
+
// =============================================================================
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* If you want to start from scratch with only specific components,
|
|
144
|
+
* you can build a config directly without merging.
|
|
145
|
+
*
|
|
146
|
+
* This is useful when you want full control over what's available.
|
|
147
|
+
*/
|
|
148
|
+
// import type { ComponentConfig } from '@measured/puck'
|
|
149
|
+
// import { ContainerConfig, FlexConfig } from '@delmaredigital/payload-puck/components'
|
|
150
|
+
// import { HeadingConfig, TextConfig } from '@delmaredigital/payload-puck/components'
|
|
151
|
+
//
|
|
152
|
+
// export const minimalConfig: PuckConfig = {
|
|
153
|
+
// root: {
|
|
154
|
+
// fields: {
|
|
155
|
+
// title: { type: 'text', label: 'Page Title' },
|
|
156
|
+
// },
|
|
157
|
+
// defaultProps: {
|
|
158
|
+
// title: 'New Page',
|
|
159
|
+
// },
|
|
160
|
+
// render: ({ children }) => <>{children}</>,
|
|
161
|
+
// },
|
|
162
|
+
// categories: {
|
|
163
|
+
// layout: {
|
|
164
|
+
// title: 'Layout',
|
|
165
|
+
// components: ['Container', 'Flex'],
|
|
166
|
+
// },
|
|
167
|
+
// content: {
|
|
168
|
+
// title: 'Content',
|
|
169
|
+
// components: ['Heading', 'Text', 'Banner'],
|
|
170
|
+
// },
|
|
171
|
+
// },
|
|
172
|
+
// components: {
|
|
173
|
+
// Container: ContainerConfig as ComponentConfig<any>,
|
|
174
|
+
// Flex: FlexConfig as ComponentConfig<any>,
|
|
175
|
+
// Heading: HeadingConfig as ComponentConfig<any>,
|
|
176
|
+
// Text: TextConfig as ComponentConfig<any>,
|
|
177
|
+
// Banner: CustomBannerConfig as ComponentConfig<any>,
|
|
178
|
+
// },
|
|
179
|
+
// }
|
|
180
|
+
|
|
181
|
+
// =============================================================================
|
|
182
|
+
// Usage in your Puck Editor
|
|
183
|
+
// =============================================================================
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Import this config in your Puck editor page:
|
|
187
|
+
*
|
|
188
|
+
* ```tsx
|
|
189
|
+
* // app/(manage)/pages/[id]/edit/page.tsx
|
|
190
|
+
* 'use client'
|
|
191
|
+
*
|
|
192
|
+
* import { Puck } from '@measured/puck'
|
|
193
|
+
* import { customConfig } from '@/lib/puck/custom-config'
|
|
194
|
+
* import { ThemeProvider } from '@delmaredigital/payload-puck/theme'
|
|
195
|
+
*
|
|
196
|
+
* export default function EditorPage({ data, onSave }) {
|
|
197
|
+
* return (
|
|
198
|
+
* <ThemeProvider>
|
|
199
|
+
* <Puck
|
|
200
|
+
* config={customConfig}
|
|
201
|
+
* data={data}
|
|
202
|
+
* onPublish={onSave}
|
|
203
|
+
* />
|
|
204
|
+
* </ThemeProvider>
|
|
205
|
+
* )
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* And in your page renderer:
|
|
210
|
+
*
|
|
211
|
+
* ```tsx
|
|
212
|
+
* // app/(frontend)/[...slug]/page.tsx
|
|
213
|
+
* import { Render } from '@measured/puck'
|
|
214
|
+
* import { customConfig } from '@/lib/puck/custom-config'
|
|
215
|
+
*
|
|
216
|
+
* export default function Page({ data }) {
|
|
217
|
+
* return <Render config={customConfig} data={data} />
|
|
218
|
+
* }
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
|
|
222
|
+
// Export for use in your application
|
|
223
|
+
export default customConfig
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payload Configuration with Puck Plugin
|
|
3
|
+
*
|
|
4
|
+
* Copy to: src/payload.config.ts (merge with existing config)
|
|
5
|
+
*
|
|
6
|
+
* This shows the minimal configuration needed to add Puck to your Payload setup.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { buildConfig } from 'payload'
|
|
10
|
+
import { createPuckPlugin } from '@delmaredigital/payload-puck/plugin'
|
|
11
|
+
// Import your other Payload plugins, collections, etc.
|
|
12
|
+
|
|
13
|
+
export default buildConfig({
|
|
14
|
+
// ... your existing config (admin, db, etc.)
|
|
15
|
+
|
|
16
|
+
plugins: [
|
|
17
|
+
// Add Puck plugin
|
|
18
|
+
createPuckPlugin({
|
|
19
|
+
// Collection slug for pages (default: 'pages')
|
|
20
|
+
pagesCollection: 'pages',
|
|
21
|
+
|
|
22
|
+
// Auto-generate the Pages collection (default: true)
|
|
23
|
+
// Set to false if you want to define your own collection
|
|
24
|
+
autoGenerateCollection: true,
|
|
25
|
+
|
|
26
|
+
// Optional: Override collection config
|
|
27
|
+
collectionOverrides: {
|
|
28
|
+
admin: {
|
|
29
|
+
defaultColumns: ['title', 'slug', 'updatedAt'],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// Optional: Custom access control
|
|
34
|
+
access: {
|
|
35
|
+
read: () => true,
|
|
36
|
+
create: ({ req }) => !!req.user,
|
|
37
|
+
update: ({ req }) => !!req.user,
|
|
38
|
+
delete: ({ req }) => !!req.user,
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Optional: Custom layouts (shown in editor page layout selector)
|
|
42
|
+
// Only value/label are needed here - header/footer components are added
|
|
43
|
+
// in your puck-layouts.ts file for editor preview and frontend rendering
|
|
44
|
+
layouts: [
|
|
45
|
+
{ value: 'default', label: 'Default' },
|
|
46
|
+
{ value: 'landing', label: 'Landing' },
|
|
47
|
+
{ value: 'full-width', label: 'Full Width' },
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
// Admin UI configuration
|
|
51
|
+
admin: {
|
|
52
|
+
// URL pattern for the editor (use {id} placeholder)
|
|
53
|
+
editorPathPattern: '/pages/{id}/edit',
|
|
54
|
+
// Button label in Payload admin
|
|
55
|
+
buttonLabel: 'Edit with Puck',
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
// ... your other plugins
|
|
60
|
+
],
|
|
61
|
+
|
|
62
|
+
// Required for Puck pages: Enable drafts on the pages collection
|
|
63
|
+
// (The plugin handles this automatically when autoGenerateCollection is true)
|
|
64
|
+
})
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Page Layouts
|
|
3
|
+
*
|
|
4
|
+
* Copy this file to: src/lib/puck-layouts.ts
|
|
5
|
+
*
|
|
6
|
+
* Define custom page layouts that affect how Puck content is rendered.
|
|
7
|
+
* Each layout can specify CSS classes, max-width constraints, header/footer
|
|
8
|
+
* components, and editor preview styling.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* 1. Copy this file to your project's lib folder
|
|
12
|
+
* 2. Import your Header/Footer components
|
|
13
|
+
* 3. Customize the layouts to match your design system
|
|
14
|
+
* 4. Import and use in your PuckEditor, PageRenderer, and plugin config
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_LAYOUTS,
|
|
19
|
+
createLayout,
|
|
20
|
+
mergeLayouts,
|
|
21
|
+
type LayoutDefinition,
|
|
22
|
+
} from '@delmaredigital/payload-puck/layouts'
|
|
23
|
+
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Import your site's header/footer components
|
|
26
|
+
// =============================================================================
|
|
27
|
+
|
|
28
|
+
// Uncomment and adjust these imports for your project:
|
|
29
|
+
// import { Header } from '@/components/header'
|
|
30
|
+
// import { Footer } from '@/components/footer'
|
|
31
|
+
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Layouts with Header/Footer Examples
|
|
34
|
+
// =============================================================================
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Default layout with sticky header
|
|
38
|
+
*
|
|
39
|
+
* For layouts with sticky/fixed headers, set stickyHeaderHeight to the
|
|
40
|
+
* header's pixel height. This adds padding-top to content in both the
|
|
41
|
+
* editor preview AND the frontend, ensuring content doesn't render
|
|
42
|
+
* behind the header.
|
|
43
|
+
*
|
|
44
|
+
* Note: stickyFooter defaults to true - the footer will always be pushed
|
|
45
|
+
* to the bottom of the viewport even with minimal content. Set to false
|
|
46
|
+
* if you want the footer to flow naturally after content.
|
|
47
|
+
*/
|
|
48
|
+
export const defaultWithHeader = createLayout({
|
|
49
|
+
value: 'default',
|
|
50
|
+
label: 'Default',
|
|
51
|
+
description: 'Standard page layout with header and footer',
|
|
52
|
+
classes: {
|
|
53
|
+
wrapper: '',
|
|
54
|
+
container: 'mx-auto px-4 sm:px-6 lg:px-8',
|
|
55
|
+
content: '',
|
|
56
|
+
},
|
|
57
|
+
maxWidth: '1200px',
|
|
58
|
+
fullWidth: false,
|
|
59
|
+
// Uncomment to add your header/footer:
|
|
60
|
+
// header: Header,
|
|
61
|
+
// footer: Footer,
|
|
62
|
+
// Editor preview settings
|
|
63
|
+
editorBackground: '#ffffff',
|
|
64
|
+
editorDarkMode: false,
|
|
65
|
+
// Set this to your header's height if it's sticky/fixed
|
|
66
|
+
stickyHeaderHeight: 80,
|
|
67
|
+
// stickyFooter: true (default) - footer stays at bottom of viewport
|
|
68
|
+
// Set to false if you want footer to flow after content:
|
|
69
|
+
// stickyFooter: false,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Landing page layout - no header/footer
|
|
74
|
+
*
|
|
75
|
+
* Full-width layout for custom landing pages where you want
|
|
76
|
+
* complete control over the header area (e.g., transparent headers
|
|
77
|
+
* over hero sections).
|
|
78
|
+
*/
|
|
79
|
+
export const landingLayout = createLayout({
|
|
80
|
+
value: 'landing',
|
|
81
|
+
label: 'Landing',
|
|
82
|
+
description: 'Full-width layout without header/footer',
|
|
83
|
+
classes: {
|
|
84
|
+
wrapper: '',
|
|
85
|
+
container: '',
|
|
86
|
+
content: '',
|
|
87
|
+
},
|
|
88
|
+
fullWidth: true,
|
|
89
|
+
// No header/footer - landing pages have custom designs
|
|
90
|
+
editorBackground: '#f8fafc',
|
|
91
|
+
editorDarkMode: false,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Dark theme layout example
|
|
96
|
+
*
|
|
97
|
+
* Demonstrates editorDarkMode for layouts with dark backgrounds.
|
|
98
|
+
*/
|
|
99
|
+
export const darkLayout = createLayout({
|
|
100
|
+
value: 'dark',
|
|
101
|
+
label: 'Dark',
|
|
102
|
+
description: 'Dark theme layout',
|
|
103
|
+
classes: {
|
|
104
|
+
wrapper: 'bg-gray-900',
|
|
105
|
+
container: 'mx-auto px-4 sm:px-6 lg:px-8',
|
|
106
|
+
content: '',
|
|
107
|
+
},
|
|
108
|
+
maxWidth: '1200px',
|
|
109
|
+
fullWidth: false,
|
|
110
|
+
// Uncomment to add dark-themed header/footer:
|
|
111
|
+
// header: DarkHeader,
|
|
112
|
+
// footer: DarkFooter,
|
|
113
|
+
editorBackground: '#111827', // gray-900
|
|
114
|
+
editorDarkMode: true,
|
|
115
|
+
stickyHeaderHeight: 80,
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// Additional Layout Examples
|
|
120
|
+
// =============================================================================
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Blog post layout - narrow width optimized for reading
|
|
124
|
+
*/
|
|
125
|
+
export const blogLayout = createLayout({
|
|
126
|
+
value: 'blog',
|
|
127
|
+
label: 'Blog Post',
|
|
128
|
+
description: 'Narrow layout optimized for long-form reading',
|
|
129
|
+
classes: {
|
|
130
|
+
wrapper: '',
|
|
131
|
+
container: 'mx-auto px-4 sm:px-6',
|
|
132
|
+
content: 'prose prose-lg max-w-none',
|
|
133
|
+
},
|
|
134
|
+
maxWidth: '720px',
|
|
135
|
+
fullWidth: false,
|
|
136
|
+
// Uncomment for blog header/footer:
|
|
137
|
+
// header: Header,
|
|
138
|
+
// footer: Footer,
|
|
139
|
+
editorBackground: '#ffffff',
|
|
140
|
+
stickyHeaderHeight: 80,
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Documentation layout - with sidebar space consideration
|
|
145
|
+
*/
|
|
146
|
+
export const docsLayout = createLayout({
|
|
147
|
+
value: 'docs',
|
|
148
|
+
label: 'Documentation',
|
|
149
|
+
description: 'Layout for documentation pages',
|
|
150
|
+
classes: {
|
|
151
|
+
wrapper: '',
|
|
152
|
+
container: 'mx-auto px-4 sm:px-6 lg:px-8',
|
|
153
|
+
content: 'prose max-w-none',
|
|
154
|
+
},
|
|
155
|
+
maxWidth: '900px',
|
|
156
|
+
fullWidth: false,
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Dashboard layout - full width with minimal padding
|
|
161
|
+
*/
|
|
162
|
+
export const dashboardLayout = createLayout({
|
|
163
|
+
value: 'dashboard',
|
|
164
|
+
label: 'Dashboard',
|
|
165
|
+
description: 'Full-width layout for dashboards and data displays',
|
|
166
|
+
classes: {
|
|
167
|
+
wrapper: 'min-h-screen bg-gray-50',
|
|
168
|
+
container: 'p-4 sm:p-6',
|
|
169
|
+
content: '',
|
|
170
|
+
},
|
|
171
|
+
fullWidth: true,
|
|
172
|
+
editorBackground: '#f9fafb', // gray-50
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Marketing layout - sections span full width, content contained
|
|
177
|
+
*/
|
|
178
|
+
export const marketingLayout = createLayout({
|
|
179
|
+
value: 'marketing',
|
|
180
|
+
label: 'Marketing',
|
|
181
|
+
description: 'Full-width sections with contained content areas',
|
|
182
|
+
classes: {
|
|
183
|
+
wrapper: '',
|
|
184
|
+
container: '',
|
|
185
|
+
content: '',
|
|
186
|
+
},
|
|
187
|
+
fullWidth: true,
|
|
188
|
+
// Uncomment for marketing header/footer:
|
|
189
|
+
// header: Header,
|
|
190
|
+
// footer: Footer,
|
|
191
|
+
dataAttributes: {
|
|
192
|
+
'data-page-type': 'marketing',
|
|
193
|
+
},
|
|
194
|
+
stickyHeaderHeight: 80,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
// =============================================================================
|
|
198
|
+
// Combined Layouts
|
|
199
|
+
// =============================================================================
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* All custom layouts combined with defaults
|
|
203
|
+
*
|
|
204
|
+
* Use this in your PuckEditor and PageRenderer
|
|
205
|
+
*/
|
|
206
|
+
export const customLayouts: LayoutDefinition[] = mergeLayouts(
|
|
207
|
+
DEFAULT_LAYOUTS,
|
|
208
|
+
[
|
|
209
|
+
defaultWithHeader,
|
|
210
|
+
landingLayout,
|
|
211
|
+
darkLayout,
|
|
212
|
+
blogLayout,
|
|
213
|
+
docsLayout,
|
|
214
|
+
dashboardLayout,
|
|
215
|
+
marketingLayout,
|
|
216
|
+
],
|
|
217
|
+
{ replace: true } // Replace default layouts with our customized versions
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
// =============================================================================
|
|
221
|
+
// Usage Examples
|
|
222
|
+
// =============================================================================
|
|
223
|
+
|
|
224
|
+
/*
|
|
225
|
+
// 1. In your editor page (e.g., app/(manage)/pages/[id]/edit/page.tsx):
|
|
226
|
+
import { PuckEditor } from '@delmaredigital/payload-puck/editor'
|
|
227
|
+
import { customLayouts } from '@/lib/puck-layouts'
|
|
228
|
+
|
|
229
|
+
<PuckEditor
|
|
230
|
+
config={editorConfig}
|
|
231
|
+
pageId={page.id}
|
|
232
|
+
initialData={page.puckData}
|
|
233
|
+
layouts={customLayouts} // <-- Pass layouts here
|
|
234
|
+
/>
|
|
235
|
+
|
|
236
|
+
// 2. In your page renderer (e.g., app/(frontend)/[...slug]/page.tsx):
|
|
237
|
+
import { PageRenderer } from '@delmaredigital/payload-puck/render'
|
|
238
|
+
import { customLayouts } from '@/lib/puck-layouts'
|
|
239
|
+
|
|
240
|
+
<PageRenderer
|
|
241
|
+
data={page.puckData}
|
|
242
|
+
layouts={customLayouts} // <-- Pass layouts here
|
|
243
|
+
/>
|
|
244
|
+
|
|
245
|
+
// 3. In payload.config.ts (optional - for layout field in Pages collection):
|
|
246
|
+
import { customLayouts } from '@/lib/puck-layouts'
|
|
247
|
+
|
|
248
|
+
createPuckPlugin({
|
|
249
|
+
layouts: customLayouts,
|
|
250
|
+
// ... other options
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
// 4. Create a custom Puck config with layouts:
|
|
254
|
+
import { createConfig } from '@delmaredigital/payload-puck/config'
|
|
255
|
+
import { customLayouts } from '@/lib/puck-layouts'
|
|
256
|
+
|
|
257
|
+
const myConfig = createConfig(customLayouts)
|
|
258
|
+
*/
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Puck Theme Configuration
|
|
3
|
+
*
|
|
4
|
+
* Copy this file to: src/lib/puck-theme.ts
|
|
5
|
+
*
|
|
6
|
+
* Customizes Puck component styles to match your design system.
|
|
7
|
+
* This example uses shadcn/ui CSS variable conventions.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { puckTheme } from '@/lib/puck-theme'
|
|
12
|
+
*
|
|
13
|
+
* <PageRenderer data={data} config={config} theme={puckTheme} />
|
|
14
|
+
* <PuckEditor ... theme={puckTheme} />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { ThemeConfig } from '@delmaredigital/payload-puck/theme'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Theme using CSS variables from your design system
|
|
22
|
+
*
|
|
23
|
+
* Assumes your globals.css defines:
|
|
24
|
+
* --primary, --primary-foreground
|
|
25
|
+
* --secondary, --secondary-foreground
|
|
26
|
+
* --accent, --accent-foreground
|
|
27
|
+
* --muted, --muted-foreground
|
|
28
|
+
* --destructive, --destructive-foreground
|
|
29
|
+
* --background, --foreground
|
|
30
|
+
* --input, --ring
|
|
31
|
+
*/
|
|
32
|
+
export const puckTheme: ThemeConfig = {
|
|
33
|
+
// Button component variants
|
|
34
|
+
buttonVariants: {
|
|
35
|
+
default: {
|
|
36
|
+
classes: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
37
|
+
},
|
|
38
|
+
secondary: {
|
|
39
|
+
classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
40
|
+
},
|
|
41
|
+
outline: {
|
|
42
|
+
classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
|
43
|
+
},
|
|
44
|
+
ghost: {
|
|
45
|
+
classes: 'hover:bg-accent hover:text-accent-foreground',
|
|
46
|
+
},
|
|
47
|
+
destructive: {
|
|
48
|
+
classes: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
|
49
|
+
},
|
|
50
|
+
link: {
|
|
51
|
+
classes: 'text-primary underline-offset-4 hover:underline',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// CTA button variants
|
|
56
|
+
ctaButtonVariants: {
|
|
57
|
+
primary: {
|
|
58
|
+
classes: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
59
|
+
},
|
|
60
|
+
secondary: {
|
|
61
|
+
classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
62
|
+
},
|
|
63
|
+
outline: {
|
|
64
|
+
classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// CTA background styles
|
|
69
|
+
ctaBackgroundStyles: {
|
|
70
|
+
default: 'bg-muted',
|
|
71
|
+
dark: 'bg-primary text-primary-foreground',
|
|
72
|
+
light: 'bg-background',
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
// Focus ring class
|
|
76
|
+
focusRingColor: 'focus:ring-ring',
|
|
77
|
+
|
|
78
|
+
// Color picker presets - customize with your brand colors
|
|
79
|
+
colorPresets: [
|
|
80
|
+
{ hex: '#ffffff', label: 'White' },
|
|
81
|
+
{ hex: '#f8fafc', label: 'Background' },
|
|
82
|
+
{ hex: '#f1f5f9', label: 'Secondary' },
|
|
83
|
+
{ hex: '#e2e8f0', label: 'Muted' },
|
|
84
|
+
{ hex: '#64748b', label: 'Muted FG' },
|
|
85
|
+
{ hex: '#334155', label: 'Slate 700' },
|
|
86
|
+
{ hex: '#1e293b', label: 'Primary' },
|
|
87
|
+
{ hex: '#0f172a', label: 'Foreground' },
|
|
88
|
+
{ hex: '#000000', label: 'Black' },
|
|
89
|
+
// Add your brand accent colors:
|
|
90
|
+
// { hex: '#3b82f6', label: 'Brand Blue' },
|
|
91
|
+
// { hex: '#10b981', label: 'Success' },
|
|
92
|
+
// { hex: '#ef4444', label: 'Danger' },
|
|
93
|
+
],
|
|
94
|
+
}
|