Picker
Pickers allow users to choose a single option from a collapsible list of options when space is limited.
Content
Picker
follows the Collection Components API, accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the items
prop, and a function to render the children.
import {Picker, PickerItem} from '@react-spectrum/s2';
function Example() {
let options = [
{ id: 1, name: 'Aardvark' },
{ id: 2, name: 'Cat' },
{ id: 3, name: 'Dog' },
{ id: 4, name: 'Kangaroo' },
{ id: 5, name: 'Koala' },
{ id: 6, name: 'Penguin' },
{ id: 7, name: 'Snake' },
{ id: 8, name: 'Turtle' },
{ id: 9, name: 'Wombat' }
];
return (
<Picker label="Animals" items={options}>
{(item) => <PickerItem>{item.name}</PickerItem>}
</Picker>
);
}
Slots
PickerItem
supports icons, and label
and description
text slots.
import {Picker, PickerItem, Text} from '@react-spectrum/s2';
import Comment from '@react-spectrum/s2/icons/Comment';
import Edit from '@react-spectrum/s2/icons/Edit';
import UserSettings from '@react-spectrum/s2/icons/UserSettings';
<Picker label="Permissions" defaultSelectedKey="read">
<PickerItem id="read" textValue="Read">
<Comment />
<Text slot="label">Read</Text>
<Text slot="description">Comment only</Text>
</PickerItem>
<PickerItem id="write" textValue="Write">
<Edit />
<Text slot="label">Write</Text>
<Text slot="description">Read and write only</Text>
</PickerItem>
<PickerItem id="admin" textValue="Admin">
<UserSettings />
<Text slot="label">Admin</Text>
<Text slot="description">Full access</Text>
</PickerItem>
</Picker>
Sections
Use the <PickerSection>
component to group options. A <Header>
element, with a <Heading>
and optional description
slot can be included to label a section. Sections without a header must have an aria-label
.
import {Picker, PickerSection, PickerItem, Header, Heading, Text} from '@react-spectrum/s2';
<Picker label="Ice cream flavor">
<PickerSection>
<Header>
<Heading>Neopolitan flavors</Heading>
<Text slot="description">These flavors are common</Text>
</Header>
<PickerItem>Chocolate</PickerItem>
<PickerItem>Strawberry</PickerItem>
<PickerItem>Vanilla</PickerItem>
</PickerSection>
<PickerSection>
<Header>
<Heading>Others</Heading>
<Text slot="description">These flavors are uncommon</Text>
</Header>
<PickerItem>Matcha</PickerItem>
<PickerItem>Ube</PickerItem>
<PickerItem>Prickly pear</PickerItem>
</PickerSection>
</Picker>
Asynchronous loading
Use the loadingState
and onLoadMore
props to enable async loading and infinite scrolling.
import {Picker, PickerItem} from '@react-spectrum/s2';
import {useAsyncList} from 'react-stately';
interface Character {
name: string
}
function AsyncLoadingExample() {
let list = useAsyncList<Character>({
async load({signal, cursor}) {
let res = await fetch(
cursor || `https://pokeapi.co/api/v2/pokemon`,
{ signal }
);
let json = await res.json();
return {
items: json.results,
cursor: json.next
};
}
});
return (
<Picker
aria-label="Pokemon"
items={list.items}
loadingState={list.loadingState}
onLoadMore={list.loadMore}>
{(item) => <PickerItem id={item.name}>{item.name}</PickerItem>}
</Picker>
);
}
Links
Use the href
prop on a <PickerItem>
to create a link. See the client side routing guide to learn how to integrate with your framework. Link items in a Picker
are not selectable.
import {Picker, PickerItem} from '@react-spectrum/s2';
<Picker label="Project">
<PickerItem href="https://example.com/" target="_blank">Create new…</PickerItem>
<PickerItem>Proposal</PickerItem>
<PickerItem>Budget</PickerItem>
<PickerItem>Onboarding</PickerItem>
</Picker>
Selection
Use the defaultSelectedKey
or selectedKey
prop to set the selected item. The selected key corresponds to the id
prop of an item. Items can be disabled with the isDisabled
prop. See the selection guide for more details.
Current selection: bison
import {Picker, PickerItem, type Key} from '@react-spectrum/s2';
import {useState} from 'react';
function Example() {
let [animal, setAnimal] = useState<Key>("bison");
return (
<div>
<Picker
label="Pick an animal"
selectedKey={animal}
onSelectionChange={setAnimal}
>
<PickerItem id="koala">Koala</PickerItem>
<PickerItem id="kangaroo">Kangaroo</PickerItem>
<PickerItem id="platypus" isDisabled>Platypus</PickerItem>
<PickerItem id="eagle">Bald Eagle</PickerItem>
<PickerItem id="bison">Bison</PickerItem>
<PickerItem id="skunk">Skunk</PickerItem>
</Picker>
<p>Current selection: {animal}</p>
</div>
);
}
Forms
Use the name
prop to submit the id
of the selected item to the server. Set the isRequired
prop to validate that the user selects an option, or implement custom client or server-side validation. See the Forms guide to learn more.
Popover options
The open state of the Picker can be controlled via the defaultOpen
and isOpen
props. The align
, direction
, shouldFlip
and menuWidth
props control the behavior of the popover.
Select is closed
API
<Picker>
<PickerItem>
<Icon />
<Text slot="label" />
<Text slot="description" />
</PickerItem>
<PickerSection>
<Header>
<Heading />
<Text slot="description" />
</Header>
<PickerItem />
</PickerSection>
</Picker>
Picker
Name | Type | Default |
---|---|---|
placeholder | string | Default: 'Select an item' (localized)
|
Temporary text that occupies the select when it is empty. | ||
isDisabled | boolean | Default: — |
Whether the input is disabled. | ||
size | 'S'
| 'M'
| 'L'
| 'XL' | Default: 'M'
|
The size of the Picker. | ||
styles | StylesProp | Default: — |
Spectrum-defined styles, returned by the style() macro. | ||
children | ReactNode | | Default: — |
The contents of the collection. | ||
items | Iterable | Default: — |
Item objects in the collection. | ||
loadingState | LoadingState | Default: — |
The current loading state of the Picker. | ||
onLoadMore |
| Default: — |
Handler that is called when more items should be loaded, e.g. while scrolling near the bottom. | ||
dependencies | ReadonlyArray | Default: — |
Values that should invalidate the item cache when using dynamic collections. | ||
selectionMode | SelectionMode | Default: 'single'
|
Whether single or multiple selection is enabled. | ||
disabledKeys | Iterable | Default: — |
The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with. | ||
value | ValueType | Default: — |
The current value (controlled). | ||
defaultValue | ValueType | Default: — |
The default value (uncontrolled). | ||
onChange |
| Default: — |
Handler that is called when the value changes. | ||
PickerItem
Name | Type | |
---|---|---|
children | ReactNode | |
id | Key | |
The unique id of the item. | ||
value | T | |
The object value that this item represents. When using dynamic collections, this is set automatically. | ||
textValue | string | |
A string representation of the item's contents, used for features like typeahead. | ||
isDisabled | boolean | |
Whether the item is disabled. | ||
styles | StylesProp | |
Spectrum-defined styles, returned by the style() macro. | ||
PickerSection
Name | Type | |
---|---|---|
id | Key | |
The unique id of the section. | ||
value | T | |
The object value that this section represents. When using dynamic collections, this is set automatically. | ||
children | ReactNode | | |
Static child items or a function to render children. | ||
items | Iterable | |
Item objects in the section. | ||
dependencies | ReadonlyArray | |
Values that should invalidate the item cache when using dynamic collections. | ||