# Form Builder
URL: /docs/web/components/form-builder
A drag-and-drop form designer with a field palette, canvas, properties panel, live preview and code export for TanStack Form, React Hook Form, Zod and raw useState.
**Demo:**
```tsx
'use client';
import { FormBuilder } from '@docyrus/ui/components/form-builder';
export function FormBuilderDemo() {
return (
);
}
```
The component fills its parent (`flex h-full flex-col`), so wrap it in a sized container or pass a `className` with explicit dimensions.
### Reading builder state
`useBuilderContext` is exposed for consumers that want to render their own toolbar, persist drafts, or react to selection. It must be used inside a ``, which `` already renders internally — to read state from outside the default UI, render `` yourself and place `` (or its sub-components) underneath.
```tsx
import {
BuilderProvider,
useBuilderContext
} from "@docyrus/ui/components/form-builder";
function FieldCount() {
const { state } = useBuilderContext();
return {state.fields.length} fields;
}
```
## Built-in field types
The palette ships with **9 categories** covering 30+ field types from the Docyrus form-fields library. Each type maps to a `DynamicFormField` renderer, so what users build in the canvas is exactly what they get at runtime.
| Category | Field types |
|----------|-------------|
| Text & Input | `field-text`, `field-textarea`, `field-email`, `field-url`, `field-phone`, `field-color` |
| Numbers | `field-number`, `field-money`, `field-percent`, `field-rating`, `field-duration`, `field-currency` |
| Selection | `field-select`, `field-multiSelect`, `field-tagSelect`, `field-radioGroup`, `field-enum`, `field-status`, `field-approvalStatus` |
| Date & Time | `field-date`, `field-dateTime`, `field-time`, `field-dateRange` |
| Toggle | `field-switch`, `field-checkbox` |
| Visual & Media | `field-icon`, `field-avatar`, `field-file`, `field-image` |
| Relation & User | `field-userSelect`, `field-userMultiSelect`, `field-relation`, `field-locationSelect` |
| Rich Content | `field-htmlEditor`, `field-codeEditor`, `field-docEditor`, `field-emailEditor` |
| Data Structure | `field-taskList`, `field-schemaRepeater`, `field-queryBuilder` |
## Code export
Switch the toolbar's view mode to **Code** to render generated TSX for the current form. Four templates are available:
| Template | Output |
|----------|--------|
| `tanstack` | `useForm` from `@tanstack/react-form` driving `DynamicFormField` |
| `rhf` | `useForm` from `react-hook-form` with native inputs |
| `zod` | `react-hook-form` + `zodResolver` and a generated `z.object` schema |
| `raw` | `useState` per field, plain `` markup |
The generated code uses user-project import paths (`@/components/docyrus/form-fields`, `@/components/ui/button`) so it drops straight into a project that has installed `@docyrus/ui-form-fields` and the matching shadcn primitives. Adjust the prefix if your project uses a different alias.
## API Reference
### ``
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | `flex h-full flex-col` | Override the root container classes. Useful for setting an explicit height or max width. |
### `useBuilderContext()`
Returns the live builder state and dispatchers. Throws if called outside a ``.
| Property | Type | Description |
|----------|------|-------------|
| `state` | `BuilderState` | The full reducer state (fields, selection, view mode, grid columns, form title). |
| `dispatch` | `Dispatch` | Low-level dispatcher for every reducer action (including undo/redo, reorder, clear). |
| `selectedField` | `BuilderField \| null` | The currently focused field, or `null` when nothing is selected. |
| `addField` | `(componentType: string, index?: number) => void` | Append (or insert at `index`) a new field of the given palette type. |
| `removeField` | `(id: string) => void` | Remove a field by id. |
| `duplicateField` | `(id: string) => void` | Clone a field by id and insert it directly after the source. |
| `selectField` | `(id: string \| null) => void` | Update the selection. |
| `canUndo` | `boolean` | `true` when there is at least one entry in the undo stack. |
| `canRedo` | `boolean` | `true` when there is at least one entry in the redo stack. |
### ``
Wraps children in the builder reducer and history. Accepts only `children`; rendered automatically by ``.
## Components
| Component | Description |
|-----------|-------------|
| `FormBuilder` | The full builder experience (toolbar, palette, canvas, properties panel, preview, code export). The properties panel has four tabs — **General**, **Options** (enum fields only), **Validation**, and **Actions**. The **Validation** tab supports required toggle, min/max/pattern constraints, and **Custom Validations** — JSONata-based rules evaluated on submit. Each custom validation rule has an `expression` (returns `true` to pass) and a `message` shown on failure. Supported field types: `text`, `textarea`, `email`, `url`, `phone`, `number`, `money`, `percent`, `duration`, `date`, `dateTime`, `rating`. |
| `BuilderProvider` | Reducer + 50-step undo/redo history provider. |
| `useBuilderContext` | Hook for reading builder state and triggering actions. |
| `generateCode` | Standalone helper that turns a `BuilderState` into a TSX string for any of the four templates. |
## Type Exports
| Type | Description |
|------|-------------|
| `FormBuilderProps` | Props for `` (`className?`). |
| `BuilderField` | A single field on the canvas: id, component type, `IField` config, optional enum options and `colSpan`. |
| `BuilderState` | Top-level reducer state — `fields`, `selectedFieldId`, `viewMode`, `formTitle`, `formDescription`, `gridColumns`. |
| `BuilderAction` | Union of every dispatchable action (add/remove/reorder/duplicate/update/select/undo/redo/clear/set-meta/set-view-mode). |
| `PaletteCategory` | A palette section (id, label, icon, items). |
| `PaletteItem` | A single palette entry (component type, label, icon, default field type, search tags). |
| `PropertySchema` | Metadata for one editable property in the right-hand properties panel. |
| `CodeTemplate` | `'tanstack' \| 'rhf' \| 'zod' \| 'raw'` — accepted by `generateCode`. |
| `FieldAction` | Trigger + ordered blocks definition stored on `BuilderField.field.fieldActions`. Authored through the **Actions** tab in the properties panel. |
| `FieldActionBlock` | Named block with if / else-if / else branches and unconditional steps. |
| `FieldActionStep` | Discriminated union of imperative commands: value writes, visibility, required, disabled, readOnly. |