@akhatmirzo/ui

Select

Pick one value from a list without search — with groups, icons and form support.

Buyurtma shu viloyatga yetkaziladi

Qiymat: —

Import

import { Select } from '@akhatmirzo/ui';

When to use

  • One choice out of roughly 5–15 options — a region, a payment method, a status. With three options or fewer, a RadioGroup works better: everything is visible at once.
  • Need search? Use Combobox. Select has no search on purpose; long lists like cities or products belong in a Combobox.
  • Several values also call for Combobox with multiple — Select returns a single value.
  • Always give it a name: put it inside a Field or pass aria-label.
  • Not for commands. Actions like "Edit" or "Delete" go in a DropdownMenu.

Groups and separators

Select.Group puts options under a heading, and Select.Separator draws a line between groups. The selected option gets a ✓ mark.

<Select defaultValue="fer">
  <Select.Item value="tsh">Toshkent</Select.Item>
  <Select.Group label="Vodiy">
    <Select.Item value="and">Andijon</Select.Item>
    <Select.Item value="fer">Farg'ona</Select.Item>
  </Select.Group>
  <Select.Separator />
  <Select.Group label="Janub">
    <Select.Item value="qash">Qashqadaryo</Select.Item>
  </Select.Group>
</Select>

Sizes

Three sizes — 32, 40 and 48px, the same heights as Input and Button, so they line up in a row. The panel is as wide as the trigger; long lists scroll after 320px.

States

Inside a Field, disabled, error and required are wired up for you — no need to repeat them on Select. Without a Field, pass invalid and disabled directly. To disable a single option, set disabled on Select.Item; keyboard navigation skips it.

To'lov usulini tanlang

Options with icons

The icon prop on Select.Item reserves a 16px slot before the label. Handy for short markers such as status colors.

In a form

When you pass name, Select renders a hidden native <select>, so the value is submitted with FormData. Validate the empty case yourself and show the message through the error prop of Field.

FormData: —

Inside a dialog

Select works inside a Dialog or a Drawer out of the box: the panel detects the modal layer and raises its z-index, so the list opens above the dialog. There is nothing to configure — see the "Select and Combobox inside a dialog" section on the Dialog page for a working example.

Props

Select

className goes to the trigger and contentClassName to the dropdown panel. Any other <button> attributes (id, aria-*, data-*, onBlur ...) and ref are passed to the trigger as well.

PropTypeDefaultDescription
valuestring—Selected value (controlled)
defaultValuestring—Initial value (uncontrolled)
onValueChange(value: string) => void—Called when the user picks an option
openboolean—Whether the panel is open (controlled)
defaultOpenboolean—Open on first render
onOpenChange(open: boolean) => void—Called when the panel opens or closes
placeholderReactNode'Tanlang'Shown while nothing is selected
size'sm' | 'md' | 'lg''md'Height: 32 / 40 / 48px
invalidboolean—Error state. Set automatically when Field has an error
disabledboolean—Disables the whole Select
requiredboolean—Required field (aria-required)
namestring—Name of the hidden native select for forms
autoCompletestring—Passed to the hidden native select
dir'ltr' | 'rtl'—Text direction
contentClassNamestring—Class for the dropdown panel
containerHTMLElement | null—Portal container (defaults to document.body)
childrenrequiredReactNode—Select.Item, Select.Group and Select.Separator

Select.Item

PropTypeDefaultDescription
valuerequiredstring—Option value
iconReactNode—Leading icon (16px)
disabledboolean—Disables the option
textValuestring—Text for typeahead when children aren't plain text

Select.Group

PropTypeDefaultDescription
labelReactNode—Group heading
childrenReactNode—The Select.Item elements in the group

Select.Separator is a divider line between groups; it only takes className.

Data attributes

AttributeOnValue
data-sizetriggersm · md · lg
data-statetriggeropen · closed
data-placeholdertriggerpresent while nothing is selected
data-invalidtriggerpresent in the error state
data-disabledtriggerpresent when disabled
data-stateoptionchecked · unchecked
data-highlightedoptionpresent under the keyboard or the mouse

Keyboard

KeyAction
Enter / Space / ↓ / ↑Opens the panel when the trigger is focused
↓ / ↑Moves between options (disabled ones are skipped)
Home / EndFirst / last option
A letterJumps to the next option starting with that letter
Enter / SpaceSelects and closes
EscCloses without changing the value, focus returns

Accessibility

  • Roles. The trigger is role="combobox" with aria-expanded, the panel is a listbox, and each option is an option with aria-selected. It is built on Radix Select.
  • Field wiring. Inside a Field, the label, description and error are linked to the trigger through aria-labelledby / aria-describedby. Errors set aria-invalid="true"; required sets aria-required="true".
  • Focus. When the panel opens, focus moves to the selected option; on close it returns to the trigger.
  • Never leave it unnamed. Without a Field, add an aria-label (for example aria-label="Currency").
  • Decorations. The chevron, the ✓ mark and icon are aria-hidden, so screen readers only read the option text.

On this page