Repository navigation
fix(ui): name every control, tie validation to its field, skip link, page titles and focus - #99
Merged
Merged
Conversation
…page titles and focus - Launch/edit form: Namespace and App type selects are labelled (aria-labelledby); env-var rows are a fieldset with named inputs and a named remove button; the Public switch is labelled and described. The validation message is a role="alert" with id form-error, and the field it is about gets aria-invalid + aria-describedby. - Layout: a "Skip to content" link to <main id="main">. - usePageTitle sets "<page> · <app title>" as document.title on every route and, after a client-side navigation, moves focus to the page's h1. - Apps table: aria-sort on sortable headers, aria-pressed on filter chips. Conditions on the detail page carry sr-only "Passing:"/"Failing:" text. Metrics placeholders are h2, not h3 under an h1. - tests/pages/a11y.test.tsx runs axe-core on all six pages in light and dark (contrast excluded: jsdom does no layout), plus validation wiring, heading focus and the skip link. Biome's recommended a11y rules already run in CI (#80). Closes #59 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016pvMUQJoLkBDk6B94TTm45
…e pages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016pvMUQJoLkBDk6B94TTm45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #59.
What changed
aria-labelledby(their<Label>s had nohtmlFor, and a select trigger isn't labelable).<fieldset>/<legend>. Each row's inputs are named ("Variable 1 name", "Value of LOG_LEVEL"), and the icon-only remove button is "Remove LOG_LEVEL".aria-invalidandaria-describedby="form-error", and the message is<p id="form-error" role="alert">in the destructive colour instead of a muted<p>.<main id="main" tabIndex={-1}>.usePageTitlehook setsdocument.titleto " · " on every route. After a client-side navigation it moves focus to the page's<h1>(tabIndex={-1}) once the heading renders, since pages show a spinner first, so screen readers announce the new page. The first page after a full load keeps the browser's focus.aria-sort, and filter chips carryaria-pressed.aria-hidden.h2(axe flaggedh3directly under theh1).tests/pages/a11y.test.tsxruns axe-core on Dashboard, Apps, App detail, Edit, Launch and Metrics (inside the realLayout), in light and dark.color-contrastis disabled because jsdom does no layout or painting. Before the fixes above it caught an unnamed toggle on Launch and Edit and the heading-order skip on Metrics. The same file tests the validation wiring, heading focus after navigating, and the skip link.Lint rules and dependency: Biome's
recommendedpreset includes thea11yrules and has run in CI since #80. It's why the env group is a<fieldset>. I usedaxe-coredirectly rather thanvitest-axe, which was last published in 2022; it's a dev dependency only.Testing
npm run check:ci,npm run buildandnpm testpass (66 tests).This PR overlaps #96, #97 and #98 in
app-form.tsxandapps.tsx. I'll rebase whichever merges later.🤖 Generated with Claude Code
https://claude.ai/code/session_016pvMUQJoLkBDk6B94TTm45