HeroUI

SelectUpdated

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

Import

import {Select} from "@heroui/react";

Usage

State
import {Label, ListBox, Select} from "@heroui/react";

export function Default() {
  return (
    <Select className="w-[256px]" placeholder="Select one">

Anatomy

Import the Select component and access all parts using dot notation.

import {Select, Label, Description, Header, ListBox, Separator} from "@heroui/react";

export default () => (
  <Select>
    <Label />
    <Select.Trigger>
      <Select.Value />
      <Select.Indicator />
    </Select.Trigger>
    <Description />
    <Select.Popover>
      <ListBox>
        <ListBox.Item>
          <Label />
          <Description />
          <ListBox.ItemIndicator />
        </ListBox.Item>
        <ListBox.Section>
          <Header />
          <ListBox.Item>
            <Label />
          </ListBox.Item>
        </ListBox.Section>
      </ListBox>
    </Select.Popover>
  </Select>
);

With Description

StateSelect your state of residence
import {Description, Label, ListBox, Select} from "@heroui/react";

export function WithDescription() {
  return (
    <Select className="w-[256px]" placeholder="Select one">

Multiple Select

Countries to Visit
import {Label, ListBox, Select} from "@heroui/react";

export function MultipleSelect() {
  return (
    <Select className="w-[256px]" placeholder="Select countries" selectionMode="multiple">

With Sections

Country
import {Header, Label, ListBox, Select, Separator} from "@heroui/react";

export function WithSections() {
  return (
    <Select className="w-[256px]" placeholder="Select a country">

With Disabled Options

Animal
import {Label, ListBox, Select} from "@heroui/react";

export function WithDisabledOptions() {
  return (
    <Select className="w-[256px]" disabledKeys={["cat", "kangaroo"]} placeholder="Select an animal">

With Autocomplete

Countries to Visit
"use client";

import {Label, ListBox, SearchField, Select, Tag, TagGroup} from "@heroui/react";
import {Autocomplete, useFilter} from "react-aria-components";

Custom Indicator

State
import {ChevronsExpandVertical} from "@gravity-ui/icons";
import {Label, ListBox, Select} from "@heroui/react";

export function CustomIndicator() {
  return (

Required

State
Country
"use client";

import {Button, FieldError, Form, Label, ListBox, Select} from "@heroui/react";

export function Required() {

Full Width

Favorite Animal
import {Label, ListBox, Select} from "@heroui/react";

export function FullWidth() {
  return (
    <div className="w-[400px] space-y-4">

On Surface

State
Country
"use client";

import {Button, FieldError, Form, Label, ListBox, Select, Surface} from "@heroui/react";

export function OnSurface() {

Custom Value

User
"use client";

import {
  Avatar,
  AvatarFallback,

Controlled

State (controlled)

Selected: California

"use client";

import type {Key} from "react-aria-components";

import {Label, ListBox, Select} from "@heroui/react";

Controlled Multiple

States (controlled multiple)

Selected: california, texas

"use client";

import type {Key} from "@heroui/react";

import {Label, ListBox, Select} from "@heroui/react";

Controlled Open State

State

Select is closed

"use client";

import {Button, Label, ListBox, Select} from "@heroui/react";
import {useState} from "react";

Asynchronous Loading

Pick a Pokemon
"use client";

import {Label, ListBox, Select, Spinner} from "@heroui/react";
import {useAsyncList} from "@react-stately/data";
import {Collection, ListBoxLoadMoreItem} from "react-aria-components";

Disabled

State
Countries to Visit
import {Label, ListBox, Select} from "@heroui/react";

export function Disabled() {
  return (
    <div className="flex flex-col gap-4">

Styling

Passing Tailwind CSS classes

import {Select} from "@heroui/react";

function CustomSelect() {
  return (
    <Select className="w-full">
      <Label>State</Label>
      <Select.Trigger className="rounded-lg border bg-surface p-2">
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Popover>
        <ListBox>
          <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
            Item 1
          </ListBox.Item>
        </ListBox>
      </Select.Popover>
    </Select>
  );
}

Customizing the component classes

To customize the Select component classes, you can use the @layer components directive.


Learn more.

@layer components {
  .select {
    @apply flex flex-col gap-1;
  }

  .select__trigger {
    @apply rounded-lg border border-border bg-surface p-2;
  }

  .select__value {
    @apply text-current;
  }

  .select__indicator {
    @apply text-muted;
  }

  .select__popover {
    @apply rounded-lg border border-border bg-surface p-2;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Select component uses these CSS classes (View source styles):

Base Classes

  • .select - Base select container
  • .select__trigger - The button that triggers the select
  • .select__value - The displayed value or placeholder
  • .select__indicator - The dropdown indicator icon
  • .select__popover - The popover container

Variant Classes

  • .select__trigger--on-surface - On surface variant styling

State Classes

  • .select[data-invalid="true"] - Invalid state
  • .select__trigger[data-focus-visible="true"] - Focused trigger state
  • .select__trigger[data-disabled="true"] - Disabled trigger state
  • .select__value[data-placeholder="true"] - Placeholder state
  • .select__indicator[data-open="true"] - Open indicator state

Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover or [data-hovered="true"] on trigger
  • Focus: :focus-visible or [data-focus-visible="true"] on trigger
  • Disabled: :disabled or [data-disabled="true"] on select
  • Open: [data-open="true"] on indicator

API Reference

Select Props

PropTypeDefaultDescription
placeholderstring'Select an item'Temporary text that occupies the select when it is empty
selectionMode"single" | "multiple""single"Whether single or multiple selection is enabled
isOpenboolean-Sets the open state of the menu (controlled)
defaultOpenboolean-Sets the default open state of the menu (uncontrolled)
onOpenChange(isOpen: boolean) => void-Handler called when the open state changes
disabledKeysIterable<Key>-Keys of disabled items
isDisabledboolean-Whether the select is disabled
valueKey | Key[] | null-Current value (controlled)
defaultValueKey | Key[] | null-Default value (uncontrolled)
onChange(value: Key | Key[] | null) => void-Handler called when the value changes
isRequiredboolean-Whether user input is required
isInvalidboolean-Whether the select value is invalid
namestring-The name of the input, used when submitting an HTML form
autoCompletestring-Describes the type of autocomplete functionality
fullWidthbooleanfalseWhether the select should take full width of its container
isOnSurfaceboolean-Whether the select is displayed on a surface component
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Select content or render function

Select.Trigger Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Trigger content or render function

Select.Value Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Value content or render function

Select.Indicator Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode-Custom indicator content

Select.Popover Props

PropTypeDefaultDescription
placement"bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "top" | "top left" | "top right" | "top start" | "top end" | "left" | "left top" | "left bottom" | "start" | "start top" | "start bottom" | "right" | "right top" | "right bottom" | "end" | "end top" | "end bottom""bottom"Placement of the popover relative to the trigger
classNamestring-Additional CSS classes
childrenReactNode-Content children

RenderProps

When using render functions with Select.Value, these values are provided:

PropTypeDescription
defaultChildrenReactNodeThe default rendered value
isPlaceholderbooleanWhether the value is a placeholder
stateSelectStateThe state of the select
selectedItemsNode[]The currently selected items

Accessibility

The Select component implements the ARIA listbox pattern and provides:

  • Full keyboard navigation support
  • Screen reader announcements for selection changes
  • Proper focus management
  • Support for disabled states
  • Typeahead search functionality
  • HTML form integration

For more information, see the React Aria Select documentation.

On this page