Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve cancellation of events when using disabled or aria-disabled attributes #2890

Merged
merged 3 commits into from
Dec 20, 2023

Conversation

RobinMalfait
Copy link
Member

This PR fixes and improves the disabled and aria-disabled event handling that we introduced in
#1265.

We wrongly assumed that we don't want to attach any event listeners if the disabled or
aria-disabled props were used. While in most cases this is true, and is even a no-op (the browser
doesn't call onClick on a <button disabled>) it is not true in other cases.

For example <a disabled> doesn't exist, instead we use <a aria-hidden="">. If we now want to
"disabled" the native click behaviour we have to add onClick={e => e.preventDefault()}.

In the linked PR, we were removing the onClick we could have added. In this PR we make sure to
always add e => e.preventDefault() instead of the onXYZ handler we or you provided. We only do
this for onClick, onMouseDown, onMouseUp, onPointerDown, onPoiterUp, onKeyDown,
onKeyUp and onKeyPress. These are typically the events that cause an actual action that we want
to prevent instead.

The initial idea was that whenever an element had the `disabled` or
`aria-disabled` prop/attribute that we were going to remove all the
event listeners.

However, this is not ideal because in some scenario's we were actually
explicitly adding `onClick()` listeners (for `<a>` elements) to
`e.preventDefault()` when the link was marked as "disabled" to prevent
it executing the actual link click.

This commit will allow all defined listeners as-is, however, if you are
using one of the following event listeners:

- `onClick`
- `onPointerUp`
- `onPointerDown`
- `onMouseUp`
- `onMouseDown`
- `onKeyUp`
- `onKeyPress`
- `onKeyDown`

Then we will replace it with `(e) => e.preventDefault()` instead.

This way we are still invoking your own listeners, but are explicitly
calling `e.preventDefault()` on listeners that should not be executed in
the first place when an element is `disabled`.
Copy link

vercel bot commented Dec 20, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
headlessui-react 🛑 Canceled (Inspect) Dec 20, 2023 11:04pm
headlessui-vue ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 20, 2023 11:04pm

@RobinMalfait RobinMalfait changed the title Improve cancellation of event when using disabled or aria-disabled attributes Improve cancellation of events when using disabled or aria-disabled attributes Dec 20, 2023
@RobinMalfait RobinMalfait force-pushed the fix/cancel-events-when-disabled branch from 7068e8f to 304c184 Compare December 20, 2023 23:03
@RobinMalfait RobinMalfait merged commit 33a5893 into main Dec 20, 2023
7 of 8 checks passed
@RobinMalfait RobinMalfait deleted the fix/cancel-events-when-disabled branch December 20, 2023 23:09
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.

1 participant