Skip to content

feat(Treeview): add new component#144

Open
johnleider wants to merge 16 commits intomasterfrom
feat/treeview
Open

feat(Treeview): add new component#144
johnleider wants to merge 16 commits intomasterfrom
feat/treeview

Conversation

@johnleider
Copy link
Member

Summary

  • Adds a headless compound Treeview component built on createNested composable
  • 10 sub-components: Root, List, Item, Activator, Content, Cue, Checkbox, Indicator, Group, SelectAll
  • Full WAI-ARIA treeview pattern with keyboard support
  • Cascade, independent, and leaf selection modes
  • Tri-state checkbox with mixed/indeterminate states
  • Documentation page with settings panel and cascade selection examples
  • API reference with JSDoc descriptions and @example snippets for all props
  • Fixed generate-api.ts to extract props and examples from external types.ts files via ts-morph fallback

Sub-components

Component Purpose
Treeview.Root Provides nested context, selection mode, open strategy
Treeview.List Wrapper with role="tree" and aria-multiselectable
Treeview.Item Registers as tree node, provides item context
Treeview.Activator Toggle button for expand/collapse
Treeview.Content Collapsible children container
Treeview.Cue Visual expand/collapse indicator (chevron)
Treeview.Checkbox Tri-state selection checkbox
Treeview.Indicator Visual selection state indicator
Treeview.Group Semantic role="group" wrapper
Treeview.SelectAll Tree-wide select/unselect toggle

Test plan

  • 1267 lines of component tests (54 tests)
  • 114 composable tests for createNested
  • Full suite: 3065 tests passing
  • Typecheck clean
  • Lint clean
  • knip + sherif clean
  • Manual: verify docs page renders at /components/disclosure/treeview
  • Manual: verify API reference shows descriptions and code examples

johnleider and others added 8 commits March 1, 2026 20:36
Headless treeview with 9 sub-components: Root, List, Item, Activator,
Content, Cue, Group, Checkbox, Indicator. Built on createNested for
tree state management with selection, open/close, and activation.

Exposes --v0-treeview-depth CSS custom property on each item for
consumer-driven indentation. Cue self-hides on leaf nodes via
hasContent signal from Content. Indicator follows existing
CheckboxIndicator pattern with data-state visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gister

Ticket select/unselect/toggle were pointing to createGroup's
non-cascade versions. Override them after group.register() so
TreeviewCheckbox clicks propagate to descendants and update
ancestor mixed states.
Settings panel demonstrates activation, functional toggles/selects,
disabled categories, depth indentation via CSS variable, and recursive
rendering. Removes file-explorer and selection live examples.
…rops

Also fix generate-api.ts to extract @example tags in the ts-morph
fallback path used by components with external types files.
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 4, 2026

Open in StackBlitz

commit: 8f6fc54

@johnleider johnleider changed the title feat(Treeview): add compound treeview component feat(Treeview): add new component Mar 5, 2026
Create reusable useRovingFocus composable for roving tabindex pattern
with linear and grid navigation modes. Wire into Treeview for full
WAI-ARIA tree keyboard nav: arrows, Home/End, Enter, Space, *.

- useRovingFocus: manages focusedId, isTabbable, step with disabled
  skip, optional circular nav, orientation + grid (columns) support
- createNested: add el to NestedTicket, add visibleItems() for
  depth-first traversal of open nodes
- TreeviewList: creates roving focus, handles all tree keyboard
  mappings including ArrowRight/Left for expand/collapse/parent
- TreeviewItem: captures el ref, consumes roving for tabindex
- TreeviewActivator/Checkbox: remove independent tabindex (now -1),
  keyboard handling moved to tree container level
Add renderless Treeview.Checkbox with cascade selection to the basic
example. Demonstrates keyboard Space to toggle selection alongside
arrow key navigation and Enter to expand/collapse.
…sable

- Enter key activates focused node (leaf nodes now keyboard-reachable)
- Space key no-op in single-select mode per WAI-ARIA spec
- SelectAll onClick/onKeydown in attrs for renderless mode support
- revealOnOpen runs after open strategy to fix single+reveal combo
- Remove String(ticket.id) coercion; use ID type throughout
- unselectAll with mandatory recalculates ancestor mixed states
- Move TreeviewRoot imports to regular script (dual-script convention)
- disabled prop typed as MaybeRefOrGetter for consistency
- siblings() uses rootIds set for root nodes
- Fix duplicate describe names in createNested tests
@johnleider johnleider force-pushed the master branch 5 times, most recently from a6133f0 to eb8ed41 Compare March 17, 2026 02:24
Resolve useRovingFocus conflict by taking master's RTL support.
ArrowRight/ArrowLeft tree semantics (open/close, focus parent/child)
now swap in RTL layouts, matching the useRovingFocus RTL support
added in master.
- Space key toggles selection in single-select mode per WAI-ARIA spec
- Unwrap NestedContext.multiple with toValue to match boolean type
- Use isNullOrUndefined type guard in TreeviewList keyboard handler
- Fix orphaned JSDoc on NestedActiveMode (belongs on NestedOptions)
- Remove stale comment headers in createNested
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant