SpectreSkills
← All skills

form-builder-canvas

v1.0.0

Build the form authoring surface — a field palette, a drag-and-drop canvas that packs fields into rows, and an inspector for the selected field. Trigger when implementing the editor where someone assembles a form.

Formsformsdrag-and-dropbuilder
Install
npx @spectre-apps/skills add form-builder-canvas

Writes .claude/skills/form-builder-canvas/SKILL.md. Add --user to install globally.

What it does

Form builder canvas

The editor is three regions around one FormDefinition (see form-definition):

┌────────────┬──────────────────────────┬────────────────┐
│  Palette   │  Canvas                  │  Inspector     │
│  add field │  rows, steps, selection  │  selected field│
└────────────┴──────────────────────────┴────────────────┘

The host's component library supplies the chrome. This skill is the behavior. Any drag-and-drop library is fine; the gestures below are the contract.

Palette

Render one item per field manifest, in catalog order. The three-letter tag is the glyph — skip an icon set.

Adding a field (click or drag onto the canvas) inserts a new field built from that type's defaults, with a name unique among the form's existing keys. On a multi-step form the new field lands in step 1; the author drags it from there.

Canvas

Draw fields as cards in the rows from the width packer, in array order. The canvas is a projection of the flat fields array, so a drop writes back an index into that array. Use each row's startIndex to turn a row-relative drop into that index.

Gestures:

  • Reorder within a row or across rows.
  • Move between steps by dropping on another step's header.
  • Drop on an empty canvas. The empty state is a real drop target, with a short line of copy pointing at the palette.

One field is selected. Delete removes it. Duplicate inserts a copy after it with a fresh id and a unique name.

Inspector

The inspector edits the selected field and shows only what its manifest allows:

  • label, and the submission key (editable; once edited, label changes leave it)
  • placeholder, when supportsPlaceholder
  • required, when supportsRequired
  • options editor, when hasOptions — add, remove, reorder lines
  • width: Full, Half, Third, Quarter
  • step assignment, when the form has more than one step
  • conditional rule, aimed at another field on this form

Form-level settings (heading, button label, success message, destination, spam protection) live in a form settings surface, separate from the field inspector, so selecting a field never hides them behind a mode switch that is hard to find. A header control is enough.

Steps

Multi-step is a setting on the form. Off, the canvas is one list. On, fields group into step containers:

  • The header title is editable inline. Default titles are "Step one", "Step two", and so on, stored as the steps array.
  • Add inserts a step after the current one and renumbers.
  • Delete is refused when it is the only step. Otherwise its fields move to the previous step. Confirm when the step still has fields.
  • Collapse is local UI state and is not persisted.
  • The submit button renders on the last step only. Earlier steps navigate.

Starter forms

Ship two or three starters as plain FormDefinition values — a one-line email signup (email at 75% width beside the button's row), a contact form (name, email, message), and a two-step contact form. Applying one replaces the field list. After that it is an ordinary form; nothing stays linked to the starter.

Save

Track dirty state against the last loaded document and save the whole field list plus step titles in one write. A banner names unsaved edits. Warnings from form-definition render inline and do not block the save; publishing a form with no-fields or no-submit-target is the point to insist.

The canvas hands the same document to form-preview. It does not draw a lookalike of the published form inside the card.