From 9f5b5ea6a758efe1ca085bbd13b9a89cd2b41e4f Mon Sep 17 00:00:00 2001
From: Danny White <3104761+dnywh@users.noreply.github.com>
Date: Mon, 7 Sep 2026 16:59:40 +1000
Subject: [PATCH] fix(ui): standardise disclosure focus rings (#49660)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## What kind of change does this PR introduce?
Bug fix and design-system accessibility update.
## What is the current behavior?
Accordion and collapsible triggers do not consistently use the shared
focus treatment. Accordion focus can animate from the browser outline,
while call sites need to manage radius and focus geometry themselves.
## What is the new behavior?
Bare accordion and collapsible triggers use the rounded `focus-inset`
treatment by default, positioned 2px inside the control. Interactive
children composed with `asChild`, such as a standard `Button`, retain
their own focus treatment. Accordion triggers include a small default
horizontal hit-area padding (`px-2`) and retain an explicit outer-ring
option for standalone controls. The focus indicator is not animated.
Focused tests cover the default and opt-out accordion variants.
| Before | After |
| --- | --- |
| |
|
|
|
|
## Visual impact
Most call sites should look the same at rest. The exceptions are
accordion triggers that did not already set their own horizontal
padding: they pick up the new default `px-2`, `rounded-md`, and lose the
old blanket `transition-all` on the trigger (chevron rotation is
unchanged).
| Resting layout change | Why |
| --- | --- |
| Accordion triggers without an explicit `px-*` | Inherit new default
`px-2` and `rounded-md` |
| Accordion triggers with their own `px-*` | Unchanged (call-site
padding wins) |
| Collapsible triggers | Focus ring only; spacing comes from the child
element |
| Direct `focus-inset` users (table rows, etc.) | Focus ring only |
## To test
Use Tab to focus each disclosure trigger. Confirm the focus outline is
rounded, sits 2px inside the trigger, and appears immediately without a
dark flash.
Previews:
[design-system](https://design-system-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app)
·
[studio-staging](https://studio-staging-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app)
·
[docs](https://docs-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app)
·
[www](https://zone-www-dot-com-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app)
### Design system
-
[Accordion](https://design-system-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/design-system/docs/components/accordion)
-
[Collapsible](https://design-system-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/design-system/docs/components/collapsible)
### Studio (focus-only unless noted)
- [Account → Access tokens → **New
token**](https://studio-staging-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/dashboard/account/tokens):
permission category accordions (already `px-4`)
- [Database →
Roles](https://studio-staging-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/dashboard/project/_/database/roles):
role row collapsibles
- [Observability → Query
performance](https://studio-staging-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/dashboard/project/_/observability/query-performance):
index suggestion accordions (already `px-4`)
- [Settings → JWT
(legacy)](https://studio-staging-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/dashboard/project/_/settings/jwt/legacy):
migration help collapsible
### Docs
- Docs mobile nav (narrow viewport): accordion sections **(resting
layout: +px-2)**
### WWW
- [Pricing →
FAQs](https://zone-www-dot-com-git-dnywh-fixaccordion-focus-rings-supabase.vercel.app/pricing):
FAQ accordions **(resting layout: +px-2)**
- WWW mobile nav (narrow viewport): menu accordions **(resting layout:
+px-2)**
### Not worth opening manually
Sheets, modals, error fallbacks, and replication/cron/integration
advanced-settings accordions inherit the focus fix but need specific
flows or failure states to reach. Error-state troubleshooting accordions
(`TroubleshootingSections`) also gain **+px-2** when visible.
## Summary by CodeRabbit
## New Features
- Accordion triggers now use an inset focus style by default, with an
option to use the standard ring style.
- Accordion and collapsible trigger styling can be customized more
flexibly.
## Accessibility
- Focus indicators appear consistently without flashing browser
defaults.
- Focus transitions are limited to visual properties that preserve
immediate keyboard focus visibility.
## Documentation
- Updated accessibility guidance explains inset focus behavior and
transition considerations.
---
.../content/docs/accessibility.mdx | 9 ++-
packages/config/css/utilities.css | 11 ++-
.../components/shadcn/ui/accordion.test.tsx | 37 +++++++++
.../ui/src/components/shadcn/ui/accordion.tsx | 78 +++++++++++--------
.../src/components/shadcn/ui/collapsible.tsx | 4 +-
5 files changed, 97 insertions(+), 42 deletions(-)
create mode 100644 packages/ui/src/components/shadcn/ui/accordion.test.tsx
diff --git a/apps/design-system/content/docs/accessibility.mdx b/apps/design-system/content/docs/accessibility.mdx
index efdede1da8f..c1660c5b963 100644
--- a/apps/design-system/content/docs/accessibility.mdx
+++ b/apps/design-system/content/docs/accessibility.mdx
@@ -59,16 +59,17 @@ focus-visible:ring-offset-background
Uses `outline` (not `ring`) so it paints reliably on interactive `