Skip to content

Commit 82923e2

Browse files
authored
a11y: Standardize copy button announcement (#52229)
1 parent e114494 commit 82923e2

File tree

7 files changed

+19
-14
lines changed

7 files changed

+19
-14
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@
232232
"@octokit/request-error": "6.1.1",
233233
"@primer/behaviors": "^1.7.0",
234234
"@primer/css": "^21.3.1",
235+
"@primer/live-region-element": "^0.7.0",
235236
"@primer/octicons": "^19.11.0",
236237
"@primer/octicons-react": "^19.11.0",
237238
"@primer/react": "36.27.0",

src/content-render/stylesheets/annotate.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,7 @@
137137
.subnav-item[aria-current]:not([aria-current="false"]) {
138138
z-index: 0;
139139
}
140+
141+
button.js-btn-copy.copied::after {
142+
content: "Copied!";
143+
}

src/content-render/tests/__snapshots__/annotate.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`annotate > renders annotations 1`] = `
4-
"<div class="annotate beside"><div class="annotate-header"><header class="d-flex flex-items-center flex-justify-between p-2 text-small rounded-top-1 border-top border-left border-right"><span class="flex-1">YAML</span><div class="annotate-toggle"><button name="annotate-display" value="beside" type="button" class="annotate-option">Beside</button><button name="annotate-display" value="inline" type="button" class="annotate-option">Inline</button></div><button class="js-btn-copy btn btn-sm tooltipped tooltipped-nw" aria-label="Copy YAML code to clipboard" data-clipboard="1746955726" aria-live="polite" aria-atomic="true"><svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-copy" aria-hidden="true"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><pre hidden data-clipboard="1746955726"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.
4+
"<div class="annotate beside"><div class="annotate-header"><header class="d-flex flex-items-center flex-justify-between p-2 text-small rounded-top-1 border-top border-left border-right"><span class="flex-1">YAML</span><div class="annotate-toggle"><button name="annotate-display" value="beside" type="button" class="annotate-option">Beside</button><button name="annotate-display" value="inline" type="button" class="annotate-option">Inline</button></div><button class="js-btn-copy btn btn-sm tooltipped tooltipped-nw" aria-label="Copy YAML code to clipboard" data-clipboard="1746955726"><svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-copy" aria-hidden="true"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><pre hidden data-clipboard="1746955726"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.
55
name: Post welcome comment
66
77
# Add the \`pull_request\` event, so that the workflow runs automatically

src/content-render/unified/code-header.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ export function header(lang, code, subnav) {
6262
class: ['js-btn-copy', 'btn', 'btn-sm', 'tooltipped', 'tooltipped-nw'],
6363
'aria-label': `Copy ${languages[lang]?.name} code to clipboard`,
6464
'data-clipboard': codeId,
65-
'aria-live': 'polite',
66-
'aria-atomic': 'true',
6765
},
6866
btnIcon(),
6967
),

src/frame/components/lib/copy-code.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { announce } from '@primer/live-region-element'
2+
13
export default function copyCode() {
24
const buttons = Array.from(document.querySelectorAll('button.js-btn-copy'))
35

@@ -13,11 +15,12 @@ export default function copyCode() {
1315
if (!text) return
1416
await navigator.clipboard.writeText(text)
1517

16-
const beforeTooltip = button.getAttribute('aria-label') || ''
17-
button.setAttribute('aria-label', 'Copied!')
18+
button.classList.add('copied')
19+
20+
announce('Copied!')
1821

1922
setTimeout(() => {
20-
button.setAttribute('aria-label', beforeTooltip)
23+
button.classList.remove('copied')
2124
}, 2000)
2225
}),
2326
)

src/rest/components/RestCodeSamples.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState, useEffect, useRef, FormEvent } from 'react'
22
import { FormControl, Select, TabNav } from '@primer/react'
33
import { Tooltip } from '@primer/react/next'
44
import { CheckIcon, CopyIcon } from '@primer/octicons-react'
5+
import { announce } from '@primer/live-region-element'
56
import Cookies from 'src/frame/components/lib/cookies'
67
import cx from 'classnames'
78

@@ -288,14 +289,11 @@ export function RestCodeSamples({ operation, slug, heading }: Props) {
288289
>
289290
<button
290291
className="js-btn-copy btn-octicon"
291-
aria-label={
292-
isCopied
293-
? t('button_text.copied')
294-
: `${t('button_text.copy_to_clipboard')} ${selectedLanguage} request example`
295-
}
296-
aria-live="polite"
297-
aria-atomic="true"
298-
onClick={() => setCopied()}
292+
aria-label={`${t('button_text.copy_to_clipboard')} ${selectedLanguage} request example`}
293+
onClick={() => {
294+
setCopied()
295+
announce('Copied!')
296+
}}
299297
>
300298
{isCopied ? <CheckIcon /> : <CopyIcon />}
301299
</button>

0 commit comments

Comments
 (0)