fix(docs): add aria-label to Expressive Code copy-to-clipboard buttons#24099
fix(docs): add aria-label to Expressive Code copy-to-clipboard buttons#24099
Conversation
Expressive Code renders copy buttons with `title` but no `aria-label`, so they lack an accessible name for screen readers (WCAG 2.1 SC 4.1.2). Add copy-button-aria.ts script that mirrors `title` → `aria-label` on `.expressive-code button[title]:not([aria-label])` elements, following the same pattern as the existing search-aria.ts enhancement. Resolves warning #3 from the multi-device docs testing report. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/afbccc07-e106-4294-af54-242e4af333b2 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds an accessibility patch so Expressive Code’s copy-to-clipboard buttons receive an accessible name by mirroring their existing title attribute into aria-label when missing, including on Astro client-side navigation.
Changes:
- Add a new DOM enhancement script to set
aria-labelon.expressive-codebuttons based ontitle. - Load the new script from
CustomHead.astroalongside existing accessibility/enhancement scripts.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| docs/src/scripts/copy-button-aria.ts | New client-side enhancement that mirrors title → aria-label for copy buttons and re-applies on astro:page-load. |
| docs/src/components/CustomHead.astro | Imports the new script so it runs site-wide. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const buttons = document.querySelectorAll<HTMLButtonElement>( | ||
| '.expressive-code button[title]:not([aria-label])', | ||
| ); | ||
|
|
||
| buttons.forEach((button) => { | ||
| const label = button.getAttribute('title'); | ||
| if (label) { | ||
| button.setAttribute('aria-label', label); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| // Run on initial page load | ||
| if (document.readyState === 'loading') { | ||
| document.addEventListener('DOMContentLoaded', enhanceCopyButtons); | ||
| } else { | ||
| enhanceCopyButtons(); |
There was a problem hiding this comment.
This new script is indented with tabs (e.g. in the querySelectorAll / forEach block). The other docs enhancement scripts use 2-space indentation (see docs/src/scripts/responsive-tables.ts and search-aria.ts), and the repo’s Prettier config is set for 2-space formatting. Reformat this file to match the established style (run Prettier or convert tabs to spaces) to avoid inconsistent diffs and formatter churn.
| const buttons = document.querySelectorAll<HTMLButtonElement>( | |
| '.expressive-code button[title]:not([aria-label])', | |
| ); | |
| buttons.forEach((button) => { | |
| const label = button.getAttribute('title'); | |
| if (label) { | |
| button.setAttribute('aria-label', label); | |
| } | |
| }); | |
| } | |
| // Run on initial page load | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', enhanceCopyButtons); | |
| } else { | |
| enhanceCopyButtons(); | |
| const buttons = document.querySelectorAll<HTMLButtonElement>( | |
| '.expressive-code button[title]:not([aria-label])', | |
| ); | |
| buttons.forEach((button) => { | |
| const label = button.getAttribute('title'); | |
| if (label) { | |
| button.setAttribute('aria-label', label); | |
| } | |
| }); | |
| } | |
| // Run on initial page load | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', enhanceCopyButtons); | |
| } else { | |
| enhanceCopyButtons(); |
Expressive Code renders copy buttons with
title="Copy to clipboard"but noaria-label, leaving them without an accessible name for screen readers (WCAG 2.1 SC 4.1.2).Changes
docs/src/scripts/copy-button-aria.ts— new script that selects.expressive-code button[title]:not([aria-label])and mirrorstitle→aria-label; re-runs onastro:page-loadfor client-side navigationdocs/src/components/CustomHead.astro— imports the new script alongside the existingsearch-aria.tsandresponsive-tables.tsenhancementsFollows the established pattern for DOM-based accessibility patches in this project. Only sets
aria-labelon buttons that don't already have one — no visual change.