aria-ease 2.8.0 → 2.8.2
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/bin/cli.js +3 -4
- package/dist/chunk-PCORWVIQ.js +213 -0
- package/dist/{chunk-4F6O5RKZ.js → chunk-SSBW5VAA.js} +0 -1
- package/dist/{contractTestRunnerPlaywright-FM6MK6DY.js → contractTestRunnerPlaywright-SE6TPWZZ.js} +1 -2
- package/{bin/contractTestRunnerPlaywright-2LQHVMXT.js → dist/contractTestRunnerPlaywright-YNHMLHQ2.js} +6 -178
- package/dist/contractTestRunnerPlaywright-ZY2T4UTV.js +254 -0
- package/dist/index.cjs +23 -8
- package/dist/index.d.cts +11 -14
- package/dist/index.d.ts +11 -14
- package/dist/index.js +24 -9
- package/dist/src/{Types.d-BbztRe-S.d.cts → Types.d-w1KLKLcA.d.cts} +8 -1
- package/dist/src/{Types.d-BbztRe-S.d.ts → Types.d-w1KLKLcA.d.ts} +8 -1
- package/dist/src/accordion/index.cjs +0 -2
- package/dist/src/accordion/index.d.cts +1 -1
- package/dist/src/accordion/index.d.ts +1 -1
- package/dist/src/accordion/index.js +0 -2
- package/dist/src/block/index.cjs +13 -5
- package/dist/src/block/index.d.cts +4 -3
- package/dist/src/block/index.d.ts +4 -3
- package/dist/src/block/index.js +14 -6
- package/dist/src/checkbox/index.cjs +0 -2
- package/dist/src/checkbox/index.d.cts +1 -1
- package/dist/src/checkbox/index.d.ts +1 -1
- package/dist/src/checkbox/index.js +0 -2
- package/dist/src/{chunk-DF4OR64G.js → chunk-TBJ6MIC7.js} +0 -2
- package/dist/src/menu/index.cjs +9 -4
- package/dist/src/menu/index.d.cts +4 -11
- package/dist/src/menu/index.d.ts +4 -11
- package/dist/src/menu/index.js +10 -5
- package/dist/src/radio/index.cjs +0 -2
- package/dist/src/radio/index.d.cts +1 -1
- package/dist/src/radio/index.d.ts +1 -1
- package/dist/src/radio/index.js +0 -2
- package/dist/src/toggle/index.cjs +0 -2
- package/dist/src/toggle/index.d.cts +1 -1
- package/dist/src/toggle/index.d.ts +1 -1
- package/dist/src/toggle/index.js +0 -2
- package/dist/src/utils/test/{chunk-UAS6V5MH.js → chunk-SSBW5VAA.js} +0 -2
- package/dist/src/utils/test/{contractTestRunnerPlaywright-IBC4FHWK.js → contractTestRunnerPlaywright-I36Y2NHA.js} +1 -3
- package/dist/src/utils/test/contractTestRunnerPlaywright-YNHMLHQ2.js +249 -0
- package/dist/src/utils/test/contractTestRunnerPlaywright-ZY2T4UTV.js +249 -0
- package/dist/src/utils/test/contracts/MenuContract.json +52 -8
- package/dist/src/utils/test/index.cjs +1 -3
- package/dist/src/utils/test/index.js +2 -4
- package/package.json +14 -13
- package/bin/cli.cjs +0 -475
- package/bin/cli.cjs.map +0 -1
- package/bin/cli.d.cts +0 -1
- package/bin/cli.d.ts +0 -1
- package/bin/cli.d.ts.map +0 -1
- package/bin/cli.js.map +0 -1
- package/bin/cli.ts +0 -122
- package/bin/configLoader.d.ts +0 -19
- package/bin/configLoader.d.ts.map +0 -1
- package/bin/configLoader.js +0 -155
- package/bin/configLoader.ts +0 -170
- package/bin/contractTestRunnerPlaywright-2LQHVMXT.js.map +0 -1
- package/dist/chunk-4F6O5RKZ.js.map +0 -1
- package/dist/contractTestRunnerPlaywright-FM6MK6DY.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/src/accordion/index.cjs.map +0 -1
- package/dist/src/accordion/index.js.map +0 -1
- package/dist/src/block/index.cjs.map +0 -1
- package/dist/src/block/index.js.map +0 -1
- package/dist/src/checkbox/index.cjs.map +0 -1
- package/dist/src/checkbox/index.js.map +0 -1
- package/dist/src/chunk-CGC24XEF.js +0 -127
- package/dist/src/chunk-CGC24XEF.js.map +0 -1
- package/dist/src/chunk-DF4OR64G.js.map +0 -1
- package/dist/src/chunk-MNMWQWXH.js +0 -117
- package/dist/src/chunk-MNMWQWXH.js.map +0 -1
- package/dist/src/menu/index.cjs.map +0 -1
- package/dist/src/menu/index.js.map +0 -1
- package/dist/src/radio/index.cjs.map +0 -1
- package/dist/src/radio/index.js.map +0 -1
- package/dist/src/toggle/index.cjs.map +0 -1
- package/dist/src/toggle/index.js.map +0 -1
- package/dist/src/utils/test/chunk-UAS6V5MH.js.map +0 -1
- package/dist/src/utils/test/contractTestRunnerPlaywright-IBC4FHWK.js.map +0 -1
- package/dist/src/utils/test/index.cjs.map +0 -1
- package/dist/src/utils/test/index.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
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}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/handleKeyPress/handleKeyPress.ts","../../../src/block/src/makeBlockAccessible/makeBlockAccessible.ts"],"names":[],"mappings":"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","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 handleMenuClose(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 handleMenuClose(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 case \"Tab\": {\n if (menuElementDiv && triggerButton && (!event.shiftKey || event.shiftKey)) {\n handleMenuClose(menuElementDiv, triggerButton);\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 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
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.js","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,127 +0,0 @@
|
|
|
1
|
-
// src/utils/handleKeyPress/handleKeyPress.ts
|
|
2
|
-
function isTextInput(el) {
|
|
3
|
-
if (el.tagName !== "INPUT") return false;
|
|
4
|
-
const type = el.type;
|
|
5
|
-
return ["text", "email", "password", "tel", "number"].includes(type);
|
|
6
|
-
}
|
|
7
|
-
function isTextArea(el) {
|
|
8
|
-
return el.tagName === "TEXTAREA";
|
|
9
|
-
}
|
|
10
|
-
function isNativeButton(el) {
|
|
11
|
-
return el.tagName === "BUTTON" || el.tagName === "INPUT" && ["button", "submit", "reset"].includes(el.type);
|
|
12
|
-
}
|
|
13
|
-
function isLink(el) {
|
|
14
|
-
return el.tagName === "A";
|
|
15
|
-
}
|
|
16
|
-
function moveFocus(elementItems, currentIndex, direction) {
|
|
17
|
-
const len = elementItems.length;
|
|
18
|
-
const nextIndex = (currentIndex + direction + len) % len;
|
|
19
|
-
elementItems.item(nextIndex).focus();
|
|
20
|
-
}
|
|
21
|
-
function isClickableButNotSemantic(el) {
|
|
22
|
-
return el.getAttribute("data-custom-click") !== null && el.getAttribute("data-custom-click") !== void 0;
|
|
23
|
-
}
|
|
24
|
-
function handleMenuEscapeKeyPress(menuElement, menuTriggerButton) {
|
|
25
|
-
menuElement.style.display = "none";
|
|
26
|
-
const menuTriggerButtonId = menuTriggerButton.getAttribute("id");
|
|
27
|
-
if (!menuTriggerButtonId) {
|
|
28
|
-
console.error("[aria-ease] Menu trigger button must have an id attribute to properly set aria attributes.");
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
menuTriggerButton.setAttribute("aria-expanded", "false");
|
|
32
|
-
}
|
|
33
|
-
function hasSubmenu(menuItem) {
|
|
34
|
-
return menuItem.getAttribute("aria-haspopup") === "true" || menuItem.getAttribute("aria-haspopup") === "menu";
|
|
35
|
-
}
|
|
36
|
-
function getSubmenuId(menuItem) {
|
|
37
|
-
return menuItem.getAttribute("aria-controls");
|
|
38
|
-
}
|
|
39
|
-
function handleKeyPress(event, elementItems, elementItemIndex, menuElementDiv, triggerButton, openSubmenu, closeSubmenu) {
|
|
40
|
-
const currentEl = elementItems.item(elementItemIndex);
|
|
41
|
-
switch (event.key) {
|
|
42
|
-
case "ArrowUp":
|
|
43
|
-
case "ArrowLeft": {
|
|
44
|
-
if (event.key === "ArrowLeft" && menuElementDiv && closeSubmenu) {
|
|
45
|
-
const labelledBy = menuElementDiv.getAttribute("aria-labelledby");
|
|
46
|
-
if (labelledBy) {
|
|
47
|
-
const parentTrigger = document.getElementById(labelledBy);
|
|
48
|
-
if (parentTrigger && parentTrigger.getAttribute("role") === "menuitem") {
|
|
49
|
-
event.preventDefault();
|
|
50
|
-
closeSubmenu();
|
|
51
|
-
parentTrigger.focus();
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (!isTextInput(currentEl) && !isTextArea(currentEl)) {
|
|
57
|
-
event.preventDefault();
|
|
58
|
-
moveFocus(elementItems, elementItemIndex, -1);
|
|
59
|
-
} else if (isTextInput(currentEl) || isTextArea(currentEl)) {
|
|
60
|
-
const cursorStart = currentEl.selectionStart;
|
|
61
|
-
if (cursorStart === 0) {
|
|
62
|
-
event.preventDefault();
|
|
63
|
-
moveFocus(elementItems, elementItemIndex, -1);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
case "ArrowDown":
|
|
69
|
-
case "ArrowRight": {
|
|
70
|
-
if (event.key === "ArrowRight" && hasSubmenu(currentEl) && openSubmenu) {
|
|
71
|
-
event.preventDefault();
|
|
72
|
-
const submenuId = getSubmenuId(currentEl);
|
|
73
|
-
if (submenuId) {
|
|
74
|
-
openSubmenu(submenuId);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (!isTextInput(currentEl) && !isTextArea(currentEl)) {
|
|
79
|
-
event.preventDefault();
|
|
80
|
-
moveFocus(elementItems, elementItemIndex, 1);
|
|
81
|
-
} else if (isTextInput(currentEl) || isTextArea(currentEl)) {
|
|
82
|
-
const value = currentEl.value;
|
|
83
|
-
const cursorEnd = currentEl.selectionStart;
|
|
84
|
-
if (cursorEnd === value.length) {
|
|
85
|
-
event.preventDefault();
|
|
86
|
-
moveFocus(elementItems, elementItemIndex, 1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
case "Escape": {
|
|
92
|
-
event.preventDefault();
|
|
93
|
-
if (menuElementDiv && triggerButton) {
|
|
94
|
-
if (getComputedStyle(menuElementDiv).display === "block") {
|
|
95
|
-
handleMenuEscapeKeyPress(menuElementDiv, triggerButton);
|
|
96
|
-
}
|
|
97
|
-
triggerButton.focus();
|
|
98
|
-
}
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
case "Enter":
|
|
102
|
-
case " ": {
|
|
103
|
-
if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) {
|
|
104
|
-
event.preventDefault();
|
|
105
|
-
currentEl.click();
|
|
106
|
-
} else if (isNativeButton(currentEl)) {
|
|
107
|
-
event.preventDefault();
|
|
108
|
-
currentEl.click();
|
|
109
|
-
}
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
case "Tab": {
|
|
113
|
-
if (menuElementDiv && !event.shiftKey) {
|
|
114
|
-
event.preventDefault();
|
|
115
|
-
moveFocus(elementItems, elementItemIndex, 1);
|
|
116
|
-
} else if (menuElementDiv && event.shiftKey) {
|
|
117
|
-
event.preventDefault();
|
|
118
|
-
moveFocus(elementItems, elementItemIndex, -1);
|
|
119
|
-
}
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export { handleKeyPress };
|
|
126
|
-
//# sourceMappingURL=chunk-CGC24XEF.js.map
|
|
127
|
-
//# sourceMappingURL=chunk-CGC24XEF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/handleKeyPress/handleKeyPress.ts"],"names":[],"mappings":"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","file":"chunk-CGC24XEF.js","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 case \"Tab\": {\n if (menuElementDiv && !event.shiftKey) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, 1);\n } else if (menuElementDiv && event.shiftKey) {\n event.preventDefault();\n moveFocus(elementItems, elementItemIndex, -1);\n }\n break;\n }\n default:\n break;\n }\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/handleKeyPress/handleKeyPress.ts"],"names":[],"mappings":"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","file":"chunk-DF4OR64G.js","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 handleMenuClose(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 handleMenuClose(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 case \"Tab\": {\n if (menuElementDiv && triggerButton && (!event.shiftKey || event.shiftKey)) {\n handleMenuClose(menuElementDiv, triggerButton);\n } \n break;\n }\n default:\n break;\n }\n}"]}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// src/utils/handleKeyPress/handleKeyPress.ts
|
|
2
|
-
function isTextInput(el) {
|
|
3
|
-
if (el.tagName !== "INPUT") return false;
|
|
4
|
-
const type = el.type;
|
|
5
|
-
return ["text", "email", "password", "tel", "number"].includes(type);
|
|
6
|
-
}
|
|
7
|
-
function isTextArea(el) {
|
|
8
|
-
return el.tagName === "TEXTAREA";
|
|
9
|
-
}
|
|
10
|
-
function isNativeButton(el) {
|
|
11
|
-
return el.tagName === "BUTTON" || el.tagName === "INPUT" && ["button", "submit", "reset"].includes(el.type);
|
|
12
|
-
}
|
|
13
|
-
function isLink(el) {
|
|
14
|
-
return el.tagName === "A";
|
|
15
|
-
}
|
|
16
|
-
function moveFocus(elementItems, currentIndex, direction) {
|
|
17
|
-
const len = elementItems.length;
|
|
18
|
-
const nextIndex = (currentIndex + direction + len) % len;
|
|
19
|
-
elementItems.item(nextIndex).focus();
|
|
20
|
-
}
|
|
21
|
-
function isClickableButNotSemantic(el) {
|
|
22
|
-
return el.getAttribute("data-custom-click") !== null && el.getAttribute("data-custom-click") !== void 0;
|
|
23
|
-
}
|
|
24
|
-
function handleMenuEscapeKeyPress(menuElement, menuTriggerButton) {
|
|
25
|
-
menuElement.style.display = "none";
|
|
26
|
-
const menuTriggerButtonId = menuTriggerButton.getAttribute("id");
|
|
27
|
-
if (!menuTriggerButtonId) {
|
|
28
|
-
console.error("[aria-ease] Menu trigger button must have an id attribute to properly set aria attributes.");
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
menuTriggerButton.setAttribute("aria-expanded", "false");
|
|
32
|
-
}
|
|
33
|
-
function hasSubmenu(menuItem) {
|
|
34
|
-
return menuItem.getAttribute("aria-haspopup") === "true" || menuItem.getAttribute("aria-haspopup") === "menu";
|
|
35
|
-
}
|
|
36
|
-
function getSubmenuId(menuItem) {
|
|
37
|
-
return menuItem.getAttribute("aria-controls");
|
|
38
|
-
}
|
|
39
|
-
function handleKeyPress(event, elementItems, elementItemIndex, menuElementDiv, triggerButton, openSubmenu, closeSubmenu) {
|
|
40
|
-
const currentEl = elementItems.item(elementItemIndex);
|
|
41
|
-
switch (event.key) {
|
|
42
|
-
case "ArrowUp":
|
|
43
|
-
case "ArrowLeft": {
|
|
44
|
-
if (event.key === "ArrowLeft" && menuElementDiv && closeSubmenu) {
|
|
45
|
-
const labelledBy = menuElementDiv.getAttribute("aria-labelledby");
|
|
46
|
-
if (labelledBy) {
|
|
47
|
-
const parentTrigger = document.getElementById(labelledBy);
|
|
48
|
-
if (parentTrigger && parentTrigger.getAttribute("role") === "menuitem") {
|
|
49
|
-
event.preventDefault();
|
|
50
|
-
closeSubmenu();
|
|
51
|
-
parentTrigger.focus();
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (!isTextInput(currentEl) && !isTextArea(currentEl)) {
|
|
57
|
-
event.preventDefault();
|
|
58
|
-
moveFocus(elementItems, elementItemIndex, -1);
|
|
59
|
-
} else if (isTextInput(currentEl) || isTextArea(currentEl)) {
|
|
60
|
-
const cursorStart = currentEl.selectionStart;
|
|
61
|
-
if (cursorStart === 0) {
|
|
62
|
-
event.preventDefault();
|
|
63
|
-
moveFocus(elementItems, elementItemIndex, -1);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
case "ArrowDown":
|
|
69
|
-
case "ArrowRight": {
|
|
70
|
-
if (event.key === "ArrowRight" && hasSubmenu(currentEl) && openSubmenu) {
|
|
71
|
-
event.preventDefault();
|
|
72
|
-
const submenuId = getSubmenuId(currentEl);
|
|
73
|
-
if (submenuId) {
|
|
74
|
-
openSubmenu(submenuId);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (!isTextInput(currentEl) && !isTextArea(currentEl)) {
|
|
79
|
-
event.preventDefault();
|
|
80
|
-
moveFocus(elementItems, elementItemIndex, 1);
|
|
81
|
-
} else if (isTextInput(currentEl) || isTextArea(currentEl)) {
|
|
82
|
-
const value = currentEl.value;
|
|
83
|
-
const cursorEnd = currentEl.selectionStart;
|
|
84
|
-
if (cursorEnd === value.length) {
|
|
85
|
-
event.preventDefault();
|
|
86
|
-
moveFocus(elementItems, elementItemIndex, 1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
case "Escape": {
|
|
92
|
-
event.preventDefault();
|
|
93
|
-
if (menuElementDiv && triggerButton) {
|
|
94
|
-
if (getComputedStyle(menuElementDiv).display === "block") {
|
|
95
|
-
handleMenuEscapeKeyPress(menuElementDiv, triggerButton);
|
|
96
|
-
}
|
|
97
|
-
triggerButton.focus();
|
|
98
|
-
}
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
case "Enter":
|
|
102
|
-
case " ": {
|
|
103
|
-
if (!isNativeButton(currentEl) && !isLink(currentEl) && isClickableButNotSemantic(currentEl)) {
|
|
104
|
-
event.preventDefault();
|
|
105
|
-
currentEl.click();
|
|
106
|
-
} else if (isNativeButton(currentEl)) {
|
|
107
|
-
event.preventDefault();
|
|
108
|
-
currentEl.click();
|
|
109
|
-
}
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export { handleKeyPress };
|
|
116
|
-
//# sourceMappingURL=chunk-MNMWQWXH.js.map
|
|
117
|
-
//# sourceMappingURL=chunk-MNMWQWXH.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/handleKeyPress/handleKeyPress.ts"],"names":[],"mappings":"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","file":"chunk-MNMWQWXH.js","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}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/handleKeyPress/handleKeyPress.ts","../../../src/menu/src/makeMenuAccessible/makeMenuAccessible.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;AAEA,SAAS,eAAA,CAAgB,aAA0B,iBAAA,EAAgC;AAC/E,EAAA,WAAA,CAAY,MAAM,OAAA,GAAU,MAAA;AAC5B,EAAA,MAAM,mBAAA,GAAsB,iBAAA,CAAkB,YAAA,CAAa,IAAI,CAAA;AAC/D,EAAA,IAAI,CAAC,mBAAA,EAAqB;AACtB,IAAA,OAAA,CAAQ,MAAM,4FAA4F,CAAA;AAC1G,IAAA;AAAA,EACJ;AACA,EAAA,iBAAA,CAAkB,YAAA,CAAa,iBAAiB,OAAO,CAAA;AAC3D;AAEA,SAAS,WAAW,QAAA,EAAgC;AAChD,EAAA,OAAO,QAAA,CAAS,aAAa,eAAe,CAAA,KAAM,UAAU,QAAA,CAAS,YAAA,CAAa,eAAe,CAAA,KAAM,MAAA;AAC3G;AAEA,SAAS,aAAa,QAAA,EAAsC;AACxD,EAAA,OAAO,QAAA,CAAS,aAAa,eAAe,CAAA;AAChD;AAGO,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,cAAA,IAAkB,YAAA,EAAc;AAC5D,QAAA,MAAM,UAAA,GAAa,cAAA,CAAe,YAAA,CAAa,iBAAiB,CAAA;AAChE,QAAA,IAAI,UAAA,EAAY;AACZ,UAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,cAAA,CAAe,UAAU,CAAA;AACxD,UAAA,IAAI,aAAA,IAAiB,aAAA,CAAc,YAAA,CAAa,MAAM,MAAM,UAAA,EAAY;AACpE,YAAA,KAAA,CAAM,cAAA,EAAe;AACrB,YAAA,YAAA,EAAa;AACb,YAAA,aAAA,CAAc,KAAA,EAAM;AACpB,YAAA;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAEA,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;AACnE,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,MAAM,SAAA,GAAY,aAAa,SAAS,CAAA;AACxC,QAAA,IAAI,SAAA,EAAW;AACX,UAAA,WAAA,CAAY,SAAS,CAAA;AACrB,UAAA;AAAA,QACJ;AAAA,MACJ;AAEA,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;AACrB,MAAA,IAAI,kBAAkB,aAAA,EAAe;AACjC,QAAA,IAAI,gBAAA,CAAiB,cAAc,CAAA,CAAE,OAAA,KAAY,OAAA,EAAS;AACtD,UAAA,eAAA,CAAgB,gBAAgB,aAAa,CAAA;AAAA,QACjD;AACA,QAAA,aAAA,CAAc,KAAA,EAAM;AAAA,MACxB;AACA,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;AAAA,IACA,KAAK,KAAA,EAAO;AACR,MAAA,IAAI,kBAAkB,aAAA,KAAkB,CAAC,KAAA,CAAM,QAAA,IAAY,MAAM,QAAA,CAAA,EAAW;AACxE,QAAA,eAAA,CAAgB,gBAAgB,aAAa,CAAA;AAAA,MACjD;AACA,MAAA;AAAA,IACJ;AAEI;AAEZ;;;ACnIO,SAAS,kBAAA,CAAmB,EAAE,MAAA,EAAQ,cAAA,EAAgB,WAAU,EAAiE;AACtI,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;AACnD,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,MAAM,CAAA,iFAAA,CAAmF,CAAA;AACvI,IAAA,OAAO,EAAE,UAAU,MAAM;AAAA,IAAC,CAAA,EAAG,WAAW,MAAM;AAAA,IAAC,CAAA,EAAG,SAAS,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EACtE;AAEA,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE,CAAA;AAC5D,EAAA,IAAI,CAAC,aAAA,EAAe;AAClB,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,SAAS,CAAA,2FAAA,CAA6F,CAAA;AACpJ,IAAA,OAAO,EAAE,UAAU,MAAM;AAAA,IAAC,CAAA,EAAG,WAAW,MAAM;AAAA,IAAC,CAAA,EAAG,SAAS,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EACtE;AAEA,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAiD;AACxE,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAmD;AAEhF,EAAA,IAAI,WAAA,GAA4C,IAAA;AAChD,EAAA,IAAI,aAAA,GAAsC,IAAA;AAE1C,EAAA,SAAS,QAAA,GAAW;AAClB,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,WAAA,GAAc,OAAA,CAAQ,gBAAA,CAAiB,CAAA,CAAA,EAAI,cAAc,CAAA,CAAE,CAAA;AAAA,IAC7D;AACA,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,SAAS,gBAAA,GAAkC;AACzC,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,MAAM,WAAW,QAAA,EAAS;AAC1B,MAAA,aAAA,GAAgB,EAAC;AAEjB,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA;AAC5B,QAAA,MAAM,QAAA,GAAW,sBAAsB,IAAI,CAAA;AAE3C,QAAA,IAAI,CAAC,QAAA,EAAU;AACb,UAAA,IAAI,CAAC,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA,EAAG;AAClC,YAAA,IAAA,CAAK,YAAA,CAAa,YAAY,IAAI,CAAA;AAAA,UACpC;AACA,UAAA,aAAA,CAAc,KAAK,IAAI,CAAA;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,aAAA;AAAA,EACT;AAEA,EAAA,SAAS,eAAe,KAAA,EAA6C;AACnE,IAAA,MAAM,YAAA,GAAe;AAAA,MACnB,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,IAAA,EAAM,CAAC,KAAA,KAAkB,KAAA,CAAM,KAAK,CAAA;AAAA,MACpC,OAAA,EAAS,CAAC,QAAA,KAAyD;AACjE,QAAA,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAAA,MACxB,CAAA;AAAA,MACA,CAAC,MAAA,CAAO,QAAQ,GAAG,aAAa;AAC9B,QAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,UAAA,MAAM,IAAA;AAAA,QACR;AAAA,MACF;AAAA,KACF;AACA,IAAA,OAAO,YAAA;AAAA,EACT;AAEA,EAAA,SAAS,sBAAsB,IAAA,EAA4B;AACzD,IAAA,IAAI,SAAS,IAAA,CAAK,aAAA;AAClB,IAAA,OAAO,MAAA,IAAU,WAAW,OAAA,EAAS;AACnC,MAAA,IAAI,MAAA,CAAO,YAAA,CAAa,MAAM,CAAA,KAAM,MAAA,EAAQ;AAC1C,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAA,GAAS,MAAA,CAAO,aAAA;AAAA,IAClB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,SAAS,QAAQ,MAAA,EAAiB;AAChC,IAAA,aAAA,CAAc,YAAA,CAAa,eAAA,EAAiB,MAAA,GAAS,MAAA,GAAS,OAAO,CAAA;AAAA,EACvE;AAEA,EAAA,SAAS,YAAY,SAAA,EAAmB;AACtC,IAAA,IAAI,eAAA,GAAkB,gBAAA,CAAiB,GAAA,CAAI,SAAS,CAAA;AACpD,IAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,aAAA,CAAc,CAAA,gBAAA,EAAmB,SAAS,CAAA,EAAA,CAAI,CAAA;AAC7E,MAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gDAAA,EAAmD,SAAS,CAAA,qBAAA,EAAwB,MAAM,CAAA,EAAA,CAAI,CAAA;AAC5G,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,eAAe,EAAA,EAAI;AACtB,QAAA,MAAM,WAAA,GAAc,WAAW,SAAS,CAAA,CAAA;AACxC,QAAA,cAAA,CAAe,EAAA,GAAK,WAAA;AACpB,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,iCAAA,EAAoC,SAAS,CAAA,iCAAA,EAAoC,WAAW,CAAA,EAAA,CAAI,CAAA;AAAA,MAC/G;AAEA,MAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE,CAAA;AAC7D,MAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,qCAAA,EAAwC,SAAS,CAAA,4CAAA,CAA8C,CAAA;AAC7G,QAAA;AAAA,MACF;AAEA,MAAA,eAAA,GAAkB,kBAAA,CAAmB;AAAA,QACnC,MAAA,EAAQ,SAAA;AAAA,QACR,cAAA;AAAA,QACA,WAAW,cAAA,CAAe;AAAA,OAC3B,CAAA;AACD,MAAA,gBAAA,CAAiB,GAAA,CAAI,WAAW,eAAe,CAAA;AAAA,IACjD;AAEA,IAAA,eAAA,CAAgB,QAAA,EAAS;AAAA,EAC3B;AAEA,EAAA,SAAS,YAAA,GAAe;AACtB,IAAA,SAAA,EAAU;AAAA,EACZ;AAEA,EAAA,SAAS,YAAA,GAAe;AACtB,IAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,IAAA,MAAM,YAAA,GAAe,eAAe,KAAK,CAAA;AAEzC,IAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,QAAA,EAAuB,KAAA,KAAkB;AACtD,MAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC7B,QAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAAyB,cAAA;AAAA,UACxC,KAAA;AAAA,UACA,YAAA;AAAA,UACA,KAAA;AAAA,UACA,OAAA;AAAA,UACA,aAAA;AAAA,UACA,WAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,OAAO,CAAA;AAC5C,QAAA,UAAA,CAAW,GAAA,CAAI,UAAU,OAAO,CAAA;AAAA,MAClC;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,eAAA,GAAkB;AACzB,IAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,IAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,QAAA,KAA0B;AACvC,MAAA,MAAM,OAAA,GAAU,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA;AACvC,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,OAAO,CAAA;AAC/C,QAAA,UAAA,CAAW,OAAO,QAAQ,CAAA;AAAA,MAC5B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,QAAA,GAAW;AAClB,IAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,OAAA;AACxB,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,MAAM,QAAQ,gBAAA,EAAiB;AAC/B,IAAA,YAAA,EAAa;AAEb,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,MAAA,KAAA,CAAM,CAAC,EAAE,KAAA,EAAM;AAAA,IACjB;AAAA,EACF;AAEA,EAAA,SAAS,SAAA,GAAY;AACnB,IAAA,eAAA,EAAgB;AAChB,IAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,MAAA;AACxB,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,aAAA,CAAc,KAAA,EAAM;AAAA,EACtB;AAEA,EAAA,SAAS,OAAA,GAAU;AACjB,IAAA,eAAA,EAAgB;AAChB,IAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,MAAA;AACxB,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,gBAAA,CAAiB,OAAA,CAAQ,CAAA,QAAA,KAAY,QAAA,CAAS,OAAA,EAAS,CAAA;AACvD,IAAA,gBAAA,CAAiB,KAAA,EAAM;AAAA,EACzB;AAEA,EAAA,SAAS,OAAA,GAAU;AACjB,IAAA,WAAA,GAAc,IAAA;AACd,IAAA,aAAA,GAAgB,IAAA;AAAA,EAClB;AAEA,EAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,OAAA,EAAS,OAAA,EAAQ;AACjD","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 handleMenuClose(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 handleMenuClose(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 case \"Tab\": {\n if (menuElementDiv && triggerButton && (!event.shiftKey || event.shiftKey)) {\n handleMenuClose(menuElementDiv, triggerButton);\n } \n break;\n }\n default:\n break;\n }\n}","/**\n * Adds keyboard interaction to toggle menu. The menu traps focus and can be interacted with using the keyboard. The first interactive item of the menu has focus when menu open.\n * @param {string} menuId - The id of the menu.\n * @param {string} menuItemsClass - The class of the items that are children of the menu.\n * @param {string} triggerId - The id of the button that triggers the menu.\n*/\n\nimport { handleKeyPress } from \"../../../utils/handleKeyPress/handleKeyPress\";\nimport { NodeListOfHTMLElement } from \"Types\";\n\n\nexport function makeMenuAccessible({ menuId, menuItemsClass, triggerId }: {menuId: string; menuItemsClass: string; triggerId: string;}) {\n const menuDiv = document.querySelector(`#${menuId}`) as HTMLElement;\n if (!menuDiv) {\n console.error(`[aria-ease] Element with id=\"${menuId}\" not found. Make sure the menu element exists before calling makeMenuAccessible.`);\n return { openMenu: () => {}, closeMenu: () => {}, cleanup: () => {} };\n }\n\n const triggerButton = document.querySelector(`#${triggerId}`) as HTMLElement;\n if (!triggerButton) {\n console.error(`[aria-ease] Element with id=\"${triggerId}\" not found. Make sure the trigger button element exists before calling makeMenuAccessible.`);\n return { openMenu: () => {}, closeMenu: () => {}, cleanup: () => {} };\n }\n\n const handlerMap = new Map<HTMLElement, (event: KeyboardEvent) => void>();\n const submenuInstances = new Map<string, ReturnType<typeof makeMenuAccessible>>();\n\n let cachedItems: NodeListOfHTMLElement | null = null;\n let filteredItems: HTMLElement[] | null = null;\n \n function getItems() {\n if (!cachedItems) {\n cachedItems = menuDiv.querySelectorAll(`.${menuItemsClass}`) as NodeListOfHTMLElement;\n }\n return cachedItems;\n }\n\n function getFilteredItems(): HTMLElement[] {\n if (!filteredItems) {\n const allItems = getItems();\n filteredItems = [];\n \n for (let i = 0; i < allItems.length; i++) {\n const item = allItems.item(i);\n const isNested = isItemInNestedSubmenu(item);\n \n if (!isNested) {\n if (!item.hasAttribute('tabindex')) {\n item.setAttribute('tabindex', '-1');\n }\n filteredItems.push(item);\n }\n }\n }\n return filteredItems;\n }\n\n function toNodeListLike(items: HTMLElement[]): NodeListOfHTMLElement {\n const nodeListLike = {\n length: items.length,\n item: (index: number) => items[index],\n forEach: (callback: (item: HTMLElement, index: number) => void) => {\n items.forEach(callback);\n },\n [Symbol.iterator]: function* () {\n for (const item of items) {\n yield item;\n }\n }\n };\n return nodeListLike as NodeListOfHTMLElement;\n }\n\n function isItemInNestedSubmenu(item: HTMLElement): boolean {\n let parent = item.parentElement;\n while (parent && parent !== menuDiv) {\n if (parent.getAttribute('role') === 'menu') {\n return true;\n }\n parent = parent.parentElement;\n }\n return false;\n }\n\n function setAria(isOpen: boolean) {\n triggerButton.setAttribute(\"aria-expanded\", isOpen ? \"true\" : \"false\");\n }\n\n function openSubmenu(submenuId: string) {\n let submenuInstance = submenuInstances.get(submenuId);\n if (!submenuInstance) {\n const submenuTrigger = menuDiv.querySelector(`[aria-controls=\"${submenuId}\"]`) as HTMLElement;\n if (!submenuTrigger) {\n console.error(`[aria-ease] Submenu trigger with aria-controls=\"${submenuId}\" not found in menu \"${menuId}\".`);\n return;\n }\n\n if (!submenuTrigger.id) {\n const generatedId = `trigger-${submenuId}`;\n submenuTrigger.id = generatedId;\n console.warn(`[aria-ease] Submenu trigger for \"${submenuId}\" had no ID. Auto-generated ID: \"${generatedId}\".`);\n }\n\n const submenuElement = document.querySelector(`#${submenuId}`);\n if (!submenuElement) {\n console.error(`[aria-ease] Submenu element with id=\"${submenuId}\" not found. Cannot create submenu instance.`);\n return;\n }\n\n submenuInstance = makeMenuAccessible({\n menuId: submenuId,\n menuItemsClass: menuItemsClass,\n triggerId: submenuTrigger.id\n });\n submenuInstances.set(submenuId, submenuInstance);\n }\n \n submenuInstance.openMenu();\n }\n\n function closeSubmenu() {\n closeMenu();\n }\n\n function addListeners() {\n const items = getFilteredItems();\n const nodeListLike = toNodeListLike(items);\n \n items.forEach((menuItem: HTMLElement, index: number) => {\n if (!handlerMap.has(menuItem)) {\n const handler = (event: KeyboardEvent) => handleKeyPress(\n event, \n nodeListLike, \n index, \n menuDiv, \n triggerButton,\n openSubmenu,\n closeSubmenu\n );\n menuItem.addEventListener(\"keydown\", handler);\n handlerMap.set(menuItem, handler);\n } \n });\n }\n\n function removeListeners() {\n const items = getFilteredItems();\n items.forEach((menuItem: HTMLElement) => {\n const handler = handlerMap.get(menuItem);\n if (handler) {\n menuItem.removeEventListener(\"keydown\", handler);\n handlerMap.delete(menuItem);\n }\n });\n }\n\n function openMenu() {\n menuDiv.style.display = \"block\";\n setAria(true);\n const items = getFilteredItems();\n addListeners();\n \n if (items.length > 0) {\n items[0].focus();\n }\n }\n\n function closeMenu() {\n removeListeners();\n menuDiv.style.display = \"none\";\n setAria(false);\n triggerButton.focus();\n }\n\n function cleanup() {\n removeListeners();\n menuDiv.style.display = \"none\";\n setAria(false);\n submenuInstances.forEach(instance => instance.cleanup());\n submenuInstances.clear();\n }\n\n function refresh() {\n cachedItems = null;\n filteredItems = null;\n }\n\n return { openMenu, closeMenu, cleanup, refresh };\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/menu/src/makeMenuAccessible/makeMenuAccessible.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Adds keyboard interaction to toggle menu. The menu traps focus and can be interacted with using the keyboard. The first interactive item of the menu has focus when menu open.\n * @param {string} menuId - The id of the menu.\n * @param {string} menuItemsClass - The class of the items that are children of the menu.\n * @param {string} triggerId - The id of the button that triggers the menu.\n*/\n\nimport { handleKeyPress } from \"../../../utils/handleKeyPress/handleKeyPress\";\nimport { NodeListOfHTMLElement } from \"Types\";\n\n\nexport function makeMenuAccessible({ menuId, menuItemsClass, triggerId }: {menuId: string; menuItemsClass: string; triggerId: string;}) {\n const menuDiv = document.querySelector(`#${menuId}`) as HTMLElement;\n if (!menuDiv) {\n console.error(`[aria-ease] Element with id=\"${menuId}\" not found. Make sure the menu element exists before calling makeMenuAccessible.`);\n return { openMenu: () => {}, closeMenu: () => {}, cleanup: () => {} };\n }\n\n const triggerButton = document.querySelector(`#${triggerId}`) as HTMLElement;\n if (!triggerButton) {\n console.error(`[aria-ease] Element with id=\"${triggerId}\" not found. Make sure the trigger button element exists before calling makeMenuAccessible.`);\n return { openMenu: () => {}, closeMenu: () => {}, cleanup: () => {} };\n }\n\n const handlerMap = new Map<HTMLElement, (event: KeyboardEvent) => void>();\n const submenuInstances = new Map<string, ReturnType<typeof makeMenuAccessible>>();\n\n let cachedItems: NodeListOfHTMLElement | null = null;\n let filteredItems: HTMLElement[] | null = null;\n \n function getItems() {\n if (!cachedItems) {\n cachedItems = menuDiv.querySelectorAll(`.${menuItemsClass}`) as NodeListOfHTMLElement;\n }\n return cachedItems;\n }\n\n function getFilteredItems(): HTMLElement[] {\n if (!filteredItems) {\n const allItems = getItems();\n filteredItems = [];\n \n for (let i = 0; i < allItems.length; i++) {\n const item = allItems.item(i);\n const isNested = isItemInNestedSubmenu(item);\n \n if (!isNested) {\n if (!item.hasAttribute('tabindex')) {\n item.setAttribute('tabindex', '-1');\n }\n filteredItems.push(item);\n }\n }\n }\n return filteredItems;\n }\n\n function toNodeListLike(items: HTMLElement[]): NodeListOfHTMLElement {\n const nodeListLike = {\n length: items.length,\n item: (index: number) => items[index],\n forEach: (callback: (item: HTMLElement, index: number) => void) => {\n items.forEach(callback);\n },\n [Symbol.iterator]: function* () {\n for (const item of items) {\n yield item;\n }\n }\n };\n return nodeListLike as NodeListOfHTMLElement;\n }\n\n function isItemInNestedSubmenu(item: HTMLElement): boolean {\n let parent = item.parentElement;\n while (parent && parent !== menuDiv) {\n if (parent.getAttribute('role') === 'menu') {\n return true;\n }\n parent = parent.parentElement;\n }\n return false;\n }\n\n function setAria(isOpen: boolean) {\n triggerButton.setAttribute(\"aria-expanded\", isOpen ? \"true\" : \"false\");\n }\n\n function openSubmenu(submenuId: string) {\n let submenuInstance = submenuInstances.get(submenuId);\n if (!submenuInstance) {\n const submenuTrigger = menuDiv.querySelector(`[aria-controls=\"${submenuId}\"]`) as HTMLElement;\n if (!submenuTrigger) {\n console.error(`[aria-ease] Submenu trigger with aria-controls=\"${submenuId}\" not found in menu \"${menuId}\".`);\n return;\n }\n\n if (!submenuTrigger.id) {\n const generatedId = `trigger-${submenuId}`;\n submenuTrigger.id = generatedId;\n console.warn(`[aria-ease] Submenu trigger for \"${submenuId}\" had no ID. Auto-generated ID: \"${generatedId}\".`);\n }\n\n const submenuElement = document.querySelector(`#${submenuId}`);\n if (!submenuElement) {\n console.error(`[aria-ease] Submenu element with id=\"${submenuId}\" not found. Cannot create submenu instance.`);\n return;\n }\n\n submenuInstance = makeMenuAccessible({\n menuId: submenuId,\n menuItemsClass: menuItemsClass,\n triggerId: submenuTrigger.id\n });\n submenuInstances.set(submenuId, submenuInstance);\n }\n \n submenuInstance.openMenu();\n }\n\n function closeSubmenu() {\n closeMenu();\n }\n\n function addListeners() {\n const items = getFilteredItems();\n const nodeListLike = toNodeListLike(items);\n \n items.forEach((menuItem: HTMLElement, index: number) => {\n if (!handlerMap.has(menuItem)) {\n const handler = (event: KeyboardEvent) => handleKeyPress(\n event, \n nodeListLike, \n index, \n menuDiv, \n triggerButton,\n openSubmenu,\n closeSubmenu\n );\n menuItem.addEventListener(\"keydown\", handler);\n handlerMap.set(menuItem, handler);\n } \n });\n }\n\n function removeListeners() {\n const items = getFilteredItems();\n items.forEach((menuItem: HTMLElement) => {\n const handler = handlerMap.get(menuItem);\n if (handler) {\n menuItem.removeEventListener(\"keydown\", handler);\n handlerMap.delete(menuItem);\n }\n });\n }\n\n function openMenu() {\n menuDiv.style.display = \"block\";\n setAria(true);\n const items = getFilteredItems();\n addListeners();\n \n if (items.length > 0) {\n items[0].focus();\n }\n }\n\n function closeMenu() {\n removeListeners();\n menuDiv.style.display = \"none\";\n setAria(false);\n triggerButton.focus();\n }\n\n function cleanup() {\n removeListeners();\n menuDiv.style.display = \"none\";\n setAria(false);\n submenuInstances.forEach(instance => instance.cleanup());\n submenuInstances.clear();\n }\n\n function refresh() {\n cachedItems = null;\n filteredItems = null;\n }\n\n return { openMenu, closeMenu, cleanup, refresh };\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/radio/src/updateRadioAriaAttributes/updateRadioAriaAttributes.ts"],"names":[],"mappings":";;;AAUO,SAAS,yBAAA,CAA0B,OAAA,EAAiB,WAAA,EAAqB,WAAA,EAA4B,wBAAA,EAAwC;AAChJ,EAAA,MAAM,QAAA,GAA+B,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AACzE,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,OAAO,CAAA,yFAAA,CAA2F,CAAA;AAChJ,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,UAAA,GAA4B,MAAM,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI,WAAW,EAAE,CAAC,CAAA;AACzF,EAAA,IAAG,UAAA,CAAW,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,WAAW,CAAA,sFAAA,CAAwF,CAAA;AACpJ,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,IAAA,OAAA,CAAQ,MAAM,CAAA,+HAAA,CAAiI,CAAA;AAC/I,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,wBAAA,GAA2B,CAAA,IAAK,wBAAA,IAA4B,WAAA,CAAY,MAAA,EAAQ;AAClF,IAAA,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,wBAAwB,CAAA,6CAAA,EAAgD,WAAA,CAAY,MAAM,CAAA,CAAA,CAAG,CAAA;AACtI,IAAA;AAAA,EACF;AAEA,EAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,EAAwB,KAAA,KAAkB;AAC5D,IAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,YAAA,CAAa,cAAc,CAAA;AACrD,IAAA,MAAM,kBAAkB,KAAA,KAAU,wBAAA,GAA4B,KAAA,CAAM,OAAA,GAAU,SAAS,OAAA,GAAW,OAAA;AAClG,IAAA,IAAI,OAAA,IAAW,YAAY,eAAA,EAAiB;AAC1C,MAAA,SAAA,CAAU,YAAA,CAAa,gBAAgB,eAAe,CAAA;AAAA,IACxD;AAAA,EACF,CAAC,CAAA;AACL","file":"index.cjs","sourcesContent":["/**\n * Adds screen reader accessibility to multiple radio buttons. Updates the aria attributes of the radio buttons. Radio elements must possess the following aria attributes; aria-checked and aria-label.\n * @param {string} radioId The id of the radio parent container.\n * @param {string} radiosClass The shared class of all the radios.\n * @param {RadioStates[]} radioStates Array of objects containing radio buttons state information.\n * @param {number} currentPressedRadioIndex Index of the currently checked or unchecked radio button.\n */\n\nimport { RadioStates } from \"../../../../Types\";\n\nexport function updateRadioAriaAttributes(radioId: string, radiosClass: string, radioStates: RadioStates[], currentPressedRadioIndex: number): void {\n const radioDiv: HTMLElement | null = document.querySelector(`#${radioId}`);\n if (!radioDiv) {\n console.error(`[aria-ease] Element with id=\"${radioId}\" not found. Make sure the radio element exists before calling updateRadioAriaAttributes.`);\n return;\n }\n \n const radioItems: HTMLElement[] = Array.from(radioDiv.querySelectorAll(`.${radiosClass}`));\n if(radioItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${radiosClass}\" not found. Make sure the radio items exist before calling updateRadioAriaAttributes.`);\n return;\n }\n\n if (radioStates.length === 0) {\n console.error(`[aria-ease] Radio states array is empty. Make sure the radioStates array is populated before calling updateRadioAriaAttributes.`);\n return;\n }\n\n if (currentPressedRadioIndex < 0 || currentPressedRadioIndex >= radioStates.length) {\n console.error(`[aria-ease] Radio index ${currentPressedRadioIndex} is out of bounds for states array of length ${radioStates.length}.`);\n return;\n }\n\n radioItems.forEach((radioItem: HTMLElement, index: number) => {\n const state = radioStates[index];\n const checked = radioItem.getAttribute(\"aria-checked\");\n const shouldBeChecked = index === currentPressedRadioIndex ? (state.checked ? \"true\" : \"false\") : \"false\";\n if (checked && checked !== shouldBeChecked) {\n radioItem.setAttribute(\"aria-checked\", shouldBeChecked);\n }\n });\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/radio/src/updateRadioAriaAttributes/updateRadioAriaAttributes.ts"],"names":[],"mappings":";AAUO,SAAS,yBAAA,CAA0B,OAAA,EAAiB,WAAA,EAAqB,WAAA,EAA4B,wBAAA,EAAwC;AAChJ,EAAA,MAAM,QAAA,GAA+B,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AACzE,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,OAAO,CAAA,yFAAA,CAA2F,CAAA;AAChJ,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,UAAA,GAA4B,MAAM,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,CAAA,EAAI,WAAW,EAAE,CAAC,CAAA;AACzF,EAAA,IAAG,UAAA,CAAW,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,WAAW,CAAA,sFAAA,CAAwF,CAAA;AACpJ,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,IAAA,OAAA,CAAQ,MAAM,CAAA,+HAAA,CAAiI,CAAA;AAC/I,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,wBAAA,GAA2B,CAAA,IAAK,wBAAA,IAA4B,WAAA,CAAY,MAAA,EAAQ;AAClF,IAAA,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,wBAAwB,CAAA,6CAAA,EAAgD,WAAA,CAAY,MAAM,CAAA,CAAA,CAAG,CAAA;AACtI,IAAA;AAAA,EACF;AAEA,EAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,EAAwB,KAAA,KAAkB;AAC5D,IAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,YAAA,CAAa,cAAc,CAAA;AACrD,IAAA,MAAM,kBAAkB,KAAA,KAAU,wBAAA,GAA4B,KAAA,CAAM,OAAA,GAAU,SAAS,OAAA,GAAW,OAAA;AAClG,IAAA,IAAI,OAAA,IAAW,YAAY,eAAA,EAAiB;AAC1C,MAAA,SAAA,CAAU,YAAA,CAAa,gBAAgB,eAAe,CAAA;AAAA,IACxD;AAAA,EACF,CAAC,CAAA;AACL","file":"index.js","sourcesContent":["/**\n * Adds screen reader accessibility to multiple radio buttons. Updates the aria attributes of the radio buttons. Radio elements must possess the following aria attributes; aria-checked and aria-label.\n * @param {string} radioId The id of the radio parent container.\n * @param {string} radiosClass The shared class of all the radios.\n * @param {RadioStates[]} radioStates Array of objects containing radio buttons state information.\n * @param {number} currentPressedRadioIndex Index of the currently checked or unchecked radio button.\n */\n\nimport { RadioStates } from \"../../../../Types\";\n\nexport function updateRadioAriaAttributes(radioId: string, radiosClass: string, radioStates: RadioStates[], currentPressedRadioIndex: number): void {\n const radioDiv: HTMLElement | null = document.querySelector(`#${radioId}`);\n if (!radioDiv) {\n console.error(`[aria-ease] Element with id=\"${radioId}\" not found. Make sure the radio element exists before calling updateRadioAriaAttributes.`);\n return;\n }\n \n const radioItems: HTMLElement[] = Array.from(radioDiv.querySelectorAll(`.${radiosClass}`));\n if(radioItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${radiosClass}\" not found. Make sure the radio items exist before calling updateRadioAriaAttributes.`);\n return;\n }\n\n if (radioStates.length === 0) {\n console.error(`[aria-ease] Radio states array is empty. Make sure the radioStates array is populated before calling updateRadioAriaAttributes.`);\n return;\n }\n\n if (currentPressedRadioIndex < 0 || currentPressedRadioIndex >= radioStates.length) {\n console.error(`[aria-ease] Radio index ${currentPressedRadioIndex} is out of bounds for states array of length ${radioStates.length}.`);\n return;\n }\n\n radioItems.forEach((radioItem: HTMLElement, index: number) => {\n const state = radioStates[index];\n const checked = radioItem.getAttribute(\"aria-checked\");\n const shouldBeChecked = index === currentPressedRadioIndex ? (state.checked ? \"true\" : \"false\") : \"false\";\n if (checked && checked !== shouldBeChecked) {\n radioItem.setAttribute(\"aria-checked\", shouldBeChecked);\n }\n });\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/toggle/src/updateToggleAriaAttribute/updateToggleAriaAttribute.ts"],"names":[],"mappings":";;;AAUO,SAAS,yBAAA,CAA0B,QAAA,EAAkB,YAAA,EAAsB,YAAA,EAA8B,yBAAA,EAAyC;AACvJ,EAAA,MAAM,SAAA,GAAgC,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAE,CAAA;AAC3E,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,QAAQ,CAAA,0FAAA,CAA4F,CAAA;AAClJ,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAA6B,MAAM,IAAA,CAAK,SAAA,CAAU,iBAAiB,CAAA,CAAA,EAAI,YAAY,EAAE,CAAC,CAAA;AAC5F,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,YAAY,CAAA,uFAAA,CAAyF,CAAA;AAEtJ,IAAA;AAAA,EACF;AAEA,EAAA,IAAG,WAAA,CAAY,MAAA,KAAW,YAAA,CAAa,MAAA,EAAQ;AAC7C,IAAA,OAAA,CAAQ,MAAM,CAAA,oDAAA,EAAuD,WAAA,CAAY,MAAM,CAAA,mBAAA,EAAsB,YAAA,CAAa,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAClJ,IAAA;AAAA,EACF;AAEA,EAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,MAAA,EAAQ,KAAA,KAAU;AACrC,IAAA,IAAI,UAAU,yBAAA,EAA2B;AACvC,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,YAAA,CAAa,cAAc,CAAA;AAClD,MAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,KAAK,CAAA,CAAE,UAAU,MAAA,GAAS,OAAA;AAC/D,MAAA,IAAI,OAAA,IAAW,YAAY,eAAA,EAAiB;AAC1C,QAAA,MAAA,CAAO,YAAA,CAAa,gBAAgB,eAAe,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH","file":"index.cjs","sourcesContent":["/**\n * Adds screen reader accessibility to toggle buttons. Updates the aria attributes of the toggle buttons. Button must be a semantic button element or a non-semantic element with a role of button, and possess the aria-pressed attribute.\n * @param {string} toggleId The id of the toggle buttons parent container.\n * @param {string} togglesClass The shared class of all the toggle buttons.\n * @param {ToggleStates[]} toggleStates Array of objects containing toggle buttons state information.\n * @param {number} currentPressedToggleIndex Index of the currently pressed or unpressed toggle button.\n*/\n\nimport { ToggleStates } from \"../../../../Types\";\n\nexport function updateToggleAriaAttribute(toggleId: string, togglesClass: string, toggleStates: ToggleStates[], currentPressedToggleIndex: number): void {\n const toggleDiv: HTMLElement | null = document.querySelector(`#${toggleId}`);\n if (!toggleDiv) {\n console.error(`[aria-ease] Element with id=\"${toggleId}\" not found. Make sure the toggle element exists before calling updateToggleAriaAttribute.`);\n return;\n }\n\n const toggleItems: HTMLElement[] = Array.from(toggleDiv.querySelectorAll(`.${togglesClass}`));\n if (toggleItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${togglesClass}\" not found. Make sure the toggle items exist before calling updateToggleAriaAttribute.`);\n \n return;\n }\n\n if(toggleItems.length !== toggleStates.length) {\n console.error(`[aria-ease] Toggle state/DOM length mismatch: found ${toggleItems.length} triggers, but got ${toggleStates.length} state objects.'`);\n return;\n }\n\n toggleItems.forEach((toggle, index) => {\n if (index === currentPressedToggleIndex) {\n const pressed = toggle.getAttribute(\"aria-pressed\");\n const shouldBePressed = toggleStates[index].pressed ? 'true' : 'false';\n if (pressed && pressed !== shouldBePressed) {\n toggle.setAttribute(\"aria-pressed\", shouldBePressed);\n }\n }\n });\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/toggle/src/updateToggleAriaAttribute/updateToggleAriaAttribute.ts"],"names":[],"mappings":";AAUO,SAAS,yBAAA,CAA0B,QAAA,EAAkB,YAAA,EAAsB,YAAA,EAA8B,yBAAA,EAAyC;AACvJ,EAAA,MAAM,SAAA,GAAgC,QAAA,CAAS,aAAA,CAAc,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAE,CAAA;AAC3E,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,QAAQ,CAAA,0FAAA,CAA4F,CAAA;AAClJ,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAA6B,MAAM,IAAA,CAAK,SAAA,CAAU,iBAAiB,CAAA,CAAA,EAAI,YAAY,EAAE,CAAC,CAAA;AAC5F,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,YAAY,CAAA,uFAAA,CAAyF,CAAA;AAEtJ,IAAA;AAAA,EACF;AAEA,EAAA,IAAG,WAAA,CAAY,MAAA,KAAW,YAAA,CAAa,MAAA,EAAQ;AAC7C,IAAA,OAAA,CAAQ,MAAM,CAAA,oDAAA,EAAuD,WAAA,CAAY,MAAM,CAAA,mBAAA,EAAsB,YAAA,CAAa,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAClJ,IAAA;AAAA,EACF;AAEA,EAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,MAAA,EAAQ,KAAA,KAAU;AACrC,IAAA,IAAI,UAAU,yBAAA,EAA2B;AACvC,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,YAAA,CAAa,cAAc,CAAA;AAClD,MAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,KAAK,CAAA,CAAE,UAAU,MAAA,GAAS,OAAA;AAC/D,MAAA,IAAI,OAAA,IAAW,YAAY,eAAA,EAAiB;AAC1C,QAAA,MAAA,CAAO,YAAA,CAAa,gBAAgB,eAAe,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH","file":"index.js","sourcesContent":["/**\n * Adds screen reader accessibility to toggle buttons. Updates the aria attributes of the toggle buttons. Button must be a semantic button element or a non-semantic element with a role of button, and possess the aria-pressed attribute.\n * @param {string} toggleId The id of the toggle buttons parent container.\n * @param {string} togglesClass The shared class of all the toggle buttons.\n * @param {ToggleStates[]} toggleStates Array of objects containing toggle buttons state information.\n * @param {number} currentPressedToggleIndex Index of the currently pressed or unpressed toggle button.\n*/\n\nimport { ToggleStates } from \"../../../../Types\";\n\nexport function updateToggleAriaAttribute(toggleId: string, togglesClass: string, toggleStates: ToggleStates[], currentPressedToggleIndex: number): void {\n const toggleDiv: HTMLElement | null = document.querySelector(`#${toggleId}`);\n if (!toggleDiv) {\n console.error(`[aria-ease] Element with id=\"${toggleId}\" not found. Make sure the toggle element exists before calling updateToggleAriaAttribute.`);\n return;\n }\n\n const toggleItems: HTMLElement[] = Array.from(toggleDiv.querySelectorAll(`.${togglesClass}`));\n if (toggleItems.length === 0) {\n console.error(`[aria-ease] Element with class=\"${togglesClass}\" not found. Make sure the toggle items exist before calling updateToggleAriaAttribute.`);\n \n return;\n }\n\n if(toggleItems.length !== toggleStates.length) {\n console.error(`[aria-ease] Toggle state/DOM length mismatch: found ${toggleItems.length} triggers, but got ${toggleStates.length} state objects.'`);\n return;\n }\n\n toggleItems.forEach((toggle, index) => {\n if (index === currentPressedToggleIndex) {\n const pressed = toggle.getAttribute(\"aria-pressed\");\n const shouldBePressed = toggleStates[index].pressed ? 'true' : 'false';\n if (pressed && pressed !== shouldBePressed) {\n toggle.setAttribute(\"aria-pressed\", shouldBePressed);\n }\n }\n });\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/utils/test/contract/contract.json","../../../../src/utils/test/contract/ContractReporter.ts"],"names":[],"mappings":"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","file":"chunk-UAS6V5MH.js","sourcesContent":["{\n \"menu\": {\n \"path\": \"./contracts/MenuContract.json\",\n \"component\": \"menu\"\n }\n}","/**\n * Contract Test Reporter - Vitest-style output for accessibility contract tests\n * Provides clear, actionable feedback with proper formatting and context\n */\n\ninterface TestResult {\n description: string;\n status: 'pass' | 'fail' | 'skip';\n failureMessage?: string;\n skipReason?: string;\n}\n\nexport class ContractReporter {\n private startTime: number = 0;\n private componentName: string = '';\n private staticPasses: number = 0;\n private staticFailures: number = 0;\n private dynamicResults: TestResult[] = [];\n private totalTests: number = 0;\n private skipped: number = 0;\n private isPlaywright: boolean = false;\n\n constructor(isPlaywright: boolean = false) {\n this.isPlaywright = isPlaywright;\n }\n\n private log(message: string) {\n process.stderr.write(message + '\\n');\n }\n\n start(componentName: string, totalTests: number) {\n this.startTime = Date.now();\n this.componentName = componentName;\n this.totalTests = totalTests;\n \n const mode = this.isPlaywright ? 'Playwright (Real Browser)' : 'jsdom (Fast)';\n this.log(`\\n${'═'.repeat(60)}`);\n this.log(`🔍 Testing ${componentName} Component - ${mode}`);\n this.log(`${'═'.repeat(60)}\\n`);\n }\n\n reportStatic(passes: number, failures: number) {\n this.staticPasses = passes;\n this.staticFailures = failures;\n \n const icon = failures === 0 ? '✅' : '❌';\n const status = failures === 0 ? 'PASS' : 'FAIL';\n \n this.log(`${icon} Static ARIA Tests: ${status}`);\n this.log(` ${passes}/${passes + failures} required attributes present\\n`);\n }\n\n /**\n * Report individual dynamic test result\n */\n reportTest(test: { description: string; requiresBrowser?: boolean }, status: 'pass' | 'fail' | 'skip', failureMessage?: string) {\n const result: TestResult = {\n description: test.description,\n status,\n failureMessage,\n };\n\n if (status === 'skip' && test.requiresBrowser) {\n result.skipReason = 'Requires real browser (addEventListener events)';\n }\n\n this.dynamicResults.push(result);\n\n const icons = { pass: '✓', fail: '✗', skip: '○' };\n //const colors = { pass: '', fail: '', skip: '' };\n \n this.log(` ${icons[status]} ${test.description}`);\n \n if (status === 'skip' && !this.isPlaywright) {\n this.log(` ↳ Skipped in jsdom (runs in Playwright)`);\n }\n \n if (status === 'fail' && failureMessage) {\n this.log(` ↳ ${failureMessage}`);\n }\n }\n\n /**\n * Report all failures with actionable context\n */\n private reportFailures(failures: string[]) {\n if (failures.length === 0) return;\n\n this.log(`\\n${'─'.repeat(60)}`);\n this.log(`❌ Failures (${failures.length}):\\n`);\n\n failures.forEach((failure, index) => {\n this.log(`${index + 1}. ${failure}`);\n \n if (failure.includes('aria-')) {\n this.log(` 💡 Add the missing ARIA attribute to improve screen reader support`);\n } else if (failure.includes('focus')) {\n this.log(` 💡 Check keyboard event handlers and focus management`);\n } else if (failure.includes('visible')) {\n this.log(` 💡 Verify display/visibility styles and state management`);\n }\n this.log('');\n });\n }\n\n /**\n * Report skipped tests with helpful context\n */\n private reportSkipped() {\n if (this.skipped === 0 || this.isPlaywright) return;\n\n const skippedTests = this.dynamicResults.filter(r => r.status === 'skip');\n \n this.log(`\\n${'─'.repeat(60)}`);\n this.log(`ℹ️ Skipped Tests (${this.skipped}):\\n`);\n this.log(`These tests use native keyboard events via addEventListener,`);\n this.log(`which jsdom cannot simulate. They run successfully in Playwright.\\n`);\n \n skippedTests.forEach((test, index) => {\n this.log(`${index + 1}. ${test.description}`);\n });\n \n this.log(`\\n💡 Run with Playwright for full validation:`);\n this.log(` testUiComponent('${this.componentName}', component, 'http://localhost:5173/')\\n`);\n }\n\n /**\n * Generate final summary with statistics\n */\n summary(failures: string[]) {\n const duration = Date.now() - this.startTime;\n //const totalDynamic = this.dynamicResults.length;\n const dynamicPasses = this.dynamicResults.filter(r => r.status === 'pass').length;\n const dynamicFailures = this.dynamicResults.filter(r => r.status === 'fail').length;\n this.skipped = this.dynamicResults.filter(r => r.status === 'skip').length;\n \n const totalPasses = this.staticPasses + dynamicPasses;\n const totalFailures = this.staticFailures + dynamicFailures;\n const totalRun = totalPasses + totalFailures;\n\n // Report failures first\n if (failures.length > 0) {\n this.reportFailures(failures);\n }\n\n // Report skipped tests\n this.reportSkipped();\n\n // Summary section\n this.log(`\\n${'═'.repeat(60)}`);\n this.log(`📊 Summary\\n`);\n \n if (totalFailures === 0 && this.skipped === 0) {\n this.log(`✅ All ${totalRun} tests passed!`);\n this.log(` ${this.componentName} component meets APG and WCAG guidelines ✓`);\n } else if (totalFailures === 0) {\n this.log(`✅ ${totalPasses}/${totalRun} tests passed`);\n this.log(`○ ${this.skipped} tests skipped (jsdom limitation)`);\n this.log(` ${this.componentName} component works correctly`);\n } else {\n this.log(`❌ ${totalFailures} test${totalFailures > 1 ? 's' : ''} failed`);\n this.log(`✅ ${totalPasses} test${totalPasses > 1 ? 's' : ''} passed`);\n if (this.skipped > 0) {\n this.log(`○ ${this.skipped} test${this.skipped > 1 ? 's' : ''} skipped`);\n }\n }\n \n this.log(`⏱️ Duration: ${duration}ms`);\n this.log(`${'═'.repeat(60)}\\n`);\n\n // Provide next steps\n if (totalFailures > 0) {\n this.log(`🔧 Next Steps:`);\n this.log(` 1. Review the failures above`);\n this.log(` 2. Fix ARIA attributes and keyboard handlers`);\n this.log(` 3. Re-run tests to verify fixes\\n`);\n } else if (!this.isPlaywright && this.skipped > 0) {\n this.log(`✨ Optional: Run Playwright tests for complete validation\\n`);\n }\n\n return {\n passes: totalPasses,\n failures: totalFailures,\n skipped: this.skipped,\n duration,\n };\n }\n\n /**\n * Report an error during test execution\n */\n error(message: string, context?: string) {\n this.log(`\\n❌ Error: ${message}`);\n if (context) {\n this.log(` Context: ${context}`);\n }\n this.log('');\n }\n}"]}
|