Choice3 checks
FormSelect
One option from a list of any size.
Example
Installation
bunx --bun shadcn@latest add @fieldkit/form-selectNeeds the @fieldkit registry. Add it once
Usage
- 1
Add the field to your schema
schema.tsimport { z } from "zod"import { optionField } from "@/lib/field-schemas" export const schema = z.object({ country: optionField(countryCodes, "Choose a country"),}) - 2
Render it inside a Form
The name prop matches the schema key.
example-form.tsximport { Form } from "@/components/form/form"import { FormSelect } from "@/components/form/form-select"import { FormSubmit } from "@/components/form/form-submit"import { FieldGroup } from "@/components/ui/field"import { schema } from "./schema" export function ExampleForm() { return ( <Form schema={schema} defaultValues={{ country: "" }} onSubmit={save} > <FieldGroup> <FormSelect name="country" options={countries} /> <FormSubmit>Save</FormSubmit> </FieldGroup> </Form> )}
Checks
CheckOptionError message
One of the options
optionFieldChoose a countrySearch
search, auto above 10, always above 100NoneVirtualized list
auto above 100NoneSame list, more inputs
FormMultiSelect and FormCombobox share the option list, search and virtualization.
Long lists
Above 100 options the list renders only the rows in view with TanStack Virtual. The preview above lists every country.
Terminal
const virtualizer = useVirtualizer({ count: options.length, getScrollElement: () => listRef.current, estimateSize: () => 32, overscan: 8,})Best practices
- Use FormRadioGroup for 5 options or fewer
- Long lists render only the rows in view
Try these values
Terminal
optionField(["admin", "editor", "viewer"], "Choose a role")| Input | Result | Output |
|---|---|---|
"editor" | Valid | "editor" |
"owner" | Invalid | Choose a role |
"" | Invalid | Choose a role |
API reference
FormSelect
PropDescription
options (required)Array<{ value, label, keywords?, hint?, disabled? }>The choices.searchbooleanSearchable list. On by default above 10 options.placeholderstring = "Choose an option"Shown when empty.Field frame
PropDescription
namestringKey in the schema. Also picks the preset label and autocomplete.labelReact.ReactNodeOverrides the preset label. Pass null to hide it.descriptionReact.ReactNodeHint under the control.requiredbooleanOverrides the asterisk read from the schema.fieldPropsFormFieldPropsProps for the wrapping Field, such as className.