fix(a11y): apply external a11y-skill audit findings - #190
Merged
Merged
Conversation
Audited against frontend-a11y (mikemai2awesome), accessibility-skills (mgifford), and the Intopia web-accessibility skill. - Navbar: hamburger keeps a constant `aria-label="Menu"`; `aria-expanded` carries open/closed instead of flipping the name (keep-name-constant rule). - ConsentBanner: drop redundant `title` on the reset button (title attribute is for `<iframe>` only; `aria-label` already names it). - AboutSection, ChallengeHighlights: drop synthetic `<section aria-label>` landmarks with no real heading; render plain `<div>`s so the landmarks menu is not cluttered by generically named regions. - SolutionDetail: rename the sidebar `<aside>` label from "Solution navigation" to "Solution sidebar" (it is a complementary region, not navigation). - External links: move the "opens in a new tab" hint out of each link's accessible name into a single shared hidden `#new-tab-hint` node referenced via `aria-describedby`. Removes the inline sr-only spans and the phrase from social-icon `aria-label`s across components and pages, and updates the adventure generator (`annotateExternalLinks`) to emit `aria-describedby`. - Update tests and styleguide for the new external-link pattern. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Run `npm run generate` after updating `annotateExternalLinks`. - External links in generated prose now carry `aria-describedby="new-tab-hint"` instead of an inline sr-only "(opens in new tab)" span. - No YAML source content changed. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
Contributor
|
- remark-gfm autolinks bare URLs authored in prose, so addresses like http://localhost:8080/ became clickable new-tab external links on the deployed site, pointing at the visitor's own machine. - `annotateExternalLinks` now unwraps non-public URLs (loopback, mDNS, and single-label hosts) to plain text instead of stamping target/rel and the new-tab hint on them. Real public links are unchanged. - Add a regression test asserting generated files link no loopback URL and keep localhost addresses as plain text. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Run `npm run generate` after the annotateExternalLinks change. - localhost URLs in generated prose now render as plain text, not links. - No YAML source content changed. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- isNonPublicUrl now also unwraps private IPv4 ranges (10.x, 192.168.x, 172.16-31.x) so a bare private-IP URL in prose cannot become a new-tab link to the visitor's own network on the deployed site. - Extend the regression test's loopback pattern to cover those ranges. - No content change: no adventure prose contains such URLs, so regeneration is a no-op. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- The rule was globally off to allow intentional role="list" on <ul>/<ol>
(Safari VoiceOver strips list semantics under list-none).
- Re-enable with { ul: ["list"], ol: ["list"] } so that workaround stays valid
while other redundant roles (e.g. role="button" on <button>) are caught at
lint time. Verified: role="button" on <button> is flagged, role="list" on
<ul> is not; lint stays green.
Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
CLAUDE.md tells contributors to read ACCESSIBILITY.md before touching any
component, so the adjudicated rules belong there, not only in the on-demand
audit command. Two existing bullets contradicted the shipped code and are fixed.
- ACCESSIBILITY.md:
- External links: replace the removed per-link sr-only span with
aria-describedby="new-tab-hint"; add the no-linked-localhost rule.
- Semantic HTML: correct the section-naming bullet (name a <section> landmark
only via a real heading; never invent a synthetic aria-label; use a plain
<div> when there is no heading).
- ARIA: constant toggle name across states; title only on <iframe>; the
native-disabled vs aria-disabled nuance.
- a11y-audit.md: Component Rules + Contrast and Transparency guardrail sections,
plus a Credits section for the community sources that informed them.
- keyboard.md: Disabled Controls rule per the WAI-ARIA APG Button Pattern.
Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Rename the floating consent-reset button's accessible name from "Reset cookie preferences" to "Cookie Preferences": clicking re-opens the preferences banner rather than resetting to defaults, so the destination name is more accurate. The button stays icon-only with the Cookie glyph aria-hidden (name via aria-label). - Fix the visual-regression mask selector, which referenced a non-existent aria-label="Change cookie preferences" and never matched; it now mirrors the real aria-label (the file's documented pattern). - Update the e2e and unit name assertions to match. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
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.
Audited this repo against three external agent a11y skill sets — frontend-a11y (mikemai2awesome), accessibility-skills (mgifford), and the Intopia web-accessibility skill — and applied the findings that were genuine divergences. The codebase was already strongly compliant (native
<details>, mounted-then-filled live regions, no positive tabindex,:focus-visible, route-change announcer, tooltip Escape handling); these are the remaining items.Changes
aria-label="Menu";aria-expandedcarries open/closed instead of flipping the name.titleon the reset button (title is for<iframe>only;aria-labelalready names it).<section aria-label="…">landmarks that had no real heading; render plain<div>s so the screen-reader landmarks menu is not cluttered.<aside>label from "Solution navigation" to "Solution sidebar" (it is a complementary region, not navigation).#new-tab-hintnode referenced viaaria-describedby. Removed inlinesr-onlyspans and the phrase from social-iconaria-labels across 22 components/pages, and updated the adventure generator (annotateExternalLinks) so generated prose links usearia-describedbytoo.Notes
aria-describedbyto a few external links that previously had no hint at all, making hinting consistent. Improvement, not a regression.Verification
npm run lint: cleannpm test: 1097 passednpm run build: clean rebuild succeedsnpm run test:e2e: 215 passed (axe in dark + light mode)🤖 Generated with Claude Code