Skip to content

[ButtonBase] Add focusableWhenDisabled prop#48680

Closed
siriwatknp wants to merge 3 commits into
mui:masterfrom
siriwatknp:feat/button-base-focusable-when-disabled
Closed

[ButtonBase] Add focusableWhenDisabled prop#48680
siriwatknp wants to merge 3 commits into
mui:masterfrom
siriwatknp:feat/button-base-focusable-when-disabled

Conversation

@siriwatknp

@siriwatknp siriwatknp commented Jun 17, 2026

Copy link
Copy Markdown
Member

closes #33182

Sandbox: https://stackblitz.com/edit/o5kyiyjo?file=src%2FDemo.tsx

Problem

The documented way to use Tooltip with a disabled element wraps it in a <span>:

<Tooltip title="Delete">
  <span>
    <IconButton disabled><DeleteIcon /></IconButton>
  </span>
</Tooltip>

Tooltip injects the accessible name onto the outermost cloned child — the span, not the button. This:

  • puts an aria-label on a span (Axe/Lighthouse warn — a span has no nameable role),
  • leaves the real <button> with no accessible name,
  • and the usual workaround (duplicating aria-label on the button) produces two elements with the same name, which breaks getByLabelText and risks double announcement.

The wrapper is only needed because a disabled element doesn't fire the events Tooltip listens to — and ButtonBase additionally sets pointer-events: none on .Mui-disabled.

Solution

Make focusableWhenDisabled a public prop on ButtonBase (inherited by Button and IconButton). When set on a disabled element, it uses aria-disabled instead of the native disabled attribute and keeps pointer-events, so the element stays focusable and keeps firing events while remaining inert.

Tooltip then attaches directly to the element — works on hover and keyboard focus, and the accessible name lands on the element itself, no wrapper:

<Tooltip title="Delete">
  <IconButton aria-label="Delete" disabled focusableWhenDisabled>
    <DeleteIcon />
  </IconButton>
</Tooltip>

Changes

  • ButtonBase: expose focusableWhenDisabled publicly (type + propType) and forward it to useButtonBase — it was previously destructured but never passed, so the disabledaria-disabled swap was dead code for component consumers.
  • ButtonBase: move .Mui-disabled { pointer-events: none } into a variant gated on !focusableWhenDisabled, so a focusable-disabled element still receives hover events.
  • Docs: rewrite the Tooltip "Disabled elements" section to recommend focusableWhenDisabled; keep the span approach as the documented fallback for native / non-ButtonBase elements.

When focusableWhenDisabled is falsy, ButtonBase and useButtonBase behave exactly as before — only opt-in usage changes.

Make the internal focusableWhenDisabled prop public on ButtonBase, Button,
and IconButton, and wire it through to useButtonBase (it was destructured but
never forwarded). When set, the element uses aria-disabled instead of the
native disabled attribute and keeps pointer-events, so a disabled element
stays focusable and keeps firing events.

This lets Tooltip listen to hover and focus directly on a disabled element and
forward the accessible name to it, removing the need for the span wrapper that
broke accessibility. Update the Tooltip disabled-elements docs accordingly.
@code-infra-dashboard

code-infra-dashboard Bot commented Jun 17, 2026

Copy link
Copy Markdown

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/material 🔺+144B(+0.03%) 🔺+21B(+0.01%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@siriwatknp siriwatknp requested a review from mj12albert June 17, 2026 06:36
@siriwatknp

Copy link
Copy Markdown
Member Author

@mj12albert Is this the plan when you added the nativeButton prop in #48680?

@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jun 17, 2026
Signed-off-by: Siriwat K <siriwatkunaporn@gmail.com>
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jun 17, 2026
@mj12albert

Copy link
Copy Markdown
Member

@siriwatknp I already have a PR open #48613 😬

@siriwatknp siriwatknp closed this Jun 18, 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.

Accessibility of Tooltip with disabled items

2 participants