Skip to content

Commit

Permalink
feat: allow data prop to accept an empty object
Browse files Browse the repository at this point in the history
This is a long-standing API tidy-up to enable partial Data objects to be provided to Puck for easier instantiation.
  • Loading branch information
chrisvxd committed Apr 24, 2024
1 parent 480467a commit aedd401
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 34 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ const config = {
};

// Describe the initial data
const initialData = {
content: [],
root: {},
};
const initialData = {};

// Save the data to your database
const save = (data) => {};
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/pages/docs/api-reference/components/puck.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function Editor() {
| Param | Example | Type | Status |
| ------------------------------- | -------------------------------------- | -------------------------------------------------- | ------------ |
| [`config`](#config) | `config: { components: {} }` | [Config](/docs/api-reference/configuration/config) | Required |
| [`data`](#data) | `data: { content: [], root: {} }` | [Data](/docs/api-reference/data) | Required |
| [`data`](#data) | `data: {}` | [Data](/docs/api-reference/data) | Required |
| [`dnd`](#dnd) | `dnd: {}` | [DndConfig](#dnd-params) | - |
| [`children`](#children) | `children: <Puck.Preview />` | ReactNode | - |
| [`headerPath`](#headerpath) | `headerPath: "/my-page"` | String | - |
Expand Down
8 changes: 4 additions & 4 deletions apps/docs/pages/docs/api-reference/components/render.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export function Example() {

## Props

| Param | Example | Type | Status |
| ------------------- | --------------------------------- | ------------------------------------ | -------- |
| [`config`](#config) | `config: { components: {} }` | [Config](/docs/api-reference/config) | Required |
| [`data`](#data) | `data: { content: [], root: {} }` | [Data](/docs/api-reference/data) | Required |
| Param | Example | Type | Status |
| ------------------- | ---------------------------- | ------------------------------------ | -------- |
| [`config`](#config) | `config: { components: {} }` | [Config](/docs/api-reference/config) | Required |
| [`data`](#data) | `data: {}` | [Data](/docs/api-reference/data) | Required |

## Required props

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ This is useful if you need to run your resolvers before passing your data to [`<

## Args

| Param | Example | Type |
| -------- | --------------------------- | -------------------------------------------------- |
| `data` | `{ content: {}, root: {} }` | [Data](/docs/api-reference/data) |
| `config` | `{ components: {} }` | [Config](/docs/api-reference/configuration/config) |
| Param | Example | Type |
| -------- | -------------------- | -------------------------------------------------- |
| `data` | `{}` | [Data](/docs/api-reference/data) |
| `config` | `{ components: {} }` | [Config](/docs/api-reference/configuration/config) |

## Returns

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ console.log(updatedData);

| Param | Example | Type |
| ------------ | -------------------------------------- | -------------------------------- |
| `data` | `{ content: {}, root: {} }` | [Data](/docs/api-reference/data) |
| `data` | `{}` | [Data](/docs/api-reference/data) |
| `transforms` | `{ HeadingBlock: (props) => (props) }` | Object |

### `data`
Expand Down
5 changes: 1 addition & 4 deletions apps/docs/pages/docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ const config = {
};

// Describe the initial data
const initialData = {
content: [],
root: {},
};
const initialData = {};

// Save the data to your database
const save = (data) => {};
Expand Down
5 changes: 3 additions & 2 deletions packages/core/components/Puck/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function Puck<UserConfig extends Config = Config>({
}: {
children?: ReactNode;
config: UserConfig;
data: Data;
data: Partial<Data>;
ui?: Partial<UiState>;
onChange?: (data: Data) => void;
onPublish?: (data: Data) => void;
Expand Down Expand Up @@ -147,7 +147,7 @@ export function Puck<UserConfig extends Config = Config>({
}

// DEPRECATED
const rootProps = initialData.root.props || initialData.root;
const rootProps = initialData?.root?.props || initialData.root || {};

const defaultedRootProps = {
...config.root?.defaultProps,
Expand All @@ -159,6 +159,7 @@ export function Puck<UserConfig extends Config = Config>({
data: {
...initialData,
root: defaultedRootProps,
content: initialData.content || [],
},
ui: {
...initial,
Expand Down
14 changes: 10 additions & 4 deletions packages/core/components/Render/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@ export function Render<UserConfig extends Config = Config>({
data,
}: {
config: UserConfig;
data: Data;
data: Partial<Data>;
}) {
const defaultedData = {
...data,
root: data.root || {},
content: data.content || [],
};

// DEPRECATED
const rootProps = data.root.props || data.root;
const rootProps = defaultedData.root.props || defaultedData.root;
const title = rootProps?.title || "";

if (config.root?.render) {
return (
<DropZoneProvider value={{ data, config, mode: "render" }}>
<DropZoneProvider value={{ data: defaultedData, config, mode: "render" }}>
<config.root.render
{...rootProps}
puck={{
Expand All @@ -34,7 +40,7 @@ export function Render<UserConfig extends Config = Config>({
}

return (
<DropZoneProvider value={{ data, config, mode: "render" }}>
<DropZoneProvider value={{ data: defaultedData, config, mode: "render" }}>
<DropZone zone={rootDroppableId} />
</DropZoneProvider>
);
Expand Down
7 changes: 7 additions & 0 deletions packages/core/lib/default-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Data } from "../types/Config";

export const defaultData = (data: Partial<Data>) => ({
...data,
root: data.root || {},
content: data.content || [],
});
11 changes: 7 additions & 4 deletions packages/core/lib/resolve-all-data.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Config, Data, MappedItem } from "../types/Config";
import { resolveAllComponentData } from "./resolve-component-data";
import { resolveRootData } from "./resolve-root-data";
import { defaultData } from "./default-data";

export async function resolveAllData(
data: Data,
data: Partial<Data>,
config: Config,
onResolveStart?: (item: MappedItem) => void,
onResolveEnd?: (item: MappedItem) => void
) {
const dynamicRoot = await resolveRootData(data, config);
const defaultedData = defaultData(data);

const dynamicRoot = await resolveRootData(defaultedData, config);

const { zones = {} } = data;

Expand All @@ -26,10 +29,10 @@ export async function resolveAllData(
}

return {
...data,
...defaultedData,
root: dynamicRoot,
content: await resolveAllComponentData(
data.content,
defaultedData.content,
config,
onResolveStart,
onResolveEnd
Expand Down
15 changes: 9 additions & 6 deletions packages/core/lib/transform-props.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Data, DefaultComponentProps, DefaultRootProps } from "../types/Config";
import { defaultData } from "./default-data";

type PropTransform<
Props extends DefaultComponentProps = DefaultComponentProps,
Expand All @@ -14,7 +15,7 @@ type PropTransform<
export function transformProps<
Props extends DefaultComponentProps = DefaultComponentProps,
RootProps extends DefaultComponentProps = DefaultComponentProps
>(data: Data, propTransforms: PropTransform<Props, RootProps>): Data {
>(data: Partial<Data>, propTransforms: PropTransform<Props, RootProps>): Data {
const mapItem = (item) => {
if (propTransforms[item.type]) {
return {
Expand All @@ -26,21 +27,23 @@ export function transformProps<
return item;
};

const defaultedData = defaultData(data);

// DEPRECATED
const rootProps = data.root.props || data.root;
let newRoot = { ...data.root };
const rootProps = defaultedData.root.props || defaultedData.root;
let newRoot = { ...defaultedData.root };
if (propTransforms["root"]) {
if (data.root.props) {
if (defaultedData.root.props) {
newRoot.props = propTransforms["root"](rootProps as any);
} else {
newRoot = propTransforms["root"](rootProps as any);
}
}

const afterPropTransforms: Data = {
...data,
...defaultedData,
root: newRoot,
content: data.content.map(mapItem),
content: defaultedData.content.map(mapItem),
zones: Object.keys(data.zones || {}).reduce(
(acc, zoneKey) => ({
...acc,
Expand Down

0 comments on commit aedd401

Please sign in to comment.