@delmaredigital/payload-puck 0.1.3 → 0.3.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/README.md +293 -1237
- package/dist/admin/EditWithPuckButton.d.ts +74 -0
- package/dist/admin/EditWithPuckButton.d.ts.map +1 -0
- package/dist/admin/EditWithPuckButton.js +114 -0
- package/dist/admin/EditWithPuckButton.js.map +1 -0
- package/dist/admin/EditWithPuckCell.d.ts +43 -0
- package/dist/admin/EditWithPuckCell.d.ts.map +1 -0
- package/dist/admin/EditWithPuckCell.js +66 -0
- package/dist/admin/EditWithPuckCell.js.map +1 -0
- package/dist/admin/PuckEditorView.d.ts +85 -0
- package/dist/admin/PuckEditorView.d.ts.map +1 -0
- package/dist/admin/PuckEditorView.js +135 -0
- package/dist/admin/PuckEditorView.js.map +1 -0
- package/dist/admin/client.d.ts +8 -104
- package/dist/admin/client.d.ts.map +1 -0
- package/dist/admin/client.js +14 -176
- package/dist/admin/client.js.map +1 -0
- package/dist/admin/generateAdminComponents.d.ts +51 -0
- package/dist/admin/generateAdminComponents.d.ts.map +1 -0
- package/dist/admin/generateAdminComponents.js +42 -0
- package/dist/admin/generateAdminComponents.js.map +1 -0
- package/dist/admin/index.d.ts +14 -150
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +17 -30
- package/dist/admin/index.js.map +1 -0
- package/dist/api/createPuckApiRoutes.d.ts +31 -0
- package/dist/api/createPuckApiRoutes.d.ts.map +1 -0
- package/dist/api/createPuckApiRoutes.js +193 -0
- package/dist/api/createPuckApiRoutes.js.map +1 -0
- package/dist/api/createPuckApiRoutesVersions.d.ts +28 -0
- package/dist/api/createPuckApiRoutesVersions.d.ts.map +1 -0
- package/dist/api/createPuckApiRoutesVersions.js +144 -0
- package/dist/api/createPuckApiRoutesVersions.js.map +1 -0
- package/dist/api/createPuckApiRoutesWithId.d.ts +34 -0
- package/dist/api/createPuckApiRoutesWithId.d.ts.map +1 -0
- package/dist/api/createPuckApiRoutesWithId.js +251 -0
- package/dist/api/createPuckApiRoutesWithId.js.map +1 -0
- package/dist/api/index.d.ts +11 -431
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +40 -587
- package/dist/api/index.js.map +1 -0
- package/dist/api/types.d.ts +302 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/utils/mapRootProps.d.ts +76 -0
- package/dist/api/utils/mapRootProps.d.ts.map +1 -0
- package/dist/api/utils/mapRootProps.js +169 -0
- package/dist/api/utils/mapRootProps.js.map +1 -0
- package/dist/collections/Templates.d.ts +9 -0
- package/dist/collections/Templates.d.ts.map +1 -0
- package/dist/collections/Templates.js +62 -0
- package/dist/collections/Templates.js.map +1 -0
- package/dist/components/AccordionClient.d.ts +20 -0
- package/dist/components/AccordionClient.d.ts.map +1 -0
- package/dist/components/AccordionClient.js +67 -0
- package/dist/components/AccordionClient.js.map +1 -0
- package/dist/components/AnimatedWrapper.d.ts +33 -0
- package/dist/components/AnimatedWrapper.d.ts.map +1 -0
- package/dist/components/AnimatedWrapper.js +61 -0
- package/dist/components/AnimatedWrapper.js.map +1 -0
- package/dist/components/exports.d.ts +54 -0
- package/dist/components/exports.d.ts.map +1 -0
- package/dist/components/exports.js +71 -0
- package/dist/components/exports.js.map +1 -0
- package/dist/components/index.d.ts +8 -219
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +15 -9155
- package/dist/components/index.js.map +1 -0
- package/dist/components/interactive/Accordion.d.ts +28 -0
- package/dist/components/interactive/Accordion.d.ts.map +1 -0
- package/dist/components/interactive/Accordion.js +159 -0
- package/dist/components/interactive/Accordion.js.map +1 -0
- package/dist/components/interactive/Accordion.server.d.ts +29 -0
- package/dist/components/interactive/Accordion.server.d.ts.map +1 -0
- package/dist/components/interactive/Accordion.server.js +30 -0
- package/dist/components/interactive/Accordion.server.js.map +1 -0
- package/dist/components/interactive/Button.d.ts +26 -0
- package/dist/components/interactive/Button.d.ts.map +1 -0
- package/dist/components/interactive/Button.js +133 -0
- package/dist/components/interactive/Button.js.map +1 -0
- package/dist/components/interactive/Button.server.d.ts +28 -0
- package/dist/components/interactive/Button.server.d.ts.map +1 -0
- package/dist/components/interactive/Button.server.js +96 -0
- package/dist/components/interactive/Button.server.js.map +1 -0
- package/dist/components/interactive/Card.d.ts +27 -0
- package/dist/components/interactive/Card.d.ts.map +1 -0
- package/dist/components/interactive/Card.js +128 -0
- package/dist/components/interactive/Card.js.map +1 -0
- package/dist/components/interactive/Card.server.d.ts +29 -0
- package/dist/components/interactive/Card.server.d.ts.map +1 -0
- package/dist/components/interactive/Card.server.js +77 -0
- package/dist/components/interactive/Card.server.js.map +1 -0
- package/dist/components/interactive/Divider.d.ts +18 -0
- package/dist/components/interactive/Divider.d.ts.map +1 -0
- package/dist/components/interactive/Divider.js +68 -0
- package/dist/components/interactive/Divider.js.map +1 -0
- package/dist/components/interactive/Divider.server.d.ts +20 -0
- package/dist/components/interactive/Divider.server.d.ts.map +1 -0
- package/dist/components/interactive/Divider.server.js +50 -0
- package/dist/components/interactive/Divider.server.js.map +1 -0
- package/dist/components/interactive/index.d.ts +10 -0
- package/dist/components/interactive/index.d.ts.map +1 -0
- package/dist/components/interactive/index.js +10 -0
- package/dist/components/interactive/index.js.map +1 -0
- package/dist/components/layout/Container.d.ts +29 -0
- package/dist/components/layout/Container.d.ts.map +1 -0
- package/dist/components/layout/Container.js +166 -0
- package/dist/components/layout/Container.js.map +1 -0
- package/dist/components/layout/Container.server.d.ts +32 -0
- package/dist/components/layout/Container.server.d.ts.map +1 -0
- package/dist/components/layout/Container.server.js +105 -0
- package/dist/components/layout/Container.server.js.map +1 -0
- package/dist/components/layout/Flex.d.ts +36 -0
- package/dist/components/layout/Flex.d.ts.map +1 -0
- package/dist/components/layout/Flex.js +183 -0
- package/dist/components/layout/Flex.js.map +1 -0
- package/dist/components/layout/Flex.server.d.ts +36 -0
- package/dist/components/layout/Flex.server.d.ts.map +1 -0
- package/dist/components/layout/Flex.server.js +97 -0
- package/dist/components/layout/Flex.server.js.map +1 -0
- package/dist/components/layout/Grid.d.ts +31 -0
- package/dist/components/layout/Grid.d.ts.map +1 -0
- package/dist/components/layout/Grid.js +164 -0
- package/dist/components/layout/Grid.js.map +1 -0
- package/dist/components/layout/Grid.server.d.ts +32 -0
- package/dist/components/layout/Grid.server.d.ts.map +1 -0
- package/dist/components/layout/Grid.server.js +92 -0
- package/dist/components/layout/Grid.server.js.map +1 -0
- package/dist/components/layout/Section.d.ts +35 -0
- package/dist/components/layout/Section.d.ts.map +1 -0
- package/dist/components/layout/Section.js +212 -0
- package/dist/components/layout/Section.js.map +1 -0
- package/dist/components/layout/Section.server.d.ts +35 -0
- package/dist/components/layout/Section.server.d.ts.map +1 -0
- package/dist/components/layout/Section.server.js +144 -0
- package/dist/components/layout/Section.server.js.map +1 -0
- package/dist/components/layout/Spacer.d.ts +18 -0
- package/dist/components/layout/Spacer.d.ts.map +1 -0
- package/dist/components/layout/Spacer.js +99 -0
- package/dist/components/layout/Spacer.js.map +1 -0
- package/dist/components/layout/Spacer.server.d.ts +21 -0
- package/dist/components/layout/Spacer.server.d.ts.map +1 -0
- package/dist/components/layout/Spacer.server.js +61 -0
- package/dist/components/layout/Spacer.server.js.map +1 -0
- package/dist/components/layout/Template.d.ts +35 -0
- package/dist/components/layout/Template.d.ts.map +1 -0
- package/dist/components/layout/Template.js +124 -0
- package/dist/components/layout/Template.js.map +1 -0
- package/dist/components/layout/Template.server.d.ts +32 -0
- package/dist/components/layout/Template.server.d.ts.map +1 -0
- package/dist/components/layout/Template.server.js +75 -0
- package/dist/components/layout/Template.server.js.map +1 -0
- package/dist/components/layout/index.d.ts +14 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +13 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/components/media/Image.d.ts +30 -0
- package/dist/components/media/Image.d.ts.map +1 -0
- package/dist/components/media/Image.js +123 -0
- package/dist/components/media/Image.js.map +1 -0
- package/dist/components/media/Image.server.d.ts +28 -0
- package/dist/components/media/Image.server.d.ts.map +1 -0
- package/dist/components/media/Image.server.js +76 -0
- package/dist/components/media/Image.server.js.map +1 -0
- package/dist/components/media/index.d.ts +7 -0
- package/dist/components/media/index.d.ts.map +1 -0
- package/dist/components/media/index.js +7 -0
- package/dist/components/media/index.js.map +1 -0
- package/dist/components/typography/Heading.d.ts +21 -0
- package/dist/components/typography/Heading.d.ts.map +1 -0
- package/dist/components/typography/Heading.js +71 -0
- package/dist/components/typography/Heading.js.map +1 -0
- package/dist/components/typography/Heading.server.d.ts +21 -0
- package/dist/components/typography/Heading.server.d.ts.map +1 -0
- package/dist/components/typography/Heading.server.js +49 -0
- package/dist/components/typography/Heading.server.js.map +1 -0
- package/dist/components/typography/RichText.d.ts +20 -0
- package/dist/components/typography/RichText.d.ts.map +1 -0
- package/dist/components/typography/RichText.editor.d.ts +11 -0
- package/dist/components/typography/RichText.editor.d.ts.map +1 -0
- package/dist/components/typography/RichText.editor.js +67 -0
- package/dist/components/typography/RichText.editor.js.map +1 -0
- package/dist/components/typography/RichText.js +73 -0
- package/dist/components/typography/RichText.js.map +1 -0
- package/dist/components/typography/RichText.server.d.ts +22 -0
- package/dist/components/typography/RichText.server.d.ts.map +1 -0
- package/dist/components/typography/RichText.server.js +52 -0
- package/dist/components/typography/RichText.server.js.map +1 -0
- package/dist/components/typography/Text.d.ts +20 -0
- package/dist/components/typography/Text.d.ts.map +1 -0
- package/dist/components/typography/Text.js +61 -0
- package/dist/components/typography/Text.js.map +1 -0
- package/dist/components/typography/Text.server.d.ts +21 -0
- package/dist/components/typography/Text.server.d.ts.map +1 -0
- package/dist/components/typography/Text.server.js +39 -0
- package/dist/components/typography/Text.server.js.map +1 -0
- package/dist/components/typography/index.d.ts +10 -0
- package/dist/components/typography/index.d.ts.map +1 -0
- package/dist/components/typography/index.js +10 -0
- package/dist/components/typography/index.js.map +1 -0
- package/dist/config/config.editor.d.ts +15 -56
- package/dist/config/config.editor.d.ts.map +1 -0
- package/dist/config/config.editor.js +125 -9364
- package/dist/config/config.editor.js.map +1 -0
- package/dist/config/index.d.ts +7 -33
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +110 -2028
- package/dist/config/index.js.map +1 -0
- package/dist/config/merge.d.ts +23 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +80 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/presets.d.ts +342 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +247 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/editor/PuckEditor.client.d.ts +131 -0
- package/dist/editor/PuckEditor.client.d.ts.map +1 -0
- package/dist/editor/PuckEditor.client.js +42 -0
- package/dist/editor/PuckEditor.client.js.map +1 -0
- package/dist/editor/PuckEditorCore.client.d.ts +141 -0
- package/dist/editor/PuckEditorCore.client.d.ts.map +1 -0
- package/dist/editor/PuckEditorCore.client.js +306 -0
- package/dist/editor/PuckEditorCore.client.js.map +1 -0
- package/dist/editor/components/HeaderActions.d.ts +109 -0
- package/dist/editor/components/HeaderActions.d.ts.map +1 -0
- package/dist/editor/components/HeaderActions.js +254 -0
- package/dist/editor/components/HeaderActions.js.map +1 -0
- package/dist/editor/components/IframeWrapper.d.ts +77 -0
- package/dist/editor/components/IframeWrapper.d.ts.map +1 -0
- package/dist/editor/components/IframeWrapper.js +257 -0
- package/dist/editor/components/IframeWrapper.js.map +1 -0
- package/dist/editor/components/LoadingState.d.ts +14 -0
- package/dist/editor/components/LoadingState.d.ts.map +1 -0
- package/dist/editor/components/LoadingState.js +12 -0
- package/dist/editor/components/LoadingState.js.map +1 -0
- package/dist/editor/components/PreviewModal.d.ts +54 -0
- package/dist/editor/components/PreviewModal.d.ts.map +1 -0
- package/dist/editor/components/PreviewModal.js +298 -0
- package/dist/editor/components/PreviewModal.js.map +1 -0
- package/dist/editor/components/VersionHistory.d.ts +44 -0
- package/dist/editor/components/VersionHistory.d.ts.map +1 -0
- package/dist/editor/components/VersionHistory.js +308 -0
- package/dist/editor/components/VersionHistory.js.map +1 -0
- package/dist/editor/hooks/useUnsavedChanges.d.ts +27 -0
- package/dist/editor/hooks/useUnsavedChanges.d.ts.map +1 -0
- package/dist/editor/hooks/useUnsavedChanges.js +55 -0
- package/dist/editor/hooks/useUnsavedChanges.js.map +1 -0
- package/dist/editor/index.d.ts +16 -756
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +49 -4533
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/plugins/index.d.ts +12 -0
- package/dist/editor/plugins/index.d.ts.map +1 -0
- package/dist/editor/plugins/index.js +12 -0
- package/dist/editor/plugins/index.js.map +1 -0
- package/dist/endpoints/index.d.ts +46 -0
- package/dist/endpoints/index.d.ts.map +1 -0
- package/dist/endpoints/index.js +204 -0
- package/dist/endpoints/index.js.map +1 -0
- package/dist/exports/client.d.ts +19 -0
- package/dist/exports/client.d.ts.map +1 -0
- package/dist/exports/client.js +21 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/rsc.d.ts +19 -0
- package/dist/exports/rsc.d.ts.map +1 -0
- package/dist/exports/rsc.js +19 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/fields/AlignmentField.d.ts +36 -0
- package/dist/fields/AlignmentField.d.ts.map +1 -0
- package/dist/fields/AlignmentField.js +120 -0
- package/dist/fields/AlignmentField.js.map +1 -0
- package/dist/fields/AnimationField.d.ts +44 -0
- package/dist/fields/AnimationField.d.ts.map +1 -0
- package/dist/fields/AnimationField.js +329 -0
- package/dist/fields/AnimationField.js.map +1 -0
- package/dist/fields/BackgroundField.d.ts +40 -0
- package/dist/fields/BackgroundField.d.ts.map +1 -0
- package/dist/fields/BackgroundField.js +413 -0
- package/dist/fields/BackgroundField.js.map +1 -0
- package/dist/fields/BorderField.d.ts +29 -0
- package/dist/fields/BorderField.d.ts.map +1 -0
- package/dist/fields/BorderField.js +264 -0
- package/dist/fields/BorderField.js.map +1 -0
- package/dist/fields/ColorPickerField.d.ts +43 -0
- package/dist/fields/ColorPickerField.d.ts.map +1 -0
- package/dist/fields/ColorPickerField.js +285 -0
- package/dist/fields/ColorPickerField.js.map +1 -0
- package/dist/fields/DimensionsField.d.ts +43 -0
- package/dist/fields/DimensionsField.d.ts.map +1 -0
- package/dist/fields/DimensionsField.js +532 -0
- package/dist/fields/DimensionsField.js.map +1 -0
- package/dist/fields/FlexAlignmentField.d.ts +61 -0
- package/dist/fields/FlexAlignmentField.d.ts.map +1 -0
- package/dist/fields/FlexAlignmentField.js +166 -0
- package/dist/fields/FlexAlignmentField.js.map +1 -0
- package/dist/fields/FolderPickerField.d.ts +17 -0
- package/dist/fields/FolderPickerField.d.ts.map +1 -0
- package/dist/fields/FolderPickerField.js +282 -0
- package/dist/fields/FolderPickerField.js.map +1 -0
- package/dist/fields/GradientEditor.d.ts +22 -0
- package/dist/fields/GradientEditor.d.ts.map +1 -0
- package/dist/fields/GradientEditor.js +322 -0
- package/dist/fields/GradientEditor.js.map +1 -0
- package/dist/fields/LockedField.d.ts +67 -0
- package/dist/fields/LockedField.d.ts.map +1 -0
- package/dist/fields/LockedField.js +170 -0
- package/dist/fields/LockedField.js.map +1 -0
- package/dist/fields/MarginField.d.ts +31 -0
- package/dist/fields/MarginField.d.ts.map +1 -0
- package/dist/fields/MarginField.js +233 -0
- package/dist/fields/MarginField.js.map +1 -0
- package/dist/fields/MediaField.d.ts +33 -0
- package/dist/fields/MediaField.d.ts.map +1 -0
- package/dist/fields/MediaField.js +677 -0
- package/dist/fields/MediaField.js.map +1 -0
- package/dist/fields/PaddingField.d.ts +29 -0
- package/dist/fields/PaddingField.d.ts.map +1 -0
- package/dist/fields/PaddingField.js +232 -0
- package/dist/fields/PaddingField.js.map +1 -0
- package/dist/fields/PageSegmentField.d.ts +17 -0
- package/dist/fields/PageSegmentField.d.ts.map +1 -0
- package/dist/fields/PageSegmentField.js +92 -0
- package/dist/fields/PageSegmentField.js.map +1 -0
- package/dist/fields/ResetField.d.ts +27 -0
- package/dist/fields/ResetField.d.ts.map +1 -0
- package/dist/fields/ResetField.js +122 -0
- package/dist/fields/ResetField.js.map +1 -0
- package/dist/fields/ResponsiveField.d.ts +38 -0
- package/dist/fields/ResponsiveField.d.ts.map +1 -0
- package/dist/fields/ResponsiveField.js +275 -0
- package/dist/fields/ResponsiveField.js.map +1 -0
- package/dist/fields/ResponsiveVisibilityField.d.ts +34 -0
- package/dist/fields/ResponsiveVisibilityField.d.ts.map +1 -0
- package/dist/fields/ResponsiveVisibilityField.js +145 -0
- package/dist/fields/ResponsiveVisibilityField.js.map +1 -0
- package/dist/fields/SizeField.d.ts +54 -0
- package/dist/fields/SizeField.d.ts.map +1 -0
- package/dist/fields/SizeField.js +255 -0
- package/dist/fields/SizeField.js.map +1 -0
- package/dist/fields/SlugPreviewField.d.ts +16 -0
- package/dist/fields/SlugPreviewField.d.ts.map +1 -0
- package/dist/fields/SlugPreviewField.js +49 -0
- package/dist/fields/SlugPreviewField.js.map +1 -0
- package/dist/fields/TemplateField.d.ts +31 -0
- package/dist/fields/TemplateField.d.ts.map +1 -0
- package/dist/fields/TemplateField.js +428 -0
- package/dist/fields/TemplateField.js.map +1 -0
- package/dist/fields/TiptapField.d.ts +40 -0
- package/dist/fields/TiptapField.d.ts.map +1 -0
- package/dist/fields/TiptapField.js +857 -0
- package/dist/fields/TiptapField.js.map +1 -0
- package/dist/fields/TiptapModal.d.ts +10 -0
- package/dist/fields/TiptapModal.d.ts.map +1 -0
- package/dist/fields/TiptapModal.js +114 -0
- package/dist/fields/TiptapModal.js.map +1 -0
- package/dist/fields/TiptapModalField.d.ts +23 -0
- package/dist/fields/TiptapModalField.d.ts.map +1 -0
- package/dist/fields/TiptapModalField.js +55 -0
- package/dist/fields/TiptapModalField.js.map +1 -0
- package/dist/fields/TransformField.d.ts +31 -0
- package/dist/fields/TransformField.d.ts.map +1 -0
- package/dist/fields/TransformField.js +384 -0
- package/dist/fields/TransformField.js.map +1 -0
- package/dist/fields/VerticalAlignmentField.d.ts +35 -0
- package/dist/fields/VerticalAlignmentField.d.ts.map +1 -0
- package/dist/fields/VerticalAlignmentField.js +120 -0
- package/dist/fields/VerticalAlignmentField.js.map +1 -0
- package/dist/fields/WidthField.d.ts +28 -0
- package/dist/fields/WidthField.d.ts.map +1 -0
- package/dist/fields/WidthField.js +339 -0
- package/dist/fields/WidthField.js.map +1 -0
- package/dist/fields/index.d.ts +44 -559
- package/dist/fields/index.d.ts.map +1 -0
- package/dist/fields/index.js +91 -7685
- package/dist/fields/index.js.map +1 -0
- package/dist/fields/richtext-output.css +219 -0
- package/dist/{shared-DeNKN95N.d.mts → fields/shared.d.ts} +114 -133
- package/dist/fields/shared.d.ts.map +1 -0
- package/dist/fields/shared.js +1542 -0
- package/dist/fields/shared.js.map +1 -0
- package/dist/fields/{index.css → tiptap-styles.css} +75 -166
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useResponsiveStyles.d.ts +51 -0
- package/dist/hooks/useResponsiveStyles.d.ts.map +1 -0
- package/dist/hooks/useResponsiveStyles.js +149 -0
- package/dist/hooks/useResponsiveStyles.js.map +1 -0
- package/dist/hooks/useScrollAnimation.d.ts +56 -0
- package/dist/hooks/useScrollAnimation.d.ts.map +1 -0
- package/dist/hooks/useScrollAnimation.js +116 -0
- package/dist/hooks/useScrollAnimation.js.map +1 -0
- package/dist/index.d.ts +66 -6
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -568
- package/dist/index.js.map +1 -0
- package/dist/layouts/LayoutWrapper.d.ts +33 -0
- package/dist/layouts/LayoutWrapper.d.ts.map +1 -0
- package/dist/layouts/LayoutWrapper.js +112 -0
- package/dist/layouts/LayoutWrapper.js.map +1 -0
- package/dist/layouts/defaults.d.ts +40 -0
- package/dist/layouts/defaults.d.ts.map +1 -0
- package/dist/layouts/defaults.js +106 -0
- package/dist/layouts/defaults.js.map +1 -0
- package/dist/layouts/index.d.ts +27 -94
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +30 -393
- package/dist/layouts/index.js.map +1 -0
- package/dist/{types-D7D3rZ1J.d.ts → layouts/types.d.ts} +8 -11
- package/dist/layouts/types.d.ts.map +1 -0
- package/dist/layouts/types.js +7 -0
- package/dist/layouts/types.js.map +1 -0
- package/dist/layouts/utils.d.ts +42 -0
- package/dist/layouts/utils.d.ts.map +1 -0
- package/dist/layouts/utils.js +83 -0
- package/dist/layouts/utils.js.map +1 -0
- package/dist/plugin/collections/Pages.d.ts +8 -0
- package/dist/plugin/collections/Pages.d.ts.map +1 -0
- package/dist/plugin/collections/Pages.js +117 -0
- package/dist/plugin/collections/Pages.js.map +1 -0
- package/dist/plugin/fields/index.d.ts +153 -0
- package/dist/plugin/fields/index.d.ts.map +1 -0
- package/dist/plugin/fields/index.js +364 -0
- package/dist/plugin/fields/index.js.map +1 -0
- package/dist/plugin/fields/types.d.ts +108 -0
- package/dist/plugin/fields/types.d.ts.map +1 -0
- package/dist/plugin/fields/types.js +7 -0
- package/dist/plugin/fields/types.js.map +1 -0
- package/dist/plugin/index.d.ts +13 -255
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +276 -553
- package/dist/plugin/index.js.map +1 -0
- package/dist/render/HybridPageRenderer.d.ts +85 -0
- package/dist/render/HybridPageRenderer.d.ts.map +1 -0
- package/dist/render/HybridPageRenderer.js +29 -0
- package/dist/render/HybridPageRenderer.js.map +1 -0
- package/dist/render/PageRenderer.d.ts +51 -0
- package/dist/render/PageRenderer.d.ts.map +1 -0
- package/dist/render/PageRenderer.js +61 -0
- package/dist/render/PageRenderer.js.map +1 -0
- package/dist/render/PuckEditor.client.d.ts +66 -0
- package/dist/render/PuckEditor.client.d.ts.map +1 -0
- package/dist/render/PuckEditor.client.js +66 -0
- package/dist/render/PuckEditor.client.js.map +1 -0
- package/dist/render/index.d.ts +8 -106
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +10 -2162
- package/dist/render/index.js.map +1 -0
- package/dist/theme/context.d.ts +59 -0
- package/dist/theme/context.d.ts.map +1 -0
- package/dist/theme/context.js +73 -0
- package/dist/theme/context.js.map +1 -0
- package/dist/theme/defaults.d.ts +39 -0
- package/dist/theme/defaults.d.ts.map +1 -0
- package/dist/theme/defaults.js +72 -0
- package/dist/theme/defaults.js.map +1 -0
- package/dist/theme/example.d.ts +30 -0
- package/dist/theme/example.d.ts.map +1 -0
- package/dist/theme/example.js +89 -0
- package/dist/theme/example.js.map +1 -0
- package/dist/theme/index.d.ts +17 -140
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +34 -200
- package/dist/theme/index.js.map +1 -0
- package/dist/{types-_6MvjyKv.d.ts → theme/types.d.ts} +8 -9
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +9 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme/utils.d.ts +30 -0
- package/dist/theme/utils.d.ts.map +1 -0
- package/dist/theme/utils.js +84 -0
- package/dist/theme/utils.js.map +1 -0
- package/dist/{index-CQu6SzDg.d.mts → types/index.d.ts} +120 -115
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +23 -257
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +56 -425
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/{index.d.mts → migration.d.ts} +16 -112
- package/dist/utils/migration.d.ts.map +1 -0
- package/dist/utils/migration.js +309 -0
- package/dist/utils/migration.js.map +1 -0
- package/dist/utils/validation.d.ts +89 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +247 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/views/PuckConfigContext.d.ts +71 -0
- package/dist/views/PuckConfigContext.d.ts.map +1 -0
- package/dist/views/PuckConfigContext.js +45 -0
- package/dist/views/PuckConfigContext.js.map +1 -0
- package/dist/views/PuckEditorClient.d.ts +73 -0
- package/dist/views/PuckEditorClient.d.ts.map +1 -0
- package/dist/views/PuckEditorClient.js +130 -0
- package/dist/views/PuckEditorClient.js.map +1 -0
- package/dist/views/PuckEditorView.d.ts +19 -0
- package/dist/views/PuckEditorView.d.ts.map +1 -0
- package/dist/views/PuckEditorView.js +106 -0
- package/dist/views/PuckEditorView.js.map +1 -0
- package/dist/views/index.d.ts +10 -0
- package/dist/views/index.d.ts.map +1 -0
- package/dist/views/index.js +10 -0
- package/dist/views/index.js.map +1 -0
- package/package.json +50 -72
- package/dist/AccordionClient.d.mts +0 -24
- package/dist/AccordionClient.d.ts +0 -24
- package/dist/AccordionClient.js +0 -786
- package/dist/AccordionClient.mjs +0 -784
- package/dist/AnimatedWrapper.d.mts +0 -30
- package/dist/AnimatedWrapper.d.ts +0 -30
- package/dist/AnimatedWrapper.js +0 -379
- package/dist/AnimatedWrapper.mjs +0 -377
- package/dist/admin/client.d.mts +0 -108
- package/dist/admin/client.mjs +0 -173
- package/dist/admin/index.d.mts +0 -157
- package/dist/admin/index.mjs +0 -29
- package/dist/api/index.d.mts +0 -460
- package/dist/api/index.mjs +0 -578
- package/dist/components/index.css +0 -339
- package/dist/components/index.d.mts +0 -222
- package/dist/components/index.mjs +0 -9109
- package/dist/config/config.editor.css +0 -339
- package/dist/config/config.editor.d.mts +0 -153
- package/dist/config/config.editor.mjs +0 -9347
- package/dist/config/index.d.mts +0 -68
- package/dist/config/index.mjs +0 -2008
- package/dist/editor/index.d.mts +0 -784
- package/dist/editor/index.mjs +0 -4500
- package/dist/fields/index.d.mts +0 -600
- package/dist/fields/index.mjs +0 -7569
- package/dist/index-CoUQnyC3.d.ts +0 -327
- package/dist/index.d.mts +0 -6
- package/dist/index.mjs +0 -555
- package/dist/layouts/index.d.mts +0 -96
- package/dist/layouts/index.mjs +0 -378
- package/dist/plugin/index.d.mts +0 -289
- package/dist/plugin/index.mjs +0 -555
- package/dist/render/index.d.mts +0 -109
- package/dist/render/index.mjs +0 -2140
- package/dist/shared-DeNKN95N.d.ts +0 -546
- package/dist/theme/index.d.mts +0 -155
- package/dist/theme/index.mjs +0 -186
- package/dist/types-D7D3rZ1J.d.mts +0 -116
- package/dist/types-_6MvjyKv.d.mts +0 -104
- package/dist/utils/index.mjs +0 -412
- package/dist/utils-DaRs9t0J.d.mts +0 -85
- package/dist/utils-gAvt0Vhw.d.ts +0 -85
- package/examples/README.md +0 -247
- package/examples/api/puck/pages/[id]/route.ts +0 -64
- package/examples/api/puck/pages/[id]/versions/route.ts +0 -47
- package/examples/api/puck/pages/route.ts +0 -45
- package/examples/app/(frontend)/page.tsx +0 -94
- package/examples/app/(manage)/layout.tsx +0 -31
- package/examples/app/[...slug]/page.tsx +0 -101
- package/examples/app/pages/[id]/edit/page.tsx +0 -148
- package/examples/components/CustomBanner.tsx +0 -368
- package/examples/config/custom-config.ts +0 -223
- package/examples/config/payload.config.example.ts +0 -64
- package/examples/lib/puck-layouts.ts +0 -258
- package/examples/lib/puck-theme.ts +0 -94
- package/examples/styles/puck-theme.css +0 -171
package/README.md
CHANGED
|
@@ -9,16 +9,14 @@ A PayloadCMS plugin for integrating [Puck](https://puckeditor.com) visual page b
|
|
|
9
9
|
- [Installation](#installation)
|
|
10
10
|
- [Quick Start](#quick-start)
|
|
11
11
|
- [Styling Setup](#styling-setup)
|
|
12
|
-
- [Setup Checklist](#setup-checklist)
|
|
13
12
|
- [Core Concepts](#core-concepts)
|
|
14
13
|
- [Components](#components)
|
|
15
|
-
- [Configuration](#configuration)
|
|
16
14
|
- [Custom Fields](#custom-fields)
|
|
17
15
|
- [Theming](#theming)
|
|
18
16
|
- [Layouts](#layouts)
|
|
19
|
-
- [
|
|
20
|
-
- [Plugin Options](#plugin-options)
|
|
17
|
+
- [Page-Tree Integration](#page-tree-integration)
|
|
21
18
|
- [Hybrid Integration](#hybrid-integration)
|
|
19
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
22
20
|
- [License](#license)
|
|
23
21
|
|
|
24
22
|
---
|
|
@@ -31,65 +29,24 @@ A PayloadCMS plugin for integrating [Puck](https://puckeditor.com) visual page b
|
|
|
31
29
|
|------------|---------|---------|
|
|
32
30
|
| `@measured/puck` | >= 0.20.0 | Visual editor core |
|
|
33
31
|
| `payload` | >= 3.0.0 | CMS backend |
|
|
34
|
-
|
|
|
32
|
+
| `@payloadcms/next` | >= 3.0.0 | Payload Next.js integration |
|
|
33
|
+
| `next` | >= 14.0.0 | React framework |
|
|
35
34
|
| `react` | >= 18.0.0 | UI library |
|
|
36
35
|
| `@tailwindcss/typography` | >= 0.5.0 | RichText component styling |
|
|
37
36
|
|
|
38
|
-
> **⚠️ Don't skip the styling setup!** After Quick Start, you must configure Tailwind to scan this package. See [Styling Setup](#styling-setup).
|
|
39
|
-
|
|
40
37
|
### Install
|
|
41
38
|
|
|
42
39
|
```bash
|
|
43
40
|
pnpm add @delmaredigital/payload-puck @measured/puck
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
Or install from GitHub:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pnpm add github:delmaredigital/payload-puck#main @measured/puck
|
|
50
|
-
```
|
|
51
|
-
|
|
52
43
|
---
|
|
53
44
|
|
|
54
45
|
## Quick Start
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<details>
|
|
59
|
-
<summary><strong>Option A: Copy Boilerplate (Fastest)</strong></summary>
|
|
60
|
-
|
|
61
|
-
The package includes ready-to-use example files:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
# Copy API routes
|
|
65
|
-
cp -r node_modules/@delmaredigital/payload-puck/examples/api/puck src/app/api/
|
|
66
|
-
|
|
67
|
-
# Copy editor layout (REQUIRED - imports Tailwind CSS) and page
|
|
68
|
-
mkdir -p src/app/\(manage\)/pages/\[id\]/edit
|
|
69
|
-
cp node_modules/@delmaredigital/payload-puck/examples/app/\(manage\)/layout.tsx src/app/\(manage\)/
|
|
70
|
-
cp node_modules/@delmaredigital/payload-puck/examples/app/pages/\[id\]/edit/page.tsx src/app/\(manage\)/pages/\[id\]/edit/
|
|
71
|
-
|
|
72
|
-
# Copy frontend routes (homepage + dynamic pages)
|
|
73
|
-
mkdir -p src/app/\(frontend\)
|
|
74
|
-
cp node_modules/@delmaredigital/payload-puck/examples/app/\(frontend\)/page.tsx src/app/\(frontend\)/
|
|
75
|
-
mkdir -p src/app/\(frontend\)/\[...slug\]
|
|
76
|
-
cp node_modules/@delmaredigital/payload-puck/examples/app/\[...slug\]/page.tsx src/app/\(frontend\)/\[...slug\]/
|
|
77
|
-
|
|
78
|
-
# Copy theme config (optional)
|
|
79
|
-
mkdir -p src/lib
|
|
80
|
-
cp node_modules/@delmaredigital/payload-puck/examples/lib/puck-theme.ts src/lib/
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
> **Important:** Update the CSS import path in `src/app/(manage)/layout.tsx` to match your project's globals.css location.
|
|
84
|
-
|
|
85
|
-
See `examples/README.md` for detailed customization instructions.
|
|
86
|
-
|
|
87
|
-
</details>
|
|
88
|
-
|
|
89
|
-
<details>
|
|
90
|
-
<summary><strong>Option B: Manual Setup</strong></summary>
|
|
47
|
+
The plugin integrates directly into Payload's admin UI with minimal configuration. API endpoints and admin views are registered automatically.
|
|
91
48
|
|
|
92
|
-
|
|
49
|
+
### Step 1: Add the Plugin
|
|
93
50
|
|
|
94
51
|
```typescript
|
|
95
52
|
// payload.config.ts
|
|
@@ -106,254 +63,146 @@ export default buildConfig({
|
|
|
106
63
|
})
|
|
107
64
|
```
|
|
108
65
|
|
|
109
|
-
|
|
66
|
+
This automatically:
|
|
67
|
+
- Creates a `pages` collection with Puck fields (or adds fields to your existing collection)
|
|
68
|
+
- Registers API endpoints at `/api/puck/:collection`
|
|
69
|
+
- Adds the Puck editor view at `/admin/puck-editor/:collection/:id`
|
|
70
|
+
- Adds "Edit with Puck" buttons to the admin UI
|
|
110
71
|
|
|
111
|
-
|
|
112
|
-
// app/api/puck/pages/route.ts
|
|
113
|
-
import { createPuckApiRoutes } from '@delmaredigital/payload-puck/api'
|
|
114
|
-
import { getPayload } from 'payload'
|
|
115
|
-
import config from '@payload-config'
|
|
116
|
-
import { headers } from 'next/headers'
|
|
72
|
+
### Step 2: Provide Puck Configuration
|
|
117
73
|
|
|
118
|
-
|
|
119
|
-
collection: 'pages',
|
|
120
|
-
payloadConfig: config,
|
|
121
|
-
auth: {
|
|
122
|
-
authenticate: async (request) => {
|
|
123
|
-
const payload = await getPayload({ config })
|
|
124
|
-
const { user } = await payload.auth({ headers: await headers() })
|
|
125
|
-
if (!user) return { authenticated: false }
|
|
126
|
-
return { authenticated: true, user: { id: user.id } }
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
})
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
// app/api/puck/pages/[id]/route.ts
|
|
134
|
-
import { createPuckApiRoutesWithId } from '@delmaredigital/payload-puck/api'
|
|
135
|
-
import config from '@payload-config'
|
|
136
|
-
|
|
137
|
-
export const { GET, PATCH, DELETE } = createPuckApiRoutesWithId({
|
|
138
|
-
collection: 'pages',
|
|
139
|
-
payloadConfig: config,
|
|
140
|
-
auth: {
|
|
141
|
-
authenticate: async (request) => {
|
|
142
|
-
// Same auth logic as above
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
})
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
#### Step 3: Create the Editor Layout & Page
|
|
149
|
-
|
|
150
|
-
First, create a layout that imports your Tailwind CSS:
|
|
74
|
+
Wrap your app with `PuckConfigProvider` to supply the Puck configuration. This is required because Puck configs contain React components that cannot be serialized from server to client.
|
|
151
75
|
|
|
152
76
|
```typescript
|
|
153
|
-
// app/(
|
|
154
|
-
import '
|
|
155
|
-
|
|
156
|
-
export const metadata = {
|
|
157
|
-
title: 'Puck Editor',
|
|
158
|
-
description: 'Visual page editor',
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export default function ManageLayout({ children }: { children: React.ReactNode }) {
|
|
162
|
-
return (
|
|
163
|
-
// data-theme may be required if your CSS hides content until theme is set
|
|
164
|
-
<html lang="en" data-theme="light">
|
|
165
|
-
<body>{children}</body>
|
|
166
|
-
</html>
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Then create the editor page:
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
// app/(manage)/pages/[id]/edit/page.tsx
|
|
175
|
-
'use client'
|
|
176
|
-
|
|
177
|
-
import { PuckEditorView } from '@delmaredigital/payload-puck/editor'
|
|
77
|
+
// app/(app)/layout.tsx (covers both admin and frontend)
|
|
78
|
+
import { PuckConfigProvider } from '@delmaredigital/payload-puck/client'
|
|
178
79
|
import { editorConfig } from '@delmaredigital/payload-puck/config/editor'
|
|
179
80
|
|
|
180
|
-
export default function
|
|
81
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
181
82
|
return (
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
83
|
+
<html lang="en">
|
|
84
|
+
<body>
|
|
85
|
+
<PuckConfigProvider config={editorConfig}>
|
|
86
|
+
{children}
|
|
87
|
+
</PuckConfigProvider>
|
|
88
|
+
</body>
|
|
89
|
+
</html>
|
|
189
90
|
)
|
|
190
91
|
}
|
|
191
92
|
```
|
|
192
93
|
|
|
193
|
-
|
|
194
|
-
- **Save Draft** - Saves without publishing
|
|
195
|
-
- **Publish** - Publishes the page
|
|
196
|
-
- **Draft/Published badge** - Shows current document status
|
|
197
|
-
- **Unsaved changes warning** - Prevents accidental navigation
|
|
198
|
-
- **Heading Analyzer** - WCAG-compliant heading outline visualization (enabled by default)
|
|
199
|
-
|
|
200
|
-
**Heading Analyzer Plugin**
|
|
201
|
-
|
|
202
|
-
The heading analyzer plugin is included by default and displays a heading outline in the editor sidebar. It helps identify accessibility issues like skipped heading levels (e.g., jumping from H1 to H3).
|
|
94
|
+
### Step 3: Create a Frontend Route
|
|
203
95
|
|
|
204
|
-
|
|
96
|
+
The plugin can't auto-create frontend routes (Next.js App Router is file-based), but here's copy-paste ready code:
|
|
205
97
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
<PuckEditorView
|
|
209
|
-
plugins={[myCustomPlugin]}
|
|
210
|
-
// ...
|
|
211
|
-
/>
|
|
212
|
-
|
|
213
|
-
// Disable all default plugins
|
|
214
|
-
<PuckEditorView
|
|
215
|
-
plugins={false}
|
|
216
|
-
// ...
|
|
217
|
-
/>
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
#### Step 4: Create a Frontend Route
|
|
98
|
+
<details>
|
|
99
|
+
<summary><strong>📄 app/(frontend)/[[...slug]]/page.tsx</strong> (click to expand)</summary>
|
|
221
100
|
|
|
222
101
|
```typescript
|
|
223
|
-
// app/(frontend)/[...slug]/page.tsx
|
|
224
102
|
import { getPayload } from 'payload'
|
|
225
103
|
import config from '@payload-config'
|
|
226
104
|
import { PageRenderer } from '@delmaredigital/payload-puck/render'
|
|
227
105
|
import { baseConfig } from '@delmaredigital/payload-puck/config'
|
|
228
106
|
import { notFound } from 'next/navigation'
|
|
107
|
+
import type { Metadata } from 'next'
|
|
229
108
|
|
|
230
|
-
|
|
231
|
-
|
|
109
|
+
// Fetch page by slug (or homepage if no slug)
|
|
110
|
+
async function getPage(slug?: string[]) {
|
|
232
111
|
const payload = await getPayload({ config })
|
|
112
|
+
const slugPath = slug?.join('/') || ''
|
|
233
113
|
|
|
114
|
+
// Try to find by slug, or find homepage
|
|
234
115
|
const { docs } = await payload.find({
|
|
235
116
|
collection: 'pages',
|
|
236
|
-
where:
|
|
117
|
+
where: slugPath
|
|
118
|
+
? { slug: { equals: slugPath } }
|
|
119
|
+
: { isHomepage: { equals: true } },
|
|
237
120
|
limit: 1,
|
|
238
121
|
})
|
|
239
122
|
|
|
240
|
-
|
|
123
|
+
return docs[0] || null
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Generate metadata from page SEO fields
|
|
127
|
+
export async function generateMetadata({
|
|
128
|
+
params
|
|
129
|
+
}: {
|
|
130
|
+
params: Promise<{ slug?: string[] }>
|
|
131
|
+
}): Promise<Metadata> {
|
|
132
|
+
const { slug } = await params
|
|
133
|
+
const page = await getPage(slug)
|
|
134
|
+
|
|
135
|
+
if (!page) return {}
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
title: page.meta?.title || page.title,
|
|
139
|
+
description: page.meta?.description,
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Render the page
|
|
144
|
+
export default async function Page({
|
|
145
|
+
params
|
|
146
|
+
}: {
|
|
147
|
+
params: Promise<{ slug?: string[] }>
|
|
148
|
+
}) {
|
|
149
|
+
const { slug } = await params
|
|
150
|
+
const page = await getPage(slug)
|
|
151
|
+
|
|
241
152
|
if (!page) notFound()
|
|
242
153
|
|
|
243
154
|
return <PageRenderer config={baseConfig} data={page.puckData} />
|
|
244
155
|
}
|
|
245
156
|
```
|
|
246
157
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// app/api/puck/pages/[id]/versions/route.ts
|
|
251
|
-
import { createPuckApiRoutesVersions } from '@delmaredigital/payload-puck/api'
|
|
252
|
-
import config from '@payload-config'
|
|
158
|
+
</details>
|
|
253
159
|
|
|
254
|
-
|
|
255
|
-
collection: 'pages',
|
|
256
|
-
payloadConfig: config,
|
|
257
|
-
auth: {
|
|
258
|
-
authenticate: async (request) => {
|
|
259
|
-
// Same auth logic as your main routes
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
})
|
|
263
|
-
```
|
|
160
|
+
> **Note:** The `[[...slug]]` pattern with double brackets makes the slug optional, so this handles both `/` (homepage) and `/any/path`.
|
|
264
161
|
|
|
265
|
-
|
|
162
|
+
### That's It!
|
|
266
163
|
|
|
267
|
-
|
|
164
|
+
- The plugin registers the editor view at `/admin/puck-editor/:collection/:id`
|
|
165
|
+
- "Edit with Puck" buttons appear in the collection list view
|
|
166
|
+
- The editor runs inside Payload's admin UI with full navigation
|
|
167
|
+
- API endpoints are handled automatically via Payload's endpoint system
|
|
268
168
|
|
|
269
169
|
---
|
|
270
170
|
|
|
271
171
|
## Styling Setup
|
|
272
172
|
|
|
273
|
-
|
|
173
|
+
### Tailwind Typography (Required)
|
|
274
174
|
|
|
275
|
-
|
|
276
|
-
<summary><strong>⚠️ Tailwind Typography</strong> — Required for RichText component</summary>
|
|
277
|
-
|
|
278
|
-
The RichText component uses the `prose` class from `@tailwindcss/typography`. **Without this, rich text content will be unstyled** — no proper heading sizes, list styles, blockquote formatting, etc.
|
|
175
|
+
The RichText component uses `@tailwindcss/typography`:
|
|
279
176
|
|
|
280
177
|
```bash
|
|
281
178
|
pnpm add @tailwindcss/typography
|
|
282
179
|
```
|
|
283
180
|
|
|
284
|
-
**Tailwind v4
|
|
285
|
-
|
|
181
|
+
**Tailwind v4:**
|
|
286
182
|
```css
|
|
287
183
|
@import "tailwindcss";
|
|
288
184
|
@plugin "@tailwindcss/typography";
|
|
289
185
|
```
|
|
290
186
|
|
|
291
|
-
**Tailwind v3
|
|
292
|
-
|
|
187
|
+
**Tailwind v3:**
|
|
293
188
|
```javascript
|
|
294
189
|
// tailwind.config.js
|
|
295
190
|
module.exports = {
|
|
296
|
-
plugins: [
|
|
297
|
-
require('@tailwindcss/typography'),
|
|
298
|
-
],
|
|
191
|
+
plugins: [require('@tailwindcss/typography')],
|
|
299
192
|
}
|
|
300
193
|
```
|
|
301
194
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
<details>
|
|
305
|
-
<summary><strong>⚠️ Tailwind Source Scanning</strong> — Required for component styles</summary>
|
|
306
|
-
|
|
307
|
-
**Without this, Tailwind won't include the plugin's CSS classes in your build.** Components will have missing styles.
|
|
308
|
-
|
|
309
|
-
The `@source` directive (v4) or `content` path (v3) tells Tailwind to scan the package for class names.
|
|
310
|
-
|
|
311
|
-
**Tailwind v4**
|
|
195
|
+
### Package Scanning (Required)
|
|
312
196
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
| CSS file location | `@source` path |
|
|
316
|
-
|-------------------|----------------|
|
|
317
|
-
| `globals.css` (root) | `./node_modules/@delmaredigital/payload-puck` |
|
|
318
|
-
| `src/globals.css` | `../node_modules/@delmaredigital/payload-puck` |
|
|
319
|
-
| `src/styles/tailwind.css` | `../../node_modules/@delmaredigital/payload-puck` |
|
|
197
|
+
Tell Tailwind to scan the plugin's components:
|
|
320
198
|
|
|
199
|
+
**Tailwind v4:**
|
|
321
200
|
```css
|
|
322
|
-
|
|
323
|
-
@plugin "@tailwindcss/typography";
|
|
324
|
-
|
|
325
|
-
/* Adjust path based on your CSS file location */
|
|
201
|
+
/* Adjust path relative to your CSS file */
|
|
326
202
|
@source "../node_modules/@delmaredigital/payload-puck";
|
|
327
|
-
|
|
328
|
-
@theme inline {
|
|
329
|
-
--color-background: var(--background);
|
|
330
|
-
--color-foreground: var(--foreground);
|
|
331
|
-
--color-primary: var(--primary);
|
|
332
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
333
|
-
--color-secondary: var(--secondary);
|
|
334
|
-
--color-secondary-foreground: var(--secondary-foreground);
|
|
335
|
-
--color-muted: var(--muted);
|
|
336
|
-
--color-muted-foreground: var(--muted-foreground);
|
|
337
|
-
--color-accent: var(--accent);
|
|
338
|
-
--color-accent-foreground: var(--accent-foreground);
|
|
339
|
-
--color-destructive: var(--destructive);
|
|
340
|
-
--color-destructive-foreground: var(--destructive-foreground);
|
|
341
|
-
--color-border: var(--border);
|
|
342
|
-
--color-input: var(--input);
|
|
343
|
-
--color-ring: var(--ring);
|
|
344
|
-
--color-popover: var(--popover);
|
|
345
|
-
--color-popover-foreground: var(--popover-foreground);
|
|
346
|
-
--color-card: var(--card);
|
|
347
|
-
--color-card-foreground: var(--card-foreground);
|
|
348
|
-
--radius-sm: calc(var(--radius) - 4px);
|
|
349
|
-
--radius-md: calc(var(--radius) - 2px);
|
|
350
|
-
--radius-lg: var(--radius);
|
|
351
|
-
--radius-xl: calc(var(--radius) + 4px);
|
|
352
|
-
}
|
|
353
203
|
```
|
|
354
204
|
|
|
355
|
-
**Tailwind v3
|
|
356
|
-
|
|
205
|
+
**Tailwind v3:**
|
|
357
206
|
```javascript
|
|
358
207
|
// tailwind.config.js
|
|
359
208
|
module.exports = {
|
|
@@ -364,118 +213,57 @@ module.exports = {
|
|
|
364
213
|
}
|
|
365
214
|
```
|
|
366
215
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
<details>
|
|
370
|
-
<summary><strong>⚠️ Theme CSS Variables</strong> — Required if not using shadcn/ui</summary>
|
|
371
|
-
|
|
372
|
-
The field components use [shadcn/ui](https://ui.shadcn.com)-style CSS variables.
|
|
373
|
-
|
|
374
|
-
**If you use shadcn/ui:** No action needed — components inherit your existing theme.
|
|
216
|
+
### Theme CSS Variables
|
|
375
217
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
```bash
|
|
379
|
-
cp node_modules/@delmaredigital/payload-puck/examples/styles/puck-theme.css src/styles/
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
Then import it:
|
|
218
|
+
The plugin uses [shadcn/ui](https://ui.shadcn.com)-style CSS variables. If you don't use shadcn/ui, define these in your CSS:
|
|
383
219
|
|
|
384
220
|
```css
|
|
385
|
-
|
|
221
|
+
:root {
|
|
222
|
+
--background: 0 0% 100%;
|
|
223
|
+
--foreground: 222.2 84% 4.9%;
|
|
224
|
+
--primary: 222.2 47.4% 11.2%;
|
|
225
|
+
--primary-foreground: 210 40% 98%;
|
|
226
|
+
--secondary: 210 40% 96%;
|
|
227
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
228
|
+
--muted: 210 40% 96%;
|
|
229
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
230
|
+
--accent: 210 40% 96%;
|
|
231
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
232
|
+
--destructive: 0 84.2% 60.2%;
|
|
233
|
+
--destructive-foreground: 210 40% 98%;
|
|
234
|
+
--border: 214.3 31.8% 91.4%;
|
|
235
|
+
--input: 214.3 31.8% 91.4%;
|
|
236
|
+
--ring: 222.2 84% 4.9%;
|
|
237
|
+
--radius: 0.5rem;
|
|
238
|
+
}
|
|
386
239
|
```
|
|
387
240
|
|
|
388
|
-
<details>
|
|
389
|
-
<summary>CSS Variable Reference</summary>
|
|
390
|
-
|
|
391
|
-
| Variable | Purpose |
|
|
392
|
-
|----------|---------|
|
|
393
|
-
| `--background` | Page background color |
|
|
394
|
-
| `--foreground` | Default text color |
|
|
395
|
-
| `--primary` | Primary buttons, active states |
|
|
396
|
-
| `--primary-foreground` | Text on primary backgrounds |
|
|
397
|
-
| `--secondary` | Secondary buttons |
|
|
398
|
-
| `--secondary-foreground` | Text on secondary backgrounds |
|
|
399
|
-
| `--muted` | Subtle backgrounds, disabled states |
|
|
400
|
-
| `--muted-foreground` | Muted text |
|
|
401
|
-
| `--accent` | Hover states |
|
|
402
|
-
| `--accent-foreground` | Text on accent backgrounds |
|
|
403
|
-
| `--destructive` | Error messages, delete buttons |
|
|
404
|
-
| `--destructive-foreground` | Text on destructive backgrounds |
|
|
405
|
-
| `--border` | General borders |
|
|
406
|
-
| `--input` | Form input borders |
|
|
407
|
-
| `--ring` | Focus rings |
|
|
408
|
-
| `--popover` | Dropdown/modal backgrounds |
|
|
409
|
-
| `--popover-foreground` | Text in popovers |
|
|
410
|
-
| `--card` | Card backgrounds |
|
|
411
|
-
| `--card-foreground` | Text in cards |
|
|
412
|
-
| `--radius` | Base border radius |
|
|
413
|
-
|
|
414
|
-
</details>
|
|
415
|
-
|
|
416
|
-
</details>
|
|
417
|
-
|
|
418
|
-
---
|
|
419
|
-
|
|
420
|
-
## Setup Checklist
|
|
421
|
-
|
|
422
|
-
Use this checklist to verify your setup is complete.
|
|
423
|
-
|
|
424
|
-
### ✅ Core Setup
|
|
425
|
-
|
|
426
|
-
- [ ] Install packages: `@delmaredigital/payload-puck` and `@measured/puck`
|
|
427
|
-
- [ ] Add `createPuckPlugin()` to your Payload config
|
|
428
|
-
- [ ] Create API routes (`/api/puck/pages` and `/api/puck/pages/[id]`)
|
|
429
|
-
- [ ] Create editor route layout that imports Tailwind CSS (see examples)
|
|
430
|
-
- [ ] Create the editor page component with `PuckEditorView`
|
|
431
|
-
- [ ] Create a frontend route with `PageRenderer`
|
|
432
|
-
|
|
433
|
-
### ⚠️ Styling Setup
|
|
434
|
-
|
|
435
|
-
- [ ] Install and configure `@tailwindcss/typography`
|
|
436
|
-
- [ ] Add Tailwind `@source` directive (v4) or `content` path (v3)
|
|
437
|
-
- [ ] Set up theme CSS variables (if not using shadcn/ui)
|
|
438
|
-
|
|
439
|
-
### ⚙️ Collection Config
|
|
440
|
-
|
|
441
|
-
- [ ] Enable `versions: { drafts: true }` on your pages collection
|
|
442
|
-
|
|
443
|
-
### 📦 Optional
|
|
444
|
-
|
|
445
|
-
- [ ] Version history API route (`/api/puck/pages/[id]/versions`)
|
|
446
|
-
- [ ] Custom theme configuration via `ThemeProvider`
|
|
447
|
-
- [ ] Custom layouts with headers/footers
|
|
448
|
-
- [ ] Custom components
|
|
449
|
-
|
|
450
241
|
---
|
|
451
242
|
|
|
452
|
-
|
|
453
|
-
<summary><strong>Core Concepts</strong> — Server vs Client configs, Draft system</summary>
|
|
243
|
+
## Core Concepts
|
|
454
244
|
|
|
455
245
|
### Server vs Client Configuration
|
|
456
246
|
|
|
457
|
-
The plugin provides two configurations
|
|
247
|
+
The plugin provides two configurations for React Server Components:
|
|
458
248
|
|
|
459
249
|
| Config | Import | Use Case |
|
|
460
250
|
|--------|--------|----------|
|
|
461
251
|
| `baseConfig` | `@delmaredigital/payload-puck/config` | Server-safe rendering with `PageRenderer` |
|
|
462
|
-
| `editorConfig` | `@delmaredigital/payload-puck/config/editor` | Client-side editing with full
|
|
252
|
+
| `editorConfig` | `@delmaredigital/payload-puck/config/editor` | Client-side editing with full interactivity |
|
|
463
253
|
|
|
464
254
|
```typescript
|
|
465
255
|
// Server component - use baseConfig
|
|
466
256
|
import { baseConfig } from '@delmaredigital/payload-puck/config'
|
|
467
257
|
<PageRenderer config={baseConfig} data={page.puckData} />
|
|
468
258
|
|
|
469
|
-
//
|
|
259
|
+
// PuckConfigProvider - use editorConfig
|
|
470
260
|
import { editorConfig } from '@delmaredigital/payload-puck/config/editor'
|
|
471
|
-
<
|
|
261
|
+
<PuckConfigProvider config={editorConfig}>
|
|
472
262
|
```
|
|
473
263
|
|
|
474
264
|
### Draft System
|
|
475
265
|
|
|
476
|
-
The editor uses Payload's native draft system.
|
|
477
|
-
|
|
478
|
-
> **⚠️ Required:** Without `drafts: true`, the Save Draft and Publish buttons won't work correctly.
|
|
266
|
+
The editor uses Payload's native draft system. The plugin automatically enables drafts on the pages collection. You can also enable it manually:
|
|
479
267
|
|
|
480
268
|
```typescript
|
|
481
269
|
{
|
|
@@ -486,293 +274,49 @@ The editor uses Payload's native draft system.
|
|
|
486
274
|
}
|
|
487
275
|
```
|
|
488
276
|
|
|
489
|
-
</details>
|
|
490
|
-
|
|
491
277
|
---
|
|
492
278
|
|
|
493
|
-
|
|
494
|
-
<summary><strong>Components</strong> — Layout, Typography, Media, Interactive</summary>
|
|
279
|
+
## Components
|
|
495
280
|
|
|
496
281
|
### Layout
|
|
497
282
|
|
|
498
|
-
| Component | Description |
|
|
499
|
-
|
|
500
|
-
| **Container** | Content wrapper with max-width and background
|
|
501
|
-
| **Flex** | Flexible box layout with direction and alignment |
|
|
502
|
-
| **Grid** | CSS Grid layout with responsive columns |
|
|
503
|
-
| **Section** |
|
|
504
|
-
| **Spacer** | Vertical/horizontal spacing element |
|
|
505
|
-
| **Template** |
|
|
283
|
+
| Component | Description |
|
|
284
|
+
|-----------|-------------|
|
|
285
|
+
| **Container** | Content wrapper with max-width and background |
|
|
286
|
+
| **Flex** | Flexible box layout with direction and alignment |
|
|
287
|
+
| **Grid** | CSS Grid layout with responsive columns |
|
|
288
|
+
| **Section** | Two-layer: full-bleed section + constrained content area |
|
|
289
|
+
| **Spacer** | Vertical/horizontal spacing element |
|
|
290
|
+
| **Template** | Save/load reusable component arrangements |
|
|
506
291
|
|
|
507
292
|
### Typography
|
|
508
293
|
|
|
509
|
-
| Component | Description |
|
|
510
|
-
|
|
511
|
-
| **Heading** | H1-H6 headings with size and alignment
|
|
512
|
-
| **Text** | Paragraph text with styling options |
|
|
513
|
-
| **RichText** | TipTap-powered WYSIWYG editor |
|
|
514
|
-
|
|
515
|
-
> **⚠️ RichText requires `@tailwindcss/typography`** — see [Styling Setup](#styling-setup). Without it, content renders without proper formatting.
|
|
516
|
-
|
|
517
|
-
### Media
|
|
518
|
-
|
|
519
|
-
| Component | Description | Responsive Controls |
|
|
520
|
-
|-----------|-------------|---------------------|
|
|
521
|
-
| **Image** | Responsive image with alt text and sizing | Visibility |
|
|
294
|
+
| Component | Description |
|
|
295
|
+
|-----------|-------------|
|
|
296
|
+
| **Heading** | H1-H6 headings with size and alignment |
|
|
297
|
+
| **Text** | Paragraph text with styling options |
|
|
298
|
+
| **RichText** | TipTap-powered WYSIWYG editor |
|
|
522
299
|
|
|
523
|
-
### Interactive
|
|
300
|
+
### Media & Interactive
|
|
524
301
|
|
|
525
|
-
| Component | Description |
|
|
526
|
-
|
|
527
|
-
| **
|
|
528
|
-
| **
|
|
529
|
-
| **
|
|
530
|
-
| **
|
|
302
|
+
| Component | Description |
|
|
303
|
+
|-----------|-------------|
|
|
304
|
+
| **Image** | Responsive image with alt text |
|
|
305
|
+
| **Button** | Styled button/link with variants |
|
|
306
|
+
| **Card** | Content card with optional image |
|
|
307
|
+
| **Divider** | Horizontal rule with styles |
|
|
308
|
+
| **Accordion** | Expandable content sections |
|
|
531
309
|
|
|
532
310
|
### Responsive Controls
|
|
533
311
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
- **
|
|
537
|
-
- **
|
|
538
|
-
- **Margin** - Outer spacing per breakpoint
|
|
539
|
-
- **Visibility** - Show/hide components at specific breakpoints
|
|
540
|
-
|
|
541
|
-
Breakpoints follow Tailwind CSS conventions:
|
|
542
|
-
| Breakpoint | Min Width | Description |
|
|
543
|
-
|------------|-----------|-------------|
|
|
544
|
-
| base | 0px | Mobile (default) |
|
|
545
|
-
| sm | 640px | Small tablets |
|
|
546
|
-
| md | 768px | Tablets |
|
|
547
|
-
| lg | 1024px | Laptops |
|
|
548
|
-
| xl | 1280px | Desktops |
|
|
549
|
-
|
|
550
|
-
### Template Component
|
|
551
|
-
|
|
552
|
-
The Template component allows saving groups of components as reusable templates. The plugin automatically creates a `puck-templates` collection in Payload.
|
|
553
|
-
|
|
554
|
-
**Saving a template:**
|
|
555
|
-
1. Add a Template component to your page
|
|
556
|
-
2. Add child components inside the Template slot
|
|
557
|
-
3. Click "Save as Template" and give it a name/category
|
|
558
|
-
|
|
559
|
-
**Loading a template:**
|
|
560
|
-
1. Add a Template component to your page
|
|
561
|
-
2. Select a saved template from the dropdown
|
|
562
|
-
3. The template's components are loaded into the slot
|
|
563
|
-
|
|
564
|
-
</details>
|
|
312
|
+
Layout components support per-breakpoint customization:
|
|
313
|
+
- **Dimensions** - Width, max-width, height constraints
|
|
314
|
+
- **Padding/Margin** - Spacing per breakpoint
|
|
315
|
+
- **Visibility** - Show/hide at specific breakpoints
|
|
565
316
|
|
|
566
317
|
---
|
|
567
318
|
|
|
568
|
-
|
|
569
|
-
<summary><strong>Configuration</strong> — Merging configs, Custom components</summary>
|
|
570
|
-
|
|
571
|
-
### Merging Custom Components
|
|
572
|
-
|
|
573
|
-
```typescript
|
|
574
|
-
import { mergeConfigs } from '@delmaredigital/payload-puck/config'
|
|
575
|
-
import { baseConfig } from '@delmaredigital/payload-puck/config'
|
|
576
|
-
import { MyCustomComponent } from './components/MyCustomComponent'
|
|
577
|
-
|
|
578
|
-
const customConfig = mergeConfigs({
|
|
579
|
-
base: baseConfig,
|
|
580
|
-
components: {
|
|
581
|
-
MyCustomComponent,
|
|
582
|
-
},
|
|
583
|
-
categories: {
|
|
584
|
-
custom: { title: 'Custom', components: ['MyCustomComponent'] },
|
|
585
|
-
},
|
|
586
|
-
exclude: ['Spacer'], // Optionally remove components
|
|
587
|
-
})
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
### Creating Custom Components
|
|
591
|
-
|
|
592
|
-
Components need two variants to work across server rendering and the editor:
|
|
593
|
-
|
|
594
|
-
| File | Purpose | Used By |
|
|
595
|
-
|------|---------|---------|
|
|
596
|
-
| `MyComponent.server.tsx` | Server-safe render (no hooks/interactivity) | `baseConfig` → `PageRenderer` |
|
|
597
|
-
| `MyComponent.tsx` or `.editor.tsx` | Full interactivity + field definitions | `editorConfig` → `PuckEditor` |
|
|
598
|
-
|
|
599
|
-
**Server variant** (`MyComponent.server.tsx`):
|
|
600
|
-
- No `'use client'` directive
|
|
601
|
-
- No React hooks (`useState`, `useEffect`, etc.)
|
|
602
|
-
- No event handlers that require client JS
|
|
603
|
-
- **If component has slots**: Must include `fields: { content: { type: 'slot' } }` (Puck needs this to transform slot data into a renderable component)
|
|
604
|
-
- Other fields can be omitted (not used in rendering)
|
|
605
|
-
|
|
606
|
-
**Editor variant** (`MyComponent.tsx`):
|
|
607
|
-
- Can use `'use client'` if needed
|
|
608
|
-
- Full interactivity with hooks
|
|
609
|
-
- Includes all `fields` for the Puck sidebar
|
|
610
|
-
|
|
611
|
-
<details>
|
|
612
|
-
<summary><strong>Example: Interactive Component</strong></summary>
|
|
613
|
-
|
|
614
|
-
```tsx
|
|
615
|
-
// components/Tabs.server.tsx - Server-safe version
|
|
616
|
-
import type { ComponentConfig } from '@measured/puck'
|
|
617
|
-
|
|
618
|
-
export interface TabsProps {
|
|
619
|
-
items: { title: string; content: string }[]
|
|
620
|
-
defaultTab: number
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
export const TabsConfig: ComponentConfig<TabsProps> = {
|
|
624
|
-
label: 'Tabs',
|
|
625
|
-
defaultProps: {
|
|
626
|
-
items: [{ title: 'Tab 1', content: 'Content 1' }],
|
|
627
|
-
defaultTab: 0,
|
|
628
|
-
},
|
|
629
|
-
// No fields - server version only renders
|
|
630
|
-
render: ({ items, defaultTab }) => (
|
|
631
|
-
<div>
|
|
632
|
-
{/* Render only the default tab statically */}
|
|
633
|
-
<div className="flex border-b">
|
|
634
|
-
{items.map((item, i) => (
|
|
635
|
-
<div key={i} className={i === defaultTab ? 'border-b-2 border-primary' : ''}>
|
|
636
|
-
{item.title}
|
|
637
|
-
</div>
|
|
638
|
-
))}
|
|
639
|
-
</div>
|
|
640
|
-
<div>{items[defaultTab]?.content}</div>
|
|
641
|
-
</div>
|
|
642
|
-
),
|
|
643
|
-
}
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
```tsx
|
|
647
|
-
// components/Tabs.tsx - Editor version with interactivity
|
|
648
|
-
'use client'
|
|
649
|
-
|
|
650
|
-
import type { ComponentConfig } from '@measured/puck'
|
|
651
|
-
import { useState } from 'react'
|
|
652
|
-
|
|
653
|
-
export interface TabsProps {
|
|
654
|
-
items: { title: string; content: string }[]
|
|
655
|
-
defaultTab: number
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
export const TabsConfig: ComponentConfig<TabsProps> = {
|
|
659
|
-
label: 'Tabs',
|
|
660
|
-
fields: {
|
|
661
|
-
items: {
|
|
662
|
-
type: 'array',
|
|
663
|
-
label: 'Tabs',
|
|
664
|
-
arrayFields: {
|
|
665
|
-
title: { type: 'text', label: 'Title' },
|
|
666
|
-
content: { type: 'textarea', label: 'Content' },
|
|
667
|
-
},
|
|
668
|
-
},
|
|
669
|
-
defaultTab: { type: 'number', label: 'Default Tab' },
|
|
670
|
-
},
|
|
671
|
-
defaultProps: {
|
|
672
|
-
items: [{ title: 'Tab 1', content: 'Content 1' }],
|
|
673
|
-
defaultTab: 0,
|
|
674
|
-
},
|
|
675
|
-
render: ({ items, defaultTab }) => {
|
|
676
|
-
const [activeTab, setActiveTab] = useState(defaultTab)
|
|
677
|
-
|
|
678
|
-
return (
|
|
679
|
-
<div>
|
|
680
|
-
<div className="flex border-b">
|
|
681
|
-
{items.map((item, i) => (
|
|
682
|
-
<button
|
|
683
|
-
key={i}
|
|
684
|
-
onClick={() => setActiveTab(i)}
|
|
685
|
-
className={i === activeTab ? 'border-b-2 border-primary' : ''}
|
|
686
|
-
>
|
|
687
|
-
{item.title}
|
|
688
|
-
</button>
|
|
689
|
-
))}
|
|
690
|
-
</div>
|
|
691
|
-
<div>{items[activeTab]?.content}</div>
|
|
692
|
-
</div>
|
|
693
|
-
)
|
|
694
|
-
},
|
|
695
|
-
}
|
|
696
|
-
```
|
|
697
|
-
|
|
698
|
-
Then register both:
|
|
699
|
-
```tsx
|
|
700
|
-
// In your custom baseConfig
|
|
701
|
-
import { TabsConfig } from './components/Tabs.server'
|
|
702
|
-
|
|
703
|
-
// In your custom editorConfig
|
|
704
|
-
import { TabsConfig } from './components/Tabs'
|
|
705
|
-
```
|
|
706
|
-
</details>
|
|
707
|
-
|
|
708
|
-
<details>
|
|
709
|
-
<summary><strong>Example: Component with Slot (nested components)</strong></summary>
|
|
710
|
-
|
|
711
|
-
```tsx
|
|
712
|
-
// components/Card.server.tsx - Server-safe version WITH slot field
|
|
713
|
-
import type { ComponentConfig } from '@measured/puck'
|
|
714
|
-
|
|
715
|
-
export interface CardProps {
|
|
716
|
-
content: unknown // Slot for nested components
|
|
717
|
-
title: string
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
export const CardConfig: ComponentConfig<CardProps> = {
|
|
721
|
-
label: 'Card',
|
|
722
|
-
// CRITICAL: Slot field MUST be defined for Puck to transform data into component
|
|
723
|
-
fields: {
|
|
724
|
-
content: { type: 'slot' },
|
|
725
|
-
},
|
|
726
|
-
defaultProps: {
|
|
727
|
-
content: [],
|
|
728
|
-
title: 'Card Title',
|
|
729
|
-
},
|
|
730
|
-
render: ({ content: Content, title }) => (
|
|
731
|
-
<div className="border rounded-lg p-4">
|
|
732
|
-
<h3 className="font-bold mb-2">{title}</h3>
|
|
733
|
-
<Content /> {/* Renders nested components */}
|
|
734
|
-
</div>
|
|
735
|
-
),
|
|
736
|
-
}
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
```tsx
|
|
740
|
-
// components/Card.tsx - Editor version with all fields
|
|
741
|
-
import type { ComponentConfig } from '@measured/puck'
|
|
742
|
-
|
|
743
|
-
export interface CardProps {
|
|
744
|
-
content: unknown
|
|
745
|
-
title: string
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
export const CardConfig: ComponentConfig<CardProps> = {
|
|
749
|
-
label: 'Card',
|
|
750
|
-
fields: {
|
|
751
|
-
title: { type: 'text', label: 'Title' },
|
|
752
|
-
content: { type: 'slot' },
|
|
753
|
-
},
|
|
754
|
-
defaultProps: {
|
|
755
|
-
content: [],
|
|
756
|
-
title: 'Card Title',
|
|
757
|
-
},
|
|
758
|
-
render: ({ content: Content, title }) => (
|
|
759
|
-
<div className="border rounded-lg p-4">
|
|
760
|
-
<h3 className="font-bold mb-2">{title}</h3>
|
|
761
|
-
<Content />
|
|
762
|
-
</div>
|
|
763
|
-
),
|
|
764
|
-
}
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
**Why slots need the field definition:** Puck stores slot content as an array of component data. The `fields: { content: { type: 'slot' } }` tells Puck to transform this array into a renderable `<Content />` component before passing it to `render()`. Without this, you'll get "Element type is invalid: got array" errors.
|
|
768
|
-
</details>
|
|
769
|
-
|
|
770
|
-
</details>
|
|
771
|
-
|
|
772
|
-
---
|
|
773
|
-
|
|
774
|
-
<details>
|
|
775
|
-
<summary><strong>Custom Fields</strong> — 19 field types with usage examples</summary>
|
|
319
|
+
## Custom Fields
|
|
776
320
|
|
|
777
321
|
All fields are imported from `@delmaredigital/payload-puck/fields`.
|
|
778
322
|
|
|
@@ -780,334 +324,54 @@ All fields are imported from `@delmaredigital/payload-puck/fields`.
|
|
|
780
324
|
|
|
781
325
|
| Field | Description |
|
|
782
326
|
|-------|-------------|
|
|
783
|
-
| **MediaField** | Payload media library integration
|
|
784
|
-
| **TiptapField** | Rich text editor with formatting
|
|
785
|
-
| **ColorPickerField** | Color picker with
|
|
786
|
-
| **BackgroundField** |
|
|
787
|
-
| **PaddingField** | Visual
|
|
788
|
-
| **
|
|
789
|
-
| **
|
|
790
|
-
| **
|
|
791
|
-
| **
|
|
792
|
-
| **
|
|
793
|
-
| **
|
|
794
|
-
| **
|
|
795
|
-
| **
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
<details>
|
|
807
|
-
<summary><strong>MediaField</strong></summary>
|
|
808
|
-
|
|
809
|
-
Integrates with Payload's media collection:
|
|
810
|
-
|
|
811
|
-
```typescript
|
|
812
|
-
import { createMediaField } from '@delmaredigital/payload-puck/fields'
|
|
813
|
-
|
|
814
|
-
const config = {
|
|
815
|
-
components: {
|
|
816
|
-
Hero: {
|
|
817
|
-
fields: {
|
|
818
|
-
backgroundImage: createMediaField({
|
|
819
|
-
label: 'Background Image',
|
|
820
|
-
collection: 'media', // Default: 'media'
|
|
821
|
-
}),
|
|
822
|
-
},
|
|
823
|
-
},
|
|
824
|
-
},
|
|
825
|
-
}
|
|
826
|
-
```
|
|
827
|
-
</details>
|
|
828
|
-
|
|
829
|
-
<details>
|
|
830
|
-
<summary><strong>TiptapField</strong></summary>
|
|
831
|
-
|
|
832
|
-
Rich text editor with formatting toolbar:
|
|
833
|
-
|
|
834
|
-
```typescript
|
|
835
|
-
import { createTiptapField } from '@delmaredigital/payload-puck/fields'
|
|
836
|
-
|
|
837
|
-
const config = {
|
|
838
|
-
components: {
|
|
839
|
-
TextBlock: {
|
|
840
|
-
fields: {
|
|
841
|
-
content: createTiptapField({ label: 'Content' }),
|
|
842
|
-
},
|
|
843
|
-
},
|
|
844
|
-
},
|
|
845
|
-
}
|
|
846
|
-
```
|
|
847
|
-
</details>
|
|
848
|
-
|
|
849
|
-
<details>
|
|
850
|
-
<summary><strong>ColorPickerField</strong></summary>
|
|
851
|
-
|
|
852
|
-
Color picker with presets and alpha channel:
|
|
853
|
-
|
|
854
|
-
```typescript
|
|
855
|
-
import { createColorPickerField } from '@delmaredigital/payload-puck/fields'
|
|
856
|
-
|
|
857
|
-
const config = {
|
|
858
|
-
components: {
|
|
859
|
-
Section: {
|
|
860
|
-
fields: {
|
|
861
|
-
backgroundColor: createColorPickerField({
|
|
862
|
-
label: 'Background Color',
|
|
863
|
-
}),
|
|
864
|
-
},
|
|
865
|
-
},
|
|
866
|
-
},
|
|
867
|
-
}
|
|
868
|
-
```
|
|
869
|
-
</details>
|
|
870
|
-
|
|
871
|
-
<details>
|
|
872
|
-
<summary><strong>BackgroundField</strong></summary>
|
|
873
|
-
|
|
874
|
-
Full background editor with solid colors, gradients, and images:
|
|
875
|
-
|
|
876
|
-
```typescript
|
|
877
|
-
import { createBackgroundField, backgroundValueToCSS } from '@delmaredigital/payload-puck/fields'
|
|
878
|
-
|
|
879
|
-
const config = {
|
|
880
|
-
components: {
|
|
881
|
-
Section: {
|
|
882
|
-
fields: {
|
|
883
|
-
background: createBackgroundField({ label: 'Background' }),
|
|
884
|
-
},
|
|
885
|
-
render: ({ background }) => (
|
|
886
|
-
<section style={{ background: backgroundValueToCSS(background) }}>
|
|
887
|
-
{/* content */}
|
|
888
|
-
</section>
|
|
889
|
-
),
|
|
890
|
-
},
|
|
891
|
-
},
|
|
892
|
-
}
|
|
893
|
-
```
|
|
894
|
-
</details>
|
|
895
|
-
|
|
896
|
-
<details>
|
|
897
|
-
<summary><strong>DimensionsField</strong></summary>
|
|
898
|
-
|
|
899
|
-
Width/height with min/max constraints and alignment:
|
|
900
|
-
|
|
901
|
-
```typescript
|
|
902
|
-
import { createDimensionsField, dimensionsValueToCSS } from '@delmaredigital/payload-puck/fields'
|
|
903
|
-
|
|
904
|
-
const config = {
|
|
905
|
-
components: {
|
|
906
|
-
Container: {
|
|
907
|
-
fields: {
|
|
908
|
-
dimensions: createDimensionsField({ label: 'Size' }),
|
|
909
|
-
},
|
|
910
|
-
render: ({ dimensions, children }) => (
|
|
911
|
-
<div style={dimensionsValueToCSS(dimensions)}>
|
|
912
|
-
{children}
|
|
913
|
-
</div>
|
|
914
|
-
),
|
|
915
|
-
},
|
|
916
|
-
},
|
|
917
|
-
}
|
|
918
|
-
```
|
|
919
|
-
</details>
|
|
920
|
-
|
|
921
|
-
<details>
|
|
922
|
-
<summary><strong>PaddingField & MarginField</strong></summary>
|
|
923
|
-
|
|
924
|
-
Visual spacing editors:
|
|
925
|
-
|
|
926
|
-
```typescript
|
|
927
|
-
import { createPaddingField, createMarginField } from '@delmaredigital/payload-puck/fields'
|
|
928
|
-
|
|
929
|
-
const config = {
|
|
930
|
-
components: {
|
|
931
|
-
Box: {
|
|
932
|
-
fields: {
|
|
933
|
-
padding: createPaddingField({ label: 'Padding' }),
|
|
934
|
-
margin: createMarginField({ label: 'Margin' }),
|
|
935
|
-
},
|
|
936
|
-
},
|
|
937
|
-
},
|
|
938
|
-
}
|
|
939
|
-
```
|
|
940
|
-
</details>
|
|
941
|
-
|
|
942
|
-
<details>
|
|
943
|
-
<summary><strong>LockedTextField & LockedRadioField</strong></summary>
|
|
944
|
-
|
|
945
|
-
Protected fields that require confirmation before editing:
|
|
946
|
-
|
|
947
|
-
```typescript
|
|
948
|
-
import {
|
|
949
|
-
createLockedTextField,
|
|
950
|
-
createLockedRadioField,
|
|
951
|
-
lockedSlugField, // Pre-built slug field
|
|
952
|
-
lockedHomepageField, // Pre-built homepage toggle
|
|
953
|
-
} from '@delmaredigital/payload-puck/fields'
|
|
954
|
-
|
|
955
|
-
// Use pre-built fields
|
|
956
|
-
const config = {
|
|
957
|
-
root: {
|
|
958
|
-
fields: {
|
|
959
|
-
slug: lockedSlugField,
|
|
960
|
-
isHomepage: lockedHomepageField,
|
|
961
|
-
},
|
|
962
|
-
},
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
// Or create custom locked fields
|
|
966
|
-
const customLockedField = createLockedTextField({
|
|
967
|
-
label: 'API Key',
|
|
968
|
-
placeholder: 'Enter API key',
|
|
969
|
-
warningMessage: 'Changing this will break integrations.',
|
|
970
|
-
})
|
|
971
|
-
```
|
|
972
|
-
</details>
|
|
973
|
-
|
|
974
|
-
<details>
|
|
975
|
-
<summary><strong>AnimationField</strong></summary>
|
|
976
|
-
|
|
977
|
-
Entrance animations with customizable timing:
|
|
978
|
-
|
|
979
|
-
```typescript
|
|
980
|
-
import { createAnimationField, getEntranceAnimationClasses } from '@delmaredigital/payload-puck/fields'
|
|
981
|
-
|
|
982
|
-
const config = {
|
|
983
|
-
components: {
|
|
984
|
-
AnimatedSection: {
|
|
985
|
-
fields: {
|
|
986
|
-
animation: createAnimationField({ label: 'Entrance Animation' }),
|
|
987
|
-
},
|
|
988
|
-
render: ({ animation, children }) => (
|
|
989
|
-
<div className={getEntranceAnimationClasses(animation)}>
|
|
990
|
-
{children}
|
|
991
|
-
</div>
|
|
992
|
-
),
|
|
993
|
-
},
|
|
994
|
-
},
|
|
995
|
-
}
|
|
996
|
-
```
|
|
997
|
-
</details>
|
|
998
|
-
|
|
999
|
-
<details>
|
|
1000
|
-
<summary><strong>ResponsiveField</strong></summary>
|
|
1001
|
-
|
|
1002
|
-
Values that change per breakpoint:
|
|
1003
|
-
|
|
1004
|
-
```typescript
|
|
1005
|
-
import { createResponsiveField, BREAKPOINTS } from '@delmaredigital/payload-puck/fields'
|
|
1006
|
-
|
|
1007
|
-
const config = {
|
|
1008
|
-
components: {
|
|
1009
|
-
Grid: {
|
|
1010
|
-
fields: {
|
|
1011
|
-
columns: createResponsiveField({
|
|
1012
|
-
label: 'Columns',
|
|
1013
|
-
field: { type: 'number' },
|
|
1014
|
-
defaultValue: { sm: 1, md: 2, lg: 3 },
|
|
1015
|
-
}),
|
|
1016
|
-
},
|
|
1017
|
-
},
|
|
1018
|
-
},
|
|
1019
|
-
}
|
|
1020
|
-
```
|
|
1021
|
-
</details>
|
|
1022
|
-
|
|
1023
|
-
<details>
|
|
1024
|
-
<summary><strong>ResponsiveVisibilityField</strong></summary>
|
|
1025
|
-
|
|
1026
|
-
Show/hide components at different breakpoints (like Divi/Elementor):
|
|
1027
|
-
|
|
1028
|
-
```typescript
|
|
1029
|
-
import { createResponsiveVisibilityField, visibilityValueToCSS } from '@delmaredigital/payload-puck/fields'
|
|
1030
|
-
|
|
1031
|
-
const config = {
|
|
1032
|
-
components: {
|
|
1033
|
-
MobileOnlyBanner: {
|
|
1034
|
-
fields: {
|
|
1035
|
-
visibility: createResponsiveVisibilityField({ label: 'Visibility' }),
|
|
1036
|
-
},
|
|
1037
|
-
render: ({ visibility, children }) => {
|
|
1038
|
-
const visibilityCSS = visibilityValueToCSS(visibility, 'mobile-banner')
|
|
1039
|
-
return (
|
|
1040
|
-
<>
|
|
1041
|
-
{visibilityCSS && <style>{visibilityCSS}</style>}
|
|
1042
|
-
<div className="mobile-banner">{children}</div>
|
|
1043
|
-
</>
|
|
1044
|
-
)
|
|
1045
|
-
},
|
|
1046
|
-
},
|
|
327
|
+
| **MediaField** | Payload media library integration |
|
|
328
|
+
| **TiptapField** | Rich text editor with formatting |
|
|
329
|
+
| **ColorPickerField** | Color picker with opacity and presets |
|
|
330
|
+
| **BackgroundField** | Solid colors, gradients, images |
|
|
331
|
+
| **PaddingField / MarginField** | Visual spacing editors |
|
|
332
|
+
| **BorderField** | Border width, style, color, radius |
|
|
333
|
+
| **DimensionsField** | Width/height with constraints |
|
|
334
|
+
| **AlignmentField** | Text alignment options |
|
|
335
|
+
| **AnimationField** | Entrance animations |
|
|
336
|
+
| **ResponsiveVisibilityField** | Show/hide per breakpoint |
|
|
337
|
+
| **FolderPickerField** | Hierarchical folder selection (page-tree) |
|
|
338
|
+
| **PageSegmentField** | URL segment with slugification (page-tree) |
|
|
339
|
+
| **SlugPreviewField** | Read-only computed slug (page-tree) |
|
|
340
|
+
|
|
341
|
+
### Usage Example
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import { createMediaField, createBackgroundField, backgroundValueToCSS } from '@delmaredigital/payload-puck/fields'
|
|
345
|
+
|
|
346
|
+
const HeroConfig = {
|
|
347
|
+
fields: {
|
|
348
|
+
image: createMediaField({ label: 'Background Image' }),
|
|
349
|
+
background: createBackgroundField({ label: 'Overlay' }),
|
|
1047
350
|
},
|
|
351
|
+
render: ({ image, background }) => (
|
|
352
|
+
<section style={{ background: backgroundValueToCSS(background) }}>
|
|
353
|
+
{/* content */}
|
|
354
|
+
</section>
|
|
355
|
+
),
|
|
1048
356
|
}
|
|
1049
357
|
```
|
|
1050
358
|
|
|
1051
|
-
The field displays device icons with visibility toggles. Green = visible, Red = hidden at that breakpoint.
|
|
1052
|
-
</details>
|
|
1053
|
-
|
|
1054
359
|
### CSS Helper Functions
|
|
1055
360
|
|
|
1056
|
-
Convert field values to CSS:
|
|
1057
|
-
|
|
1058
361
|
```typescript
|
|
1059
362
|
import {
|
|
1060
363
|
backgroundValueToCSS,
|
|
1061
364
|
dimensionsValueToCSS,
|
|
1062
365
|
animationValueToCSS,
|
|
1063
|
-
transformValueToCSS,
|
|
1064
|
-
gradientValueToCSS,
|
|
1065
|
-
sizeValueToCSS,
|
|
1066
|
-
// Responsive helpers
|
|
1067
|
-
responsiveValueToCSS,
|
|
1068
366
|
visibilityValueToCSS,
|
|
1069
367
|
} from '@delmaredigital/payload-puck/fields'
|
|
1070
|
-
|
|
1071
|
-
const styles = {
|
|
1072
|
-
background: backgroundValueToCSS(background),
|
|
1073
|
-
...dimensionsValueToCSS(dimensions),
|
|
1074
|
-
animation: animationValueToCSS(animation),
|
|
1075
|
-
transform: transformValueToCSS(transform),
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
// Responsive values generate CSS media queries
|
|
1079
|
-
const uniqueId = 'my-component-123'
|
|
1080
|
-
const { baseStyles, mediaQueryCSS } = responsiveValueToCSS(
|
|
1081
|
-
dimensions, // ResponsiveValue<T> or T
|
|
1082
|
-
dimensionsValueToCSS, // Converter function
|
|
1083
|
-
uniqueId // CSS class selector
|
|
1084
|
-
)
|
|
1085
|
-
|
|
1086
|
-
// Visibility generates show/hide media queries
|
|
1087
|
-
const visibilityCSS = visibilityValueToCSS(visibility, uniqueId)
|
|
1088
|
-
|
|
1089
|
-
// Render with media queries
|
|
1090
|
-
return (
|
|
1091
|
-
<>
|
|
1092
|
-
{mediaQueryCSS && <style>{mediaQueryCSS}</style>}
|
|
1093
|
-
{visibilityCSS && <style>{visibilityCSS}</style>}
|
|
1094
|
-
<div className={uniqueId} style={baseStyles}>{children}</div>
|
|
1095
|
-
</>
|
|
1096
|
-
)
|
|
1097
368
|
```
|
|
1098
369
|
|
|
1099
|
-
</details>
|
|
1100
|
-
|
|
1101
370
|
---
|
|
1102
371
|
|
|
1103
|
-
|
|
1104
|
-
<summary><strong>Theming</strong> — Button variants, color presets, focus rings</summary>
|
|
1105
|
-
|
|
1106
|
-
Customize button styles, color presets, and focus rings to match your design system.
|
|
372
|
+
## Theming
|
|
1107
373
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
Wrap your `PageRenderer` with `ThemeProvider` to apply custom theming:
|
|
374
|
+
Customize button styles, color presets, and focus rings:
|
|
1111
375
|
|
|
1112
376
|
```typescript
|
|
1113
377
|
import { PageRenderer } from '@delmaredigital/payload-puck/render'
|
|
@@ -1115,94 +379,24 @@ import { ThemeProvider } from '@delmaredigital/payload-puck/theme'
|
|
|
1115
379
|
|
|
1116
380
|
<ThemeProvider theme={{
|
|
1117
381
|
buttonVariants: {
|
|
1118
|
-
default: { classes: 'bg-primary text-
|
|
1119
|
-
secondary: { classes: 'bg-secondary text-
|
|
382
|
+
default: { classes: 'bg-primary text-white hover:bg-primary/90' },
|
|
383
|
+
secondary: { classes: 'bg-secondary text-foreground hover:bg-secondary/90' },
|
|
1120
384
|
},
|
|
1121
385
|
focusRingColor: 'focus:ring-primary',
|
|
1122
|
-
}}>
|
|
1123
|
-
<PageRenderer config={baseConfig} data={page.puckData} />
|
|
1124
|
-
</ThemeProvider>
|
|
1125
|
-
```
|
|
1126
|
-
|
|
1127
|
-
### Using the Example Theme
|
|
1128
|
-
|
|
1129
|
-
```typescript
|
|
1130
|
-
import { ThemeProvider, exampleTheme } from '@delmaredigital/payload-puck/theme'
|
|
1131
|
-
|
|
1132
|
-
<ThemeProvider theme={exampleTheme}>
|
|
1133
|
-
<PageRenderer data={page.puckData} />
|
|
1134
|
-
</ThemeProvider>
|
|
1135
|
-
|
|
1136
|
-
// Or customize specific values
|
|
1137
|
-
<ThemeProvider theme={{
|
|
1138
|
-
...exampleTheme,
|
|
1139
|
-
focusRingColor: 'focus:ring-brand',
|
|
1140
|
-
}}>
|
|
1141
|
-
<PageRenderer data={page.puckData} />
|
|
1142
|
-
</ThemeProvider>
|
|
1143
|
-
```
|
|
1144
|
-
|
|
1145
|
-
### Theme Options
|
|
1146
|
-
|
|
1147
|
-
| Option | Description |
|
|
1148
|
-
|--------|-------------|
|
|
1149
|
-
| `buttonVariants` | Button component variant styles (default, secondary, outline, ghost) |
|
|
1150
|
-
| `ctaButtonVariants` | CallToAction button styles (primary, secondary, outline) |
|
|
1151
|
-
| `ctaBackgroundStyles` | CallToAction background styles (default, dark, light) |
|
|
1152
|
-
| `colorPresets` | Color picker preset swatches |
|
|
1153
|
-
| `extendColorPresets` | If true, adds to defaults instead of replacing |
|
|
1154
|
-
| `focusRingColor` | Focus ring class (e.g., `focus:ring-primary`) |
|
|
1155
|
-
|
|
1156
|
-
### Custom Color Presets
|
|
1157
|
-
|
|
1158
|
-
```typescript
|
|
1159
|
-
<ThemeProvider theme={{
|
|
1160
386
|
colorPresets: [
|
|
1161
387
|
{ hex: '#3b82f6', label: 'Brand Blue' },
|
|
1162
388
|
{ hex: '#10b981', label: 'Success' },
|
|
1163
|
-
{ hex: '#ef4444', label: 'Danger' },
|
|
1164
389
|
],
|
|
1165
|
-
extendColorPresets: false, // Replace defaults
|
|
1166
390
|
}}>
|
|
1167
|
-
<PageRenderer data={page.puckData} />
|
|
391
|
+
<PageRenderer config={baseConfig} data={page.puckData} />
|
|
1168
392
|
</ThemeProvider>
|
|
1169
393
|
```
|
|
1170
394
|
|
|
1171
|
-
### Direct Theme Imports
|
|
1172
|
-
|
|
1173
|
-
```typescript
|
|
1174
|
-
import {
|
|
1175
|
-
ThemeProvider,
|
|
1176
|
-
useTheme,
|
|
1177
|
-
getVariantClasses,
|
|
1178
|
-
DEFAULT_THEME,
|
|
1179
|
-
} from '@delmaredigital/payload-puck/theme'
|
|
1180
|
-
|
|
1181
|
-
function MyButton({ variant }) {
|
|
1182
|
-
const theme = useTheme()
|
|
1183
|
-
const classes = getVariantClasses(theme.buttonVariants, variant)
|
|
1184
|
-
return <button className={classes}>Click me</button>
|
|
1185
|
-
}
|
|
1186
|
-
```
|
|
1187
|
-
|
|
1188
|
-
</details>
|
|
1189
|
-
|
|
1190
395
|
---
|
|
1191
396
|
|
|
1192
|
-
|
|
1193
|
-
<summary><strong>Layouts</strong> — Page structure, headers/footers, responsive controls</summary>
|
|
1194
|
-
|
|
1195
|
-
The layout system controls page structure, max-width constraints, and optional header/footer rendering. Layouts are selected per-page in the Puck editor's "Page Setup" panel.
|
|
1196
|
-
|
|
1197
|
-
### Built-in Layouts
|
|
397
|
+
## Layouts
|
|
1198
398
|
|
|
1199
|
-
|
|
1200
|
-
|--------|-------------|
|
|
1201
|
-
| **Default** | Standard page with max-width container (1200px) |
|
|
1202
|
-
| **Landing** | Full-width sections, no container constraints |
|
|
1203
|
-
| **Full Width** | Edge-to-edge content |
|
|
1204
|
-
|
|
1205
|
-
### Defining Custom Layouts
|
|
399
|
+
Define page layouts with headers, footers, and styling:
|
|
1206
400
|
|
|
1207
401
|
```typescript
|
|
1208
402
|
// lib/puck-layouts.ts
|
|
@@ -1218,204 +412,91 @@ export const siteLayouts: LayoutDefinition[] = [
|
|
|
1218
412
|
maxWidth: '1200px',
|
|
1219
413
|
header: SiteHeader,
|
|
1220
414
|
footer: SiteFooter,
|
|
1221
|
-
editorBackground: '#ffffff',
|
|
1222
|
-
editorDarkMode: false,
|
|
1223
415
|
stickyHeaderHeight: 80,
|
|
1224
|
-
// Default background for frontend (overridden by pageBackground in Puck)
|
|
1225
|
-
styles: {
|
|
1226
|
-
wrapper: {
|
|
1227
|
-
background: 'var(--site-bg)',
|
|
1228
|
-
backgroundAttachment: 'fixed',
|
|
1229
|
-
},
|
|
1230
|
-
},
|
|
1231
416
|
},
|
|
1232
417
|
{
|
|
1233
418
|
value: 'landing',
|
|
1234
419
|
label: 'Landing',
|
|
1235
420
|
description: 'Full-width landing page',
|
|
1236
421
|
fullWidth: true,
|
|
1237
|
-
editorBackground: '#f8fafc',
|
|
1238
|
-
styles: {
|
|
1239
|
-
wrapper: {
|
|
1240
|
-
background: 'linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%)',
|
|
1241
|
-
},
|
|
1242
|
-
},
|
|
1243
|
-
},
|
|
1244
|
-
{
|
|
1245
|
-
value: 'full-width',
|
|
1246
|
-
label: 'Full Width',
|
|
1247
|
-
description: 'Edge-to-edge content',
|
|
1248
|
-
fullWidth: true,
|
|
1249
422
|
},
|
|
1250
423
|
]
|
|
1251
424
|
```
|
|
1252
425
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
### Using Layouts in the Editor
|
|
426
|
+
Pass layouts to the `PuckConfigProvider`:
|
|
1256
427
|
|
|
1257
428
|
```typescript
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
<PuckEditor
|
|
1262
|
-
config={editorConfig}
|
|
1263
|
-
pageId={page.id}
|
|
1264
|
-
initialData={page.puckData}
|
|
1265
|
-
layouts={siteLayouts}
|
|
1266
|
-
/>
|
|
429
|
+
<PuckConfigProvider config={editorConfig} layouts={siteLayouts}>
|
|
430
|
+
{children}
|
|
431
|
+
</PuckConfigProvider>
|
|
1267
432
|
```
|
|
1268
433
|
|
|
1269
|
-
|
|
434
|
+
And use them with `PageRenderer`:
|
|
1270
435
|
|
|
1271
436
|
```typescript
|
|
1272
|
-
import {
|
|
1273
|
-
import { LayoutWrapper, DEFAULT_LAYOUTS } from '@delmaredigital/payload-puck/layouts'
|
|
437
|
+
import { LayoutWrapper } from '@delmaredigital/payload-puck/layouts'
|
|
1274
438
|
|
|
1275
|
-
|
|
1276
|
-
const page = await getPage(params.slug)
|
|
1277
|
-
const layout = DEFAULT_LAYOUTS.find(l => l.value === page.puckData?.root?.props?.pageLayout)
|
|
439
|
+
const layout = siteLayouts.find(l => l.value === page.puckData?.root?.props?.pageLayout)
|
|
1278
440
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
</LayoutWrapper>
|
|
1283
|
-
)
|
|
1284
|
-
}
|
|
441
|
+
<LayoutWrapper layout={layout}>
|
|
442
|
+
<PageRenderer config={baseConfig} data={page.puckData} />
|
|
443
|
+
</LayoutWrapper>
|
|
1285
444
|
```
|
|
1286
445
|
|
|
1287
|
-
### Layout Definition Options
|
|
1288
|
-
|
|
1289
|
-
| Option | Type | Default | Description |
|
|
1290
|
-
|--------|------|---------|-------------|
|
|
1291
|
-
| `value` | `string` | — | Unique identifier |
|
|
1292
|
-
| `label` | `string` | — | Display name in editor |
|
|
1293
|
-
| `description` | `string` | — | Optional description |
|
|
1294
|
-
| `maxWidth` | `string` | — | Container max-width (e.g., `'1200px'`) |
|
|
1295
|
-
| `fullWidth` | `boolean` | `false` | If true, no container constraints |
|
|
1296
|
-
| `classes` | `object` | — | CSS classes for wrapper/container/content |
|
|
1297
|
-
| `styles` | `object` | — | Inline styles for wrapper/container/content |
|
|
1298
|
-
| `header` | `ComponentType` | — | Header component for editor preview and frontend |
|
|
1299
|
-
| `footer` | `ComponentType` | — | Footer component for editor preview and frontend |
|
|
1300
|
-
| `editorBackground` | `string` | `'#ffffff'` | Background color/gradient for editor preview |
|
|
1301
|
-
| `editorDarkMode` | `boolean` | `false` | Whether to use dark mode styling in editor preview |
|
|
1302
|
-
| `stickyHeaderHeight` | `number` | — | Height in px of sticky/fixed header for proper content offset |
|
|
1303
|
-
| `stickyFooter` | `boolean` | `true` | Push footer to bottom of viewport even with minimal content. Set to `false` to let footer flow naturally after content |
|
|
1304
|
-
|
|
1305
|
-
### Page-Level Settings
|
|
1306
|
-
|
|
1307
|
-
The editor automatically includes page-level controls that allow overriding layout defaults per-page:
|
|
1308
|
-
|
|
1309
|
-
| Field | Options | Description |
|
|
1310
|
-
|-------|---------|-------------|
|
|
1311
|
-
| `showHeader` | `default`, `show`, `hide` | Override header visibility for this page |
|
|
1312
|
-
| `showFooter` | `default`, `show`, `hide` | Override footer visibility for this page |
|
|
1313
|
-
| `pageBackground` | Background field | Custom page background color/gradient/image |
|
|
1314
|
-
| `pageMaxWidth` | Select | Override layout's max-width constraint |
|
|
1315
|
-
|
|
1316
|
-
These settings appear in the editor's "Page Setup" panel and are applied in both the editor preview and frontend rendering.
|
|
1317
|
-
|
|
1318
|
-
</details>
|
|
1319
|
-
|
|
1320
446
|
---
|
|
1321
447
|
|
|
1322
|
-
|
|
1323
|
-
<summary><strong>API Routes</strong> — Auth configuration, root props mapping</summary>
|
|
1324
|
-
|
|
1325
|
-
### Auth Configuration
|
|
448
|
+
## Page-Tree Integration
|
|
1326
449
|
|
|
1327
|
-
|
|
450
|
+
When `@delmaredigital/payload-page-tree` is detected, the plugin automatically adds folder management to the Puck sidebar.
|
|
1328
451
|
|
|
1329
|
-
|
|
1330
|
-
const auth = {
|
|
1331
|
-
// Required: Authenticate the request
|
|
1332
|
-
authenticate: async (request) => {
|
|
1333
|
-
const session = await getSession(request)
|
|
1334
|
-
if (!session?.user) return { authenticated: false }
|
|
1335
|
-
return { authenticated: true, user: session.user }
|
|
1336
|
-
},
|
|
452
|
+
### How It Works
|
|
1337
453
|
|
|
1338
|
-
|
|
1339
|
-
canList: async (user) => ({ allowed: true }),
|
|
1340
|
-
canView: async (user, pageId) => ({ allowed: true }),
|
|
1341
|
-
canEdit: async (user, pageId) => ({ allowed: user.role === 'editor' }),
|
|
1342
|
-
canPublish: async (user, pageId) => ({ allowed: user.role === 'admin' }),
|
|
1343
|
-
canDelete: async (user, pageId) => ({ allowed: user.role === 'admin' }),
|
|
1344
|
-
}
|
|
1345
|
-
```
|
|
454
|
+
The plugin checks if your collection has a `pageSegment` field (page-tree's signature). When detected:
|
|
1346
455
|
|
|
1347
|
-
|
|
456
|
+
1. **Folder Picker** - Select a folder from the hierarchy
|
|
457
|
+
2. **Page Segment** - Edit the page's URL segment
|
|
458
|
+
3. **Slug Preview** - See the computed slug (folder path + segment)
|
|
1348
459
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
```typescript
|
|
1352
|
-
createPuckApiRoutesWithId({
|
|
1353
|
-
// ...
|
|
1354
|
-
rootPropsMapping: [
|
|
1355
|
-
{ from: 'title', to: 'meta.title' },
|
|
1356
|
-
{ from: 'description', to: 'meta.description' },
|
|
1357
|
-
{ from: 'pageLayout', to: 'pageLayout' },
|
|
1358
|
-
],
|
|
1359
|
-
})
|
|
1360
|
-
```
|
|
1361
|
-
|
|
1362
|
-
</details>
|
|
1363
|
-
|
|
1364
|
-
---
|
|
1365
|
-
|
|
1366
|
-
<details>
|
|
1367
|
-
<summary><strong>Plugin Options</strong> — Collection config, access control</summary>
|
|
460
|
+
### Configuration
|
|
1368
461
|
|
|
1369
462
|
```typescript
|
|
1370
463
|
createPuckPlugin({
|
|
1371
|
-
//
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
// Auto-generate the Pages collection (default: true)
|
|
1375
|
-
autoGenerateCollection: true,
|
|
464
|
+
// Auto-detect (default)
|
|
465
|
+
pageTreeIntegration: undefined,
|
|
1376
466
|
|
|
1377
|
-
//
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
},
|
|
467
|
+
// Explicitly enable with custom config
|
|
468
|
+
pageTreeIntegration: {
|
|
469
|
+
folderSlug: 'payload-folders',
|
|
470
|
+
pageSegmentFieldName: 'pageSegment',
|
|
1382
471
|
},
|
|
1383
472
|
|
|
1384
|
-
//
|
|
1385
|
-
|
|
1386
|
-
read: () => true,
|
|
1387
|
-
create: ({ req }) => !!req.user,
|
|
1388
|
-
update: ({ req }) => !!req.user,
|
|
1389
|
-
delete: ({ req }) => !!req.user,
|
|
1390
|
-
},
|
|
473
|
+
// Explicitly disable
|
|
474
|
+
pageTreeIntegration: false,
|
|
1391
475
|
})
|
|
1392
476
|
```
|
|
1393
477
|
|
|
1394
|
-
|
|
478
|
+
### Performance
|
|
479
|
+
|
|
480
|
+
Detection is instant - it reads the in-memory collection config, no database queries.
|
|
1395
481
|
|
|
1396
482
|
---
|
|
1397
483
|
|
|
1398
|
-
|
|
1399
|
-
<summary><strong>Hybrid Integration</strong> — Add Puck to existing collections with legacy blocks</summary>
|
|
484
|
+
## Hybrid Integration
|
|
1400
485
|
|
|
1401
|
-
|
|
486
|
+
Add Puck to existing collections with legacy blocks.
|
|
1402
487
|
|
|
1403
488
|
### Automatic (Recommended)
|
|
1404
489
|
|
|
1405
|
-
If you already have a `pages` collection
|
|
490
|
+
If you already have a `pages` collection, the plugin adds only the Puck-specific fields:
|
|
1406
491
|
|
|
1407
492
|
```typescript
|
|
1408
493
|
// payload.config.ts
|
|
1409
|
-
import { buildConfig } from 'payload'
|
|
1410
|
-
import { createPuckPlugin } from '@delmaredigital/payload-puck/plugin'
|
|
1411
|
-
|
|
1412
494
|
export default buildConfig({
|
|
1413
495
|
collections: [
|
|
1414
496
|
{
|
|
1415
497
|
slug: 'pages',
|
|
1416
498
|
fields: [
|
|
1417
499
|
{ name: 'title', type: 'text', required: true },
|
|
1418
|
-
{ name: 'slug', type: 'text', required: true },
|
|
1419
500
|
{ name: 'layout', type: 'blocks', blocks: [HeroBlock, CTABlock] },
|
|
1420
501
|
],
|
|
1421
502
|
},
|
|
@@ -1426,162 +507,137 @@ export default buildConfig({
|
|
|
1426
507
|
})
|
|
1427
508
|
```
|
|
1428
509
|
|
|
1429
|
-
The
|
|
1430
|
-
|
|
1431
|
-
**Smart detection:** The `editorVersion` field automatically detects whether existing pages use legacy blocks or Puck data. Pages with legacy blocks are marked `'legacy'`, pages with Puck content are marked `'puck'`, and new empty pages use the configured default. This prevents migrations from incorrectly overwriting existing content.
|
|
510
|
+
The `editorVersion` field auto-detects whether pages use legacy blocks or Puck.
|
|
1432
511
|
|
|
1433
512
|
### Manual with `getPuckFields()`
|
|
1434
513
|
|
|
1435
|
-
For full control, disable auto-generation and use `getPuckFields()`:
|
|
1436
|
-
|
|
1437
514
|
```typescript
|
|
1438
|
-
// collections/Pages.ts
|
|
1439
|
-
import type { CollectionConfig } from 'payload'
|
|
1440
515
|
import { getPuckFields } from '@delmaredigital/payload-puck'
|
|
1441
516
|
|
|
1442
517
|
export const Pages: CollectionConfig = {
|
|
1443
518
|
slug: 'pages',
|
|
1444
|
-
versions: { drafts: true },
|
|
1445
519
|
fields: [
|
|
1446
|
-
{ name: 'title', type: 'text'
|
|
1447
|
-
{ name: '
|
|
1448
|
-
{ name: 'layout', type: 'blocks', blocks: [HeroBlock, CTABlock] },
|
|
1449
|
-
|
|
520
|
+
{ name: 'title', type: 'text' },
|
|
521
|
+
{ name: 'layout', type: 'blocks', blocks: [...] },
|
|
1450
522
|
...getPuckFields({
|
|
1451
|
-
includeSEO:
|
|
1452
|
-
includeConversion: true,
|
|
1453
|
-
// Custom conversion types (optional - defaults to standard types)
|
|
1454
|
-
conversionTypeOptions: [
|
|
1455
|
-
{ label: 'Registration', value: 'registration' },
|
|
1456
|
-
{ label: 'Donation', value: 'donation' },
|
|
1457
|
-
{ label: 'Course Start', value: 'course_start' },
|
|
1458
|
-
{ label: 'Custom', value: 'custom' },
|
|
1459
|
-
],
|
|
523
|
+
includeSEO: true,
|
|
1460
524
|
includeEditorVersion: true,
|
|
1461
525
|
includePageLayout: true,
|
|
1462
|
-
includeIsHomepage: false,
|
|
1463
|
-
// Custom layouts (only value/label needed for the field)
|
|
1464
|
-
layouts: [
|
|
1465
|
-
{ value: 'default', label: 'Default' },
|
|
1466
|
-
{ value: 'landing', label: 'Landing' },
|
|
1467
|
-
],
|
|
1468
526
|
}),
|
|
1469
527
|
],
|
|
1470
528
|
}
|
|
1471
529
|
```
|
|
1472
530
|
|
|
1473
|
-
|
|
1474
|
-
// payload.config.ts
|
|
1475
|
-
createPuckPlugin({
|
|
1476
|
-
pagesCollection: 'pages',
|
|
1477
|
-
autoGenerateCollection: false,
|
|
1478
|
-
})
|
|
1479
|
-
```
|
|
1480
|
-
|
|
1481
|
-
### Individual Field Imports
|
|
531
|
+
### Rendering Hybrid Pages
|
|
1482
532
|
|
|
1483
533
|
```typescript
|
|
1484
|
-
import {
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
const Pages: CollectionConfig = {
|
|
1493
|
-
slug: 'pages',
|
|
1494
|
-
fields: [
|
|
1495
|
-
puckDataField,
|
|
1496
|
-
editorVersionField,
|
|
1497
|
-
createPageLayoutField(myCustomLayouts),
|
|
1498
|
-
],
|
|
1499
|
-
}
|
|
534
|
+
import { HybridPageRenderer } from '@delmaredigital/payload-puck/render'
|
|
535
|
+
import { LegacyBlockRenderer } from '@/components/LegacyBlockRenderer'
|
|
536
|
+
|
|
537
|
+
<HybridPageRenderer
|
|
538
|
+
page={page}
|
|
539
|
+
config={puckConfig}
|
|
540
|
+
legacyRenderer={(blocks) => <LegacyBlockRenderer blocks={blocks} />}
|
|
541
|
+
/>
|
|
1500
542
|
```
|
|
1501
543
|
|
|
1502
|
-
|
|
544
|
+
---
|
|
1503
545
|
|
|
1504
|
-
|
|
546
|
+
## Advanced Configuration
|
|
1505
547
|
|
|
1506
|
-
|
|
548
|
+
### Plugin Options
|
|
549
|
+
|
|
550
|
+
| Option | Default | Description |
|
|
551
|
+
|--------|---------|-------------|
|
|
552
|
+
| `pagesCollection` | `'pages'` | Collection slug to use for pages |
|
|
553
|
+
| `autoGenerateCollection` | `true` | Create the collection if it doesn't exist, or add Puck fields to existing |
|
|
554
|
+
| `enableEndpoints` | `true` | Register API endpoints at `/api/puck/:collection` for the editor |
|
|
555
|
+
| `enableAdminView` | `true` | Register the Puck editor view in Payload admin |
|
|
556
|
+
| `adminViewPath` | `'/puck-editor'` | Path for the editor (full path: `/admin/puck-editor/:collection/:id`) |
|
|
557
|
+
| `pageTreeIntegration` | auto-detect | Integration with `@delmaredigital/payload-page-tree` |
|
|
558
|
+
| `layouts` | `undefined` | Layout definitions for page templates |
|
|
1507
559
|
|
|
1508
560
|
```typescript
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
561
|
+
createPuckPlugin({
|
|
562
|
+
pagesCollection: 'pages',
|
|
563
|
+
autoGenerateCollection: true,
|
|
564
|
+
enableEndpoints: true,
|
|
565
|
+
enableAdminView: true,
|
|
566
|
+
adminViewPath: '/puck-editor',
|
|
567
|
+
pageTreeIntegration: undefined, // auto-detects
|
|
1514
568
|
|
|
1515
|
-
|
|
1516
|
-
|
|
569
|
+
// Collection overrides (merged with generated collection)
|
|
570
|
+
collectionOverrides: {
|
|
571
|
+
admin: {
|
|
572
|
+
defaultColumns: ['title', 'slug', 'updatedAt'],
|
|
573
|
+
},
|
|
574
|
+
},
|
|
1517
575
|
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
}
|
|
576
|
+
// Access control
|
|
577
|
+
access: {
|
|
578
|
+
read: () => true,
|
|
579
|
+
create: ({ req }) => !!req.user,
|
|
580
|
+
update: ({ req }) => !!req.user,
|
|
581
|
+
delete: ({ req }) => !!req.user,
|
|
582
|
+
},
|
|
583
|
+
})
|
|
1527
584
|
```
|
|
1528
585
|
|
|
1529
|
-
|
|
586
|
+
### Custom API Routes (Advanced)
|
|
1530
587
|
|
|
1531
|
-
|
|
588
|
+
If you need custom API route handling beyond the built-in endpoints, you can disable automatic endpoints and create your own:
|
|
1532
589
|
|
|
1533
590
|
```typescript
|
|
1534
|
-
//
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
591
|
+
// payload.config.ts
|
|
592
|
+
createPuckPlugin({
|
|
593
|
+
enableEndpoints: false, // Disable built-in endpoints
|
|
594
|
+
})
|
|
595
|
+
```
|
|
1539
596
|
|
|
1540
|
-
|
|
1541
|
-
const page = await getPage(params.slug)
|
|
1542
|
-
|
|
1543
|
-
if (page.editorVersion === 'puck' && page.puckData) {
|
|
1544
|
-
return (
|
|
1545
|
-
<PageRenderer
|
|
1546
|
-
config={puckConfig}
|
|
1547
|
-
data={page.puckData}
|
|
1548
|
-
layouts={siteLayouts}
|
|
1549
|
-
/>
|
|
1550
|
-
)
|
|
1551
|
-
}
|
|
597
|
+
Then create custom routes using the provided factories:
|
|
1552
598
|
|
|
1553
|
-
|
|
1554
|
-
|
|
599
|
+
```typescript
|
|
600
|
+
// app/api/puck/[collection]/route.ts
|
|
601
|
+
import { createPuckApiRoutes } from '@delmaredigital/payload-puck/api'
|
|
602
|
+
import { getPayload } from 'payload'
|
|
603
|
+
import config from '@payload-config'
|
|
604
|
+
import { headers } from 'next/headers'
|
|
605
|
+
|
|
606
|
+
export const { GET, POST } = createPuckApiRoutes({
|
|
607
|
+
payloadConfig: config,
|
|
608
|
+
auth: {
|
|
609
|
+
authenticate: async (request) => {
|
|
610
|
+
const payload = await getPayload({ config })
|
|
611
|
+
const { user } = await payload.auth({ headers: await headers() })
|
|
612
|
+
if (!user) return { authenticated: false }
|
|
613
|
+
return { authenticated: true, user: { id: user.id } }
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
})
|
|
1555
617
|
```
|
|
1556
618
|
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
| Export | Description |
|
|
1560
|
-
|--------|-------------|
|
|
1561
|
-
| `getPuckFields(options)` | Returns array of Puck fields based on options |
|
|
1562
|
-
| `puckDataField` | JSON field for Puck editor data (hidden) |
|
|
1563
|
-
| `editorVersionField` | Select field: 'legacy' \| 'puck' (auto-detects based on content) |
|
|
1564
|
-
| `createEditorVersionField(default, sidebar, legacyBlocksFieldName)` | Factory for custom editor version field |
|
|
1565
|
-
| `pageLayoutField` | Layout selector with DEFAULT_LAYOUTS |
|
|
1566
|
-
| `createPageLayoutField(layouts, sidebar)` | Factory for custom layout options |
|
|
1567
|
-
| `isHomepageField` | Checkbox for homepage designation |
|
|
1568
|
-
| `seoFieldGroup` | Group named `meta` with title, description, image, noindex, etc. |
|
|
1569
|
-
| `conversionFieldGroup` | Group for conversion tracking analytics (default types) |
|
|
1570
|
-
| `createConversionFieldGroup(types, sidebar)` | Factory for custom conversion types |
|
|
1571
|
-
| `DEFAULT_CONVERSION_TYPES` | Default conversion types array |
|
|
1572
|
-
| `generatePuckEditField(slug, config)` | Creates the "Edit with Puck" UI button |
|
|
1573
|
-
|
|
1574
|
-
### Available Render Exports
|
|
1575
|
-
|
|
1576
|
-
| Export | Description |
|
|
1577
|
-
|--------|-------------|
|
|
1578
|
-
| `PageRenderer` | Renders Puck data with layout support |
|
|
1579
|
-
| `HybridPageRenderer` | Renders either Puck or legacy pages based on `editorVersion` |
|
|
619
|
+
---
|
|
1580
620
|
|
|
1581
|
-
|
|
621
|
+
## Export Reference
|
|
622
|
+
|
|
623
|
+
| Export Path | Description |
|
|
624
|
+
|-------------|-------------|
|
|
625
|
+
| `@delmaredigital/payload-puck` | Plugin creation, field utilities |
|
|
626
|
+
| `@delmaredigital/payload-puck/plugin` | `createPuckPlugin` |
|
|
627
|
+
| `@delmaredigital/payload-puck/config` | `baseConfig`, `createConfig()`, `extendConfig()` |
|
|
628
|
+
| `@delmaredigital/payload-puck/config/editor` | `editorConfig` for editing |
|
|
629
|
+
| `@delmaredigital/payload-puck/client` | `PuckConfigProvider`, `usePuckConfig`, client components |
|
|
630
|
+
| `@delmaredigital/payload-puck/rsc` | `PuckEditorView` for Payload admin views |
|
|
631
|
+
| `@delmaredigital/payload-puck/render` | `PageRenderer`, `HybridPageRenderer` |
|
|
632
|
+
| `@delmaredigital/payload-puck/fields` | Custom Puck fields and CSS helpers |
|
|
633
|
+
| `@delmaredigital/payload-puck/components` | Component configs for custom configurations |
|
|
634
|
+
| `@delmaredigital/payload-puck/theme` | `ThemeProvider`, theme utilities |
|
|
635
|
+
| `@delmaredigital/payload-puck/layouts` | Layout definitions, `LayoutWrapper` |
|
|
636
|
+
| `@delmaredigital/payload-puck/api` | API route factories (for custom implementations) |
|
|
637
|
+
| `@delmaredigital/payload-puck/admin/client` | `EditWithPuckButton`, `EditWithPuckCell` |
|
|
1582
638
|
|
|
1583
639
|
---
|
|
1584
640
|
|
|
1585
641
|
## License
|
|
1586
642
|
|
|
1587
|
-
MIT
|
|
643
|
+
MIT
|