Skip to content

feat: support description text in tree items - #10710

Open
minwookshin wants to merge 4 commits into
adobe:mainfrom
minwookshin:feat-tree-description-slot-10665
Open

minwookshin wants to merge 4 commits into
adobe:mainfrom
minwookshin:feat-tree-description-slot-10665

Conversation

@minwookshin

@minwookshin minwookshin commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Closes #10665

Tree items need a description slot that follows the existing GridList accessibility behavior. Text slot="description" now uses the inherited aria-labelledby relationship, so the row name includes its description. The Tree-specific override is removed, and the shared slot ID refreshes when collection content changes so removed descriptions do not leave dangling references.

Implemented with OpenAI Codex.

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change.
  • Filled out test instructions.
  • Updated documentation.
  • Looked at the Accessibility Practices for this feature — treegrid naming and descriptions.
  • I understand every change in this PR and can explain why it's there.
  • If AI-assisted, I followed the AI contribution guidance and pointed my assistant at AGENTS.md.

📝 Test Instructions:

Open React Aria Components → Tree → With Descriptions. The parent row should be named “Projects Shared project files”; expanding it reveals “Report Last updated today”. Check keyboard selection, expansion/collapse and pointer activation. Regressions also cover explicit labels, custom description IDs, and removing/reinserting description content.

Full yarn test passed (8,442 tests). The first SSR run had a local ECONNRESET in useViewportSize; a second full yarn test:ssr run passed all 74 tests without code changes. The runtime code is unchanged by this follow-up; the October 13 serial browser run passed (423 tests, 63 skipped). Formatting, type checking, lint, package checks and constraints passed. The first full browser run had a Firefox TokenField selection failure and a WebKit DateRangePicker failure; both passed individually on the original and modified code, and the full serial run then passed without further code changes.

The story passed keyboard/pointer checks in Chromium, Firefox and WebKit with English/light/wide and Arabic/dark/narrow layouts. Chromium's accessibility tree and native Safari both expose the combined row name. VoiceOver speech remains unverified because the local caption-window inspection timed out; its settings were restored. Touch and high-contrast mode were not checked.

Storybook used the standard Parcel server with a local Unix-socket path-length workaround. Neither the workaround nor test fixtures change repository files.

🧢 Your Project:

Open-source contribution.

Developed and tested with assistance from OpenAI Codex.
@minwookshin
minwookshin marked this pull request as ready for review October 4, 2026 02:07

@snowystinger snowystinger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #10665 you asked

Would you prefer aria-describedby here, rather than GridList's combined aria-labelledby behavior?

Did you test both with various combinations of screen readers/OS/browser? If so, do you have the data that informed your decision?

@minwookshin

Copy link
Copy Markdown
Contributor Author

I checked the browser accessibility tree, but I haven't compared both approaches with screen readers yet.

@devongovett

Copy link
Copy Markdown
Member

Let's match how useGridListItem works and concatenate the description as part of aria-labelledby. Looks like we originally tried aria-describedby in #3121 but switched to labelledby because it announced better.

// TODO: should it return a state specifically for isExpanded? Or is aria attribute sufficient?
return {
...gridListAria,
rowProps: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you don't need this override. We can just inherit the behavior from useGridListItem?

Comment thread packages/dev/s2-docs/pages/react-aria/Tree.mdx Outdated
Comment thread packages/react-aria-components/test/Tree.test.tsx Outdated
Comment thread packages/react-aria-components/test/Tree.test.tsx Outdated
Comment thread packages/react-aria-components/test/Tree.test.tsx Outdated
Comment thread packages/react-aria-components/test/Tree.test.tsx Outdated
Comment thread packages/react-aria-components/test/Tree.test.tsx Outdated
Comment thread packages/react-aria-components/test/Tree.test.tsx Outdated
let {onAction, linkBehavior, keyboardNavigationBehavior, shouldSelectOnPressUp} =
listMap.get(state)!;
let descriptionId = useSlotId();
let descriptionId = useSlotId([node]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is related to this test?:
updates the description relationship when the slot is removed and added

If so, was this an existing bug in GridList? and can you add a test specifically for GridList. It can be basically the same as the Tree one. That way we can verify before and after

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would node.key (or id? i'm going off memory for this comment) be better?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget to answer in comment thread

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, GridList had the same stale aria-labelledby reference; the new test covers removing and re-adding a description with an explicit ID. node.key still fails because the item's key stays the same when the description changes.

Comment thread packages/dev/s2-docs/pages/react-aria/Tree.mdx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TreeItem has no description slot

3 participants