aria-ease 1.2.3 → 1.2.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Aria-Ease
2
2
 
3
- Out of the box accessibility utility package to develop production ready packages.
3
+ Out of the box accessibility utility package to develop production ready applications.
4
4
 
5
5
  ## Install
6
6
 
@@ -57,19 +57,19 @@ const App = () => {
57
57
  export default App
58
58
  ```
59
59
 
60
- Add accessibility to tab: tab can be tabs, interactive sliders and carousels e.t.c. Basically any component that is permanently displayed and has a list of related interractive children items. The function creates a focus trap within the tab and the focus can be navigated using the arrow keys.
60
+ Add accessibility to block: block can be entire web page body, tabs, interactive sliders and carousels e.t.c. Basically any component that is permanently displayed and has a list of related interractive children items. The function creates a focus trap within the block and the focus can be navigated using the arrow keys.
61
61
 
62
- The makeTabAccessible function takes two string arguments; the id of the tab main div, and the class name of the children item of the div. The function should be called on page render, so the event listeners get activated. On click of a button, the clicked button gets focused and the focus can be navigated using the arrow keys.
62
+ The makeBlockAccessible function takes two string arguments; the id of the block main div, and the class name of the children item of the div. The function should be called on page render, so the event listeners get activated. On click of a button, the clicked button gets focused and the focus can be navigated using the arrow keys.
63
63
 
64
64
  #### Usage
65
65
 
66
66
  ```
67
67
  import { useEffect } from 'react'
68
- import { makeTabAccessible } from "aria-ease"
68
+ import { makeBlockAccessible } from "aria-ease"
69
69
 
70
70
  const App = () => {
71
71
  useEffect(() => {
72
- makeTabAccessible('custom-tab', 'custom-tab-item')
72
+ makeBlockAccessible('custom-tab', 'custom-tab-item')
73
73
  },[])
74
74
 
75
75
  return (
package/aria-ease.d.ts CHANGED
@@ -10,11 +10,11 @@ declare module 'aria-ease' {
10
10
  function makeMenuAccessible(menuId: string, menuItemClass: string): void;
11
11
 
12
12
  /**
13
- * Adds keyboard interaction to tab. The tab traps focus and can be interacted with using the keyboard.
14
- * @param {string} tabId - The id of the tab container.
15
- * @param {string} tabItemClass - The class of the individual tab items.
13
+ * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
14
+ * @param {string} blockId - The id of the block container.
15
+ * @param {string} blockItemClass - The class of the individual block items.
16
16
  */
17
- function makeTabAccessible(tabId: string, tabItemClass: string): void;
17
+ function makeBlockAccessible(blockId: string, blockItemClass: string): void;
18
18
 
19
19
  /**
20
20
  * Updates the aria attributes of the menu trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-pressed, aria-label.
@@ -22,7 +22,14 @@ declare module 'aria-ease' {
22
22
  * @param {string} ariaLabel The aria-label to be updated.
23
23
  */
24
24
  function updateMenuTriggerAriaAttributes(triggerId: string, ariaLabel: string): void;
25
+
26
+ /**
27
+ * Cleans up the event listeners that were added to childen items of the menu, to prevent memory leak.
28
+ * @param {string} menuId The id of the menu
29
+ * @param {string} menuItemClass The class of the items that are children of the menu
30
+ */
31
+ function cleanUpMenuEventListeners(menuId: string, menuItemClass: string): void;
25
32
 
26
- export { makeMenuAccessible, makeTabAccessible, updateMenuTriggerAriaAttributes };
33
+ export { makeMenuAccessible, makeBlockAccessible, updateMenuTriggerAriaAttributes, cleanUpMenuEventListeners };
27
34
  }
28
35
 
package/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { makeMenuAccessible } from './src/menu/makeMenuAccessible.js'
2
- import { makeTabAccessible } from './src/tab/makeTabAccessible.js'
2
+ import { makeBlockAccessible } from './src/block/makeBlockAccessible.js'
3
3
  import { updateMenuTriggerAriaAttributes } from './src/menu/updateMenuTriggerAriaAttributes.js'
4
+ import { cleanUpMenuEventListeners } from './src/menu/cleanUpMenuEventListeners.js'
4
5
 
5
6
  export {
6
7
  makeMenuAccessible,
7
- makeTabAccessible,
8
- updateMenuTriggerAriaAttributes
8
+ makeBlockAccessible,
9
+ updateMenuTriggerAriaAttributes,
10
+ cleanUpMenuEventListeners
9
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aria-ease",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "Out of the box utility accessibility package to develop production ready applications.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
3
+ * @param {string} blockId The id of the block
4
+ * @param {string} blockItemClass The class of the items that are children of the block
5
+ */
6
+ import { handleKeyPress } from '../handleKeyPress';
7
+ var eventListenersAdded = new Set();
8
+ export function makeBlockAccessible(blockId, blockItemClass) {
9
+ var blockDiv = document.querySelector("#".concat(blockId));
10
+ var blockItems = blockDiv.querySelectorAll(".".concat(blockItemClass));
11
+ blockItems.forEach(function (blockItem, blockItemIndex) {
12
+ if (!eventListenersAdded.has(blockItem)) {
13
+ eventListenersAdded.add(blockItem);
14
+ blockItem.addEventListener('keydown', function (event) { return handleKeyPress(event, blockItems, blockItemIndex); });
15
+ }
16
+ });
17
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
3
+ * @param {string} blockId The id of the block
4
+ * @param {string} blockItemClass The class of the items that are children of the block
5
+ */
6
+
7
+ import { HTMLElement, NodeListOfHTMLElement } from "../../Types"
8
+ import { handleKeyPress } from '../handleKeyPress';
9
+
10
+ let eventListenersAdded: Set<HTMLElement> = new Set();
11
+
12
+ export function makeBlockAccessible(blockId: string, blockItemClass: string): void {
13
+ const blockDiv: HTMLElement = document.querySelector(`#${blockId}`) as HTMLElement
14
+ const blockItems: NodeListOfHTMLElement = blockDiv.querySelectorAll(`.${blockItemClass}`)
15
+
16
+ blockItems.forEach((blockItem: HTMLElement, blockItemIndex: number): void => {
17
+ if (!eventListenersAdded.has(blockItem)) {
18
+ eventListenersAdded.add(blockItem);
19
+ blockItem.addEventListener('keydown', (event: KeyboardEvent) => handleKeyPress(event, blockItems, blockItemIndex));
20
+ }
21
+ });
22
+
23
+ }
@@ -0,0 +1,55 @@
1
+ export function handleKeyPress(event, elementItems, elementItemIndex, elementDiv, triggerButton) {
2
+ switch (event.key) {
3
+ case 'ArrowUp':
4
+ case 'ArrowLeft':
5
+ event.preventDefault();
6
+ if (elementItemIndex === 0) {
7
+ elementItems.item(elementItems.length - 1).focus();
8
+ }
9
+ else {
10
+ elementItems.item(elementItemIndex - 1).focus();
11
+ }
12
+ break;
13
+ case 'ArrowDown':
14
+ case 'ArrowRight':
15
+ event.preventDefault();
16
+ if (elementItemIndex === elementItems.length - 1) {
17
+ elementItems.item(0).focus();
18
+ }
19
+ else {
20
+ elementItems.item(elementItemIndex + 1).focus();
21
+ }
22
+ break;
23
+ case 'Escape':
24
+ event.preventDefault();
25
+ if (elementDiv && triggerButton) {
26
+ (getComputedStyle(elementDiv).display === 'block') ?
27
+ triggerButton.click() :
28
+ null;
29
+ triggerButton.focus();
30
+ }
31
+ break;
32
+ case 'Enter':
33
+ case ' ':
34
+ event.preventDefault();
35
+ if (elementItems.item(elementItemIndex).tagName === 'BUTTON') {
36
+ elementItems.item(elementItemIndex).click();
37
+ break;
38
+ }
39
+ else if (elementItems.item(elementItemIndex).tagName === 'A') {
40
+ window.location.href = elementItems.item(elementItemIndex).href;
41
+ break;
42
+ }
43
+ else if (elementItems.item(elementItemIndex).type === 'radio') {
44
+ elementItems.item(elementItemIndex).checked = true;
45
+ break;
46
+ }
47
+ else if (elementItems.item(elementItemIndex).type === 'checkbox') {
48
+ elementItems.item(elementItemIndex).checked = !elementItems.item(elementItemIndex).checked;
49
+ break;
50
+ }
51
+ break;
52
+ default:
53
+ break;
54
+ }
55
+ }
@@ -0,0 +1,53 @@
1
+ import { NodeListOfHTMLElement, HTMLElement } from "../Types";
2
+
3
+ export function handleKeyPress(event: KeyboardEvent, elementItems: NodeListOfHTMLElement, elementItemIndex: number, elementDiv?: HTMLElement | undefined, triggerButton?: HTMLElement | undefined): void {
4
+ switch(event.key) {
5
+ case 'ArrowUp':
6
+ case 'ArrowLeft':
7
+ event.preventDefault()
8
+ if (elementItemIndex === 0) {
9
+ elementItems.item(elementItems.length - 1).focus();
10
+ } else {
11
+ elementItems.item(elementItemIndex - 1).focus();
12
+ }
13
+ break;
14
+ case 'ArrowDown':
15
+ case 'ArrowRight':
16
+ event.preventDefault()
17
+ if (elementItemIndex === elementItems.length - 1) {
18
+ elementItems.item(0).focus();
19
+ } else {
20
+ elementItems.item(elementItemIndex + 1).focus();
21
+ }
22
+ break;
23
+ case 'Escape':
24
+ event.preventDefault();
25
+ if(elementDiv && triggerButton) {
26
+ (getComputedStyle(elementDiv).display === 'block') ?
27
+ triggerButton.click() :
28
+ null
29
+ triggerButton.focus()
30
+ }
31
+
32
+ break;
33
+ case 'Enter':
34
+ case ' ':
35
+ event.preventDefault()
36
+ if(elementItems.item(elementItemIndex).tagName === 'BUTTON') {
37
+ elementItems.item(elementItemIndex).click()
38
+ break;
39
+ } else if (elementItems.item(elementItemIndex).tagName === 'A') {
40
+ window.location.href = elementItems.item(elementItemIndex).href;
41
+ break;
42
+ } else if (elementItems.item(elementItemIndex).type === 'radio') {
43
+ elementItems.item(elementItemIndex).checked = true
44
+ break;
45
+ } else if (elementItems.item(elementItemIndex).type === 'checkbox') {
46
+ elementItems.item(elementItemIndex).checked = !elementItems.item(elementItemIndex).checked
47
+ break;
48
+ }
49
+ break;
50
+ default:
51
+ break;
52
+ }
53
+ }
@@ -0,0 +1,10 @@
1
+ import { handleKeyPress } from "../handleKeyPress";
2
+ export function cleanUpMenuEventListeners(menuId, menuItemClass) {
3
+ var menuDiv = document.querySelector("#".concat(menuId));
4
+ var menuItems = menuDiv.querySelectorAll(".".concat(menuItemClass));
5
+ var triggerId = menuDiv.getAttribute('aria-labelledby');
6
+ var triggerButton = document.querySelector("#".concat(triggerId));
7
+ menuItems.forEach(function (menuItem, menuItemIndex) {
8
+ menuItem.removeEventListener('keydown', function (event) { return handleKeyPress(event, menuItems, menuItemIndex, menuDiv, triggerButton); });
9
+ });
10
+ }
@@ -0,0 +1,15 @@
1
+ import { NodeListOfHTMLElement } from "../../Types"
2
+ import { handleKeyPress } from "../handleKeyPress"
3
+
4
+
5
+ export function cleanUpMenuEventListeners(menuId: string, menuItemClass: string): void {
6
+ const menuDiv: HTMLElement = document.querySelector(`#${menuId}`) as HTMLElement
7
+ const menuItems: NodeListOfHTMLElement = menuDiv.querySelectorAll(`.${menuItemClass}`)
8
+
9
+ const triggerId: string = menuDiv.getAttribute('aria-labelledby') as string
10
+ const triggerButton: HTMLElement = document.querySelector(`#${triggerId}`) as HTMLElement
11
+
12
+ menuItems.forEach((menuItem: HTMLElement, menuItemIndex: number): void => {
13
+ menuItem.removeEventListener('keydown', (event: KeyboardEvent): void => handleKeyPress(event, menuItems, menuItemIndex, menuDiv, triggerButton));
14
+ })
15
+ }
@@ -3,6 +3,7 @@
3
3
  * @param {string} menuId The id of the menu
4
4
  * @param {string} menuItemClass The class of the items that are children of the menu
5
5
  */
6
+ import { handleKeyPress } from '../handleKeyPress';
6
7
  var eventListenersAdded = new Set();
7
8
  export function makeMenuAccessible(menuId, menuItemClass) {
8
9
  var menuDiv = document.querySelector("#".concat(menuId));
@@ -13,60 +14,7 @@ export function makeMenuAccessible(menuId, menuItemClass) {
13
14
  menuItems.forEach(function (menuItem, menuItemIndex) {
14
15
  if (!eventListenersAdded.has(menuItem)) {
15
16
  eventListenersAdded.add(menuItem);
16
- menuItem.addEventListener('keydown', function (event) { return handleKeyPress(event, menuItems, menuItemIndex); });
17
+ menuItem.addEventListener('keydown', function (event) { return handleKeyPress(event, menuItems, menuItemIndex, menuDiv, triggerButton); });
17
18
  }
18
19
  });
19
- function handleKeyPress(event, menuItems, menuItemIndex) {
20
- switch (event.key) {
21
- case 'ArrowUp':
22
- case 'ArrowLeft':
23
- event.preventDefault();
24
- if (menuItemIndex === 0) {
25
- menuItems.item(menuItems.length - 1).focus();
26
- }
27
- else {
28
- menuItems.item(menuItemIndex - 1).focus();
29
- }
30
- break;
31
- case 'ArrowDown':
32
- case 'ArrowRight':
33
- event.preventDefault();
34
- if (menuItemIndex === menuItems.length - 1) {
35
- menuItems.item(0).focus();
36
- }
37
- else {
38
- menuItems.item(menuItemIndex + 1).focus();
39
- }
40
- break;
41
- case 'Escape':
42
- event.preventDefault();
43
- (getComputedStyle(menuDiv).display === 'block') ?
44
- triggerButton.click() :
45
- null;
46
- triggerButton.focus();
47
- break;
48
- case 'Enter':
49
- case ' ':
50
- event.preventDefault();
51
- if (menuItems.item(menuItemIndex).tagName === 'BUTTON') {
52
- menuItems.item(menuItemIndex).click();
53
- break;
54
- }
55
- else if (menuItems.item(menuItemIndex).tagName === 'A') {
56
- window.location.href = menuItems.item(menuItemIndex).href;
57
- break;
58
- }
59
- else if (menuItems.item(menuItemIndex).type === 'radio') {
60
- menuItems.item(menuItemIndex).checked = true;
61
- break;
62
- }
63
- else if (menuItems.item(menuItemIndex).type === 'checkbox') {
64
- menuItems.item(menuItemIndex).checked = !menuItems.item(menuItemIndex).checked;
65
- break;
66
- }
67
- break;
68
- default:
69
- break;
70
- }
71
- }
72
20
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { HTMLElement, NodeListOfHTMLElement } from '../../Types'
8
+ import { handleKeyPress } from '../handleKeyPress';
8
9
 
9
10
  let eventListenersAdded: Set<HTMLElement> = new Set();
10
11
 
@@ -19,56 +20,7 @@ export function makeMenuAccessible(menuId: string, menuItemClass: string): void
19
20
  menuItems.forEach((menuItem: HTMLElement, menuItemIndex: number): void => {
20
21
  if (!eventListenersAdded.has(menuItem)) {
21
22
  eventListenersAdded.add(menuItem);
22
- menuItem.addEventListener('keydown', (event: KeyboardEvent): void => handleKeyPress(event, menuItems, menuItemIndex))
23
+ menuItem.addEventListener('keydown', (event: KeyboardEvent): void => handleKeyPress(event, menuItems, menuItemIndex, menuDiv, triggerButton))
23
24
  }
24
25
  })
25
-
26
- function handleKeyPress(event: KeyboardEvent, menuItems: NodeListOfHTMLElement, menuItemIndex: number): void {
27
- switch(event.key) {
28
- case 'ArrowUp':
29
- case 'ArrowLeft':
30
- event.preventDefault()
31
- if (menuItemIndex === 0) {
32
- menuItems.item(menuItems.length - 1).focus();
33
- } else {
34
- menuItems.item(menuItemIndex - 1).focus();
35
- }
36
- break;
37
- case 'ArrowDown':
38
- case 'ArrowRight':
39
- event.preventDefault()
40
- if (menuItemIndex === menuItems.length - 1) {
41
- menuItems.item(0).focus();
42
- } else {
43
- menuItems.item(menuItemIndex + 1).focus();
44
- }
45
- break;
46
- case 'Escape':
47
- event.preventDefault();
48
- (getComputedStyle(menuDiv).display === 'block') ?
49
- triggerButton.click() :
50
- null
51
- triggerButton.focus()
52
- break;
53
- case 'Enter':
54
- case ' ':
55
- event.preventDefault()
56
- if(menuItems.item(menuItemIndex).tagName === 'BUTTON') {
57
- menuItems.item(menuItemIndex).click()
58
- break;
59
- } else if (menuItems.item(menuItemIndex).tagName === 'A') {
60
- window.location.href = menuItems.item(menuItemIndex).href;
61
- break;
62
- } else if (menuItems.item(menuItemIndex).type === 'radio') {
63
- menuItems.item(menuItemIndex).checked = true
64
- break;
65
- } else if (menuItems.item(menuItemIndex).type === 'checkbox') {
66
- menuItems.item(menuItemIndex).checked = !menuItems.item(menuItemIndex).checked
67
- break;
68
- }
69
- break;
70
- default:
71
- break;
72
- }
73
- }
74
26
  }
@@ -1,62 +0,0 @@
1
- /**
2
- * Adds keyboard interaction to tab. The tab traps focus and can be interacted with using the keyboard.
3
- * @param {string} tabId The id of the tab
4
- * @param {string} tabItemClass The class of the items that are children of the tab
5
- */
6
- var eventListenersAdded = new Set();
7
- export function makeTabAccessible(tabId, tabItemClass) {
8
- var tabDiv = document.querySelector("#".concat(tabId));
9
- var tabItems = tabDiv.querySelectorAll(".".concat(tabItemClass));
10
- tabItems.forEach(function (tabItem, tabItemIndex) {
11
- if (!eventListenersAdded.has(tabItem)) {
12
- eventListenersAdded.add(tabItem);
13
- tabItem.addEventListener('keydown', function (event) { return handleKeyPress(event, tabItems, tabItemIndex); });
14
- }
15
- });
16
- function handleKeyPress(event, tabItems, tabItemIndex) {
17
- switch (event.key) {
18
- case 'ArrowUp':
19
- case 'ArrowLeft':
20
- event.preventDefault();
21
- if (tabItemIndex === 0) {
22
- tabItems.item(tabItems.length - 1).focus();
23
- }
24
- else {
25
- tabItems.item(tabItemIndex - 1).focus();
26
- }
27
- break;
28
- case 'ArrowDown':
29
- case 'ArrowRight':
30
- event.preventDefault();
31
- if (tabItemIndex === tabItems.length - 1) {
32
- tabItems.item(0).focus();
33
- }
34
- else {
35
- tabItems.item(tabItemIndex + 1).focus();
36
- }
37
- break;
38
- case 'Enter':
39
- case ' ':
40
- event.preventDefault();
41
- if (tabItems.item(tabItemIndex).type === 'radio') {
42
- tabItems.item(tabItemIndex).checked = true;
43
- break;
44
- }
45
- else if (tabItems.item(tabItemIndex).type === 'checkbox') {
46
- tabItems.item(tabItemIndex).checked = !tabItems.item(tabItemIndex).checked;
47
- break;
48
- }
49
- else if (tabItems.item(tabItemIndex).tagName === 'BUTTON') {
50
- tabItems.item(tabItemIndex).click();
51
- break;
52
- }
53
- else if (tabItems.item(tabItemIndex).tagName === 'A') {
54
- window.location.href = tabItems.item(tabItemIndex).href;
55
- break;
56
- }
57
- break;
58
- default:
59
- break;
60
- }
61
- }
62
- }
@@ -1,63 +0,0 @@
1
- /**
2
- * Adds keyboard interaction to tab. The tab traps focus and can be interacted with using the keyboard.
3
- * @param {string} tabId The id of the tab
4
- * @param {string} tabItemClass The class of the items that are children of the tab
5
- */
6
-
7
- import { HTMLElement, NodeListOfHTMLElement } from "../../Types"
8
-
9
- let eventListenersAdded: Set<HTMLElement> = new Set();
10
-
11
- export function makeTabAccessible(tabId: string, tabItemClass: string): void {
12
- const tabDiv: HTMLElement = document.querySelector(`#${tabId}`) as HTMLElement
13
- const tabItems: NodeListOfHTMLElement = tabDiv.querySelectorAll(`.${tabItemClass}`)
14
-
15
- tabItems.forEach((tabItem: HTMLElement, tabItemIndex: number): void => {
16
- if (!eventListenersAdded.has(tabItem)) {
17
- eventListenersAdded.add(tabItem);
18
- tabItem.addEventListener('keydown', (event: KeyboardEvent) => handleKeyPress(event, tabItems, tabItemIndex));
19
- }
20
- });
21
-
22
- function handleKeyPress(event: KeyboardEvent, tabItems: NodeListOfHTMLElement, tabItemIndex: number): void {
23
- switch(event.key) {
24
- case 'ArrowUp':
25
- case 'ArrowLeft':
26
- event.preventDefault()
27
- if (tabItemIndex === 0) {
28
- tabItems.item(tabItems.length - 1).focus();
29
- } else {
30
- tabItems.item(tabItemIndex - 1).focus();
31
- }
32
- break;
33
- case 'ArrowDown':
34
- case 'ArrowRight':
35
- event.preventDefault()
36
- if (tabItemIndex === tabItems.length - 1) {
37
- tabItems.item(0).focus();
38
- } else {
39
- tabItems.item(tabItemIndex + 1).focus();
40
- }
41
- break;
42
- case 'Enter':
43
- case ' ':
44
- event.preventDefault()
45
- if (tabItems.item(tabItemIndex).type === 'radio') {
46
- tabItems.item(tabItemIndex).checked = true
47
- break;
48
- } else if (tabItems.item(tabItemIndex).type === 'checkbox') {
49
- tabItems.item(tabItemIndex).checked = !tabItems.item(tabItemIndex).checked
50
- break;
51
- } else if (tabItems.item(tabItemIndex).tagName === 'BUTTON') {
52
- tabItems.item(tabItemIndex).click()
53
- break;
54
- } else if (tabItems.item(tabItemIndex).tagName === 'A') {
55
- window.location.href = tabItems.item(tabItemIndex).href
56
- break;
57
- }
58
- break;
59
- default:
60
- break;
61
- }
62
- }
63
- }