Add comprehensive library expansion with new components and demos
- Add new libraries: ui-accessibility, ui-animations, ui-backgrounds, ui-code-display, ui-data-utils, ui-font-manager, hcl-studio - Add extensive layout components: gallery-grid, infinite-scroll-container, kanban-board, masonry, split-view, sticky-layout - Add comprehensive demo components for all new features - Update project configuration and dependencies - Expand component exports and routing structure - Add UI landing pages planning document 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
364
projects/ui-accessibility/README.md
Normal file
364
projects/ui-accessibility/README.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# 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
|
||||
<!-- Add to your app.component.html -->
|
||||
<ui-skip-links></ui-skip-links>
|
||||
```
|
||||
|
||||
## Core Features
|
||||
|
||||
### Focus Trap Directive
|
||||
|
||||
Trap focus within containers like modals and drawers:
|
||||
|
||||
```html
|
||||
<!-- Before: Basic modal -->
|
||||
<ui-modal [open]="isOpen">
|
||||
<h2>Settings</h2>
|
||||
<input type="text" placeholder="Name">
|
||||
<button>Save</button>
|
||||
</ui-modal>
|
||||
|
||||
<!-- After: Focus-trapped modal -->
|
||||
<ui-modal [open]="isOpen" uiFocusTrap>
|
||||
<h2>Settings</h2>
|
||||
<input type="text" placeholder="Name">
|
||||
<button>Save</button>
|
||||
</ui-modal>
|
||||
```
|
||||
|
||||
**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
|
||||
<!-- Before: Basic menu -->
|
||||
<ui-menu>
|
||||
<ui-menu-item>Profile</ui-menu-item>
|
||||
<ui-menu-item>Settings</ui-menu-item>
|
||||
<ui-menu-item>Logout</ui-menu-item>
|
||||
</ui-menu>
|
||||
|
||||
<!-- After: Keyboard navigable menu -->
|
||||
<ui-menu uiArrowNavigation="vertical">
|
||||
<ui-menu-item tabindex="0">Profile</ui-menu-item>
|
||||
<ui-menu-item tabindex="-1">Settings</ui-menu-item>
|
||||
<ui-menu-item tabindex="-1">Logout</ui-menu-item>
|
||||
</ui-menu>
|
||||
```
|
||||
|
||||
**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
|
||||
<!-- Screen reader only text -->
|
||||
<ui-screen-reader-only>
|
||||
Additional context for screen readers
|
||||
</ui-screen-reader-only>
|
||||
|
||||
<!-- Focusable hidden text (becomes visible on focus) -->
|
||||
<ui-screen-reader-only type="focusable">
|
||||
Press Enter to activate
|
||||
</ui-screen-reader-only>
|
||||
|
||||
<!-- Status messages -->
|
||||
<ui-screen-reader-only type="status" statusType="error" [visible]="hasError">
|
||||
Please correct the errors below
|
||||
</ui-screen-reader-only>
|
||||
```
|
||||
|
||||
### 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
|
||||
<!-- Body classes added automatically -->
|
||||
<body class="prefers-reduced-motion prefers-high-contrast">
|
||||
|
||||
<!-- Your CSS can respond -->
|
||||
<style>
|
||||
.prefers-reduced-motion * {
|
||||
animation-duration: 0.01s !important;
|
||||
}
|
||||
|
||||
.prefers-high-contrast .card {
|
||||
border: 1px solid ButtonText;
|
||||
background: ButtonFace;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Available Directives
|
||||
|
||||
| Directive | Purpose | Usage |
|
||||
|-----------|---------|--------|
|
||||
| `uiFocusTrap` | Trap focus within container | `<div uiFocusTrap>` |
|
||||
| `uiArrowNavigation` | Arrow key navigation | `<ul uiArrowNavigation="vertical">` |
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user