Preview
Installation
Basic usage
Keep labels, navigation and state in the consuming application. TreeView owns the nested list; Collapsible owns each branch disclosure.
Branch controls support Tab, Enter and Space through Collapsible. Links preserve native navigation and modified clicks. Branch rows expand or collapse by default. Set an itemโs action to "navigate" when its label must open a destination; that branch keeps a separate disclosure control. This is a semantic navigation list, not a tree widget with arrow-key navigation.
Use expandedIds and onExpandedIdsChange to control expansion. Closing a branch returns focus from a hidden descendant to its disclosure control. Use activeId and onActiveIdChange to control the active item. Long labels wrap within the available width.
Structures
TreeView is the public component. The diagram shows its internal composition, including nested branches, labels and counts. Pass TreeViewItem data rather than assembling public subparts.
Examples
Use cases
Menu
Click any branch row to expand or collapse its children. The basic menu places its indicator on the right. Leaf links open their destinations; explicit action="navigate" also supports linked branches.
File Tree
Click a folder row to expand or collapse it. The basic file tree uses its closed or open folder icon as the indicator, without an extra arrow. Files can open their content or be selected for an operation.
Folder selection
Set the itemโs action to "select" when a folder represents an operation such as choosing a working directory. Its label selects the folder, while the arrow still controls disclosure.
Code Structure
Read nested component composition in monospace. Branches start expanded. Click a branch row to collapse or expand it. The basic code variant includes a trunk rail. Leaf labels have no action by default. Code labels have no decorative icons.
Table of Contents
Navigate page sections with a reading-progress rail. TOC headings stay expanded without arrows by default. See Table of Contents for heading depth, compact mode and navigation configuration.
Disclosure indicator
Folder icon
The basic file tree uses a folder icon that changes when the branch opens. The whole folder row controls disclosure.
Arrow
Use disclosureIndicator="arrow" to add a separate visual arrow to the file row. Default branch rows still use one action.
Indicator position
Leading
Place the branch arrow before the label. Code structure uses this position by default.
Trailing
Place the arrow at the rowโs end. The basic menu uses this position by default.
Linked branch
Set action="navigate" when a branch has its own page. Its label opens that page and its separate disclosure control expands or collapses its children.
Rail
None
Menu and file defaults use indentation without a trunk. Set rail="none" to remove the code variantโs default trunk.
Trunk
A quiet line connects each expanded branch.
Indicators
No counter
Labels stand on their own unless an item supplies a count.
Child count
Show the number of direct children beside a branch label. An explicit item count takes precedence.
Mobile reading progress
A compact section selector and a clock follow the article as you read. Scroll the article or select a section. The clock shows the actual reading fraction without a numeric counter.
Pricing guide
Overview
Choose a plan that fits your team. Every plan includes shared projects and version history.
Plans
Start with the essentials. Add seats as your team grows, and change your plan at any time.
Billing
Choose monthly or annual billing. Your plan renews on the same date each period.
Invoices
Download invoices from your billing history. Each invoice includes the plan, seats and billing period.
FAQs
Plan changes take effect at the next billing period. Contact your account owner to update payment details.
Highlight width
Content
Set itemWidth="content" to keep hover feedback close to the label.
Row
The default menu, file and code variants use the full row, including the empty leading area.
States
Active and focus
Resting labels use a secondary text color. The selected label uses the foreground color without a fill or border. Hover adds a row background without an underline. Keyboard focus keeps a separate ring.
Disabled
Disabled items cannot activate. Their labels remain visible.
Empty
An empty tree shows the supplied label.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
items | TreeViewItem[] | Nested items. Each item has an id and label, with optional children, href, action, icon, count, disabled and code. | |
TreeViewItem.action | "navigate" | "toggle" | "select" | "none" | Controls the label action and overrides inference. Omit it to toggle branches first, including branches with hrefs. Leaves use native href navigation or non-code selection when onActiveIdChange is supplied. Code leaves are inert by default. Navigate without href and toggle without children are inert. The arrow only toggles expansion. | |
variant | "menu" | "file" | "code" | "outline" | Use-case styling. Default: menu. TableOfContents composes outline. | |
rail | "none" | "trunk" | Expanded-branch guide. Default: trunk for code, none for menu/file/outline. | |
itemWidth | "content" | "row" | Width of hover feedback. Row feedback uses a common tree width sized to the widest descendant, capped by its host. Default: row for menu/file/code, content for outline. | |
disclosureIndicator | "arrow" | "folder" | Branch indicator. Default: folder for file, arrow for menu/code/outline. | |
disclosurePosition | "start" | "end" | Indicator position. Default: end for menu/outline, start for file/code. | |
counter | "none" | "children" | Optional direct-child count. Default: none. Item count takes precedence. | |
collapsible | boolean | Enables branch controls. Default: true. TableOfContents passes false by default to keep every heading visible without arrows. | |
expandedIds | string[] | Caller-owned expanded branch IDs. | |
defaultExpandedIds | string[] | Initial expanded branch IDs. An explicit empty array keeps every branch closed; omitted defaults expand code branches only. | |
onExpandedIdsChange | (ids: string[]) => void | Called when a disclosure changes expansion. | |
activeId | string | Caller-owned active item ID. | |
onActiveIdChange | (id: string) => void | Called when a link or select action selects an item. | |
onNavigate | (id: string, event: React.MouseEvent<HTMLAnchorElement>) => void | Called for ordinary link clicks. Modified clicks preserve browser behavior. | |
aria-label | string | Accessible name of the navigation list. Default: Tree view. | |
emptyLabel | string | Text shown when there are no items. Default: No items. | |
className | string | Additional class on the navigation root. |