Select

A select displays a collapsible list of options and allows a user to select one or more of them.


Installation

npx nextui-cli@latest add select
No need to install this package if @nextui-org/react is already installed globally.

Import

NextUI exports 3 select-related components:

  • Select: The main component, which is a wrapper for the other components.
  • SelectSection: The component that contains a group of select items.
  • SelectItem: The component that represents a select item.

Usage

Dynamic items

Select follows the Collection Components API, accepting both static and dynamic collections.

  • Static: The usage example above shows the static implementation, which can be used when the full list of options is known ahead of time.
  • Dynamic: The example below can be used when the options come from an external data source such as an API call, or update over time.

Multiple Selection

You can use the selectionMode="multiple" property to allow multiple selection.

Disabled

Disabled Items

You can disable specific items by using the disabledKeys property.

Required

If you pass the isRequired property to the select, it will have a danger asterisk at the end of the label and the select will be required.

Sizes

Colors

Variants

Radius

Label Placements

You can change the position of the label by setting the labelPlacement property to inside, outside or outside-left.

Note: If the label is not passed, the labelPlacement property will be outside by default.

Start Content

You can use the startContent and endContent properties to add content to the start and end of the select.

Item Start & End Content

Since the Select component uses the Listbox component under the hood, you can use the startContent and endContent properties of the SelectItem component to add content to the start and end of the select item.

Custom Selector Icon

By default the select uses a chevron-down icon as the selector icon which rotates when the select is open. You can customize this icon by passing a custom one to the selectorIcon property.

Note: Use the disableSelectorIconRotation property to disable the rotation of the icon.

Without Scroll Shadow

Select component uses the ScrollShadow under the hood to show a shadow when the select content is scrollable. You can disable this shadow by passing using the scrollShadowProps property.

Note: You can also use the showScrollIndicators property to disable the scroll indicators.

With Description

You can add a description to the select by passing the description property.

With Error Message

You can combine the isInvalid and errorMessage properties to show an invalid select.

Controlled

You can use the selectedKeys and onSelectionChange / onChange properties to control the select value.

Using onSelectionChange:

Using onChange:

Controlling the open state

You can control the open state of the select by using the isOpen and onOpenChange / onClose properties.

Custom Items

You can customize the select items by modifying the SelectItem children.

Custom Render Value

By default the select will render the selected item's text value, but you can customize this by passing a renderValue function.

The renderValue function receives the selected items as a parameter and must return a ReactNode. Check the Render Value Function section for more details.

Asynchronous Loading

Select supports asynchronous loading, in the example below we are using a custom hook to fetch the Pokemon API data in combination with the useInfiniteScroll hook to load more data when the user reaches the end of the list.

The isLoading prop is used to show a loading indicator instead of the selector icon when the data is being fetched.

npm install @nextui-org/use-infinite-scroll
import {useInfiniteScroll} from "@nextui-org/use-infinite-scroll";

With Sections

You can use the SelectSection component to group select items.

Custom Sections Style

You can customize the sections style by using the classNames property of the SelectSection component.

Multiple Select Controlled

You can use the same properties as the single select to control the multiple select, selectedKeys and onSelectionChange / onChange.

Using onSelectionChange:

Using onChange:

Multiple With Chips

You can render any component as the select value by using the renderValue property. In this example we are using the Chip component to render the selected items.

Note: Make sure to pass the isMultiline property to the Select component to allow the chips to wrap.

The renderValue function receives the selected items as a parameter and must return a ReactNode. Check the Render Value Function section for more details.

Customizing the select

You can customize any slot of the select by using the classNames property. Select component also provides the popoverProps and listboxProps properties to customize the popover and listbox components.

Slots

  • base: The main wrapper of the select. This wraps the rest of the slots.
  • label: The label of the select.
  • mainWrapper: Wraps the helperWrapper and the trigger slots.
  • trigger: The trigger of the select. This wraps the label the inner wrapper and the selector icon.
  • innerWrapper: The wrapper of the select content. This wraps the start/end content and the select value.
  • selectorIcon: The selector icon of the select. This is the icon that rotates when the select is open (data-open).
  • value: The select value. This is also the slot that wraps the renderValue function result.
  • listboxWrapper: The wrapper of the listbox. This wraps the listbox component, this slot is used on top of the scroll shadow component.
  • listbox: The listbox component. This is the component that wraps the select items.
  • popoverContent: The popover content slot. Use this to modify the popover content styles.
  • helperWrapper: The wrapper of the helper text. This wraps the helper text and the error message.
  • description: The description of the select.
  • errorMessage: The error message of the select.

Data Attributes

Select has the following attributes on the base element:

  • data-filled: Indicates if the select has a value, is focused, has start/end content or is open.

Select has the following attributes on the trigger element:

  • data-open: Indicates if the select is open.
  • data-disabled: When the select trigger is disabled. Based on select isDisabled prop.
  • data-focus: When the select trigger is being focused. Based on useFocusRing.
  • data-focus-visible: When the select trigger is being focused with the keyboard. Based on useFocusRing.
  • data-pressed: When the select trigger is pressed. Based on usePress
  • data-hover: When the select trigger is being hovered. Based on useHover

Select has the following attributes on the selectorIcon element:

  • data-open: Indicates if the select is open.

SelectItem has the following attributes on the base element:

  • data-disabled: When the select item is disabled. Based on select disabledKeys prop.
  • data-selected: When the select item is selected. Based on select selectedKeys prop.
  • data-hover: When the select item is being hovered. Based on useHover
  • data-pressed: When the select item is pressed. Based on usePress
  • data-focus: When the select item is being focused. Based on useFocusRing.
  • data-focus-visible: When the select item is being focused with the keyboard. Based on useFocusRing.

Accessibility

  • Exposed to assistive technology as a button with a listbox popup using ARIA (combined with Listbox).
  • Support for selecting a single option.
  • Support for selecting multiple options.
  • Support for disabled options.
  • Support for sections.
  • Labeling support for accessibility.
  • Support for description and error message help text linked to the input via ARIA.
  • Support for mouse, touch, and keyboard interactions.
  • Tab stop focus management.
  • Keyboard support for opening the listbox using the arrow keys, including automatically focusing the first or last item accordingly.
  • Typeahead to allow selecting options by typing text, even without opening the listbox.
  • Browser autofill integration via a hidden native <select> element.
  • Support for mobile form navigation via software keyboard.
  • Mobile screen reader listbox dismissal support.

API

Select Props

AttributeTypeDescriptionDefault
children*ReactNode[]The children to render. Usually a list of SelectItem and SelectSection elements.-
itemsIterable<T>Item objects in the select. (dynamic)-
selectionModesingle | multipleThe type of selection that is allowed in the collection.-
selectedKeysall | React.Key[]The currently selected keys in the collection (controlled).-
disabledKeysall | React.Key[]The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.-
defaultSelectedKeysall | React.Key[]The initial selected keys in the collection (uncontrolled).-
variantflat | bordered | faded | underlinedThe variant of the select.flat
colordefault | primary | secondary | success | warning | dangerThe color of the select.default
sizesm | md | lgThe size of the select.md
radiusnone | sm | md | lg | fullThe radius of the select.-
placeholderstringThe placeholder of the select.Select an option
labelPlacementinside | outside | outside-leftThe position of the label.inside
labelReactNodeThe content to display as the label.-
descriptionReactNodeA description for the select. Provides a hint such as specific requirements for what to choose.-
errorMessageReactNode | ((v: ValidationResult) => ReactNode)An error message for the select.-
startContentReactNodeElement to be rendered in the left side of the select.-
endContentReactNodeElement to be rendered in the right side of the select.-
selectorIconReactNodeElement to be rendered as the selector icon.-
scrollRefReact.RefObject<HTMLElement>A ref to the scrollable element.-
spinnerRefReact.RefObject<HTMLElement>A ref to the spinner element.-
fullWidthbooleanWhether the select should take up the width of its parent.true
isOpenbooleanWhether the select is open by default (controlled).-
defaultOpenbooleanWhether the select is open by default (uncontrolled).-
isRequiredbooleanWhether user select is required on the select before form submission.false
isDisabledbooleanWhether the select is disabled.false
isMultilinebooleanWhether the select should allow multiple lines of text.false
isInvalidbooleanWhether the select is invalid.false
validationStatevalid | invalidWhether the select should display its "valid" or "invalid" visual styling. (Deprecated) use isInvalid instead.-
showScrollIndicatorsbooleanWhether the select should show scroll indicators when the listbox is scrollable.true
autoFocusbooleanWhether the select should be focused on the first mount.false
disallowEmptySelectionbooleanWhether the collection allows empty selection.false
disableAnimationbooleanWhether the select should be animated.true
disableSelectorIconRotationbooleanWhether the select should disable the rotation of the selector icon.false
popoverPropsPopoverPropsProps to be passed to the popover component.-
listboxPropsListboxPropsProps to be passed to the listbox component.-
scrollShadowPropsScrollShadowPropsProps to be passed to the scroll shadow component.-
classNamesRecord<"base"| "label"| "trigger"| "mainWrapper" | "innerWrapper"| "selectorIcon" | "value" | "listboxWrapper"| "listbox" | "popoverContent" | "helperWrapper" | "description" | "errorMessage", string>Allows to set custom class names for the Select slots.-

Select Events

AttributeTypeDescription
onClose() => voidCallback fired when the select popover is closed.
onOpenChange(isOpen: boolean) => voidCallback fired when the select popover is opened or closed.
onSelectionChange(keys: React.Key[]) => voidCallback fired when the selected keys change.
onChangeReact.ChangeEvent<HTMLSelectElement>Native select change event, fired when the selected value changes.
renderValueRenderValueFunctionFunction to render the value of the select. It renders the selected item by default.

SelectItem Props

Check the ListboxItem props.

SelectItem Events

Check the ListboxItem events.

SelectSection Props

Check the ListboxSection props.


Types

Render Value Function

The T type is the type of the data passed to the select items.

export type SelectedItemProps<T> = {
/** A unique key for the item. */
key?: Key;
/** The props passed to the item. */
props?: Record<string, any>;
/** The item data. */
data?: T | null;
/** An accessibility label for this item. */
"aria-label"?: string;
/** The rendered contents of this item (e.g. JSX). */
rendered?: ReactNode;
/** A string value for this item, used for features like typeahead. */
textValue?: string;
/** The type of item this item represents. */
type?: string;
};
type SelectedItems<T> = Array<SelectedItemProps<T>>;
renderValue: (items: SelectedItems<T>) => ReactNode;