Skip to content

fix(listbox): support disabling entire listboxes - #10619

Open
dvd233 wants to merge 3 commits into
adobe:mainfrom
dvd233:codex/fix/listbox-disabled-state-5837
Open

dvd233 wants to merge 3 commits into
adobe:mainfrom
dvd233:codex/fix/listbox-disabled-state-5837

Conversation

@dvd233

@dvd233 dvd233 commented Sep 21, 2026

Copy link
Copy Markdown

Closes #5837

Summary

Add a top-level isDisabled prop to ListBox. The prop is applied in the shared list state so every item key is treated as disabled by the existing selection, focus, and interaction machinery. The listbox also exposes aria-disabled="true", and a Storybook example demonstrates the disabled state.

This lets applications disable a ListBox without enumerating all of its items in disabledKeys, including dynamically loaded collections.

✅ 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 (the existing ListBox documentation does not yet describe this new prop).
  • Looked at the Accessibility Practices for this feature - ARIA Practices.
  • 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 CLAUDE.md.

📝 Test Instructions:

Focused tests:

  • yarn test packages/@adobe/react-spectrum/test/listbox/ListBox.test.js --runInBand
  • yarn test packages/react-aria-components/test/ListBox.test.js --runInBand
  • yarn test:ssr packages/@adobe/react-spectrum/test/listbox/ListBox.ssr.test.js packages/react-aria-components/test/ListBox.ssr.test.js --runInBand
  • yarn check-types
  • yarn oxlint packages/react-stately/src/list/useListState.ts packages/react-aria/src/listbox/useListBox.ts packages/react-aria-components/test/ListBox.test.js packages/@adobe/react-spectrum/test/listbox/ListBox.test.js
  • yarn oxfmt --check packages/react-stately/src/list/useListState.ts packages/react-aria/src/listbox/useListBox.ts packages/react-aria-components/test/ListBox.test.js packages/@adobe/react-spectrum/test/listbox/ListBox.test.js packages/@adobe/react-spectrum/stories/listbox/ListBox.stories.tsx

The focused ListBox suites passed (43/43 and 105 passed, 1 skipped); the focused SSR suites passed (2 suites, 3 tests); and the full SSR suite passed (60 suites, 74 tests). The full Jest run passed 7,998 tests across 373 suites; four unrelated suites remain environment/baseline failures: empty locale fixtures in NumberField/NumberParser, Windows temp-directory permission/timeout in a codemod CLI test, and Windows path-separator expectations in LocalesResolver.

🧢 Your Project:

dvd233

AI assistance was used to inspect the issue, prepare the implementation, and run verification. I reviewed the final diff and verified the behavior and test results.

@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.

Hi, thanks for the PR. You have two other open PRs with waiting comments. Please revisit those before opening anymore.

: {},
{
role: 'listbox',
'aria-disabled': props.isDisabled || undefined,

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 don't think aria-disabled should be be applied for disabledBehavior: 'selection'
I think we've forgotten to include it in the props for ListBox, but it's used in RAC ListBox.

selectionManager: state.selectionManager,
collection: state.collection,
disabledKeys: state.disabledKeys,
disabledKeys: props.isDisabled ? new Set(state.collection.getKeys()) : state.disabledKeys,

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 love this extra full collection iteration, at the very least we should memo it.

otherwise, we'll want to consider expanding the api to "all" or a new isDisabled prop meaning the entire selectable list. That may end up adding the new partial behaviour to every selectable list though, so would need to be careful with that.

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.

Disable entire ListBox without needing to set disabledKeys

2 participants