@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.
Files changed (565) hide show
  1. package/README.md +293 -1237
  2. package/dist/admin/EditWithPuckButton.d.ts +74 -0
  3. package/dist/admin/EditWithPuckButton.d.ts.map +1 -0
  4. package/dist/admin/EditWithPuckButton.js +114 -0
  5. package/dist/admin/EditWithPuckButton.js.map +1 -0
  6. package/dist/admin/EditWithPuckCell.d.ts +43 -0
  7. package/dist/admin/EditWithPuckCell.d.ts.map +1 -0
  8. package/dist/admin/EditWithPuckCell.js +66 -0
  9. package/dist/admin/EditWithPuckCell.js.map +1 -0
  10. package/dist/admin/PuckEditorView.d.ts +85 -0
  11. package/dist/admin/PuckEditorView.d.ts.map +1 -0
  12. package/dist/admin/PuckEditorView.js +135 -0
  13. package/dist/admin/PuckEditorView.js.map +1 -0
  14. package/dist/admin/client.d.ts +8 -104
  15. package/dist/admin/client.d.ts.map +1 -0
  16. package/dist/admin/client.js +14 -176
  17. package/dist/admin/client.js.map +1 -0
  18. package/dist/admin/generateAdminComponents.d.ts +51 -0
  19. package/dist/admin/generateAdminComponents.d.ts.map +1 -0
  20. package/dist/admin/generateAdminComponents.js +42 -0
  21. package/dist/admin/generateAdminComponents.js.map +1 -0
  22. package/dist/admin/index.d.ts +14 -150
  23. package/dist/admin/index.d.ts.map +1 -0
  24. package/dist/admin/index.js +17 -30
  25. package/dist/admin/index.js.map +1 -0
  26. package/dist/api/createPuckApiRoutes.d.ts +31 -0
  27. package/dist/api/createPuckApiRoutes.d.ts.map +1 -0
  28. package/dist/api/createPuckApiRoutes.js +193 -0
  29. package/dist/api/createPuckApiRoutes.js.map +1 -0
  30. package/dist/api/createPuckApiRoutesVersions.d.ts +28 -0
  31. package/dist/api/createPuckApiRoutesVersions.d.ts.map +1 -0
  32. package/dist/api/createPuckApiRoutesVersions.js +144 -0
  33. package/dist/api/createPuckApiRoutesVersions.js.map +1 -0
  34. package/dist/api/createPuckApiRoutesWithId.d.ts +34 -0
  35. package/dist/api/createPuckApiRoutesWithId.d.ts.map +1 -0
  36. package/dist/api/createPuckApiRoutesWithId.js +251 -0
  37. package/dist/api/createPuckApiRoutesWithId.js.map +1 -0
  38. package/dist/api/index.d.ts +11 -431
  39. package/dist/api/index.d.ts.map +1 -0
  40. package/dist/api/index.js +40 -587
  41. package/dist/api/index.js.map +1 -0
  42. package/dist/api/types.d.ts +302 -0
  43. package/dist/api/types.d.ts.map +1 -0
  44. package/dist/api/types.js +2 -0
  45. package/dist/api/types.js.map +1 -0
  46. package/dist/api/utils/mapRootProps.d.ts +76 -0
  47. package/dist/api/utils/mapRootProps.d.ts.map +1 -0
  48. package/dist/api/utils/mapRootProps.js +169 -0
  49. package/dist/api/utils/mapRootProps.js.map +1 -0
  50. package/dist/collections/Templates.d.ts +9 -0
  51. package/dist/collections/Templates.d.ts.map +1 -0
  52. package/dist/collections/Templates.js +62 -0
  53. package/dist/collections/Templates.js.map +1 -0
  54. package/dist/components/AccordionClient.d.ts +20 -0
  55. package/dist/components/AccordionClient.d.ts.map +1 -0
  56. package/dist/components/AccordionClient.js +67 -0
  57. package/dist/components/AccordionClient.js.map +1 -0
  58. package/dist/components/AnimatedWrapper.d.ts +33 -0
  59. package/dist/components/AnimatedWrapper.d.ts.map +1 -0
  60. package/dist/components/AnimatedWrapper.js +61 -0
  61. package/dist/components/AnimatedWrapper.js.map +1 -0
  62. package/dist/components/exports.d.ts +54 -0
  63. package/dist/components/exports.d.ts.map +1 -0
  64. package/dist/components/exports.js +71 -0
  65. package/dist/components/exports.js.map +1 -0
  66. package/dist/components/index.d.ts +8 -219
  67. package/dist/components/index.d.ts.map +1 -0
  68. package/dist/components/index.js +15 -9155
  69. package/dist/components/index.js.map +1 -0
  70. package/dist/components/interactive/Accordion.d.ts +28 -0
  71. package/dist/components/interactive/Accordion.d.ts.map +1 -0
  72. package/dist/components/interactive/Accordion.js +159 -0
  73. package/dist/components/interactive/Accordion.js.map +1 -0
  74. package/dist/components/interactive/Accordion.server.d.ts +29 -0
  75. package/dist/components/interactive/Accordion.server.d.ts.map +1 -0
  76. package/dist/components/interactive/Accordion.server.js +30 -0
  77. package/dist/components/interactive/Accordion.server.js.map +1 -0
  78. package/dist/components/interactive/Button.d.ts +26 -0
  79. package/dist/components/interactive/Button.d.ts.map +1 -0
  80. package/dist/components/interactive/Button.js +133 -0
  81. package/dist/components/interactive/Button.js.map +1 -0
  82. package/dist/components/interactive/Button.server.d.ts +28 -0
  83. package/dist/components/interactive/Button.server.d.ts.map +1 -0
  84. package/dist/components/interactive/Button.server.js +96 -0
  85. package/dist/components/interactive/Button.server.js.map +1 -0
  86. package/dist/components/interactive/Card.d.ts +27 -0
  87. package/dist/components/interactive/Card.d.ts.map +1 -0
  88. package/dist/components/interactive/Card.js +128 -0
  89. package/dist/components/interactive/Card.js.map +1 -0
  90. package/dist/components/interactive/Card.server.d.ts +29 -0
  91. package/dist/components/interactive/Card.server.d.ts.map +1 -0
  92. package/dist/components/interactive/Card.server.js +77 -0
  93. package/dist/components/interactive/Card.server.js.map +1 -0
  94. package/dist/components/interactive/Divider.d.ts +18 -0
  95. package/dist/components/interactive/Divider.d.ts.map +1 -0
  96. package/dist/components/interactive/Divider.js +68 -0
  97. package/dist/components/interactive/Divider.js.map +1 -0
  98. package/dist/components/interactive/Divider.server.d.ts +20 -0
  99. package/dist/components/interactive/Divider.server.d.ts.map +1 -0
  100. package/dist/components/interactive/Divider.server.js +50 -0
  101. package/dist/components/interactive/Divider.server.js.map +1 -0
  102. package/dist/components/interactive/index.d.ts +10 -0
  103. package/dist/components/interactive/index.d.ts.map +1 -0
  104. package/dist/components/interactive/index.js +10 -0
  105. package/dist/components/interactive/index.js.map +1 -0
  106. package/dist/components/layout/Container.d.ts +29 -0
  107. package/dist/components/layout/Container.d.ts.map +1 -0
  108. package/dist/components/layout/Container.js +166 -0
  109. package/dist/components/layout/Container.js.map +1 -0
  110. package/dist/components/layout/Container.server.d.ts +32 -0
  111. package/dist/components/layout/Container.server.d.ts.map +1 -0
  112. package/dist/components/layout/Container.server.js +105 -0
  113. package/dist/components/layout/Container.server.js.map +1 -0
  114. package/dist/components/layout/Flex.d.ts +36 -0
  115. package/dist/components/layout/Flex.d.ts.map +1 -0
  116. package/dist/components/layout/Flex.js +183 -0
  117. package/dist/components/layout/Flex.js.map +1 -0
  118. package/dist/components/layout/Flex.server.d.ts +36 -0
  119. package/dist/components/layout/Flex.server.d.ts.map +1 -0
  120. package/dist/components/layout/Flex.server.js +97 -0
  121. package/dist/components/layout/Flex.server.js.map +1 -0
  122. package/dist/components/layout/Grid.d.ts +31 -0
  123. package/dist/components/layout/Grid.d.ts.map +1 -0
  124. package/dist/components/layout/Grid.js +164 -0
  125. package/dist/components/layout/Grid.js.map +1 -0
  126. package/dist/components/layout/Grid.server.d.ts +32 -0
  127. package/dist/components/layout/Grid.server.d.ts.map +1 -0
  128. package/dist/components/layout/Grid.server.js +92 -0
  129. package/dist/components/layout/Grid.server.js.map +1 -0
  130. package/dist/components/layout/Section.d.ts +35 -0
  131. package/dist/components/layout/Section.d.ts.map +1 -0
  132. package/dist/components/layout/Section.js +212 -0
  133. package/dist/components/layout/Section.js.map +1 -0
  134. package/dist/components/layout/Section.server.d.ts +35 -0
  135. package/dist/components/layout/Section.server.d.ts.map +1 -0
  136. package/dist/components/layout/Section.server.js +144 -0
  137. package/dist/components/layout/Section.server.js.map +1 -0
  138. package/dist/components/layout/Spacer.d.ts +18 -0
  139. package/dist/components/layout/Spacer.d.ts.map +1 -0
  140. package/dist/components/layout/Spacer.js +99 -0
  141. package/dist/components/layout/Spacer.js.map +1 -0
  142. package/dist/components/layout/Spacer.server.d.ts +21 -0
  143. package/dist/components/layout/Spacer.server.d.ts.map +1 -0
  144. package/dist/components/layout/Spacer.server.js +61 -0
  145. package/dist/components/layout/Spacer.server.js.map +1 -0
  146. package/dist/components/layout/Template.d.ts +35 -0
  147. package/dist/components/layout/Template.d.ts.map +1 -0
  148. package/dist/components/layout/Template.js +124 -0
  149. package/dist/components/layout/Template.js.map +1 -0
  150. package/dist/components/layout/Template.server.d.ts +32 -0
  151. package/dist/components/layout/Template.server.d.ts.map +1 -0
  152. package/dist/components/layout/Template.server.js +75 -0
  153. package/dist/components/layout/Template.server.js.map +1 -0
  154. package/dist/components/layout/index.d.ts +14 -0
  155. package/dist/components/layout/index.d.ts.map +1 -0
  156. package/dist/components/layout/index.js +13 -0
  157. package/dist/components/layout/index.js.map +1 -0
  158. package/dist/components/media/Image.d.ts +30 -0
  159. package/dist/components/media/Image.d.ts.map +1 -0
  160. package/dist/components/media/Image.js +123 -0
  161. package/dist/components/media/Image.js.map +1 -0
  162. package/dist/components/media/Image.server.d.ts +28 -0
  163. package/dist/components/media/Image.server.d.ts.map +1 -0
  164. package/dist/components/media/Image.server.js +76 -0
  165. package/dist/components/media/Image.server.js.map +1 -0
  166. package/dist/components/media/index.d.ts +7 -0
  167. package/dist/components/media/index.d.ts.map +1 -0
  168. package/dist/components/media/index.js +7 -0
  169. package/dist/components/media/index.js.map +1 -0
  170. package/dist/components/typography/Heading.d.ts +21 -0
  171. package/dist/components/typography/Heading.d.ts.map +1 -0
  172. package/dist/components/typography/Heading.js +71 -0
  173. package/dist/components/typography/Heading.js.map +1 -0
  174. package/dist/components/typography/Heading.server.d.ts +21 -0
  175. package/dist/components/typography/Heading.server.d.ts.map +1 -0
  176. package/dist/components/typography/Heading.server.js +49 -0
  177. package/dist/components/typography/Heading.server.js.map +1 -0
  178. package/dist/components/typography/RichText.d.ts +20 -0
  179. package/dist/components/typography/RichText.d.ts.map +1 -0
  180. package/dist/components/typography/RichText.editor.d.ts +11 -0
  181. package/dist/components/typography/RichText.editor.d.ts.map +1 -0
  182. package/dist/components/typography/RichText.editor.js +67 -0
  183. package/dist/components/typography/RichText.editor.js.map +1 -0
  184. package/dist/components/typography/RichText.js +73 -0
  185. package/dist/components/typography/RichText.js.map +1 -0
  186. package/dist/components/typography/RichText.server.d.ts +22 -0
  187. package/dist/components/typography/RichText.server.d.ts.map +1 -0
  188. package/dist/components/typography/RichText.server.js +52 -0
  189. package/dist/components/typography/RichText.server.js.map +1 -0
  190. package/dist/components/typography/Text.d.ts +20 -0
  191. package/dist/components/typography/Text.d.ts.map +1 -0
  192. package/dist/components/typography/Text.js +61 -0
  193. package/dist/components/typography/Text.js.map +1 -0
  194. package/dist/components/typography/Text.server.d.ts +21 -0
  195. package/dist/components/typography/Text.server.d.ts.map +1 -0
  196. package/dist/components/typography/Text.server.js +39 -0
  197. package/dist/components/typography/Text.server.js.map +1 -0
  198. package/dist/components/typography/index.d.ts +10 -0
  199. package/dist/components/typography/index.d.ts.map +1 -0
  200. package/dist/components/typography/index.js +10 -0
  201. package/dist/components/typography/index.js.map +1 -0
  202. package/dist/config/config.editor.d.ts +15 -56
  203. package/dist/config/config.editor.d.ts.map +1 -0
  204. package/dist/config/config.editor.js +125 -9364
  205. package/dist/config/config.editor.js.map +1 -0
  206. package/dist/config/index.d.ts +7 -33
  207. package/dist/config/index.d.ts.map +1 -0
  208. package/dist/config/index.js +110 -2028
  209. package/dist/config/index.js.map +1 -0
  210. package/dist/config/merge.d.ts +23 -0
  211. package/dist/config/merge.d.ts.map +1 -0
  212. package/dist/config/merge.js +80 -0
  213. package/dist/config/merge.js.map +1 -0
  214. package/dist/config/presets.d.ts +342 -0
  215. package/dist/config/presets.d.ts.map +1 -0
  216. package/dist/config/presets.js +247 -0
  217. package/dist/config/presets.js.map +1 -0
  218. package/dist/editor/PuckEditor.client.d.ts +131 -0
  219. package/dist/editor/PuckEditor.client.d.ts.map +1 -0
  220. package/dist/editor/PuckEditor.client.js +42 -0
  221. package/dist/editor/PuckEditor.client.js.map +1 -0
  222. package/dist/editor/PuckEditorCore.client.d.ts +141 -0
  223. package/dist/editor/PuckEditorCore.client.d.ts.map +1 -0
  224. package/dist/editor/PuckEditorCore.client.js +306 -0
  225. package/dist/editor/PuckEditorCore.client.js.map +1 -0
  226. package/dist/editor/components/HeaderActions.d.ts +109 -0
  227. package/dist/editor/components/HeaderActions.d.ts.map +1 -0
  228. package/dist/editor/components/HeaderActions.js +254 -0
  229. package/dist/editor/components/HeaderActions.js.map +1 -0
  230. package/dist/editor/components/IframeWrapper.d.ts +77 -0
  231. package/dist/editor/components/IframeWrapper.d.ts.map +1 -0
  232. package/dist/editor/components/IframeWrapper.js +257 -0
  233. package/dist/editor/components/IframeWrapper.js.map +1 -0
  234. package/dist/editor/components/LoadingState.d.ts +14 -0
  235. package/dist/editor/components/LoadingState.d.ts.map +1 -0
  236. package/dist/editor/components/LoadingState.js +12 -0
  237. package/dist/editor/components/LoadingState.js.map +1 -0
  238. package/dist/editor/components/PreviewModal.d.ts +54 -0
  239. package/dist/editor/components/PreviewModal.d.ts.map +1 -0
  240. package/dist/editor/components/PreviewModal.js +298 -0
  241. package/dist/editor/components/PreviewModal.js.map +1 -0
  242. package/dist/editor/components/VersionHistory.d.ts +44 -0
  243. package/dist/editor/components/VersionHistory.d.ts.map +1 -0
  244. package/dist/editor/components/VersionHistory.js +308 -0
  245. package/dist/editor/components/VersionHistory.js.map +1 -0
  246. package/dist/editor/hooks/useUnsavedChanges.d.ts +27 -0
  247. package/dist/editor/hooks/useUnsavedChanges.d.ts.map +1 -0
  248. package/dist/editor/hooks/useUnsavedChanges.js +55 -0
  249. package/dist/editor/hooks/useUnsavedChanges.js.map +1 -0
  250. package/dist/editor/index.d.ts +16 -756
  251. package/dist/editor/index.d.ts.map +1 -0
  252. package/dist/editor/index.js +49 -4533
  253. package/dist/editor/index.js.map +1 -0
  254. package/dist/editor/plugins/index.d.ts +12 -0
  255. package/dist/editor/plugins/index.d.ts.map +1 -0
  256. package/dist/editor/plugins/index.js +12 -0
  257. package/dist/editor/plugins/index.js.map +1 -0
  258. package/dist/endpoints/index.d.ts +46 -0
  259. package/dist/endpoints/index.d.ts.map +1 -0
  260. package/dist/endpoints/index.js +204 -0
  261. package/dist/endpoints/index.js.map +1 -0
  262. package/dist/exports/client.d.ts +19 -0
  263. package/dist/exports/client.d.ts.map +1 -0
  264. package/dist/exports/client.js +21 -0
  265. package/dist/exports/client.js.map +1 -0
  266. package/dist/exports/rsc.d.ts +19 -0
  267. package/dist/exports/rsc.d.ts.map +1 -0
  268. package/dist/exports/rsc.js +19 -0
  269. package/dist/exports/rsc.js.map +1 -0
  270. package/dist/fields/AlignmentField.d.ts +36 -0
  271. package/dist/fields/AlignmentField.d.ts.map +1 -0
  272. package/dist/fields/AlignmentField.js +120 -0
  273. package/dist/fields/AlignmentField.js.map +1 -0
  274. package/dist/fields/AnimationField.d.ts +44 -0
  275. package/dist/fields/AnimationField.d.ts.map +1 -0
  276. package/dist/fields/AnimationField.js +329 -0
  277. package/dist/fields/AnimationField.js.map +1 -0
  278. package/dist/fields/BackgroundField.d.ts +40 -0
  279. package/dist/fields/BackgroundField.d.ts.map +1 -0
  280. package/dist/fields/BackgroundField.js +413 -0
  281. package/dist/fields/BackgroundField.js.map +1 -0
  282. package/dist/fields/BorderField.d.ts +29 -0
  283. package/dist/fields/BorderField.d.ts.map +1 -0
  284. package/dist/fields/BorderField.js +264 -0
  285. package/dist/fields/BorderField.js.map +1 -0
  286. package/dist/fields/ColorPickerField.d.ts +43 -0
  287. package/dist/fields/ColorPickerField.d.ts.map +1 -0
  288. package/dist/fields/ColorPickerField.js +285 -0
  289. package/dist/fields/ColorPickerField.js.map +1 -0
  290. package/dist/fields/DimensionsField.d.ts +43 -0
  291. package/dist/fields/DimensionsField.d.ts.map +1 -0
  292. package/dist/fields/DimensionsField.js +532 -0
  293. package/dist/fields/DimensionsField.js.map +1 -0
  294. package/dist/fields/FlexAlignmentField.d.ts +61 -0
  295. package/dist/fields/FlexAlignmentField.d.ts.map +1 -0
  296. package/dist/fields/FlexAlignmentField.js +166 -0
  297. package/dist/fields/FlexAlignmentField.js.map +1 -0
  298. package/dist/fields/FolderPickerField.d.ts +17 -0
  299. package/dist/fields/FolderPickerField.d.ts.map +1 -0
  300. package/dist/fields/FolderPickerField.js +282 -0
  301. package/dist/fields/FolderPickerField.js.map +1 -0
  302. package/dist/fields/GradientEditor.d.ts +22 -0
  303. package/dist/fields/GradientEditor.d.ts.map +1 -0
  304. package/dist/fields/GradientEditor.js +322 -0
  305. package/dist/fields/GradientEditor.js.map +1 -0
  306. package/dist/fields/LockedField.d.ts +67 -0
  307. package/dist/fields/LockedField.d.ts.map +1 -0
  308. package/dist/fields/LockedField.js +170 -0
  309. package/dist/fields/LockedField.js.map +1 -0
  310. package/dist/fields/MarginField.d.ts +31 -0
  311. package/dist/fields/MarginField.d.ts.map +1 -0
  312. package/dist/fields/MarginField.js +233 -0
  313. package/dist/fields/MarginField.js.map +1 -0
  314. package/dist/fields/MediaField.d.ts +33 -0
  315. package/dist/fields/MediaField.d.ts.map +1 -0
  316. package/dist/fields/MediaField.js +677 -0
  317. package/dist/fields/MediaField.js.map +1 -0
  318. package/dist/fields/PaddingField.d.ts +29 -0
  319. package/dist/fields/PaddingField.d.ts.map +1 -0
  320. package/dist/fields/PaddingField.js +232 -0
  321. package/dist/fields/PaddingField.js.map +1 -0
  322. package/dist/fields/PageSegmentField.d.ts +17 -0
  323. package/dist/fields/PageSegmentField.d.ts.map +1 -0
  324. package/dist/fields/PageSegmentField.js +92 -0
  325. package/dist/fields/PageSegmentField.js.map +1 -0
  326. package/dist/fields/ResetField.d.ts +27 -0
  327. package/dist/fields/ResetField.d.ts.map +1 -0
  328. package/dist/fields/ResetField.js +122 -0
  329. package/dist/fields/ResetField.js.map +1 -0
  330. package/dist/fields/ResponsiveField.d.ts +38 -0
  331. package/dist/fields/ResponsiveField.d.ts.map +1 -0
  332. package/dist/fields/ResponsiveField.js +275 -0
  333. package/dist/fields/ResponsiveField.js.map +1 -0
  334. package/dist/fields/ResponsiveVisibilityField.d.ts +34 -0
  335. package/dist/fields/ResponsiveVisibilityField.d.ts.map +1 -0
  336. package/dist/fields/ResponsiveVisibilityField.js +145 -0
  337. package/dist/fields/ResponsiveVisibilityField.js.map +1 -0
  338. package/dist/fields/SizeField.d.ts +54 -0
  339. package/dist/fields/SizeField.d.ts.map +1 -0
  340. package/dist/fields/SizeField.js +255 -0
  341. package/dist/fields/SizeField.js.map +1 -0
  342. package/dist/fields/SlugPreviewField.d.ts +16 -0
  343. package/dist/fields/SlugPreviewField.d.ts.map +1 -0
  344. package/dist/fields/SlugPreviewField.js +49 -0
  345. package/dist/fields/SlugPreviewField.js.map +1 -0
  346. package/dist/fields/TemplateField.d.ts +31 -0
  347. package/dist/fields/TemplateField.d.ts.map +1 -0
  348. package/dist/fields/TemplateField.js +428 -0
  349. package/dist/fields/TemplateField.js.map +1 -0
  350. package/dist/fields/TiptapField.d.ts +40 -0
  351. package/dist/fields/TiptapField.d.ts.map +1 -0
  352. package/dist/fields/TiptapField.js +857 -0
  353. package/dist/fields/TiptapField.js.map +1 -0
  354. package/dist/fields/TiptapModal.d.ts +10 -0
  355. package/dist/fields/TiptapModal.d.ts.map +1 -0
  356. package/dist/fields/TiptapModal.js +114 -0
  357. package/dist/fields/TiptapModal.js.map +1 -0
  358. package/dist/fields/TiptapModalField.d.ts +23 -0
  359. package/dist/fields/TiptapModalField.d.ts.map +1 -0
  360. package/dist/fields/TiptapModalField.js +55 -0
  361. package/dist/fields/TiptapModalField.js.map +1 -0
  362. package/dist/fields/TransformField.d.ts +31 -0
  363. package/dist/fields/TransformField.d.ts.map +1 -0
  364. package/dist/fields/TransformField.js +384 -0
  365. package/dist/fields/TransformField.js.map +1 -0
  366. package/dist/fields/VerticalAlignmentField.d.ts +35 -0
  367. package/dist/fields/VerticalAlignmentField.d.ts.map +1 -0
  368. package/dist/fields/VerticalAlignmentField.js +120 -0
  369. package/dist/fields/VerticalAlignmentField.js.map +1 -0
  370. package/dist/fields/WidthField.d.ts +28 -0
  371. package/dist/fields/WidthField.d.ts.map +1 -0
  372. package/dist/fields/WidthField.js +339 -0
  373. package/dist/fields/WidthField.js.map +1 -0
  374. package/dist/fields/index.d.ts +44 -559
  375. package/dist/fields/index.d.ts.map +1 -0
  376. package/dist/fields/index.js +91 -7685
  377. package/dist/fields/index.js.map +1 -0
  378. package/dist/fields/richtext-output.css +219 -0
  379. package/dist/{shared-DeNKN95N.d.mts → fields/shared.d.ts} +114 -133
  380. package/dist/fields/shared.d.ts.map +1 -0
  381. package/dist/fields/shared.js +1542 -0
  382. package/dist/fields/shared.js.map +1 -0
  383. package/dist/fields/{index.css → tiptap-styles.css} +75 -166
  384. package/dist/hooks/index.d.ts +8 -0
  385. package/dist/hooks/index.d.ts.map +1 -0
  386. package/dist/hooks/index.js +8 -0
  387. package/dist/hooks/index.js.map +1 -0
  388. package/dist/hooks/useResponsiveStyles.d.ts +51 -0
  389. package/dist/hooks/useResponsiveStyles.d.ts.map +1 -0
  390. package/dist/hooks/useResponsiveStyles.js +149 -0
  391. package/dist/hooks/useResponsiveStyles.js.map +1 -0
  392. package/dist/hooks/useScrollAnimation.d.ts +56 -0
  393. package/dist/hooks/useScrollAnimation.d.ts.map +1 -0
  394. package/dist/hooks/useScrollAnimation.js +116 -0
  395. package/dist/hooks/useScrollAnimation.js.map +1 -0
  396. package/dist/index.d.ts +66 -6
  397. package/dist/index.d.ts.map +1 -0
  398. package/dist/index.js +67 -568
  399. package/dist/index.js.map +1 -0
  400. package/dist/layouts/LayoutWrapper.d.ts +33 -0
  401. package/dist/layouts/LayoutWrapper.d.ts.map +1 -0
  402. package/dist/layouts/LayoutWrapper.js +112 -0
  403. package/dist/layouts/LayoutWrapper.js.map +1 -0
  404. package/dist/layouts/defaults.d.ts +40 -0
  405. package/dist/layouts/defaults.d.ts.map +1 -0
  406. package/dist/layouts/defaults.js +106 -0
  407. package/dist/layouts/defaults.js.map +1 -0
  408. package/dist/layouts/index.d.ts +27 -94
  409. package/dist/layouts/index.d.ts.map +1 -0
  410. package/dist/layouts/index.js +30 -393
  411. package/dist/layouts/index.js.map +1 -0
  412. package/dist/{types-D7D3rZ1J.d.ts → layouts/types.d.ts} +8 -11
  413. package/dist/layouts/types.d.ts.map +1 -0
  414. package/dist/layouts/types.js +7 -0
  415. package/dist/layouts/types.js.map +1 -0
  416. package/dist/layouts/utils.d.ts +42 -0
  417. package/dist/layouts/utils.d.ts.map +1 -0
  418. package/dist/layouts/utils.js +83 -0
  419. package/dist/layouts/utils.js.map +1 -0
  420. package/dist/plugin/collections/Pages.d.ts +8 -0
  421. package/dist/plugin/collections/Pages.d.ts.map +1 -0
  422. package/dist/plugin/collections/Pages.js +117 -0
  423. package/dist/plugin/collections/Pages.js.map +1 -0
  424. package/dist/plugin/fields/index.d.ts +153 -0
  425. package/dist/plugin/fields/index.d.ts.map +1 -0
  426. package/dist/plugin/fields/index.js +364 -0
  427. package/dist/plugin/fields/index.js.map +1 -0
  428. package/dist/plugin/fields/types.d.ts +108 -0
  429. package/dist/plugin/fields/types.d.ts.map +1 -0
  430. package/dist/plugin/fields/types.js +7 -0
  431. package/dist/plugin/fields/types.js.map +1 -0
  432. package/dist/plugin/index.d.ts +13 -255
  433. package/dist/plugin/index.d.ts.map +1 -0
  434. package/dist/plugin/index.js +276 -553
  435. package/dist/plugin/index.js.map +1 -0
  436. package/dist/render/HybridPageRenderer.d.ts +85 -0
  437. package/dist/render/HybridPageRenderer.d.ts.map +1 -0
  438. package/dist/render/HybridPageRenderer.js +29 -0
  439. package/dist/render/HybridPageRenderer.js.map +1 -0
  440. package/dist/render/PageRenderer.d.ts +51 -0
  441. package/dist/render/PageRenderer.d.ts.map +1 -0
  442. package/dist/render/PageRenderer.js +61 -0
  443. package/dist/render/PageRenderer.js.map +1 -0
  444. package/dist/render/PuckEditor.client.d.ts +66 -0
  445. package/dist/render/PuckEditor.client.d.ts.map +1 -0
  446. package/dist/render/PuckEditor.client.js +66 -0
  447. package/dist/render/PuckEditor.client.js.map +1 -0
  448. package/dist/render/index.d.ts +8 -106
  449. package/dist/render/index.d.ts.map +1 -0
  450. package/dist/render/index.js +10 -2162
  451. package/dist/render/index.js.map +1 -0
  452. package/dist/theme/context.d.ts +59 -0
  453. package/dist/theme/context.d.ts.map +1 -0
  454. package/dist/theme/context.js +73 -0
  455. package/dist/theme/context.js.map +1 -0
  456. package/dist/theme/defaults.d.ts +39 -0
  457. package/dist/theme/defaults.d.ts.map +1 -0
  458. package/dist/theme/defaults.js +72 -0
  459. package/dist/theme/defaults.js.map +1 -0
  460. package/dist/theme/example.d.ts +30 -0
  461. package/dist/theme/example.d.ts.map +1 -0
  462. package/dist/theme/example.js +89 -0
  463. package/dist/theme/example.js.map +1 -0
  464. package/dist/theme/index.d.ts +17 -140
  465. package/dist/theme/index.d.ts.map +1 -0
  466. package/dist/theme/index.js +34 -200
  467. package/dist/theme/index.js.map +1 -0
  468. package/dist/{types-_6MvjyKv.d.ts → theme/types.d.ts} +8 -9
  469. package/dist/theme/types.d.ts.map +1 -0
  470. package/dist/theme/types.js +9 -0
  471. package/dist/theme/types.js.map +1 -0
  472. package/dist/theme/utils.d.ts +30 -0
  473. package/dist/theme/utils.d.ts.map +1 -0
  474. package/dist/theme/utils.js +84 -0
  475. package/dist/theme/utils.js.map +1 -0
  476. package/dist/{index-CQu6SzDg.d.mts → types/index.d.ts} +120 -115
  477. package/dist/types/index.d.ts.map +1 -0
  478. package/dist/types/index.js +2 -0
  479. package/dist/types/index.js.map +1 -0
  480. package/dist/utils/index.d.ts +23 -257
  481. package/dist/utils/index.d.ts.map +1 -0
  482. package/dist/utils/index.js +56 -425
  483. package/dist/utils/index.js.map +1 -0
  484. package/dist/utils/{index.d.mts → migration.d.ts} +16 -112
  485. package/dist/utils/migration.d.ts.map +1 -0
  486. package/dist/utils/migration.js +309 -0
  487. package/dist/utils/migration.js.map +1 -0
  488. package/dist/utils/validation.d.ts +89 -0
  489. package/dist/utils/validation.d.ts.map +1 -0
  490. package/dist/utils/validation.js +247 -0
  491. package/dist/utils/validation.js.map +1 -0
  492. package/dist/views/PuckConfigContext.d.ts +71 -0
  493. package/dist/views/PuckConfigContext.d.ts.map +1 -0
  494. package/dist/views/PuckConfigContext.js +45 -0
  495. package/dist/views/PuckConfigContext.js.map +1 -0
  496. package/dist/views/PuckEditorClient.d.ts +73 -0
  497. package/dist/views/PuckEditorClient.d.ts.map +1 -0
  498. package/dist/views/PuckEditorClient.js +130 -0
  499. package/dist/views/PuckEditorClient.js.map +1 -0
  500. package/dist/views/PuckEditorView.d.ts +19 -0
  501. package/dist/views/PuckEditorView.d.ts.map +1 -0
  502. package/dist/views/PuckEditorView.js +106 -0
  503. package/dist/views/PuckEditorView.js.map +1 -0
  504. package/dist/views/index.d.ts +10 -0
  505. package/dist/views/index.d.ts.map +1 -0
  506. package/dist/views/index.js +10 -0
  507. package/dist/views/index.js.map +1 -0
  508. package/package.json +50 -72
  509. package/dist/AccordionClient.d.mts +0 -24
  510. package/dist/AccordionClient.d.ts +0 -24
  511. package/dist/AccordionClient.js +0 -786
  512. package/dist/AccordionClient.mjs +0 -784
  513. package/dist/AnimatedWrapper.d.mts +0 -30
  514. package/dist/AnimatedWrapper.d.ts +0 -30
  515. package/dist/AnimatedWrapper.js +0 -379
  516. package/dist/AnimatedWrapper.mjs +0 -377
  517. package/dist/admin/client.d.mts +0 -108
  518. package/dist/admin/client.mjs +0 -173
  519. package/dist/admin/index.d.mts +0 -157
  520. package/dist/admin/index.mjs +0 -29
  521. package/dist/api/index.d.mts +0 -460
  522. package/dist/api/index.mjs +0 -578
  523. package/dist/components/index.css +0 -339
  524. package/dist/components/index.d.mts +0 -222
  525. package/dist/components/index.mjs +0 -9109
  526. package/dist/config/config.editor.css +0 -339
  527. package/dist/config/config.editor.d.mts +0 -153
  528. package/dist/config/config.editor.mjs +0 -9347
  529. package/dist/config/index.d.mts +0 -68
  530. package/dist/config/index.mjs +0 -2008
  531. package/dist/editor/index.d.mts +0 -784
  532. package/dist/editor/index.mjs +0 -4500
  533. package/dist/fields/index.d.mts +0 -600
  534. package/dist/fields/index.mjs +0 -7569
  535. package/dist/index-CoUQnyC3.d.ts +0 -327
  536. package/dist/index.d.mts +0 -6
  537. package/dist/index.mjs +0 -555
  538. package/dist/layouts/index.d.mts +0 -96
  539. package/dist/layouts/index.mjs +0 -378
  540. package/dist/plugin/index.d.mts +0 -289
  541. package/dist/plugin/index.mjs +0 -555
  542. package/dist/render/index.d.mts +0 -109
  543. package/dist/render/index.mjs +0 -2140
  544. package/dist/shared-DeNKN95N.d.ts +0 -546
  545. package/dist/theme/index.d.mts +0 -155
  546. package/dist/theme/index.mjs +0 -186
  547. package/dist/types-D7D3rZ1J.d.mts +0 -116
  548. package/dist/types-_6MvjyKv.d.mts +0 -104
  549. package/dist/utils/index.mjs +0 -412
  550. package/dist/utils-DaRs9t0J.d.mts +0 -85
  551. package/dist/utils-gAvt0Vhw.d.ts +0 -85
  552. package/examples/README.md +0 -247
  553. package/examples/api/puck/pages/[id]/route.ts +0 -64
  554. package/examples/api/puck/pages/[id]/versions/route.ts +0 -47
  555. package/examples/api/puck/pages/route.ts +0 -45
  556. package/examples/app/(frontend)/page.tsx +0 -94
  557. package/examples/app/(manage)/layout.tsx +0 -31
  558. package/examples/app/[...slug]/page.tsx +0 -101
  559. package/examples/app/pages/[id]/edit/page.tsx +0 -148
  560. package/examples/components/CustomBanner.tsx +0 -368
  561. package/examples/config/custom-config.ts +0 -223
  562. package/examples/config/payload.config.example.ts +0 -64
  563. package/examples/lib/puck-layouts.ts +0 -258
  564. package/examples/lib/puck-theme.ts +0 -94
  565. 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
- - [API Routes](#api-routes)
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
- | `next` | >= 15.4.8 | React framework |
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
- > **📋 Important:** After completing these steps, continue to [Styling Setup](#styling-setup) and verify with the [Setup Checklist](#setup-checklist).
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
- #### Step 1: Add the Plugin
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
- #### Step 2: Create API Routes
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
- ```typescript
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
- export const { GET, POST } = createPuckApiRoutes({
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/(manage)/layout.tsx
154
- import '@/app/(frontend)/globals.css' // Adjust path to your CSS
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 EditorPage() {
81
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
181
82
  return (
182
- <PuckEditorView
183
- config={editorConfig}
184
- collectionSlug="pages"
185
- apiBasePath="/api/puck"
186
- backUrl="/admin/collections/pages"
187
- previewUrl={(slug) => `/${slug}`}
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
- The editor includes:
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
- To add additional plugins or disable the default:
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
- ```typescript
207
- // Add additional plugins (headingAnalyzer is still included)
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
- export default async function Page({ params }: { params: Promise<{ slug: string[] }> }) {
231
- const { slug } = await params
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: { slug: { equals: slug.join('/') } },
117
+ where: slugPath
118
+ ? { slug: { equals: slugPath } }
119
+ : { isHomepage: { equals: true } },
237
120
  limit: 1,
238
121
  })
239
122
 
240
- const page = docs[0]
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
- #### Step 5: Enable Version History (Optional)
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
- export const { GET, POST } = createPuckApiRoutesVersions({
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
- The History button automatically appears when this route exists.
162
+ ### That's It!
266
163
 
267
- </details>
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
- > **⚠️ This section is critical.** Without proper styling setup, components will render with broken or missing styles.
173
+ ### Tailwind Typography (Required)
274
174
 
275
- <details>
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** — Add the `@plugin` directive to your main CSS file:
285
-
181
+ **Tailwind v4:**
286
182
  ```css
287
183
  @import "tailwindcss";
288
184
  @plugin "@tailwindcss/typography";
289
185
  ```
290
186
 
291
- **Tailwind v3** — Add to your Tailwind config:
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
- </details>
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
- The path is relative to your CSS file's location and must resolve to your project's `node_modules`:
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
- @import "tailwindcss";
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
- </details>
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
- **If you don't use shadcn/ui:** Copy the theme boilerplate:
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
- @import './puck-theme.css';
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
- <details>
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 to handle React Server Components:
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 TipTap support |
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
- // Client component - use editorConfig
259
+ // PuckConfigProvider - use editorConfig
470
260
  import { editorConfig } from '@delmaredigital/payload-puck/config/editor'
471
- <PuckEditor config={editorConfig} ... />
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
- <details>
494
- <summary><strong>Components</strong> — Layout, Typography, Media, Interactive</summary>
279
+ ## Components
495
280
 
496
281
  ### Layout
497
282
 
498
- | Component | Description | Responsive Controls |
499
- |-----------|-------------|---------------------|
500
- | **Container** | Content wrapper with max-width and background options | Dimensions, Padding, Margin, Visibility |
501
- | **Flex** | Flexible box layout with direction and alignment | Dimensions, Padding, Margin, Visibility |
502
- | **Grid** | CSS Grid layout with responsive columns | Dimensions, Padding, Margin, Visibility |
503
- | **Section** | Full-width section with slot for nested content | Dimensions, Padding, Margin, Visibility |
504
- | **Spacer** | Vertical/horizontal spacing element | Visibility |
505
- | **Template** | Reusable component arrangements - save and load templates | Dimensions, Padding, Margin, Visibility |
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 | Responsive Controls |
510
- |-----------|-------------|---------------------|
511
- | **Heading** | H1-H6 headings with size and alignment options | — |
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 | Responsive Controls |
526
- |-----------|-------------|---------------------|
527
- | **Button** | Styled button/link with variants | |
528
- | **Card** | Content card with optional image header | — |
529
- | **Divider** | Horizontal rule with style options | — |
530
- | **Accordion** | Expandable content sections | |
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
- Components with responsive controls allow you to customize their behavior at different breakpoints (mobile, tablet, desktop). Available controls:
535
-
536
- - **Dimensions** - Width, max-width, height constraints per breakpoint
537
- - **Padding** - Inner spacing per breakpoint
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
- <details>
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 with upload/browse |
784
- | **TiptapField** | Rich text editor with formatting toolbar |
785
- | **ColorPickerField** | Color picker with presets and transparency |
786
- | **BackgroundField** | Backgrounds with solid colors, gradients, and images |
787
- | **PaddingField** | Visual padding editor with per-side controls |
788
- | **MarginField** | Visual margin editor with per-side controls |
789
- | **BorderField** | Border editor with width, style, color, radius |
790
- | **DimensionsField** | Width/height with min/max constraints |
791
- | **SizeField** | Preset sizes (sm, md, lg) or custom values |
792
- | **AlignmentField** | Text alignment (left, center, right, justify) |
793
- | **JustifyContentField** | Flexbox justify-content options |
794
- | **AlignItemsField** | Flexbox align-items options |
795
- | **VerticalAlignmentField** | Vertical alignment (top, center, bottom) |
796
- | **LockedTextField** | Protected text field with edit confirmation |
797
- | **LockedRadioField** | Protected radio field with edit confirmation |
798
- | **ResponsiveField** | Per-breakpoint values for responsive design |
799
- | **ResponsiveVisibilityField** | Show/hide toggle per breakpoint (Divi/Elementor-style) |
800
- | **AnimationField** | Entrance animations with easing/duration |
801
- | **TransformField** | CSS transforms (rotate, scale, translate) |
802
- | **GradientEditor** | Visual gradient builder |
803
-
804
- ### Usage Examples
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
- <details>
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
- ### Basic Usage
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-primary-foreground hover:bg-primary/90' },
1119
- secondary: { classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/90' },
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
- <details>
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
- | Layout | Description |
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
- > **Background priority:** If a user sets `pageBackground` in the Puck editor, it overrides the layout's `styles.wrapper.background`. This allows layouts to define sensible defaults while letting individual pages customize their appearance.
1254
-
1255
- ### Using Layouts in the Editor
426
+ Pass layouts to the `PuckConfigProvider`:
1256
427
 
1257
428
  ```typescript
1258
- import { PuckEditor } from '@delmaredigital/payload-puck/editor'
1259
- import { siteLayouts } from '@/lib/puck-layouts'
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
- ### Using Layouts on the Frontend
434
+ And use them with `PageRenderer`:
1270
435
 
1271
436
  ```typescript
1272
- import { PageRenderer } from '@delmaredigital/payload-puck/render'
1273
- import { LayoutWrapper, DEFAULT_LAYOUTS } from '@delmaredigital/payload-puck/layouts'
437
+ import { LayoutWrapper } from '@delmaredigital/payload-puck/layouts'
1274
438
 
1275
- export default async function Page({ params }) {
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
- return (
1280
- <LayoutWrapper layout={layout}>
1281
- <PageRenderer config={baseConfig} data={page.puckData} />
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
- <details>
1323
- <summary><strong>API Routes</strong> — Auth configuration, root props mapping</summary>
1324
-
1325
- ### Auth Configuration
448
+ ## Page-Tree Integration
1326
449
 
1327
- The API routes require an `auth` configuration with permission hooks:
450
+ When `@delmaredigital/payload-page-tree` is detected, the plugin automatically adds folder management to the Puck sidebar.
1328
451
 
1329
- ```typescript
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
- // Optional permission hooks
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
- ### Root Props Mapping
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
- Sync Puck root.props to Payload fields automatically:
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
- // Collection slug for pages (default: 'pages')
1372
- pagesCollection: 'pages',
1373
-
1374
- // Auto-generate the Pages collection (default: true)
1375
- autoGenerateCollection: true,
464
+ // Auto-detect (default)
465
+ pageTreeIntegration: undefined,
1376
466
 
1377
- // Override collection config
1378
- collectionOverrides: {
1379
- admin: {
1380
- defaultColumns: ['title', 'slug', 'updatedAt'],
1381
- },
467
+ // Explicitly enable with custom config
468
+ pageTreeIntegration: {
469
+ folderSlug: 'payload-folders',
470
+ pageSegmentFieldName: 'pageSegment',
1382
471
  },
1383
472
 
1384
- // Custom access control
1385
- access: {
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
- </details>
478
+ ### Performance
479
+
480
+ Detection is instant - it reads the in-memory collection config, no database queries.
1395
481
 
1396
482
  ---
1397
483
 
1398
- <details>
1399
- <summary><strong>Hybrid Integration</strong> — Add Puck to existing collections with legacy blocks</summary>
484
+ ## Hybrid Integration
1400
485
 
1401
- If you have an existing Pages collection with legacy Payload blocks, you can add Puck support without replacing your collection.
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 defined, the plugin automatically adds only the Puck-specific fields that don't already exist:
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 plugin adds: `puckData`, `editorVersion`, `pageLayout`, `meta` (SEO fields), and the "Edit with Puck" button.
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', required: true },
1447
- { name: 'slug', type: 'text', required: true },
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: false,
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
- ```typescript
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
- puckDataField,
1486
- editorVersionField,
1487
- createPageLayoutField,
1488
- seoFieldGroup,
1489
- conversionFieldGroup,
1490
- } from '@delmaredigital/payload-puck'
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
- ### Rendering Hybrid Pages
544
+ ---
1503
545
 
1504
- **Option A: Using `HybridPageRenderer` (Recommended)**
546
+ ## Advanced Configuration
1505
547
 
1506
- The `HybridPageRenderer` component handles the branching logic for you:
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
- // app/(frontend)/[...slug]/page.tsx
1510
- import { HybridPageRenderer } from '@delmaredigital/payload-puck/render'
1511
- import { puckConfig } from '@/puck/config'
1512
- import { siteLayouts } from '@/lib/puck-layouts'
1513
- import { LegacyBlockRenderer } from '@/components/LegacyBlockRenderer'
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
- export default async function Page({ params }) {
1516
- const page = await getPage(params.slug)
569
+ // Collection overrides (merged with generated collection)
570
+ collectionOverrides: {
571
+ admin: {
572
+ defaultColumns: ['title', 'slug', 'updatedAt'],
573
+ },
574
+ },
1517
575
 
1518
- return (
1519
- <HybridPageRenderer
1520
- page={page}
1521
- config={puckConfig}
1522
- layouts={siteLayouts}
1523
- legacyRenderer={(blocks) => <LegacyBlockRenderer blocks={blocks} />}
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
- **Option B: Manual Branching**
586
+ ### Custom API Routes (Advanced)
1530
587
 
1531
- For more control, handle the branching yourself:
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
- // app/(frontend)/[...slug]/page.tsx
1535
- import { PageRenderer } from '@delmaredigital/payload-puck/render'
1536
- import { puckConfig } from '@/puck/config'
1537
- import { siteLayouts } from '@/lib/puck-layouts'
1538
- import { LegacyBlockRenderer } from '@/components/LegacyBlockRenderer'
591
+ // payload.config.ts
592
+ createPuckPlugin({
593
+ enableEndpoints: false, // Disable built-in endpoints
594
+ })
595
+ ```
1539
596
 
1540
- export default async function Page({ params }) {
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
- return <LegacyBlockRenderer blocks={page.layout} />
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
- ### Available Field Exports
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
- </details>
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