Most custom designer UI is built from a small set of hooks. The full
[hooks reference](/docs/reference/hooks) lists everything, but this page covers
the hooks that usually matter first when you are wiring up toolbars, panes,
custom controls, and document actions.

## Reading the document

Use these hooks when your UI needs to reflect the current document or selection.

| Hook | Use it for |
| --- | --- |
| `useLayers` | Reading the raw layer array. |
| `useLayersWithStyles` | Reading layers with computed `style` and `contentStyle`. |
| `useLayerTree` | Rendering a nested layer tree. |
| `useSelectedLayers` | Reading the selected layer objects. |
| `useSelectedLayerTypes` | Showing controls for the selected layer types. |

Most inspector controls start with `useSelectedLayers`:

```tsx
import { useSelectedLayers } from "@shadcn/designer"

function SelectedLayersList() {
  const selectedLayers = useSelectedLayers()

  if (!selectedLayers.length) {
    return null
  }

  // Render a list of the selected layers.
  return (
    <ul>
      {selectedLayers.map((layer) => (
        <li key={layer.id}>{layer.name}</li>
      ))}
    </ul>
  )
}
```

## Updating layer data

Layer data falls into four buckets: common layer properties, layer-specific
values, metadata, and CSS variables.

| Hook | Use it for |
| --- | --- |
| `useSetLayersValue` | Updating the `value` of one or more layers. |
| `useSetLayersMeta` | Updating the `meta` of one or more layers. |
| `useSetLayersProperty` | Updating shared layer fields like `name`, `isLocked`|
| `createLayerCssVarAction` + `useLayerCssVarAction` | Building controls for CSS variables like fill, size, position, and typography. |

Use `useSetLayersValue` for custom layer values:

```tsx
import { useSelectedLayers, useSetLayersValue } from "@shadcn/designer"

function ShapeTypeAction() {
  const selectedLayers = useSelectedLayers()
  const setLayersValue = useSetLayersValue()
  const shapeLayers = selectedLayers.filter((layer) => layer.type === "shape")

  return (
    <button
      onClick={() => setLayersValue(shapeLayers, { type: "circle" })}
      disabled={shapeLayers.length === 0}
    >
      Circle
    </button>
  )
}
```

`useSetLayersValue` and `useSetLayersMeta` accept a layer ID, an array of layer
IDs, a layer object, or an array of layer objects. If you only have IDs, pass the
layer type as a generic so TypeScript can check the value:

```tsx
setLayersValue<"shape">(selectedLayerIds, { type: "square" })
setLayersMeta<"shape">(selectedLayerIds, { source: "toolbar" })
```

Use the updater form when the next value depends on the previous value:

```tsx
setLayersValue<"shape">("shape-1", (prev) => ({
  ...prev,
  type: prev.type === "circle" ? "square" : "circle",
}))
```

Use `useSetLayersProperty` for common fields that are not specific to one layer
type:

```tsx
const setLayersProperty = useSetLayersProperty()

setLayersProperty(selectedLayerIds, "isLocked", true)
```

Do not use `useSetLayersProperty` to update `cssVars`. Use `createLayerCssVarAction` and `useLayerCssVarAction` instead.

For visual properties stored in `cssVars`, prefer a CSS variable action. It
automatically reads and writes the value across the current selection.

```tsx
import {
  createLayerCssVarAction,
  useLayerCssVarAction,
} from "@shadcn/designer"

const fill = createLayerCssVarAction("--background-color", "#000000")

function FillAction() {
  const [value, setValue] = useLayerCssVarAction(fill)

  return (
    <input
      type="color"
      value={value}
      onChange={(event) => setValue(event.target.value)}
    />
  )
}
```

All of these setters record undo history by default. Pass `{ history: false }`
when you need an internal update that should not create an undo step:

```tsx
setLayersValue<"shape">("shape-1", { type: "circle" }, { history: false })
```

## Creating and deleting layers

Use these hooks when a control changes the structure of the document.

| Hook | Use it for |
| --- | --- |
| `useAddLayers` | Creating one or more layers from layer input. |
| `useDeleteLayers` | Deleting layers by ID. |

Use `useAddLayers` when you are creating new layer objects yourself:

```tsx
const addLayers = useAddLayers()

addLayers([
  {
    type: "text",
    name: "Text",
    value: "Hello world",
    cssVars: {
      "--translate-x": "120px",
      "--translate-y": "120px",
    },
  },
])
```

## Canvas and editor controls

These hooks control the designer shell rather than the document data itself.

| Hook | Use it for |
| --- | --- |
| `useDesignerAction` | Running canvas-level commands like zoom, undo, redo, redraw, and deselect. |
| `useDesignerTool` / `useSetDesignerTool` | Reading or switching between the move and hand tools. |
| `useZoom` / `useSetZoom` | Reading or setting the current zoom. |
| `useFrameSize` / `useSetFrameSize` | Reading or setting the frame size. |
| `useUnitSystem` / `useSetUnitSystem` | Reading or setting the active unit system. |
| `useDPI` / `useSetDPI` | Reading or setting DPI for unit conversion. |

`useDesignerAction` is useful for toolbar buttons that map directly to designer
commands:

```tsx
const designerAction = useDesignerAction()

designerAction("ZOOM_IN")
designerAction("ZOOM_FIT")
designerAction("UNSELECT_ALL")
```

For controls that need to show the current value, pair the read and write hooks:

```tsx
const zoom = useZoom()
const setZoom = useSetZoom()

setZoom(Math.min(zoom + 0.1, 3))
```

## History

Use the dedicated history hooks when you are building undo and redo UI.

| Hook | Use it for |
| --- | --- |
| `useUndo` | Undoing the last recorded layer change. |
| `useRedo` | Redoing the next recorded layer change. |
| `useCanUndo` | Disabling undo UI when there is nothing to undo. |
| `useCanRedo` | Disabling redo UI when there is nothing to redo. |

```tsx
function HistoryActions() {
  const undo = useUndo()
  const redo = useRedo()
  const canUndo = useCanUndo()
  const canRedo = useCanRedo()

  return (
    <div>
      <button onClick={undo} disabled={!canUndo}>
        Undo
      </button>
      <button onClick={redo} disabled={!canRedo}>
        Redo
      </button>
    </div>
  )
}
```

## Next Steps

- See the full [Hooks Reference](/docs/reference/hooks).
- Learn how to register typed layer values in [Type Safety](/docs/concepts/type-safety).
- Learn how to build custom layer types in [Layers](/docs/concepts/layers).