Skip to content

feat(ui): wire Mosaic Button to the headless Button with focusableWhenDisabled - #9320

Open
alexcarpenter wants to merge 1 commit into
carp/headless-buttonfrom
carp/mosaic-button-focusableWhenDisabled
Open

feat(ui): wire Mosaic Button to the headless Button with focusableWhenDisabled#9320
alexcarpenter wants to merge 1 commit into
carp/headless-buttonfrom
carp/mosaic-button-focusableWhenDisabled

Conversation

@alexcarpenter

Copy link
Copy Markdown
Member

Description

Note

Stacked on #9319. Review that one first; this PR's diff is against it.

Mosaic's Button now renders the headless Button instead of a bare <button>, and forwards a new focusableWhenDisabled prop:

<Button disabled={submitting} focusableWhenDisabled type='submit'>Save</Button>

A button that disables itself mid-interaction drops focus to the body, and the user loses their place on the page. With the prop set, the button keeps its position in the tab order and is marked aria-disabled instead. type='button' is dropped from the call site since the headless component already defaults it.

Regating the interactive states

The variant styles gated every hover/active/[data-open] state on :enabled. That gate stops holding under focusableWhenDisabled, which by design omits the disabled attribute — a disabled button would have kept lighting up on hover. The button is also deliberately left hit-testable while disabled, so cursor: not-allowed renders and a wrapping tooltip still receives the pointer, which rules out suppressing the states with pointer-events.

All 52 selectors are regated on :not([data-disabled]). themeProps reflects data-disabled from the prop, so it is present whether or not the native attribute is, and one selector covers both. Compiled output is equivalent: 27 deduped atoms, no :enabled left in styles.css.

Mosaic components are internal — only styles.css is exported from the package — so there is no public API change and no call site opts into the prop yet. Hence the empty changeset.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 175b14a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview Aug 4, 2026 12:54am
swingset Ready Ready Preview Aug 4, 2026 12:54am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant