Select
Accessible dropdown component supporting single and multiple selection with keyboard navigation and validation
Installation
npm install --save @godaddy/antaresProps
label?string | undefined—Visible label above the trigger Required if aria-label is not provided
autoFocus?boolean | undefined—Focus on mount
childrenReactNode | ((item: T) => ReactNode)—SelectItem elements or render function
className?string | undefined—Component CSS class
defaultOpen?boolean | undefined—Default open state (uncontrolled)
defaultSelectedKey?RACKey | undefined—Initial selected key (uncontrolled)
description?string | undefined—Help text below the trigger
errorMessage?string | undefined—Error text shown when invalid
isDisabled?boolean | undefined—Disables interaction
isInvalid?boolean | undefined—Shows error styling and errorMessage
isOpen?boolean | undefined—Open state (controlled)
isRequired?boolean | undefined—Shows red asterisk, requires value for submission
items?Iterable<T> | undefined—Items for dynamic rendering (children must be render function)
labelStyle?"default" | "float" | undefined'default'Label positioning style
name?string | undefined—Form submission name
onOpenChange?((isOpen: boolean) => void) | undefined—Called when open state changes
onSelectionChange?((key: RACKey | null) => void) | undefined—Called when selection changes
placeholder?string | undefined—Placeholder text when empty
selectedKey?RACKey | null | undefined—Selected key (controlled)
selectionMode?"single" | "multiple" | undefined'single'Whether single or multiple selection is enabled
size?"sm" | "md" | undefined'md'Visual size variant
Examples
Static
import { Select, SelectItem } from '@godaddy/antares';export function SelectStaticExample() { return ( <Select aria-label="Coffee drinks"> <SelectItem id="espresso">Espresso</SelectItem> <SelectItem id="latte">Latte</SelectItem> <SelectItem id="cappuccino">Cappuccino</SelectItem> <SelectItem id="americano">Americano</SelectItem> <SelectItem id="mocha">Mocha</SelectItem> </Select> );}Controlled
import { useState } from 'react';import { Box, Flex, Select, SelectItem } from '@godaddy/antares';export function SelectControlledExample() { const [selectedKey, setSelectedKey] = useState<string>('latte'); return ( <Flex direction="column" gap="md"> <Select aria-label="Coffee drinks" selectedKey={selectedKey} onSelectionChange={(key) => setSelectedKey(key as string)} > <SelectItem id="espresso">Espresso</SelectItem> <SelectItem id="latte">Latte</SelectItem> <SelectItem id="cappuccino">Cappuccino</SelectItem> <SelectItem id="americano">Americano</SelectItem> <SelectItem id="mocha">Mocha</SelectItem> </Select> <Box padding="md" elevation="card" rounding="lg"> <strong>Selected:</strong> {selectedKey} </Box> </Flex> );}Dynamic Items
import { Select, SelectItem } from '@godaddy/antares';const items = [ { id: '1', name: 'Espresso', category: 'Classic' }, { id: '2', name: 'Latte', category: 'Classic' }, { id: '3', name: 'Cappuccino', category: 'Classic' }, { id: '4', name: 'Americano', category: 'Classic' }, { id: '5', name: 'Mocha', category: 'Specialty' }, { id: '6', name: 'Macchiato', category: 'Specialty' }, { id: '7', name: 'Cold Brew', category: 'Cold' }];export function SelectDynamicExample() { return ( <Select aria-label="Coffee drinks" items={items}> {function renderItem(item) { return ( <SelectItem id={item.id} textValue={item.name}> {item.name} ({item.category}) </SelectItem> ); }} </Select> );}Multiple Selection
import { Select, SelectItem } from '@godaddy/antares';export function SelectMultipleExample() { return ( <Select aria-label="Coffee drinks" selectionMode="multiple"> <SelectItem id="espresso">Espresso</SelectItem> <SelectItem id="latte">Latte</SelectItem> <SelectItem id="cappuccino">Cappuccino</SelectItem> <SelectItem id="americano">Americano</SelectItem> <SelectItem id="mocha">Mocha</SelectItem> </Select> );}Customization
Data Attributes
React Aria Components automatically adds data attributes for styling different states:
Select Container: data-invalid, data-disabled, data-required, data-focused
Trigger Button: data-pressed, data-disabled, data-focused, aria-expanded
Select Value: data-placeholder
Popover: data-entering, data-exiting
List Items: data-hovered, data-focused, data-pressed, data-selected, data-disabled, data-selection-mode
[data-selected] {
background-color: #eff6ff;
font-weight: 600;
}
[data-invalid] .button {
border-color: #dc2626;
}
[aria-expanded="true"] {
border-color: #3b82f6;
}Component Customization
Individual child components can be styled by passing className props:
<Select label="Coffee">
<SelectItem id="espresso" className="premium-option">
Espresso
</SelectItem>
<SelectSection className="featured-section">
<SelectHeader>Featured</SelectHeader>
<SelectItem id="special">Special Blend</SelectItem>
</SelectSection>
</Select>Accessibility
Keyboard Navigation
- Space/Enter: Opens the popover and focuses the selected item
- Arrow Down/Up: Navigate through options
- Home/End: Jump to first/last option
- Escape: Closes the popover
- Tab: Moves focus to the next focusable element
- Type to select: Type characters to jump to matching options
- Space (in multi-select): Toggle selection of focused item
Troubleshooting
Selection Not Updating
// ❌ Wrong: Using both value and defaultValue
<Select value={value} defaultValue="espresso">
<SelectItem id="espresso">Espresso</SelectItem>
</Select>
// ✅ Controlled mode
<Select value={value} onChange={setValue}>
<SelectItem id="espresso">Espresso</SelectItem>
</Select>
// ✅ Uncontrolled mode
<Select defaultValue="espresso">
<SelectItem id="espresso">Espresso</SelectItem>
</Select>Styling Overrides Not Applying
/* ❌ May not have enough specificity */
.item {
background-color: red;
}
/* ✅ Use data attributes for higher specificity */
.my-select [data-selected] {
background-color: red;
}Keyboard Navigation Not Working
/* ❌ Don't remove focus outlines without replacement */
.button:focus {
outline: none;
}
/* ✅ Provide visible focus indicator */
.button:focus-visible {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}SegmentedController
A segmented controller is a linear set of two or more segments, each of which functions as a button. A segmented controller allows users to select options, switch views, or sort elements.
TextField
TextField is a single-line or multiline text input with optional label, description, and error message. Use it in forms for short answers (email, search, name) or longer content (comments). It supports optional leading and trailing text adornments (e.g. currency or units).