aria-ease 2.2.3 → 2.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 +407 -27
- package/bin/cli.cjs +475 -0
- package/bin/cli.cjs.map +1 -0
- package/bin/cli.d.ts.map +1 -0
- package/bin/cli.js +452 -0
- package/bin/cli.js.map +1 -0
- package/bin/{audit-cli.ts → cli.ts} +25 -20
- package/bin/configLoader.d.ts +19 -0
- package/bin/configLoader.d.ts.map +1 -0
- package/bin/configLoader.js +155 -0
- package/bin/configLoader.ts +170 -0
- package/bin/contractTestRunnerPlaywright-2LQHVMXT.js +426 -0
- package/bin/contractTestRunnerPlaywright-2LQHVMXT.js.map +1 -0
- package/dist/chunk-4F6O5RKZ.js +207 -0
- package/dist/chunk-4F6O5RKZ.js.map +1 -0
- package/dist/contractTestRunnerPlaywright-FM6MK6DY.js +255 -0
- package/dist/contractTestRunnerPlaywright-FM6MK6DY.js.map +1 -0
- package/dist/index.cjs +13644 -233
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -7
- package/dist/index.d.ts +102 -7
- package/dist/index.js +13191 -7
- package/dist/index.js.map +1 -1
- package/dist/{Types.d-p85gN5m_.d.cts → src/Types.d-BbztRe-S.d.cts} +0 -5
- package/dist/{Types.d-p85gN5m_.d.ts → src/Types.d-BbztRe-S.d.ts} +0 -5
- package/dist/src/accordion/index.cjs +25 -19
- package/dist/src/accordion/index.cjs.map +1 -1
- package/dist/src/accordion/index.d.cts +1 -1
- package/dist/src/accordion/index.d.ts +1 -1
- package/dist/src/accordion/index.js +28 -1
- package/dist/src/accordion/index.js.map +1 -1
- package/dist/src/block/index.cjs +99 -99
- package/dist/src/block/index.cjs.map +1 -1
- package/dist/src/block/index.d.cts +4 -2
- package/dist/src/block/index.d.ts +4 -2
- package/dist/src/block/index.js +42 -2
- package/dist/src/block/index.js.map +1 -1
- package/dist/src/checkbox/index.cjs +30 -13
- package/dist/src/checkbox/index.cjs.map +1 -1
- package/dist/src/checkbox/index.d.cts +1 -1
- package/dist/src/checkbox/index.d.ts +1 -1
- package/dist/src/checkbox/index.js +33 -1
- package/dist/src/checkbox/index.js.map +1 -1
- package/dist/src/chunk-MNMWQWXH.js +117 -0
- package/dist/src/chunk-MNMWQWXH.js.map +1 -0
- package/dist/src/menu/index.cjs +208 -130
- package/dist/src/menu/index.cjs.map +1 -1
- package/dist/src/menu/index.d.cts +9 -3
- package/dist/src/menu/index.d.ts +9 -3
- package/dist/src/menu/index.js +118 -2
- package/dist/src/menu/index.js.map +1 -1
- package/dist/src/radio/index.cjs +29 -16
- package/dist/src/radio/index.cjs.map +1 -1
- package/dist/src/radio/index.d.cts +1 -1
- package/dist/src/radio/index.d.ts +1 -1
- package/dist/src/radio/index.js +32 -1
- package/dist/src/radio/index.js.map +1 -1
- package/dist/src/toggle/index.cjs +26 -16
- package/dist/src/toggle/index.cjs.map +1 -1
- package/dist/src/toggle/index.d.cts +1 -1
- package/dist/src/toggle/index.d.ts +1 -1
- package/dist/src/toggle/index.js +29 -1
- package/dist/src/toggle/index.js.map +1 -1
- package/dist/src/utils/test/chunk-UAS6V5MH.js +203 -0
- package/dist/src/utils/test/chunk-UAS6V5MH.js.map +1 -0
- package/dist/src/utils/test/contractTestRunnerPlaywright-IBC4FHWK.js +251 -0
- package/dist/src/utils/test/contractTestRunnerPlaywright-IBC4FHWK.js.map +1 -0
- package/dist/src/utils/test/contracts/MenuContract.json +343 -0
- package/dist/src/utils/test/index.cjs +13092 -0
- package/dist/src/utils/test/index.cjs.map +1 -0
- package/dist/src/utils/test/index.d.cts +16 -0
- package/dist/src/utils/test/index.d.ts +16 -0
- package/dist/src/utils/test/index.js +12608 -0
- package/dist/src/utils/test/index.js.map +1 -0
- package/package.json +33 -12
- package/bin/audit-cli.cjs +0 -876
- package/bin/audit-cli.cjs.map +0 -1
- package/bin/audit-cli.js +0 -779
- package/bin/audit-cli.js.map +0 -1
- package/dist/chunk-4366LRNM.js +0 -38
- package/dist/chunk-4366LRNM.js.map +0 -1
- package/dist/chunk-5HQ6LLC5.js +0 -21
- package/dist/chunk-5HQ6LLC5.js.map +0 -1
- package/dist/chunk-FBQ5LF2T.js +0 -21
- package/dist/chunk-FBQ5LF2T.js.map +0 -1
- package/dist/chunk-KVTLMA4J.js +0 -58
- package/dist/chunk-KVTLMA4J.js.map +0 -1
- package/dist/chunk-MEA5U2G4.js +0 -24
- package/dist/chunk-MEA5U2G4.js.map +0 -1
- package/dist/chunk-RK3JUAFZ.js +0 -18
- package/dist/chunk-RK3JUAFZ.js.map +0 -1
- package/dist/chunk-RT5IROW4.js +0 -99
- package/dist/chunk-RT5IROW4.js.map +0 -1
- package/dist/src/utils/audit/audit.cjs +0 -239
- package/dist/src/utils/audit/audit.cjs.map +0 -1
- package/dist/src/utils/audit/audit.d.cts +0 -5
- package/dist/src/utils/audit/audit.d.ts +0 -5
- package/dist/src/utils/audit/audit.js +0 -232
- package/dist/src/utils/audit/audit.js.map +0 -1
- /package/bin/{audit-cli.d.cts → cli.d.cts} +0 -0
- /package/bin/{audit-cli.d.ts → cli.d.ts} +0 -0
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
2
3
|
// src/accordion/src/updateAccordionTriggerAriaAttributes/updateAccordionTriggerAriaAttributes.ts
|
|
3
4
|
function updateAccordionTriggerAriaAttributes(accordionId, accordionTriggersClass, accordionStates, clickedTriggerIndex) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const accordionDiv = document.querySelector(`#${accordionId}`);
|
|
6
|
+
if (!accordionDiv) {
|
|
7
|
+
console.error(`[aria-ease] Element with id="${accordionId}" not found. Make sure the accordion element exists before calling updateAccordionTriggerAriaAttributes.`);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const accordionItems = Array.from(accordionDiv.querySelectorAll(`.${accordionTriggersClass}`));
|
|
11
|
+
if (accordionItems.length === 0) {
|
|
12
|
+
console.error(`[aria-ease] Element with class="${accordionTriggersClass}" not found. Make sure the accordion items exist before calling updateAccordionTriggerAriaAttributes.`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (accordionItems.length !== accordionStates.length) {
|
|
16
|
+
console.error(`[aria-ease] Accordion state/DOM length mismatch: found ${accordionItems.length} triggers, but got ${accordionStates.length} state objects.'`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
accordionItems.forEach((accordionItem, index) => {
|
|
20
|
+
const state = accordionStates[index];
|
|
21
|
+
const expanded = accordionItem.getAttribute("aria-expanded");
|
|
22
|
+
const shouldBeExpanded = index === clickedTriggerIndex ? state.display ? "true" : "false" : "false";
|
|
23
|
+
if (expanded && expanded !== shouldBeExpanded) {
|
|
24
|
+
accordionItem.setAttribute("aria-expanded", shouldBeExpanded);
|
|
7
25
|
}
|
|
8
|
-
|
|
9
|
-
if (accordionItems.length === 0) {
|
|
10
|
-
throw new Error("Invalid accordion items shared class provided.");
|
|
11
|
-
}
|
|
12
|
-
if (accordionItems.length !== accordionStates.length) {
|
|
13
|
-
throw new Error("Accordion state/DOM length mismatch: found ".concat(accordionItems.length, " triggers, but got ").concat(accordionStates.length, " state objects."));
|
|
14
|
-
}
|
|
15
|
-
accordionItems.forEach(function(accordionItem, index) {
|
|
16
|
-
var state = accordionStates[index];
|
|
17
|
-
var expanded = accordionItem.getAttribute("aria-expanded");
|
|
18
|
-
var shouldBeExpanded = index === clickedTriggerIndex ? state.display ? "true" : "false" : "false";
|
|
19
|
-
if (expanded && expanded !== shouldBeExpanded) {
|
|
20
|
-
accordionItem.setAttribute("aria-expanded", shouldBeExpanded);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
26
|
+
});
|
|
23
27
|
}
|
|
24
|
-
|
|
28
|
+
|
|
29
|
+
exports.updateAccordionTriggerAriaAttributes = updateAccordionTriggerAriaAttributes;
|
|
30
|
+
//# sourceMappingURL=index.cjs.map
|
|
25
31
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["../../../src/accordion/src/updateAccordionTriggerAriaAttributes/updateAccordionTriggerAriaAttributes.ts"],"names":[],"mappings":";;;AAUO,SAAS,oCAAA,CAAqC,WAAA,EAAqB,sBAAA,EAAgC,eAAA,EAAoC,mBAAA,EAAmC;AAC7K,EAAA,MAAM,YAAA,GAAmC,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,WAAW,CAAA,CAAE,CAAA;AACjF,EAAA,IAAI,CAAC,YAAA,EAAc;AACf,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,WAAW,CAAA,wGAAA,CAA0G,CAAA;AACnK,IAAA;AAAA,EACJ;AAEA,EAAA,MAAM,cAAA,GAAgC,MAAM,IAAA,CAAK,YAAA,CAAa,iBAAiB,CAAA,CAAA,EAAI,sBAAsB,EAAE,CAAC,CAAA;AAC5G,EAAA,IAAI,cAAA,CAAe,WAAW,CAAA,EAAG;AAC7B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,sBAAsB,CAAA,qGAAA,CAAuG,CAAA;AAC9K,IAAA;AAAA,EACJ;AAEA,EAAA,IAAI,cAAA,CAAe,MAAA,KAAW,eAAA,CAAgB,MAAA,EAAQ;AAClD,IAAA,OAAA,CAAQ,MAAM,CAAA,uDAAA,EAA0D,cAAA,CAAe,MAAM,CAAA,mBAAA,EAAsB,eAAA,CAAgB,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAC3J,IAAA;AAAA,EACJ;AAEA,EAAA,cAAA,CAAe,OAAA,CAAQ,CAAC,aAAA,EAA4B,KAAA,KAAkB;AAClE,IAAA,MAAM,KAAA,GAAQ,gBAAgB,KAAK,CAAA;AACnC,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,YAAA,CAAa,eAAe,CAAA;AAC3D,IAAA,MAAM,mBAAmB,KAAA,KAAU,mBAAA,GAAuB,KAAA,CAAM,OAAA,GAAU,SAAS,OAAA,GAAW,OAAA;AAC9F,IAAA,IAAI,QAAA,IAAY,aAAa,gBAAA,EAAkB;AAC3C,MAAA,aAAA,CAAc,YAAA,CAAa,iBAAiB,gBAAgB,CAAA;AAAA,IAChE;AAAA,EACJ,CAAC,CAAA;AACL","file":"index.cjs","sourcesContent":["/**\n * Adds screen reader accessibility to accordions. Updates the aria attributes of the accordion trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-controls, aria-label (for only non-text triggers).\n * @param {string} accordionId The id of the accordion triggers parent container.\n * @param {string} accordionTriggersClass The shared class of all the accordion triggers.\n * @param {AccordionStates[]} accordionStates Array of objects containing accordions state information.\n * @param {number} clickedTriggerIndex Index of the currently clicked accordion trigger within the accordion div container.\n*/\n\nimport { AccordionStates } from \"../../../../Types\";\n\nexport function updateAccordionTriggerAriaAttributes(accordionId: string, accordionTriggersClass: string, accordionStates: AccordionStates[], clickedTriggerIndex: number): void {\n const accordionDiv: HTMLElement | null = document.querySelector(`#${accordionId}`);\n if (!accordionDiv) {\n console.error(`[aria-ease] Element with id=\"${accordionId}\" not found. Make sure the accordion element exists before calling updateAccordionTriggerAriaAttributes.`); \n return;\n }\n\n const accordionItems: HTMLElement[] = Array.from(accordionDiv.querySelectorAll(`.${accordionTriggersClass}`));\n if (accordionItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${accordionTriggersClass}\" not found. Make sure the accordion items exist before calling updateAccordionTriggerAriaAttributes.`);\n return;\n }\n\n if (accordionItems.length !== accordionStates.length) {\n console.error(`[aria-ease] Accordion state/DOM length mismatch: found ${accordionItems.length} triggers, but got ${accordionStates.length} state objects.'`);\n return;\n }\n\n accordionItems.forEach((accordionItem: HTMLElement, index: number) => {\n const state = accordionStates[index];\n const expanded = accordionItem.getAttribute(\"aria-expanded\");\n const shouldBeExpanded = index === clickedTriggerIndex ? (state.display ? \"true\" : \"false\") : \"false\";\n if (expanded && expanded !== shouldBeExpanded) {\n accordionItem.setAttribute(\"aria-expanded\", shouldBeExpanded);\n }\n });\n}"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AccordionStates } from '
|
|
1
|
+
import { A as AccordionStates } from '../Types.d-BbztRe-S.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adds screen reader accessibility to accordions. Updates the aria attributes of the accordion trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-controls, aria-label (for only non-text triggers).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AccordionStates } from '
|
|
1
|
+
import { A as AccordionStates } from '../Types.d-BbztRe-S.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adds screen reader accessibility to accordions. Updates the aria attributes of the accordion trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-controls, aria-label (for only non-text triggers).
|
|
@@ -1,2 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
// src/accordion/src/updateAccordionTriggerAriaAttributes/updateAccordionTriggerAriaAttributes.ts
|
|
2
|
+
function updateAccordionTriggerAriaAttributes(accordionId, accordionTriggersClass, accordionStates, clickedTriggerIndex) {
|
|
3
|
+
const accordionDiv = document.querySelector(`#${accordionId}`);
|
|
4
|
+
if (!accordionDiv) {
|
|
5
|
+
console.error(`[aria-ease] Element with id="${accordionId}" not found. Make sure the accordion element exists before calling updateAccordionTriggerAriaAttributes.`);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const accordionItems = Array.from(accordionDiv.querySelectorAll(`.${accordionTriggersClass}`));
|
|
9
|
+
if (accordionItems.length === 0) {
|
|
10
|
+
console.error(`[aria-ease] Element with class="${accordionTriggersClass}" not found. Make sure the accordion items exist before calling updateAccordionTriggerAriaAttributes.`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (accordionItems.length !== accordionStates.length) {
|
|
14
|
+
console.error(`[aria-ease] Accordion state/DOM length mismatch: found ${accordionItems.length} triggers, but got ${accordionStates.length} state objects.'`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
accordionItems.forEach((accordionItem, index) => {
|
|
18
|
+
const state = accordionStates[index];
|
|
19
|
+
const expanded = accordionItem.getAttribute("aria-expanded");
|
|
20
|
+
const shouldBeExpanded = index === clickedTriggerIndex ? state.display ? "true" : "false" : "false";
|
|
21
|
+
if (expanded && expanded !== shouldBeExpanded) {
|
|
22
|
+
accordionItem.setAttribute("aria-expanded", shouldBeExpanded);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { updateAccordionTriggerAriaAttributes };
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
2
29
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["../../../src/accordion/src/updateAccordionTriggerAriaAttributes/updateAccordionTriggerAriaAttributes.ts"],"names":[],"mappings":";AAUO,SAAS,oCAAA,CAAqC,WAAA,EAAqB,sBAAA,EAAgC,eAAA,EAAoC,mBAAA,EAAmC;AAC7K,EAAA,MAAM,YAAA,GAAmC,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,WAAW,CAAA,CAAE,CAAA;AACjF,EAAA,IAAI,CAAC,YAAA,EAAc;AACf,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,WAAW,CAAA,wGAAA,CAA0G,CAAA;AACnK,IAAA;AAAA,EACJ;AAEA,EAAA,MAAM,cAAA,GAAgC,MAAM,IAAA,CAAK,YAAA,CAAa,iBAAiB,CAAA,CAAA,EAAI,sBAAsB,EAAE,CAAC,CAAA;AAC5G,EAAA,IAAI,cAAA,CAAe,WAAW,CAAA,EAAG;AAC7B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,sBAAsB,CAAA,qGAAA,CAAuG,CAAA;AAC9K,IAAA;AAAA,EACJ;AAEA,EAAA,IAAI,cAAA,CAAe,MAAA,KAAW,eAAA,CAAgB,MAAA,EAAQ;AAClD,IAAA,OAAA,CAAQ,MAAM,CAAA,uDAAA,EAA0D,cAAA,CAAe,MAAM,CAAA,mBAAA,EAAsB,eAAA,CAAgB,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAC3J,IAAA;AAAA,EACJ;AAEA,EAAA,cAAA,CAAe,OAAA,CAAQ,CAAC,aAAA,EAA4B,KAAA,KAAkB;AAClE,IAAA,MAAM,KAAA,GAAQ,gBAAgB,KAAK,CAAA;AACnC,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,YAAA,CAAa,eAAe,CAAA;AAC3D,IAAA,MAAM,mBAAmB,KAAA,KAAU,mBAAA,GAAuB,KAAA,CAAM,OAAA,GAAU,SAAS,OAAA,GAAW,OAAA;AAC9F,IAAA,IAAI,QAAA,IAAY,aAAa,gBAAA,EAAkB;AAC3C,MAAA,aAAA,CAAc,YAAA,CAAa,iBAAiB,gBAAgB,CAAA;AAAA,IAChE;AAAA,EACJ,CAAC,CAAA;AACL","file":"index.js","sourcesContent":["/**\n * Adds screen reader accessibility to accordions. Updates the aria attributes of the accordion trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-controls, aria-label (for only non-text triggers).\n * @param {string} accordionId The id of the accordion triggers parent container.\n * @param {string} accordionTriggersClass The shared class of all the accordion triggers.\n * @param {AccordionStates[]} accordionStates Array of objects containing accordions state information.\n * @param {number} clickedTriggerIndex Index of the currently clicked accordion trigger within the accordion div container.\n*/\n\nimport { AccordionStates } from \"../../../../Types\";\n\nexport function updateAccordionTriggerAriaAttributes(accordionId: string, accordionTriggersClass: string, accordionStates: AccordionStates[], clickedTriggerIndex: number): void {\n const accordionDiv: HTMLElement | null = document.querySelector(`#${accordionId}`);\n if (!accordionDiv) {\n console.error(`[aria-ease] Element with id=\"${accordionId}\" not found. Make sure the accordion element exists before calling updateAccordionTriggerAriaAttributes.`); \n return;\n }\n\n const accordionItems: HTMLElement[] = Array.from(accordionDiv.querySelectorAll(`.${accordionTriggersClass}`));\n if (accordionItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${accordionTriggersClass}\" not found. Make sure the accordion items exist before calling updateAccordionTriggerAriaAttributes.`);\n return;\n }\n\n if (accordionItems.length !== accordionStates.length) {\n console.error(`[aria-ease] Accordion state/DOM length mismatch: found ${accordionItems.length} triggers, but got ${accordionStates.length} state objects.'`);\n return;\n }\n\n accordionItems.forEach((accordionItem: HTMLElement, index: number) => {\n const state = accordionStates[index];\n const expanded = accordionItem.getAttribute(\"aria-expanded\");\n const shouldBeExpanded = index === clickedTriggerIndex ? (state.display ? \"true\" : \"false\") : \"false\";\n if (expanded && expanded !== shouldBeExpanded) {\n accordionItem.setAttribute(\"aria-expanded\", shouldBeExpanded);\n }\n });\n}"]}
|
package/dist/src/block/index.cjs
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
2
3
|
// src/utils/handleKeyPress/handleKeyPress.ts
|
|
3
4
|
function isTextInput(el) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"text",
|
|
8
|
-
"email",
|
|
9
|
-
"password",
|
|
10
|
-
"tel",
|
|
11
|
-
"number"
|
|
12
|
-
].includes(type);
|
|
5
|
+
if (el.tagName !== "INPUT") return false;
|
|
6
|
+
const type = el.type;
|
|
7
|
+
return ["text", "email", "password", "tel", "number"].includes(type);
|
|
13
8
|
}
|
|
14
9
|
function isTextArea(el) {
|
|
15
|
-
|
|
10
|
+
return el.tagName === "TEXTAREA";
|
|
16
11
|
}
|
|
17
12
|
function isNativeButton(el) {
|
|
18
|
-
|
|
19
|
-
"button",
|
|
20
|
-
"submit",
|
|
21
|
-
"reset"
|
|
22
|
-
].includes(el.type);
|
|
13
|
+
return el.tagName === "BUTTON" || el.tagName === "INPUT" && ["button", "submit", "reset"].includes(el.type);
|
|
23
14
|
}
|
|
24
15
|
function isLink(el) {
|
|
25
|
-
|
|
16
|
+
return el.tagName === "A";
|
|
26
17
|
}
|
|
27
18
|
function moveFocus(elementItems, currentIndex, direction) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
const len = elementItems.length;
|
|
20
|
+
const nextIndex = (currentIndex + direction + len) % len;
|
|
21
|
+
elementItems.item(nextIndex).focus();
|
|
31
22
|
}
|
|
32
23
|
function isClickableButNotSemantic(el) {
|
|
33
|
-
|
|
24
|
+
return el.getAttribute("data-custom-click") !== null && el.getAttribute("data-custom-click") !== void 0;
|
|
34
25
|
}
|
|
35
|
-
function
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
event.preventDefault();
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case "Enter":
|
|
75
|
-
case " ":
|
|
76
|
-
{
|
|
77
|
-
if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) {
|
|
78
|
-
event.preventDefault();
|
|
79
|
-
currentEl.click();
|
|
80
|
-
}
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
26
|
+
function hasSubmenu(menuItem) {
|
|
27
|
+
return menuItem.getAttribute("aria-haspopup") === "true" || menuItem.getAttribute("aria-haspopup") === "menu";
|
|
28
|
+
}
|
|
29
|
+
function handleKeyPress(event, elementItems, elementItemIndex, menuElementDiv, triggerButton, openSubmenu, closeSubmenu) {
|
|
30
|
+
const currentEl = elementItems.item(elementItemIndex);
|
|
31
|
+
switch (event.key) {
|
|
32
|
+
case "ArrowUp":
|
|
33
|
+
case "ArrowLeft": {
|
|
34
|
+
if (event.key === "ArrowLeft" && menuElementDiv) ;
|
|
35
|
+
if (!isTextInput(currentEl) && !isTextArea(currentEl)) {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
moveFocus(elementItems, elementItemIndex, -1);
|
|
38
|
+
} else if (isTextInput(currentEl) || isTextArea(currentEl)) {
|
|
39
|
+
const cursorStart = currentEl.selectionStart;
|
|
40
|
+
if (cursorStart === 0) {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
moveFocus(elementItems, elementItemIndex, -1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "ArrowDown":
|
|
48
|
+
case "ArrowRight": {
|
|
49
|
+
if (event.key === "ArrowRight" && hasSubmenu(currentEl) && openSubmenu) ;
|
|
50
|
+
if (!isTextInput(currentEl) && !isTextArea(currentEl)) {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
moveFocus(elementItems, elementItemIndex, 1);
|
|
53
|
+
} else if (isTextInput(currentEl) || isTextArea(currentEl)) {
|
|
54
|
+
const value = currentEl.value;
|
|
55
|
+
const cursorEnd = currentEl.selectionStart;
|
|
56
|
+
if (cursorEnd === value.length) {
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
moveFocus(elementItems, elementItemIndex, 1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
83
62
|
}
|
|
63
|
+
case "Escape": {
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case "Enter":
|
|
68
|
+
case " ": {
|
|
69
|
+
if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
currentEl.click();
|
|
72
|
+
} else if (isNativeButton(currentEl)) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
currentEl.click();
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
84
79
|
}
|
|
80
|
+
|
|
85
81
|
// src/block/src/makeBlockAccessible/makeBlockAccessible.ts
|
|
86
82
|
var eventListenersMap = /* @__PURE__ */ new Map();
|
|
87
|
-
function makeBlockAccessible(blockId,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
function makeBlockAccessible(blockId, blockItemsClass) {
|
|
84
|
+
const blockDiv = document.querySelector(`#${blockId}`);
|
|
85
|
+
if (!blockDiv) {
|
|
86
|
+
console.error(`[aria-ease] Element with id="${blockId}" not found. Make sure the block element exists before calling makeBlockAccessible.`);
|
|
87
|
+
return { cleanup: () => {
|
|
88
|
+
} };
|
|
89
|
+
}
|
|
90
|
+
const blockItems = blockDiv.querySelectorAll(`.${blockItemsClass}`);
|
|
91
|
+
if (!blockItems || blockItems.length === 0) {
|
|
92
|
+
console.error(`[aria-ease] Element with class="${blockItemsClass}" not found. Make sure the block items exist before calling makeBlockAccessible.`);
|
|
93
|
+
return { cleanup: () => {
|
|
94
|
+
} };
|
|
95
|
+
}
|
|
96
|
+
blockItems.forEach((blockItem) => {
|
|
97
|
+
if (!eventListenersMap.has(blockItem)) {
|
|
98
|
+
const handler = (event) => {
|
|
99
|
+
const items = blockDiv.querySelectorAll(`.${blockItemsClass}`);
|
|
100
|
+
const index = Array.prototype.indexOf.call(items, blockItem);
|
|
101
|
+
handleKeyPress(event, items, index);
|
|
102
|
+
};
|
|
103
|
+
blockItem.addEventListener("keydown", handler);
|
|
104
|
+
eventListenersMap.set(blockItem, handler);
|
|
91
105
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
var index = Array.prototype.indexOf.call(items, blockItem);
|
|
101
|
-
handleKeyPress(event, items, index);
|
|
102
|
-
var handler = function(event2) {
|
|
103
|
-
return handleKeyPress(event2, items, index);
|
|
104
|
-
};
|
|
105
|
-
eventListenersMap.set(blockItem, handler);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
106
|
+
});
|
|
107
|
+
function cleanup() {
|
|
108
|
+
blockItems.forEach((blockItem) => {
|
|
109
|
+
const handler = eventListenersMap.get(blockItem);
|
|
110
|
+
if (handler) {
|
|
111
|
+
blockItem.removeEventListener("keydown", handler);
|
|
112
|
+
eventListenersMap.delete(blockItem);
|
|
113
|
+
}
|
|
108
114
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (eventListenersMap.has(blockItem)) {
|
|
112
|
-
blockItem.removeEventListener("keydown", function(event) {
|
|
113
|
-
return handleKeyPress(event, blockItems, blockItemIndex);
|
|
114
|
-
});
|
|
115
|
-
eventListenersMap.delete(blockItem);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
};
|
|
115
|
+
}
|
|
116
|
+
return { cleanup };
|
|
119
117
|
}
|
|
120
|
-
|
|
118
|
+
|
|
119
|
+
exports.makeBlockAccessible = makeBlockAccessible;
|
|
120
|
+
//# sourceMappingURL=index.cjs.map
|
|
121
121
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/macx/aria-ease/package/dist/src/block/index.cjs","../../../src/utils/handleKeyPress/handleKeyPress.ts"],"names":[],"mappings":"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","sourcesContent":["'use strict';\n\n// src/utils/handleKeyPress/handleKeyPress.ts\nfunction isTextInput(el) {\n if (el.tagName !== \"INPUT\") return false;\n const type = el.type;\n return [\"text\", \"email\", \"password\", \"tel\", \"number\"].includes(type);\n}\nfunction isTextArea(el) {\n return el.tagName === \"TEXTAREA\";\n}\nfunction isNativeButton(el) {\n return el.tagName === \"BUTTON\" || el.tagName === \"INPUT\" && [\"button\", \"submit\", \"reset\"].includes(el.type);\n}\nfunction isLink(el) {\n return el.tagName === \"A\";\n}\nfunction moveFocus(elementItems, currentIndex, direction) {\n const len = elementItems.length;\n const nextIndex = (currentIndex + direction + len) % len;\n elementItems.item(nextIndex).focus();\n}\nfunction isClickableButNotSemantic(el) {\n return el.getAttribute(\"data-custom-click\") !== null || el.getAttribute(\"data-custom-click\") !== void 0;\n}\nfunction handleKeyPress(event, elementItems, elementItemIndex, menuElementDiv, triggerButton) {\n const currentEl = elementItems.item(elementItemIndex);\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowLeft\": {\n if (!isTextInput(currentEl) && !isTextArea(currentEl)) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n } else if (isTextInput(currentEl) || isTextArea(currentEl)) {\n const cursorStart = currentEl.selectionStart;\n if (cursorStart === 0) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n }\n }\n break;\n }\n case \"ArrowDown\":\n case \"ArrowRight\": {\n if (!isTextInput(currentEl) && !isTextArea(currentEl)) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n } else if (isTextInput(currentEl) || isTextArea(currentEl)) {\n const value = currentEl.value;\n const cursorEnd = currentEl.selectionStart;\n if (cursorEnd === value.length) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n }\n }\n break;\n }\n case \"Escape\": {\n event.preventDefault();\n break;\n }\n case \"Enter\":\n case \" \": {\n if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) {\n event.preventDefault();\n currentEl.click();\n }\n break;\n }\n }\n}\n\n// src/block/src/makeBlockAccessible/makeBlockAccessible.ts\nvar eventListenersMap = /* @__PURE__ */ new Map();\nfunction makeBlockAccessible(blockId, blockElementsClass) {\n const blockDiv = document.querySelector(`#${blockId}`);\n if (!blockDiv) {\n throw new Error(\"Invalid block main div id provided.\");\n }\n const blockItems = blockDiv.querySelectorAll(`.${blockElementsClass}`);\n if (!blockItems) {\n throw new Error(\"Invalid block items shared class provided.\");\n }\n blockItems.forEach((blockItem) => {\n if (!eventListenersMap.has(blockItem)) {\n blockItem.addEventListener(\"keydown\", (event) => {\n const items = blockDiv.querySelectorAll(`.${blockElementsClass}`);\n const index = Array.prototype.indexOf.call(items, blockItem);\n handleKeyPress(event, items, index);\n const handler = (event2) => handleKeyPress(event2, items, index);\n eventListenersMap.set(blockItem, handler);\n });\n }\n });\n return function cleanUpBlockEventListeners() {\n blockItems.forEach((blockItem, blockItemIndex) => {\n if (eventListenersMap.has(blockItem)) {\n blockItem.removeEventListener(\"keydown\", (event) => handleKeyPress(event, blockItems, blockItemIndex));\n eventListenersMap.delete(blockItem);\n }\n });\n };\n}\n\nexports.makeBlockAccessible = makeBlockAccessible;\n//# sourceMappingURL=index.cjs.map\n","import { NodeListOfHTMLElement, HTMLElement } from \"../../../Types\";\n\n\nfunction isTextInput(el: HTMLElement): boolean {\n if (el.tagName !== 'INPUT') return false;\n const type = (el as HTMLInputElement).type;\n return ['text', 'email', 'password', 'tel', 'number'].includes(type);\n}\n\nfunction isTextArea(el: HTMLElement): boolean {\n return el.tagName === 'TEXTAREA';\n}\n\nexport function isNativeButton(el: HTMLElement): boolean {\n return el.tagName === 'BUTTON' || (el.tagName === 'INPUT' && ['button', 'submit', 'reset'].includes((el as HTMLInputElement).type));\n}\n\nexport function isLink(el: HTMLElement): boolean {\n return el.tagName === 'A';\n}\n\nfunction moveFocus(elementItems: NodeListOfHTMLElement, currentIndex: number, direction: -1 | 1) {\n const len = elementItems.length;\n const nextIndex = (currentIndex + direction + len) % len;\n elementItems.item(nextIndex).focus();\n}\n\nfunction isClickableButNotSemantic(el: HTMLElement): boolean {\n return el.getAttribute(\"data-custom-click\") !== null || el.getAttribute(\"data-custom-click\") !== undefined;\n}\n\nfunction handleMenuEscapeKeyPress(menuElement: HTMLElement, menuTriggerButton: HTMLElement) {\n menuElement.style.display = 'none';\n const menuTriggerButtonId = menuTriggerButton.getAttribute('id');\n if (!menuTriggerButtonId) {\n throw new Error(\"Menu trigger button does not have id attribute\");\n }\n menuTriggerButton.setAttribute(\"aria-expanded\", \"false\");\n}\n\nexport function handleKeyPress(\n event: KeyboardEvent,\n elementItems: NodeListOfHTMLElement,\n elementItemIndex: number,\n menuElementDiv?: HTMLElement,\n triggerButton?: HTMLElement\n): void {\n const currentEl = elementItems.item(elementItemIndex);\n switch (event.key) {\n case 'ArrowUp':\n case 'ArrowLeft': {\n if (!isTextInput(currentEl) && !isTextArea(currentEl)) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n } else if (isTextInput(currentEl) || isTextArea(currentEl)) {\n const cursorStart = (currentEl as HTMLInputElement | HTMLTextAreaElement).selectionStart;\n if (cursorStart === 0) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n }\n }\n break;\n }\n case 'ArrowDown':\n case 'ArrowRight': {\n if (!isTextInput(currentEl) && !isTextArea(currentEl)) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n } else if (isTextInput(currentEl) || isTextArea(currentEl)) {\n const value = (currentEl as HTMLInputElement | HTMLTextAreaElement).value;\n const cursorEnd = (currentEl as HTMLInputElement | HTMLTextAreaElement).selectionStart;\n if (cursorEnd === value.length) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n }\n }\n break;\n }\n case 'Escape': {\n event.preventDefault();\n if (menuElementDiv && triggerButton) {\n if (getComputedStyle(menuElementDiv).display === 'block') {\n handleMenuEscapeKeyPress(menuElementDiv, triggerButton);\n }\n triggerButton.focus();\n }\n break;\n }\n case 'Enter':\n case ' ': {\n if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) {\n event.preventDefault();\n currentEl.click();\n }\n break;\n }\n default:\n break;\n }\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/handleKeyPress/handleKeyPress.ts","../../../src/block/src/makeBlockAccessible/makeBlockAccessible.ts"],"names":[],"mappings":";;;AAGA,SAAS,YAAY,EAAA,EAA0B;AAC3C,EAAA,IAAI,EAAA,CAAG,OAAA,KAAY,OAAA,EAAS,OAAO,KAAA;AACnC,EAAA,MAAM,OAAQ,EAAA,CAAwB,IAAA;AACtC,EAAA,OAAO,CAAC,QAAQ,OAAA,EAAS,UAAA,EAAY,OAAO,QAAQ,CAAA,CAAE,SAAS,IAAI,CAAA;AACvE;AAEA,SAAS,WAAW,EAAA,EAA0B;AAC1C,EAAA,OAAO,GAAG,OAAA,KAAY,UAAA;AAC1B;AAEO,SAAS,eAAe,EAAA,EAA0B;AACrD,EAAA,OAAO,EAAA,CAAG,OAAA,KAAY,QAAA,IAAa,EAAA,CAAG,OAAA,KAAY,OAAA,IAAW,CAAC,QAAA,EAAU,QAAA,EAAU,OAAO,CAAA,CAAE,QAAA,CAAU,GAAwB,IAAI,CAAA;AACrI;AAEO,SAAS,OAAO,EAAA,EAA0B;AAC7C,EAAA,OAAO,GAAG,OAAA,KAAY,GAAA;AAC1B;AAEA,SAAS,SAAA,CAAU,YAAA,EAAqC,YAAA,EAAsB,SAAA,EAAmB;AAC7F,EAAA,MAAM,MAAM,YAAA,CAAa,MAAA;AACzB,EAAA,MAAM,SAAA,GAAA,CAAa,YAAA,GAAe,SAAA,GAAY,GAAA,IAAO,GAAA;AACrD,EAAA,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA,CAAE,KAAA,EAAM;AACvC;AAEA,SAAS,0BAA0B,EAAA,EAA0B;AACzD,EAAA,OAAO,EAAA,CAAG,aAAa,mBAAmB,CAAA,KAAM,QAAQ,EAAA,CAAG,YAAA,CAAa,mBAAmB,CAAA,KAAM,MAAA;AACrG;AAYA,SAAS,WAAW,QAAA,EAAgC;AAChD,EAAA,OAAO,QAAA,CAAS,aAAa,eAAe,CAAA,KAAM,UAAU,QAAA,CAAS,YAAA,CAAa,eAAe,CAAA,KAAM,MAAA;AAC3G;AAOO,SAAS,eACZ,KAAA,EACA,YAAA,EACA,kBACA,cAAA,EACA,aAAA,EACA,aACA,YAAA,EACI;AACJ,EAAA,MAAM,SAAA,GAAY,YAAA,CAAa,IAAA,CAAK,gBAAgB,CAAA;AACpD,EAAA,QAAQ,MAAM,GAAA;AAAK,IACf,KAAK,SAAA;AAAA,IACL,KAAK,WAAA,EAAa;AACd,MAAA,IAAG,KAAA,CAAM,GAAA,KAAQ,WAAA,IAAe,cAAkB,EAAc;AAahE,MAAA,IAAI,CAAC,WAAA,CAAY,SAAS,KAAK,CAAC,UAAA,CAAW,SAAS,CAAA,EAAG;AACnD,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,SAAA,CAAU,YAAA,EAAc,kBAAkB,EAAE,CAAA;AAAA,MAChD,WAAW,WAAA,CAAY,SAAS,CAAA,IAAK,UAAA,CAAW,SAAS,CAAA,EAAG;AACxD,QAAA,MAAM,cAAe,SAAA,CAAqD,cAAA;AAC1E,QAAA,IAAI,gBAAgB,CAAA,EAAG;AACnB,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,SAAA,CAAU,YAAA,EAAc,kBAAkB,EAAE,CAAA;AAAA,QAChD;AAAA,MACJ;AACA,MAAA;AAAA,IACJ;AAAA,IACA,KAAK,WAAA;AAAA,IACL,KAAK,YAAA,EAAc;AACf,MAAA,IAAG,MAAM,GAAA,KAAQ,YAAA,IAAgB,UAAA,CAAW,SAAS,KAAK,WAAA,EAAa;AASvE,MAAA,IAAI,CAAC,WAAA,CAAY,SAAS,KAAK,CAAC,UAAA,CAAW,SAAS,CAAA,EAAG;AACnD,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,SAAA,CAAU,YAAA,EAAc,kBAAkB,CAAC,CAAA;AAAA,MAC/C,WAAW,WAAA,CAAY,SAAS,CAAA,IAAK,UAAA,CAAW,SAAS,CAAA,EAAG;AACxD,QAAA,MAAM,QAAS,SAAA,CAAqD,KAAA;AACpE,QAAA,MAAM,YAAa,SAAA,CAAqD,cAAA;AACxE,QAAA,IAAI,SAAA,KAAc,MAAM,MAAA,EAAQ;AAC5B,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,SAAA,CAAU,YAAA,EAAc,kBAAkB,CAAC,CAAA;AAAA,QAC/C;AAAA,MACJ;AACA,MAAA;AAAA,IACJ;AAAA,IACA,KAAK,QAAA,EAAU;AACX,MAAA,KAAA,CAAM,cAAA,EAAe;AAOrB,MAAA;AAAA,IACJ;AAAA,IACA,KAAK,OAAA;AAAA,IACL,KAAK,GAAA,EAAK;AACN,MAAA,IAAI,CAAC,cAAA,CAAe,SAAS,CAAA,IAAK,CAAC,OAAO,SAAS,CAAA,IAAK,yBAAA,CAA0B,SAAS,CAAA,EAAG;AAC1F,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,SAAA,CAAU,KAAA,EAAM;AAAA,MACpB,CAAA,MAAA,IAAW,cAAA,CAAe,SAAS,CAAA,EAAG;AAClC,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,SAAA,CAAU,KAAA,EAAM;AAAA,MACpB;AACA,MAAA;AAAA,IACJ;AAEI;AAEZ;;;AC/HA,IAAM,iBAAA,uBAAwB,GAAA,EAAiD;AAExE,SAAS,mBAAA,CAAoB,SAAiB,eAAA,EAAyB;AAC5E,EAAA,MAAM,QAAA,GAAwB,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AAClE,EAAA,IAAG,CAAC,QAAA,EAAU;AACZ,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,OAAO,CAAA,mFAAA,CAAqF,CAAA;AAC1I,IAAA,OAAO,EAAE,SAAS,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EAC7B;AAEA,EAAA,MAAM,UAAA,GAAoC,QAAA,CAAS,gBAAA,CAAiB,CAAA,CAAA,EAAI,eAAe,CAAA,CAAE,CAAA;AACzF,EAAA,IAAG,CAAC,UAAA,IAAc,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AACzC,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,eAAe,CAAA,gFAAA,CAAkF,CAAA;AAClJ,IAAA,OAAO,EAAE,SAAS,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EAC7B;AAEA,EAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,KAAiC;AACnD,IAAA,IAAI,CAAC,iBAAA,CAAkB,GAAA,CAAI,SAAS,CAAA,EAAG;AACrC,MAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAAyB;AACxC,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,gBAAA,CAAiB,CAAA,CAAA,EAAI,eAAe,CAAA,CAAE,CAAA;AAC7D,QAAA,MAAM,QAAQ,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,IAAA,CAAK,OAAO,SAAS,CAAA;AAC3D,QAAA,cAAA,CAAe,KAAA,EAAO,OAAO,KAAK,CAAA;AAAA,MACpC,CAAA;AACA,MAAA,SAAA,CAAU,gBAAA,CAAiB,WAAW,OAAO,CAAA;AAC7C,MAAA,iBAAA,CAAkB,GAAA,CAAI,WAAW,OAAO,CAAA;AAAA,IAC1C;AAAA,EACF,CAAC,CAAA;AAED,EAAA,SAAS,OAAA,GAAgB;AACvB,IAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,KAAiC;AACnD,MAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,GAAA,CAAI,SAAS,CAAA;AAC/C,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,SAAA,CAAU,mBAAA,CAAoB,WAAW,OAAO,CAAA;AAChD,QAAA,iBAAA,CAAkB,OAAO,SAAS,CAAA;AAAA,MACpC;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,EAAE,OAAA,EAAQ;AACnB","file":"index.cjs","sourcesContent":["import { NodeListOfHTMLElement } from \"../../../Types\";\n\n\nfunction isTextInput(el: HTMLElement): boolean {\n if (el.tagName !== \"INPUT\") return false;\n const type = (el as HTMLInputElement).type;\n return [\"text\", \"email\", \"password\", \"tel\", \"number\"].includes(type);\n}\n\nfunction isTextArea(el: HTMLElement): boolean {\n return el.tagName === \"TEXTAREA\";\n}\n\nexport function isNativeButton(el: HTMLElement): boolean {\n return el.tagName === \"BUTTON\" || (el.tagName === \"INPUT\" && [\"button\", \"submit\", \"reset\"].includes((el as HTMLInputElement).type));\n}\n\nexport function isLink(el: HTMLElement): boolean {\n return el.tagName === \"A\";\n}\n\nfunction moveFocus(elementItems: NodeListOfHTMLElement, currentIndex: number, direction: -1 | 1) {\n const len = elementItems.length;\n const nextIndex = (currentIndex + direction + len) % len;\n elementItems.item(nextIndex).focus();\n}\n\nfunction isClickableButNotSemantic(el: HTMLElement): boolean {\n return el.getAttribute(\"data-custom-click\") !== null && el.getAttribute(\"data-custom-click\") !== undefined;\n}\n\nfunction handleMenuEscapeKeyPress(menuElement: HTMLElement, menuTriggerButton: HTMLElement) {\n menuElement.style.display = \"none\";\n const menuTriggerButtonId = menuTriggerButton.getAttribute(\"id\");\n if (!menuTriggerButtonId) {\n console.error(\"[aria-ease] Menu trigger button must have an id attribute to properly set aria attributes.\");\n return;\n }\n menuTriggerButton.setAttribute(\"aria-expanded\", \"false\");\n}\n\nfunction hasSubmenu(menuItem: HTMLElement): boolean {\n return menuItem.getAttribute(\"aria-haspopup\") === \"true\" || menuItem.getAttribute(\"aria-haspopup\") === \"menu\";\n}\n\nfunction getSubmenuId(menuItem: HTMLElement): string | null {\n return menuItem.getAttribute(\"aria-controls\");\n}\n\n\nexport function handleKeyPress(\n event: KeyboardEvent,\n elementItems: NodeListOfHTMLElement,\n elementItemIndex: number,\n menuElementDiv?: HTMLElement,\n triggerButton?: HTMLElement,\n openSubmenu?: (submenuId: string) => void,\n closeSubmenu?: () => void\n): void {\n const currentEl = elementItems.item(elementItemIndex);\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowLeft\": {\n if(event.key === \"ArrowLeft\" && menuElementDiv && closeSubmenu) {\n const labelledBy = menuElementDiv.getAttribute(\"aria-labelledby\");\n if (labelledBy) {\n const parentTrigger = document.getElementById(labelledBy);\n if (parentTrigger && parentTrigger.getAttribute(\"role\") === \"menuitem\") {\n event.preventDefault();\n closeSubmenu();\n parentTrigger.focus();\n return;\n }\n }\n }\n\n if (!isTextInput(currentEl) && !isTextArea(currentEl)) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n } else if (isTextInput(currentEl) || isTextArea(currentEl)) {\n const cursorStart = (currentEl as HTMLInputElement | HTMLTextAreaElement).selectionStart;\n if (cursorStart === 0) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n }\n }\n break;\n }\n case \"ArrowDown\":\n case \"ArrowRight\": {\n if(event.key === \"ArrowRight\" && hasSubmenu(currentEl) && openSubmenu) {\n event.preventDefault();\n const submenuId = getSubmenuId(currentEl);\n if (submenuId) {\n openSubmenu(submenuId);\n return;\n }\n }\n \n if (!isTextInput(currentEl) && !isTextArea(currentEl)) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n } else if (isTextInput(currentEl) || isTextArea(currentEl)) {\n const value = (currentEl as HTMLInputElement | HTMLTextAreaElement).value;\n const cursorEnd = (currentEl as HTMLInputElement | HTMLTextAreaElement).selectionStart;\n if (cursorEnd === value.length) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n }\n }\n break;\n }\n case \"Escape\": {\n event.preventDefault();\n if (menuElementDiv && triggerButton) {\n if (getComputedStyle(menuElementDiv).display === \"block\") {\n handleMenuEscapeKeyPress(menuElementDiv, triggerButton);\n }\n triggerButton.focus();\n }\n break;\n }\n case \"Enter\":\n case \" \": {\n if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) { \n event.preventDefault();\n currentEl.click();\n } else if (isNativeButton(currentEl)) {\n event.preventDefault();\n currentEl.click();\n }\n break;\n }\n default:\n break;\n }\n}","/** \n * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.\n * @param {string} blockId The id of the block container.\n * @param {string} blockItemsClass The shared class of the elements that are children of the block.\n*/\n\nimport { NodeListOfHTMLElement } from \"../../../../Types\"\nimport { handleKeyPress } from \"../../../utils/handleKeyPress/handleKeyPress\";\n\nconst eventListenersMap = new Map<HTMLElement, (event: KeyboardEvent) => void>();\n\nexport function makeBlockAccessible(blockId: string, blockItemsClass: string) {\n const blockDiv: HTMLElement = document.querySelector(`#${blockId}`) as HTMLElement\n if(!blockDiv) {\n console.error(`[aria-ease] Element with id=\"${blockId}\" not found. Make sure the block element exists before calling makeBlockAccessible.`);\n return { cleanup: () => {} };\n }\n\n const blockItems: NodeListOfHTMLElement = blockDiv.querySelectorAll(`.${blockItemsClass}`);\n if(!blockItems || blockItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${blockItemsClass}\" not found. Make sure the block items exist before calling makeBlockAccessible.`);\n return { cleanup: () => {} };\n }\n\n blockItems.forEach((blockItem: HTMLElement): void => {\n if (!eventListenersMap.has(blockItem)) {\n const handler = (event: KeyboardEvent) => {\n const items = blockDiv.querySelectorAll(`.${blockItemsClass}`) as NodeListOf<HTMLElement>;\n const index = Array.prototype.indexOf.call(items, blockItem);\n handleKeyPress(event, items, index);\n };\n blockItem.addEventListener(\"keydown\", handler);\n eventListenersMap.set(blockItem, handler);\n }\n });\n\n function cleanup(): void {\n blockItems.forEach((blockItem: HTMLElement): void => {\n const handler = eventListenersMap.get(blockItem);\n if (handler) {\n blockItem.removeEventListener(\"keydown\", handler);\n eventListenersMap.delete(blockItem);\n }\n });\n };\n\n return { cleanup }\n}"]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
|
|
3
3
|
* @param {string} blockId The id of the block container.
|
|
4
|
-
* @param {string}
|
|
4
|
+
* @param {string} blockItemsClass The shared class of the elements that are children of the block.
|
|
5
5
|
*/
|
|
6
|
-
declare function makeBlockAccessible(blockId: string,
|
|
6
|
+
declare function makeBlockAccessible(blockId: string, blockItemsClass: string): {
|
|
7
|
+
cleanup: () => void;
|
|
8
|
+
};
|
|
7
9
|
|
|
8
10
|
export { makeBlockAccessible };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
|
|
3
3
|
* @param {string} blockId The id of the block container.
|
|
4
|
-
* @param {string}
|
|
4
|
+
* @param {string} blockItemsClass The shared class of the elements that are children of the block.
|
|
5
5
|
*/
|
|
6
|
-
declare function makeBlockAccessible(blockId: string,
|
|
6
|
+
declare function makeBlockAccessible(blockId: string, blockItemsClass: string): {
|
|
7
|
+
cleanup: () => void;
|
|
8
|
+
};
|
|
7
9
|
|
|
8
10
|
export { makeBlockAccessible };
|
package/dist/src/block/index.js
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { handleKeyPress } from '../chunk-MNMWQWXH.js';
|
|
2
|
+
|
|
3
|
+
// src/block/src/makeBlockAccessible/makeBlockAccessible.ts
|
|
4
|
+
var eventListenersMap = /* @__PURE__ */ new Map();
|
|
5
|
+
function makeBlockAccessible(blockId, blockItemsClass) {
|
|
6
|
+
const blockDiv = document.querySelector(`#${blockId}`);
|
|
7
|
+
if (!blockDiv) {
|
|
8
|
+
console.error(`[aria-ease] Element with id="${blockId}" not found. Make sure the block element exists before calling makeBlockAccessible.`);
|
|
9
|
+
return { cleanup: () => {
|
|
10
|
+
} };
|
|
11
|
+
}
|
|
12
|
+
const blockItems = blockDiv.querySelectorAll(`.${blockItemsClass}`);
|
|
13
|
+
if (!blockItems || blockItems.length === 0) {
|
|
14
|
+
console.error(`[aria-ease] Element with class="${blockItemsClass}" not found. Make sure the block items exist before calling makeBlockAccessible.`);
|
|
15
|
+
return { cleanup: () => {
|
|
16
|
+
} };
|
|
17
|
+
}
|
|
18
|
+
blockItems.forEach((blockItem) => {
|
|
19
|
+
if (!eventListenersMap.has(blockItem)) {
|
|
20
|
+
const handler = (event) => {
|
|
21
|
+
const items = blockDiv.querySelectorAll(`.${blockItemsClass}`);
|
|
22
|
+
const index = Array.prototype.indexOf.call(items, blockItem);
|
|
23
|
+
handleKeyPress(event, items, index);
|
|
24
|
+
};
|
|
25
|
+
blockItem.addEventListener("keydown", handler);
|
|
26
|
+
eventListenersMap.set(blockItem, handler);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
function cleanup() {
|
|
30
|
+
blockItems.forEach((blockItem) => {
|
|
31
|
+
const handler = eventListenersMap.get(blockItem);
|
|
32
|
+
if (handler) {
|
|
33
|
+
blockItem.removeEventListener("keydown", handler);
|
|
34
|
+
eventListenersMap.delete(blockItem);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return { cleanup };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { makeBlockAccessible };
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
3
43
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["../../../src/block/src/makeBlockAccessible/makeBlockAccessible.ts"],"names":[],"mappings":";;;AASA,IAAM,iBAAA,uBAAwB,GAAA,EAAiD;AAExE,SAAS,mBAAA,CAAoB,SAAiB,eAAA,EAAyB;AAC5E,EAAA,MAAM,QAAA,GAAwB,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AAClE,EAAA,IAAG,CAAC,QAAA,EAAU;AACZ,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,OAAO,CAAA,mFAAA,CAAqF,CAAA;AAC1I,IAAA,OAAO,EAAE,SAAS,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EAC7B;AAEA,EAAA,MAAM,UAAA,GAAoC,QAAA,CAAS,gBAAA,CAAiB,CAAA,CAAA,EAAI,eAAe,CAAA,CAAE,CAAA;AACzF,EAAA,IAAG,CAAC,UAAA,IAAc,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AACzC,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,eAAe,CAAA,gFAAA,CAAkF,CAAA;AAClJ,IAAA,OAAO,EAAE,SAAS,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EAC7B;AAEA,EAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,KAAiC;AACnD,IAAA,IAAI,CAAC,iBAAA,CAAkB,GAAA,CAAI,SAAS,CAAA,EAAG;AACrC,MAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAAyB;AACxC,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,gBAAA,CAAiB,CAAA,CAAA,EAAI,eAAe,CAAA,CAAE,CAAA;AAC7D,QAAA,MAAM,QAAQ,KAAA,CAAM,SAAA,CAAU,OAAA,CAAQ,IAAA,CAAK,OAAO,SAAS,CAAA;AAC3D,QAAA,cAAA,CAAe,KAAA,EAAO,OAAO,KAAK,CAAA;AAAA,MACpC,CAAA;AACA,MAAA,SAAA,CAAU,gBAAA,CAAiB,WAAW,OAAO,CAAA;AAC7C,MAAA,iBAAA,CAAkB,GAAA,CAAI,WAAW,OAAO,CAAA;AAAA,IAC1C;AAAA,EACF,CAAC,CAAA;AAED,EAAA,SAAS,OAAA,GAAgB;AACvB,IAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,KAAiC;AACnD,MAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,GAAA,CAAI,SAAS,CAAA;AAC/C,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,SAAA,CAAU,mBAAA,CAAoB,WAAW,OAAO,CAAA;AAChD,QAAA,iBAAA,CAAkB,OAAO,SAAS,CAAA;AAAA,MACpC;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,EAAE,OAAA,EAAQ;AACnB","file":"index.js","sourcesContent":["/** \n * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.\n * @param {string} blockId The id of the block container.\n * @param {string} blockItemsClass The shared class of the elements that are children of the block.\n*/\n\nimport { NodeListOfHTMLElement } from \"../../../../Types\"\nimport { handleKeyPress } from \"../../../utils/handleKeyPress/handleKeyPress\";\n\nconst eventListenersMap = new Map<HTMLElement, (event: KeyboardEvent) => void>();\n\nexport function makeBlockAccessible(blockId: string, blockItemsClass: string) {\n const blockDiv: HTMLElement = document.querySelector(`#${blockId}`) as HTMLElement\n if(!blockDiv) {\n console.error(`[aria-ease] Element with id=\"${blockId}\" not found. Make sure the block element exists before calling makeBlockAccessible.`);\n return { cleanup: () => {} };\n }\n\n const blockItems: NodeListOfHTMLElement = blockDiv.querySelectorAll(`.${blockItemsClass}`);\n if(!blockItems || blockItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${blockItemsClass}\" not found. Make sure the block items exist before calling makeBlockAccessible.`);\n return { cleanup: () => {} };\n }\n\n blockItems.forEach((blockItem: HTMLElement): void => {\n if (!eventListenersMap.has(blockItem)) {\n const handler = (event: KeyboardEvent) => {\n const items = blockDiv.querySelectorAll(`.${blockItemsClass}`) as NodeListOf<HTMLElement>;\n const index = Array.prototype.indexOf.call(items, blockItem);\n handleKeyPress(event, items, index);\n };\n blockItem.addEventListener(\"keydown\", handler);\n eventListenersMap.set(blockItem, handler);\n }\n });\n\n function cleanup(): void {\n blockItems.forEach((blockItem: HTMLElement): void => {\n const handler = eventListenersMap.get(blockItem);\n if (handler) {\n blockItem.removeEventListener(\"keydown\", handler);\n eventListenersMap.delete(blockItem);\n }\n });\n };\n\n return { cleanup }\n}"]}
|
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
2
3
|
// src/checkbox/src/updateCheckboxAriaAttributes/updateCheckboxAriaAttributes.ts
|
|
3
4
|
function updateCheckboxAriaAttributes(checkboxId, checkboxesClass, checkboxStates, currentPressedCheckboxIndex) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const checkboxDiv = document.querySelector(`#${checkboxId}`);
|
|
6
|
+
if (!checkboxDiv) {
|
|
7
|
+
console.error(`[aria-ease] Invalid checkbox main div id provided. No checkbox div with id '${checkboxDiv} found.'`);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const checkboxItems = Array.from(document.querySelectorAll(`.${checkboxesClass}`));
|
|
11
|
+
if (checkboxItems.length === 0) {
|
|
12
|
+
console.error(`[aria-ease] Element with class="${checkboxesClass}" not found. Make sure the checkbox items exist before calling updateCheckboxAriaAttributes.`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (checkboxStates.length === 0) {
|
|
16
|
+
console.error(`[aria-ease] Checkbox states array is empty. Make sure the checkboxStates array is populated before calling updateCheckboxAriaAttributes.`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (currentPressedCheckboxIndex < 0 || currentPressedCheckboxIndex >= checkboxStates.length) {
|
|
20
|
+
console.error(`[aria-ease] Checkbox index ${currentPressedCheckboxIndex} is out of bounds for states array of length ${checkboxStates.length}.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
checkboxItems.forEach((checkbox, index) => {
|
|
24
|
+
if (index === currentPressedCheckboxIndex) {
|
|
25
|
+
const checked = checkbox.getAttribute("aria-checked");
|
|
26
|
+
const shouldBeChecked = checkboxStates[index].checked ? "true" : "false";
|
|
27
|
+
if (checked && checked !== shouldBeChecked) {
|
|
28
|
+
checkbox.setAttribute("aria-checked", shouldBeChecked);
|
|
29
|
+
}
|
|
7
30
|
}
|
|
8
|
-
|
|
9
|
-
if (checkboxItems.length === 0) {
|
|
10
|
-
throw new Error("Invalid checkboxes shared class provided.");
|
|
11
|
-
}
|
|
12
|
-
checkboxItems.forEach(function(checkbox, index) {
|
|
13
|
-
if (index === currentPressedCheckboxIndex) {
|
|
14
|
-
checkbox.setAttribute("aria-checked", checkboxStates[index].checked ? "true" : "false");
|
|
15
|
-
}
|
|
16
|
-
});
|
|
31
|
+
});
|
|
17
32
|
}
|
|
18
|
-
|
|
33
|
+
|
|
34
|
+
exports.updateCheckboxAriaAttributes = updateCheckboxAriaAttributes;
|
|
35
|
+
//# sourceMappingURL=index.cjs.map
|
|
19
36
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["../../../src/checkbox/src/updateCheckboxAriaAttributes/updateCheckboxAriaAttributes.ts"],"names":[],"mappings":";;;AAUO,SAAS,4BAAA,CAA6B,UAAA,EAAoB,eAAA,EAAyB,cAAA,EAAkC,2BAAA,EAA2C;AACrK,EAAA,MAAM,WAAA,GAAkC,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,UAAU,CAAA,CAAE,CAAA;AAC/E,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,4EAAA,EAA+E,WAAW,CAAA,QAAA,CAAU,CAAA;AAClH,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAA+B,MAAM,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI,eAAe,EAAE,CAAC,CAAA;AAChG,EAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,eAAe,CAAA,4FAAA,CAA8F,CAAA;AAC9J,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,cAAA,CAAe,WAAW,CAAA,EAAG;AAC/B,IAAA,OAAA,CAAQ,MAAM,CAAA,wIAAA,CAA0I,CAAA;AACxJ,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,2BAAA,GAA8B,CAAA,IAAK,2BAAA,IAA+B,cAAA,CAAe,MAAA,EAAQ;AAC3F,IAAA,OAAA,CAAQ,MAAM,CAAA,2BAAA,EAA8B,2BAA2B,CAAA,6CAAA,EAAgD,cAAA,CAAe,MAAM,CAAA,CAAA,CAAG,CAAA;AAC/I,IAAA;AAAA,EACF;AAEA,EAAA,aAAA,CAAc,OAAA,CAAQ,CAAC,QAAA,EAAuB,KAAA,KAAkB;AAC9D,IAAA,IAAI,UAAU,2BAAA,EAA6B;AACzC,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,YAAA,CAAa,cAAc,CAAA;AACpD,MAAA,MAAM,eAAA,GAAkB,cAAA,CAAe,KAAK,CAAA,CAAE,UAAU,MAAA,GAAS,OAAA;AACjE,MAAA,IAAI,OAAA,IAAW,YAAY,eAAA,EAAiB;AAC1C,QAAA,QAAA,CAAS,YAAA,CAAa,gBAAgB,eAAe,CAAA;AAAA,MACvD;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH","file":"index.cjs","sourcesContent":["/**\n * Adds screen reader accessibility to multiple checkboxes. Updates the aria attributes of the checkboxes. Checkbox elements must possess the following aria attributes; aria-checked and aria-label.\n * @param {string} checkboxId The id of the checkbox parent container.\n * @param {string} checkboxesClass The shared class of all the checkboxes.\n * @param {CheckboxStates[]} checkboxStates Array of objects containing checkboxes state information.\n * @param {number} currentPressedCheckboxIndex Index of the currently checked or unchecked checkbox.\n*/\n\nimport { CheckboxStates } from \"../../../../Types\";\n\nexport function updateCheckboxAriaAttributes(checkboxId: string, checkboxesClass: string, checkboxStates: CheckboxStates[], currentPressedCheckboxIndex: number): void {\n const checkboxDiv: HTMLElement | null = document.querySelector(`#${checkboxId}`);\n if (!checkboxDiv) {\n console.error(`[aria-ease] Invalid checkbox main div id provided. No checkbox div with id '${checkboxDiv} found.'`);\n return;\n }\n \n const checkboxItems: HTMLElement[] = Array.from(document.querySelectorAll(`.${checkboxesClass}`));\n if (checkboxItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${checkboxesClass}\" not found. Make sure the checkbox items exist before calling updateCheckboxAriaAttributes.`);\n return;\n };\n\n if (checkboxStates.length === 0) {\n console.error(`[aria-ease] Checkbox states array is empty. Make sure the checkboxStates array is populated before calling updateCheckboxAriaAttributes.`);\n return;\n }\n\n if (currentPressedCheckboxIndex < 0 || currentPressedCheckboxIndex >= checkboxStates.length) {\n console.error(`[aria-ease] Checkbox index ${currentPressedCheckboxIndex} is out of bounds for states array of length ${checkboxStates.length}.`);\n return;\n }\n\n checkboxItems.forEach((checkbox: HTMLElement, index: number) => {\n if (index === currentPressedCheckboxIndex) {\n const checked = checkbox.getAttribute(\"aria-checked\");\n const shouldBeChecked = checkboxStates[index].checked ? 'true' : 'false';\n if (checked && checked !== shouldBeChecked) {\n checkbox.setAttribute(\"aria-checked\", shouldBeChecked);\n }\n }\n });\n}"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CheckboxStates } from '
|
|
1
|
+
import { C as CheckboxStates } from '../Types.d-BbztRe-S.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adds screen reader accessibility to multiple checkboxes. Updates the aria attributes of the checkboxes. Checkbox elements must possess the following aria attributes; aria-checked and aria-label.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CheckboxStates } from '
|
|
1
|
+
import { C as CheckboxStates } from '../Types.d-BbztRe-S.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adds screen reader accessibility to multiple checkboxes. Updates the aria attributes of the checkboxes. Checkbox elements must possess the following aria attributes; aria-checked and aria-label.
|