A Tree
represents a hierarchical list of items that might have child items
that can be expanded, collapsed, or selected. To create a Tree
within
react-md
, the basic requirements are to provide:
id
for the tree (required for a11y)aria-label
or aria-labelledby
describing the purpose of the treeTreeData
to render where the requirements are to have an
itemId
and parentId
referencing other itemId
s within the tree or null
for root level items.itemId
s within the tree and handlers for updating the
selected idsitemId
s within the tree and handlers for updating the
expanded idsThis might seem like a lot to get started with, but luckily @react-md/tree
provides two hooks for handling the selectedIds
and expandedIds
named
useTreeItemSelection
and useTreeItemExpansion
that should work for most
cases out of the box.
A tree will be created by traversing the TreeData
and linking itemId
s of
each item to a parentId
. Every item that has a parentId
pointing to null
(or a custom rootId
prop) will appear at the root of the tree while all
parentId
s pointing to another itemId
will be a child of that item.
If you are a Typescript user, this package also provides a bunch of types you can use to strictly type your tree:
TreeItemIds
,BaseTreeItem
,TreeData
,TreeItemSorter
,TreeItemRenderer
, etc. See more in the examples below.
One of the biggest "selling points" for this package is the built-in accessibility and keyboard movement. They key features are:
aria-activedescendant
ArrowUp
and ArrowDown
keysSpace
and Enter
Home
and End
ArrowRight
and ArrowLeft
keysArrowLeft
ArrowRight
*
(asterisk)Control+a
(requires
multiSelect
prop enabled)Control+Shift+Home
(requires multiSelect
prop enabled)Control+Shift+End
(requires multiSelect
prop enabled)One of the most common forms of a tree is a single selection tree that only
allows one item to be selected at a time. This example will render a very simple
folder tree and show how items are linked together and rendered within the tree
along with an example of using the useTreeItemSelection
and
useTreeItemExpansion
hooks.
The useTreeItemSelection
hook returns an object containing the following props
to pass to the Tree
component to get selection behavior:
selectedIds
- A list of the current selected ids within the tree.onItemSelection
- A callback that updates the selectedIds
when an item
within the tree is clickedonMultiItemSelection
- A callback that updates the selectedIds
when a
"batch selection" occurs. This callback will never be called if the second
argument for this hook is omitted or set to false
.multiSelect
- Boolean if multi-select behavior is enabled for this tree. The
default is false
.The useTreeItemExpansion
hook returns an object containing the following props
to pass to the Tree
component to get expansion behavior:
expandedIds
- A list of the current expanded ids within the tree.onItemExpansion
- A callback that updates the expandedIds
when a tree item
should be expanded or collapsedonMultiItemExpansion
- A callback that updates the expandedIds
when a
"batch expansion" occurs (pressing the asterisk *
key)To create a multi-selectable tree, all that is required is to enable the
multiSelect
argument on the useTreeItemSelection
hook. Now multi tree items
will be selectable and the additional keyboard shortcuts for selecting items
will be enabled.
Now that you've learned a bit about how to use the Tree
component to render
simple trees, let's look at how we can customize how each item is rendered with
the getItemProps
prop on the Tree
.
This prop can be used to add additional styling or general ListItem
props that
you'd like to not store in your tree and dynamically apply to each item. This
function will provide the current item
merged with the focused
, selected
,
and expanded
booleans representing the state of the item.
The example below will render a simple "code file tree" by dynamically applying icons based on file types and overriding some styles when focused or selected.