Skip to content

fix(storefront/a11y): swap focus-within for focus-visible on Button, restore focus rings on styled=false #1979

Description

@filiphsps

What to build

The shared Button primitive uses focus-within:brightness-75 instead of focus-visible. This:

  • Triggers on mouse-down (:focus-within matches on any descendant focus, including programmatic), producing the focus style for non-keyboard users.
  • Provides no visible outline/ring — only a brightness change — which can be invisible on themed surfaces.

Additionally, several places pass styled={false} to Button (e.g. cart-button.tsx:19-31, "Clear cart" in cart-lines.tsx:34-45), which strips the existing focus styling without providing a replacement. Keyboard users get nothing.

Fix:

  • Replace focus-within with focus-visible on the Button base.
  • Add an explicit focus-visible:ring-2 focus-visible:ring-offset-2 (or token-equivalent) so the focused state is visible across light/dark surfaces.
  • When styled={false}, still apply a minimum focus-visible ring at the wrapper.

Acceptance criteria

  • No focus-within usage remains on Button (and any other interactive primitives where it was used as a focus proxy)
  • Keyboard Tab through cart, header, and PDP produces a visible focus indicator on every interactive control
  • styled={false} Buttons still surface focus
  • Existing button tests updated; add focus-visible snapshot/assertion

Blocked by

None — can start immediately.

References

  • apps/storefront/src/components/actionable/button.tsx:33
  • apps/storefront/src/components/header/cart-button.tsx:19
  • apps/storefront/src/components/cart/cart-lines.tsx:34

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't workingComponentsready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions