Founding price: $35, then $79.99 after 23:59 UTC on 4 November, then $79.99
Get ProA tree that loads each branch the first time it opens, with a busy row, a spoken status, an error state and a retry.
Derived from this item’s props table, because it declares no controls of its own. Changes drive the preview live.
Use it for large or remote hierarchies: cloud storage, repositories, org charts, category trees behind an API.
Do not use it when the whole tree is already in memory; tree-view is simpler. For very many visible rows use virtual-tree.
It uses tree-view, which the CLI installs for you.
import { AsyncTree } from "@/components/ui/async-tree"<AsyncTree
aria-label="Folders"
nodes={[{ id: "inbox", label: "Inbox", hasChildren: true }]}
loadChildren={async (node) => {
const res = await fetch(`/api/folders/${node.id}`)
if (!res.ok) throw new Error("failed")
return res.json()
}}
/>| Prop | Type | Default | Description |
|---|---|---|---|
nodes | TreeNode[] | - | The top level. A branch to load has hasChildren: true and no children. |
loadChildren | (node) => Promise<TreeNode[]> | - | Resolve with the children. Reject to show the error. |
onNodesChange | (nodes) => void | - | Called with the full tree after each load. |
retryLabel | string | "Retry" | Text of the retry button. |
... | - | - | All TreeView props. |
tree-view.Motion respects prefers-reduced-motion: the only animation is the loading spinner, which is switched off. Layout uses logical properties, so the component works in right-to-left languages.
The component ships with a Testing Library test (async-tree.test.tsx) that covers its keyboard paths, roles and states.