Canvas UI reference
Technical reference for the CanvasLayout component and its APIs.
This page is intended for developers who need to understand or extend the Canvas UI component.
Component location
assets/src/App/components/CanvasLayout/
├── index.jsx # Main CanvasLayout component
├── CanvasUIPreferences.jsx # Toolbar preference toggles
└── CanvasPreviewItem.jsx # Drag-overlay preview elementCanvasLayout props
sensors
object
Yes
@dnd-kit sensor configuration (pointer + keyboard).
onDragEnd
function
Yes
Called with the drag result when an item is dropped.
collisionDetection
function
No
@dnd-kit collision-detection strategy used to determine valid drop targets. Defaults to rectIntersection; pointerWithin is also available for contexts that need more precise pointer-based targeting.
canvas
ReactNode
Yes
Content rendered in the canvas panel.
dragOverlay
ReactNode
Yes
Element rendered as the drag ghost.
id
string
No
Unique identifier for this canvas instance.
preferenceId
string
No
Raw entity ID used as the localStorage key for layout preferences. Defaults to id.
wrapperRef
ref
No
Ref attached to the outer wrapper element.
toolbarRef
ref
No
Ref attached to the toolbar element.
extraOptions
array
No
Additional toolbar toggle options (see below).
sidebarDefaultSize
number
No
Default sidebar width as a percentage (default: 450px-equivalent).
sidebarMinSize
number
No
Minimum sidebar width in pixels (default: 400).
sidebarMaxSize
number
No
Maximum sidebar width in pixels (default: 700).
extraOptions shape
The No-distraction toggle is always present and does not need to be included in extraOptions.
useUIPreference hook
Each toggle in the toolbar is backed by the useUIPreference hook, which reads and writes to localStorage:
The hook returns [value, setter] — identical signature to useState.
Drag-and-drop internals
CanvasLayout wraps its children in a @dnd-kit DndContext. Each draggable item must use useSortable from @dnd-kit/sortable:
The onDragEnd prop receives the standard @dnd-kit drag-end event. Use arrayMove from @dnd-kit/sortable to reorder the item array:
Click-to-add activation distance
Sidebar items can be added to the canvas either by dragging or by a plain click. A pointer-sensor activation-distance threshold (a few pixels of movement) is what allows this: it distinguishes a click from the start of a drag, so a click fires the "add" handler instead of starting a drag operation. Consumers wiring up their own sidebar items should apply the same activation-distance constraint on their MouseSensor if they want click-to-add alongside drag-to-add.
Sidebar position
A SidebarPositionButton toggle pair (in CanvasUIPreferences.jsx) lets the user dock the sidebar on the left or right of the canvas. Like the other toolbar toggles, the choice is persisted via the useUIPreference hook, keyed off preferenceId, so it's remembered per entity.
Inline editing (nameSlot)
CanvasPreviewItem exposes a nameSlot render prop so consumers can inject inline-editable controls into the card header instead of relying solely on the settings panel. Known consumers include the form builder's inline Label editor, and equivalent inline name/type editors for meta fields, dynamic blocks, and CCT table columns — each lives alongside its own page (not inside the shared CanvasLayout/ directory above).
A field/column-level isReusable flag governs two things: whether its name is inline-editable at all, and whether it can be re-added to the canvas while already present. It's false for items bound to an existing meta field, CCT column, or WordPress core field, so that binding can't be broken by a rename or duplicate.
Resizable panels
The sidebar/canvas split uses react-resizable-panels. The divider position is persisted in localStorage under the key acpt_canvas_panel_{preferenceId}. The sidebar Panel also has an explicit, stable id, which fixes a bug where saved panel widths could get mixed up after switching the sidebar from one side to the other.
Dependencies
@dnd-kit/core
6.x
Drag-and-drop context
@dnd-kit/sortable
7.x
Sortable list abstraction
@dnd-kit/utilities
3.x
CSS transform helpers
react-resizable-panels
4.x
Resizable sidebar/canvas split
Last updated