Form fields

Accessible inputs, textarea, searchable select, switch, and slider with shared labels, hints, and error or success messaging.

Overview
Typical form controls with hints, validation styling, searchable select, switch, and slider

Lowercase letters, numbers, and hyphens only.

Endpoint responded with 200 OK.

0/200

Optional. Shown on the team directory.

Digest of deploys and failed checks.

4

Parallel jobs allowed per workspace (1–16).

1import {
2 FormInput,
3 FormTextarea,
4 FormSelect,
5 FormSwitch,
6 FormSlider,
7} from "@/registry/ui/form-fields"
8
9<div className="mx-auto w-full max-w-lg space-y-8 text-left">
10 <FormInput
11 label="Workspace"
12 name="workspace"
13 placeholder="acme-corp"
14 hint="Lowercase letters, numbers, and hyphens only."
15 />
16 <FormInput
17 label="API token"
18 name="token"
19 type="password"
20 placeholder="••••••••"
21 error="Token must be at least 32 characters."
22 />
23 <FormInput
24 label="Webhook URL"
25 name="webhook"
26 placeholder="https://"
27 success="Endpoint responded with 200 OK."
28 />
29 <FormTextarea
30 label="Description"
31 name="description"
32 placeholder="What is this project for?"
33 maxLength={200}
34 showCount
35 hint="Optional. Shown on the team directory."
36 />
37 <FormSelect
38 label="Region"
39 placeholder="Choose a region"
40 options={[
41 { value: "iad", label: "US East (IAD)" },
42 { value: "sfo", label: "US West (SFO)" },
43 { value: "fra", label: "EU (Frankfurt)" },
44 ]}
45 />
46 <FormSelect
47 label="Role"
48 placeholder="Search roles…"
49 searchable
50 searchPlaceholder="Filter roles…"
51 options={[
52 { value: "owner", label: "Owner" },
53 { value: "admin", label: "Admin" },
54 { value: "member", label: "Member" },
55 { value: "billing", label: "Billing" },
56 ]}
57 />
58 <FormSwitch
59 label="Email notifications"
60 description="Digest of deploys and failed checks."
61 />
62 <FormSlider
63 label="Concurrent builds"
64 hint="Parallel jobs allowed per workspace (1–16)."
65 defaultValue={[4]}
66 min={1}
67 max={16}
68 step={1}
69 showValue
70 />
71</div>
Loading state
Use state="loading" to show a spinner on supported controls
1import { FormInput, FormSelect } from "@/registry/ui/form-fields"
2
3<div className="mx-auto w-full max-w-lg space-y-6 text-left">
4 <FormInput label="Verifying domain" state="loading" readOnly value="example.com" />
5 <FormSelect
6 label="Importing"
7 state="loading"
8 options={[{ value: "x", label: "Placeholder" }]}
9 />
10</div>

Props

NameTypeDefaultDescription
ValidationStatetype"default" | "error" | "success" | "loading" — inferred from error/success strings unless state is set
FormInput / FormTextareacomponentslabel, hint, error, success, state, required, disabled; FormInput adds leftIcon, rightIcon; FormTextarea adds showCount with maxLength
FormSelectcomponentoptions { value, label, disabled }[], value, onValueChange, searchable, searchPlaceholder, emptyMessage
FormSwitchcomponentlabel, description, hint, error, success, checked, onCheckedChange
FormSlidercomponentmin, max, step, defaultValue, value, onValueChange, showValue, formatValue