diff --git a/README.md b/README.md index a932ca0d9d..156c458ad9 100644 --- a/README.md +++ b/README.md @@ -86,19 +86,19 @@ Puck can be configured to work with plugins. Plugins can extend the functionalit The plugin API follows a React paradigm. Each plugin passed to the Puck editor can provide three functions: -- `renderPage` (`Component`): Render the root node of the preview content -- `renderPageFields` (`Component`): Render the page fields +- `renderRoot` (`Component`): Render the root node of the preview content +- `renderRootFields` (`Component`): Render the root fields - `renderFields` (`Component`): Render the fields for the currently selected component -Each render function receives the `children` prop, which you should render to show the page or fields, and the `data` prop, which can be used to read the data model for the page. +Each render function receives the `children` prop, which you must render, and the `data` prop, which can be used to read the data model. #### Example -Here's a basic plugin that renders a "My plugin" heading in the page field area: +Here's a basic plugin that renders a "My plugin" heading in the root field area: ```jsx const myPlugin = { - renderPageFields: (props) => ( + renderRootFields: (props) => (
{props.children} @@ -123,7 +123,7 @@ The `` component renders the Puck editor. ### `` -The `` component renders a user-facing page using Puck data. +The `` component renders user-facing UI using Puck data. - **config** (`Config`): Puck component configuration - **data** (`Data`): Data to render @@ -132,10 +132,10 @@ The `` component renders a user-facing page using Puck data. The `Config` object describes which components Puck should render, how they should render and which inputs are available to them. -- **page** (`object`) +- **root** (`object`) - **fields** (`object`): - - **title** (`Field`): A mandatory field for the page title. - - **[fieldName]** (`Field`): User defined fields, used to describe the input data stored in the `page` key. + - **title** (`Field`): Title of the content, typically used for the page title. + - **[fieldName]** (`Field`): User defined fields, used to describe the input data stored in the `root` key. - **render** (`Component`): Render a React component at the root of your component tree. Useful for defining context providers. - **components** (`object`): Definitions for each of the components you want to show in the visual editor - **[componentName]** (`object`) @@ -161,11 +161,11 @@ A `Field` represents a user input field shown in the Puck interface. ### `Data` -The `Data` object stores the state of a page. +The `Data` object stores the puck state. -- **page** (`object`): - - **title** (string): Page title - - **[prop]** (string): User defined data from page fields +- **root** (`object`): + - **title** (string): Title of the content, typically used for the page title + - **[prop]** (string): User defined data from `root` fields - **content** (`object[]`): - **type** (string): Component name - **props** (object): @@ -184,8 +184,8 @@ An `Adaptor` can be used to load content from an external content repository, li Plugins that can be used to enhance Puck. -- **renderPage** (`Component`): Render the root node of the preview content -- **renderPageFields** (`Component`): Render the page fields +- **renderRoot** (`Component`): Render the root node of the preview content +- **renderRootFields** (`Component`): Render the root fields - **renderFields** (`Component`): Render the fields for the currently selected component ## License diff --git a/apps/demo/app/[framework]/[...puckPath]/client.tsx b/apps/demo/app/[framework]/[...puckPath]/client.tsx index 7fae26f5ed..0a92e74ae1 100644 --- a/apps/demo/app/[framework]/[...puckPath]/client.tsx +++ b/apps/demo/app/[framework]/[...puckPath]/client.tsx @@ -38,9 +38,9 @@ export function Client({ useEffect(() => { if (!isEdit) { - document.title = data?.page?.title || ""; + document.title = data?.root?.title || ""; } - }, [data]); + }, [data, isEdit]); if (isEdit) { return ( diff --git a/apps/demo/app/configs/antd/index.tsx b/apps/demo/app/configs/antd/index.tsx index dd7f3451a2..5f126bbbd3 100644 --- a/apps/demo/app/configs/antd/index.tsx +++ b/apps/demo/app/configs/antd/index.tsx @@ -14,7 +14,7 @@ type Props = { // We avoid the name config as next gets confused export const conf: Config = { - page: { + root: { fields: { title: { type: "text", @@ -59,7 +59,7 @@ export const initialData: Record = { }, }, ], - page: { title: "Home", layout: "" }, + root: { title: "Home", layout: "" }, }, "/about": { content: [ @@ -72,7 +72,7 @@ export const initialData: Record = { }, }, ], - page: { title: "About us", layout: "" }, + root: { title: "About us", layout: "" }, }, }; diff --git a/apps/demo/app/configs/custom/index.tsx b/apps/demo/app/configs/custom/index.tsx index 6cced24224..c7ed8b1fde 100644 --- a/apps/demo/app/configs/custom/index.tsx +++ b/apps/demo/app/configs/custom/index.tsx @@ -23,7 +23,7 @@ type Props = { // We avoid the name config as next gets confused export const conf: Config = { - page: { + root: { render: Root, }, components: { @@ -302,15 +302,15 @@ export const initialData: Record = { props: { size: "96px", id: "VerticalSpace-1687284290127" }, }, ], - page: { title: "Custom Example" }, + root: { title: "Custom Example" }, }, "/pricing": { content: [], - page: { title: "Pricing" }, + root: { title: "Pricing" }, }, "/about": { content: [], - page: { title: "About Us" }, + root: { title: "About Us" }, }, }; diff --git a/apps/demo/app/configs/custom/root.tsx b/apps/demo/app/configs/custom/root.tsx index 3df18befe2..ddcc8a240c 100644 --- a/apps/demo/app/configs/custom/root.tsx +++ b/apps/demo/app/configs/custom/root.tsx @@ -1,12 +1,12 @@ import { ReactNode } from "react"; -import { DefaultPageProps } from "@measured/puck/types/Config"; +import { DefaultRootProps } from "@measured/puck/types/Config"; import { Footer } from "./components/Footer"; export type RootProps = { children: ReactNode; title: string; -} & DefaultPageProps; +} & DefaultRootProps; const NavItem = ({ label, href }: { label: string; href: string }) => { const navPath = window.location.pathname.replace("/edit", "") || "/"; diff --git a/apps/demo/app/configs/material-ui/index.tsx b/apps/demo/app/configs/material-ui/index.tsx index 12627508ab..bf0644cf18 100644 --- a/apps/demo/app/configs/material-ui/index.tsx +++ b/apps/demo/app/configs/material-ui/index.tsx @@ -19,7 +19,7 @@ type Props = { // We avoid the name config as next gets confused export const conf: Config = { - page: { + root: { fields: { title: { type: "text", @@ -140,7 +140,7 @@ export const initialData: Record = { }, }, ], - page: { title: "MUI Demo" }, + root: { title: "MUI Demo" }, }, }; diff --git a/packages/core/components/Puck/index.tsx b/packages/core/components/Puck/index.tsx index 70a4789039..7299d93d08 100644 --- a/packages/core/components/Puck/index.tsx +++ b/packages/core/components/Puck/index.tsx @@ -38,7 +38,7 @@ const PluginRenderer = ({ children: ReactNode; data: Data; plugins; - renderMethod: "renderPage" | "renderPageFields" | "renderFields"; + renderMethod: "renderRoot" | "renderRootFields" | "renderFields"; }) => { return plugins .filter((item) => item[renderMethod]) @@ -51,7 +51,7 @@ const PluginRenderer = ({ export function Puck({ config, - data: initialData = { content: [], page: { title: "" } }, + data: initialData = { content: [], root: { title: "" } }, onChange, onPublish, plugins = [], @@ -75,22 +75,22 @@ export function Puck({ (pageProps) => ( - {config.page?.render - ? config.page?.render({ ...pageProps, editMode: true }) + {config.root?.render + ? config.root?.render({ ...pageProps, editMode: true }) : pageProps.children} ), - [config.page] + [config.root] ); const PageFieldWrapper = useCallback( (props) => ( {props.children} @@ -115,7 +115,7 @@ export function Puck({ const FieldWrapper = selectedIndex !== null ? ComponentFieldWrapper : PageFieldWrapper; - const pageFields = config.page?.fields || defaultPageFields; + const rootFields = config.root?.fields || defaultPageFields; let fields = selectedIndex !== null @@ -123,7 +123,7 @@ export function Puck({ string, Field >) || {} - : pageFields; + : rootFields; useEffect(() => { if (onChange) onChange(data); @@ -298,7 +298,7 @@ export function Puck({ zoom: 0.75, }} > - + {(provided, snapshot) => (
-1 + data.root._meta?.locked?.indexOf(fieldName) > -1 } - value={data.page[fieldName]} + value={data.root[fieldName]} onChange={onChange} /> ); diff --git a/packages/core/components/Render/index.tsx b/packages/core/components/Render/index.tsx index ec2c2f320c..d399c43219 100644 --- a/packages/core/components/Render/index.tsx +++ b/packages/core/components/Render/index.tsx @@ -9,11 +9,11 @@ export function Render({ config, data }: { config: Config; data: Data }) { return ; }); - if (config.page) { + if (config.root) { return ( - + {children} - + ); } diff --git a/packages/core/types/Config.tsx b/packages/core/types/Config.tsx index 79746bca9c..910e5775a3 100644 --- a/packages/core/types/Config.tsx +++ b/packages/core/types/Config.tsx @@ -33,7 +33,7 @@ export type Field< }[]; }; -export type DefaultPageProps = { +export type DefaultRootProps = { children: ReactNode; title: string; editMode: boolean; @@ -61,12 +61,12 @@ export type ComponentConfig< export type Config< Props extends { [key: string]: any } = { [key: string]: any }, - PageProps extends DefaultPageProps = DefaultPageProps + RootProps extends DefaultRootProps = DefaultRootProps > = { components: { [ComponentName in keyof Props]: ComponentConfig; }; - page?: ComponentConfig; + root?: ComponentConfig; }; type MappedItem = @@ -79,11 +79,11 @@ type MappedItem = export type Data< Props extends { [key: string]: any } = { [key: string]: any }, - PageProps extends { title: string; [key: string]: any } = { + RootProps extends { title: string; [key: string]: any } = { title: string; [key: string]: any; } > = { - page: PageProps; + root: RootProps; content: MappedItem[]; }; diff --git a/packages/core/types/Plugin.ts b/packages/core/types/Plugin.ts index da0687c1e7..980ec4e6aa 100644 --- a/packages/core/types/Plugin.ts +++ b/packages/core/types/Plugin.ts @@ -2,11 +2,11 @@ import { ReactElement, ReactNode } from "react"; import { Data } from "./Config"; export type Plugin = { - renderPageFields?: (props: { + renderRootFields?: (props: { children: ReactNode; data: Data; }) => ReactElement; - renderPage?: (props: { + renderRoot?: (props: { children: ReactNode; data: Data; }) => ReactElement; diff --git a/packages/plugin-heading-analyzer/src/HeadingAnalyzer.tsx b/packages/plugin-heading-analyzer/src/HeadingAnalyzer.tsx index 543be95f66..95cb883f04 100644 --- a/packages/plugin-heading-analyzer/src/HeadingAnalyzer.tsx +++ b/packages/plugin-heading-analyzer/src/HeadingAnalyzer.tsx @@ -195,7 +195,7 @@ const HeadingOutlineAnalyer = ({ }; const HeadingAnalyzer: Plugin = { - renderPageFields: HeadingOutlineAnalyer, + renderRootFields: HeadingOutlineAnalyer, }; export default HeadingAnalyzer;