chore(lint): enforce jsx-a11y/label-has-associated-control - #234
Merged
Conversation
eslint-config-next enables only a narrow jsx-a11y subset (alt-text, aria-props, role validity), so <label>s not wired to a control pass a clean lint. Enable label-has-associated-control at error to catch that in CI, and fix the 4 pre-existing violations: the browse-library filter labels in ClinicalDashboard sat next to aria-labeled <select>s without being associated to them, so associate each via htmlFor/id. Deliberately did NOT enable the sibling control-has-associated-label (which flags an unlabeled input/select): it false-positives on this codebase's pervasive <label><span>text</span><input/></label> pattern (~13 correct controls) and depth tuning does not clear them. Precise unlabeled-control detection belongs in a runtime axe-core check (tracked separately). lint (0 errors), typecheck, and prettier all clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
What
Adds one accessibility lint rule —
jsx-a11y/label-has-associated-controlat error — and fixes the 4 pre-existing violations it surfaces. Config-only + a small, self-contained markup fix. No new dependencies.Why
Follow-up to the 2026-07 DOM/a11y audit.
eslint-config-nextenables only a narrowjsx-a11ysubset (alt-text, aria-props, role validity), so a<label>that isn't wired to a control passes a clean lint. This closes that gap and enforces it in CI.The 4 fixes: the browse-library filter labels in
ClinicalDashboard(Type/Site/Topic/Population) sat next toaria-labeled<select>s but weren't associated with them. Each is now linked viahtmlFor/id(thearia-labelstays as the descriptive name).Deliberately scoped out
I measured the sibling rule
control-has-associated-label(which flags an unlabeled<input>/<select>— the exact regression class from the audit) and did not enable it: it false-positives on this codebase's pervasive<label><span>text</span><input/></label>pattern (~13 correctly-labeled controls across auth-panel, forms, DocumentManagementActions, master-search-header, …), anddepthtuning doesn't clear them. Enabling it — even atwarn— would flood lint with noise on correct code. Precise unlabeled-control detection is better done with a runtime axe-core check (no false positives), which needs a dependency + test wiring and is tracked as a separate task.Testing
eslint(full scope) — 0 errors (rule enforced; the 20 remaining warnings are pre-existingno-unused-vars)tsc --noEmit— cleanprettier --check— cleanClinical governance
Lint config + accessibility markup only. No ingestion, answer generation, search/ranking, source rendering, document access, privacy, or clinical output — governance preflight N/A.
🤖 Generated with Claude Code