mirror of
https://github.com/github/awesome-copilot.git
synced 2026-08-25 10:21:40 +00:00
fix(website): resolve accessibility violations in ported detail pages
Fixes the three axe violations surfaced by the a11y audit after the Primer Brand redesign: - aria-prohibited-attr: `aria-label` was set on roleless `div`s in InstructionDetail and PluginDetail. The "Applies to" list now uses list/listitem roles; plugin provenance uses a group role. - scrollable-region-focusable: the install command `code` element overflows horizontally but was not keyboard reachable. Added tabIndex to all three render sites. - color-contrast: the Playbook "New" label used the brand's success-fg on success-subtle, reaching only 4.09:1 in light mode. Stepped one down the same green ramp for 6.14:1. Scoped to light mode; dark mode already passed and its green-7 is near-black. Also corrects the stale route list in the audit script: /hooks/, /workflows/ and /tools/ have never existed as pages. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
This commit is contained in:
@@ -28,21 +28,16 @@ const routes = [
|
|||||||
'/agents/',
|
'/agents/',
|
||||||
'/instructions/',
|
'/instructions/',
|
||||||
'/skills/',
|
'/skills/',
|
||||||
'/hooks/',
|
|
||||||
'/workflows/',
|
|
||||||
'/extensions/',
|
'/extensions/',
|
||||||
'/plugins/',
|
'/plugins/',
|
||||||
'/tools/',
|
|
||||||
'/contributors/',
|
'/contributors/',
|
||||||
|
'/learning-hub/',
|
||||||
'/learning-hub/cookbook/',
|
'/learning-hub/cookbook/',
|
||||||
'/learning-hub/github-copilot-app/',
|
|
||||||
// Representative dedicated detail pages (one per resource type) so the audit
|
// Representative dedicated detail pages (one per resource type) so the audit
|
||||||
// covers the shared detail layout, sidebar, install buttons, and file browser.
|
// covers the shared detail layout, sidebar, install buttons, and file browser.
|
||||||
'/agent/accessibility/',
|
'/agent/accessibility/',
|
||||||
'/instruction/a11y/',
|
'/instruction/a11y/',
|
||||||
'/skill/acquire-codebase-knowledge/',
|
'/skill/acquire-codebase-knowledge/',
|
||||||
'/hook/dependency-license-checker/',
|
|
||||||
'/workflow/daily-issues-report/',
|
|
||||||
'/plugin/accessibility-kanban/',
|
'/plugin/accessibility-kanban/',
|
||||||
'/extension/accessibility-kanban/',
|
'/extension/accessibility-kanban/',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ function InstallCommand({ command }: { command: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={appStyles.installBar}>
|
<div className={appStyles.installBar}>
|
||||||
<code className={appStyles.installCommand}>{command}</code>
|
<code className={appStyles.installCommand} tabIndex={0}>
|
||||||
|
{command}
|
||||||
|
</code>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={appStyles.installCopy}
|
className={appStyles.installCopy}
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ export function InstallCommandBar() {
|
|||||||
))}
|
))}
|
||||||
</ActionMenu.Overlay>
|
</ActionMenu.Overlay>
|
||||||
</ActionMenu>
|
</ActionMenu>
|
||||||
<code className={styles.installCommand}>{selected.command}</code>
|
<code className={styles.installCommand} tabIndex={0}>
|
||||||
|
{selected.command}
|
||||||
|
</code>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={styles.installCopy}
|
className={styles.installCopy}
|
||||||
|
|||||||
@@ -125,9 +125,11 @@ export function InstructionDetail({
|
|||||||
// are promoted into the hero rather than left in the sidebar.
|
// are promoted into the hero rather than left in the sidebar.
|
||||||
const heroExtras =
|
const heroExtras =
|
||||||
applyTo.length > 0 ? (
|
applyTo.length > 0 ? (
|
||||||
<div className={styles.metaValues} aria-label="Applies to">
|
<div className={styles.metaValues} role="list" aria-label="Applies to">
|
||||||
{applyTo.map((pattern) => (
|
{applyTo.map((pattern) => (
|
||||||
<Token key={pattern} text={pattern} />
|
<span key={pattern} role="listitem">
|
||||||
|
<Token text={pattern} />
|
||||||
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
|
|||||||
@@ -141,7 +141,9 @@ export function PluginDetail({
|
|||||||
const install = (
|
const install = (
|
||||||
<>
|
<>
|
||||||
<div className={installStyles.installBar}>
|
<div className={installStyles.installBar}>
|
||||||
<code className={installStyles.installCommand}>{installCommand}</code>
|
<code className={installStyles.installCommand} tabIndex={0}>
|
||||||
|
{installCommand}
|
||||||
|
</code>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={installStyles.installCopy}
|
className={installStyles.installCopy}
|
||||||
@@ -167,7 +169,7 @@ export function PluginDetail({
|
|||||||
// Provenance sits in the hero: whether the plugin ships from this repository
|
// Provenance sits in the hero: whether the plugin ships from this repository
|
||||||
// or from a third-party repo is the first thing a reader needs to know.
|
// or from a third-party repo is the first thing a reader needs to know.
|
||||||
const heroExtras = (
|
const heroExtras = (
|
||||||
<div className={styles.metaValues} aria-label="Plugin provenance">
|
<div className={styles.metaValues} role="group" aria-label="Plugin provenance">
|
||||||
<Label color={item.external ? "purple" : "green"} size="medium">
|
<Label color={item.external ? "purple" : "green"} size="medium">
|
||||||
{item.external ? "External plugin" : "Built-in"}
|
{item.external ? "External plugin" : "Built-in"}
|
||||||
</Label>
|
</Label>
|
||||||
|
|||||||
@@ -1049,6 +1049,16 @@
|
|||||||
background-color: var(--brand-color-success-subtle);
|
background-color: var(--brand-color-success-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In light mode the brand's success-fg on success-subtle only reaches 4.09:1 at
|
||||||
|
* this text size. Step one down the same green ramp to clear WCAG AA (6.14:1)
|
||||||
|
* without leaving the brand palette. Dark mode already passes, and its green-7
|
||||||
|
* is near-black, so this is deliberately light-mode only.
|
||||||
|
*/
|
||||||
|
.page[data-mode="light"] .recCardLabelAccent {
|
||||||
|
color: var(--base-color-scale-green-7);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Secondary label variant: stroke only, no fill. Pairs with the neutral filled
|
* Secondary label variant: stroke only, no fill. Pairs with the neutral filled
|
||||||
* .recCardLabel so the two tags on a card read as distinct (per brand cards).
|
* .recCardLabel so the two tags on a card read as distinct (per brand cards).
|
||||||
|
|||||||
Reference in New Issue
Block a user