@ordojs/accessibility
Version:
Comprehensive accessibility system for OrdoJS with ARIA generation, automated testing, and screen reader support
1 lines • 22.1 kB
Source Map (JSON)
{"version":3,"sources":["../../src/focus/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @fileoverview OrdoJS Accessibility - Focus Management Module\n *\n * Focus management, skip links, and keyboard navigation.\n */\n\nimport { EventEmitter } from 'events';\nimport type {\n FocusConfig,\n FocusInfo,\n KeyboardNavigation\n} from '../types/index.js';\n\n/**\n * Focus manager for handling focus management and keyboard navigation\n */\nexport class FocusManager extends EventEmitter {\n private config: FocusConfig;\n private focusableElements: Map<string, FocusInfo>;\n private focusTraps: Map<string, string[]>;\n private skipLinks: Map<string, string>;\n private isInitialized: boolean;\n\n /**\n * Create a new FocusManager instance\n *\n * @param config - Focus configuration\n */\n constructor(config: FocusConfig) {\n super();\n\n this.config = config;\n this.focusableElements = new Map();\n this.focusTraps = new Map();\n this.skipLinks = new Map();\n this.isInitialized = false;\n }\n\n /**\n * Initialize the focus manager\n */\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n console.warn('Focus manager is already initialized');\n return;\n }\n\n try {\n // Initialize focus management\n await this.initializeFocusManagement();\n\n this.isInitialized = true;\n console.log('Focus manager initialized successfully');\n\n this.emit('initialized');\n } catch (error) {\n console.error('Failed to initialize focus manager:', error);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Register focusable element\n *\n * @param element - Element selector\n * @param info - Focus information\n */\n registerFocusableElement(element: string, info: Partial<FocusInfo> = {}): void {\n const focusInfo: FocusInfo = {\n element,\n tabIndex: info.tabIndex || 0,\n focusOrder: info.focusOrder || 0,\n focusable: info.focusable !== false,\n focused: false,\n focusTrap: info.focusTrap || false,\n skipLink: info.skipLink || false,\n ariaState: info.ariaState || {},\n ariaProperty: info.ariaProperty || {}\n };\n\n // Only set optional properties if they have values\n if (info.ariaLabel) {\n focusInfo.ariaLabel = info.ariaLabel;\n }\n if (info.ariaDescription) {\n focusInfo.ariaDescription = info.ariaDescription;\n }\n if (info.ariaRole) {\n focusInfo.ariaRole = info.ariaRole;\n }\n\n this.focusableElements.set(element, focusInfo);\n this.emit('elementRegistered', focusInfo);\n }\n\n /**\n * Create focus trap\n *\n * @param trapId - Focus trap ID\n * @param elements - Elements in the trap\n * @param options - Trap options\n */\n createFocusTrap(\n trapId: string,\n elements: string[],\n options: {\n restoreFocus?: boolean;\n initialFocus?: string;\n returnFocus?: boolean;\n } = {}\n ): void {\n this.focusTraps.set(trapId, elements);\n\n // Set focus order for trapped elements\n elements.forEach((element, index) => {\n const focusInfo = this.focusableElements.get(element);\n if (focusInfo) {\n focusInfo.focusOrder = index;\n focusInfo.focusTrap = true;\n this.focusableElements.set(element, focusInfo);\n }\n });\n\n // Set initial focus\n if (options.initialFocus) {\n this.setFocus(options.initialFocus);\n }\n\n this.emit('focusTrapCreated', { trapId, elements, options });\n }\n\n /**\n * Remove focus trap\n *\n * @param trapId - Focus trap ID\n * @param options - Removal options\n */\n removeFocusTrap(\n trapId: string,\n options: {\n restoreFocus?: boolean;\n returnFocus?: boolean;\n } = {}\n ): void {\n const elements = this.focusTraps.get(trapId);\n if (elements) {\n // Remove focus trap from elements\n elements.forEach(element => {\n const focusInfo = this.focusableElements.get(element);\n if (focusInfo) {\n focusInfo.focusTrap = false;\n this.focusableElements.set(element, focusInfo);\n }\n });\n\n this.focusTraps.delete(trapId);\n this.emit('focusTrapRemoved', { trapId, options });\n }\n }\n\n /**\n * Set focus to element\n *\n * @param element - Element selector\n */\n setFocus(element: string): void {\n const focusInfo = this.focusableElements.get(element);\n if (focusInfo && focusInfo.focusable) {\n // Clear previous focus\n for (const info of this.focusableElements.values()) {\n info.focused = false;\n }\n\n // Set new focus\n focusInfo.focused = true;\n this.focusableElements.set(element, focusInfo);\n\n this.emit('focusChanged', focusInfo);\n }\n }\n\n /**\n * Move focus to next element\n *\n * @param currentElement - Current element\n * @returns Next focused element or undefined\n */\n moveToNextElement(currentElement: string): FocusInfo | undefined {\n const current = this.focusableElements.get(currentElement);\n if (!current) return undefined;\n\n const focusableElements = Array.from(this.focusableElements.values())\n .filter(info => info.focusable)\n .sort((a, b) => a.focusOrder - b.focusOrder);\n\n const currentIndex = focusableElements.findIndex(info => info.element === currentElement);\n if (currentIndex === -1) return undefined;\n\n const nextIndex = (currentIndex + 1) % focusableElements.length;\n const nextElement = focusableElements[nextIndex];\n\n if (nextElement) {\n this.setFocus(nextElement.element);\n return nextElement;\n }\n return undefined;\n }\n\n /**\n * Move focus to previous element\n *\n * @param currentElement - Current element\n * @returns Previous focused element or undefined\n */\n moveToPreviousElement(currentElement: string): FocusInfo | undefined {\n const current = this.focusableElements.get(currentElement);\n if (!current) return undefined;\n\n const focusableElements = Array.from(this.focusableElements.values())\n .filter(info => info.focusable)\n .sort((a, b) => a.focusOrder - b.focusOrder);\n\n const currentIndex = focusableElements.findIndex(info => info.element === currentElement);\n if (currentIndex === -1) return undefined;\n\n const prevIndex = currentIndex === 0 ? focusableElements.length - 1 : currentIndex - 1;\n const prevElement = focusableElements[prevIndex];\n\n if (prevElement) {\n this.setFocus(prevElement.element);\n return prevElement;\n }\n return undefined;\n }\n\n /**\n * Add skip link\n *\n * @param target - Target element\n * @param label - Skip link label\n * @param position - Skip link position\n */\n addSkipLink(\n target: string,\n label: string,\n position: 'top' | 'bottom' = 'top'\n ): void {\n this.skipLinks.set(target, label);\n this.emit('skipLinkAdded', { target, label, position });\n }\n\n /**\n * Remove skip link\n *\n * @param target - Target element\n */\n removeSkipLink(target: string): void {\n this.skipLinks.delete(target);\n this.emit('skipLinkRemoved', { target });\n }\n\n /**\n * Handle keyboard navigation\n *\n * @param event - Keyboard event\n * @param currentElement - Current element\n * @returns Navigation result\n */\n handleKeyboardNavigation(\n event: KeyboardEvent,\n currentElement: string\n ): {\n handled: boolean;\n action: string;\n target?: string;\n } {\n const navigation: KeyboardNavigation = {\n id: `nav_${Date.now()}`,\n type: 'custom',\n key: event.key,\n keyCode: event.keyCode,\n target: currentElement,\n action: '',\n description: '',\n enabled: true,\n visible: true\n };\n\n let handled = false;\n let action = '';\n\n switch (event.key) {\n case 'Tab':\n if (event.shiftKey) {\n const prevElement = this.moveToPreviousElement(currentElement);\n if (prevElement) {\n action = 'moveToPrevious';\n handled = true;\n }\n } else {\n const nextElement = this.moveToNextElement(currentElement);\n if (nextElement) {\n action = 'moveToNext';\n handled = true;\n }\n }\n break;\n\n case 'Escape':\n // Exit focus trap or close modal\n action = 'escape';\n handled = true;\n break;\n\n case 'Enter':\n case ' ':\n // Activate element\n action = 'activate';\n handled = true;\n break;\n\n case 'ArrowUp':\n // Navigate up\n action = 'navigateUp';\n handled = true;\n break;\n\n case 'ArrowDown':\n // Navigate down\n action = 'navigateDown';\n handled = true;\n break;\n\n case 'ArrowLeft':\n // Navigate left\n action = 'navigateLeft';\n handled = true;\n break;\n\n case 'ArrowRight':\n // Navigate right\n action = 'navigateRight';\n handled = true;\n break;\n\n case 'Home':\n // Move to first element\n action = 'moveToFirst';\n handled = true;\n break;\n\n case 'End':\n // Move to last element\n action = 'moveToLast';\n handled = true;\n break;\n }\n\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n navigation.action = action;\n this.emit('keyboardNavigation', navigation);\n\n return {\n handled,\n action,\n target: currentElement\n };\n }\n\n /**\n * Get focusable elements\n *\n * @returns Array of focusable elements\n */\n getFocusableElements(): FocusInfo[] {\n return Array.from(this.focusableElements.values())\n .filter(info => info.focusable)\n .sort((a, b) => a.focusOrder - b.focusOrder);\n }\n\n /**\n * Get focus trap elements\n *\n * @param trapId - Focus trap ID\n * @returns Array of trapped elements\n */\n getFocusTrapElements(trapId: string): FocusInfo[] {\n const elements = this.focusTraps.get(trapId);\n if (!elements) return [];\n\n return elements\n .map(element => this.focusableElements.get(element))\n .filter((info): info is FocusInfo => info !== undefined)\n .sort((a, b) => a.focusOrder - b.focusOrder);\n }\n\n /**\n * Get skip links\n *\n * @returns Array of skip links\n */\n getSkipLinks(): Array<{ target: string; label: string }> {\n return Array.from(this.skipLinks.entries()).map(([target, label]) => ({\n target,\n label\n }));\n }\n\n /**\n * Get currently focused element\n *\n * @returns Focused element or undefined\n */\n getFocusedElement(): FocusInfo | undefined {\n return Array.from(this.focusableElements.values()).find(info => info.focused);\n }\n\n /**\n * Get focus manager statistics\n *\n * @returns Statistics\n */\n getStats(): {\n totalElements: number;\n focusableElements: number;\n focusedElements: number;\n focusTraps: number;\n skipLinks: number;\n } {\n const totalElements = this.focusableElements.size;\n const focusableElements = Array.from(this.focusableElements.values())\n .filter(info => info.focusable).length;\n const focusedElements = Array.from(this.focusableElements.values())\n .filter(info => info.focused).length;\n\n return {\n totalElements,\n focusableElements,\n focusedElements,\n focusTraps: this.focusTraps.size,\n skipLinks: this.skipLinks.size\n };\n }\n\n /**\n * Initialize focus management\n */\n private async initializeFocusManagement(): Promise<void> {\n console.log('Initializing focus management...');\n\n // Set up focus indicators if enabled\n if (this.config.focusIndicators) {\n this.setupFocusIndicators();\n }\n\n // Set up skip links if enabled\n if (this.config.skipLinks) {\n this.setupSkipLinks();\n }\n\n // Set up focus restoration if enabled\n if (this.config.focusRestoration) {\n this.setupFocusRestoration();\n }\n }\n\n /**\n * Setup focus indicators\n */\n private setupFocusIndicators(): void {\n // This is a simplified implementation\n // In a real implementation, you would add CSS for focus indicators\n console.log('Setting up focus indicators...');\n }\n\n /**\n * Setup skip links\n */\n private setupSkipLinks(): void {\n // This is a simplified implementation\n // In a real implementation, you would create skip link elements\n console.log('Setting up skip links...');\n }\n\n /**\n * Setup focus restoration\n */\n private setupFocusRestoration(): void {\n // This is a simplified implementation\n // In a real implementation, you would track focus history\n console.log('Setting up focus restoration...');\n }\n}\n"]}