import {Layout} from '../../src/Layout'; export default Layout;
import docs from 'docs:react-aria-components';
export const section = 'Guides'; export const description = 'Implementing selection in React Aria';
Many collection components support selecting items by clicking or tapping them, or by using the keyboard. This page discusses how to handle selection events, how to control selection programmatically, and the data structures used to represent a selection.
Most collection components support item selection, which is handled by the onSelectionChange event. Use the selectedKeys prop to control the selected items programmatically, or defaultSelectedKeys for uncontrolled behavior.
Selection is represented by a Set containing the id of each selected item. You can also pass any iterable collection (e.g. an array) to the selectedKeys and defaultSelectedKeys props, but the onSelectionChange event will always pass back a Set.
<ExampleSwitcher type="component" examples={['ListBox', 'GridList', 'Tree', 'TagGroup', 'Table']}>
"use client";
import {type Selection} from 'react-aria-components';
import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox';
import {useState} from 'react';
function Example() {
let [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(['cheese']));
return (
<div>
<ListBox
aria-label="Sandwich contents"
///- begin highlight -///
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
///- end highlight -///
>
<ListBoxItem id="lettuce">Lettuce</ListBoxItem>
<ListBoxItem id="tomato">Tomato</ListBoxItem>
<ListBoxItem id="cheese">Cheese</ListBoxItem>
<ListBoxItem id="tuna">Tuna Salad</ListBoxItem>
<ListBoxItem id="egg">Egg Salad</ListBoxItem>
<ListBoxItem id="ham">Ham</ListBoxItem>
</ListBox>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
}"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';
import {Button, type Selection} from 'react-aria-components';
import {useState} from 'react';
export default function Example() {
let [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(['cheese']));
return (
<div>
<GridList
aria-label="Sandwich contents"
///- begin highlight -///
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
///- end highlight -///
>
<SandwichItem id="lettuce">Lettuce</SandwichItem>
<SandwichItem id="tomato">Tomato</SandwichItem>
<SandwichItem id="cheese">Cheese</SandwichItem>
<SandwichItem id="tuna">Tuna Salad</SandwichItem>
<SandwichItem id="egg">Egg Salad</SandwichItem>
<SandwichItem id="ham">Ham</SandwichItem>
</GridList>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
}
///- begin collapse -///
function SandwichItem(props: GridListItemProps) {
return (
<GridListItem {...props} textValue={props.children}>
{props.children}
<Button aria-label="Info">ⓘ</Button>
</GridListItem>
);
}
///- end collapse -///"use client";
import {type Selection} from 'react-aria-components';
import {Tree, TreeItem} from 'vanilla-starter/Tree';
import {useState} from 'react';
function Example() {
let [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(['project']));
return (
<div>
<Tree
aria-label="Files"
defaultExpandedKeys={['documents', 'photos', 'project']}
///- begin highlight -///
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
///- end highlight -///
>
<TreeItem id="documents" title="Documents">
<TreeItem id="project" title="Project">
<TreeItem title="Weekly Report" />
</TreeItem>
</TreeItem>
<TreeItem id="photos" title="Photos">
<TreeItem title="Image 1" />
<TreeItem title="Image 2" />
</TreeItem>
</Tree>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
}"use client";
import {type Selection} from 'react-aria-components';
import {TagGroup, Tag} from 'vanilla-starter/TagGroup';
import {useState} from 'react';
function Example() {
let [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(['cheese']));
return (
<div>
<TagGroup
label="Sandwich contents"
///- begin highlight -///
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
///- end highlight -///
>
<Tag id="lettuce">Lettuce</Tag>
<Tag id="tomato">Tomato</Tag>
<Tag id="cheese">Cheese</Tag>
<Tag id="tuna">Tuna Salad</Tag>
<Tag id="egg">Egg Salad</Tag>
<Tag id="ham">Ham</Tag>
</TagGroup>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
}"use client";
import {type Selection} from 'react-aria-components';
import {Table, TableHeader, TableBody, Column, Row, Cell} from 'vanilla-starter/Table';
import {useState} from 'react';
///- begin collapse -///
const rows = [
{id: 'lettuce', name: 'Lettuce', type: 'Vegetable', calories: 4},
{id: 'tomato', name: 'Tomato', type: 'Vegetable', calories: 5},
{id: 'cheese', name: 'Cheddar', type: 'Cheese', calories: 113},
{id: 'tuna', name: 'Tuna salad', type: 'Salad', calories: 187},
{id: 'egg', name: 'Egg salad', type: 'Salad', calories: 200},
{id: 'ham', name: 'Ham', type: 'Meat', calories: 205}
];
///- end collapse -///
function Example() {
let [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(['cheese']));
return (
<div>
<Table
aria-label="Sandwich contents"
///- begin highlight -///
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
///- end highlight -///
>
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Calories</Column>
</TableHeader>
<TableBody items={rows}>
{item => (
<Row>
<Cell>{item.name}</Cell>
<Cell>{item.type}</Cell>
<Cell>{item.calories}</Cell>
</Row>
)}
</TableBody>
</Table>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
}Some components support a checkbox to select all items in the collection, or a keyboard shortcut like ⌘ Cmd + A. This represents a selection of all items in the collection, regardless of whether or not all items have been loaded from the network. For example, when using a component with infinite scrolling support, the user will be unaware that all items are not yet loaded. For this reason, it makes sense for select all to represent all items, not just the loaded ones.
When a select all event occurs, onSelectionChange is called with the string "all" rather than a set of selected keys. selectedKeys
and defaultSelectedKeys can also be set to "all" to programmatically select all items. The application must adjust its handling of bulk actions in this case to apply to the entire collection rather than only the keys available to it locally.
"use client";
import {Table, TableHeader, Column, TableBody, Row, Cell} from 'react-aria-components';
import {Checkbox} from 'vanilla-starter/Checkbox';
import {useState} from 'react';
///- begin collapse -///
const rows = [
{name: 'Games', date: '6/7/2020', type: 'File folder'},
{name: 'Program Files', date: '4/7/2021', type: 'File folder'},
{name: 'bootmgr', date: '11/20/2010', type: 'System file'},
{name: 'log.txt', date: '1/18/2016', type: 'Text Document'}
];
///- end collapse -///
function Example() {
let [selectedKeys, setSelectedKeys] = useState(new Set());
///- begin highlight -///
function performBulkAction() {
if (selectedKeys === 'all') {
// perform action on all items
} else {
// perform action on selected items in selectedKeys
}
}
///- end highlight -///
///- begin collapse -///
return (
<div>
<Table
aria-label="Files"
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}>
<TableHeader>
<Column><Checkbox slot="selection" /></Column>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Date Modified</Column>
</TableHeader>
<TableBody items={rows}>
{item => (
<Row id={item.name}>
<Cell><Checkbox slot="selection" /></Cell>
<Cell>{item.name}</Cell>
<Cell>{item.type}</Cell>
<Cell>{item.date}</Cell>
</Row>
)}
</TableBody>
</Table>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
///- end collapse -///
}By default, React Aria uses the "toggle" selection behavior, which behaves like a checkbox group: clicking, tapping, or pressing the Space or Enter keys toggles selection for the focused row. Using the arrow keys moves focus but does not change selection. The "toggle" selection mode is often paired with a column of checkboxes in each row as an explicit affordance for selection.
When the selectionBehavior prop is set to "replace", clicking a row with the mouse replaces the selection with only that row. Using the arrow keys moves both focus and selection. To select multiple rows, modifier keys such as Ctrl, Cmd, and Shift can be used. On touch screen devices, selection always behaves as toggle since modifier keys may not be available. This behavior emulates native platforms such as macOS and Windows, and is often used when checkboxes in each row are not desired.
To move focus without moving selection, the Ctrl key on Windows or the Option key on macOS can be held while pressing the arrow keys. Holding this modifier while pressing the Space key toggles selection for the focused row, which allows multiple selection of non-contiguous items.
These selection styles implement the behaviors defined in Aria Practices.
<ExampleSwitcher type="component" examples={['ListBox', 'GridList', 'Tree', 'TagGroup', 'Table']}>
"use client";
import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox';
import {useState} from 'react';
function Example(props) {
let [selectedKeys, setSelectedKeys] = useState(new Set());
return (
<ListBox
{...props}
aria-label="ListBox"
selectionMode="multiple"
/*- begin highlight -*/
/* PROPS */
/*- end highlight -*/
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}>
<ListBoxItem id="one">One</ListBoxItem>
<ListBoxItem id="two">Two</ListBoxItem>
<ListBoxItem id="three">Three</ListBoxItem>
</ListBox>
);
}"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';
import {useState} from 'react';
function Example(props) {
let [selectedKeys, setSelectedKeys] = useState(new Set());
return (
<GridList
{...props}
aria-label="GridList"
selectionMode="multiple"
/*- begin highlight -*/
/* PROPS */
/*- end highlight -*/
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}>
<GridListItem id="one">One</GridListItem>
<GridListItem id="two">Two</GridListItem>
<GridListItem id="three">Three</GridListItem>
</GridList>
);
}"use client";
import {type Selection} from 'react-aria-components';
import {Tree, TreeItem} from 'vanilla-starter/Tree';
import {useState} from 'react';
function Example(props) {
let [selectedKeys, setSelectedKeys] = useState<Selection>(new Set());
return (
<div>
<Tree
{...props}
aria-label="Files"
defaultExpandedKeys={['documents', 'photos', 'project']}
selectionMode="multiple"
/*- begin highlight -*/
/* PROPS */
/*- end highlight -*/
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}>
<TreeItem id="documents" title="Documents">
<TreeItem id="project" title="Project">
<TreeItem title="Weekly Report" />
</TreeItem>
</TreeItem>
<TreeItem id="photos" title="Photos">
<TreeItem title="Image 1" />
<TreeItem title="Image 2" />
</TreeItem>
</Tree>
<p>selectedKeys: {selectedKeys === 'all' ? 'all' : [...selectedKeys].join(', ')}</p>
</div>
);
}"use client";
import {TagGroup, Tag} from 'vanilla-starter/TagGroup';
import {useState} from 'react';
function Example(props) {
let [selectedKeys, setSelectedKeys] = useState(new Set());
return (
<TagGroup
{...props}
label="TagGroup"
selectionMode="multiple"
/*- begin highlight -*/
/* PROPS */
/*- end highlight -*/
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}>
<Tag id="one">One</Tag>
<Tag id="two">Two</Tag>
<Tag id="three">Three</Tag>
</TagGroup>
);
}"use client";
import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table';
import {TableBody, Cell} from 'react-aria-components';
import {useState} from 'react';
function Example(props) {
let [selectedKeys, setSelectedKeys] = useState(new Set());
return (
<Table
{...props}
aria-label="Table"
selectionMode="multiple"
/*- begin highlight -*/
/* PROPS */
/*- end highlight -*/
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}>
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Date Modified</Column>
</TableHeader>
<TableBody>
<Row>
<Cell>Games</Cell>
<Cell>File folder</Cell>
<Cell>6/7/2020</Cell>
</Row>
<Row>
<Cell>Program Files</Cell>
<Cell>File folder</Cell>
<Cell>4/7/2021</Cell>
</Row>
<Row>
<Cell>bootmgr</Cell>
<Cell>System file</Cell>
<Cell>11/20/2010</Cell>
</Row>
<Row>
<Cell>log.txt</Cell>
<Cell>Text Document</Cell>
<Cell>1/18/2016</Cell>
</Row>
</TableBody>
</Table>
);
}In some components, like a Select or ComboBox, only single selection is supported. In this case, the singular selectedKey and defaultSelectedKey props are available instead of their plural variants. These accept a single id instead of a Set as their value.
<ExampleSwitcher type="component" examples={['Select', 'ComboBox']}>
"use client";
import type {Key} from 'react-aria-components';
import {COMPONENT, COMPONENTItem} from 'vanilla-starter/COMPONENT';
import {useState} from 'react';
function Example() {
let [selectedKey, setSelectedKey] = useState<Key | null>(null);
return (
<div>
<COMPONENT
label="COMPONENT"
///- begin highlight -///
selectedKey={selectedKey}
///- end highlight -///
onSelectionChange={setSelectedKey}>
<COMPONENTItem id="one">One</COMPONENTItem>
<COMPONENTItem id="two">Two</COMPONENTItem>
<COMPONENTItem id="three">Three</COMPONENTItem>
</COMPONENT>
<p>selectedKey: {String(selectedKey)}</p>
</div>
);
}In components which support multiple selection, you can limit the selection to a single item using the
selectionMode prop. This continues to accept selectedKeys and defaultSelectedKeys as a Set, but it will
only contain a single id at a time.
Render a <SelectionIndicator /> within each collection item to animate selection changes. All CSS properties listed by transition-property are animated. Include the translate property to smoothly animate the position. Use the entering and exiting states to add a transition when no items are selected.
"use client";
import {GridList, GridListItem, SelectionIndicator} from 'react-aria-components';
import './SelectionIndicator.css';
function SelectableItem({id, children}) {
return (
<GridListItem id={id} className="animated-GridListItem">
{/*- begin highlight -*/}
<SelectionIndicator />
{/*- end highlight -*/}
{children}
</GridListItem>
);
}
<GridList
aria-label="Animated GridList"
selectionMode="single">
<SelectableItem>Home</SelectableItem>
<SelectableItem>Getting Started</SelectableItem>
<SelectableItem>Components</SelectableItem>
</GridList>In addition to selection, some collection components support item actions via the onAction prop. In the default "toggle" selection behavior, when nothing is selected, clicking, tapping, or pressing the Enter key triggers the item action. Items may be selected using the checkbox, or by pressing the Space key. When at least one item is selected, clicking or tapping a row toggles the selection.
In the "replace" selection behavior, selection is the primary interaction. Clicking an item with a mouse selects it, and double clicking performs the action. On touch devices, actions remain the primary tap interaction. Long pressing enters selection mode, which temporarily swaps the selection behavior to "toggle". Deselecting all items exits selection mode and reverts the selection behavior back to "replace". Keyboard behaviors are unaffected.
<ExampleSwitcher type="component" examples={['GridList', 'Tree', 'Table']}>
"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';
<GridList/* PROPS */>
{/*- begin highlight -*/}
<GridListItem onAction={() => alert('Opening Games')}>
{/*- end highlight -*/}
Games
</GridListItem>
<GridListItem onAction={() => alert('Opening Documents')}>
Documents
</GridListItem>
<GridListItem onAction={() => alert('Opening Photos')}>
Photos
</GridListItem>
</GridList>"use client";
import {Tree, TreeItem} from 'vanilla-starter/Tree';
<Tree
aria-label="Files"
selectionMode="multiple"
/* PROPS */
defaultExpandedKeys={['computer']}>
<TreeItem id="computer" title="My Computer">
<TreeItem
title="Games"
/*- begin highlight -*/
onAction={() => alert('Opening Games')} />
{/*- end highlight -*/}
<TreeItem
title="Documents"
onAction={() => alert('Opening Documents')} />
<TreeItem
title="Photos"
onAction={() => alert('Opening Photos')} />
</TreeItem>
</Tree>"use client";
import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table';
import {useState} from 'react';
<Table
aria-label="Table"
selectionMode="multiple"
/* PROPS */
selectionMode="multiple">
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Date Modified</Column>
</TableHeader>
<TableBody>
{/*- begin highlight -*/}
<Row onAction={() => alert('Opening Games')}>
{/*- end highlight -*/}
<Cell>Games</Cell>
<Cell>File folder</Cell>
<Cell>6/7/2020</Cell>
</Row>
<Row onAction={() => alert('Opening Documents')}>
<Cell>Documents</Cell>
<Cell>File folder</Cell>
<Cell>4/7/2021</Cell>
</Row>
<Row onAction={() => alert('Opening Photos')}>
<Cell>Photos</Cell>
<Cell>File folder</Cell>
<Cell>11/20/2010</Cell>
</Row>
</TableBody>
</Table>In dynamic collections, it may be more convenient to use the onAction prop at the collection level instead of on individual items. This receives the id of the pressed item.
<ExampleSwitcher type="component" examples={['GridList', 'Tree', 'Table']}>
"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';
///- begin collapse -///
const files = [
{id: 'games', name: 'Games'},
{id: 'documents', name: 'Documents'},
{id: 'photos', name: 'Photos'}
];
///- end collapse -///
<GridList
aria-label="Files"
selectionMode="multiple"
/* PROPS */
items={files}
/*- begin highlight -*/
onAction={id => alert(`Opening ${id}`)}>
{/*- end highlight -*/}
{item => <GridListItem>{item.name}</GridListItem>}
</GridList>"use client";
import {Tree, TreeItem} from 'vanilla-starter/Tree';
import {Collection} from 'react-aria-components';
///- begin collapse -///
const files = [
{id: 'games', name: 'Games'},
{id: 'documents', name: 'Documents'},
{id: 'photos', name: 'Photos'}
];
///- end collapse -///
<Tree
aria-label="Files"
selectionMode="multiple"
/* PROPS */
defaultExpandedKeys={['computer']}
/*- begin highlight -*/
onAction={id => alert(`Opening ${id}`)}>
{/*- end highlight -*/}
<TreeItem id="computer" title="My Computer">
<Collection items={files}>
{item => <TreeItem title={item.name} />}
</Collection>
</TreeItem>
</Tree>"use client";
import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table';
import {useState} from 'react';
///- begin collapse -///
const files = [
{id: 'games', name: 'Games', type: 'Folder', date: '6/7/2020'},
{id: 'documents', name: 'Documents', type: 'Folder', date: '4/7/2021'},
{id: 'photos', name: 'Photos', type: 'Folder', date: '11/20/2010'}
];
///- end collapse -///
<Table
aria-label="Table"
selectionMode="multiple"
/* PROPS */
/*- begin highlight -*/
onRowAction={id => alert(`Opening ${id}`)}>
{/*- end highlight -*/}
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Date Modified</Column>
</TableHeader>
<TableBody items={files}>
{item => (
<Row>
<Cell>{item.name}</Cell>
<Cell>{item.type}</Cell>
<Cell>{item.date}</Cell>
</Row>
)}
</TableBody>
</Table>An item can be disabled with the isDisabled prop. By default, disabled items are not focusable, selectable, or actionable. When disabledBehavior="selection", only selection is disabled.
<ExampleSwitcher type="component" examples={['ListBox', 'GridList', 'Tree', 'TagGroup', 'Table']}>
"use client";
import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox';
<ListBox aria-label="Pokemon" selectionMode="multiple">
<ListBoxItem>Charizard</ListBoxItem>
<ListBoxItem>Blastoise</ListBoxItem>
{/*- begin highlight -*/}
<ListBoxItem isDisabled>Venusaur</ListBoxItem>
{/*- end highlight -*/}
<ListBoxItem>Pikachu</ListBoxItem>
</ListBox>"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';
<GridList/* PROPS */>
<GridListItem>Charizard</GridListItem>
<GridListItem>Blastoise</GridListItem>
{/*- begin highlight -*/}
<GridListItem isDisabled>Venusaur</GridListItem>
{/*- end highlight -*/}
<GridListItem>Pikachu</GridListItem>
</GridList>"use client";
import {Tree, TreeItem} from 'vanilla-starter/Tree';
<Tree
aria-label="Pokemon evolution"
style={{height: 250}}
defaultExpandedKeys={['bulbasaur', 'ivysaur']}
/* PROPS */
selectionMode="multiple">
<TreeItem id="bulbasaur" title="Bulbasaur">
<TreeItem id="ivysaur" title="Ivysaur">
{/*- begin highlight -*/}
<TreeItem id="venusaur" title="Venusaur" isDisabled />
{/*- end highlight -*/}
</TreeItem>
</TreeItem>
<TreeItem id="charmander" title="Charmander">
<TreeItem id="charmeleon" title="Charmeleon">
<TreeItem id="charizard" title="Charizard" />
</TreeItem>
</TreeItem>
<TreeItem id="squirtle" title="Squirtle">
<TreeItem id="wartortle" title="Wartortle">
<TreeItem id="blastoise" title="Blastoise" />
</TreeItem>
</TreeItem>
</Tree>"use client";
import {TagGroup, Tag} from 'vanilla-starter/TagGroup';
<TagGroup
label="Pokemon"
/* PROPS */
selectionMode="multiple">
<Tag>Charizard</Tag>
<Tag>Blastoise</Tag>
{/*- begin highlight -*/}
<Tag isDisabled>Venusaur</Tag>
{/*- end highlight -*/}
<Tag>Pikachu</Tag>
</TagGroup>import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table';
<Table
aria-label="Pokemon"
/* PROPS */
selectionMode="multiple">
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Level</Column>
</TableHeader>
<TableBody>
<Row id="charizard">
<Cell>Charizard</Cell>
<Cell>Fire, Flying</Cell>
<Cell>67</Cell>
</Row>
<Row id="blastoise">
<Cell>Blastoise</Cell>
<Cell>Water</Cell>
<Cell>56</Cell>
</Row>
{/*- begin highlight -*/}
<Row id="venusaur" isDisabled>
{/*- end highlight -*/}
<Cell>Venusaur</Cell>
<Cell>Grass, Poison</Cell>
<Cell>83</Cell>
</Row>
<Row id="pikachu">
<Cell>Pikachu</Cell>
<Cell>Electric</Cell>
<Cell>100</Cell>
</Row>
</TableBody>
</Table>In dynamic collections, it may be more convenient to use the disabledKeys prop at the collection level instead of isDisabled on individual items. This accepts a list of item ids that are disabled.
<ExampleSwitcher type="component" examples={['ListBox', 'GridList', 'Tree', 'TagGroup', 'Table']}>
"use client";
import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox';
///- begin collapse -///
const items = [
{id: 1, name: 'Charizard'},
{id: 2, name: 'Blastoise'},
{id: 3, name: 'Venusaur'},
{id: 4, name: 'Pikachu'}
];
///- end collapse -///
<ListBox
aria-label="Pokemon"
/* PROPS */
///- begin highlight -///
disabledKeys={[3]}
///- end highlight -///
items={items}>
{item => <ListBoxItem>{item.name}</ListBoxItem>}
</ListBox>"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';
///- begin collapse -///
const items = [
{id: 1, name: 'Charizard'},
{id: 2, name: 'Blastoise'},
{id: 3, name: 'Venusaur'},
{id: 4, name: 'Pikachu'}
];
///- end collapse -///
<GridList
aria-label="Pokemon"
/* PROPS */
///- begin highlight -///
disabledKeys={[3]}
///- end highlight -///
items={items}>
{item => <GridListItem>{item.name}</GridListItem>}
</GridList>"use client";
import {Tree, TreeItem} from 'vanilla-starter/Tree';
import {Collection} from 'react-aria-components';
///- begin collapse -///
let items = [
{id: 1, name: 'Bulbasaur', type: 'Grass', level: 14, children: [
{id: 2, name: 'Ivysaur', type: 'Grass', level: 30, children: [
{id: 3, name: 'Venusaur', type: 'Grass', level: 83}
]}
]},
{id: 4, name: 'Charmander', type: 'Fire', level: 16, children: [
{id: 5, name: 'Charmeleon', type: 'Fire', level: 32, children: [
{id: 6, name: 'Charizard', type: 'Fire, Flying', level: 67}
]}
]},
{id: 7, name: 'Squirtle', type: 'Water', level: 8, children: [
{id: 8, name: 'Wartortle', type: 'Water', level: 34, children: [
{id: 9, name: 'Blastoise', type: 'Water', level: 56}
]}
]}
];
///- end collapse -///
<Tree
aria-label="Pokemon evolution"
style={{height: 250}}
defaultExpandedKeys={[1, 2]}
selectionMode="multiple"
/* PROPS */
///- begin highlight -///
disabledKeys={[3]}
///- end highlight -///
items={items}>
{function renderItem(item: Pokemon) {
return (
<TreeItem title={item.name}>
<Collection items={item.children}>
{renderItem}
</Collection>
</TreeItem>
)
}}
</Tree>"use client";
import {TagGroup, Tag} from 'vanilla-starter/TagGroup';
///- begin collapse -///
const items = [
{id: 1, name: 'Charizard'},
{id: 2, name: 'Blastoise'},
{id: 3, name: 'Venusaur'},
{id: 4, name: 'Pikachu'}
];
///- end collapse -///
<TagGroup
aria-label="Pokemon"
selectionMode="multiple"
/* PROPS */
///- begin highlight -///
disabledKeys={[3]}
///- end highlight -///
items={items}>
{item => <Tag>{item.name}</Tag>}
</TagGroup>"use client";
import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table';
///- begin collapse -///
let items = [
{id: 1, name: 'Charizard', type: 'Fire, Flying', level: 67},
{id: 2, name: 'Blastoise', type: 'Water', level: 56},
{id: 3, name: 'Venusaur', type: 'Grass, Poison', level: 83},
{id: 4, name: 'Pikachu', type: 'Electric', level: 100}
];
///- end collapse -///
<Table
aria-label="Pokemon"
/* PROPS */
///- begin highlight -///
disabledKeys={[3]}
///- end highlight -///
selectionMode="multiple">
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Type</Column>
<Column>Level</Column>
</TableHeader>
<TableBody items={items}>
{item => (
<Row>
<Cell>{item.name}</Cell>
<Cell>{item.type}</Cell>
<Cell>{item.level}</Cell>
</Row>
)}
</TableBody>
</Table>