# UI Accessibility A comprehensive Angular accessibility library that enhances your existing components with WCAG 2.1 Level AA compliant features while using semantic tokens from your design system. ## Features - **๐ŸŽฏ Focus Management** - Advanced focus trapping, restoration, and monitoring - **โŒจ๏ธ Keyboard Navigation** - Arrow keys, roving tabindex, custom shortcuts - **๐Ÿ“ข Screen Reader Support** - Live announcements, ARIA enhancements - **๐ŸŽจ Design System Integration** - Uses semantic motion, color, and spacing tokens - **โ™ฟ High Contrast & Reduced Motion** - Automatic detection and adaptation - **๐Ÿ”ง Zero Rewrites Required** - Enhance existing components with directives - **๐Ÿงช Developer Experience** - Debug modes, warnings, and comprehensive logging ## Installation ```bash npm install ui-accessibility ``` ## Quick Start ### 1. Import the Module ```typescript import { UiAccessibilityModule } from 'ui-accessibility'; @NgModule({ imports: [ UiAccessibilityModule.forRoot({ // Optional configuration skipLinks: { enabled: true }, keyboard: { enableArrowNavigation: true }, development: { warnings: true } }) ] }) export class AppModule {} ``` ### 2. Import SCSS Utilities ```scss // Import accessibility utilities (uses your semantic tokens) @use 'ui-accessibility/src/lib/utilities/a11y-utilities'; ``` ### 3. Add Skip Links ```html ``` ## Core Features ### Focus Trap Directive Trap focus within containers like modals and drawers: ```html

Settings

Settings

``` **Features:** - Automatic focus on first element - Tab wrapping within container - Focus restoration on close - Uses semantic motion tokens for transitions ### Arrow Navigation Directive Add keyboard navigation to lists, menus, and grids: ```html Profile Settings Logout Profile Settings Logout ``` **Navigation Options:** - `vertical` - Up/Down arrows - `horizontal` - Left/Right arrows - `both` - All arrow keys - `grid` - 2D navigation with column support ### Live Announcer Service Announce dynamic content changes to screen readers: ```typescript import { LiveAnnouncerService } from 'ui-accessibility'; constructor(private announcer: LiveAnnouncerService) {} // Announce with different politeness levels onItemAdded() { this.announcer.announce('Item added to cart', 'polite'); } onError() { this.announcer.announce('Error: Please fix the required fields', 'assertive'); } // Announce a sequence of messages onProcessComplete() { this.announcer.announceSequence([ 'Processing started', 'Validating data', 'Processing complete' ], 'polite', 1500); } ``` ### Screen Reader Components Hide content visually while keeping it accessible: ```html Additional context for screen readers Press Enter to activate Please correct the errors below ``` ### Keyboard Manager Service Register global and element-specific keyboard shortcuts: ```typescript import { KeyboardManagerService } from 'ui-accessibility'; constructor(private keyboard: KeyboardManagerService) {} ngOnInit() { // Global shortcut this.keyboard.registerGlobalShortcut('save', { key: 's', ctrlKey: true, description: 'Save document', handler: () => this.save() }); // Element-specific shortcut const element = this.elementRef.nativeElement; this.keyboard.registerElementShortcut('close', element, { key: 'Escape', description: 'Close dialog', handler: () => this.close() }); } ``` ## Design System Integration All features use semantic tokens from your design system: ### Focus Indicators ```scss // Automatic integration with your focus tokens .my-component:focus-visible { outline: $semantic-border-focus-width solid $semantic-color-focus; box-shadow: $semantic-shadow-input-focus; transition: outline-color $semantic-motion-duration-fast; } ``` ### Skip Links Styling Uses your semantic spacing, colors, and typography: ```scss .skip-link { padding: $semantic-spacing-component-padding-y $semantic-spacing-component-padding-x; background: $semantic-color-surface-primary; color: $semantic-color-text-primary; border-color: $semantic-color-border-focus; } ``` ### Motion & Animations Respects reduced motion preferences: ```typescript // Service automatically detects preference const duration = this.highContrast.getMotionDuration('300ms', '0.01s'); // SCSS utilities adapt automatically @media (prefers-reduced-motion: reduce) { .fade-in-a11y { animation-duration: 0.01s; } } ``` ## Advanced Configuration ### Full Configuration Example ```typescript UiAccessibilityModule.forRoot({ announcer: { defaultPoliteness: 'polite', defaultDuration: 4000, enabled: true }, focusManagement: { trapFocus: true, restoreFocus: true, focusVisibleEnabled: true }, keyboard: { enableShortcuts: true, enableArrowNavigation: true, customShortcuts: [ { key: '/', ctrlKey: true, description: 'Search' } ] }, skipLinks: { enabled: true, position: 'top', links: [ { href: '#main', text: 'Skip to main content' }, { href: '#nav', text: 'Skip to navigation' }, { href: '#search', text: 'Skip to search' } ] }, accessibility: { respectReducedMotion: true, respectHighContrast: true, injectAccessibilityStyles: true, addBodyClasses: true }, development: { warnings: true, logging: true } }) ``` ### High Contrast & Reduced Motion Automatic detection and CSS class application: ```html ``` ## Available Directives | Directive | Purpose | Usage | |-----------|---------|--------| | `uiFocusTrap` | Trap focus within container | `
` | | `uiArrowNavigation` | Arrow key navigation | `