formsselect
Select
Dropdown select component with search and custom item rendering.
Import#
Slot Structure#
Trigger control and a floating listbox with grouped options. The control or search input keeps focus while options provide selection, highlight, and active-descendant semantics.
Control#
Listbox#
Examples#
Single Select#
Basic single selection with controlled value.
Variants#
Visual style variants.
Sizes#
From xs to xl.
Disabled#
Non-interactive state.
Searchable#
Type to filter options.
Grouped Options#
Options organized in sections.
Infinite Scroll#
Scroll to the bottom to load more options.
Virtual Rendering#
Import useListVirtualizer from moraine/utils to render only visible entries. Pass its virtualRender to Select and forward scrollToItem to its scrollToIndex method so keyboard highlighting can reveal off-screen options.
Install the adapter’s optional peer dependency before using it:
API Reference#
Attributes#
Slot
root3 attributesSelect root that owns open state, value display, and popup positioning.
Data Attributes
| Data Attribute | Description |
|---|---|
| data-disabled | Present when the component or item is disabled. |
| data-invalid | Present when the field has a validation error. |
| data-required | Present when the field is required. |
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | — | Class applied to the component root or trigger element. |
| classes | SelectT.Classes | undefined | — | — |
| closeIcon | IconT.Name | — | Icon kept for API compatibility; Select has no clear action. |
| defaultOpen | boolean | undefined | false | Initial open state. |
| defaultSearchValue | string | undefined | — | Default search value. |
| defaultValue | TItem | null | undefined | — | The default value of the input (uncontrolled). |
| disabled | boolean | undefined | false | Whether the input is disabled. |
| emptyRender | ComponentOrElement<SelectT.EmptyRenderProps<TItem>> | undefined | — | Custom renderer for the empty state when current filtered result has no matches. |
| filterOption | boolean | "startsWith" | "endsWith" | "contains" | ((inputValue: string, option: SelectT.Item<TItem>) => boolean) | undefined | true | Filter function or boolean. `false` disables filtering. |
| gutter | number | undefined | 0 | Gap (px) between the control and popup content. |
| id | string | undefined | — | The ID of the input element. |
| itemProps | ((option: SelectT.Item<TItem> & BaseSelectT.OptionRenderState) => ElementProps<HTMLDivElement> | undefined) | undefined | — | Additional attributes for an option row. |
| labelRender | ComponentOrElement<SelectT.LabelRenderProps<TItem>> | undefined | — | Custom renderer for the option label text. |
| leadingIcon | IconT.Name | — | Icon shown before the input/value area. |
| listboxProps | ElementProps<HTMLDivElement> | undefined | — | Additional attributes for the listbox element. |
| loading | boolean | undefined | — | Whether the select is in a loading state. |
| loadingIcon | IconT.Name | icon-loading | Icon shown during loading state. |
| name | string | undefined | — | The name of the input element, used for form submission. |
| onChange | ((value: NoInfer<TItem | null>) => void) | undefined | — | Called when the selection changes. |
| onOpenChange | ((open: boolean) => void) | undefined | — | Called whenever the popup open state changes. |
| onScrollBottom | (() => void) | undefined | — | Called when the listbox is scrolled to bottom. Useful for infinite loading scenarios. Make sure to set `overflowPadding` and `scrollBottomThreshold` appropriately to ensure the callback is triggered at the right time. |
| onSearch | ((value: string) => void) | undefined | — | Called when the search input changes. |
| open | boolean | undefined | — | Controlled open state. |
| optionRender | ComponentOrElement<SelectT.OptionRenderProps<TItem>> | undefined | — | Custom renderer for each option in the dropdown. Passes `null` for empty state. |
| options | SelectT.Item<TItem>[] | undefined | — | Available options. |
| overflowPadding | number | undefined | 4 | Padding (px) used when calculating popup overflow and viewport collision. |
| placeholder | string | undefined | — | Placeholder text shown when no value is selected. |
| ref | JSX.HTMLElementTags["div"] extends { ref?: infer Ref; } ? Ref : never | undefined | — | — |
| required | boolean | undefined | false | Whether the input is required. |
| scrollBottomThreshold | number | undefined | 20 | Distance (px) from the bottom at which onScrollBottom fires. |
| scrollToItem | ((item: SelectT.Item<TItem>, entryIndex: number) => void) | undefined | — | Scrolls a highlighted option into view using its flattened entry index. |
| search | boolean | undefined | false | Enable search input. |
| searchMaxLength | number | undefined | — | Maximum search text length applied on final commit. |
| searchValue | string | undefined | — | Controlled search value. |
| size | "xs" | "sm" | "md" | "lg" | "xl" | undefined | — | — |
| style | JSX.CSSProperties | undefined | — | — |
| styles | SelectT.Styles | undefined | — | — |
| trailingIcon | IconT.Name | icon-chevron-down | Icon for the dropdown trigger. |
| value | TItem | null | undefined | — | The current value of the input (controlled). |
| variant | "none" | "outline" | "ghost" | "subtle" | undefined | — | — |
| virtualRender | Component<SelectT.VirtualRenderProps<TItem>> | undefined | — | Renders flattened group labels and options through a virtualization layer. |
Items#
| Prop | Type | Default | Description |
|---|---|---|---|
| children | Omit<BaseSelectT.Item<SelectT.Value>, "children">[] | undefined | — | One-layer child options for grouped select. |
| description | string | JSX.Element | — | Description shown below the label. |
| disabled | boolean | undefined | — | Whether the option is disabled. |
| icon | IconT.Name | — | Icon shown next to the label. |
| key | string | undefined | — | Text key used for filtering and matching; set this when `label` is not a string. |
| label | string | JSX.Element | — | Label to display for the option, or the option group title. |
| value | SelectT.Value | undefined | — | Value of the option. |