The designer provides a comprehensive set of hooks for managing the state and behavior of the designer. These hooks provide a simple way to access and modify the designer's state, handle user interactions, and manage the design canvas.
Designer
The core hooks for controlling the designer and the canvas.
useDesignerAction
Executes designer-level actions like zoom, undo/redo, etc.
import { useDesignerAction } from "@shadcn/designer"
function DesignerControls() {
const designerAction = useDesignerAction()
return (
<div>
<button onClick={() => designerAction("ZOOM_IN")}>Zoom In</button>
<button onClick={() => designerAction("ZOOM_OUT")}>Zoom Out</button>
<button onClick={() => designerAction("ZOOM_FIT")}>Fit to Screen</button>
<button onClick={() => designerAction("ZOOM_RESET")}>Reset Zoom</button>
<button onClick={() => designerAction("ZOOM_100")}>100%</button>
<button onClick={() => designerAction("UNSELECT_ALL")}>Deselect All</button>
<button onClick={() => designerAction("HISTORY_UNDO")}>Undo</button>
<button onClick={() => designerAction("HISTORY_REDO")}>Redo</button>
<button onClick={() => designerAction("REDRAW")}>Redraw Canvas</button>
</div>
)
}
Available Actions:
Action | Description |
---|---|
ZOOM_IN | Increase zoom level by one step |
ZOOM_OUT | Decrease zoom level by one step |
ZOOM_RESET | Reset zoom to default level and center canvas |
ZOOM_100 | Set zoom to 100% |
ZOOM_FIT | Fit canvas to viewport and center |
REDRAW | Redraw the canvas and center it |
UNSELECT_ALL | Clear all layer selections |
HISTORY_UNDO | Trigger undo action |
HISTORY_REDO | Trigger redo action |
See also useUndo
and useRedo
for undo/redo functionality.
useFrameSize
Gets the current frame/canvas size.
import { useFrameSize } from "@shadcn/designer"
function FrameInfo() {
const frameSize = useFrameSize()
return (
<div>
Canvas: {frameSize.width} × {frameSize.height}
</div>
)
}
useSetFrameSize
Sets the frame/canvas size.
import { useSetFrameSize } from "@shadcn/designer"
function FrameSizeControl() {
const setFrameSize = useSetFrameSize()
const handlePreset = (width: number, height: number) => {
setFrameSize({ width, height })
}
return (
<div>
<button onClick={() => handlePreset(1920, 1080)}>HD</button>
<button onClick={() => handlePreset(1024, 1024)}>Square</button>
</div>
)
}
useZoom
Gets the current zoom level of the canvas.
import { useZoom } from "@shadcn/designer"
function ZoomIndicator() {
const zoom = useZoom()
return <span>{Math.round(zoom * 100)}%</span>
}
useSetZoom
Sets the zoom level of the canvas.
import { useSetZoom } from "@shadcn/designer"
function ZoomSlider() {
const zoom = useZoom()
const setZoom = useSetZoom()
return (
<input
type="range"
min="0.1"
max="3"
step="0.1"
value={zoom}
onChange={(e) => setZoom(parseFloat(e.target.value))}
/>
)
}
useTargets
Gets the current interaction targets on the canvas.
import { useTargets } from "@shadcn/designer"
function TargetInfo() {
const targets = useTargets()
return <div>Active targets: {targets.length}</div>
}
useSetTargets
Sets the interaction targets on the canvas.
import { useSetTargets, type Target } from "@shadcn/designer"
function TargetController({ newTargets }) {
const setTargets = useSetTargets()
React.useEffect(() => {
const target = document.querySelector(
`[data-layer-id="SOME_LAYER_ID"].layer`
) as Target | null
setTargets([target])
}, [setTargets])
return null
}
Layer Management
Essential hooks for working with layers - selecting, creating, modifying, and managing layer state.
useSelectedLayers
Gets the currently selected layers on the canvas.
import { useSelectedLayers } from "@shadcn/designer"
function LayerInfo() {
const selectedLayers = useSelectedLayers()
return (
<div>
{selectedLayers.length > 0 ? (
<p>Selected: {selectedLayers[0].name}</p>
) : (
<p>No layers selected</p>
)}
</div>
)
}
useSetSelectedLayers
Sets the selected layers on the canvas.
import { useSetSelectedLayers } from "@shadcn/designer"
function LayerSelector({ layer }) {
const setSelectedLayers = useSetSelectedLayers()
const handleSelect = () => {
setSelectedLayers([layer])
}
return <button onClick={handleSelect}>Select Layer</button>
}
useSelectedLayerIds
Gets an array of IDs for currently selected layers.
import { useSelectedLayerIds } from "@shadcn/designer"
function SelectedLayerCount() {
const selectedLayerIds = useSelectedLayerIds()
return <span>Selected: {selectedLayerIds.length}</span>
}
useSelectedLayerTypes
Gets the unique types of currently selected layers.
import { useSelectedLayerTypes } from "@shadcn/designer"
function LayerTypeIndicator() {
const selectedLayerTypes = useSelectedLayerTypes()
return (
<div>
Types: {selectedLayerTypes.join(", ")}
</div>
)
}
useLayers
Gets all layers in the design.
import { useLayers } from "@shadcn/designer"
function LayerCount() {
const layers = useLayers()
return <span>Total layers: {layers.length}</span>
}
To add or remove layers, see useAddLayers
and useDeleteLayers
.
useLayersWithStyles
Gets all layers with computed styles applied.
import { useLayersWithStyles } from "@shadcn/designer"
function StyledLayerList() {
const layersWithStyles = useLayersWithStyles()
return (
<div>
{layersWithStyles.map(layer => (
<div key={layer.id} style={layer.style}>
{layer.name}
</div>
))}
</div>
)
}
useAddLayers
Adds new layers to the design canvas.
import { useAddLayers } from "@shadcn/designer"
function AddTextButton() {
const addLayers = useAddLayers()
const handleAddText = () => {
addLayers([
{
type: "text",
name: "New Text",
cssVars: {
"--content": "Hello World",
"--font-size": "16px"
}
}
])
}
return <button onClick={handleAddText}>Add Text Layer</button>
}
useDeleteLayers
Deletes layers from the design canvas.
import { useDeleteLayers, useSelectedLayerIds } from "@shadcn/designer"
function DeleteSelectedButton() {
const deleteLayers = useDeleteLayers()
const selectedLayerIds = useSelectedLayerIds()
const handleDelete = () => {
deleteLayers(selectedLayerIds)
}
return (
<button
onClick={handleDelete}
disabled={selectedLayerIds.length === 0}
>
Delete Selected
</button>
)
}
useGetLayers
Gets specific layers by their IDs.
import { useGetLayers } from "@shadcn/designer"
function LayerDetails({ layerIds }) {
const getLayers = useGetLayers()
const layers = getLayers(layerIds)
return (
<div>
{layers.map(layer => (
<div key={layer.id}>{layer.name}</div>
))}
</div>
)
}
useSetLayersProperty
Sets a property on multiple layers at once.
import { useSetLayersProperty } from "@shadcn/designer"
function LockSelectedLayers() {
const setLayersProperty = useSetLayersProperty()
const selectedLayerIds = useSelectedLayerIds()
const handleLock = () => {
setLayersProperty(selectedLayerIds, "isLocked", true)
}
return <button onClick={handleLock}>Lock Selected</button>
}
See the Layer type for more information on the properties that can be set and how to use the meta
property to store arbitrary data on a layer.
useLayersAction
Executes common layer actions like duplicate, delete, show/hide, etc.
import { useLayersAction, useSelectedLayerIds } from "@shadcn/designer"
function LayerActions() {
const layersAction = useLayersAction()
const selectedLayerIds = useSelectedLayerIds()
const handleDuplicate = () => {
layersAction("DUPLICATE_LAYER", selectedLayerIds)
}
const handleToggleVisibility = () => {
layersAction("SHOW_HIDE_LAYER", selectedLayerIds)
}
return (
<div>
<button onClick={handleDuplicate}>Duplicate</button>
<button onClick={handleToggleVisibility}>Toggle Visibility</button>
</div>
)
}
Available Actions:
Action | Description |
---|---|
DUPLICATE_LAYER | Duplicate the selected layers |
SHOW_HIDE_LAYER | Show or hide the selected layers |
BRING_TO_FRONT | Bring the selected layers to the front |
SEND_TO_BACK | Send the selected layers to the back |
LOCK_UNLOCK_LAYER | Lock or unlock the selected layers |
useLayerTypes
Gets the available layer types that can be created.
import { useLayerTypes } from "@shadcn/designer"
function LayerTypeMenu() {
const layerTypes = useLayerTypes()
return (
<select>
{layerTypes.map(type => (
<option key={type.type} value={type.type}>
{type.name}
</option>
))}
</select>
)
}
useLayerCssVarAction
Manages CSS variables for selected layers with type-safe serialization.
// Create a typed CSS variable action
const fontSize = createLayerCssVarAction("--font-size", "16px")
You can also pass a serialize
and deserialize
function to the createLayerCssVarAction
function to customize the serialization and deserialization of the value.
const fontSize = createLayerCssVarAction("--font-size", "16px", {
serialize: (value: number) => `${value}px`,
deserialize: (value: string | undefined) => {
return value ? parseInt(value) : 16
}
})
import { useLayerCssVarAction, createLayerCssVarAction } from "@shadcn/designer"
// Create a typed CSS variable action
const fontSize = createLayerCssVarAction("--font-size", "16px")
function FontSizeControl() {
const [value, setValue] = useLayerCssVarAction(fontSize)
return (
<input
type="range"
min="8"
max="72"
value={value}
onChange={(e) => setValue(parseInt(e.target.value))}
/>
)
}
History Management
Hooks for managing undo/redo functionality and action history.
useUndo
Triggers an undo action.
import { useUndo, useCanUndo } from "@shadcn/designer"
function UndoButton() {
const undo = useUndo()
const canUndo = useCanUndo()
return (
<button onClick={undo} disabled={!canUndo}>
Undo
</button>
)
}
useRedo
Triggers a redo action.
import { useRedo, useCanRedo } from "@shadcn/designer"
function RedoButton() {
const redo = useRedo()
const canRedo = useCanRedo()
return (
<button onClick={redo} disabled={!canRedo}>
Redo
</button>
)
}
useCanUndo
Checks if undo is available.
import { useCanUndo } from "@shadcn/designer"
function HistoryStatus() {
const canUndo = useCanUndo()
return canUndo ? "Changes available" : "No changes to undo"
}
useCanRedo
Checks if redo is available.
import { useCanRedo } from "@shadcn/designer"
function RedoStatus() {
const canRedo = useCanRedo()
return canRedo ? "Redo available" : "Nothing to redo"
}
Keyboard Shortcuts
Hooks for handling keyboard interactions and custom shortcuts.
useShortcut
Registers a keyboard shortcut with a callback.
import { useShortcut } from "@shadcn/designer"
function ShortcutHandler() {
useShortcut("DUPLICATE_LAYER", () => {
console.log("Duplicate shortcut pressed")
})
useShortcut("DELETE_LAYER", () => {
console.log("Delete shortcut pressed")
})
return null // This component just handles shortcuts
}
useKeybindings
Gets the current keybinding configuration.
import { useKeybindings } from "@shadcn/designer"
function ShortcutList() {
const keybindings = useKeybindings()
return (
<div>
{Object.entries(keybindings).map(([key, binding]) => (
<div key={key}>
<strong>{binding.name}</strong>: {binding.key}
</div>
))}
</div>
)
}
useSetKeybindings
Sets custom keybinding configuration.
import { useSetKeybindings } from "@shadcn/designer"
function CustomizeShortcuts() {
const setKeybindings = useSetKeybindings()
const handleCustomize = () => {
setKeybindings({
"DUPLICATE_LAYER": {
key: "cmd+d",
name: "Duplicate Layer",
group: "layer"
}
// ... more keybindings
})
}
return <button onClick={handleCustomize}>Customize Shortcuts</button>
}
Development
Hooks for debugging and development.
useDebug
Gets the current debug mode state.
import { useDebug } from "@shadcn/designer"
function DebugPanel() {
const debug = useDebug()
if (!debug) return null
return <div>Debug information...</div>
}
useSetDebug
Sets the debug mode state.
import { useSetDebug } from "@shadcn/designer"
function DebugToggle() {
const debug = useDebug()
const setDebug = useSetDebug()
return (
<button onClick={() => setDebug(!debug)}>
{debug ? "Disable" : "Enable"} Debug
</button>
)
}
Utilities
Helper hooks for cross-platform compatibility and general utilities.
useIsMac
Detects if the user is on macOS platform, useful for showing platform-specific keyboard shortcuts and UI elements.
import { useIsMac } from "@shadcn/designer"
function ShortcutDisplay({ keybinding }) {
const isMac = useIsMac()
const label = isMac
? keybinding.labelMac
: keybinding.label
return <span>{label}</span>
}