# 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 | `
` |
## Available Services
| Service | Purpose | Key Methods |
|---------|---------|-------------|
| `LiveAnnouncerService` | Screen reader announcements | `announce()`, `announceSequence()` |
| `FocusMonitorService` | Focus origin tracking | `monitor()`, `focusVia()` |
| `KeyboardManagerService` | Keyboard shortcuts | `registerGlobalShortcut()` |
| `HighContrastService` | Accessibility preferences | `getCurrentPreferences()` |
| `A11yConfigService` | Configuration management | `getConfig()`, `isEnabled()` |
## SCSS Utilities
```scss
// Import specific utilities
@use 'ui-accessibility/src/lib/utilities/focus-visible';
@use 'ui-accessibility/src/lib/utilities/screen-reader';
// Use utility classes
.my-element {
@extend .focus-ring; // Adds focus ring on :focus-visible
@extend .touch-target; // Ensures minimum touch target size
}
// Screen reader utilities
.sr-instructions {
@extend .sr-only; // Visually hidden, screen reader accessible
}
.status-text {
@extend .sr-only-focusable; // Hidden until focused
}
```
## WCAG 2.1 Compliance
This library helps achieve Level AA compliance:
- โ
**1.3.1** - Info and Relationships (ARIA attributes)
- โ
**1.4.3** - Contrast (High contrast mode support)
- โ
**1.4.13** - Content on Hover/Focus (Proper focus management)
- โ
**2.1.1** - Keyboard (Full keyboard navigation)
- โ
**2.1.2** - No Keyboard Trap (Proper focus trapping)
- โ
**2.4.1** - Bypass Blocks (Skip links)
- โ
**2.4.3** - Focus Order (Logical tab sequence)
- โ
**2.4.7** - Focus Visible (Enhanced focus indicators)
- โ
**3.2.1** - On Focus (Predictable focus behavior)
- โ
**4.1.3** - Status Messages (Live announcements)
## Browser Support
- Chrome 88+
- Firefox 85+
- Safari 14+
- Edge 88+
## Demo
Visit `/accessibility` in your demo application to see interactive examples of all features.
## Contributing
This library integrates seamlessly with your existing component architecture and design system tokens, requiring no rewrites of existing components.