components / select
Select
Accessible combobox with keyboard navigation, type-to-search and a detailed style with an icon/description per option.
How to use
Accessible combobox (`role="combobox"` + `listbox`) with keyboard navigation, typeahead and controlled or uncontrolled selection. Enable `searchable` to filter by text and `variant="detailed"` for options with `leading` and `description`.
preview
Select.tsx
import { Select } from "vaiperui"; <Select label="Country" placeholder="Choose a country" searchable options={[ { value: "br", label: "Brazil" }, { value: "us", label: "United States" }, { value: "pt", label: "Portugal" }, ]}/>Colors
preview
colors.tsx
<Select variantColor="primary" label="Country" options={options} /><Select variantColor="success" label="Country" options={options} /><Select variantColor="warning" label="Country" options={options} /><Select variantColor="danger" label="Country" options={options} />Styles
`detailed` enlarges the trigger and the options, with a `leading` slot and a `description` per item.
preview
styles.tsx
<Select variant="default" label="Country" options={options} /><Select variant="detailed" label="Country" options={options} />Sizes
preview
sizes.tsx
<Select size="sm" label="Country" options={options} /><Select size="md" label="Country" options={options} /><Select size="lg" label="Country" options={options} />Radius
preview
radius.tsx
<Select radius="none" label="Country" options={options} /><Select radius="sm" label="Country" options={options} /><Select radius="md" label="Country" options={options} /><Select radius="lg" label="Country" options={options} /><Select radius="full" label="Country" options={options} />Search
`searchable` adds a field to filter the options by text.
preview
search.tsx
<Select searchable label="Country" options={options} /><Select searchable searchStyle="full" label="Country" options={options} /><Select label="Country" options={options} />States
`disabled` blocks the whole select. An option with `disabled: true` appears blocked and cannot be chosen.
preview
states.tsx
<Select label="Country" options={options} disabled /> const options = [ { value: "br", label: "Brazil" }, { value: "pt", label: "Portugal", disabled: true },]Custom color
`customColor` overrides `variantColor` and paints focus, border and highlight from a single color.
preview
custom-color.tsx
<Select customColor="#ff6600" label="Country" options={options} /><Select customColor="#22c55e" label="Country" options={options} /><Select customColor="#a78bfa" label="Country" options={options} />Props
| Prop | Values | Default | Description |
|---|---|---|---|
| options | SelectOption[] | — | List of options ({ value, label, disabled?, description?, leading? }) |
| value / defaultValue | string | — | Controlled / uncontrolled |
| onValueChange | (value: string) => void | — | Fired when an option is selected |
| placeholder | string | "Select an option" | Text shown when nothing is selected |
| emptyMessage | string | "No options found" | Text when there are no options |
| noResultsMessage | (query: string) => string | (query) => `No results for "${query}"` | Text when a search has no matches; receives the typed query |
| searchable | boolean | false | Shows a search field inside the menu to filter by text |
| searchPlaceholder | string | "Search..." | Search field placeholder |
| clearSearchLabel | string | "Clear search" | Accessible name of the button that clears the search |
| searchStyle | "boxed" | "full" | "boxed" | `boxed`: inset, rounded field. `full`: the field spans the whole top of the menu, with a divider |
| variant | default | detailed | default | default: compact single-line dropdown. detailed: larger trigger and options, with leading and description per option and a tint on the selected one |
| variantColor | primary | success | warning | danger | primary | Focus color, open border and option highlight |
| customColor | valid CSS color | { light, dark } | — | Overrides variantColor: paints focus, border and highlight from a single color, or from a { light, dark } object |
| size | sm | md | lg | md | Height of the trigger and the options |
| radius | none | sm | md | lg | full | md | Rounding of the trigger and the menu |
| animation | none | smooth | fast | bounce | smooth | Menu transition |
| disabled | boolean | false | Disables the whole select |
| name | string | — | Mirrors the value into an <input type="hidden"> for form submission |
| label / aria-label / id / className / style | string / string / string / string / CSSProperties | — | Label above the trigger, accessible name when there is no label, and layout props |
| option.leading / option.description | ReactNode / string | — | Visual slot (flag, icon, avatar) before the text, and a second line per option. The slot works in both variants; the description only renders with variant="detailed" |