fix(web): section-header hover outline + clear buttons out of tab order (#1487) (#1488)

* fix(web): section-header hover outline + clear buttons out of tab order (#1487)

Two button-behavior adjustments:

1. History section headers (Pinned / History) now use the filter-toggle
   style — a thin outline on hover instead of a background fill — by pointing
   the `sectionHeader` Group variant at the shared `.filter-toggle` class. The
   open section keeps its filled background (passed per-instance via `bg`).

2. Every input clear button added in #1448 is removed from the keyboard tab
   order via `tabIndex={-1}` (CloseButton clear buttons app-wide, plus the
   Autocomplete clear button through `theme/Autocomplete.ts` clearButtonProps),
   so tabbing through a form moves to the next field, not onto the clear button.
   The buttons stay mouse-clickable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(web): apply filter-toggle hover outline to Resources accordion headers (#1487)

The Resources screen `disclosure` accordion controls now share the same
outline-on-hover treatment as the filter toggle buttons and History section
headers: a thin border on hover instead of a background fill, plus a filled
background when the section is open (keyed off `aria-expanded`). The `.filter-
toggle` class is added to the disclosure control slot; the default-variant
accordion (Server Settings) keeps its background-fill hover via a `:not(.filter-
toggle)` guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(web): extract ClearButton element, replace 34 inline clear buttons

Addresses the code-review suggestion on PR #1488: the same five-line
`CloseButton` clear-affordance block (aria-label="Clear" + tabIndex={-1} +
onClick) was hand-copied across 17 files. Extract a single
`elements/ClearButton` (Mantine `CloseButton.withProps` with the aria-label and
tabIndex baked in) and replace all 34 call sites, so the clear-button contract
lives in one place. A global CloseButton theme default would be wrong here — it
would also catch tabbable modal-close X buttons and the Select clear buttons —
so a dedicated element is the right altitude.

Net -151 lines. Adds element unit tests + a Storybook play test covering the
aria-label / tabIndex / clickable contract for all sites at once.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cliff Hall 2026-06-14 22:27:46 -04:00 • committed by GitHub
commit bb32d1db5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -283,14 +283,18 @@
/* ── Filter toggle buttons (Logging / History / Network) ─────────
*
* Shared by the FilterToggleButton element. Unlike `.list-item`, hover is a
* thin border rather than a background fill, and the active (on) state is the
* filled background. Keeping the two states distinct means toggling a button
* off while the cursor is still over it is immediately visible, instead of the
* hover background masking the removal of the active background (issue #1460).
* The 1px transparent border is reserved here (not as an inline style in the
* theme variant — inline styles outrank stylesheet `:hover` rules) so the hover
* border doesn't shift layout. */
* Shared by the FilterToggleButton element, the History list's collapsible
* section headers (the `sectionHeader` Group variant), and the Resources
* disclosure accordion controls (the `disclosure` Accordion variant). The
* active (on / open) state is keyed off `aria-pressed` for the toggle buttons
* and `aria-expanded` for the accordion controls. Unlike `.list-item`,
* hover is a thin border rather than a background fill, and the active (on)
* state is the filled background. Keeping the two states distinct means
* toggling a button off while the cursor is still over it is immediately
* visible, instead of the hover background masking the removal of the active
* background (issue #1460). The 1px transparent border is reserved here (not as
* an inline style in the theme variant — inline styles outrank stylesheet
* `:hover` rules) so the hover border doesn't shift layout. */
.filter-toggle {
border: 1px solid transparent;
@ -301,7 +305,8 @@
border-color: var(--inspector-brand-primary);
}
.filter-toggle[aria-pressed="true"] {
.filter-toggle[aria-pressed="true"],
.filter-toggle[aria-expanded="true"] {
background-color: var(--mantine-primary-color-light);
}
@ -342,7 +347,11 @@
/* ── Accordion button hover ─────────────────────────────── */
.mantine-Accordion-control:hover {
/* Default accordions (e.g. Server Settings) keep the background-fill hover.
* The Resources `disclosure` accordion opts out via `.filter-toggle` (added to
* its control slot in theme/Accordion.ts) so it gets the outline-on-hover
* treatment instead — see the `.filter-toggle` rules above. */
.mantine-Accordion-control:not(.filter-toggle):hover {
background-color: var(--mantine-primary-color-light-hover);
}