@puckeditor/cli 0.24.0-canary.301a0304
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/bin.mjs +7304 -0
- package/dist/docs/api-reference/actions.md +63 -0
- package/dist/docs/api-reference/components/action-bar-action.md +35 -0
- package/dist/docs/api-reference/components/action-bar-group.md +24 -0
- package/dist/docs/api-reference/components/action-bar-label.md +25 -0
- package/dist/docs/api-reference/components/action-bar-separator.md +16 -0
- package/dist/docs/api-reference/components/action-bar.md +32 -0
- package/dist/docs/api-reference/components/auto-field.md +63 -0
- package/dist/docs/api-reference/components/drawer-item.md +75 -0
- package/dist/docs/api-reference/components/drawer.md +29 -0
- package/dist/docs/api-reference/components/drop-zone.md +232 -0
- package/dist/docs/api-reference/components/field-label.md +138 -0
- package/dist/docs/api-reference/components/inline-text-field.md +77 -0
- package/dist/docs/api-reference/components/puck-components.md +19 -0
- package/dist/docs/api-reference/components/puck-fields.md +39 -0
- package/dist/docs/api-reference/components/puck-layout.md +27 -0
- package/dist/docs/api-reference/components/puck-outline.md +19 -0
- package/dist/docs/api-reference/components/puck-preview.md +39 -0
- package/dist/docs/api-reference/components/puck.md +561 -0
- package/dist/docs/api-reference/components/render.md +94 -0
- package/dist/docs/api-reference/components/rich-text-menu-control.md +87 -0
- package/dist/docs/api-reference/components/rich-text-menu-group.md +27 -0
- package/dist/docs/api-reference/components/rich-text-menu.md +99 -0
- package/dist/docs/api-reference/components.md +32 -0
- package/dist/docs/api-reference/configuration/component-config.md +569 -0
- package/dist/docs/api-reference/configuration/config.md +108 -0
- package/dist/docs/api-reference/configuration.md +4 -0
- package/dist/docs/api-reference/data-model/app-state.md +168 -0
- package/dist/docs/api-reference/data-model/component-data.md +62 -0
- package/dist/docs/api-reference/data-model/data.md +95 -0
- package/dist/docs/api-reference/data-model/item-selector.md +34 -0
- package/dist/docs/api-reference/data-model/root-data.md +59 -0
- package/dist/docs/api-reference/data-model.md +8 -0
- package/dist/docs/api-reference/dictionary.md +172 -0
- package/dist/docs/api-reference/field-transforms.md +51 -0
- package/dist/docs/api-reference/fields/array.md +211 -0
- package/dist/docs/api-reference/fields/base.md +96 -0
- package/dist/docs/api-reference/fields/custom.md +193 -0
- package/dist/docs/api-reference/fields/external.md +413 -0
- package/dist/docs/api-reference/fields/number.md +132 -0
- package/dist/docs/api-reference/fields/object.md +78 -0
- package/dist/docs/api-reference/fields/radio.md +82 -0
- package/dist/docs/api-reference/fields/richtext.md +422 -0
- package/dist/docs/api-reference/fields/select.md +79 -0
- package/dist/docs/api-reference/fields/slot.md +302 -0
- package/dist/docs/api-reference/fields/text.md +93 -0
- package/dist/docs/api-reference/fields/textarea.md +93 -0
- package/dist/docs/api-reference/fields.md +16 -0
- package/dist/docs/api-reference/functions/migrate.md +204 -0
- package/dist/docs/api-reference/functions/register-overlay-portal.md +45 -0
- package/dist/docs/api-reference/functions/resolve-all-data.md +27 -0
- package/dist/docs/api-reference/functions/set-deep.md +55 -0
- package/dist/docs/api-reference/functions/transform-props.md +51 -0
- package/dist/docs/api-reference/functions/use-get-puck.md +24 -0
- package/dist/docs/api-reference/functions/use-puck.md +43 -0
- package/dist/docs/api-reference/functions/walk-tree.md +88 -0
- package/dist/docs/api-reference/functions.md +8 -0
- package/dist/docs/api-reference/overrides/action-bar.md +35 -0
- package/dist/docs/api-reference/overrides/component-overlay.md +41 -0
- package/dist/docs/api-reference/overrides/drawer-item.md +24 -0
- package/dist/docs/api-reference/overrides/drawer.md +19 -0
- package/dist/docs/api-reference/overrides/field-label.md +18 -0
- package/dist/docs/api-reference/overrides/field-types.md +51 -0
- package/dist/docs/api-reference/overrides/fields.md +19 -0
- package/dist/docs/api-reference/overrides/header-actions.md +24 -0
- package/dist/docs/api-reference/overrides/header.md +29 -0
- package/dist/docs/api-reference/overrides/iframe.md +32 -0
- package/dist/docs/api-reference/overrides/outline.md +19 -0
- package/dist/docs/api-reference/overrides/preview.md +19 -0
- package/dist/docs/api-reference/overrides/puck.md +19 -0
- package/dist/docs/api-reference/overrides.md +28 -0
- package/dist/docs/api-reference/permissions.md +55 -0
- package/dist/docs/api-reference/plugin.md +112 -0
- package/dist/docs/api-reference/plugins/blocks-plugin.md +57 -0
- package/dist/docs/api-reference/plugins/fields-plugin.md +68 -0
- package/dist/docs/api-reference/plugins/legacy-side-bar-plugin.md +54 -0
- package/dist/docs/api-reference/plugins/outline-plugin.md +57 -0
- package/dist/docs/api-reference/puck-api.md +278 -0
- package/dist/docs/api-reference/theming/action-bar.md +32 -0
- package/dist/docs/api-reference/theming/button.md +65 -0
- package/dist/docs/api-reference/theming/canvas.md +20 -0
- package/dist/docs/api-reference/theming/computed-values.md +194 -0
- package/dist/docs/api-reference/theming/drawer.md +34 -0
- package/dist/docs/api-reference/theming/fields.md +70 -0
- package/dist/docs/api-reference/theming/global.md +127 -0
- package/dist/docs/api-reference/theming/header.md +19 -0
- package/dist/docs/api-reference/theming/icon-button.md +28 -0
- package/dist/docs/api-reference/theming/outline.md +35 -0
- package/dist/docs/api-reference/theming/plugin-bar.md +24 -0
- package/dist/docs/api-reference/theming/sidebar.md +19 -0
- package/dist/docs/api-reference/theming/slot.md +27 -0
- package/dist/docs/cli.md +201 -0
- package/dist/docs/extending-puck/composition.md +54 -0
- package/dist/docs/extending-puck/custom-fields.md +133 -0
- package/dist/docs/extending-puck/field-transforms.md +89 -0
- package/dist/docs/extending-puck/internal-puck-api.md +96 -0
- package/dist/docs/extending-puck/plugins.md +159 -0
- package/dist/docs/extending-puck/theming.md +88 -0
- package/dist/docs/extending-puck/ui-overrides.md +134 -0
- package/dist/docs/getting-started.md +68 -0
- package/dist/docs/guides/migrations/dropzones-to-slots.md +138 -0
- package/dist/docs/index.json +466 -0
- package/dist/docs/index.md +37 -0
- package/dist/docs/integrating-puck/categories.md +92 -0
- package/dist/docs/integrating-puck/component-configuration.md +159 -0
- package/dist/docs/integrating-puck/data-migration.md +86 -0
- package/dist/docs/integrating-puck/dynamic-fields.md +86 -0
- package/dist/docs/integrating-puck/dynamic-props.md +137 -0
- package/dist/docs/integrating-puck/external-data-sources.md +149 -0
- package/dist/docs/integrating-puck/feature-toggling.md +121 -0
- package/dist/docs/integrating-puck/localization.md +228 -0
- package/dist/docs/integrating-puck/multi-column-layouts.md +226 -0
- package/dist/docs/integrating-puck/overlay-portals.md +25 -0
- package/dist/docs/integrating-puck/rich-text-editing.md +230 -0
- package/dist/docs/integrating-puck/root-configuration.md +171 -0
- package/dist/docs/integrating-puck/server-components.md +199 -0
- package/dist/docs/integrating-puck/styling.md +117 -0
- package/dist/docs/integrating-puck/viewports.md +75 -0
- package/dist/templates/astro/README.md +52 -0
- package/dist/templates/astro/_gitignore +24 -0
- package/dist/templates/astro/astro.config.mjs +14 -0
- package/dist/templates/astro/database.json +1 -0
- package/dist/templates/astro/package.json +25 -0
- package/dist/templates/astro/public/favicon.svg +9 -0
- package/dist/templates/astro/src/lib/pages.ts +21 -0
- package/dist/templates/astro/src/lib/resolve-puck-path.ts +19 -0
- package/dist/templates/astro/src/pages/[...puckPath].astro +25 -0
- package/dist/templates/astro/src/pages/api/pages.ts +18 -0
- package/dist/templates/astro/src/puck/editor.tsx +32 -0
- package/dist/templates/astro/src/puck/pages.ts +15 -0
- package/dist/templates/astro/src/puck/render.tsx +9 -0
- package/dist/templates/astro/src/puck.config.tsx +23 -0
- package/dist/templates/astro/tsconfig.json +14 -0
- package/dist/templates/astro-ai/README.md +64 -0
- package/dist/templates/astro-ai/_gitignore +24 -0
- package/dist/templates/astro-ai/astro.config.mjs +21 -0
- package/dist/templates/astro-ai/database.json +1 -0
- package/dist/templates/astro-ai/package.json +27 -0
- package/dist/templates/astro-ai/public/favicon.svg +9 -0
- package/dist/templates/astro-ai/src/lib/pages.ts +21 -0
- package/dist/templates/astro-ai/src/lib/resolve-puck-path.ts +19 -0
- package/dist/templates/astro-ai/src/pages/[...puckPath].astro +25 -0
- package/dist/templates/astro-ai/src/pages/api/pages.ts +18 -0
- package/dist/templates/astro-ai/src/pages/api/puck/[...all].ts +36 -0
- package/dist/templates/astro-ai/src/puck/editor.tsx +53 -0
- package/dist/templates/astro-ai/src/puck/pages.ts +15 -0
- package/dist/templates/astro-ai/src/puck/render.tsx +10 -0
- package/dist/templates/astro-ai/src/puck.config.tsx +23 -0
- package/dist/templates/astro-ai/tsconfig.json +14 -0
- package/dist/templates/express/README.md +66 -0
- package/dist/templates/express/_gitignore +16 -0
- package/dist/templates/express/database.json +1 -0
- package/dist/templates/express/package.json +20 -0
- package/dist/templates/express/src/index.ts +15 -0
- package/dist/templates/express/src/puck/pages.ts +39 -0
- package/dist/templates/express/tsconfig.json +12 -0
- package/dist/templates/express-ai/README.md +81 -0
- package/dist/templates/express-ai/_gitignore +16 -0
- package/dist/templates/express-ai/database.json +1 -0
- package/dist/templates/express-ai/package.json +22 -0
- package/dist/templates/express-ai/src/index.ts +17 -0
- package/dist/templates/express-ai/src/puck/cloud.ts +71 -0
- package/dist/templates/express-ai/src/puck/pages.ts +39 -0
- package/dist/templates/express-ai/tsconfig.json +12 -0
- package/dist/templates/hono/README.md +66 -0
- package/dist/templates/hono/_gitignore +32 -0
- package/dist/templates/hono/database.json +1 -0
- package/dist/templates/hono/package.json +20 -0
- package/dist/templates/hono/src/index.ts +21 -0
- package/dist/templates/hono/src/puck/pages.ts +32 -0
- package/dist/templates/hono/tsconfig.json +13 -0
- package/dist/templates/hono-ai/README.md +81 -0
- package/dist/templates/hono-ai/_gitignore +32 -0
- package/dist/templates/hono-ai/database.json +1 -0
- package/dist/templates/hono-ai/package.json +22 -0
- package/dist/templates/hono-ai/src/index.ts +23 -0
- package/dist/templates/hono-ai/src/puck/cloud.ts +30 -0
- package/dist/templates/hono-ai/src/puck/pages.ts +32 -0
- package/dist/templates/hono-ai/tsconfig.json +13 -0
- package/dist/templates/manifest.json +4 -0
- package/dist/templates/next/README.md +112 -0
- package/dist/templates/next/_gitignore +35 -0
- package/dist/templates/next/app/[...puckPath]/client.tsx +9 -0
- package/dist/templates/next/app/[...puckPath]/page.tsx +49 -0
- package/dist/templates/next/app/favicon.ico +0 -0
- package/dist/templates/next/app/layout.tsx +13 -0
- package/dist/templates/next/app/page.tsx +1 -0
- package/dist/templates/next/app/puck/[...puckPath]/client.tsx +20 -0
- package/dist/templates/next/app/puck/[...puckPath]/page.tsx +55 -0
- package/dist/templates/next/app/puck/api/route.ts +25 -0
- package/dist/templates/next/app/puck/page.tsx +3 -0
- package/dist/templates/next/app/styles.css +3 -0
- package/dist/templates/next/database.json +1 -0
- package/dist/templates/next/lib/get-page.ts +11 -0
- package/dist/templates/next/next.config.js +3 -0
- package/dist/templates/next/package.json +25 -0
- package/dist/templates/next/proxy.ts +27 -0
- package/dist/templates/next/puck.config.tsx +25 -0
- package/dist/templates/next/tsconfig/base.json +20 -0
- package/dist/templates/next/tsconfig/nextjs.json +21 -0
- package/dist/templates/next/tsconfig.json +8 -0
- package/dist/templates/next-ai/README.md +169 -0
- package/dist/templates/next-ai/_gitignore +35 -0
- package/dist/templates/next-ai/app/[...puckPath]/client.tsx +12 -0
- package/dist/templates/next-ai/app/[...puckPath]/page.tsx +49 -0
- package/dist/templates/next-ai/app/api/pages/route.ts +26 -0
- package/dist/templates/next-ai/app/api/puck/[...all]/route.ts +31 -0
- package/dist/templates/next-ai/app/layout.tsx +13 -0
- package/dist/templates/next-ai/app/page.tsx +1 -0
- package/dist/templates/next-ai/app/puck/[...puckPath]/client.tsx +38 -0
- package/dist/templates/next-ai/app/puck/[...puckPath]/page.tsx +57 -0
- package/dist/templates/next-ai/app/puck/page.tsx +3 -0
- package/dist/templates/next-ai/app/styles.css +3 -0
- package/dist/templates/next-ai/database.json +1 -0
- package/dist/templates/next-ai/lib/get-page.ts +11 -0
- package/dist/templates/next-ai/next.config.js +3 -0
- package/dist/templates/next-ai/package.json +27 -0
- package/dist/templates/next-ai/proxy.ts +27 -0
- package/dist/templates/next-ai/public/favicon.ico +0 -0
- package/dist/templates/next-ai/puck.config.tsx +25 -0
- package/dist/templates/next-ai/tsconfig/base.json +20 -0
- package/dist/templates/next-ai/tsconfig/nextjs.json +21 -0
- package/dist/templates/next-ai/tsconfig.json +8 -0
- package/dist/templates/react-router/README.md +113 -0
- package/dist/templates/react-router/_gitignore +6 -0
- package/dist/templates/react-router/app/components/puck-render.tsx +8 -0
- package/dist/templates/react-router/app/lib/pages.server.ts +29 -0
- package/dist/templates/react-router/app/lib/resolve-puck-path.server.ts +19 -0
- package/dist/templates/react-router/app/root.tsx +65 -0
- package/dist/templates/react-router/app/routes/_index.tsx +31 -0
- package/dist/templates/react-router/app/routes/puck-splat.tsx +95 -0
- package/dist/templates/react-router/app/routes.ts +7 -0
- package/dist/templates/react-router/database.json +1 -0
- package/dist/templates/react-router/package.json +33 -0
- package/dist/templates/react-router/public/favicon.ico +0 -0
- package/dist/templates/react-router/puck.config.tsx +23 -0
- package/dist/templates/react-router/react-router.config.ts +7 -0
- package/dist/templates/react-router/tsconfig.json +29 -0
- package/dist/templates/react-router/vite.config.ts +10 -0
- package/dist/templates/react-router-ai/README.md +172 -0
- package/dist/templates/react-router-ai/_gitignore +6 -0
- package/dist/templates/react-router-ai/app/components/puck-render.tsx +11 -0
- package/dist/templates/react-router-ai/app/lib/pages.server.ts +29 -0
- package/dist/templates/react-router-ai/app/lib/resolve-puck-path.server.ts +19 -0
- package/dist/templates/react-router-ai/app/root.tsx +65 -0
- package/dist/templates/react-router-ai/app/routes/_index.tsx +31 -0
- package/dist/templates/react-router-ai/app/routes/api.puck.ts +34 -0
- package/dist/templates/react-router-ai/app/routes/puck-splat.tsx +119 -0
- package/dist/templates/react-router-ai/app/routes.ts +8 -0
- package/dist/templates/react-router-ai/database.json +1 -0
- package/dist/templates/react-router-ai/package.json +35 -0
- package/dist/templates/react-router-ai/public/favicon.ico +0 -0
- package/dist/templates/react-router-ai/puck.config.tsx +25 -0
- package/dist/templates/react-router-ai/react-router.config.ts +7 -0
- package/dist/templates/react-router-ai/tsconfig.json +29 -0
- package/dist/templates/react-router-ai/vite.config.ts +10 -0
- package/dist/templates/tanstack-start/README.md +113 -0
- package/dist/templates/tanstack-start/_gitignore +12 -0
- package/dist/templates/tanstack-start/database.json +1 -0
- package/dist/templates/tanstack-start/package.json +26 -0
- package/dist/templates/tanstack-start/puck.config.tsx +23 -0
- package/dist/templates/tanstack-start/src/components/puck-render.tsx +8 -0
- package/dist/templates/tanstack-start/src/lib/pages.server.ts +26 -0
- package/dist/templates/tanstack-start/src/lib/pages.ts +39 -0
- package/dist/templates/tanstack-start/src/lib/resolve-puck-path.ts +19 -0
- package/dist/templates/tanstack-start/src/routeTree.gen.ts +86 -0
- package/dist/templates/tanstack-start/src/router.tsx +19 -0
- package/dist/templates/tanstack-start/src/routes/$.tsx +41 -0
- package/dist/templates/tanstack-start/src/routes/__root.tsx +42 -0
- package/dist/templates/tanstack-start/src/routes/index.tsx +18 -0
- package/dist/templates/tanstack-start/src/styles.css +13 -0
- package/dist/templates/tanstack-start/tsconfig.json +24 -0
- package/dist/templates/tanstack-start/vite.config.ts +15 -0
- package/dist/templates/tanstack-start-ai/README.md +171 -0
- package/dist/templates/tanstack-start-ai/_gitignore +12 -0
- package/dist/templates/tanstack-start-ai/database.json +1 -0
- package/dist/templates/tanstack-start-ai/package.json +28 -0
- package/dist/templates/tanstack-start-ai/puck.config.tsx +23 -0
- package/dist/templates/tanstack-start-ai/src/components/puck-render.tsx +11 -0
- package/dist/templates/tanstack-start-ai/src/lib/pages.server.ts +26 -0
- package/dist/templates/tanstack-start-ai/src/lib/pages.ts +39 -0
- package/dist/templates/tanstack-start-ai/src/lib/resolve-puck-path.ts +19 -0
- package/dist/templates/tanstack-start-ai/src/routeTree.gen.ts +104 -0
- package/dist/templates/tanstack-start-ai/src/router.tsx +19 -0
- package/dist/templates/tanstack-start-ai/src/routes/$.tsx +73 -0
- package/dist/templates/tanstack-start-ai/src/routes/__root.tsx +42 -0
- package/dist/templates/tanstack-start-ai/src/routes/api/puck/$.ts +39 -0
- package/dist/templates/tanstack-start-ai/src/routes/index.tsx +18 -0
- package/dist/templates/tanstack-start-ai/src/styles.css +13 -0
- package/dist/templates/tanstack-start-ai/tsconfig.json +24 -0
- package/dist/templates/tanstack-start-ai/vite.config.ts +15 -0
- package/dist/templates/vinext/README.md +112 -0
- package/dist/templates/vinext/_gitignore +33 -0
- package/dist/templates/vinext/app/[...puckPath]/client.tsx +9 -0
- package/dist/templates/vinext/app/[...puckPath]/page.tsx +49 -0
- package/dist/templates/vinext/app/favicon.ico +0 -0
- package/dist/templates/vinext/app/layout.tsx +13 -0
- package/dist/templates/vinext/app/page.tsx +1 -0
- package/dist/templates/vinext/app/puck/[...puckPath]/client.tsx +20 -0
- package/dist/templates/vinext/app/puck/[...puckPath]/page.tsx +55 -0
- package/dist/templates/vinext/app/puck/api/route.ts +25 -0
- package/dist/templates/vinext/app/puck/page.tsx +3 -0
- package/dist/templates/vinext/app/styles.css +3 -0
- package/dist/templates/vinext/database.json +1 -0
- package/dist/templates/vinext/lib/get-page.ts +11 -0
- package/dist/templates/vinext/package.json +30 -0
- package/dist/templates/vinext/proxy.ts +27 -0
- package/dist/templates/vinext/puck.config.tsx +25 -0
- package/dist/templates/vinext/tsconfig.json +30 -0
- package/dist/templates/vinext/vite.config.ts +6 -0
- package/dist/templates/vinext-ai/README.md +169 -0
- package/dist/templates/vinext-ai/_gitignore +33 -0
- package/dist/templates/vinext-ai/app/[...puckPath]/client.tsx +12 -0
- package/dist/templates/vinext-ai/app/[...puckPath]/page.tsx +49 -0
- package/dist/templates/vinext-ai/app/api/pages/route.ts +26 -0
- package/dist/templates/vinext-ai/app/api/puck/[...all]/route.ts +31 -0
- package/dist/templates/vinext-ai/app/layout.tsx +13 -0
- package/dist/templates/vinext-ai/app/page.tsx +1 -0
- package/dist/templates/vinext-ai/app/puck/[...puckPath]/client.tsx +38 -0
- package/dist/templates/vinext-ai/app/puck/[...puckPath]/page.tsx +57 -0
- package/dist/templates/vinext-ai/app/puck/page.tsx +3 -0
- package/dist/templates/vinext-ai/app/styles.css +3 -0
- package/dist/templates/vinext-ai/database.json +1 -0
- package/dist/templates/vinext-ai/lib/get-page.ts +11 -0
- package/dist/templates/vinext-ai/package.json +32 -0
- package/dist/templates/vinext-ai/proxy.ts +27 -0
- package/dist/templates/vinext-ai/public/favicon.ico +0 -0
- package/dist/templates/vinext-ai/puck.config.tsx +25 -0
- package/dist/templates/vinext-ai/tsconfig.json +30 -0
- package/dist/templates/vinext-ai/vite.config.ts +9 -0
- package/dist/templates/vite/README.md +56 -0
- package/dist/templates/vite/_gitignore +24 -0
- package/dist/templates/vite/database.json +1 -0
- package/dist/templates/vite/index.html +12 -0
- package/dist/templates/vite/package.json +29 -0
- package/dist/templates/vite/server/index.ts +13 -0
- package/dist/templates/vite/server/prod.ts +18 -0
- package/dist/templates/vite/server/puck/pages.ts +32 -0
- package/dist/templates/vite/src/App.tsx +11 -0
- package/dist/templates/vite/src/main.tsx +12 -0
- package/dist/templates/vite/src/puck/editor.tsx +28 -0
- package/dist/templates/vite/src/puck/page.tsx +27 -0
- package/dist/templates/vite/src/puck/pages.ts +15 -0
- package/dist/templates/vite/src/puck/root.tsx +27 -0
- package/dist/templates/vite/src/puck.config.tsx +23 -0
- package/dist/templates/vite/tsconfig.app.json +26 -0
- package/dist/templates/vite/tsconfig.json +7 -0
- package/dist/templates/vite/tsconfig.node.json +23 -0
- package/dist/templates/vite/vite.config.ts +14 -0
- package/dist/templates/vite-ai/README.md +67 -0
- package/dist/templates/vite-ai/_gitignore +24 -0
- package/dist/templates/vite-ai/database.json +1 -0
- package/dist/templates/vite-ai/index.html +12 -0
- package/dist/templates/vite-ai/package.json +31 -0
- package/dist/templates/vite-ai/server/index.ts +15 -0
- package/dist/templates/vite-ai/server/prod.ts +18 -0
- package/dist/templates/vite-ai/server/puck/cloud.ts +30 -0
- package/dist/templates/vite-ai/server/puck/pages.ts +32 -0
- package/dist/templates/vite-ai/src/App.tsx +11 -0
- package/dist/templates/vite-ai/src/main.tsx +12 -0
- package/dist/templates/vite-ai/src/puck/editor.tsx +49 -0
- package/dist/templates/vite-ai/src/puck/page.tsx +28 -0
- package/dist/templates/vite-ai/src/puck/pages.ts +15 -0
- package/dist/templates/vite-ai/src/puck/root.tsx +27 -0
- package/dist/templates/vite-ai/src/puck.config.tsx +23 -0
- package/dist/templates/vite-ai/tsconfig.app.json +26 -0
- package/dist/templates/vite-ai/tsconfig.json +7 -0
- package/dist/templates/vite-ai/tsconfig.node.json +23 -0
- package/dist/templates/vite-ai/vite.config.ts +14 -0
- package/package.json +51 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Categories
|
|
2
|
+
|
|
3
|
+
Categories allow you to group components in the left side bar.
|
|
4
|
+
|
|
5
|
+
## Creating categories
|
|
6
|
+
|
|
7
|
+
Use the [`categories` API](/docs/api-reference/configuration/config#categories) to define the component categories.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
const config = {
|
|
11
|
+
categories: {
|
|
12
|
+
typography: {
|
|
13
|
+
components: ["HeadingBlock", "ParagraphBlock"],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
// ...
|
|
17
|
+
};
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Components can appear in separate categories:
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
const config = {
|
|
24
|
+
categories: {
|
|
25
|
+
typography: {
|
|
26
|
+
components: ["HeadingBlock", "ParagraphBlock"],
|
|
27
|
+
},
|
|
28
|
+
foundational: {
|
|
29
|
+
components: ["HeadingBlock"],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
// ...
|
|
33
|
+
};
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
You can also change the title, collapse and hide categories:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
const config = {
|
|
40
|
+
categories: {
|
|
41
|
+
typography: {
|
|
42
|
+
components: ["HeadingBlock", "ParagraphBlock"],
|
|
43
|
+
title: "Text",
|
|
44
|
+
defaultExpanded: false, // Collapse this category by default
|
|
45
|
+
},
|
|
46
|
+
foundational: {
|
|
47
|
+
components: ["HeadingBlock"],
|
|
48
|
+
visible: false, // Mark this category as hidden
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
// ...
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## The "other" category
|
|
56
|
+
|
|
57
|
+
Any uncategorized components will be grouped in the `other` category. This will be visible by default. It respects the same API as other categories.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
const config = {
|
|
61
|
+
categories: {
|
|
62
|
+
typography: {
|
|
63
|
+
components: ["HeadingBlock", "ParagraphBlock"],
|
|
64
|
+
},
|
|
65
|
+
other: {
|
|
66
|
+
title: "Other components",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
// ...
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## TypeScript
|
|
74
|
+
|
|
75
|
+
You can pass in available category names to the `Config` type if using TypeScript
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import type { Config } from "@puckeditor/core";
|
|
79
|
+
|
|
80
|
+
const config: Config<{}, {}, "typography" | "interactive"> = {
|
|
81
|
+
categories: {
|
|
82
|
+
typography: {},
|
|
83
|
+
interactive: {},
|
|
84
|
+
},
|
|
85
|
+
// ...
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Further reading
|
|
90
|
+
|
|
91
|
+
- [`categories` API reference](/docs/api-reference/configuration/config#categories)
|
|
92
|
+
- [`renderComponentList` API reference](/docs/api-reference/components/puck#rendercomponentlistparams)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Component Configuration
|
|
2
|
+
|
|
3
|
+
Puck's core behaviour is configured via the [Config](/docs/api-reference/configuration/config). This describes:
|
|
4
|
+
|
|
5
|
+
- which components are available to Puck
|
|
6
|
+
- how to render each component
|
|
7
|
+
- which fields to show when the user selects a component
|
|
8
|
+
- additional information, like [category grouping](/docs/integrating-puck/categories)
|
|
9
|
+
|
|
10
|
+
The [Config](/docs/api-reference/configuration/config) is provided via the `config` prop to the main Puck components:
|
|
11
|
+
|
|
12
|
+
- [`<Puck>`](/docs/api-reference/components/puck) reads the Config and renders an editor UI. The user interacts with the editor to produce a [data payload](/docs/api-reference/data-model/data).
|
|
13
|
+
- [`<Render>`](/docs/api-reference/components/render) takes a [data payload](/docs/api-reference/data-model/data) and renders it according to the provided Config.
|
|
14
|
+
|
|
15
|
+
## The `render` function
|
|
16
|
+
|
|
17
|
+
Components can be defined via the `components` object in [Config](/docs/api-reference/configuration/config). Every definition must provide a [`render` function](/docs/api-reference/configuration/component-config#renderprops):
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
const config = {
|
|
21
|
+
components: {
|
|
22
|
+
HeadingBlock: {
|
|
23
|
+
render: () => {
|
|
24
|
+
return <h1>Hello, world</h1>;
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This tells Puck that **HeadingBlock** is a valid component, and describes how to render it.
|
|
32
|
+
|
|
33
|
+
When the user drags the component onto the preview and hits **Publish** in the editor UI via the `<Puck>` component, this Config will produce a [data payload](/docs/api-reference/data-model/data) like this:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"content": [
|
|
38
|
+
{
|
|
39
|
+
"type": "HeadingBlock",
|
|
40
|
+
"props": {
|
|
41
|
+
"id": "HeadingBlock-1234"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"root": {}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The data payload and Config together tell `<Render>` how to render the page. It can also be provided to `<Puck>` as an [initial `data` payload](/docs/api-reference/components/puck#data).
|
|
50
|
+
|
|
51
|
+
### TypeScript
|
|
52
|
+
|
|
53
|
+
If you're using TypeScript, we recommend strictly typing your config:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import type { Config } from "@puckeditor/core";
|
|
57
|
+
|
|
58
|
+
type Components = {
|
|
59
|
+
HeadingBlock: {};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const config: Config<Components> = {
|
|
63
|
+
components: {
|
|
64
|
+
HeadingBlock: {
|
|
65
|
+
render: () => {
|
|
66
|
+
return <h1>Hello, world</h1>;
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Adding fields
|
|
74
|
+
|
|
75
|
+
[Fields](/docs/api-reference/fields) allow users to provide input to components. The value of each field is passed in as a prop to the `render` function.
|
|
76
|
+
|
|
77
|
+
You can define a field via the [`fields` parameter](/docs/api-reference/configuration/component-config#fields):
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
const config = {
|
|
81
|
+
components: {
|
|
82
|
+
HeadingBlock: {
|
|
83
|
+
fields: {
|
|
84
|
+
title: {
|
|
85
|
+
type: "text",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
render: ({ title }) => {
|
|
89
|
+
return <h1>{title}</h1>;
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This will render a [Text field](/docs/api-reference/fields/text) when the user selects an instance of the **HeadingBlock** component in the editor UI.
|
|
97
|
+
|
|
98
|
+
When the user modifies the input, the editor will produce a data payload like this:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"content": [
|
|
103
|
+
{
|
|
104
|
+
"type": "HeadingBlock",
|
|
105
|
+
"props": {
|
|
106
|
+
"id": "HeadingBlock-1234",
|
|
107
|
+
"title": "Hello, world"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"root": {}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### TypeScript
|
|
116
|
+
|
|
117
|
+
It's best to define the props for the component if using TypeScript. This enables strict type checking for your fields.
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import type { Config } from "@puckeditor/core";
|
|
121
|
+
|
|
122
|
+
type Components = {
|
|
123
|
+
HeadingBlock: {
|
|
124
|
+
title: string;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const config: Config<Components> = {
|
|
129
|
+
// ...
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Setting default props
|
|
134
|
+
|
|
135
|
+
Default props allow you to set an initial value for a prop when a new component is added.
|
|
136
|
+
|
|
137
|
+
Provide an object to the [`defaultProps`](/docs/api-reference/configuration/component-config#fields) parameter to configure this:
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
const config = {
|
|
141
|
+
components: {
|
|
142
|
+
HeadingBlock: {
|
|
143
|
+
fields: {
|
|
144
|
+
title: {
|
|
145
|
+
type: "text",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
defaultProps: {
|
|
149
|
+
title: "Hello, world",
|
|
150
|
+
},
|
|
151
|
+
render: ({ title }) => {
|
|
152
|
+
return <h1>{title}</h1>;
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Unlike [default parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters), `defaultProps` are stored in the data payload and will populate the Puck fields.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Data Migration
|
|
2
|
+
|
|
3
|
+
## Version migrating
|
|
4
|
+
|
|
5
|
+
Puck follows semantic versioning. Major releases may introduce breaking changes for your Data payload.
|
|
6
|
+
|
|
7
|
+
Puck provides the [`migrate`](/docs/api-reference/functions/migrate) helper method to help migrate legacy data payloads to the latest data model, transforming any deprecated properties to their latest counterparts as described by the [Data API reference](/docs/api-reference/data-model/data).
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { migrate } from "@puckeditor/core";
|
|
11
|
+
|
|
12
|
+
migrate(legacyData);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Breaking changes to props
|
|
16
|
+
|
|
17
|
+
Renaming or removing the props passed to your components are considered breaking changes. Any existing [Data](/docs/api-reference/data-model/data) payloads that reference these props will be unable to render.
|
|
18
|
+
|
|
19
|
+
There are two strategies for dealing with this:
|
|
20
|
+
|
|
21
|
+
1. Retaining backwards-compatible props
|
|
22
|
+
2. Implementing a prop migration
|
|
23
|
+
|
|
24
|
+
### Retaining backwards-compatibility
|
|
25
|
+
|
|
26
|
+
The easiest way to avoid breaking changes is to implement your prop changes in a backwards compatible manor:
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
const config = {
|
|
30
|
+
HeadingBlock: ({ title, heading }) => <h1>{heading || title}</h1>,
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Implementing a prop migration
|
|
35
|
+
|
|
36
|
+
It will often be preferrable to update the underlying [Data](/docs/api-reference/data-model/data) payload. Puck provides the [`transformProps`](/docs/api-reference/functions/transform-props) utility method to conveniently transform the props for a given component throughout the payload.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { transformProps } from "@puckeditor/core";
|
|
40
|
+
|
|
41
|
+
const config = {
|
|
42
|
+
// Renamed `title` prop to `heading`
|
|
43
|
+
HeadingBlock: ({ heading }) => <h1>{heading}</h1>,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const data = {
|
|
47
|
+
content: [
|
|
48
|
+
// HeadingBlock references the legacy `title` prop
|
|
49
|
+
{ type: "HeadingBlock", props: { title: "Hello, world" } },
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const updatedData = transformProps(data, {
|
|
54
|
+
// Map `heading` to the legacy `title` prop
|
|
55
|
+
HeadingBlock: ({ title, ...props }) => ({ heading: title, ...props }),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
console.log(updatedData);
|
|
59
|
+
// { content: [{ type: "HeadingBlock", props: { heading: "Hello, world" } }] };
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You may choose to run this transform every time you render your content, or perform a batch operation against your database.
|
|
63
|
+
|
|
64
|
+
File: `Example showing data being updated before rendering`
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { Puck, Render, transformProps } from "@puckeditor/core";
|
|
68
|
+
|
|
69
|
+
const transforms = {
|
|
70
|
+
HeadingBlock: ({ title, ...props }) => ({ heading: title, ...props }),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const MyEditor = ({ data, config }) => (
|
|
74
|
+
<Puck data={transformProps(data, transforms)} config={config} />
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
export const MyPage = ({ data, config }) => (
|
|
78
|
+
<Render data={transformProps(data, transforms)} config={config} />
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Further reading
|
|
83
|
+
|
|
84
|
+
- [`Data` API reference](/docs/api-reference/data-model/data)
|
|
85
|
+
- [`migrate` API reference](/docs/api-reference/functions/migrate)
|
|
86
|
+
- [`transformProps` API reference](/docs/api-reference/functions/transform-props)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Dynamic Fields
|
|
2
|
+
|
|
3
|
+
Dynamic field resolution allows you to change the [field configuration](/docs/api-reference/configuration/component-config#fields) for a component based on the current component props.
|
|
4
|
+
|
|
5
|
+
## Dynamic component fields
|
|
6
|
+
|
|
7
|
+
The [`resolveFields` function](/docs/api-reference/configuration/component-config#resolvefieldsdata-params) allows you to make synchronous and asynchronous changes to the field configuration.
|
|
8
|
+
|
|
9
|
+
For example, we can set the configuration of one field based on the prop value of another:
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
const config = {
|
|
13
|
+
components: {
|
|
14
|
+
MyComponent: {
|
|
15
|
+
resolveFields: (data) => {
|
|
16
|
+
const fields = {
|
|
17
|
+
drink: {
|
|
18
|
+
type: "radio",
|
|
19
|
+
options: [
|
|
20
|
+
{ label: "Water", value: "water" },
|
|
21
|
+
{ label: "Orange juice", value: "orange-juice" },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (data.props.drink === "water") {
|
|
27
|
+
return {
|
|
28
|
+
...fields,
|
|
29
|
+
waterType: {
|
|
30
|
+
// ... Define field
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return fields;
|
|
36
|
+
},
|
|
37
|
+
// ...
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Making asynchronous calls
|
|
44
|
+
|
|
45
|
+
The [`resolveFields` function](/docs/api-reference/configuration/component-config#resolvefieldsdata-params) also enables asynchronous calls.
|
|
46
|
+
|
|
47
|
+
Here's an example populating the options for a [`select` field](/docs/api-reference/fields/select) based on a [`radio` field](/docs/api-reference/fields/radio)
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
const config = {
|
|
51
|
+
components: {
|
|
52
|
+
MyComponent: {
|
|
53
|
+
resolveFields: async (data, { changed, lastFields }) => {
|
|
54
|
+
// Don't call the API unless `category` has changed
|
|
55
|
+
if (!changed.category) return lastFields;
|
|
56
|
+
|
|
57
|
+
// Make an asynchronous API call to get the options
|
|
58
|
+
const options = await getOptions(data.category);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
category: {
|
|
62
|
+
type: "radio",
|
|
63
|
+
options: [
|
|
64
|
+
{ label: "Fruit", value: "fruit" },
|
|
65
|
+
{ label: "Vegetables", value: "vegetables" },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
item: {
|
|
69
|
+
type: "select",
|
|
70
|
+
options,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
render: ({ item }) => <h1>{item}</h1>,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Limitations
|
|
81
|
+
|
|
82
|
+
The [`slot` field](/docs/api-reference/fields/slot) is not currently supported by Dynamic Fields, but most use-cases can be achieved using [Dynamic Props](/docs/integrating-puck/dynamic-props).
|
|
83
|
+
|
|
84
|
+
## Further reading
|
|
85
|
+
|
|
86
|
+
- [`resolveFields` API reference](/docs/api-reference/configuration/component-config#resolvefieldsdata-params)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Dynamic Props
|
|
2
|
+
|
|
3
|
+
Dynamic prop resolution allows you to change the props for a component after the props have been changed by the user. This is useful for making third-party API calls, such as requesting the latest content from a headless CMS.
|
|
4
|
+
|
|
5
|
+
## Dynamic component props
|
|
6
|
+
|
|
7
|
+
The [`resolveData` function](/docs/api-reference/configuration/component-config#resolvedatadata-params) allows you to make changes to the props and set fields as read-only.
|
|
8
|
+
|
|
9
|
+
For example, we can set the value of one prop to another:
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
const config = {
|
|
13
|
+
components: {
|
|
14
|
+
HeadingBlock: {
|
|
15
|
+
fields: {
|
|
16
|
+
title: {
|
|
17
|
+
type: "text",
|
|
18
|
+
},
|
|
19
|
+
resolvedTitle: {
|
|
20
|
+
type: "text",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
resolveData: async ({ props }) => {
|
|
24
|
+
return {
|
|
25
|
+
props: {
|
|
26
|
+
resolvedTitle: props.title,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
render: ({ resolvedTitle }) => {
|
|
31
|
+
return <h1>{resolvedTitle}</h1>;
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> When inserting components with `resolveData`, the Puck state will update twice - once for the initial insert, and once more when the method resolves, if it changes the data. This will be reflected in the undo/redo history.
|
|
39
|
+
|
|
40
|
+
### Setting fields as read-only
|
|
41
|
+
|
|
42
|
+
[`resolveData`](/docs/api-reference/configuration/component-config#resolvedatadata-params) also allows us to mark fields as read-only using the [`readOnly` parameter](/docs/api-reference/configuration/component-config#datareadonly-1).
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
const config = {
|
|
46
|
+
components: {
|
|
47
|
+
HeadingBlock: {
|
|
48
|
+
// ...
|
|
49
|
+
resolveData: async ({ props }) => {
|
|
50
|
+
return {
|
|
51
|
+
props: {
|
|
52
|
+
resolvedTitle: props.title,
|
|
53
|
+
},
|
|
54
|
+
readOnly: { resolvedTitle: true },
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
// ...
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Preventing duplicate calls
|
|
64
|
+
|
|
65
|
+
It's possible that `resolveData` may carry out an expensive operation (like an API call) that we want to avoid making unless a specific prop has changed.
|
|
66
|
+
|
|
67
|
+
This can be restricted by checking the [`changed` param](/docs/api-reference/configuration/component-config#paramschanged) before calling any expensive operations.
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
const config = {
|
|
71
|
+
components: {
|
|
72
|
+
HeadingBlock: {
|
|
73
|
+
// ...
|
|
74
|
+
resolveData: async ({ props }, { changed }) => {
|
|
75
|
+
if (!changed.text) return { props };
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
props: {
|
|
79
|
+
resolvedTitle: await expensiveOperation(props.title),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
// ...
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Dynamic Root props
|
|
90
|
+
|
|
91
|
+
The `resolveData` method is also available on the [root component](/docs/api-reference/configuration/config#root).
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
const config = {
|
|
95
|
+
components: {},
|
|
96
|
+
root: {
|
|
97
|
+
fields: {
|
|
98
|
+
title: {
|
|
99
|
+
type: "text",
|
|
100
|
+
},
|
|
101
|
+
resolvedTitle: {
|
|
102
|
+
type: "text",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
resolveData: async ({ props }) => {
|
|
106
|
+
return {
|
|
107
|
+
props: {
|
|
108
|
+
resolvedTitle: props.title,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
render: ({ children, resolvedTitle }) => {
|
|
113
|
+
return (
|
|
114
|
+
<>
|
|
115
|
+
<h1>{resolvedTitle}</h1>
|
|
116
|
+
{children}
|
|
117
|
+
</>
|
|
118
|
+
);
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Triggering `resolveData`
|
|
125
|
+
|
|
126
|
+
Resolve data is triggered whenever the props for a component change, or when the [`resolveAllData` utility](/docs/api-reference/functions/resolve-all-data) is used.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { resolveAllData } from "@puckeditor/core";
|
|
130
|
+
|
|
131
|
+
const updatedData = await resolveAllData(data, config);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Further reading
|
|
135
|
+
|
|
136
|
+
- [`resolveData` API reference](/docs/api-reference/configuration/component-config#resolvedatadata-params)
|
|
137
|
+
- [`resolveAllData` API reference](/docs/api-reference/functions/resolve-all-data)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# External Data Sources
|
|
2
|
+
|
|
3
|
+
There are several different approaches for loading external data into a Puck component.
|
|
4
|
+
|
|
5
|
+
It's possible for Puck components to load their own data internally on the client, or on the server using [React server components](/docs/integrating-puck/server-components). This doesn't require any Puck configuration.
|
|
6
|
+
|
|
7
|
+
If you want to provide the user a way to select the data, you can use the [`external` field type](/docs/api-reference/fields/external).
|
|
8
|
+
|
|
9
|
+
## Selecting external data
|
|
10
|
+
|
|
11
|
+
The [`external` field type](/docs/api-reference/fields/external) allows users to select tabular data from a third-party data source, like a headless CMS. This will load the data once and save it into the [data payload](/docs/api-reference/data-model/data).
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
const config = {
|
|
15
|
+
components: {
|
|
16
|
+
Example: {
|
|
17
|
+
fields: {
|
|
18
|
+
data: {
|
|
19
|
+
type: "external",
|
|
20
|
+
fetchList: async () => {
|
|
21
|
+
// Query an API for a list of items
|
|
22
|
+
const items = await fetch(`/api/items`).then((res) => res.json());
|
|
23
|
+
// [
|
|
24
|
+
// { title: "Hello, world", description: "Lorem ipsum 1" },
|
|
25
|
+
// { title: "Goodbye, world", description: "Lorem ipsum 2" },
|
|
26
|
+
// ];
|
|
27
|
+
|
|
28
|
+
return items;
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
render: ({ data }) => {
|
|
33
|
+
if (!data) {
|
|
34
|
+
return "No data selected";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
<b>{data.title}</b>
|
|
40
|
+
<p>{data.description}</p>
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You can also use the [`showSearch` parameter](/docs/api-reference/fields/external#showsearch) to show a search input to the user.
|
|
50
|
+
|
|
51
|
+
## Data syncing
|
|
52
|
+
|
|
53
|
+
To keep the data in sync with the external source, we can combine the `external` field with the [`resolveData`](/docs/api-reference/configuration/component-config#resolvedatadata-params) function.
|
|
54
|
+
|
|
55
|
+
This technique re-fetches the content every time the page is loaded, or the [`resolveAllData` utility](/docs/api-reference/functions/resolve-all-data) is called.
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
const config = {
|
|
59
|
+
components: {
|
|
60
|
+
Example: {
|
|
61
|
+
fields: {
|
|
62
|
+
data: {
|
|
63
|
+
type: "external",
|
|
64
|
+
fetchList: async () => {
|
|
65
|
+
// Query an API for a list of items
|
|
66
|
+
const items = await fetch(`/api/items`).then((res) => res.json());
|
|
67
|
+
// [
|
|
68
|
+
// { title: "Hello, world", id: 0 },
|
|
69
|
+
// { title: "Goodbye, world", id: 1 },
|
|
70
|
+
// ];
|
|
71
|
+
|
|
72
|
+
return items;
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
resolveData: async ({ props }, { changed }) => {
|
|
77
|
+
if (!props.data) return { props };
|
|
78
|
+
|
|
79
|
+
// Don't query unless `data` has changed since resolveData was last run
|
|
80
|
+
if (!changed.data) return { props };
|
|
81
|
+
|
|
82
|
+
// Re-query the API for a particular item
|
|
83
|
+
const latestData = await fetch(`/api/items/${props.data.id}`).then(
|
|
84
|
+
(res) => res.json()
|
|
85
|
+
);
|
|
86
|
+
// { title: "Hello, world", description: "Lorem ipsum 1", id: 0 }
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
props: {
|
|
90
|
+
// Update the value for `data`
|
|
91
|
+
data: latestData,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
// ...
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Hybrid authoring
|
|
102
|
+
|
|
103
|
+
Hybrid authoring enables users to edit fields inline, or populate those fields with data from an external source.
|
|
104
|
+
|
|
105
|
+
This can be achieved by mapping the data from `data.title` to `title` in [`resolveData`](/docs/api-reference/configuration/component-config#resolvedatadata-params), and marking the field as read-only.
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
const config = {
|
|
109
|
+
components: {
|
|
110
|
+
Example: {
|
|
111
|
+
fields: {
|
|
112
|
+
data: {
|
|
113
|
+
// ...
|
|
114
|
+
},
|
|
115
|
+
title: {
|
|
116
|
+
type: "text",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
resolveData: async ({ props }, { changed }) => {
|
|
120
|
+
// Remove read-only from the title field if `data` is empty
|
|
121
|
+
if (!props.data) return { props, readOnly: { title: false } };
|
|
122
|
+
|
|
123
|
+
// Don't query unless `data` has changed since resolveData was last run
|
|
124
|
+
if (!changed.data) return { props };
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
props: {
|
|
128
|
+
title: props.data.title,
|
|
129
|
+
readOnly: { title: true },
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
render: ({ title }) => <b>{title}</b>,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## External data packages
|
|
140
|
+
|
|
141
|
+
We provide helper packages to load data from common data sources.
|
|
142
|
+
|
|
143
|
+
- [`contentful`](https://github.com/puckeditor/puck/tree/main/packages/field-contentful): Select content entries from a [Contentful](https://www.contentful.com) space.
|
|
144
|
+
|
|
145
|
+
## Further reading
|
|
146
|
+
|
|
147
|
+
- [`external` field API reference](/docs/api-reference/fields/external)
|
|
148
|
+
- [`resolveData` API reference](/docs/api-reference/configuration/component-config#resolvedatadata-params)
|
|
149
|
+
- [`resolveAllData` API reference](/docs/api-reference/functions/resolve-all-data)
|