Skip to content
DocsComponentsTemplatesThemesPlayground
Search
Switch to dark mode
Community
GitHub
Get started
Type to search
↑↓Navigate↵SelectEscClose
Components
Overview
App Shell
App Shell
useAppShellMobile
Aspect Ratio
Avatar
Avatar
Avatar Group
Avatar Group Overflow
Avatar Status Dot
Badge
Banner
Blockquote
Breadcrumbs
Breadcrumb Item
Breadcrumbs
Button
Button
Button Group
Icon Button
Toggle Button
Toggle Button Group
Calendar
Card
Card
Clickable Card
Selectable Card
Carousel
Chat
Chat Composer
Chat Composer Drawer
Chat Composer Input
Chat Composer Token Element
Chat Dictation Button
Chat Layout
Chat Layout Scroll Button
Chat Message
Chat Message Bubble
Chat Message List
Chat Message Metadata
Chat Send Button
Chat System Message
Chat Tokenized Text
Chat Tool Calls
Checkbox
Checkbox Input
Checkbox List
Checkbox List Item
Citation
Code
Code Block
Collapsible
Collapsible
Collapsible Group
useCollapsible
Command Palette
Command Palette
Command Palette Empty
Command Palette Footer
Command Palette Group
Command Palette Input
Command Palette Item
Command Palette List
Context Menu
Context Menu
Context Menu Item
Date Input
Date Input
Date Range Input
Date Time Input
Dialog
Alert Dialog
Dialog
Dialog Header
useImperativeAlertDialog
useImperativeDialog
Divider
Dropdown Menu
Dropdown Menu
Dropdown Menu Item
Empty State
Field
Field
Field Label
Field Status
Input Group
Input Group Text
File Input
Heading
Hover Card
Hover Card
useHoverCard
Icon
Item
Kbd
Layout
Center
Form Layout
Grid
Grid Span
H Stack
Layout
Layout Content
Layout Footer
Layout Header
Layout Panel
Section
Stack Item
V Stack
Lightbox
Link
List
List
List Item
Markdown
Metadata List
Metadata List
Metadata List Item
More Menu
Navigation
Mobile Nav
Mobile Nav Toggle
Nav Heading Menu
Nav Icon
Side Nav
Side Nav Collapse Button
Side Nav Heading
Side Nav Item
Side Nav Section
Top Nav
Top Nav Heading
Top Nav Item
Top Nav Mega Menu
Top Nav Mega Menu Featured Card
Top Nav Mega Menu Item
Top Nav Menu
Number Input
Outline
Overflow List
Overlay
Pagination
Popover
Popover
usePopover
Power Search
Progress Bar
Radio
Radio List
Radio List Item
Resizable
Resize Handle
useResizable
Segmented Control
Segmented Control
Segmented Control Item
Selector
Multi Selector
Selector
Selector Option
Skeleton
Slider
Spinner
Status Dot
Switch
Table
Table
Table Cell
Table Header Cell
Table Row
useTableColumnResize
useTableColumnSettings
useTableFiltering
useTableFilterState
useTablePagination
useTableSelection
useTableSelectionState
useTableSortable
useTableStickyColumns
Tabs
Tab
Tab List
Tab Menu
Text
Text Area
Text Input
Thumbnail
Time Input
Timestamp
Toast
Toast
useToast
Token
Tokenizer
Toolbar
Tooltip
Tooltip
useTooltip
Tree List
Typeahead
Base Typeahead
Typeahead
Typeahead Item
VisuallyHidden
Utilities
Layer Provider
Link Provider
Media Theme
Syntax Theme
Theme
useClickableContainer
useEntryAnimation
useFocusTrap
useGridFocus
useImageMode
useInputContainer
useLayer
useListFocus
useMediaQuery
useOverflow
useScrollLock
useScrollOverflow
useStreamingText
useTheme
useTreeFocus
DocsComponentsTemplatesThemesPlaygroundBlogCommunityChangelog
GitHub
Discord
Facebook
Instagram
Threads
X
Terms of usePrivacy policy
©2026 Meta Platforms, Inc.
useTreeFocus@astryxdesign/core v0.1.2 · useTreeFocus

Usage

Manages roving-tabindex focus and the WAI-ARIA tree keyboard model. ArrowUp/ArrowDown/Home/End roam linearly over the visible treeitems (skipping disabled ones), while ArrowRight/ArrowLeft carry tree semantics (expand/collapse, move to first-child/parent). Enter/Space activate, and printable characters trigger typeahead.

ts
import {useTreeFocus} from '@astryxdesign/core/hooks'

Best practices

GuidancePractices
Do

Use for hierarchical tree widgets: wire onToggleExpand to your expansion state and onActiveChange to a single roving tab stop.

Do

Attach both treeRef and handleKeyDown to the role="tree" container element.

Don't

Use for linear lists (prefer useListFocus) or 2D grids (prefer useGridFocus); those traversals differ from a tree.

Parameters

ParamTypeDescription
options
UseTreeFocusOptions

Configuration object for tree focus behavior.

options.itemSelector
string (default: '[role="treeitem"]')

Selector for visible treeitems within the tree, in DOM order.

options.isItemDisabled
(item: HTMLElement) => boolean

Predicate for whether a treeitem is disabled and must be skipped during navigation. Defaults to reading data-tree-disabled / aria-disabled.

options.getLevel
(item: HTMLElement) => number

Reads the 1-based nesting level of a treeitem. Defaults to the aria-level attribute.

options.onToggleExpand
(id: string) => void

Called to expand/collapse the treeitem with the given id (ArrowRight on a collapsed parent, ArrowLeft on an expanded parent, Enter/Space on a parent without its own action).

options.onActivate
(item: HTMLElement, id: string | undefined) => boolean | void

Called when Enter/Space activates a treeitem. Return true when handled; return false/undefined to let the hook fall back to toggling expansion.

options.onActiveChange
(id: string | undefined) => void

Notified when the hook moves focus to a treeitem. Consumers use this to move a single roving tab stop.

options.hasRovingTabIndex
boolean (default: false)

When true, the hook owns a single roving tab stop across the visible treeitems (stamps tabindex 0/-1, repairs on mount, moves with navigation). Preserves an existing tabindex="0" seed on mount. Attach the returned handleFocus to keep the stop in sync after clicks.

options.typeahead
boolean (default: true)

Whether typeahead (jump to next item whose text starts with the typed characters) is enabled.

Returns

FieldTypeDescription
treeRefReact.RefObject<HTMLElement | null>

Ref to attach to the tree container element (role="tree").

handleKeyDown(e: React.KeyboardEvent) => void

Key down handler to attach to the tree container.

handleFocus(e: React.FocusEvent) => void

Focus handler to attach to the container's onFocus. Keeps the roving tab stop in sync when hasRovingTabIndex is enabled; a no-op otherwise, so always safe to attach.

focusFirst() => void

Focus the first enabled visible treeitem.

focusLast() => void

Focus the last enabled visible treeitem.

useTreeFocus · Astryx