Types
TypeScript type reference for the designer.
This page documents the public types exported from @shadcn/designer. For tutorials and conceptual overviews, see the Concepts section.
Layer
A layer on the canvas. Layer is a discriminated union — type, value, and meta narrow per registered layer type. Without module augmentation, type is string and value is unknown. Once augmented, the union narrows to your registered layer types.
type Layer = {
id: string
name: string
type: LayerTypeName
value: unknown
cssVars?: CSSVars
meta?: Record<string, unknown>
isLocked?: boolean
parentId?: string
}| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the layer. |
name | string | Yes | Display name. |
type | LayerTypeName | Yes | Discriminator narrowed per registered layer type. |
value | Inferred from layer type | Yes | Layer-specific content. |
cssVars | CSSVars | No | CSS custom properties for styling. |
meta | Inferred or Record<string, unknown> | No | Arbitrary metadata. Narrows per layer type when augmented. |
isLocked | boolean | No | Whether the layer is locked from editing. |
parentId | string | No | ID of the parent layer (for grouping). |
LayerWithStyles
Layer plus computed CSS for rendering. This is what LayerType.render receives.
type LayerWithStyles = Layer & {
style: CSSProperties
contentStyle: CSSProperties
}| Property | Type | Description |
|---|---|---|
style | CSSProperties | Computed styles for the layer container. |
contentStyle | CSSProperties | Computed styles for the layer content (derived from cssVars). |
LayerType
Configuration that defines how a layer type behaves and renders.
type LayerType = {
type: LayerTypeName
name: string
defaultValues: DistributiveOmit<Layer, "id" | "type">
render: (layer: LayerWithStyles) => React.ReactNode
icon?: ReactNode
keybinding?: Keybinding
unstable_transformerProps?: (context: {
layer: Layer
context: TransformerContext
}) => Partial<TransformerConfig>
}| Property | Type | Required | Description |
|---|---|---|---|
type | LayerTypeName | Yes | Unique type identifier. |
name | string | Yes | Human-readable name. |
defaultValues | DistributiveOmit<Layer, "id" | "type"> | Yes | Default values for new layers. |
render | (layer: LayerWithStyles) => React.ReactNode | Yes | Render function. |
icon | ReactNode | No | Icon shown in the toolbar. |
keybinding | Keybinding | No | Keyboard shortcut for adding the layer. |
unstable_transformerProps | function | No | Customize transform behavior. Internal API — subject to change. |
Prefer createLayerType over annotating with LayerType directly — it preserves literal type, value, and meta types.
TypedLayerType
Return type of createLayerType. Preserves the literal type name K, value type V, and meta type M.
type TypedLayerType<
K extends string = string,
V = unknown,
M extends Record<string, unknown> = Record<string, unknown>,
> = {
type: K
name: string
icon?: ReactNode
defaultValues: {
name: string
value: V
cssVars?: CSSVars
meta?: M
isLocked?: boolean
}
render: (layer: LayerWithStylesFor<K, V, M>) => React.ReactNode
keybinding?: Keybinding
unstable_transformerProps?: (context: { layer: LayerFor<K, V, M>; context: TransformerContext }) => Partial<TransformerConfig>
}DesignerLayerTypes
Registry interface for type-safe layer definitions. Empty by default — augment via declare module to register your custom layer types.
// Empty by default.
interface DesignerLayerTypes {}declare module "@shadcn/designer" {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface DesignerLayerTypes extends InferLayerTypes<typeof layerTypes> {}
}When augmented, Layer.type becomes a union of your registered names, Layer.value narrows per type, and Layer.meta narrows per type. See Type Safety.
LayerTypeName
Resolves to string when the registry is empty, or to a union of registered names when augmented.
type LayerTypeName = keyof DesignerLayerTypes extends never
? string
: Extract<keyof DesignerLayerTypes, string>LayerByType
Extracts the layer shape for a registered layer type. This is useful when you want to type a helper or a user-defined type guard around a specific layer type.
type LayerByType<TType extends string> = Extract<
Layer,
{ type: TType }
> extends never
? LayerFor<TType, unknown>
: Extract<Layer, { type: TType }>function isShapeLayer(layer: Layer): layer is LayerByType<"shape"> {
return layer.type === "shape"
}LayerValue
Extracts the value type for a registered layer type. Used by
useSetLayersValue.
type LayerValue<TType extends string> = LayerByType<TType>["value"]LayerMeta
Extracts the meta type for a registered layer type. Used by
useSetLayersMeta.
type LayerMeta<TType extends string> = LayerByType<TType>["meta"]InferLayerTypes
Utility type that extracts layer type definitions from a layerTypes array for module augmentation.
type InferLayerTypes<
T extends readonly { type: string; defaultValues: { value: unknown } }[],
> = {
[E in T[number] as E["type"]]: E["defaultValues"] extends { meta?: infer M }
? [M] extends [undefined]
? { value: E["defaultValues"]["value"] }
: { value: E["defaultValues"]["value"]; meta: NonNullable<M> }
: { value: E["defaultValues"]["value"] }
}const layerTypes = [
createLayerType({ type: "text", name: "Text", defaultValues: { name: "Text", value: "Hello" }, render: () => null }),
createLayerType({ type: "card", name: "Card", defaultValues: { name: "Card", value: "", meta: { author: "" } }, render: () => null }),
]
// InferLayerTypes<typeof layerTypes> = {
// text: { value: string };
// card: { value: string; meta: { author: string } }
// }DistributiveOmit
A distributive version of Omit that preserves discriminated unions. Used internally by LayerType.defaultValues.
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : nevercreateLayerType
Helper function that creates a typed layer type definition with narrowed render and defaultValues. Infers value and meta from defaultValues.
import { createLayerType } from "@shadcn/designer"
const textLayer = createLayerType({
type: "text",
name: "Text",
defaultValues: { name: "Text", value: "Hello" },
render: (layer) => <span>{layer.value}</span>, // layer.value is string.
})See Layers for the full walkthrough.
DesignerKeybindings
Registry interface for custom keybinding names. Empty by default — augment via declare module to add custom names that get autocomplete in useShortcut.
// Empty by default.
interface DesignerKeybindings {}declare module "@shadcn/designer" {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface DesignerKeybindings extends InferKeybindings<typeof keybindings> {}
}See Keybindings.
KeybindingName
Union of all valid keybinding names. Includes built-in names from DEFAULT_KEYBINDINGS, dynamic ADD_LAYER_<TYPE> names from registered layer types, and any custom names registered via DesignerKeybindings.
type KeybindingName = keyof DesignerKeybindings extends never
? BuiltinKeybindingName | AddLayerKeybindingName
: BuiltinKeybindingName | AddLayerKeybindingName | Extract<keyof DesignerKeybindings, string>Used by useShortcut, Shortcut, and the keybindings prop on Designer.
InferKeybindings
Utility type that extracts keybinding names from a keybindings object for module augmentation.
type InferKeybindings<T extends Record<string, unknown>> = {
[K in keyof T]: true
}Keybinding
Configuration for a keyboard shortcut.
type Keybinding = {
key: string
label: string
labelMac: string
description: string
group: string
}| Property | Type | Description |
|---|---|---|
key | string | Key combination in react-hotkeys-hook syntax (e.g. "mod+d"). |
label | string | Display label for non-Mac platforms. |
labelMac | string | Display label for Mac. |
description | string | Human-readable description shown in the help dialog. |
group | string | Group name used when listing shortcuts. |
LayersActionName
Union of layer-specific action names dispatched via useLayersAction.
type LayersActionName =
| "DUPLICATE_LAYER"
| "DELETE_LAYER"
| "SHOW_HIDE_LAYER"
| "BRING_TO_FRONT"
| "SEND_TO_BACK"
| "LOCK_UNLOCK_LAYER"
| "GROUP_LAYERS"
| "UNGROUP_LAYERS"DesignerActionName
Union of designer-level action names dispatched via useDesignerAction.
type DesignerActionName =
| "ZOOM_IN"
| "ZOOM_OUT"
| "ZOOM_RESET"
| "ZOOM_100"
| "ZOOM_FIT"
| "REDRAW"
| "UNSELECT_ALL"
| "HISTORY_UNDO"
| "HISTORY_REDO"CSSVars
CSS custom properties used in layer styling.
type CSSVars = Record<string, string>FrameSize
Canvas frame dimensions.
type FrameSize = {
width: number
height: number
unit?: Unit
}| Property | Type | Required | Description |
|---|---|---|---|
width | number | Yes | Frame width. |
height | number | Yes | Frame height. |
unit | Unit | No | Unit of measurement. Defaults to "px". |
Unit
Supported measurement units.
type Unit = "px" | "mm" | "in" | "cm" | "pt"| Unit | Description | Common Use Case |
|---|---|---|
px | Pixels | Screen designs, web layouts. |
mm | Millimeters | Print designs. |
in | Inches | Print designs. |
cm | Centimeters | Print designs. |
pt | Points | Typography. |
See Unit System for conversion utilities and DPI handling.