The `<Designer />` component is designed to be unopinionated about state management, making it easy to build multi-page editors. 

The following example demonstrates how to implement a page-based workflow with persistent storage. Each page maintains its own set of layers, and you can seamlessly switch between pages using custom actions.

## Pages

We define a `Page` type to represent each page in the editor. A page has an `id`, a `name`, and a `layers` array.

```tsx
type Page = {
  id: string
  name: string
  layers: Layer[]
}
```

We use Jotai to manage the state of the editor. We define a `pagesAtom` to store the list of pages, and a `selectedPageIdAtom` to store the ID of the currently selected page.

```tsx
const INITIAL_PAGES = [
  {
    id: "1",
    name: "Page 1",
    layers: [],
  },
]

const pagesAtom = atomWithStorage<Page[]>("pages", INITIAL_PAGES)
const selectedPageIdAtom = atomWithStorage<string>("selectedPageId", INITIAL_PAGES[0].id)
```

## Designer

The `<Designer />` component is used to create the editor. We use the `layers` prop to pass the layers for the currently selected page and the `onLayersChange` prop to update the layers for the currently selected page.

```tsx
export function CustomDesigner() {
  return (
    <Designer layers={selectedPage?.layers} onLayersChange={handleLayersChange}>
      <DesignerContent>
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
      </DesignerContent>
      <DesignerToolbar>
    </Designer>
  )
}
```

## ActionPageSelector

```tsx
function ActionPageSelector() {
  const [pages] = useAtom(pageAtom)
  const [selectedPageId, setSelectedPageId] = useAtom(selectedPageIdAtom)

  return (
    <Action>
      <ActionLabel htmlFor="page-selector" className="sr-only">
        Page
      </ActionLabel>
      <ActionControls>
        <Select value={selectedPageId} onValueChange={setSelectedPageId}>
          <SelectTrigger>
            <SelectValue placeholder="Select a page" />
            <SelectContent>
              {pages.map((page) => (
                <SelectItem key={page.id} value={page.id}>
                  {page.name}
                </SelectItem>
              ))}
            </SelectContent>
          </SelectTrigger>
        </Select>
      </ActionControls>
    </Action>
  )
}
```

## ActionAddPage

```tsx
function ActionAddPage() {
  const [pages, setPages] = useAtom(pageAtom)
  const [, setSelectedPageId] = useAtom(selectedPageIdAtom)

  return (
    <Button
      variant="ghost"
      onClick={() => {
        const newPage = {
          id: `page-${pages.length + 1}`,
          name: `Page ${pages.length + 1}`,
          layers: [],
        }
        setPages([...pages, newPage])
        setSelectedPageId(newPage.id)
      }}
    >
      <IconPlus />
      Add Page
    </Button>
  )
}
```

## ActionReset

```tsx
function ActionReset() {
  const [, setPages] = useAtom(pageAtom)
  const [, setSelectedPageId] = useAtom(selectedPageIdAtom)

  return (
    <Button
      variant="outline"
      onClick={() => {
        setPages(INITIAL_PAGES)
        setSelectedPageId("1")
      }}
    >
      Reset
    </Button>
  )
}
```

## ActionExportPages

```tsx
function ActionExportPages() {
  const [pages] = useAtom(pageAtom)

  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="primary">Export</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>View JSON</DialogTitle>
          <DialogDescription>
            Here's the JSON representation of the current pages.
          </DialogDescription>
        </DialogHeader>
        <div className="max-h-[50vh] overflow-y-auto rounded-md border bg-black p-2 font-mono text-white text-xs">
          <pre>{JSON.stringify(pages, null, 2)}</pre>
        </div>
        <DialogFooter>
          <DialogClose asChild>
            <Button>Close</Button>
          </DialogClose>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
```