reggi/dev-engines
@reggi/path-to-regexp
dependabot/npm_and_yarn/main/copy-to-clipboard-4.0.2
dependabot/npm_and_yarn/main/eslint-10.4.0
dependabot/npm_and_yarn/main/npmcli/eslint-config-7.0.0
dependabot/npm_and_yarn/main/proc-log-7.0.0
dependabot/npm_and_yarn/npm_and_yarn-826852524d
dependabot/npm_and_yarn/npm_and_yarn-ab9a7f4bc2
deprecate-totp-2fa
dhei/classic-tokens
gat-bypass-2fa-docs
jpg619/fix-accessibility-content-flow
jpg619/version-bump-tar-2
kartykp/gat-bypass-2fa-docs
kartykp/upgrade-path-to-regex
main
maitxn/version-bump-tar
patch-1
reggi/cache-based-on-version
reggi/dev-engines
reggi/fix-transform-prettier
reggi/overrides
update-search-sensitivity
| 1 | /** |
| 2 | * This is an implementation of the |
| 3 | * aria-live guide: |
| 4 | * https://github.com/github/thehub/blob/main/docs/epd/engineering/dev-practicals/frontend/accessibility/readiness-routine/screenreaders/live-regions-and-screen-reader-announcements.md |
| 5 | * |
| 6 | * The code is heavily borrowed from https://github.com/github/github/blob/master/app/assets/modules/github/aria-live.ts |
| 7 | */ |
| 8 | |
| 9 | let container |
| 10 | |
| 11 | if (typeof window !== 'undefined') { |
| 12 | document.addEventListener('DOMContentLoaded', function () { |
| 13 | createNoticeContainer() |
| 14 | }) |
| 15 | } |
| 16 | |
| 17 | // Announce message update to screen reader. |
| 18 | export function announce(message) { |
| 19 | if (!container || !container.isConnected) { |
| 20 | /* This condition is for when the aria-live container no longer exists due to nav methods like turbo drive |
| 21 | which replace the body getting rid of the region. We add the container if it's missing. We then add a delay |
| 22 | to ensure aria-live can work correctly. |
| 23 | Note: This approach is not ideal and should be revisited. |
| 24 | See https://github.com/github/accessibility/issues/1900#issuecomment-1254369320 |
| 25 | */ |
| 26 | createNoticeContainer() |
| 27 | setTimeout(() => { |
| 28 | setContainerContent(message) |
| 29 | }, 200) |
| 30 | } else { |
| 31 | setContainerContent(message) |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | // Set aria-live container to message. |
| 36 | function setContainerContent(message) { |
| 37 | if (!container) { |
| 38 | return |
| 39 | } |
| 40 | if (container.textContent === message) { |
| 41 | /* This is a hack due to the way the aria live API works. |
| 42 | A screen reader will not read a live region again |
| 43 | if the text is the same. Adding a space character tells |
| 44 | the browser that the live region has updated, |
| 45 | which will cause it to read again, but with no audible difference. */ |
| 46 | container.textContent = `${message}\u00A0` |
| 47 | } else { |
| 48 | container.textContent = message |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | // Get the global screen reader notice container. |
| 53 | function createNoticeContainer() { |
| 54 | container = document.createElement('div') |
| 55 | container.setAttribute('aria-live', 'polite') |
| 56 | container.style.position = 'absolute' |
| 57 | container.style.width = '1px' |
| 58 | container.style.height = '1px' |
| 59 | container.style.padding = '0' |
| 60 | container.style.overflow = 'hidden' |
| 61 | container.style.clip = 'rect(0, 0, 0, 0)' |
| 62 | container.style.wordWrap = 'normal' |
| 63 | container.style.border = '0' |
| 64 | document.body.append(container) |
| 65 | } |