Skip to content

Commit

Permalink
feat: add initialHistories prop to Puck
Browse files Browse the repository at this point in the history
  • Loading branch information
mkilpatrick committed Jun 13, 2024
1 parent 0daf478 commit 54b5a87
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 20 deletions.
50 changes: 35 additions & 15 deletions apps/docs/pages/docs/api-reference/components/puck.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,22 @@ export function Editor() {

## Props

| Param | Example | Type | Status |
| ------------------------------- | -------------------------------------- | -------------------------------------------------- | ------------ |
| [`config`](#config) | `config: { components: {} }` | [Config](/docs/api-reference/configuration/config) | 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 | - |
| [`headerTitle`](#headertitle) | `headerTitle: "My Page"` | String | - |
| [`iframe`](#iframe) | `iframe: {}` | [IframeConfig](#iframe-params) | - |
| [`onChange()`](#onchangedata) | `onChange: (data) => {}` | Function | - |
| [`onPublish()`](#onpublishdata) | `onPublish: async (data) => {}` | Function | - |
| [`overrides`](#overrides) | `overrides: { header: () => <div /> }` | [Overrides](/docs/api-reference/overrides) | Experimental |
| [`plugins`](#plugins) | `plugins: [myPlugin]` | [Plugin\[\]](/docs/api-reference/plugin) | Experimental |
| [`ui`](#ui) | `ui: {leftSideBarVisible: false}` | [AppState.ui](/docs/api-reference/app-state#ui) | - |
| [`viewports`](#viewports) | `viewports: [{ width: 1440 }]` | [Viewport\[\]](#viewport-params) | - |
| Param | Example | Type | Status |
| --------------------------------------- | ------------------------------------------------- | -------------------------------------------------- | ------------ |
| [`config`](#config) | `config: { components: {} }` | [Config](/docs/api-reference/configuration/config) | 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 | - |
| [`headerTitle`](#headertitle) | `headerTitle: "My Page"` | String | - |
| [`iframe`](#iframe) | `iframe: {}` | [IframeConfig](#iframe-params) | - |
| [`initialHistories`](#initialHistories) | `initialHistories: [{ histories: [], index: 0 }]` | [Viewport\[\]](#initialHistories-params) | - |
| [`onChange()`](#onchangedata) | `onChange: (data) => {}` | Function | - |
| [`onPublish()`](#onpublishdata) | `onPublish: async (data) => {}` | Function | - |
| [`overrides`](#overrides) | `overrides: { header: () => <div /> }` | [Overrides](/docs/api-reference/overrides) | Experimental |
| [`plugins`](#plugins) | `plugins: [myPlugin]` | [Plugin\[\]](/docs/api-reference/plugin) | Experimental |
| [`ui`](#ui) | `ui: {leftSideBarVisible: false}` | [AppState.ui](/docs/api-reference/app-state#ui) | - |
| [`viewports`](#viewports) | `viewports: [{ width: 1440 }]` | [Viewport\[\]](#viewport-params) | - |

## Required props

Expand Down Expand Up @@ -181,6 +182,25 @@ Render the Puck preview within iframe. Defaults to `true`.

Disabling iframes will also disable [viewports](#viewports).

### `initialHistories`

Sets the undo/redo Puck history state.

#### InitialHistories params

| Param | Example | Type | Status |
| ------------------------- | --------------- | ------- | -------- |
| [`histories`](#histories) | `histories: []` | History | Required |
| [`index`](#index) | `index: 2` | number | Required |

##### `histories`

An array of histories to reset the Puck state history state to.

##### `index`

The index of the histories to set the user to.

### `onChange(data)`

Callback that triggers when the user makes a change.
Expand Down
9 changes: 7 additions & 2 deletions packages/core/components/Puck/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { Outline } from "./components/Outline";
import { Overrides } from "../../types/Overrides";
import { loadOverrides } from "../../lib/load-overrides";
import { usePuckHistory } from "../../lib/use-puck-history";
import { useHistoryStore } from "../../lib/use-history-store";
import { useHistoryStore, type History } from "../../lib/use-history-store";
import { Canvas } from "./components/Canvas";
import { defaultViewports } from "../ViewportControls/default-viewports";
import { Viewports } from "../../types/Viewports";
Expand Down Expand Up @@ -69,6 +69,7 @@ export function Puck<UserConfig extends Config = Config>({
enabled: true,
},
dnd,
initialHistories,
}: {
children?: ReactNode;
config: UserConfig;
Expand All @@ -94,8 +95,12 @@ export function Puck<UserConfig extends Config = Config>({
dnd?: {
disableAutoScroll?: boolean;
};
initialHistories?: {
histories: History<any>[];
index: number;
};
}) {
const historyStore = useHistoryStore();
const historyStore = useHistoryStore(initialHistories);

const [reducer] = useState(() =>
createReducer<UserConfig>({ config, record: historyStore.record })
Expand Down
23 changes: 23 additions & 0 deletions packages/core/lib/__tests__/use-history-store.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,26 @@ describe("use-history-store", () => {
expect(renderedHook.result.current.currentHistory.data).toBe("Banana");
});
});

describe("use-history-store-prefilled", () => {
let renderedHook: RenderHookResult<ReturnType<typeof useHistoryStore>, any>;

beforeEach(() => {
renderedHook = renderHook(() =>
useHistoryStore({
histories: [
{ id: "0", data: {} },
{ id: "1", data: {} },
{ id: "2", data: {} },
],
index: 2,
})
);
});

test("should have the correct initial state", () => {
expect(renderedHook.result.current.hasPast).toBe(true);
expect(renderedHook.result.current.hasFuture).toBe(false);
expect(renderedHook.result.current.histories.length).toBe(3);
});
});
13 changes: 10 additions & 3 deletions packages/core/lib/use-history-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,17 @@ export type HistoryStore<D = any> = {

const EMPTY_HISTORY_INDEX = -1;

export function useHistoryStore<D = any>(): HistoryStore<D> {
const [histories, setHistories] = useState<History<D>[]>([]);
export function useHistoryStore<D = any>(initialHistories?: {
histories: History<any>[];
index: number;
}): HistoryStore<D> {
const [histories, setHistories] = useState<History<D>[]>(
initialHistories?.histories ?? []
);

const [index, setIndex] = useState(EMPTY_HISTORY_INDEX);
const [index, setIndex] = useState(
initialHistories?.index ?? EMPTY_HISTORY_INDEX
);

const hasPast = index > EMPTY_HISTORY_INDEX;
const hasFuture = index < histories.length - 1;
Expand Down

0 comments on commit 54b5a87

Please sign in to comment.