-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
69 lines (53 loc) · 2.02 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
type Assertiveness = 'polite' | 'assertive';
const TAG_NAME = 'live-announcer';
const POLITE = 'polite';
const ASSERTIVE = 'assertive';
const CLEAR_MESSAGE_TIMEOUT = 100;
const INVISIBLE_CHARACTER = '\u00A0';
class HTMLLiveAnnouncerElement extends HTMLElement {
private _assertiveness: Assertiveness;
private _previousMessage: string;
connectedCallback() {
this.className = 'screen-reader-text';
this.innerHTML = '<p aria-live="polite"></p><p aria-live="assertive"></p>';
}
set assertiveness(assertiveness: Assertiveness) {
this._assertiveness = assertiveness;
}
set message(message: string) {
const ariaLiveElement = <HTMLParagraphElement>this.querySelector(`p[aria-live="${this._assertiveness}"]`);
ariaLiveElement.textContent = ''; // Clear to announce repeated messages.
if (this._previousMessage === message) {
message += INVISIBLE_CHARACTER; // Add non-breaking space invisble character, since VoiceOver doesn't announce repeated messages otherwise.
}
this._previousMessage = message;
setTimeout(() => ariaLiveElement.textContent = message, CLEAR_MESSAGE_TIMEOUT);
}
}
const announce = (message: string, assertiveness: Assertiveness = POLITE, elementName = '') => {
const announcerInstance = createInstance(elementName);
announcerInstance.assertiveness = assertiveness;
announcerInstance.message = message;
};
const createInstance = (elementName = ''): HTMLLiveAnnouncerElement => {
const tagName = elementName.length ? elementName : TAG_NAME;
let announcerInstance = <HTMLLiveAnnouncerElement>document.querySelector(tagName);
if (!announcerInstance) {
announcerInstance = <HTMLLiveAnnouncerElement>document.createElement(tagName);
document.body.prepend(announcerInstance);
}
return announcerInstance;
};
if (!customElements.get(TAG_NAME)) {
customElements.define(TAG_NAME, HTMLLiveAnnouncerElement);
}
export {
announce,
createInstance,
POLITE,
ASSERTIVE,
CLEAR_MESSAGE_TIMEOUT,
INVISIBLE_CHARACTER,
HTMLLiveAnnouncerElement,
Assertiveness
};