The canvas

Selecting & arranging elements

The canvas is clickable — every rendered element can be selected, moved, copied, and deleted. This page covers the direct-manipulation surface; the code editor and Layers panel cover the same ground from different angles (see Editing states).

Selection

A single click selects the topmost element under the cursor. Clicking again on the selected element drills into its first child; this is how deeply-nested elements get selected without reaching for the Layers panel.

Shift + click adds another element to the selection. Multi-select is usually most useful among siblings — bulk property edits and arrow-key reorder assume a shared parent — but nothing prevents selections spanning different parents.

multi-select-siblings.png

Selected elements are outlined with a blue border that stays visible on any background, light or dark. The Properties inspector — which appears at the top-right of the canvas whenever something is selected — shows the editable props of the current selection, and disappears again when you deselect.

element-selection-highlight.png

Dragging to reorder

Selected elements can be dragged to a new position. The drop target is indicated by an insertion line between siblings; release the mouse to commit.

drag-reorder-insertion-line.png

Dragging any element that is part of a multi-selection moves the whole selection to the drop target, preserving the elements' relative document order. Selections that span different parents converge at the drop point. Grabbing an element that is not in the current selection moves only that element, leaving the selection intact.

Arrow keys also reorder the selection: / swap with the previous/next sibling in a vertical container, / swap in a horizontal container. The direction is inferred from the parent's flex direction.

Cross-frame drag

Elements can be dragged from one state frame to another, or from a state frame onto a canvas element, or the other way around. During the drag, the target frame shows the same insertion-line / container-outline indicators the intra-frame drag uses, and the source element stays dimmed until drop.

cross-frame-drag-target.png

Holding Alt / Option during a drag switches the commit from move to copy — the original stays in place and a duplicate lands at the drop target. The modifier can be toggled mid-drag; the cursor reflects the current mode. Copies get fresh persistent IDs, so any comments anchored to the original don't duplicate onto the copy.

Dragging onto the empty canvas — outside any frame — spawns a new canvas element at the drop point. A live preview of what you're dropping follows the cursor so the final result is visible before release.

Dropping onto a state frame that has no UI defined yet populates that frame with the dragged element. The whole frame highlights as the drop target instead of showing an insertion line, since there's no existing JSX to insert relative to.

Transitions attached to the dragged element are always stripped on a cross-frame move. The transition row itself is preserved in the project but becomes orphaned (no source element) — cross-frame moves change the element's home, and silently retargeting a transition would almost always be wrong.

Copy, paste, duplicate

Cmd+C copies the JSX of the currently-selected element to an internal clipboard. Cmd+V with an element selected pastes the clipboard JSX as the selection's sibling. Pasting mints fresh persistent IDs on the new elements so nothing collides with the original.

Cmd+V with nothing selected is context-sensitive. If the active state frame has no UI defined yet, the clipboard populates it. Otherwise the clipboard JSX drops onto the canvas as a new canvas element at the viewport centre — a quick way to spin a variant off without first choosing a frame to paste into.

The clipboard lives in memory for the session. Copy/paste across different projects is not supported through the clipboard — use the Code panel to move JSX between projects directly.

There is no dedicated duplicate shortcut. Cmd+C followed by Cmd+V produces the same result, as does Alt + drag.

Deleting

Delete or Backspace removes every selected element, including a state's root. Deleting a state's only top-level element empties the frame, which renders as a blank artboard — you can drop a component back onto it at any time.

Panning the canvas

Hold Space and drag to pan, or drag with the middle mouse button. Trackpads pan on a two-finger scroll without any modifier.

Dropping components onto the canvas

Components from the Components panel can be dragged and dropped anywhere on the canvas: onto an element in a frame (inserted as a child / sibling of the hovered element), or onto empty space (spawns a new canvas element at the drop point). A live preview of the component follows the cursor during drag so the final placement is visible before release.

This is the same insertion path as the component-palette click behaviour — the only difference is where the new element lands.

Working with canvas elements

A canvas element behaves like a tiny single-state frame for everything that happens inside it — click to select, Properties inspector, Layers, Code panel, inline text edit, cross-frame drag, and comments all work identically.

To select the canvas element as a whole (rather than an element inside it), click its empty background. The three corner / edge resize grips appear when selected; Delete / Backspace removes it. To move it around, drag from the empty space around the content. Dragging it over a state frame promotes it into that state's JSX at the drop point; dragging the element's root out of a canvas element into a frame collapses the (now empty) canvas element automatically.

canvas-element-resize-handles.png

What the canvas does not cover

A few direct-manipulation behaviours from other design tools are not available on the Statecraft canvas:

  • Free positioning of elements inside a frame — elements stay in document flow. Absolute positioning is possible via the Properties inspector, not by dragging. (Canvas elements themselves are free-positioned on the canvas.)
  • Resize handles on elements — resizing the state frame or a canvas element is available, but individual elements inside them resize via props, not handles.