Choice3 checks

FormSelect

One option from a list of any size.

Example
Installation
bunx --bun shadcn@latest add @fieldkit/form-select

Needs the @fieldkit registry. Add it once

Usage
  1. 1

    Add the field to your schema

    schema.ts
    import { z } from "zod"import { optionField } from "@/lib/field-schemas"
    export const schema = z.object({  country: optionField(countryCodes, "Choose a country"),})
  2. 2

    Render it inside a Form

    The name prop matches the schema key.

    example-form.tsx
    import { 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
One of the optionsoptionFieldChoose a country
Searchsearch, auto above 10, always above 100None
Virtualized listauto above 100None
Same 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")
InputResultOutput
"editor"Valid"editor"
"owner"Invalid
Choose a role
""Invalid
Choose a role
API reference

FormSelect

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

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.

Search docs

Find a component, input or example