-
#2820
Added missingaria-haspopup
attribute toDialogDisclosure
andPopoverDisclosure
. -
#2858
Fixed thesetValueOnMove
state on the Select module not syncing between multiple stores.The following now works as expected:
const store1 = useSelectStore(); const store2 = useSelectStore({ store: store1, setValueOnMove: true }); store1.useState("setValueOnMove") === store2.useState("setValueOnMove"); // true
-
#2862
Elements inside Dialog and derived components are now properly disabled when the dialog is animating out. -
#2862
Fixed a bug that occurred when rendering nested Dialog elements with a third-party dialog interspersed.Previously, Ariakit didn't recognize the third-party dialog as a nested dialog when the lowest dialog opened.
-
#2862
ThehideOnEscape
prop is now triggered during the capture phase.Essentially, this means that you can now prevent the propagation of the Escape keydown event to other elements in the DOM when it's used to close an Ariakit Dialog:
<Dialog hideOnEscape={(event) => { event.stopPropagation(); return true; }} />
-
#2862
Fixed an issue where the Dialog component would automatically hide when parent dialogs closed.You can now render nested dialogs in the React tree and keep them open independently, provided they're not unmounted.
-
#2862
Fixed the Focusable and its derived components that were incorrectly calling theonFocusVisible
callback prop when the element had lost focus.This didn't align with the behavior of the
data-focus-visible
attribute. The behavior now mirrors the attribute, which will only be omitted from the element ifevent.preventDefault()
is invoked from within theonFocusVisible
callback. -
#2862
Themodal
prop is now automatically disabled on nestedMenu
components. -
#2869
Fixed uncaughtmsg.startsWith
error. -
Improved JSDocs.
-
Updated dependencies:
@ariakit/react-core@0.3.3
.
-
#2811
TypeScript: Fixed missingnull
type on props fromuseMenuStore
(combobox
,parent
,menubar
), anduseSelectStore
(combobox
). -
#2812
Fixed an infinite loop issue when usingMenuButton
with astore
that is synchronized with another store. -
Improved JSDocs.
-
Updated dependencies:
@ariakit/react-core@0.3.2
.
-
#2804
New in this version: Component providersComponent providers are optional components that act as a higher-level API on top of component stores. They wrap Ariakit components and automatically provide a store to them.
-
#2797
Fixed a regression onDialog
regarding the timing of its "focus on hide" behavior. -
#2801
Fixedvalues.slice
error that would occur when clicking onFormCheckbox
that uses an integer-like field name. -
#2802
AddedsetMounted
prop touseDisclosureStore
and derived component stores. This callback prop can be used to react to changes in themounted
state. For example:useDialogStore({ setMounted(mounted) { if (!mounted) { props.onUnmount?.(); } }, });
-
#2803
TheToolbar
component can now render without needing an explicitstore
prop or aToolbarProvider
component wrap.Toolbar
now also supports certain store props such asfocusLoop
,orientation
,rtl
, andvirtualFocus
. -
Updated dependencies:
@ariakit/react-core@0.3.1
.
-
#2714
Added support for a dynamicstore
prop on component stores.This is similar to the
store
prop on components, keeping both stores in sync. Now, component store hooks can support modifying the value of thestore
prop after the initial render. For instance:// props.store can change between renders now const checkbox = useCheckboxStore({ store: props.store });
When the
store
prop changes, the object returned from the store hook will update as well. Consequently, effects and hooks that rely on the store will re-run.While it's unlikely, this could represent a breaking change if you're depending on the
store
prop in component stores to only acknowledge the first value passed to it. -
#2783
BREAKING (This should affect very few people): Thecombobox
state onuseSelectStore
has been replaced by thecombobox
property on the store object.Before:
const combobox = useComboboxStore(); const select = useSelectStore({ combobox }); const hasCombobox = select.useState("combobox");
After:
const combobox = useComboboxStore(); const select = useSelectStore({ combobox }); const hasCombobox = Boolean(select.combobox);
In the example above,
select.combobox
is literally the same as thecombobox
store. It will be defined if thecombobox
store is passed touseSelectStore
. -
#2783
BREAKING (This should affect very few people): Theselect
andmenu
props onuseComboboxStore
have been removed. If you need to composeCombobox
withSelect
orMenu
, use thecombobox
prop onuseSelectStore
oruseMenuStore
instead. -
#2717
Thechildren
prop as a function has been deprecated on all components. Use therender
prop instead. -
#2717
Theas
prop has been deprecated on all components. Use therender
prop instead. -
#2717
ThebackdropProps
prop has been deprecated onDialog
and derived components. Use thebackdrop
prop instead. -
#2745
Component stores will now throw an error if they receive another store prop in conjunction with default prop values.
-
#2737
Fixed controlled component stores rendering with a stale state. -
#2783
Component store objects now contain properties for the composed stores passed to them as props. For instance,useSelectStore({ combobox })
will return acombobox
property if thecombobox
prop is specified. -
#2785
Addedparent
andmenubar
properties to the menu store. These properties are automatically set when rendering nested menus or menus within a menubar.Now, it also supports rendering nested menus that aren't nested in the React tree. In this case, you would have to supply the parent menu store manually to the child menu store.
These properties are also included in the returned menu store object, allowing you to verify whether the menu is nested. For instance:
const menu = useMenuStore(props); const isNested = Boolean(menu.parent);
-
#2795
Updated theMenu
component so thecomposite
andtypeahead
props are automatically set tofalse
when combining it with aCombobox
component.This means you'll not need to explicitly pass
composite={false}
when building a Menu with Combobox component. -
#2796
Composed store props such asuseSelectStore({ combobox })
now acceptnull
as a value. -
Updated dependencies:
@ariakit/react-core@0.3.0
.
-
#2718
Fixed import ofuse-sync-external-store
package for ESM builds. -
Updated dependencies:
@ariakit/react-core@0.2.17
.
-
Fixed
Collection
not populating theitems
state when passingitems
andsetItems
touseCollectionStore
. (#2704) -
Fixed
Combobox
controlled derived state. (#2705) -
The
Menu
'sdisclosureElement
state is now guaranteed to be defined as theMenuButton
element. Before, it could be overridden by a different element that received focus right before the menu opened, which could cause some weird issues. (#2695) -
Fixed
Tooltip
not closing when it's open while another popover is still visible. (#2692) -
Updated dependencies:
@ariakit/react-core@0.2.16
.
-
Fixed clicking on a custom dialog backdrop hiding all parent dialogs. (#2688)
-
Fixed
ReactDOM.flushSync
warning on low-end devices. (#2677) -
Fixed
Tooltip
not hiding when opening a dialog that was previously unmounted. (#2691) -
Fixed
Focusable
not triggeringonFocusVisible
(and thus not rendering thedata-focus-visible
attribute) when an element is focused after closing a dialog. (#2691) -
Fixed
Tooltip
showing on mouse move right after it was dismissed (by pressing Esc or opening a popover, for example). (#2691) -
Updated dependencies:
@ariakit/react-core@0.2.15
.
-
Fixed
flushSync
warning. (#2672) -
Updated dependencies:
@ariakit/react-core@0.2.14
.
-
The
as
prop has been soft deprecated. Use therender
prop instead. (#2621) -
The
Combobox
component now properly disables theautoSelect
behavior when the user is scrolling through the list of options. This should prevent issues when scrolling virtualized or infinite lists. (#2617) -
Fixed
Combobox
withautoSelect
always focusing on the first item when a virtualized list is scrolled using arrow keys. (#2636) -
Controlled store updates are now flushed synchronously. This should prevent issues when controlling a
Combobox
by passingvalue
andsetValue
to the combobox store, for example. (#2671) -
Updated dependencies:
@ariakit/react-core@0.2.13
.
-
Fixed
CompositeItem
not being tabbable before hydration. (#2601) -
Updated dependencies:
@ariakit/react-core@0.2.12
.
-
Fixed
Combobox
withautoSelect
andautoComplete="both"
so the value is maintained when the combobox input loses focus. (#2595) -
Fixed
Combobox
withautoSelect
prop causing a scroll jump when the popover was opened by typing on the input. (#2599) -
Fixed
Combobox
with theautoSelect
prop not automatically selecting the first option when used in combination withSelect
after the selected option is re-mounted. (#2592) -
Updated composite item components with the
focusOnHover
prop set totrue
so that they don't scroll into view when hovered. (#2590) -
Fixed
Menu
initial focus when used in combination withCombobox
. (#2582) -
Fixed
Popover
not updating its position when the placement changes while the popover is closed. (#2587) -
Fixed
Select
not scrolling selected option into view in Safari. (#2591) -
Updated dependencies:
@ariakit/react-core@0.2.11
.
-
Fixed
defaultItems
passed to the collection store being overriden when new items are added. (#2559) -
Fixed
Combobox
with theautoSelect
prop not allowing the user to scroll when the list of items is virtualized. (#2562) -
Fixed
Composite
not moving focus to items by pressing the arrow keys when the active item isn't rendered. (#2561) -
Fixed
CompositeItem
not being tabbable before hydration. (#2565) -
Updated dependencies:
@ariakit/react-core@0.2.10
.
-
Added new
disclosure
prop to theDisclosure
store. (#2518) -
Fixed
Focusable
not receiving focus when rendered as a native button on Safari. (#2534) -
Fixed
Dialog
withpreventBodyScroll
set totrue
(default) not preventing body scroll on nested animated dialogs. (#2534) -
Updated dependencies:
@ariakit/react-core@0.2.9
.
-
The
render
prop now supports aReactElement
as a value. See the Composition guide for more information. (#2486) -
Updated dependencies:
@ariakit/react-core@0.2.8
.
-
Fixed deeply nested
Dialog
not removing theinert
attribute from elements outside when closed. (#2507) -
Updated dependencies:
@ariakit/react-core@0.2.7
.
-
Added missing
types
field to proxy package.json files. (#2489) -
Updated dependencies:
@ariakit/react-core@0.2.6
.
-
Added
.cjs
and.js
extensions to paths in proxy package.json files to support bundlers that can't automaically resolve them. (#2487) -
Updated dependencies:
@ariakit/react-core@0.2.5
.
-
The
Checkbox
component now acceptsstring[]
as thevalue
prop. This is to conform with the native input prop type. If a string array is passed, it will be stringified, just like in the native input element. (#2456) -
Fixed the
clickOnEnter
prop onCheckbox
not working when rendering the component as a native input element. (#2456) -
Fixed typeahead behavior when the composite item element's text content starts with an empty space. (#2475)
-
Removed the delay before focusing on the final focus element when a dialog is closed. (#2462)
-
Fixed
Dialog
wrongly focusing on the final focus element when a dialog is closed by clicking on another dialog. (#2462) -
Fixed
Disclosure
timing to set thedisclosureElement
state on the disclosure store. (#2462) -
Removed the
hideOnControl
prop fromHovercard
. (#2478) -
Fixed clicking outside a
Dialog
when there's an ancestor element between the dialog content element and the portal element. (#2482) -
Fixed
Popover
with theupdatePosition
prop not moving focus into the popover when it opens. (#2482) -
Updated the
updatePosition
prop type onPopover
to allow for returning aPromise
. (#2482) -
Updated dependencies:
@ariakit/react-core@0.2.4
.
-
Updated the
SelectPopover
component so thecomposite
andtypeahead
props are automatically set tofalse
when combining it with aCombobox
component using thecombobox
prop from the select store. (#2428)This means you'll not need to explicitly pass
composite={false}
when building a Select with Combobox component. -
The
ComboboxItem
component will now register itself on the combobox store even when the combobox is closed. (#2428) -
Fixed
Combobox
withvirtualFocus
set totrue
(default) always reseting the focus when using VoiceOver and Safari to navigate through the items. (#2428) -
Fixed
autoComplete
prop type onCombobox
conflicting with the nativeautoComplete
prop. (#2428)It's now possible to extend props from
InputHTMLAttributes
without having toOmit
theautoComplete
prop. -
The
SelectList
andSelectPopover
components will now automatically render thearia-multiselectable
attribute even when thecomposite
prop is set tofalse
, but only when the underlying element has a composite role. (#2428) -
Fixed
Composite
rendering thearia-activedescendant
attribute even when thecomposite
prop was set tofalse
. (#2428) -
Fixed
Focusable
triggering focus visible when pressing the Alt/Option key. (#2428) -
Fixed
activeId
state onTab
not updating correctly when settingselectedId
with the Next.js App Router. (#2443) -
Updated dependencies:
@ariakit/react-core@0.2.3
.
-
Added
alwaysVisible
prop toDisclosureContent
and derived components to allow the content to be visible even when theopen
state isfalse
. (#2438) -
Fixed
useHovercardStore
anduseTooltipStore
not updating the state when thetimeout
,showTimeout
orhideTimeout
props changed. (#2421) -
Fixed
useTooltipStore
not updating the state when thetype
orskipTimeout
props changed. (#2421) -
Fixed
Dialog
moving focus on show and hide too early. (#2421) -
Fixed
Hovercard
andTooltip
hiding too early when pressing theEscape
key. (#2421) -
Removed unnecessary
tabIndex={0}
prop fromTooltipAnchor
. (#2421) -
Updated dependencies:
@ariakit/react-core@0.2.2
.
-
Added a
render
prop to all components as a more flexible alternative tochildren
as a function. (#2411) -
Updated dependencies:
@ariakit/react-core@0.2.1
.
-
BREAKING: Moved props from the
usePopoverStore
hook to thePopover
component:fixed
,gutter
,shift
,flip
,slide
,overlap
,sameWidth
,fitViewport
,arrowPadding
,overflowPadding
,getAnchorRect
,renderCallback
(renamed toupdatePosition
). (#2279)The exception is the
placement
prop that should still be passed to the store.Before:
const popover = usePopoverStore({ placement: "bottom", fixed: true, gutter: 8, shift: 8, flip: true, slide: true, overlap: true, sameWidth: true, fitViewport: true, arrowPadding: 8, overflowPadding: 8, getAnchorRect: (anchor) => anchor?.getBoundingClientRect(), renderCallback: (props) => props.defaultRenderCallback(), }); <Popover store={popover} />;
After:
const popover = usePopoverStore({ placement: "bottom" }); <Popover store={popover} fixed gutter={8} shift={8} flip slide overlap sameWidth fitViewport arrowPadding={8} overflowPadding={8} getAnchorRect={(anchor) => anchor?.getBoundingClientRect()} updatePosition={(props) => props.updatePosition()} />;
This change affects all the hooks and components that use
usePopoverStore
andPopover
underneath:useComboboxStore
,ComboboxPopover
,useHovercardStore
,Hovercard
,useMenuStore
,Menu
,useSelectStore
,SelectPopover
,useTooltipStore
,Tooltip
.With this change, the underlying
@floating-ui/dom
dependency has been also moved to thePopover
component, which means it can be lazy loaded. See the Lazy Popover example. -
BREAKING: The backdrop element on the
Dialog
component is now rendered as a sibling rather than as a parent of the dialog. This should make it easier to animate them separately. (#2407)This might be a breaking change if you're relying on their parent/child relationship for styling purposes (for example, to position the dialog in the center of the backdrop). If that's the case, you can apply the following styles to the dialog to achieve the same effect:
.dialog { position: fixed; inset: 1rem; margin: auto; height: fit-content; max-height: calc(100vh - 2 * 1rem); }
These styles work even if the dialog is a child of the backdrop, so you can use them regardless of whether you're upgrading to this version or not.
-
Deprecated the
backdropProps
prop on theDialog
component. Use thebackdrop
prop instead. (#2407) -
The
backdrop
prop on theDialog
component now accepts a JSX element as its value. (#2407) -
The
Dialog
component will now wait for being unmounted before restoring the body scroll when thehidden
prop is set tofalse
. This should prevent the body scroll from being restored too early when the dialog is being animated out using third-party libraries like Framer Motion. (#2407) -
The
Tooltip
component now defaults to usearia-describedby
instead ofaria-labelledby
. (#2279)If you want to use the tooltip as a label for an anchor element, you can use the
type
prop onuseTooltipStore
:useTooltipStore({ type: "label" });
-
The
Tooltip
component now supports mouse events. (#2279)It's now possible to hover over the tooltip without it disappearing, which makes it compliant with WCAG 1.4.13.
-
Fixed infinite loop on
Portal
with thepreserveTabOrder
prop set totrue
when the portalled element is placed right after its original position in the React tree. (#2279) -
Updated dependencies:
@ariakit/react-core@0.2.0
.
-
Fixed
DialogBackdrop
not including thedata-backdrop
attribute in the initial render, causing a flash of unstyled content when the dialog is initially open. (#2369) -
Fixed
Dialog
callinghideOnInteractOutside
twice when clicking on the backdrop. (#2369) -
The built-in
DialogBackdrop
component is no longer focusable. (#2369) -
Call
autoFocusOnHide
andautoFocusOnShow
with anull
argument when there's no element to focus or the element is not focusable. This allows users to specify a fallback element to focus on hide or show. (#2369) -
Updated dependencies:
@ariakit/react-core@0.1.8
.
-
Fixed
Menu
focusing on the first menu item rather than the menu container when opened with a mouse click. (#2339) -
Added
getPersistentElements
prop toDialog
to better support third-party elements that are already in the DOM by the time the dialog is opened. (#2339) -
Added support on
Dialog
for nested/parallel dialogs, such as portalled dialogs created by third-party libraries and extensions. (#2339) -
Fixed nested
Dialog
closing when dragging from the nested dialog to the parent dialog. (#2339) -
Fixed build target. (#2355)
-
Updated JSDocs.
-
Updated dependencies:
@ariakit/react-core@0.1.7
,@ariakit/core@0.1.5
.
-
Fixed
Select
component causing a scroll jump when it's dynamically rendered in a portal. (#2322) -
Fixed a bug where passing controlled props to a component store wouldn't always call the state setter with an updated value. (#2328)
-
Fixed
Menu
not respectinghidden={false}
. (#2328) -
Updated JSDocs.
-
Updated dependencies:
@ariakit/react-core@0.1.6
,@ariakit/core@0.1.4
.
-
Fixed
FormRadio
error when not explicitly providing the composite store. (#2313) -
Fixed invariant error messages on
Menu
components. (#2318) -
Updated validate and submit callbacks on
Form
so they always run in a consistent order. (#2319) -
Fixed nested
Dialog
components when they are conditionally mounted. (#2310) -
Updated dependencies:
@ariakit/react-core@0.1.5
,@ariakit/core@0.1.3
.
-
Added support for the
inert
attribute on theDialog
component. If the browser supportsinert
, modal dialogs will now use it rather than focus trap regions. (#2301) -
Fixed nested modal
Dialog
also closing the parent dialog when clicking outside. (#2300) -
Fixed modal
Dialog
eventually losing focus todocument.body
. (#2300) -
Fixed
Combobox
withautoSelect
andautoComplete
set toboth
orinline
where the completion string would lose its selected state. (#2308) -
Fixed
Combobox
not processing composition text (like chinese characters or accents). (#2308) -
Updated dependencies:
@ariakit/react-core@0.1.4
.
-
Fixed
Dialog
not returning focus when closed when rendered withReact.lazy
. (#2290) -
Fixed
Hovercard
being shown on touch/tap on mobile devices. (#2291) -
Fixed
Hovercard
not properly cleaning up the timeout to hide the card when unmounted. (#2289) -
Updated dependencies:
@ariakit/react-core@0.1.3
,@ariakit/core@0.1.2
.
-
Added missing
defaultValue
prop back touseRadioStore
. (#2265) -
Updated dependencies:
@ariakit/core@0.1.1
,@ariakit/react-core@0.1.2
.
-
Removed extra
console.log
fromHovercard
. -
Updated dependencies:
@ariakit/react-core@0.1.1
.
-
Combobox
doesn't support filtering via thelist
andmatches
props anymore. Instead, you can use a library such as match-sorter to filter the list.Before:
const combobox = useComboboxState({ list }); combobox.matches.map((value) => <ComboboxItem key={value} value={value} />);
After:
const combobox = useComboboxStore(); const value = combobox.useState("value"); const matches = useMemo(() => matchSorter(list, value), [value]); matches.map((value) => <ComboboxItem key={value} value={value} />);
This gives you more control over the filtering process, and you can use any library you want. Besides match-sorter, we also recommend fast-fuzzy for fuzzy matching.
-
Replaced state hooks (e.g.,
useComboboxState
) with component stores (e.g.,useComboboxStore
).Before:
const combobox = useComboboxState({ defaultValue: "value" }); const value = combobox.value; <Combobox state={combobox} />;
After:
const combobox = useComboboxStore({ defaultValue: "value" }); const value = combobox.useState("value"); <Combobox store={combobox} />;
This change applies to all state hooks, not just combobox, and has some API differences. Please, refer to the TypeScript definitions for more information. Learn more about the motivation behind this change in the RFC.
-
The
initialFocusRef
andfinalFocusRef
props fromDialog
and derived components have been renamed toinitialFocus
andfinalFocus
respectively. They now supportHTMLElement
in addition to refs.- <Dialog initialFocusRef={initialFocusRef} finalFocusRef={finalFocusRef} /> + <Dialog initialFocus={initialFocusRef} finalFocus={finalFocusRef} />
-
useMenuStore
anduseSelectStore
can now receive acombobox
prop to combine them with aCombobox
component. This replaces the old method of passing the result ofuseComboboxState
directly as an argument touseMenuState
anduseSelectState
.Before:
const combobox = useComboboxState(); const menu = useMenuState(combobox); const select = useSelectState(combobox);
After:
const combobox = useComboboxStore(); const menu = useMenuStore({ combobox }); const select = useSelectStore({ combobox });
-
Updated package names to include the
@ariakit
scope, providing a more distinct and specific namespace for our packages.Additionally, we've made a change to the versioning system, moving from
v2.0.0-beta.x
tov0.x.x
. This alteration means that although the library is still in beta, we can release breaking changes in minor versions without disrupting projects that don't set exact versions in theirpackage.json
.- npm i ariakit + npm i @ariakit/react
-
We've made changes to the package structure, and component hooks such as
useButton
anduseCheckbox
are no longer exported from@ariakit/react
. Instead, you can import them from@ariakit/react-core
:- import { useButton } from "@ariakit/react"; + import { useButton } from "@ariakit/react-core/button/button";
By doing so, we can reduce the API surface of the
@ariakit/react
package and move towards a stable release. It's important to note that@ariakit/react-core
does not follow semver conventions, and breaking changes may be introduced in minor and patch versions.
-
Packages are now ESM by default (commonjs modules are still available with the
.cjs
extension). -
Updated dependencies:
@ariakit/react-core@0.1.0
,@ariakit/core@0.1.0
.