Single-value dropdown picker built on Base UI Select. Renders a labelled input-style trigger with a floating option list.
Reach for Select when the user picks one value from a fixed list and no text filtering is needed.
Combobox.MultiSelect.Use @uxf/ui/select for a controlled select outside a form. Inside a @uxf/form form, use @uxf/form/select instead — it registers the field with react-hook-form and derives isInvalid / helperText from validation. This @uxf/ui component is the controlled primitive the form twin wraps.
import { Select, SelectOption } from "@uxf/ui/select";
import { useState } from "react";
const options: SelectOption[] = [
{ id: "one", label: "Option one" },
{ id: "two", label: "Option two", disabled: true },
{ id: "three", label: "Option three" },
];
function Example() {
const [value, setValue] = useState<string | number | null>(null);
return (
<Select
label="Choose an option"
name="example"
onChange={setValue}
options={options}
placeholder="Select..."
value={value}
/>
);
}
value is the selected option's id (string | number) or null, and onChange is called with the new id — not the option object.
Exports: Select and the types SelectProps, SelectOption, SelectValue.
SelectProps<Value = SelectValue, Option = SelectOption<Value>> extends FormControlProps<Value | null> and Clearable. SelectValue is number | string; SelectOption is { id: Value; label: ReactNode; disabled?: boolean }.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Required. Field label. |
name | string | — | Required. Field name (also set as data-name). |
value | Value | null | — | Required. Selected option id, or null. |
onChange | (value: Value | null) => void | — | Required. Called with the newly selected id (or null when cleared). |
options | Option[] | — | Required. Selectable options. |
placeholder | string | — | Shown when no option is selected. |
helperText | ReactNode | — | Text under the control; styled as an error when isInvalid. |
isClearable | boolean | false | Show a clear button that resets the value to null. |
isDisabled | boolean | false | Disable the control. |
isReadOnly | boolean | false | Prevent changes while staying focusable. |
isInvalid | boolean | false | Invalid styling; sets aria-invalid and styles helperText as an error. |
isRequired | boolean | false | Mark the field required (adds the label indicator). |
hiddenLabel | boolean | false | Visually hide the label (kept for assistive tech). |
renderOption | (option: Option, isSelected: boolean) => ReactNode | option.label | Custom renderer for each dropdown option. |
renderSelectedOption | (option: Option) => ReactNode | option.label | Custom renderer for the selected value in the trigger. |
keyExtractor | (option: Option) => string | number | option.id | Custom React key for options. |
noOptionsMessage | string | localized "No items found" | Empty-list message. |
iconName | IconName | arrow icon | Icon for the dropdown arrow. |
size | InputGroupSize | "default" | "small", "default", or "large". |
variant | InputGroupVariant | "default" | Input group variant. |
id | string | auto (useId) | Root id; the error-message id derives from it. |
onBlur / onFocus | FocusEventHandler<HTMLInputElement> | — | Focus handlers. |
Layout, dropdown, and ref props: className, style, form, leftAddon, rightAddon, leftElement, rightElement, inputArrow, dropdownClassName, dropdownMatchesInputWidth (default true), dropdownMaxHeight (default 240), dropdownPlacement (default "bottom"), dropdownStrategy, inputRef, inputGroupRef, inputWrapperRef.
small, default, large (via size).isInvalid; combine with helperText to show an error message.isDisabled blocks all interaction; isReadOnly keeps focus but prevents changes.isClearable, a remove button appears once a value is selected (unless disabled/read-only).dropdownPlacement="top" flips the list above the input; Floating UI auto-flips on collision.The component composes the input, label, dropdown, form-component, and icon primitives, so import all of their stylesheets once in your global CSS:
@import url("@uxf/ui/css/icon.css");
@import url("@uxf/ui/css/dropdown.css");
@import url("@uxf/ui/css/label.css");
@import url("@uxf/ui/css/form-component.css");
@import url("@uxf/ui/css/input-basic.css");
@import url("@uxf/ui/css/input.css");
@import url("@uxf/ui/css/select.css");
Also requires the global @uxf/ui token layer, set up once per app — see @uxf/ui setup.