Take the recursive File Explorer and make it accessible: expose the proper ARIA tree pattern so assistive tech announces it as a tree, not a pile of buttons. That means the right roles (tree, treeitem, group), the right states (aria-expanded, aria-selected), and a single tab stop via roving tabindex.
type FileNode = { name: string; children?: FileNode[] };
// A self-contained component. No props.
function App(): JSX.Element;
The same nested tree, now carrying ARIA roles, states, and properties.
<ul role="tree" aria-label="File system">
<li role="treeitem" aria-expanded="true" aria-selected="false" tabindex="-1"> src
<ul role="group"> … </ul>
</li>
<li role="treeitem" aria-selected="true" tabindex="0"> package.json </li>
</ul>
folders → aria-expanded reflects open/closed
files → no aria-expanded (they can't expand)
exactly one treeitem has tabindex="0" (the selected one)
tree on the root list, treeitem on every node, group on each nested child list.aria-expanded only on folders; aria-selected on the chosen node.tabindex="0", all others -1.