SelectPreview
A select displays a collapsible list of options and allows a user to select one of them
Import
import { Select } from '@heroui/react';Usage
import {Label, ListBox, Select} from "@heroui/react";
export function Default() {
  return (
    <Select className="w-[256px]" placeholder="Select one">
      <Label>State</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Item id="florida" textValue="Florida">
            Florida
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="delaware" textValue="Delaware">
            Delaware
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="california" textValue="California">
            California
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="texas" textValue="Texas">
            Texas
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="new-york" textValue="New York">
            New York
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="washington" textValue="Washington">
            Washington
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Select.Content>
    </Select>
  );
}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.Content>
      <ListBox>
        <ListBox.Item>
          <Label />
          <Description />
          <ListBox.ItemIndicator />
        </ListBox.Item>
        <ListBox.Section>
          <Header />
          <ListBox.Item>
            <Label />
          </ListBox.Item>
        </ListBox.Section>
      </ListBox>
    </Select.Content>
  </Select>
)With Description
import {Description, Label, ListBox, Select} from "@heroui/react";
export function WithDescription() {
  return (
    <Select className="w-[256px]" placeholder="Select one">
      <Label>State</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Item id="florida" textValue="Florida">
            Florida
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="delaware" textValue="Delaware">
            Delaware
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="california" textValue="California">
            California
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="texas" textValue="Texas">
            Texas
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="new-york" textValue="New York">
            New York
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="washington" textValue="Washington">
            Washington
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Select.Content>
      <Description>Select your state of residence</Description>
    </Select>
  );
}Multiple Select
import {Label, ListBox, Select} from "@heroui/react";
export function MultipleSelect() {
  return (
    <Select className="w-[256px]" placeholder="Select countries" selectionMode="multiple">
      <Label>Countries to Visit</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox selectionMode="multiple">
          <ListBox.Item id="argentina" textValue="Argentina">
            Argentina
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="venezuela" textValue="Venezuela">
            Venezuela
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="japan" textValue="Japan">
            Japan
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="france" textValue="France">
            France
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="italy" textValue="Italy">
            Italy
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="spain" textValue="Spain">
            Spain
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="thailand" textValue="Thailand">
            Thailand
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="new-zealand" textValue="New Zealand">
            New Zealand
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="iceland" textValue="Iceland">
            Iceland
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Select.Content>
    </Select>
  );
}With Sections
import {Header, Label, ListBox, Select, Separator} from "@heroui/react";
export function WithSections() {
  return (
    <Select className="w-[256px]" placeholder="Select a country">
      <Label>Country</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Section>
            <Header>North America</Header>
            <ListBox.Item id="usa" textValue="United States">
              United States
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="canada" textValue="Canada">
              Canada
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="mexico" textValue="Mexico">
              Mexico
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox.Section>
          <Separator />
          <ListBox.Section>
            <Header>Europe</Header>
            <ListBox.Item id="uk" textValue="United Kingdom">
              United Kingdom
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="france" textValue="France">
              France
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="germany" textValue="Germany">
              Germany
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="spain" textValue="Spain">
              Spain
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="italy" textValue="Italy">
              Italy
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox.Section>
          <Separator />
          <ListBox.Section>
            <Header>Asia</Header>
            <ListBox.Item id="japan" textValue="Japan">
              Japan
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="china" textValue="China">
              China
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="india" textValue="India">
              India
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="south-korea" textValue="South Korea">
              South Korea
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox.Section>
        </ListBox>
      </Select.Content>
    </Select>
  );
}With Disabled Options
import {Label, ListBox, Select} from "@heroui/react";
export function WithDisabledOptions() {
  return (
    <Select className="w-[256px]" disabledKeys={["cat", "kangaroo"]} placeholder="Select an animal">
      <Label>Animal</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Item id="dog" textValue="Dog">
            Dog
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="cat" textValue="Cat">
            Cat
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="bird" textValue="Bird">
            Bird
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="kangaroo" textValue="Kangaroo">
            Kangaroo
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="elephant" textValue="Elephant">
            Elephant
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="tiger" textValue="Tiger">
            Tiger
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Select.Content>
    </Select>
  );
}Custom Indicator
import {Label, ListBox, Select} from "@heroui/react";
import {Icon} from "@iconify/react";
export function CustomIndicator() {
  return (
    <Select className="w-[256px]" placeholder="Select one">
      <Label>State</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator className="size-3">
          <Icon icon="gravity-ui:chevrons-expand-vertical" />
        </Select.Indicator>
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Item id="florida" textValue="Florida">
            Florida
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="delaware" textValue="Delaware">
            Delaware
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="california" textValue="California">
            California
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="texas" textValue="Texas">
            Texas
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="new-york" textValue="New York">
            New York
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="washington" textValue="Washington">
            Washington
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Select.Content>
    </Select>
  );
}Required
"use client";
import {Button, FieldError, Form, Label, ListBox, Select} from "@heroui/react";
export function Required() {
  const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    const data: Record<string, string> = {};
    // Convert FormData to plain object
    formData.forEach((value, key) => {
      data[key] = value.toString();
    });
    alert("Form submitted successfully!");
  };
  return (
    <Form className="flex w-[256px] flex-col gap-4" onSubmit={onSubmit}>
      <Select isRequired className="w-full" name="state" placeholder="Select one">
        <Label>State</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox>
            <ListBox.Item id="florida" textValue="Florida">
              Florida
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="delaware" textValue="Delaware">
              Delaware
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="california" textValue="California">
              California
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="texas" textValue="Texas">
              Texas
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="new-york" textValue="New York">
              New York
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="washington" textValue="Washington">
              Washington
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </Select.Content>
        <FieldError />
      </Select>
      <Select isRequired className="w-full" name="country" placeholder="Select a country">
        <Label>Country</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox>
            <ListBox.Item id="usa" textValue="United States">
              United States
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="canada" textValue="Canada">
              Canada
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="mexico" textValue="Mexico">
              Mexico
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="uk" textValue="United Kingdom">
              United Kingdom
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="france" textValue="France">
              France
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="germany" textValue="Germany">
              Germany
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </Select.Content>
        <FieldError />
      </Select>
      <Button type="submit">Submit</Button>
    </Form>
  );
}On Surface
"use client";
import {Button, FieldError, Form, Label, ListBox, Select, Surface} from "@heroui/react";
export function OnSurface() {
  const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    const data: Record<string, string> = {};
    // Convert FormData to plain object
    formData.forEach((value, key) => {
      data[key] = value.toString();
    });
    alert("Form submitted successfully!");
  };
  return (
    <Surface className="w-[320px] rounded-3xl p-6">
      <Form className="flex w-full flex-col gap-4" onSubmit={onSubmit}>
        <Select isRequired className="w-full" name="state" placeholder="Select one">
          <Label>State</Label>
          <Select.Trigger>
            <Select.Value />
            <Select.Indicator />
          </Select.Trigger>
          <Select.Content>
            <ListBox>
              <ListBox.Item id="florida" textValue="Florida">
                Florida
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="delaware" textValue="Delaware">
                Delaware
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="california" textValue="California">
                California
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="texas" textValue="Texas">
                Texas
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="new-york" textValue="New York">
                New York
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="washington" textValue="Washington">
                Washington
                <ListBox.ItemIndicator />
              </ListBox.Item>
            </ListBox>
          </Select.Content>
          <FieldError />
        </Select>
        <Select isRequired className="w-full" name="country" placeholder="Select a country">
          <Label>Country</Label>
          <Select.Trigger>
            <Select.Value />
            <Select.Indicator />
          </Select.Trigger>
          <Select.Content>
            <ListBox>
              <ListBox.Item id="usa" textValue="United States">
                United States
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="canada" textValue="Canada">
                Canada
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="mexico" textValue="Mexico">
                Mexico
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="uk" textValue="United Kingdom">
                United Kingdom
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="france" textValue="France">
                France
                <ListBox.ItemIndicator />
              </ListBox.Item>
              <ListBox.Item id="germany" textValue="Germany">
                Germany
                <ListBox.ItemIndicator />
              </ListBox.Item>
            </ListBox>
          </Select.Content>
          <FieldError />
        </Select>
        <Button type="submit">Submit</Button>
      </Form>
    </Surface>
  );
}Custom Value
"use client";
import {
  Avatar,
  AvatarFallback,
  AvatarImage,
  Description,
  Label,
  ListBox,
  Select,
} from "@heroui/react";
export function CustomValue() {
  const users = [
    {
      avatarUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg",
      email: "bob@heroui.com",
      fallback: "B",
      id: "1",
      name: "Bob",
    },
    {
      avatarUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg",
      email: "fred@heroui.com",
      fallback: "F",
      id: "2",
      name: "Fred",
    },
    {
      avatarUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg",
      email: "martha@heroui.com",
      fallback: "M",
      id: "3",
      name: "Martha",
    },
    {
      avatarUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg",
      email: "john@heroui.com",
      fallback: "J",
      id: "4",
      name: "John",
    },
    {
      avatarUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg",
      email: "jane@heroui.com",
      fallback: "J",
      id: "5",
      name: "Jane",
    },
  ];
  return (
    <Select className="w-[256px]" placeholder="Select a user">
      <Label>User</Label>
      <Select.Trigger>
        <Select.Value>
          {({defaultChildren, isPlaceholder, state}) => {
            if (isPlaceholder || state.selectedItems.length === 0) {
              return defaultChildren;
            }
            const selectedItems = state.selectedItems;
            if (selectedItems.length > 1) {
              return `${selectedItems.length} users selected`;
            }
            const selectedItem = users.find((user) => user.id === selectedItems[0].key);
            if (!selectedItem) {
              return defaultChildren;
            }
            return (
              <div className="flex items-center gap-2">
                <Avatar className="size-4" size="sm">
                  <AvatarImage src={selectedItem.avatarUrl} />
                  <AvatarFallback>{selectedItem.fallback}</AvatarFallback>
                </Avatar>
                <span>{selectedItem.name}</span>
              </div>
            );
          }}
        </Select.Value>
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          {users.map((user) => (
            <ListBox.Item key={user.id} id={user.id} textValue={user.name}>
              <Avatar size="sm">
                <AvatarImage src={user.avatarUrl} />
                <AvatarFallback>{user.fallback}</AvatarFallback>
              </Avatar>
              <div className="flex flex-col">
                <Label>{user.name}</Label>
                <Description>{user.email}</Description>
              </div>
              <ListBox.ItemIndicator />
            </ListBox.Item>
          ))}
        </ListBox>
      </Select.Content>
    </Select>
  );
}Controlled
Selected: California
"use client";
import type {Key} from "react-aria-components";
import {Label, ListBox, Select} from "@heroui/react";
import {useState} from "react";
export function Controlled() {
  const states = [
    {
      id: "california",
      name: "California",
    },
    {
      id: "texas",
      name: "Texas",
    },
    {
      id: "florida",
      name: "Florida",
    },
    {
      id: "new-york",
      name: "New York",
    },
    {
      id: "illinois",
      name: "Illinois",
    },
    {
      id: "pennsylvania",
      name: "Pennsylvania",
    },
  ];
  const [state, setState] = useState<Key | null>("california");
  const selectedState = states.find((s) => s.id === state);
  return (
    <div className="space-y-2">
      <Select
        className="w-[256px]"
        placeholder="Select a state"
        value={state}
        onChange={(value) => setState(value)}
      >
        <Label>State (controlled)</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox>
            {states.map((state) => (
              <ListBox.Item key={state.id} id={state.id} textValue={state.name}>
                {state.name}
                <ListBox.ItemIndicator />
              </ListBox.Item>
            ))}
          </ListBox>
        </Select.Content>
      </Select>
      <p className="text-muted text-sm">Selected: {selectedState?.name || "None"}</p>
    </div>
  );
}Controlled Multiple
Selected: california, texas
"use client";
import type {Selection} from "@react-types/shared";
import {Label, ListBox, Select} from "@heroui/react";
import {useState} from "react";
export function ControlledMultiple() {
  const [selected, setSelected] = useState<Selection>(new Set(["california", "texas"]));
  const selectedItems = Array.from(selected);
  return (
    <div className="space-y-4">
      <Select className="w-[256px]" placeholder="Select states" selectionMode="multiple">
        <Label>States (controlled multiple)</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox
            selectedKeys={selected}
            selectionMode="multiple"
            onSelectionChange={(keys) => setSelected(keys as Selection)}
          >
            <ListBox.Item id="california" textValue="California">
              California
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="texas" textValue="Texas">
              Texas
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="florida" textValue="Florida">
              Florida
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="new-york" textValue="New York">
              New York
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="illinois" textValue="Illinois">
              Illinois
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="pennsylvania" textValue="Pennsylvania">
              Pennsylvania
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </Select.Content>
      </Select>
      <p className="text-sm text-neutral-500">
        Selected: {selectedItems.length > 0 ? selectedItems.join(", ") : "None"}
      </p>
    </div>
  );
}Controlled Open State
Select is closed
"use client";
import {Button, Label, ListBox, Select} from "@heroui/react";
import {useState} from "react";
export function ControlledOpenState() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <div className="space-y-4">
      <Select
        className="w-[256px]"
        isOpen={isOpen}
        placeholder="Select one"
        onOpenChange={setIsOpen}
      >
        <Label>State</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox>
            <ListBox.Item id="florida" textValue="Florida">
              Florida
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="delaware" textValue="Delaware">
              Delaware
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="california" textValue="California">
              California
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="texas" textValue="Texas">
              Texas
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="new-york" textValue="New York">
              New York
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="washington" textValue="Washington">
              Washington
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </Select.Content>
      </Select>
      <Button onPress={() => setIsOpen(!isOpen)}>{isOpen ? "Close" : "Open"} Select</Button>
      <p className="text-sm text-neutral-500">Select is {isOpen ? "open" : "closed"}</p>
    </div>
  );
}Asynchronous Loading
"use client";
import {Label, ListBox, Select, Spinner} from "@heroui/react";
import {useAsyncList} from "@react-stately/data";
import {Collection, ListBoxLoadMoreItem} from "react-aria-components";
interface Pokemon {
  name: string;
}
export function AsynchronousLoading() {
  const list = useAsyncList<Pokemon>({
    async load({cursor, signal}) {
      const res = await fetch(cursor || `https://pokeapi.co/api/v2/pokemon`, {signal});
      const json = await res.json();
      return {
        cursor: json.next,
        items: json.results,
      };
    },
  });
  return (
    <Select className="w-[256px]" placeholder="Select a Pokemon">
      <Label>Pick a Pokemon</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <Collection items={list.items}>
            {(item: Pokemon) => (
              <ListBox.Item id={item.name} textValue={item.name}>
                {item.name}
                <ListBox.ItemIndicator />
              </ListBox.Item>
            )}
          </Collection>
          <ListBoxLoadMoreItem
            isLoading={list.loadingState === "loadingMore"}
            onLoadMore={list.loadMore}
          >
            <div className="flex items-center justify-center gap-2 py-2">
              <Spinner size="sm" />
              <span className="text-sm text-neutral-500">Loading more...</span>
            </div>
          </ListBoxLoadMoreItem>
        </ListBox>
      </Select.Content>
    </Select>
  );
}Disabled
import {Label, ListBox, Select} from "@heroui/react";
export function Disabled() {
  return (
    <div className="flex flex-col gap-4">
      <Select isDisabled className="w-[256px]" defaultValue="california" placeholder="Select one">
        <Label>State</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox>
            <ListBox.Item id="florida" textValue="Florida">
              Florida
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="delaware" textValue="Delaware">
              Delaware
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="california" textValue="California">
              California
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="texas" textValue="Texas">
              Texas
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="new-york" textValue="New York">
              New York
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="washington" textValue="Washington">
              Washington
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </Select.Content>
      </Select>
      <Select
        isDisabled
        className="w-[256px]"
        defaultValue={["argentina", "japan", "france"]}
        placeholder="Select countries"
        selectionMode="multiple"
      >
        <Label>Countries to Visit</Label>
        <Select.Trigger>
          <Select.Value />
          <Select.Indicator />
        </Select.Trigger>
        <Select.Content>
          <ListBox>
            <ListBox.Item id="argentina" textValue="Argentina">
              Argentina
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="venezuela" textValue="Venezuela">
              Venezuela
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="japan" textValue="Japan">
              Japan
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="france" textValue="France">
              France
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="italy" textValue="Italy">
              Italy
              <ListBox.ItemIndicator />
            </ListBox.Item>
            <ListBox.Item id="spain" textValue="Spain">
              Spain
              <ListBox.ItemIndicator />
            </ListBox.Item>
          </ListBox>
        </Select.Content>
      </Select>
    </div>
  );
}Styling
Passing Tailwind CSS classes
import { Select } from '@heroui/react';
function CustomSelect() {
  return (
    <Select className="w-full">
      <Label>State</Label>
      <Select.Trigger className="border rounded-lg p-2 bg-surface">
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
            Item 1
          </ListBox.Item>
        </ListBox>
      </Select.Content>
    </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__content {
    @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__content- The popover content 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: 
:hoveror[data-hovered="true"]on trigger - Focus: 
:focus-visibleor[data-focus-visible="true"]on trigger - Disabled: 
:disabledor[data-disabled="true"]on select - Open: 
[data-open="true"]on indicator 
API Reference
Select Props
| Prop | Type | Default | Description | 
|---|---|---|---|
placeholder | string | 'Select an item' | Temporary text that occupies the select when it is empty | 
selectionMode | "single" | "multiple" | "single" | Whether single or multiple selection is enabled | 
isOpen | boolean | - | Sets the open state of the menu (controlled) | 
defaultOpen | boolean | - | Sets the default open state of the menu (uncontrolled) | 
onOpenChange | (isOpen: boolean) => void | - | Handler called when the open state changes | 
disabledKeys | Iterable<Key> | - | Keys of disabled items | 
isDisabled | boolean | - | Whether the select is disabled | 
value | Key | Key[] | null | - | Current value (controlled) | 
defaultValue | Key | Key[] | null | - | Default value (uncontrolled) | 
onChange | (value: Key | Key[] | null) => void | - | Handler called when the value changes | 
isRequired | boolean | - | Whether user input is required | 
isInvalid | boolean | - | Whether the select value is invalid | 
name | string | - | The name of the input, used when submitting an HTML form | 
autoComplete | string | - | Describes the type of autocomplete functionality | 
isOnSurface | boolean | - | Whether the select is displayed on a surface component | 
className | string | - | Additional CSS classes | 
children | ReactNode | RenderFunction | - | Select content or render function | 
Select.Trigger Props
| Prop | Type | Default | Description | 
|---|---|---|---|
className | string | - | Additional CSS classes | 
children | ReactNode | RenderFunction | - | Trigger content or render function | 
Select.Value Props
| Prop | Type | Default | Description | 
|---|---|---|---|
className | string | - | Additional CSS classes | 
children | ReactNode | RenderFunction | - | Value content or render function | 
Select.Indicator Props
| Prop | Type | Default | Description | 
|---|---|---|---|
className | string | - | Additional CSS classes | 
children | ReactNode | - | Custom indicator content | 
Select.Content Props
| Prop | Type | Default | Description | 
|---|---|---|---|
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 | 
className | string | - | Additional CSS classes | 
children | ReactNode | - | Content children | 
RenderProps
When using render functions with Select.Value, these values are provided:
| Prop | Type | Description | 
|---|---|---|
defaultChildren | ReactNode | The default rendered value | 
isPlaceholder | boolean | Whether the value is a placeholder | 
state | SelectState | The state of the select | 
selectedItems | Node[] | The currently selected items | 
Examples
Basic Usage
import { Select, Label, ListBox } from '@heroui/react';
<Select className="w-[256px]" placeholder="Select one">
  <Label>State</Label>
  <Select.Trigger>
    <Select.Value />
    <Select.Indicator />
  </Select.Trigger>
  <Select.Content>
    <ListBox>
      <ListBox.Item id="florida" textValue="Florida">
        Florida
        <ListBox.ItemIndicator />
      </ListBox.Item>
      <ListBox.Item id="california" textValue="California">
        California
        <ListBox.ItemIndicator />
      </ListBox.Item>
    </ListBox>
  </Select.Content>
</Select>With Sections
import { Select, Label, ListBox, Header, Separator } from '@heroui/react';
<Select className="w-[256px]" placeholder="Select a country">
  <Label>Country</Label>
  <Select.Trigger>
    <Select.Value />
    <Select.Indicator />
  </Select.Trigger>
  <Select.Content>
    <ListBox>
      <ListBox.Section>
        <Header>North America</Header>
        <ListBox.Item id="usa" textValue="United States">
          United States
          <ListBox.ItemIndicator />
        </ListBox.Item>
      </ListBox.Section>
      <Separator />
      <ListBox.Section>
        <Header>Europe</Header>
        <ListBox.Item id="uk" textValue="United Kingdom">
          United Kingdom
          <ListBox.ItemIndicator />
        </ListBox.Item>
      </ListBox.Section>
    </ListBox>
  </Select.Content>
</Select>Controlled Selection
import type { Key } from '@heroui/react';
import { Select, Label, ListBox } from '@heroui/react';
import { useState } from 'react';
function ControlledSelect() {
  const [value, setValue] = useState<Key | null>('california');
  return (
    <Select
      className="w-[256px]"
      placeholder="Select a state"
      value={value}
      onChange={setValue}
    >
      <Label>State</Label>
      <Select.Trigger>
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Content>
        <ListBox>
          <ListBox.Item id="california" textValue="California">
            California
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="texas" textValue="Texas">
            Texas
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Select.Content>
    </Select>
  );
}Custom Value Display
import { Select, Label, ListBox, Avatar, AvatarImage, AvatarFallback } from '@heroui/react';
<Select className="w-[256px]" placeholder="Select a user">
  <Label>User</Label>
  <Select.Trigger>
    <Select.Value>
      {({defaultChildren, isPlaceholder, state}) => {
        if (isPlaceholder || state.selectedItems.length === 0) {
          return defaultChildren;
        }
        const selectedItem = users.find((user) => user.id === state.selectedItems[0].key);
        if (!selectedItem) {
          return defaultChildren;
        }
        return (
          <div className="flex items-center gap-2">
            <Avatar className="size-4" size="sm">
              <AvatarImage src={selectedItem.avatarUrl} />
              <AvatarFallback>{selectedItem.fallback}</AvatarFallback>
            </Avatar>
            <span>{selectedItem.name}</span>
          </div>
        );
      }}
    </Select.Value>
    <Select.Indicator />
  </Select.Trigger>
  <Select.Content>
    <ListBox>
      {/* ListBox items */}
    </ListBox>
  </Select.Content>
</Select>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.