aria-ease 1.3.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/Types.d.ts +7 -1
- package/aria-ease.d.ts +20 -6
- package/index.js +3 -1
- package/package.json +1 -1
- package/src/checkbox/updateCheckboxAriaAttributes.js +1 -0
- package/src/checkbox/updateCheckboxAriaAttributes.ts +1 -1
- package/src/handleKeyPress.ts +0 -1
- package/src/menu/makeMenuAccessible.js +2 -2
- package/src/menu/makeMenuAccessible.ts +8 -7
- package/src/radio/updateRadioAriaAttributes.js +23 -0
- package/src/radio/updateRadioAriaAttributes.ts +27 -0
package/README.md
CHANGED
|
@@ -10,9 +10,11 @@ Out of the box accessibility utility package to develop production ready applica
|
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
|
+
The package currently has support for 5 components: accordions, blocks, checkboxes, menus, radio buttons
|
|
14
|
+
|
|
13
15
|
Add accessibility to menu: menu can be a dropdown, side menu, slide navigation e.t.c. Basically any component that toggles display and has a list of interactive children items. The function creates a focus trap within the menu and focus can be navigated using the arrow keys. The escape key also closes the menu and returns the focus back to the trigger.
|
|
14
16
|
|
|
15
|
-
The makeMenuAccessible function takes
|
|
17
|
+
The makeMenuAccessible function takes two string arguments; the id of the menu, the class name of the children item of the menu. And should only be invoked after the menu has become visible or added to the DOM. When the menu is visible the first item of the menu is in focus and focus can be navigated using the arrow keys
|
|
16
18
|
|
|
17
19
|
The updateMenuTriggerAriaAttributes function take two string arguments; the id of the menu trigger, and the aria-label that will replace the current one in the DOM. Behind the scene the aria-expanded and aria-attributes are also updated based on the visibility of the menu.
|
|
18
20
|
|
|
@@ -28,12 +30,12 @@ const MenuExample = () => {
|
|
|
28
30
|
const menu = document.querySelector('#custom-menu');
|
|
29
31
|
if (getComputedStyle(menu).display === 'none') {
|
|
30
32
|
menu.style.display = 'block';
|
|
31
|
-
makeMenuAccessible('custom-menu', 'profile-menu-item'
|
|
32
|
-
updateMenuTriggerAriaAttributes('display-button', '
|
|
33
|
+
makeMenuAccessible('custom-menu', 'profile-menu-item');
|
|
34
|
+
updateMenuTriggerAriaAttributes('display-button', 'Close profile menu');
|
|
33
35
|
} else {
|
|
34
36
|
cleanUpMenuEventListeners('custom-menu', 'profile-menu-item');
|
|
35
37
|
menu.style.display = 'none';
|
|
36
|
-
updateMenuTriggerAriaAttributes('display-button', '
|
|
38
|
+
updateMenuTriggerAriaAttributes('display-button', 'Close profile menu');
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
};
|
|
@@ -77,9 +79,8 @@ import { makeBlockAccessible } from "aria-ease"
|
|
|
77
79
|
|
|
78
80
|
const BlockExample = () => {
|
|
79
81
|
useEffect(() => {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
return cleanUp
|
|
82
|
+
const accessibleBlock = makeBlockAccessible('custom-tab', 'custom-tab-item');
|
|
83
|
+
return accessibleBlock;
|
|
83
84
|
},[])
|
|
84
85
|
|
|
85
86
|
return (
|
package/Types.d.ts
CHANGED
|
@@ -15,10 +15,16 @@ interface CheckboxStates {
|
|
|
15
15
|
uncheckedAriaLabel: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
interface RadioStates {
|
|
19
|
+
checked: boolean;
|
|
20
|
+
checkedAriaLabel: string;
|
|
21
|
+
uncheckedAriaLabel: string;
|
|
22
|
+
}
|
|
18
23
|
|
|
19
24
|
export {
|
|
20
25
|
HTMLElement,
|
|
21
26
|
NodeListOfHTMLElement,
|
|
22
27
|
AccordionStates,
|
|
23
|
-
CheckboxStates
|
|
28
|
+
CheckboxStates,
|
|
29
|
+
RadioStates
|
|
24
30
|
};
|
package/aria-ease.d.ts
CHANGED
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
* Declares the module 'aria-ease' and includes type information and JSDoc comments.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { AccordionStates, CheckboxStates } from "./Types";
|
|
5
|
+
import { AccordionStates, CheckboxStates, RadioStates } from "./Types";
|
|
6
6
|
|
|
7
7
|
declare module 'aria-ease' {
|
|
8
8
|
/**
|
|
9
9
|
* Adds keyboard interaction to toggle menu. The menu traps focus and can be interacted with using the keyboard. The first item of the menu has focus when menu appears.
|
|
10
10
|
* @param {string} menuId - The id of the menu.
|
|
11
11
|
* @param {string} menuItemClass - The class of the items that are children of the menu.
|
|
12
|
-
* @param {string} menuClosedStateAriaLabel The aria label for when the menu is closed and not displayed
|
|
13
12
|
*/
|
|
14
|
-
function makeMenuAccessible(menuId: string, menuItemClass: string
|
|
13
|
+
function makeMenuAccessible(menuId: string, menuItemClass: string): void;
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
|
|
@@ -49,7 +48,22 @@ declare module 'aria-ease' {
|
|
|
49
48
|
* @param {number} currentPressedCheckboxIndex Index of the currently checked or unchecked checkbox
|
|
50
49
|
*/
|
|
51
50
|
function updateCheckboxAriaAttributes(checkboxStates: CheckboxStates[], checkboxesClass: string, currentPressedCheckboxIndex: number): void;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Adds screen reader accessibility to radio buttons. Updates the aria attributes of the radio button. Radio element must possess the following aria attributes; aria-checked and aria-label.
|
|
54
|
+
* @param {RadioStates[]} radioStates Array of objects containing radio buttons state information
|
|
55
|
+
* @param {string} radiosClass The shared class of all the radio buttons
|
|
56
|
+
* @param {number} currentPressedRadioIndex Index of the currently checked or unchecked radio button
|
|
57
|
+
*/
|
|
58
|
+
function updateRadioAriaAttributes(radioStates: RadioStates[], radiosClass: string, currentPressedRadioIndex: number): void;
|
|
52
59
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
export {
|
|
61
|
+
makeMenuAccessible,
|
|
62
|
+
makeBlockAccessible,
|
|
63
|
+
updateMenuTriggerAriaAttributes,
|
|
64
|
+
cleanUpMenuEventListeners,
|
|
65
|
+
updateAccordionTriggerAriaAttributes,
|
|
66
|
+
updateCheckboxAriaAttributes,
|
|
67
|
+
updateRadioAriaAttributes
|
|
68
|
+
};
|
|
69
|
+
}
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { updateMenuTriggerAriaAttributes } from './src/menu/updateMenuTriggerAri
|
|
|
4
4
|
import { cleanUpMenuEventListeners } from './src/menu/cleanUpMenuEventListeners.js'
|
|
5
5
|
import { updateAccordionTriggerAriaAttributes } from './src/accordion/updateAccordionTriggerAriaAttributes.js'
|
|
6
6
|
import { updateCheckboxAriaAttributes } from './src/checkbox/updateCheckboxAriaAttributes.js'
|
|
7
|
+
import { updateRadioAriaAttributes } from './src/radio/updateRadioAriaAttributes.js'
|
|
7
8
|
|
|
8
9
|
export {
|
|
9
10
|
makeMenuAccessible,
|
|
@@ -11,5 +12,6 @@ export {
|
|
|
11
12
|
updateMenuTriggerAriaAttributes,
|
|
12
13
|
cleanUpMenuEventListeners,
|
|
13
14
|
updateAccordionTriggerAriaAttributes,
|
|
14
|
-
updateCheckboxAriaAttributes
|
|
15
|
+
updateCheckboxAriaAttributes,
|
|
16
|
+
updateRadioAriaAttributes
|
|
15
17
|
}
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ export function updateCheckboxAriaAttributes(checkboxStates, checkboxesClass, cu
|
|
|
9
9
|
if (!allCheckboxes) {
|
|
10
10
|
throw new Error('Invalid checkboxes class provided.');
|
|
11
11
|
}
|
|
12
|
+
;
|
|
12
13
|
allCheckboxes.forEach(function (checkbox, index) {
|
|
13
14
|
if (index === currentPressedCheckboxIndex) {
|
|
14
15
|
checkbox.setAttribute("aria-checked", checkboxStates[index].checked ? 'true' : 'false');
|
|
@@ -12,7 +12,7 @@ export function updateCheckboxAriaAttributes(checkboxStates: CheckboxStates[], c
|
|
|
12
12
|
|
|
13
13
|
if ( !allCheckboxes) {
|
|
14
14
|
throw new Error('Invalid checkboxes class provided.');
|
|
15
|
-
}
|
|
15
|
+
};
|
|
16
16
|
|
|
17
17
|
allCheckboxes.forEach((checkbox, index) => {
|
|
18
18
|
if (index === currentPressedCheckboxIndex) {
|
package/src/handleKeyPress.ts
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Adds keyboard interaction to toggle menu. The menu traps focus and can be interacted with using the keyboard. The first item of the menu has focus when menu appears.
|
|
3
3
|
* @param {string} menuId The id of the menu
|
|
4
4
|
* @param {string} menuItemClass The shared class of the items that are children of the menu
|
|
5
|
-
* @param {string} menuClosedStateAriaLabel The aria label for when the menu is closed and not displayed
|
|
6
5
|
*/
|
|
7
6
|
import { handleKeyPress } from '../handleKeyPress';
|
|
8
7
|
var eventListenersAdded = new Set();
|
|
9
|
-
export function makeMenuAccessible(menuId, menuItemClass
|
|
8
|
+
export function makeMenuAccessible(menuId, menuItemClass) {
|
|
10
9
|
var menuDiv = document.querySelector("#".concat(menuId));
|
|
11
10
|
var menuItems = menuDiv.querySelectorAll(".".concat(menuItemClass));
|
|
12
11
|
var triggerId = menuDiv.getAttribute('aria-labelledby');
|
|
13
12
|
var triggerButton = document.querySelector("#".concat(triggerId));
|
|
13
|
+
var menuClosedStateAriaLabel = triggerButton.getAttribute('aria-label');
|
|
14
14
|
menuItems.item(0).focus();
|
|
15
15
|
menuItems.forEach(function (menuItem, menuItemIndex) {
|
|
16
16
|
if (!eventListenersAdded.has(menuItem)) {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Adds keyboard interaction to toggle menu. The menu traps focus and can be interacted with using the keyboard. The first item of the menu has focus when menu appears.
|
|
3
3
|
* @param {string} menuId The id of the menu
|
|
4
4
|
* @param {string} menuItemClass The shared class of the items that are children of the menu
|
|
5
|
-
* @param {string} menuClosedStateAriaLabel The aria label for when the menu is closed and not displayed
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
7
|
import { HTMLElement, NodeListOfHTMLElement } from '../../Types'
|
|
@@ -10,18 +9,20 @@ import { handleKeyPress } from '../handleKeyPress';
|
|
|
10
9
|
|
|
11
10
|
let eventListenersAdded: Set<HTMLElement> = new Set();
|
|
12
11
|
|
|
13
|
-
export function makeMenuAccessible(menuId: string, menuItemClass: string
|
|
14
|
-
const menuDiv: HTMLElement = document.querySelector(`#${menuId}`) as HTMLElement
|
|
15
|
-
const menuItems: NodeListOfHTMLElement = menuDiv.querySelectorAll(`.${menuItemClass}`)
|
|
12
|
+
export function makeMenuAccessible(menuId: string, menuItemClass: string): void {
|
|
13
|
+
const menuDiv: HTMLElement = document.querySelector(`#${menuId}`) as HTMLElement;
|
|
14
|
+
const menuItems: NodeListOfHTMLElement = menuDiv.querySelectorAll(`.${menuItemClass}`);
|
|
16
15
|
|
|
17
|
-
const triggerId: string = menuDiv.getAttribute('aria-labelledby') as string
|
|
18
|
-
const triggerButton: HTMLElement = document.querySelector(`#${triggerId}`) as HTMLElement
|
|
16
|
+
const triggerId: string = menuDiv.getAttribute('aria-labelledby') as string;
|
|
17
|
+
const triggerButton: HTMLElement = document.querySelector(`#${triggerId}`) as HTMLElement;
|
|
18
|
+
|
|
19
|
+
const menuClosedStateAriaLabel: string = triggerButton.getAttribute('aria-label') as string;
|
|
19
20
|
|
|
20
21
|
menuItems.item(0).focus();
|
|
21
22
|
menuItems.forEach((menuItem: HTMLElement, menuItemIndex: number): void => {
|
|
22
23
|
if (!eventListenersAdded.has(menuItem)) {
|
|
23
24
|
eventListenersAdded.add(menuItem);
|
|
24
|
-
menuItem.addEventListener('keydown', (event: KeyboardEvent): void => handleKeyPress(event, menuItems, menuItemIndex, menuDiv, triggerButton, menuClosedStateAriaLabel))
|
|
25
|
+
menuItem.addEventListener('keydown', (event: KeyboardEvent): void => handleKeyPress(event, menuItems, menuItemIndex, menuDiv, triggerButton, menuClosedStateAriaLabel));
|
|
25
26
|
}
|
|
26
27
|
})
|
|
27
28
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds screen reader accessibility to radio buttons. Updates the aria attributes of the radio button. Radio element must possess the following aria attributes; aria-checked and aria-label.
|
|
3
|
+
* @param {RadioStates[]} radioStates Array of objects containing radio buttons state information
|
|
4
|
+
* @param {string} radiosClass The shared class of all the radio buttons
|
|
5
|
+
* @param {number} currentPressedRadioIndex Index of the currently checked or unchecked radio button
|
|
6
|
+
*/
|
|
7
|
+
export function updateRadioAriaAttributes(radioStates, radiosClass, currentPressedRadioIndex) {
|
|
8
|
+
var allRadios = Array.from(document.querySelectorAll(".".concat(radiosClass)));
|
|
9
|
+
if (!allRadios) {
|
|
10
|
+
throw new Error('Invalid radios class provided.');
|
|
11
|
+
}
|
|
12
|
+
allRadios.forEach(function (radio, index) {
|
|
13
|
+
if (index === currentPressedRadioIndex) {
|
|
14
|
+
radio.setAttribute("aria-checked", radioStates[index].checked ? 'true' : 'false');
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
if (radio.getAttribute("aria-checked") === "true") {
|
|
18
|
+
radio.setAttribute("aria-checked", 'false');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
radio.setAttribute("aria-label", radioStates[index].checked ? radioStates[index].checkedAriaLabel : radioStates[index].uncheckedAriaLabel);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds screen reader accessibility to radio buttons. Updates the aria attributes of the radio button. Radio element must possess the following aria attributes; aria-checked and aria-label.
|
|
3
|
+
* @param {RadioStates[]} radioStates Array of objects containing radio buttons state information
|
|
4
|
+
* @param {string} radiosClass The shared class of all the radio buttons
|
|
5
|
+
* @param {number} currentPressedRadioIndex Index of the currently checked or unchecked radio button
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { HTMLElement, RadioStates } from "../../Types";
|
|
9
|
+
|
|
10
|
+
export function updateRadioAriaAttributes(radioStates: RadioStates[], radiosClass: string, currentPressedRadioIndex: number): void {
|
|
11
|
+
const allRadios: HTMLElement[] = Array.from(document.querySelectorAll(`.${radiosClass}`));
|
|
12
|
+
|
|
13
|
+
if ( !allRadios) {
|
|
14
|
+
throw new Error('Invalid radios class provided.');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
allRadios.forEach((radio, index) => {
|
|
18
|
+
if (index === currentPressedRadioIndex) {
|
|
19
|
+
radio.setAttribute("aria-checked", radioStates[index].checked ? 'true' : 'false');
|
|
20
|
+
} else {
|
|
21
|
+
if(radio.getAttribute("aria-checked") === "true") {
|
|
22
|
+
radio.setAttribute("aria-checked", 'false');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
radio.setAttribute("aria-label", radioStates[index].checked ? radioStates[index].checkedAriaLabel : radioStates[index].uncheckedAriaLabel);
|
|
26
|
+
});
|
|
27
|
+
}
|