<Box sx={{maxWidth: 400}}><nav aria-label="File navigation"><TreeView aria-label="File navigation"><TreeView.Item><TreeView.LeadingVisual><TreeView.DirectoryIcon /></TreeView.LeadingVisual>src<TreeView.SubTree><TreeView.LinkItem href="#"><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>Avatar.tsx<TreeView.TrailingVisual><StyledOcticon icon={DiffAddedIcon} color="success.fg" aria-label="added" /></TreeView.TrailingVisual></TreeView.LinkItem><TreeView.LinkItem href="#" current><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>Button.tsx<TreeView.TrailingVisual><StyledOcticon icon={DiffModifiedIcon} color="attention.fg" aria-label="modified" /></TreeView.TrailingVisual></TreeView.LinkItem></TreeView.SubTree></TreeView.Item><TreeView.LinkItem href="#"><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>package.json<TreeView.TrailingVisual><StyledOcticon icon={DiffModifiedIcon} color="attention.fg" aria-label="modified" /></TreeView.TrailingVisual></TreeView.LinkItem></TreeView></nav></Box>
<Box sx={{maxWidth: 400}}><nav aria-label="File navigation"><TreeView aria-label="File navigation"><TreeView.LinkItem href="#"><TreeView.LeadingVisual><TreeView.DirectoryIcon /></TreeView.LeadingVisual>src<TreeView.SubTree><TreeView.LinkItem href="#"><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>Avatar.tsx</TreeView.LinkItem><TreeView.LinkItem href="#" current><TreeView.LeadingVisual><TreeView.DirectoryIcon /></TreeView.LeadingVisual>Button<TreeView.SubTree><TreeView.LinkItem href="#"><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>Button.tsx</TreeView.LinkItem><TreeView.LinkItem href="#"><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>Button.test.tsx</TreeView.LinkItem></TreeView.SubTree></TreeView.LinkItem></TreeView.SubTree></TreeView.LinkItem><TreeView.LinkItem href="#"><TreeView.LeadingVisual><FileIcon /></TreeView.LeadingVisual>package.json</TreeView.LinkItem></TreeView></nav></Box>
function ControlledTreeView() {const [expanded, setExpanded] = React.useState(false)return (<Box sx={{display: 'grid', gap: 2, maxWidth: 400}}><Button onClick={() => setExpanded(!expanded)}>{expanded ? 'Collapse' : 'Expand'}</Button><nav aria-label="File navigation"><TreeView aria-label="File navigation"><TreeView.Item expanded={expanded} onExpandedChange={setExpanded}>src<TreeView.SubTree><TreeView.LinkItem href="#">Avatar.tsx</TreeView.LinkItem><TreeView.LinkItem href="#" current>Button.tsx</TreeView.LinkItem></TreeView.SubTree></TreeView.Item></TreeView></nav></Box>)}render(<ControlledTreeView />)
To render stateful visuals, pass a render function to TreeView.LeadingVisual
or TreeView.TrailingVisual
. The function will be called with the expanded
state of the item.
<Box sx={{maxWidth: 400}}><nav aria-label="File navigation"><TreeView aria-label="File navigation"><TreeView.Item><TreeView.LeadingVisual>{({isExpanded}) => (isExpanded ? <FileDirectoryOpenFillIcon /> : <FileDirectoryFillIcon />)}</TreeView.LeadingVisual>src<TreeView.SubTree><TreeView.LinkItem href="#">Avatar.tsx</TreeView.LinkItem><TreeView.LinkItem href="#" current>Button.tsx</TreeView.LinkItem></TreeView.SubTree></TreeView.Item></TreeView></nav></Box>
Since stateful directory icons are a common use case for TreeView, we provide a TreeView.DirectoryIcon
component for convenience. The previous example can be rewritten as:
<Box sx={{maxWidth: 400}}><nav aria-label="File navigation"><TreeView aria-label="File navigation"><TreeView.Item><TreeView.LeadingVisual><TreeView.DirectoryIcon /></TreeView.LeadingVisual>src<TreeView.SubTree><TreeView.LinkItem href="#">Avatar.tsx</TreeView.LinkItem><TreeView.LinkItem href="#" current>Button.tsx</TreeView.LinkItem></TreeView.SubTree></TreeView.Item></TreeView></nav></Box>
See Storybook for examples with asynchronously loaded items.
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactNode |
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactNode | ||
current | boolean | false | Whether the item is the current item. No more than one item should be current at once. The path to the current item will be expanded by default. |
defaultExpanded | boolean | The expanded state of the item when it is initially rendered. Use when you do not need to control the state. | |
expanded | boolean | The controlled expanded state of item. Must be used in conjunction with onExpandedChange. | |
onExpandedChange | (expanded: boolean) => void | Event handler called when the expanded state of the item changes. | |
onSelect | (event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void | ||
ref | React.RefObject<HTMLElement> | A ref to the element rendered by this component. |
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactNode | ||
href | string | The URL that the item navigates to. href is passed to the underlying <a> element. If as is specified, the component may need different props. If the item contains a sub-nav, the item is rendered as a <button> and href is ignored. | |
current | boolean | false | Whether the item is the current item. No more than one item should be current at once. The path to the current item will be expanded by default. |
defaultExpanded | boolean | The expanded state of the item when it is initially rendered. Use when you do not need to control its state. | |
expanded | boolean | The controlled expanded state of item. Must be used in conjunction with onExpandedChange. | |
onExpandedChange | (expanded: boolean) => void | Event handler called when the expanded state of the item changes. | |
onSelect | (event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void | ||
ref | React.RefObject<HTMLElement> | A ref to the element rendered by this component. |
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | ||
state | | 'initial' | 'loading' | 'done' | 'error' | Specify a state if items in the subtree are loaded asynchronously. An asynchronous subtree can be in one of the following states:
|
Name | Type | Default | Description |
---|---|---|---|
children | | React.ReactNode | (props: {isExpanded: boolean}) => React.ReactNode | ||
label | string | Provide an accessible label for the leading visual. This is not necessary for decorative visuals |
Name | Type | Default | Description |
---|---|---|---|
children | | React.ReactNode | (props: {isExpanded: boolean}) => React.ReactNode | ||
label | string | Provide an accessible label for the trailing visual. This is not necessary for decorative visuals |
Name | Type | Default | Description |
---|