This release brings support for several long-awaited features, including support for expandable rows in Table, and window scrolling in Virtualizer. Expandable rows enable macOS Finder-like file trees by designating a treeColumn and rendering a chevron button within its cells. Window scrolling in Virtualizer enables virtualized collections to automatically scroll with the rest of the page. We've also added support for horizontally virtualized GridLists and ListBoxes! Finally, we significantly improved how we manage our dependencies – see below for details.
As always, many thanks to all of our contributors for all of your feedback, features, and fixes – special shout out to @nwidynski!
Dependency consolidation
React Aria Components now has 90% fewer dependencies! To accomplish this, we have consolidated all of our individual hook packages (e.g. @react-aria/button, @react-stately/table) into the react-aria and react-stately monopackages. Our packages now also support sub-path imports, e.g. react-aria-components/Button. This means easier upgrades with fewer dependencies to manage, simplified discovery of child components, faster builds, more effective tree shaking, and improved micro-frontend support.
Using sub-paths
In addition to the main package entry point, each component is now available under a sub-path. These sub-paths match the name of the main component, and include all child components used within it. For example, react-aria-components/Menu includes Menu, MenuItem, Popover, etc.
-import {Menu, MenuItem, Popover} from 'react-aria-components';
+import {Menu, MenuItem, Popover} from 'react-aria-components/Menu';
Benefits of using sub-paths include:
- Smaller bundles without relying on tree-shaking
- Faster builds and test runs (only need to parse code you use instead of the entire library)
- Improved discoverability of child components. TypeScript autocomplete shows you only the components typically used together.
Our documentation has been updated to show sub-paths by default, but you can continue using the main entry point if you prefer.
Migration
If you are currently using individual hook packages such as @react-aria/button, you can migrate to monopackage imports using our use-monopackages codemod. This will use the main package entry point (e.g. react-aria), not sub-paths.
npx @react-spectrum/codemods use-monopackages --path /path/to/src
If you would like to migrate to sub-path imports, run the use-subpaths codemod.
npx @react-spectrum/codemods use-subpaths --path /path/to/src
Backwards compatibility
We have worked hard to implement this change in a backward compatible way, but there are a few things to be aware of:
- Individual packages like
@react-aria/buttonstill work, but they now re-export from the monopackage (e.g.react-aria) instead of the other way around. You can continue using these packages, but new exports will not be added. Migrate to the mono-package using our codemod at your convenience. - We have gone out of our way to continue supporting old tools like webpack 4 and jest < 28, which don't support the package.json
exportsfield and the .mjs extension. We will drop support for these tools in a future major version. We recommend upgrading as soon as possible. - Due to a TypeScript issue, types that were intentionally not exported were still exposed. Using these is no longer possible. If you were using any of these types, please open an issue on GitHub.
- If you were relying on individual packages like
@react-aria/buttonbeing installed by the monopackage without declaring them in your own package.json, this will no longer occur. Please add them as dependencies or migrate to using the monopackage exports.
Changelog
General Changes
- Support CSP nonces on injected style elements - @costajohnt - PR, @LFDanLu - PR
- Fix global event attachment timing for
usePressanduseMove- @snowystinger - PR
Autocomplete
- Allow moving into an Autocomplete-wrapped two-dimensional grid with
ArrowLeftandArrowRight- @LFDanLu - PR - Fix Autocomplete focus styles when clicking the input after virtual focus - @hanityx - PR
Collections
- Support the full collection in SelectionManager for
selectedKeys="all"behavior - @reidbarber - PR - Fix focus restoration in collections when deleting items - @snowystinger - PR
ColorPicker
ColorWheel
- Prevent ColorWheel Loupe from getting stuck - @snowystinger - PR
ComboBox
- Add a generic type parameter to
useComboBoxStatefor theComboBoxStatereturn type - @reidbarber - PR - Use stable
selectedKeysin ComboBox to prevent an infinite loop - @reidbarber - PR - Accept
readonlyarrays for multiple-selection ComboBox values - @lixiaoyan - PR - Pass the selection mode generic through to ComboBox
validatetypes - @lixiaoyan - PR - Allow
nullinvalidatefor single selection - @lixiaoyan - PR - Prevent extra
onSelectionChangecalls - @reidbarber - PR - Fix required validation for multi-select ComboBox - @Nawaz-B-04 - PR
- Add
isReadOnlyrender props - @devongovett - PR
Date and Time
- Fix an SSR hydration mismatch from
Date.now-based private property keys - @reidbarber - PR
Dialog
Drag and Drop
- Prevent repeated
useDropenter and exit events for portal children in drag and drop - @reidbarber - PR
FocusScope
- Fix focus behavior for inputs inside FocusScope - @snowystinger - PR
Form
- Expose
elementTypeon FieldError to control the host element - @fellipeutaka - PR - Skip resetting form fields when the reset event is canceled - @nanto - PR
GridList
- Add an
orientationprop to GridList - @essandhu - PR, @LFDanLu - PR - Add
orientation="horizontal"support - @nwidynski - PR, PR
Listbox
- Add
orientation="horizontal"support - @nwidynski - PR, @LFDanLu - PR - Remove the macOS ARIA label workaround in Listbox
useOption- @cbodin - PR
Modal
- Prevent modal from reopening by settling canceled animation promises - @christophmeise - PR
- Prevent hover styles from sticking after closing a Modal with touch on Safari iOS 26 - @snowystinger - PR
- Expose
--page-widthand--visual-viewport-width- @lixiaoyan - PR - Use an attribute presence check for
data-react-aria-top-layerinMutationObserver- @lixiaoyan - PR
NumberField
- Add
isReadOnlyrender props - @devongovett - PR - Wrap
commit()influshSyncwhenEnteris pressed so the value flushes before form submit - @tariq-r - PR - Preserve validation errors on blur when the value doesn't change - @snowystinger - PR
- Fix various bugs in NumberParser - @snowystinger - PR
- Add
commitBehaviorto NumberField - @will-stone - PR
RangeCalendar
- Add
commitBehaviorto customize behavior when the pointer is released outside RangeCalendar - @Jiiieeef - PR, @LFDanLu - PR, PR
Select
- Add
shouldCloseOnSelectto Select - @acr92 - PR - Avoid an empty option in hidden Select markup - @sonsu-lee - PR
Table
- Add support for expandable rows - @devongovett - PR
- Fix keyboard drag and drop navigation in expandable rows - @LFDanLu - PR
- Honor minimum width set by the Table column menu - @LFDanLu - PR
- Prevent double focus rings in Table when clicking expand buttons - @LFDanLu - PR
- Use
min-widthso Firefox respects applied Table column widths - @LFDanLu - PR - Automatically focus newly added rows after a drop - @LFDanLu - PR
- Update keyboard navigation to improve navigation speed with expandable rows - @yihuiliao - PR
Tabs
- Default
shouldSelectOnPressUpto true in Tabs when an item is a link - @reidbarber - PR
TagGroup
- Apply hover state to TagGroup items with an
href- @essandhu - PR - Add
onActionprop - @onx2 - PR, @LFDanLu - PR
Tree
- Improve accessibility for TreeSection - @yihuiliao - PR
- Export
TreeEmptyStateRenderProps- @reidbarber - PR - Update keyboard navigation to improve navigation speed - @Sidnioulz - PR
- Update Tree drag and drop focus behavior - @chirokas - PR
- Fix inserting items into a child node with
useTreeDataunder React Strict Mode - @chirokas - PR
Virtualizer
- Automatically bind the Virtualizer visible rectangle to the window viewport - @devongovett - PR, PR
- Lay out Virtualizer items using a consistent size - @devongovett - PR
Released packages
- @internationalized/date@3.12.1
- @internationalized/message@3.1.9
- @internationalized/number@3.6.6
- @internationalized/string-compiler@3.4.0
- @internationalized/string@3.2.8
- @react-aria/actiongroup@3.8.0
- @react-aria/aria-modal-polyfill@3.8.0
- @react-aria/autocomplete@3.0.0-rc.7
- @react-aria/breadcrumbs@3.6.0
- @react-aria/button@3.15.0
- @react-aria/calendar@3.10.0
- @react-aria/checkbox@3.17.0
- @react-aria/collections@3.1.0
- @react-aria/color@3.2.0
- @react-aria/combobox@3.16.0
- @react-aria/datepicker@3.17.0
- @react-aria/dialog@3.6.0
- @react-aria/disclosure@3.2.0
- @react-aria/dnd@3.12.0
- @react-aria/example-theme@1.1.0
- @react-aria/focus@3.22.0
- @react-aria/form@3.2.0
- @react-aria/grid@3.15.0
- @react-aria/gridlist@3.15.0
- @react-aria/i18n@3.13.0
- @react-aria/interactions@3.28.0
- @react-aria/label@3.8.0
- @react-aria/landmark@3.1.0
- @react-aria/link@3.9.0
- @react-aria/listbox@3.16.0
- @react-aria/live-announcer@3.5.0
- @react-aria/menu@3.22.0
- @react-aria/meter@3.5.0
- @react-aria/numberfield@3.13.0
- @react-aria/overlays@3.32.0
- @react-aria/progress@3.5.0
- @react-aria/radio@3.13.0
- @react-aria/searchfield@3.9.0
- @react-aria/select@3.18.0
- @react-aria/selection@3.28.0
- @react-aria/separator@3.5.0
- @react-aria/slider@3.9.0
- @react-aria/spinbutton@3.8.0
- @react-aria/ssr@3.10.0
- @react-aria/steplist@3.0.0-alpha.26
- @react-aria/switch@3.8.0
- @react-aria/table@3.18.0
- @react-aria/tabs@3.12.0
- @react-aria/tag@3.9.0
- @react-aria/test-utils@1.0.0-beta.3
- @react-aria/textfield@3.19.0
- @react-aria/toast@3.1.0
- @react-aria/toggle@3.13.0
- @react-aria/toolbar@3.0.0-beta.25
- @react-aria/tooltip@3.10.0
- @react-aria/tree@3.2.0
- @react-aria/utils@3.34.0
- @react-aria/virtualizer@4.2.0
- @react-aria/visually-hidden@3.9.0
- @react-stately/autocomplete@3.0.0-beta.5
- @react-stately/calendar@3.10.0
- @react-stately/checkbox@3.8.0
- @react-stately/collections@3.13.0
- @react-stately/color@3.10.0
- @react-stately/combobox@3.14.0
- @react-stately/data@3.16.0
- @react-stately/datepicker@3.17.0
- @react-stately/disclosure@3.1.0
- @react-stately/dnd@3.8.0
- @react-stately/flags@3.2.0
- @react-stately/form@3.3.0
- @react-stately/grid@3.12.0
- @react-stately/layout@4.7.0
- @react-stately/list@3.14.0
- @react-stately/menu@3.10.0
- @react-stately/numberfield@3.12.0
- @react-stately/overlays@3.7.0
- @react-stately/radio@3.12.0
- @react-stately/searchfield@3.6.0
- @react-stately/select@3.10.0
- @react-stately/selection@3.21.0
- @react-stately/slider@3.8.0
- @react-stately/steplist@3.0.0-alpha.22
- @react-stately/table@3.16.0
- @react-stately/tabs@3.9.0
- @react-stately/toast@3.2.0
- @react-stately/toggle@3.10.0
- @react-stately/tooltip@3.6.0
- @react-stately/tree@3.10.0
- @react-stately/utils@3.12.0
- @react-stately/virtualizer@4.5.0
- @react-types/actionbar@3.2.0
- @react-types/actiongroup@3.5.0
- @react-types/autocomplete@3.0.0-alpha.39
- @react-types/avatar@3.1.0
- @react-types/badge@3.2.0
- @react-types/breadcrumbs@3.8.0
- @react-types/button@3.16.0
- @react-types/buttongroup@3.4.0
- @react-types/calendar@3.9.0
- @react-types/card@3.0.0-alpha.44
- @react-types/checkbox@3.11.0
- @react-types/color@3.2.0
- @react-types/combobox@3.15.0
- @react-types/contextualhelp@3.3.0
- @react-types/datepicker@3.14.0
- @react-types/dialog@3.6.0
- @react-types/divider@3.4.0
- @react-types/form@3.8.0
- @react-types/grid@3.4.0
- @react-types/illustratedmessage@3.4.0
- @react-types/image@3.6.0
- @react-types/label@3.10.0
- @react-types/layout@3.4.0
- @react-types/link@3.7.0
- @react-types/list@3.3.0
- @react-types/listbox@3.8.0
- @react-types/menu@3.11.0
- @react-types/meter@3.5.0
- @react-types/numberfield@3.9.0
- @react-types/overlays@3.10.0
- @react-types/progress@3.6.0
- @react-types/provider@3.9.0
- @react-types/radio@3.10.0
- @react-types/searchfield@3.7.0
- @react-types/select@3.13.0
- @react-types/shared@3.34.0
- @react-types/slider@3.9.0
- @react-types/statuslight@3.4.0
- @react-types/switch@3.6.0
- @react-types/table@3.14.0
- @react-types/tabs@3.4.0
- @react-types/text@3.4.0
- @react-types/textfield@3.13.0
- @react-types/tooltip@3.6.0
- @react-types/view@3.5.0
- @react-types/well@3.4.0
- @spectrum-icons/color@3.6.0
- @spectrum-icons/express@3.0.0-alpha.34
- @spectrum-icons/illustrations@3.7.0
- @spectrum-icons/ui@3.7.0
- @spectrum-icons/workflow@4.3.0
- @react-aria/optimize-locales-plugin@1.2.0
- @react-aria/parcel-resolver-optimize-locales@1.3.0
- @react-aria/mcp@1.1.0
- react-aria@3.48.0
- react-aria-components@1.17.0
- react-stately@3.46.0
- tailwindcss-react-aria-components@2.1.0