{"slug":"select","title":"Select","description":"Using the select machine in your project.","contentType":"component","framework":"react","content":"A select component lets you pick a value from predefined options.\n\n## Resources\n\n\n[Latest version: v1.35.3](https://www.npmjs.com/package/@zag-js/select)\n[Logic Visualizer](https://zag-visualizer.vercel.app/select)\n[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/select)\n\n\n\n**Features**\n\n- Supports single and multiple selection\n- Supports typeahead, keyboard navigation, and RTL\n- Supports controlled open, value, and highlight state\n- Supports form submission and browser autofill\n\n## Installation\n\nInstall the select package:\n\n```bash\nnpm install @zag-js/select @zag-js/react\n# or\nyarn add @zag-js/select @zag-js/react\n```\n\n## Anatomy\n\nCheck the select anatomy and part names.\n\n> Each part includes a `data-part` attribute to help identify them in the DOM.\n\n\n\n## Usage\n\nImport the select package:\n\n```jsx\nimport * as select from \"@zag-js/select\"\n```\n\nThese are the key exports:\n\n- `machine` - State machine logic.\n- `connect` - Maps machine state to JSX props and event handlers.\n- `collection` - Creates a [collection interface](/overview/collection) from an\n  array of items.\n\nThen use the framework integration helpers:\n\n```jsx\nimport * as select from \"@zag-js/select\"\nimport { useMachine, normalizeProps, Portal } from \"@zag-js/react\"\nimport { useId, useRef } from \"react\"\n\nconst selectData = [\n  { label: \"Nigeria\", value: \"NG\" },\n  { label: \"Japan\", value: \"JP\" },\n  { label: \"Korea\", value: \"KO\" },\n  { label: \"Kenya\", value: \"KE\" },\n  { label: \"United Kingdom\", value: \"UK\" },\n  { label: \"Ghana\", value: \"GH\" },\n  { label: \"Uganda\", value: \"UG\" },\n]\n\nexport function Select() {\n  const collection = select.collection({\n    items: selectData,\n    itemToString: (item) => item.label,\n    itemToValue: (item) => item.value,\n  })\n\n  const service = useMachine(select.machine, {\n    id: useId(),\n    collection,\n  })\n\n  const api = select.connect(service, normalizeProps)\n\n  return (\n    <div {...api.getRootProps()}>\n      <div {...api.getControlProps()}>\n        <label {...api.getLabelProps()}>Label</label>\n        <button {...api.getTriggerProps()}>\n          {api.valueAsString || \"Select option\"}\n        </button>\n      </div>\n\n      <Portal>\n        <div {...api.getPositionerProps()}>\n          <ul {...api.getContentProps()}>\n            {selectData.map((item) => (\n              <li key={item.value} {...api.getItemProps({ item })}>\n                <span>{item.label}</span>\n                <span {...api.getItemIndicatorProps({ item })}>✓</span>\n              </li>\n            ))}\n          </ul>\n        </div>\n      </Portal>\n    </div>\n  )\n}\n```\n\n### Setting the initial value\n\nUse the `defaultValue` property to set the initial value of the select.\n\n> The `value` property must be an array of strings. If selecting a single value,\n> pass an array with a single string.\n\n```jsx {13}\nconst collection = select.collection({\n  items: [\n    { label: \"Nigeria\", value: \"ng\" },\n    { label: \"Ghana\", value: \"gh\" },\n    { label: \"Kenya\", value: \"ke\" },\n    //...\n  ],\n})\n\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  defaultValue: [\"ng\"],\n})\n```\n\n### Selecting multiple values\n\nSet `multiple` to `true` to allow selecting multiple values.\n\n```jsx {5}\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  multiple: true,\n})\n```\n\n### Controlled select value\n\nUse `value` and `onValueChange` for controlled selection.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  value,\n  onValueChange(details) {\n    setValue(details.value)\n  },\n})\n```\n\n### Using a custom object format\n\nBy default, the select collection expects an array of items with `label` and\n`value` properties. To use a custom object format, pass the `itemToString` and\n`itemToValue` properties to the collection function.\n\n- `itemToString` — A function that returns the string representation of an item.\n  Used to compare items when filtering.\n- `itemToValue` — A function that returns the unique value of an item.\n- `itemToDisabled` — A function that returns the disabled state of an item.\n- `groupBy` — A function that returns the group of an item.\n- `groupSort` — An array or function to sort the groups.\n\n```jsx\nconst collection = select.collection({\n  // custom object format\n  items: [\n    { id: 1, fruit: \"Banana\", available: true, quantity: 10 },\n    { id: 2, fruit: \"Apple\", available: false, quantity: 5 },\n    { id: 3, fruit: \"Orange\", available: true, quantity: 3 },\n    //...\n  ],\n  // convert item to string\n  itemToString(item) {\n    return item.fruit\n  },\n  // convert item to value\n  itemToValue(item) {\n    return item.id\n  },\n  // convert item to disabled state\n  itemToDisabled(item) {\n    return !item.available || item.quantity === 0\n  },\n  groupBy(item) {\n    return item.available ? \"available\" : \"unavailable\"\n  },\n  groupSort: [\"available\", \"unavailable\"],\n})\n\n// use the collection\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n})\n```\n\n### Usage within a form\n\nTo use select in a form, set `name` and render `api.getHiddenSelectProps()`.\n\n```jsx\nimport * as select from \"@zag-js/select\"\nimport { useMachine, normalizeProps, Portal } from \"@zag-js/react\"\nimport { useId } from \"react\"\n\nconst selectData = [\n  { label: \"Nigeria\", value: \"NG\" },\n  { label: \"Japan\", value: \"JP\" },\n  { label: \"Korea\", value: \"KO\" },\n  { label: \"Kenya\", value: \"KE\" },\n  { label: \"United Kingdom\", value: \"UK\" },\n  { label: \"Ghana\", value: \"GH\" },\n  { label: \"Uganda\", value: \"UG\" },\n]\n\nexport function SelectWithForm() {\n  const service = useMachine(select.machine, {\n    id: useId(),\n    collection: select.collection({ items: selectData }),\n    name: \"country\",\n  })\n\n  const api = select.connect(service, normalizeProps)\n\n  return (\n    <form>\n      {/* Hidden select */}\n      <select {...api.getHiddenSelectProps()}>\n        {selectData.map((option) => (\n          <option key={option.value} value={option.value}>\n            {option.label}\n          </option>\n        ))}\n      </select>\n\n      {/* Custom Select */}\n      <div {...api.getControlProps()}>\n        <label {...api.getLabelProps()}>Label</label>\n        <button type=\"button\" {...api.getTriggerProps()}>\n          <span>{api.valueAsString || \"Select option\"}</span>\n          <CaretIcon />\n        </button>\n      </div>\n\n      <Portal>\n        <div {...api.getPositionerProps()}>\n          <ul {...api.getContentProps()}>\n            {selectData.map((item) => (\n              <li key={item.value} {...api.getItemProps({ item })}>\n                <span>{item.label}</span>\n                <span {...api.getItemIndicatorProps({ item })}>✓</span>\n              </li>\n            ))}\n          </ul>\n        </div>\n      </Portal>\n    </form>\n  )\n}\n```\n\n### Browser autofill support\n\nTo support browser autofill for form fields like state or province, set\n`autoComplete` on the machine.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  name: \"state\",\n  autoComplete: \"address-level1\",\n})\n```\n\n### Disabling an item\n\nTo disable a select item, use `itemToDisabled` in the collection.\n\n```jsx {3-4}\nconst collection = select.collection({\n  items: countries,\n  itemToDisabled(item) {\n    return item.disabled\n  },\n})\n\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n})\n```\n\n### Close on select\n\nBy default, the menu closes when you select an item with pointer, space, or\nenter. Set `closeOnSelect` to `false` to keep it open.\n\n```jsx {4}\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  closeOnSelect: false,\n})\n```\n\n### Programmatic selection control\n\nUse the API for imperative updates.\n\n```jsx\napi.selectValue(\"ng\")\napi.setValue([\"ng\", \"ke\"])\napi.clearValue() // or api.clearValue(\"ng\")\n```\n\n### Controlling open state\n\nUse `open` and `onOpenChange` for controlled open state, or `defaultOpen` for\nuncontrolled initial state.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  open,\n  onOpenChange(details) {\n    setOpen(details.open)\n    // details => { open: boolean, value: string[] }\n  },\n})\n```\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  defaultOpen: true,\n})\n```\n\n### Controlling highlighted item\n\nUse `highlightedValue` and `onHighlightChange` to manage item highlight.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  highlightedValue,\n  onHighlightChange(details) {\n    setHighlightedValue(details.highlightedValue)\n    // details => { highlightedValue, highlightedItem, highlightedIndex }\n  },\n})\n```\n\n### Positioning the popup\n\nUse `positioning` to control popup placement and behavior.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  positioning: { placement: \"bottom-start\" },\n})\n```\n\n### Looping the keyboard navigation\n\nBy default, arrow key navigation stops at the first and last options. Set\n`loopFocus: true` to loop back around.\n\n```jsx {4}\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  loopFocus: true,\n})\n```\n\n### Allowing deselection in single-select mode\n\nSet `deselectable` to allow clicking the selected item again to clear the value.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  deselectable: true,\n})\n```\n\n### Listening for highlight changes\n\nUse `onHighlightChange` to listen for highlighted item changes.\n\n```jsx {3-6}\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  onHighlightChange(details) {\n    // details => { highlightedValue, highlightedItem, highlightedIndex }\n    console.log(details)\n  },\n})\n```\n\n### Listening for selection changes\n\nUse `onValueChange` to listen for selected item changes.\n\n```jsx {4-6}\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  onValueChange(details) {\n    // details => { value: string[], items: Item[] }\n    console.log(details)\n  },\n})\n```\n\n### Listening for item selection\n\nUse `onSelect` when you need the selected item value immediately.\n\n```jsx\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  onSelect(details) {\n    // details => { value: string }\n    console.log(details.value)\n  },\n})\n```\n\n### Listening for open and close events\n\nUse `onOpenChange` to listen for open and close events.\n\n```jsx {4-7}\nconst service = useMachine(select.machine, {\n  id: useId(),\n  collection,\n  onOpenChange(details) {\n    // details => { open: boolean, value: string[] }\n    console.log(details.open)\n  },\n})\n```\n\n### Grouping items\n\nThe select relies on the collection, so rendered items must match collection\nitems.\n\nSet `groupBy` on the collection to define item groups.\n\n```tsx\nconst collection = select.collection({\n  items: [],\n  itemToValue: (item) => item.value,\n  itemToString: (item) => item.label,\n  groupBy: (item) => item.group || \"default\",\n})\n```\n\nThen, use the `collection.group()` method to render the grouped items.\n\n```tsx\n{\n  collection.group().map(([group, items], index) => (\n    <div key={`${group}-${index}`}>\n      <div {...api.getItemGroupProps({ id: group })}>{group}</div>\n      {items.map((item, index) => (\n        <div key={`${item.value}-${index}`} {...api.getItemProps({ item })}>\n          <span {...api.getItemTextProps({ item })}>{item.label}</span>\n          <span {...api.getItemIndicatorProps({ item })}>✓</span>\n        </div>\n      ))}\n    </div>\n  ))\n}\n```\n\n### Usage with large data\n\nFor large lists, combine select with a virtualization library like\n`react-window` or `@tanstack/react-virtual`.\n\nExample with `@tanstack/react-virtual`:\n\n```jsx\nfunction Demo() {\n  const selectData = []\n\n  const contentRef = useRef(null)\n\n  const rowVirtualizer = useVirtualizer({\n    count: selectData.length,\n    getScrollElement: () => contentRef.current,\n    estimateSize: () => 32,\n  })\n\n  const service = useMachine(select.machine, {\n    id: useId(),\n    collection,\n    scrollToIndexFn(details) {\n      rowVirtualizer.scrollToIndex(details.index, {\n        align: \"center\",\n        behavior: \"auto\",\n      })\n    },\n  })\n\n  const api = select.connect(service, normalizeProps)\n\n  return (\n    <div {...api.getRootProps()}>\n      {/* ... */}\n      <Portal>\n        <div {...api.getPositionerProps()}>\n          <div ref={contentRef} {...api.getContentProps()}>\n            <div\n              style={{\n                height: `${rowVirtualizer.getTotalSize()}px`,\n                width: \"100%\",\n                position: \"relative\",\n              }}\n            >\n              {rowVirtualizer.getVirtualItems().map((virtualItem) => {\n                const item = selectData[virtualItem.index]\n                return (\n                  <div\n                    key={item.value}\n                    {...api.getItemProps({ item })}\n                    style={{\n                      position: \"absolute\",\n                      top: 0,\n                      left: 0,\n                      width: \"100%\",\n                      height: `${virtualItem.size}px`,\n                      transform: `translateY(${virtualItem.start}px)`,\n                      whiteSpace: \"nowrap\",\n                      overflow: \"hidden\",\n                      textOverflow: \"ellipsis\",\n                    }}\n                  >\n                    <span>{item.label}</span>\n                    <span {...api.getItemIndicatorProps({ item })}>✓</span>\n                  </div>\n                )\n              })}\n            </div>\n          </div>\n        </div>\n      </Portal>\n    </div>\n  )\n}\n```\n\n### Usage within dialog\n\nWhen using select in a dialog, avoid rendering it in a `Portal` or `Teleport`\noutside the dialog focus scope.\n\n## Styling guide\n\nEach select part includes a `data-part` attribute you can target in CSS.\n\n### Open and closed state\n\nWhen the select is open, the trigger and content is given a `data-state`\nattribute.\n\n```css\n[data-part=\"trigger\"][data-state=\"open|closed\"] {\n  /* styles for open or closed state */\n}\n\n[data-part=\"content\"][data-state=\"open|closed\"] {\n  /* styles for open or closed state */\n}\n```\n\n### Selected state\n\nItems are given a `data-state` attribute, indicating whether they are selected.\n\n```css\n[data-part=\"item\"][data-state=\"checked|unchecked\"] {\n  /* styles for selected or unselected state */\n}\n```\n\n### Highlighted state\n\nWhen an item is highlighted, via keyboard navigation or pointer, it is given a\n`data-highlighted` attribute.\n\n```css\n[data-part=\"item\"][data-highlighted] {\n  /* styles for highlighted state */\n}\n```\n\n### Invalid state\n\nWhen the select is invalid, the label and trigger is given a `data-invalid`\nattribute.\n\n```css\n[data-part=\"label\"][data-invalid] {\n  /* styles for invalid state */\n}\n\n[data-part=\"trigger\"][data-invalid] {\n  /* styles for invalid state */\n}\n```\n\n### Disabled state\n\nWhen the select is disabled, the trigger and label is given a `data-disabled`\nattribute.\n\n```css\n[data-part=\"trigger\"][data-disabled] {\n  /* styles for disabled select state */\n}\n\n[data-part=\"label\"][data-disabled] {\n  /* styles for disabled label state */\n}\n\n[data-part=\"item\"][data-disabled] {\n  /* styles for disabled option state */\n}\n```\n\n> Optionally, when an item is disabled, it is given a `data-disabled` attribute.\n\n### Empty state\n\nWhen no option is selected, the trigger is given a `data-placeholder-shown`\nattribute.\n\n```css\n[data-part=\"trigger\"][data-placeholder-shown] {\n  /* styles for empty select state */\n}\n```\n\n## Methods and Properties\n\n### Machine Context\n\nThe select machine exposes the following context properties:\n\n**`collection`**\nType: `ListCollection<T>`\nDescription: The item collection\n\n**`ids`**\nType: `Partial<{ root: string; content: string; control: string; trigger: string; clearTrigger: string; label: string; hiddenSelect: string; positioner: string; item: (id: string | number) => string; itemGroup: (id: string | number) => string; itemGroupLabel: (id: string | number) => string; }>`\nDescription: The ids of the elements in the select. Useful for composition.\n\n**`name`**\nType: `string`\nDescription: The `name` attribute of the underlying select.\n\n**`form`**\nType: `string`\nDescription: The associate form of the underlying select.\n\n**`autoComplete`**\nType: `string`\nDescription: The autocomplete attribute for the hidden select. Enables browser autofill (e.g. \"address-level1\" for state).\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the select is disabled\n\n**`invalid`**\nType: `boolean`\nDescription: Whether the select is invalid\n\n**`readOnly`**\nType: `boolean`\nDescription: Whether the select is read-only\n\n**`required`**\nType: `boolean`\nDescription: Whether the select is required\n\n**`closeOnSelect`**\nType: `boolean`\nDescription: Whether the select should close after an item is selected\n\n**`onSelect`**\nType: `(details: SelectionDetails) => void`\nDescription: Function called when an item is selected\n\n**`onHighlightChange`**\nType: `(details: HighlightChangeDetails<T>) => void`\nDescription: The callback fired when the highlighted item changes.\n\n**`onValueChange`**\nType: `(details: ValueChangeDetails<T>) => void`\nDescription: The callback fired when the selected item changes.\n\n**`onOpenChange`**\nType: `(details: OpenChangeDetails) => void`\nDescription: Function called when the popup is opened\n\n**`positioning`**\nType: `PositioningOptions`\nDescription: The positioning options of the menu.\n\n**`value`**\nType: `string[]`\nDescription: The controlled keys of the selected items\n\n**`defaultValue`**\nType: `string[]`\nDescription: The initial default value of the select when rendered.\nUse when you don't need to control the value of the select.\n\n**`highlightedValue`**\nType: `string`\nDescription: The controlled key of the highlighted item\n\n**`defaultHighlightedValue`**\nType: `string`\nDescription: The initial value of the highlighted item when opened.\nUse when you don't need to control the highlighted value of the select.\n\n**`loopFocus`**\nType: `boolean`\nDescription: Whether to loop the keyboard navigation through the options\n\n**`multiple`**\nType: `boolean`\nDescription: Whether to allow multiple selection\n\n**`open`**\nType: `boolean`\nDescription: Whether the select menu is open\n\n**`defaultOpen`**\nType: `boolean`\nDescription: Whether the select's open state is controlled by the user\n\n**`scrollToIndexFn`**\nType: `(details: ScrollToIndexDetails) => void`\nDescription: Function to scroll to a specific index\n\n**`composite`**\nType: `boolean`\nDescription: Whether the select is a composed with other composite widgets like tabs or combobox\n\n**`deselectable`**\nType: `boolean`\nDescription: Whether the value can be cleared by clicking the selected item.\n\n**Note:** this is only applicable for single selection\n\n**`dir`**\nType: `\"ltr\" | \"rtl\"`\nDescription: The document's text/writing direction.\n\n**`id`**\nType: `string`\nDescription: The unique identifier of the machine.\n\n**`getRootNode`**\nType: `() => ShadowRoot | Node | Document`\nDescription: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.\n\n**`onPointerDownOutside`**\nType: `(event: PointerDownOutsideEvent) => void`\nDescription: Function called when the pointer is pressed down outside the component\n\n**`onFocusOutside`**\nType: `(event: FocusOutsideEvent) => void`\nDescription: Function called when the focus is moved outside the component\n\n**`onInteractOutside`**\nType: `(event: InteractOutsideEvent) => void`\nDescription: Function called when an interaction happens outside the component\n\n### Machine API\n\nThe select `api` exposes the following methods:\n\n**`focused`**\nType: `boolean`\nDescription: Whether the select is focused\n\n**`open`**\nType: `boolean`\nDescription: Whether the select is open\n\n**`empty`**\nType: `boolean`\nDescription: Whether the select value is empty\n\n**`highlightedValue`**\nType: `string`\nDescription: The value of the highlighted item\n\n**`highlightedItem`**\nType: `V`\nDescription: The highlighted item\n\n**`setHighlightValue`**\nType: `(value: string) => void`\nDescription: Function to highlight a value\n\n**`clearHighlightValue`**\nType: `VoidFunction`\nDescription: Function to clear the highlighted value\n\n**`selectedItems`**\nType: `V[]`\nDescription: The selected items\n\n**`hasSelectedItems`**\nType: `boolean`\nDescription: Whether there's a selected option\n\n**`value`**\nType: `string[]`\nDescription: The selected item keys\n\n**`valueAsString`**\nType: `string`\nDescription: The string representation of the selected items\n\n**`selectValue`**\nType: `(value: string) => void`\nDescription: Function to select a value\n\n**`selectAll`**\nType: `VoidFunction`\nDescription: Function to select all values\n\n**`setValue`**\nType: `(value: string[]) => void`\nDescription: Function to set the value of the select\n\n**`clearValue`**\nType: `(value?: string) => void`\nDescription: Function to clear the value of the select.\nIf a value is provided, it will only clear that value, otherwise, it will clear all values.\n\n**`focus`**\nType: `VoidFunction`\nDescription: Function to focus on the select input\n\n**`getItemState`**\nType: `(props: ItemProps<any>) => ItemState`\nDescription: Returns the state of a select item\n\n**`setOpen`**\nType: `(open: boolean) => void`\nDescription: Function to open or close the select\n\n**`collection`**\nType: `ListCollection<V>`\nDescription: Function to toggle the select\n\n**`reposition`**\nType: `(options?: Partial<PositioningOptions>) => void`\nDescription: Function to set the positioning options of the select\n\n**`multiple`**\nType: `boolean`\nDescription: Whether the select allows multiple selections\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the select is disabled\n\n### Data Attributes\n\n**`Root`**\n\n**`data-scope`**: select\n**`data-part`**: root\n**`data-invalid`**: Present when invalid\n**`data-readonly`**: Present when read-only\n\n**`Label`**\n\n**`data-scope`**: select\n**`data-part`**: label\n**`data-disabled`**: Present when disabled\n**`data-invalid`**: Present when invalid\n**`data-readonly`**: Present when read-only\n**`data-required`**: Present when required\n\n**`Control`**\n\n**`data-scope`**: select\n**`data-part`**: control\n**`data-state`**: \"open\" | \"closed\"\n**`data-focus`**: Present when focused\n**`data-disabled`**: Present when disabled\n**`data-invalid`**: Present when invalid\n\n**`ValueText`**\n\n**`data-scope`**: select\n**`data-part`**: value-text\n**`data-disabled`**: Present when disabled\n**`data-invalid`**: Present when invalid\n**`data-focus`**: Present when focused\n\n**`Trigger`**\n\n**`data-scope`**: select\n**`data-part`**: trigger\n**`data-state`**: \"open\" | \"closed\"\n**`data-disabled`**: Present when disabled\n**`data-invalid`**: Present when invalid\n**`data-readonly`**: Present when read-only\n**`data-placement`**: The placement of the trigger\n**`data-placeholder-shown`**: Present when placeholder is shown\n\n**`Indicator`**\n\n**`data-scope`**: select\n**`data-part`**: indicator\n**`data-state`**: \"open\" | \"closed\"\n**`data-disabled`**: Present when disabled\n**`data-invalid`**: Present when invalid\n**`data-readonly`**: Present when read-only\n\n**`Item`**\n\n**`data-scope`**: select\n**`data-part`**: item\n**`data-value`**: The value of the item\n**`data-state`**: \"checked\" | \"unchecked\"\n**`data-highlighted`**: Present when highlighted\n**`data-disabled`**: Present when disabled\n\n**`ItemText`**\n\n**`data-scope`**: select\n**`data-part`**: item-text\n**`data-state`**: \"checked\" | \"unchecked\"\n**`data-disabled`**: Present when disabled\n**`data-highlighted`**: Present when highlighted\n\n**`ItemIndicator`**\n\n**`data-scope`**: select\n**`data-part`**: item-indicator\n**`data-state`**: \"checked\" | \"unchecked\"\n\n**`ItemGroup`**\n\n**`data-scope`**: select\n**`data-part`**: item-group\n**`data-disabled`**: Present when disabled\n\n**`ClearTrigger`**\n\n**`data-scope`**: select\n**`data-part`**: clear-trigger\n**`data-invalid`**: Present when invalid\n\n**`Content`**\n\n**`data-scope`**: select\n**`data-part`**: content\n**`data-state`**: \"open\" | \"closed\"\n**`data-nested`**: listbox\n**`data-has-nested`**: listbox\n**`data-placement`**: The placement of the content\n**`data-activedescendant`**: The id the active descendant of the content\n\n### CSS Variables\n\n<CssVarTable name=\"select\" />\n\n## Accessibility\n\nAdheres to the\n[ListBox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox).\n\n### Keyboard Interactions\n\n**`Space`**\nDescription: <span>When focus is on trigger, opens the select and focuses the first selected item.<br />When focus is on the content, selects the highlighted item.</span>\n\n**`Enter`**\nDescription: <span>When focus is on trigger, opens the select and focuses the first selected item.<br />When focus is on content, selects the focused item.</span>\n\n**`ArrowDown`**\nDescription: <span>When focus is on trigger, opens the select.<br />When focus is on content, moves focus to the next item.</span>\n\n**`ArrowUp`**\nDescription: <span>When focus is on trigger, opens the select.<br />When focus is on content, moves focus to the previous item.</span>\n\n**`Esc`**\nDescription: <span>Closes the select and moves focus to trigger.</span>\n\n**`A-Z + a-z`**\nDescription: <span>When focus is on trigger, selects the item whose label starts with the typed character.<br />When focus is on the listbox, moves focus to the next item with a label that starts with the typed character.</span>","package":"@zag-js/select","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/components/select.mdx"}