Skip to content
Browse documentation
DocsComponents

Dropdown

Pick a single value from a list of options.

Installation

Terminal
pnpm dlx shadcn@latest add https://react-toolbox.io/r/dropdown.json

New here? Set up your project first. Styles, fonts, and required components are included.

Usage

Options use value and label by default. Supply valueKey and labelKey for a different data shape, or template for custom option content.

Use the Code tab above for a complete example. The import follows your configured UI alias. See Theming to customize colors, spacing, and style slots.

State and callbacks

Dropdown selection is controlled by value and onChange. The component manages the popup and keyboard highlight internally. There is no defaultValue API.

When allowBlank is false, the first enabled source item is displayed if value does not match an item. Keep your application value synchronized explicitly; this fallback does not emit a selection change.

API reference

Generated from the installed TypeScript source. Defaults are the values declared by each function; a dash means no parameter default is declared. Forwarded props can use the receiving component’s default. Callback types show the exact arguments passed to your handler.

Dropdown

PropertyTypeDefault
errorReact.ReactNode—
floatingboolean—
hintReact.ReactNode—
iconReact.ReactNode—
labelReact.ReactNode—
multilineboolean—
rowsnumber—
refReact.Ref<InputHandle>—
classNamesDropdownTheme

Classes for the component's rendered parts. Applied after legacy theme overrides.

—
allowBlankbooleantrue
autobooleantrue
sourceRequiredreadonly (T | DropdownValue)[]—
labelKeykeyof T'label' as keyof T
valueKeykeyof T'value' as keyof T
valueDropdownValue—
themeDeprecated aliasDropdownTheme

Use classNames for style slots; use ThemeProvider for design tokens.

—

Callbacks

PropertyTypeDefault
template(item: T) => React.ReactNode—
onChange(value: DropdownValue, event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void—
onBlur(event: React.FocusEvent<HTMLElement> | React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void—
onFocusReact.FocusEventHandler<HTMLElement>—
onClickReact.MouseEventHandler<HTMLElement>—
onKeyDownReact.KeyboardEventHandler<HTMLElement>—

Also inherits Omit<Omit<React.InputHTMLAttributes<InputElement>, 'onChange' | 'size'>, 'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onClick' | 'theme'>, except the omissions and overrides in its exported props type below. Use the supported native aria-*, data-*, event, and element attributes as appropriate.

Additional defaults on inherited props: className = ''; disabled = false; required = false.

Style slots

Pass a map of Tailwind classes to classNames. Available keys:

  • active
  • disabled
  • dropdown
  • error
  • errored
  • field
  • label
  • required
  • selected
  • templateValue
  • up
  • value
  • values

theme is the deprecated compatibility alias. When both are provided, classNames wins conflicting utilities within each slot. See Theming for tokens and override rules.

Exported TypeScript types

Expand a type to inspect its full declaration, including generic constraints, union branches, callback arguments, ref handles, and inherited props. Import these types from @/components/ui/material/dropdown.

DropdownValue
tsx
type DropdownValue = string | number;
DropdownItem
tsx
interface DropdownItem {
  value: DropdownValue;
  label: React.ReactNode;
  disabled?: boolean;
}
DropdownTheme
tsx
type DropdownTheme = Partial<
  Record<
    | 'active'
    | 'disabled'
    | 'dropdown'
    | 'error'
    | 'errored'
    | 'field'
    | 'label'
    | 'required'
    | 'selected'
    | 'templateValue'
    | 'up'
    | 'value'
    | 'values',
    string
  >
>;
DropdownClassNames
tsx
type DropdownClassNames = DropdownTheme;
DropdownEvent
tsx
type DropdownEvent = React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>;
DropdownProps
tsx
interface DropdownProps<T extends object = DropdownItem>
  extends Omit<
    InputProps,
    'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onClick' | 'theme'
  > {
  allowBlank?: boolean;
  auto?: boolean;
  source: readonly (T | DropdownValue)[];
  labelKey?: keyof T;
  valueKey?: keyof T;
  value?: DropdownValue;
  template?: (item: T) => React.ReactNode;
  onChange?: (value: DropdownValue, event: DropdownEvent) => void;
  onBlur?: (event: React.FocusEvent<HTMLElement> | DropdownEvent) => void;
  onFocus?: React.FocusEventHandler<HTMLElement>;
  onClick?: React.MouseEventHandler<HTMLElement>;
  onKeyDown?: React.KeyboardEventHandler<HTMLElement>;
  /** Classes for the component's rendered parts. Applied after legacy theme overrides. */
  classNames?: DropdownTheme;
  /** @deprecated Use classNames for style slots; use ThemeProvider for design tokens. */
  theme?: DropdownTheme;
}

Material guidelines

  • Use a labeled dropdown to choose one value from a defined set. Keep the selected value visible when the options close.
  • Keep options concise. If a choice needs lengthy explanation or a separate confirmation, consider a selection dialog instead.

Material Design 1: Text fields