Skip to content

[6.x] Add disabled prop to Button component#14047

Merged
jackmcdade merged 3 commits into6.xfrom
button-disabled-prop
Feb 26, 2026
Merged

[6.x] Add disabled prop to Button component#14047
jackmcdade merged 3 commits into6.xfrom
button-disabled-prop

Conversation

@duncanmcclean
Copy link
Member

@duncanmcclean duncanmcclean commented Feb 24, 2026

This pull request adds a disabled prop to the Button component, like we have for Input.

Fixes #14022

@daun
Copy link
Contributor

daun commented Feb 24, 2026

This might cause some accessibility issues in certain scenarios.

The ⁠disabled attribute removes the button from the tab order, meaning it can't be reached by keyboard navigation. This can be a problem if you're using a tooltip to explain why the button is disabled, since the user would need to tab to it to show the tooltip.

Using ⁠aria-disabled would keep the button in the tab order while still signalling a disabled state to screenreaders. The trade-off is that click events need to be blocked manually — both in CSS via ⁠pointer-events: none and in JS with ⁠event.preventDefault() — whereas ⁠disabled handles all of that automatically.

@duncanmcclean
Copy link
Member Author

@daun Good catch, thanks! Just pushed up a version using aria-disabled instead.

@jasonvarga
Copy link
Member

What's the point of a disabled attribute on a html element if you can't use it? I think if you want to tell a button to be disabled, it should disable it. If you want it to be just aria-disabled, then explicitly do that instead.

@daun
Copy link
Contributor

daun commented Feb 24, 2026

@jasonvarga I guess disabled is a bit of a misnomer in that it hides the button instead of marking it as disabled for anyone using a screenreader or keyboard exclusively. That's fine where explicitly intended, but I'd argue it's better UX and A11y to keep the element tabbable/interactive and reading/showing some type of message that explains it's disabled and why.

As a user, I'd prefer tabbing to a button that reads "Submit, disabled" to not finding a submit button at all.

There's a few articles I found helpful when dealing with this in a recent project, e.g. Usability Pitfalls of Disabled Buttons and Making Disabled Buttons more Accessible.

@jasonvarga
Copy link
Member

That's fine, but my point is that at the primitive component level, passing a disabled prop to it should just apply that.

If in the context of where you're using that button that you want to maintain tabindex/aria/etc, then using disabled is not appropriate, so don't use it.

@daun
Copy link
Contributor

daun commented Feb 24, 2026

Right, good point, makes sense to keep things literal on the primitive layer.

It would be lovely if the above use-case was somehow supported by the UI layer though, e.g. using a focusable or focusableWhenDisabled prop as a shortcut for using aria-disabled instead of disabled. But I can always submit a PR if I care enough :)

<Button :disabled focusable v-tooltip="hint" @click="handleClick">Submit</Button>

vs

<span v-if="disabled" v-tooltip="hint" @click="handleClick" tabindex="0">
  <Button disabled>Submit</button>
</span>
<Button v-else @click="handleClick">Submit</button>

@jackmcdade
Copy link
Member

@daun i think your a11y pattern is a good one to look at implementing, but i think it would be more appropriate on a wider a11y pass beyond just the button component and — for the sake of this PR — stick to native HTML semantics and just map the disabled prop to the disabled attribute for now like we do everywhere else. 🤙

@jackmcdade jackmcdade merged commit 2db624f into 6.x Feb 26, 2026
11 checks passed
@jackmcdade jackmcdade deleted the button-disabled-prop branch February 26, 2026 05:57
@daun
Copy link
Contributor

daun commented Feb 26, 2026

👌

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.

Cannot disable buttons in widgets

4 participants