1. Components
  2. Menus and selection
  3. Select

Select

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

<Select>
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Installation

npx dotui-cli@latest add select

Usage

bezbez

Use Select to allow users to choose a single option from a collapsible list of options when space is limited.

Options

Placeholder

Use the placeholder prop to provide a temporary text that occupies the text input when it is empty.

<Select placeholder="Select a provider">
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Label

A visual label can be provided for the Select using the label prop, or a hidden label using aria-label prop.

Provider
<Select label="Provider">
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Description

A description can be supplied to a Select via the description prop. The description is always visible unless the isInvalid prop is true and an error message is provided.

ProviderPlease select a provider.
<Select label="Provider" description="Please select a provider.">
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Validation

An errorMessage can be supplied to Select, which will be displayed when the isInvalid prop is set to true.

ProviderPlease select an item in the list.
<Select label="Provider" isInvalid errorMessage="Please select an item in the list.">
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Sections

Select supports sections in order to group options. Sections can be used by wrapping groups of items in a Section element.
Sections without a title must provide an aria-label for accessibility.

Model
<Select label="Model">
  <Section title="OpenAI">
    <Item>GPT-4o</Item>
    <Item>GPT-4 Turbo</Item>
    <Item>GPT-4</Item>
    <Item>GPT-3.5 Turbo</Item>
  </Section>
  <Section title="Google">
    <Item>Gemini 1.5 Flash</Item>
    <Item>Gemini 1.5 Pro</Item>
    <Item>Gemini 1.0 Pro</Item>
  </Section>
  <Section title="Meta">
    <Item>Llama 3 (70B)</Item>
    <Item>Llama 3 (8B)</Item>
    <Item>Code Llama (70B)</Item>
  </Section>
  <Section title="Mistral AI">
    <Item>Mixtral 8x22B</Item>
    <Item>Mistral Large</Item>
    <Item>Mistral 7B</Item>
  </Section>
</Select>

Items may be links to another page or website. This can be achieved by passing the href prop to the Item component.

Project
<Select label="Project">
  <Item href="/create-project">Create new...</Item>
  <Item>DotUI</Item>
  <Item>Palettify</Item>
  <Item>Notionfolio</Item>
</Select>

Disabled

The isDisabled prop can be used to disable the Select.

<Select isDisabled>
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Loading

Use the isLoading prop to indicate that the list is loading.

<Select isLoading>
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Required

Use the isRequired prop to mark the TextField as required. Use the necessityIndicator prop to control the visual style of the required state.

Provider
<Select label="Provider" isRequired necessityIndicator="icon">
  <Item>Perplexity</Item>
  <Item>Replicate</Item>
  <Item>Together AI</Item>
  <Item>ElevenLabs</Item>
</Select>

Uncontrolled

Use defaultSelectedKey to provide a default set of selected item.

<Select defaultSelectedKey="eleven-labs">
  <Item id="perplexity">Perplexity</Item>
  <Item id="replicate">Replicate</Item>
  <Item id="together-ai">Together AI</Item>
  <Item id="eleven-labs">ElevenLabs</Item>
</Select>

Controlled

Use selectedKey to control the selected item.

Selected provider: eleven-labs

const [provider, setProvider] = React.useState<Key>("eleven-labs");
return (
  <Select selectedKey={provider} onSelectionChange={setProvider}>
    <Item id="perplexity">Perplexity</Item>
    <Item id="replicate">Replicate</Item>
    <Item id="together-ai">Together AI</Item>
    <Item id="eleven-labs">ElevenLabs</Item>
  </Select>
)

Composition

If you need to customize things further, you can drop down to the composition level.

<SelectRoot>
  <Button variant="outline" suffix={<ChevronsUpDownIcon className="text-fg-muted" />}>
    <SelectValue />
  </Button>
  <Overlay type="popover">
    <ListBox>
      <Item>Perplexity</Item>
      <Item>Replicate</Item>
      <Item>Together AI</Item>
      <Item>ElevenLabs</Item>
    </ListBox>
  </Overlay>
</SelectRoot>

Examples

Asynchronous laoding

const list = useAsyncList<Character>({
  async load({ signal }) {
    const res = await fetch(`https://pokeapi.co/api/v2/pokemon`, { signal });
    const json = (await res.json()) as { results: Character[] };

    return {
      items: json.results,
    };
  },
});
return (
  <Select isLoading={list.isLoading} items={list.items}>
    {(item) => <Item id={item.name}>{item.name}</Item>}
  </Select>
);

API Reference

Select

PropTypeDefaultDescription
autoCompletestring-Describes the type of autocomplete functionality the input should provide if any.
namestring-The name of the input, used when submitting an HTML form.
isOpenboolean-Sets the open state of the menu.
defaultOpenboolean-Sets the default open state of the menu.
disabledKeysIterable<Key>-The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.
isDisabledboolean-Whether the input is disabled.
isRequiredboolean-Whether user input is required on the input before form submission.
isInvalidboolean-Whether the input value is invalid.
validate(value: Key) => ValidationError | true | null | undefined-A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if validationBehavior="native". For realtime validation, use the isInvalid prop instead.
placeholderstring-Temporary text that occupies the text input when it is empty.
selectedKeyKey | null-The currently selected key in the collection (controlled).
defaultSelectedKeyKey-The initial selected key in the collection (uncontrolled).
autoFocusboolean-Whether the element should receive focus on render.
validationBehavior'native' | 'aria''native'Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.
childrenReactNode | (item: object) => ReactNode-The contents of the collection.
dependenciesany[]-Values that should invalidate the item cache when using dynamic collections.
classNamestring | (values: SelectRenderProps & {defaultClassName: string | undefined}) => string-The CSS className for the element. A function may be provided to compute the class based on component state.
styleCSSProperties | (values: SelectRenderProps & {defaultStyle: CSSProperties}) => CSSProperties-The inline style for the element. A function may be provided to compute the style based on component state.
EventTypeDescription
onOpenChange(isOpen: boolean) => voidMethod that is called when the open state of the menu changes.
onSelectionChange(key: Key) => voidHandler that is called when the selection changes.
onFocus(e: FocusEvent<Target>) => voidHandler that is called when the element receives focus.
onBlur(e: FocusEvent<Target>) => voidHandler that is called when the element loses focus.
onFocusChange(isFocused: boolean) => voidHandler that is called when the element's focus status changes.
onKeyDown(e: KeyboardEvent) => voidHandler that is called when a key is pressed.
onKeyUp(e: KeyboardEvent) => voidHandler that is called when a key is released.
Data attributeDescription
[data-focused]Whether the select is focused, either via a mouse or keyboard.
[data-focus-visible]Whether the select is keyboard focused.
[data-disabled]Whether the select is disabled.
[data-open]Whether the select is currently open.
[data-invalid]Whether the select is invalid.
[data-required]Whether the select is required.

SelectValue

PropTypeDefaultDescription
childrenReactNode | (values: SelectValueRenderProps<object> & {defaultChildren: ReactNode | undefined}) => ReactNode-The children of the component. A function may be provided to alter the children based on component state.
classNamestring | (values: SelectValueRenderProps<object> & {defaultClassName: string | undefined}) => string-The CSS className for the element. A function may be provided to compute the class based on component state.
styleCSSProperties | (values: SelectValueRenderProps<object> & {defaultStyle: CSSProperties}) => CSSProperties-The inline style for the element. A function may be provided to compute the style based on component state.

Accessibility

Keyboard interactions

When the popover is closed:

KeyDescription
Space ArrowDownOpens the popover menu. The focus is set on the menu item selected.

When the popover menu is open:

KeyDescription
SpaceSelects the menu item in focus, closes the popover menu and moves focus to the field button.
ArrowDown ArrowUpMoves focus to previous or next menu item in the popover. Does not loop when the last or first menu item is reached.
EscCloses the popover menu and moves focus to the field button.

Last updated on 10/11/2024

dotUI

Bringing singularity to the web.

Built by mehdibha. The source code is available on GitHub.