Frontend a11y: focus-visible gaps on sort headers, breadcrumb links, combobox, page-size select; search result count unannounced #69
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #52 — that pass covered custom controls and route focus, but a sweep found a handful of interactive elements that still have no visible keyboard focus state, plus one unannounced async update. The
focusRinghelper (src/lib/focus-ring.ts) exists and is the established fix.Missing focus-visible styling
web/src/objects/objects-table.tsx:131-134— column-header sort buttons:className="flex items-center gap-1 hover:text-foreground". Hover-only feedback; keyboard focus is invisible (the file already importsfocusRingand uses it on the row link). Add${focusRing} rounded-sm.web/src/shell/breadcrumb.tsx:19— breadcrumb<Link>s:"truncate text-muted-foreground hover:text-foreground"— no focus ring. Add${focusRing} rounded-sm.web/src/components/external-uri-link.tsx— the external<a>has hover feedback only. Add${focusRing} rounded-sm.web/src/components/ui/combobox.tsx:23, 29-49—ComboboxInput("w-full rounded border px-2 py-1 pr-12 text-sm"),ComboboxClear, andComboboxTriggerhave nofocus-visible:classes, unlikeui/input.tsx/ui/select.tsxwhich carry the standardfocus-visible:ring-3 focus-visible:ring-ring/50.web/src/objects/objects-table.tsx:286-291— the native page-size<select>has no focus styling at all (default UA outline only, and inconsistent with everything around it). Fixing #68 by swapping to the uiSelectresolves this too.Unannounced async update
web/src/search/search-panel.tsx:105-107— the result count<p>{t("search.resultCount", { count: total })}</p>updates as the user types but is not a live region; screen-reader users get no feedback that results arrived. Addrole="status"(implicitaria-live="polite"), matching the pattern already used by the skeletons.Acceptance
Fixed in
ec11c9d(merged as091a1a6).objects-table.tsx), breadcrumb links, andExternalUriLinknow use the sharedfocusRinghelper (+rounded-smso the ring hugs the text).ui/combobox.tsxinput/clear/trigger got the kit's inlinefocus-visible:ring-3 focus-visible:ring-ring/50classes (input alsofocus-visible:border-ring, matchingui/input.tsx).role="status", so count updates are announced while typing; the existing search test asserts the count throughgetByRole("status").Note: the page-size select kept its native element (got a focus ring rather than a swap to the ui
Select) — if it should be swapped for visual consistency, that's #73-adjacent follow-up territory.