Search

Search the site

All components

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

Installation & source

Install via the shadcn CLI or copy the registry files manually.

bash
npx shadcn@latest add @tt-ui/form-fields

Props

NameTypeDefaultDescription
ValidationStatetype-"default" | "error" | "success" | "loading" - inferred from error/success strings unless state is set
FormInput / FormTextareacomponents-label, hint, error, success, state, required, disabled; FormInput adds leftIcon, rightIcon; FormTextarea adds showCount with maxLength
FormSelectcomponent-options { value, label, disabled }[], value, onValueChange, searchable, searchPlaceholder, emptyMessage
FormSwitchcomponent-label, description, hint, error, success, checked, onCheckedChange
FormSlidercomponent-min, max, step, defaultValue, value, onValueChange, showValue, formatValue