UNPKG

drab

Version:

Interactivity for You

83 lines (82 loc) 3.17 kB
import { define } from "../util/define.js"; /** * Use the `Announcer` element to create a visually hidden ARIA live region * that announces content changes to screen readers. Use this element when you * need to announce changes to screen readers that something has changed. If changed * element is visible on the page, add the appropriate ARIA live attribute to the * visible element instead of using this announcer. * * It's recommended to create this element with JavaScript using the `Announcer.init` method, * then you can reuse the same announcer throughout the application to * [avoid duplicate regions](https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-2/#limit-the-number-of-live-regions-on-the-page) * (see below). * * ### Attributes * * `aria-live` * * By default, the announcer is created with the * [`polite` ARIA live attribute](https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-1/#1.-using-the-aria-live-attribute). * * @example * * ```ts * import { Announcer } from "drab/announcer"; * * // creates and appends a new announcer to the body element * const announcer = Announcer.init(); * * // create announcement * announcer.announce("message"); * ``` * * > The `Base` element creates a single `Announcer` to share between all elements * > that can be accessed through `this.announce`. If you are using one of drab's other * > elements you can call `announce` directly on the element to announce changes. */ export class Announcer extends HTMLElement { constructor() { super(); } connectedCallback() { this.style.position = "absolute"; this.style.width = "1px"; this.style.height = "1px"; this.style.padding = "0"; this.style.margin = "-1px"; this.style.overflow = "hidden"; this.style.clipPath = "rect(0, 0, 0, 0)"; this.style.whiteSpace = "nowrap"; this.style.borderWidth = "0"; if (!this.ariaLive) this.ariaLive = "polite"; } /** * @param message message to announce to screen readers */ announce(message) { // this ensures multiple messages will be read in succession const span = document.createElement("span"); span.textContent = message; this.append(span); // https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-2/#empty-the-live-region-and-wait-a-bit-in-between-updates setTimeout(() => span.remove(), 10000); } /** * Helper method to create a new `Announcer` element named `drab-announcer` * and append the element to the `<body>` tag. If an announcer already exists * on the page it will return the existing element. * * @returns the created or existing `Announcer` element */ static init() { const name = "drab-announcer"; define(name, this); let announcer = document.querySelector(name); if (!announcer) { announcer = document.createElement(name); document.body.append(announcer); } return announcer; } }