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 itemIds within the tree or null
for root level items.itemIds within the tree and handlers for updating the
selected idsitemIds 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 itemIds 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
parentIds 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-activedescendantArrowUp and ArrowDown keysSpace and EnterHome and EndArrowRight and ArrowLeft keysArrowLeftArrowRight* (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 Treecomponent 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.