houser-js-utils
Version:
A comprehensive collection of TypeScript utility functions for common development tasks including array manipulation, string processing, date handling, random number generation, validation, and much more.
1 lines • 13.4 kB
Source Map (JSON)
{"version":3,"file":"AccessibilityUtils.mjs","sources":["../src/AccessibilityUtils.ts"],"sourcesContent":["/**\n * @module AccessibilityUtils\n * @description A collection of utility functions for improving web accessibility, ARIA management, and inclusive design.\n * Provides methods for handling ARIA attributes, focus management, and keyboard navigation.\n *\n * @example\n * ```typescript\n * import { AccessibilityUtils } from 'houser-js-utils';\n *\n * // Set ARIA attributes\n * AccessibilityUtils.setAriaLabel(element, 'Close dialog');\n *\n * // Manage focus\n * AccessibilityUtils.trapFocus(modalElement);\n *\n * // Check accessibility\n * const isAccessible = AccessibilityUtils.hasValidAriaLabels(form);\n * ```\n */\n\nexport const AccessibilityUtils = {\n /**\n * Gets the ARIA described by attribute of an element\n * @param element - The DOM element to check\n * @returns The value of aria-describedby attribute or null if not set\n * @example\n * ```typescript\n * const element = document.querySelector('.input');\n * const describedBy = AccessibilityUtils.getAriaDescribedBy(element);\n * ```\n */\n getAriaDescribedBy(element: Element): string | null {\n return element.getAttribute(\"aria-describedby\");\n },\n\n /**\n * Sets the ARIA described by attribute of an element\n * @param element - The DOM element to modify\n * @param describedBy - The ID(s) of the element(s) that describe this element\n * @example\n * ```typescript\n * const input = document.querySelector('.input');\n * const helpText = document.querySelector('.help-text');\n * AccessibilityUtils.setAriaDescribedBy(input, helpText.id);\n * ```\n */\n setAriaDescribedBy(element: Element, describedBy: string): void {\n element.setAttribute(\"aria-describedby\", describedBy);\n },\n\n /**\n * Gets the ARIA expanded state of an element\n * @param element - Element to check\n * @returns ARIA expanded state\n */\n getAriaExpanded(element: Element): boolean | null {\n const expanded = element.getAttribute(\"aria-expanded\");\n return expanded === null ? null : expanded === \"true\";\n },\n\n /**\n * Sets the ARIA expanded state of an element\n * @param element - Element to modify\n * @param expanded - ARIA expanded state to set\n */\n setAriaExpanded(element: Element, expanded: boolean): void {\n element.setAttribute(\"aria-expanded\", expanded.toString());\n },\n\n /**\n * Gets the ARIA hidden state of an element\n * @param element - Element to check\n * @returns ARIA hidden state\n */\n getAriaHidden(element: Element): boolean | null {\n const hidden = element.getAttribute(\"aria-hidden\");\n return hidden === null ? null : hidden === \"true\";\n },\n\n /**\n * Sets the ARIA hidden state of an element\n * @param element - Element to modify\n * @param hidden - ARIA hidden state to set\n */\n setAriaHidden(element: Element, hidden: boolean): void {\n element.setAttribute(\"aria-hidden\", hidden.toString());\n },\n\n /**\n * Gets the ARIA invalid state of an element\n * @param element - Element to check\n * @returns ARIA invalid state\n */\n getAriaInvalid(element: Element): boolean | null {\n const invalid = element.getAttribute(\"aria-invalid\");\n return invalid === null ? null : invalid === \"true\";\n },\n\n /**\n * Sets the ARIA invalid state of an element\n * @param element - Element to modify\n * @param invalid - ARIA invalid state to set\n */\n setAriaInvalid(element: Element, invalid: boolean): void {\n element.setAttribute(\"aria-invalid\", invalid.toString());\n },\n\n /**\n * Gets the ARIA label of an element\n * @param element - Element to check\n * @returns ARIA label\n */\n getAriaLabel(element: Element): string | null {\n return element.getAttribute(\"aria-label\");\n },\n\n /**\n * Sets the ARIA label of an element\n * @param element - Element to modify\n * @param label - ARIA label to set\n */\n setAriaLabel(element: Element, label: string): void {\n element.setAttribute(\"aria-label\", label);\n },\n\n /**\n * Gets the ARIA required state of an element\n * @param element - Element to check\n * @returns ARIA required state\n */\n getAriaRequired(element: Element): boolean | null {\n const required = element.getAttribute(\"aria-required\");\n return required === null ? null : required === \"true\";\n },\n\n /**\n * Sets the ARIA required state of an element\n * @param element - Element to modify\n * @param required - ARIA required state to set\n */\n setAriaRequired(element: Element, required: boolean): void {\n element.setAttribute(\"aria-required\", required.toString());\n },\n\n /**\n * Gets the ARIA role of an element\n * @param element - Element to check\n * @returns ARIA role\n */\n getAriaRole(element: Element): string | null {\n return element.getAttribute(\"role\");\n },\n\n /**\n * Sets the ARIA role of an element\n * @param element - Element to modify\n * @param role - ARIA role to set\n */\n setAriaRole(element: Element, role: string): void {\n element.setAttribute(\"role\", role);\n },\n\n /**\n * Removes focus from an element\n * @param element - Element to blur\n */\n blurElement(element: Element): void {\n if (element instanceof HTMLElement) {\n element.blur();\n }\n },\n\n /**\n * Sets focus to an element\n * @param element - Element to focus\n */\n focusElement(element: Element): void {\n if (element instanceof HTMLElement) {\n element.focus();\n }\n },\n\n /**\n * Sets focus to the first focusable element in a container\n * @param container - Container element\n */\n focusFirstElement(container: Element): void {\n const focusableElements = this.getFocusableElements(container);\n if (focusableElements.length > 0) {\n (focusableElements[0] as HTMLElement).focus();\n }\n },\n\n /**\n * Sets focus to the last focusable element in a container\n * @param container - Container element\n */\n focusLastElement(container: Element): void {\n const focusableElements = this.getFocusableElements(container);\n if (focusableElements.length > 0) {\n (focusableElements[focusableElements.length - 1] as HTMLElement).focus();\n }\n },\n\n /**\n * Sets focus to the next focusable element\n * @param currentElement - Current element\n */\n focusNextElement(currentElement: Element): void {\n const focusableElements = this.getFocusableElements(document.body);\n const currentIndex = focusableElements.indexOf(currentElement);\n if (currentIndex < focusableElements.length - 1) {\n (focusableElements[currentIndex + 1] as HTMLElement).focus();\n }\n },\n\n /**\n * Sets focus to the previous focusable element\n * @param currentElement - Current element\n */\n focusPreviousElement(currentElement: Element): void {\n const focusableElements = this.getFocusableElements(document.body);\n const currentIndex = focusableElements.indexOf(currentElement);\n if (currentIndex > 0) {\n (focusableElements[currentIndex - 1] as HTMLElement).focus();\n }\n },\n\n /**\n * Gets all focusable elements within a container\n * @param container - Container element\n * @returns Array of focusable elements\n */\n getFocusableElements(container: Element): Element[] {\n const elements = container.querySelectorAll(\"*\");\n return Array.from(elements).filter((element) => this.isFocusable(element));\n },\n\n /**\n * Gets the current focus element\n * @returns Currently focused element\n */\n getFocusedElement(): Element | null {\n return document.activeElement;\n },\n\n /**\n * Checks if an element is focusable\n * @param element - Element to check\n * @returns True if element is focusable\n */\n isFocusable(element: Element): boolean {\n if (!(element instanceof HTMLElement)) {\n return false;\n }\n\n if (element.tabIndex < 0) {\n return false;\n }\n\n if (\"disabled\" in element && element.disabled) {\n return false;\n }\n\n switch (element.tagName.toLowerCase()) {\n case \"a\":\n case \"button\":\n case \"input\":\n case \"select\":\n case \"textarea\":\n return true;\n default:\n return false;\n }\n },\n\n /**\n * Traps focus within a container element, typically used for modals or dialogs\n * @param container - The container element to trap focus within\n * @returns A function that removes the focus trap when called\n * @example\n * ```typescript\n * const modal = document.querySelector('.modal');\n * const removeTrap = AccessibilityUtils.trapFocus(modal);\n *\n * // Later, when the modal is closed:\n * removeTrap();\n * ```\n */\n trapFocus(container: Element): () => void {\n const focusableElements = this.getFocusableElements(container);\n const firstFocusableElement = focusableElements[0];\n const lastFocusableElement =\n focusableElements[focusableElements.length - 1];\n\n const handleKeyDown = (event: Event) => {\n if (!(event instanceof KeyboardEvent) || event.key !== \"Tab\") {\n return;\n }\n\n if (event.shiftKey) {\n if (document.activeElement === firstFocusableElement) {\n event.preventDefault();\n (lastFocusableElement as HTMLElement).focus();\n }\n } else {\n if (document.activeElement === lastFocusableElement) {\n event.preventDefault();\n (firstFocusableElement as HTMLElement).focus();\n }\n }\n };\n\n container.addEventListener(\"keydown\", handleKeyDown as EventListener);\n return () =>\n container.removeEventListener(\"keydown\", handleKeyDown as EventListener);\n },\n};\n"],"names":[],"mappings":"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"}