Add support for `accessibleWhenDisabled` on Button
Description
Add an accessibleWhenDisabled prop to Button that keeps a disabled button focusable and accessible to assistive technologies.
When enabled, Chakra would use aria-disabled="true" instead of the native disabled attribute.
Problem Statement/Justification
Currently, when a button becomes disabled, for example, when entering a loading state, it loses focus because the native disabled attribute removes it from the focus order.
After clicking the button, focus should ideally remain on the same control while the action is in progress instead of being lost when disabled becomes true.
I think this behavior is useful beyond loading/pending buttons, so a generic API makes more sense than something tied specifically to an isPending or loading state.
Ariakit uses the name accessibleWhenDisabled, which I prefer over something like focusableWhenDisabled. It describes the intent rather than one particular consequence of the behavior.
Proposed Solution or API
Add an accessibleWhenDisabled prop:
<Button disabled accessibleWhenDisabled>
Submit
</Button>
<Button loading accessibleWhenDisabled>
Submit
</Button>Without the prop, the current behavior remains unchanged:
<button disabled>
Submit
</button>With accessibleWhenDisabled, Chakra would render:
<button aria-disabled="true">
Submit
</button>Chakra would also need to prevent the button’s action from being triggered while aria-disabled="true", since unlike the native disabled attribute, aria-disabled does not prevent interaction by itself.
Alternatives
If this behavior is adopted, it may also be worth considering implementing it in the Zag.js button machine. The current button implementation already contains interaction logic around disabled and loading states, and moving this behavior into the shared state machine could reduce framework-specific code while making the feature available across all frameworks built on Zag.js.
Additional Information
Similar APIs / discussions:
- Ariakit uses accessibleWhenDisabled https://ariakit.com/reference/button#accessiblewhendisabled
- Base UI discusses preserving focus for buttons while loading: https://base-ui.com/react/components/button#loading-states
- Related discussion from Diego Haz: https://x.com/diegohaz/status/2086960304324325482
Source: chakra-ui/chakra-ui