File System Tree
A file system Tree featuring multiple selection and styled with Tailwind CSS.
Example#
import {Button, Collection, Tree, TreeItem, TreeItemContent} from 'react-aria-components';
import ChevronIcon from '@spectrum-icons/ui/ChevronRightMedium';
function FileSystemExample() {
return (
<div className="bg-linear-to-r from-indigo-500 to-violet-500 p-8 rounded-lg flex items-center justify-center">
<Tree
aria-label="File system"
selectionMode="multiple"
selectionBehavior="replace"
items={filesystem}
defaultExpandedKeys={['documents']}
className={`
border-separate border-spacing-0 w-60 h-100 bg-slate-900
overflow-auto rounded-lg shadow-lg`}
>
{function renderItem(item) {
return (
<TreeItem
textValue={item.name}
className={`selected:bg-slate-500 text-white
cursor-default group outline-hidden focus-visible:outline focus-visible:outline-2
focus-visible:outline-slate-600 focus-visible:-outline-offset-4
selected:focus-visible:outline-white`}
>
<TreeItemContent>
{({ hasChildItems }) => (
<div className="flex items-center space-x-2 py-2 ps-[calc(calc(var(--tree-item-level)_-_1)_*_calc(var(--spacing)_*_3))]">
{hasChildItems
? (
<Button
slot="chevron"
className={`shrink-0 w-8 h-8
group-data-[expanded=true]:rotate-90 transition-rotate duration-200
inline-flex items-center justify-center bg-transparent border-0 me-0
cursor-default outline-hidden text-white`}
>
<ChevronIcon />
</Button>
)
: <div className="shrink-0 w-8 h-8" />}
<div>{item.name}</div>
</div>
)}
</TreeItemContent>
<Collection items={item.children}>
{renderItem}
</Collection>
</TreeItem>
);
}}
</Tree>
</div>
);
}
import {
Button,
Collection,
Tree,
TreeItem,
TreeItemContent
} from 'react-aria-components';
import ChevronIcon from '@spectrum-icons/ui/ChevronRightMedium';
function FileSystemExample() {
return (
<div className="bg-linear-to-r from-indigo-500 to-violet-500 p-8 rounded-lg flex items-center justify-center">
<Tree
aria-label="File system"
selectionMode="multiple"
selectionBehavior="replace"
items={filesystem}
defaultExpandedKeys={['documents']}
className={`
border-separate border-spacing-0 w-60 h-100 bg-slate-900
overflow-auto rounded-lg shadow-lg`}
>
{function renderItem(item) {
return (
<TreeItem
textValue={item.name}
className={`selected:bg-slate-500 text-white
cursor-default group outline-hidden focus-visible:outline focus-visible:outline-2
focus-visible:outline-slate-600 focus-visible:-outline-offset-4
selected:focus-visible:outline-white`}
>
<TreeItemContent>
{({ hasChildItems }) => (
<div className="flex items-center space-x-2 py-2 ps-[calc(calc(var(--tree-item-level)_-_1)_*_calc(var(--spacing)_*_3))]">
{hasChildItems
? (
<Button
slot="chevron"
className={`shrink-0 w-8 h-8
group-data-[expanded=true]:rotate-90 transition-rotate duration-200
inline-flex items-center justify-center bg-transparent border-0 me-0
cursor-default outline-hidden text-white`}
>
<ChevronIcon />
</Button>
)
:
<div className="shrink-0 w-8 h-8" />}
<div>{item.name}</div>
</div>
)}
</TreeItemContent>
<Collection items={item.children}>
{renderItem}
</Collection>
</TreeItem>
);
}}
</Tree>
</div>
);
}
import {
Button,
Collection,
Tree,
TreeItem,
TreeItemContent
} from 'react-aria-components';
import ChevronIcon from '@spectrum-icons/ui/ChevronRightMedium';
function FileSystemExample() {
return (
<div className="bg-linear-to-r from-indigo-500 to-violet-500 p-8 rounded-lg flex items-center justify-center">
<Tree
aria-label="File system"
selectionMode="multiple"
selectionBehavior="replace"
items={filesystem}
defaultExpandedKeys={[
'documents'
]}
className={`
border-separate border-spacing-0 w-60 h-100 bg-slate-900
overflow-auto rounded-lg shadow-lg`}
>
{function renderItem(
item
) {
return (
<TreeItem
textValue={item
.name}
className={`selected:bg-slate-500 text-white
cursor-default group outline-hidden focus-visible:outline focus-visible:outline-2
focus-visible:outline-slate-600 focus-visible:-outline-offset-4
selected:focus-visible:outline-white`}
>
<TreeItemContent>
{(
{
hasChildItems
}
) => (
<div className="flex items-center space-x-2 py-2 ps-[calc(calc(var(--tree-item-level)_-_1)_*_calc(var(--spacing)_*_3))]">
{hasChildItems
? (
<Button
slot="chevron"
className={`shrink-0 w-8 h-8
group-data-[expanded=true]:rotate-90 transition-rotate duration-200
inline-flex items-center justify-center bg-transparent border-0 me-0
cursor-default outline-hidden text-white`}
>
<ChevronIcon />
</Button>
)
: (
<div className="shrink-0 w-8 h-8" />
)}
<div>
{item
.name}
</div>
</div>
)}
</TreeItemContent>
<Collection
items={item
.children}
>
{renderItem}
</Collection>
</TreeItem>
);
}}
</Tree>
</div>
);
}
Tailwind config#
This example uses the tailwindcss-react-aria-components plugin. When using Tailwind v4, add it to your CSS:
@import "tailwindcss";
@plugin "tailwindcss-react-aria-components";
@import "tailwindcss";
@plugin "tailwindcss-react-aria-components";
@import "tailwindcss";
@plugin "tailwindcss-react-aria-components";
Tailwind v3
When using Tailwind v3, add the plugin to your tailwind.config.js
instead:
module.exports = {
// ...
plugins: [
require('tailwindcss-react-aria-components')
]
};
module.exports = {
// ...
plugins: [
require('tailwindcss-react-aria-components')
]
};
module.exports = {
// ...
plugins: [
require(
'tailwindcss-react-aria-components'
)
]
};
Note: When using Tailwind v3, install tailwindcss-react-aria-components
version 1.x instead of 2.x.
Components#
Tree
A tree provides users with a way to navigate nested hierarchical information, with support for keyboard navigation and selection.