@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/dist/index.d.ts +131 -131
- package/dist/index.esm.js +148 -148
- package/dist/index.js +148 -148
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/ui/accessibility-demo.tsx +271 -0
- package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
- package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
- package/src/components/ui/advanced-transition-system.tsx +395 -0
- package/src/components/ui/animation/animated-container.tsx +166 -0
- package/src/components/ui/animation/index.ts +19 -0
- package/src/components/ui/animation/staggered-container.tsx +68 -0
- package/src/components/ui/animation-demo.tsx +250 -0
- package/src/components/ui/badge.tsx +33 -0
- package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
- package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
- package/src/components/ui/button.tsx +36 -0
- package/src/components/ui/card.tsx +207 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/color-preview.tsx +411 -0
- package/src/components/ui/data-display/chart.tsx +653 -0
- package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
- package/src/components/ui/data-display/data-grid.tsx +680 -0
- package/src/components/ui/data-display/list.tsx +456 -0
- package/src/components/ui/data-display/table.tsx +482 -0
- package/src/components/ui/data-display/timeline.tsx +441 -0
- package/src/components/ui/data-display/tree.tsx +602 -0
- package/src/components/ui/data-display/types.ts +536 -0
- package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
- package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
- package/src/components/ui/feedback/alert.tsx +157 -0
- package/src/components/ui/feedback/progress.tsx +292 -0
- package/src/components/ui/feedback/skeleton.tsx +185 -0
- package/src/components/ui/feedback/toast.tsx +280 -0
- package/src/components/ui/feedback/types.ts +125 -0
- package/src/components/ui/font-preview.tsx +288 -0
- package/src/components/ui/form-demo.tsx +553 -0
- package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
- package/src/components/ui/input.tsx +35 -0
- package/src/components/ui/label.tsx +16 -0
- package/src/components/ui/layout-demo.tsx +367 -0
- package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
- package/src/components/ui/layouts/desktop-layout.tsx +224 -0
- package/src/components/ui/layouts/index.ts +10 -0
- package/src/components/ui/layouts/mobile-layout.tsx +162 -0
- package/src/components/ui/layouts/tablet-layout.tsx +197 -0
- package/src/components/ui/mobile-form-validation.tsx +451 -0
- package/src/components/ui/mobile-input-demo.tsx +201 -0
- package/src/components/ui/mobile-input.tsx +281 -0
- package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
- package/src/components/ui/navigation/breadcrumb.tsx +158 -0
- package/src/components/ui/navigation/index.ts +36 -0
- package/src/components/ui/navigation/menu.tsx +374 -0
- package/src/components/ui/navigation/navigation-demo.tsx +324 -0
- package/src/components/ui/navigation/pagination.tsx +272 -0
- package/src/components/ui/navigation/sidebar.tsx +383 -0
- package/src/components/ui/navigation/stepper.tsx +303 -0
- package/src/components/ui/navigation/tabs.tsx +205 -0
- package/src/components/ui/navigation/types.ts +299 -0
- package/src/components/ui/overlay/backdrop.tsx +81 -0
- package/src/components/ui/overlay/focus-manager.tsx +143 -0
- package/src/components/ui/overlay/index.ts +36 -0
- package/src/components/ui/overlay/modal.tsx +270 -0
- package/src/components/ui/overlay/overlay-manager.tsx +110 -0
- package/src/components/ui/overlay/popover.tsx +462 -0
- package/src/components/ui/overlay/portal.tsx +79 -0
- package/src/components/ui/overlay/tooltip.tsx +303 -0
- package/src/components/ui/overlay/types.ts +196 -0
- package/src/components/ui/performance-demo.tsx +596 -0
- package/src/components/ui/semantic-input-system-demo.tsx +502 -0
- package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
- package/src/components/ui/tablet-layout.tsx +192 -0
- package/src/components/ui/theme-customizer.tsx +386 -0
- package/src/components/ui/theme-preview.tsx +310 -0
- package/src/components/ui/theme-switcher.tsx +264 -0
- package/src/components/ui/theme-toggle.tsx +38 -0
- package/src/components/ui/token-demo.tsx +195 -0
- package/src/components/ui/touch-demo.tsx +462 -0
- package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
- package/src/components/ui/touch-friendly-interface.tsx +296 -0
- package/src/hooks/index.ts +190 -0
- package/src/hooks/use-accessibility-support.ts +518 -0
- package/src/hooks/use-adaptive-layout.ts +289 -0
- package/src/hooks/use-advanced-patterns.ts +294 -0
- package/src/hooks/use-advanced-transition-system.ts +393 -0
- package/src/hooks/use-animation-profile.ts +288 -0
- package/src/hooks/use-battery-animations.ts +384 -0
- package/src/hooks/use-battery-conscious-loading.ts +475 -0
- package/src/hooks/use-battery-optimization.ts +330 -0
- package/src/hooks/use-battery-status.ts +299 -0
- package/src/hooks/use-component-performance.ts +344 -0
- package/src/hooks/use-device-loading-states.ts +459 -0
- package/src/hooks/use-device.tsx +110 -0
- package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
- package/src/hooks/use-form-feedback.ts +403 -0
- package/src/hooks/use-form-performance.ts +513 -0
- package/src/hooks/use-frame-rate.ts +251 -0
- package/src/hooks/use-gestures.ts +338 -0
- package/src/hooks/use-hardware-acceleration.ts +341 -0
- package/src/hooks/use-input-accessibility.ts +455 -0
- package/src/hooks/use-input-performance.ts +506 -0
- package/src/hooks/use-layout-performance.ts +319 -0
- package/src/hooks/use-loading-accessibility.ts +535 -0
- package/src/hooks/use-loading-performance.ts +473 -0
- package/src/hooks/use-memory-usage.ts +287 -0
- package/src/hooks/use-mobile-form-layout.ts +464 -0
- package/src/hooks/use-mobile-form-validation.ts +518 -0
- package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
- package/src/hooks/use-mobile-layout.ts +302 -0
- package/src/hooks/use-mobile-optimization.ts +406 -0
- package/src/hooks/use-mobile-skeleton.ts +402 -0
- package/src/hooks/use-mobile-touch.ts +414 -0
- package/src/hooks/use-performance-throttling.ts +348 -0
- package/src/hooks/use-performance.ts +316 -0
- package/src/hooks/use-reusable-architecture.ts +414 -0
- package/src/hooks/use-semantic-input-types.ts +357 -0
- package/src/hooks/use-semantic-input.ts +565 -0
- package/src/hooks/use-tablet-layout.ts +384 -0
- package/src/hooks/use-touch-friendly-input.ts +524 -0
- package/src/hooks/use-touch-friendly-interface.ts +331 -0
- package/src/hooks/use-touch-optimization.ts +375 -0
- package/src/index.ts +279 -279
- package/src/lib/utils.ts +6 -0
- package/src/themes/README.md +272 -0
- package/src/themes/ThemeContext.tsx +31 -0
- package/src/themes/ThemeProvider.tsx +232 -0
- package/src/themes/accessibility/index.ts +27 -0
- package/src/themes/accessibility.ts +259 -0
- package/src/themes/aria-patterns.ts +420 -0
- package/src/themes/base-themes.ts +55 -0
- package/src/themes/colorManager.ts +380 -0
- package/src/themes/examples/dark-theme.ts +154 -0
- package/src/themes/examples/minimal-theme.ts +108 -0
- package/src/themes/focus-management.ts +701 -0
- package/src/themes/fontLoader.ts +201 -0
- package/src/themes/high-contrast.ts +621 -0
- package/src/themes/index.ts +19 -0
- package/src/themes/inheritance.ts +227 -0
- package/src/themes/keyboard-navigation.ts +550 -0
- package/src/themes/motion-reduction.ts +662 -0
- package/src/themes/navigation.ts +238 -0
- package/src/themes/screen-reader.ts +645 -0
- package/src/themes/systemThemeDetector.ts +182 -0
- package/src/themes/themeCSSUpdater.ts +262 -0
- package/src/themes/themePersistence.ts +238 -0
- package/src/themes/themes/default.ts +586 -0
- package/src/themes/themes/harvey.ts +554 -0
- package/src/themes/themes/stan-design.ts +683 -0
- package/src/themes/types.ts +460 -0
- package/src/themes/useSystemTheme.ts +48 -0
- package/src/themes/useTheme.ts +87 -0
- package/src/themes/validation.ts +462 -0
- package/src/tokens/index.ts +34 -0
- package/src/tokens/tokenExporter.ts +397 -0
- package/src/tokens/tokenGenerator.ts +276 -0
- package/src/tokens/tokenManager.ts +248 -0
- package/src/tokens/tokenValidator.ts +543 -0
- package/src/tokens/types.ts +78 -0
- package/src/utils/bundle-analyzer.ts +260 -0
- package/src/utils/bundle-splitting.ts +483 -0
- package/src/utils/lazy-loading.ts +441 -0
- package/src/utils/performance-monitor.ts +513 -0
- package/src/utils/tree-shaking.ts +274 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface InputAccessibilityConfig {
|
|
4
|
+
enableARIA?: boolean
|
|
5
|
+
enableKeyboardNavigation?: boolean
|
|
6
|
+
enableScreenReader?: boolean
|
|
7
|
+
enableFocusManagement?: boolean
|
|
8
|
+
enableHighContrast?: boolean
|
|
9
|
+
enableReducedMotion?: boolean
|
|
10
|
+
enableVoiceControl?: boolean
|
|
11
|
+
ariaLabels?: Record<string, string>
|
|
12
|
+
focusTrap?: boolean
|
|
13
|
+
skipLinks?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface AccessibilityFeature {
|
|
17
|
+
id: string
|
|
18
|
+
name: string
|
|
19
|
+
type: 'aria' | 'keyboard' | 'screen-reader' | 'focus' | 'contrast' | 'motion' | 'voice'
|
|
20
|
+
enabled: boolean
|
|
21
|
+
impact: 'low' | 'medium' | 'high'
|
|
22
|
+
description: string
|
|
23
|
+
ariaLabel?: string
|
|
24
|
+
keyboardShortcut?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AccessibilityState {
|
|
28
|
+
isHighContrast: boolean
|
|
29
|
+
isReducedMotion: boolean
|
|
30
|
+
isVoiceControl: boolean
|
|
31
|
+
isKeyboardNavigating: boolean
|
|
32
|
+
isScreenReaderActive: boolean
|
|
33
|
+
focusIndex: number
|
|
34
|
+
accessibilityScore: number
|
|
35
|
+
activeFeatures: string[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface InputAccessibilityCallbacks {
|
|
39
|
+
onAccessibilityFeatureEnabled?: (feature: AccessibilityFeature) => void
|
|
40
|
+
onKeyboardNavigationEnabled?: (feature: string) => void
|
|
41
|
+
onScreenReaderOptimized?: (optimization: string) => void
|
|
42
|
+
onFocusManagementEnhanced?: (feature: string) => void
|
|
43
|
+
onAccessibilityScoreChanged?: (score: number) => void
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const useInputAccessibility = (
|
|
47
|
+
config: InputAccessibilityConfig = {},
|
|
48
|
+
callbacks: InputAccessibilityCallbacks = {}
|
|
49
|
+
) => {
|
|
50
|
+
const {
|
|
51
|
+
enableARIA = true,
|
|
52
|
+
enableKeyboardNavigation = true,
|
|
53
|
+
enableScreenReader = true,
|
|
54
|
+
enableFocusManagement = true,
|
|
55
|
+
enableHighContrast = true,
|
|
56
|
+
enableReducedMotion = true,
|
|
57
|
+
enableVoiceControl = true,
|
|
58
|
+
focusTrap = false
|
|
59
|
+
} = config
|
|
60
|
+
|
|
61
|
+
const [accessibilityFeatures, setAccessibilityFeatures] = useState<AccessibilityFeature[]>([])
|
|
62
|
+
const [accessibilityState, setAccessibilityState] = useState<AccessibilityState>({
|
|
63
|
+
isHighContrast: false,
|
|
64
|
+
isReducedMotion: false,
|
|
65
|
+
isVoiceControl: false,
|
|
66
|
+
isKeyboardNavigating: false,
|
|
67
|
+
isScreenReaderActive: false,
|
|
68
|
+
focusIndex: 0,
|
|
69
|
+
accessibilityScore: 0,
|
|
70
|
+
activeFeatures: []
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const [isEnhancing, setIsEnhancing] = useState(false)
|
|
74
|
+
const [enhancements, setEnhancements] = useState<string[]>([])
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
const accessibilityTimerRef = useRef<number | null>(null)
|
|
78
|
+
const motionQueryRef = useRef<MediaQueryList | null>(null)
|
|
79
|
+
const contrastQueryRef = useRef<MediaQueryList | null>(null)
|
|
80
|
+
|
|
81
|
+
// Initialize accessibility features
|
|
82
|
+
const initializeAccessibilityFeatures = useCallback(() => {
|
|
83
|
+
const features: AccessibilityFeature[] = [
|
|
84
|
+
{
|
|
85
|
+
id: 'aria-1',
|
|
86
|
+
name: 'ARIA Labels',
|
|
87
|
+
type: 'aria',
|
|
88
|
+
enabled: enableARIA,
|
|
89
|
+
impact: 'high',
|
|
90
|
+
description: 'Enhanced ARIA labels for screen readers',
|
|
91
|
+
ariaLabel: 'Enhanced accessibility labels'
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: 'aria-2',
|
|
95
|
+
name: 'ARIA Descriptions',
|
|
96
|
+
type: 'aria',
|
|
97
|
+
enabled: enableARIA,
|
|
98
|
+
impact: 'medium',
|
|
99
|
+
description: 'Detailed ARIA descriptions for complex inputs',
|
|
100
|
+
ariaLabel: 'Detailed input descriptions'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: 'keyboard-1',
|
|
104
|
+
name: 'Keyboard Navigation',
|
|
105
|
+
type: 'keyboard',
|
|
106
|
+
enabled: enableKeyboardNavigation,
|
|
107
|
+
impact: 'high',
|
|
108
|
+
description: 'Full keyboard navigation support',
|
|
109
|
+
keyboardShortcut: 'Tab, Shift+Tab, Arrow keys'
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: 'keyboard-2',
|
|
113
|
+
name: 'Keyboard Shortcuts',
|
|
114
|
+
type: 'keyboard',
|
|
115
|
+
enabled: enableKeyboardNavigation,
|
|
116
|
+
impact: 'medium',
|
|
117
|
+
description: 'Custom keyboard shortcuts for common actions',
|
|
118
|
+
keyboardShortcut: 'Ctrl+S, Ctrl+Z, etc.'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: 'screen-reader-1',
|
|
122
|
+
name: 'Screen Reader Support',
|
|
123
|
+
type: 'screen-reader',
|
|
124
|
+
enabled: enableScreenReader,
|
|
125
|
+
impact: 'high',
|
|
126
|
+
description: 'Optimized screen reader compatibility',
|
|
127
|
+
ariaLabel: 'Screen reader optimized'
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: 'screen-reader-2',
|
|
131
|
+
name: 'Live Regions',
|
|
132
|
+
type: 'screen-reader',
|
|
133
|
+
enabled: enableScreenReader,
|
|
134
|
+
impact: 'medium',
|
|
135
|
+
description: 'Live regions for dynamic content updates',
|
|
136
|
+
ariaLabel: 'Live content updates'
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: 'focus-1',
|
|
140
|
+
name: 'Focus Management',
|
|
141
|
+
type: 'focus',
|
|
142
|
+
enabled: enableFocusManagement,
|
|
143
|
+
impact: 'high',
|
|
144
|
+
description: 'Enhanced focus management and visible focus indicators',
|
|
145
|
+
ariaLabel: 'Focus management'
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: 'focus-2',
|
|
149
|
+
name: 'Focus Trap',
|
|
150
|
+
type: 'focus',
|
|
151
|
+
enabled: enableFocusManagement && focusTrap,
|
|
152
|
+
impact: 'medium',
|
|
153
|
+
description: 'Focus trap for modal dialogs and overlays',
|
|
154
|
+
ariaLabel: 'Focus containment'
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'contrast-1',
|
|
158
|
+
name: 'High Contrast',
|
|
159
|
+
type: 'contrast',
|
|
160
|
+
enabled: enableHighContrast,
|
|
161
|
+
impact: 'medium',
|
|
162
|
+
description: 'High contrast mode support',
|
|
163
|
+
ariaLabel: 'High contrast support'
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'motion-1',
|
|
167
|
+
name: 'Reduced Motion',
|
|
168
|
+
type: 'motion',
|
|
169
|
+
enabled: enableReducedMotion,
|
|
170
|
+
impact: 'medium',
|
|
171
|
+
description: 'Reduced motion preference support',
|
|
172
|
+
ariaLabel: 'Reduced motion support'
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: 'voice-1',
|
|
176
|
+
name: 'Voice Control',
|
|
177
|
+
type: 'voice',
|
|
178
|
+
enabled: enableVoiceControl,
|
|
179
|
+
impact: 'low',
|
|
180
|
+
description: 'Voice control and speech recognition support',
|
|
181
|
+
ariaLabel: 'Voice control support'
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
setAccessibilityFeatures(features)
|
|
186
|
+
return features
|
|
187
|
+
}, [enableARIA, enableKeyboardNavigation, enableScreenReader, enableFocusManagement, enableHighContrast, enableReducedMotion, enableVoiceControl, focusTrap])
|
|
188
|
+
|
|
189
|
+
// Monitor system preferences
|
|
190
|
+
const monitorSystemPreferences = useCallback(() => {
|
|
191
|
+
// Monitor reduced motion preference
|
|
192
|
+
if (enableReducedMotion) {
|
|
193
|
+
motionQueryRef.current = window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
194
|
+
const handleMotionChange = (e: MediaQueryListEvent) => {
|
|
195
|
+
setAccessibilityState(prev => ({
|
|
196
|
+
...prev,
|
|
197
|
+
isReducedMotion: e.matches
|
|
198
|
+
}))
|
|
199
|
+
}
|
|
200
|
+
motionQueryRef.current.addEventListener('change', handleMotionChange)
|
|
201
|
+
|
|
202
|
+
// Set initial state
|
|
203
|
+
setAccessibilityState(prev => ({
|
|
204
|
+
...prev,
|
|
205
|
+
isReducedMotion: motionQueryRef.current?.matches || false
|
|
206
|
+
}))
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Monitor high contrast preference
|
|
210
|
+
if (enableHighContrast) {
|
|
211
|
+
contrastQueryRef.current = window.matchMedia('(prefers-contrast: high)')
|
|
212
|
+
const handleContrastChange = (e: MediaQueryListEvent) => {
|
|
213
|
+
setAccessibilityState(prev => ({
|
|
214
|
+
...prev,
|
|
215
|
+
isHighContrast: e.matches
|
|
216
|
+
}))
|
|
217
|
+
}
|
|
218
|
+
contrastQueryRef.current.addEventListener('change', handleContrastChange)
|
|
219
|
+
|
|
220
|
+
// Set initial state
|
|
221
|
+
setAccessibilityState(prev => ({
|
|
222
|
+
...prev,
|
|
223
|
+
isHighContrast: contrastQueryRef.current?.matches || false
|
|
224
|
+
}))
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Monitor voice control preference (simulated)
|
|
228
|
+
if (enableVoiceControl) {
|
|
229
|
+
// Simulate voice control detection
|
|
230
|
+
setTimeout(() => {
|
|
231
|
+
setAccessibilityState(prev => ({
|
|
232
|
+
...prev,
|
|
233
|
+
isVoiceControl: Math.random() > 0.7 // 30% chance of voice control being active
|
|
234
|
+
}))
|
|
235
|
+
}, 1000)
|
|
236
|
+
}
|
|
237
|
+
}, [enableReducedMotion, enableHighContrast, enableVoiceControl])
|
|
238
|
+
|
|
239
|
+
// Enable ARIA support
|
|
240
|
+
const enableARIASupport = useCallback(() => {
|
|
241
|
+
if (!enableARIA) return
|
|
242
|
+
|
|
243
|
+
setIsEnhancing(true)
|
|
244
|
+
|
|
245
|
+
setTimeout(() => {
|
|
246
|
+
const ariaEnhancements = [
|
|
247
|
+
'ARIA labels applied to all input elements',
|
|
248
|
+
'ARIA descriptions added for complex inputs',
|
|
249
|
+
'ARIA live regions configured for dynamic updates',
|
|
250
|
+
'ARIA states and properties enhanced'
|
|
251
|
+
]
|
|
252
|
+
|
|
253
|
+
setEnhancements(prev => [...prev, ...ariaEnhancements])
|
|
254
|
+
setIsEnhancing(false)
|
|
255
|
+
|
|
256
|
+
ariaEnhancements.forEach(enhancement => {
|
|
257
|
+
callbacks.onAccessibilityFeatureEnabled?.({
|
|
258
|
+
id: 'aria-enhancement',
|
|
259
|
+
name: 'ARIA Enhancement',
|
|
260
|
+
type: 'aria',
|
|
261
|
+
enabled: true,
|
|
262
|
+
impact: 'high',
|
|
263
|
+
description: enhancement
|
|
264
|
+
})
|
|
265
|
+
})
|
|
266
|
+
}, 200)
|
|
267
|
+
}, [enableARIA, callbacks])
|
|
268
|
+
|
|
269
|
+
// Enable keyboard navigation
|
|
270
|
+
const enableKeyboardNavigationFeature = useCallback(() => {
|
|
271
|
+
if (!enableKeyboardNavigation) return
|
|
272
|
+
|
|
273
|
+
setIsEnhancing(true)
|
|
274
|
+
|
|
275
|
+
setTimeout(() => {
|
|
276
|
+
const keyboardEnhancements = [
|
|
277
|
+
'Tab navigation order optimized',
|
|
278
|
+
'Arrow key navigation enabled',
|
|
279
|
+
'Keyboard shortcuts configured',
|
|
280
|
+
'Focus indicators enhanced'
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
setEnhancements(prev => [...prev, ...keyboardEnhancements])
|
|
284
|
+
setIsEnhancing(false)
|
|
285
|
+
|
|
286
|
+
keyboardEnhancements.forEach(enhancement => {
|
|
287
|
+
callbacks.onKeyboardNavigationEnabled?.(enhancement)
|
|
288
|
+
})
|
|
289
|
+
}, 250)
|
|
290
|
+
}, [enableKeyboardNavigation, callbacks])
|
|
291
|
+
|
|
292
|
+
// Optimize screen reader support
|
|
293
|
+
const optimizeScreenReader = useCallback(() => {
|
|
294
|
+
if (!enableScreenReader) return
|
|
295
|
+
|
|
296
|
+
setIsEnhancing(true)
|
|
297
|
+
|
|
298
|
+
setTimeout(() => {
|
|
299
|
+
const screenReaderOptimizations = [
|
|
300
|
+
'Screen reader announcements optimized',
|
|
301
|
+
'Live regions configured for updates',
|
|
302
|
+
'Semantic HTML structure enhanced',
|
|
303
|
+
'Screen reader navigation improved'
|
|
304
|
+
]
|
|
305
|
+
|
|
306
|
+
setEnhancements(prev => [...prev, ...screenReaderOptimizations])
|
|
307
|
+
setIsEnhancing(false)
|
|
308
|
+
|
|
309
|
+
screenReaderOptimizations.forEach(optimization => {
|
|
310
|
+
callbacks.onScreenReaderOptimized?.(optimization)
|
|
311
|
+
})
|
|
312
|
+
}, 300)
|
|
313
|
+
}, [enableScreenReader, callbacks])
|
|
314
|
+
|
|
315
|
+
// Enhance focus management
|
|
316
|
+
const enhanceFocusManagement = useCallback(() => {
|
|
317
|
+
if (!enableFocusManagement) return
|
|
318
|
+
|
|
319
|
+
setIsEnhancing(true)
|
|
320
|
+
|
|
321
|
+
setTimeout(() => {
|
|
322
|
+
const focusEnhancements = [
|
|
323
|
+
'Focus indicators made visible',
|
|
324
|
+
'Focus order optimized',
|
|
325
|
+
'Focus trap implemented for modals',
|
|
326
|
+
'Skip links added for navigation'
|
|
327
|
+
]
|
|
328
|
+
|
|
329
|
+
setEnhancements(prev => [...prev, ...focusEnhancements])
|
|
330
|
+
setIsEnhancing(false)
|
|
331
|
+
|
|
332
|
+
focusEnhancements.forEach(enhancement => {
|
|
333
|
+
callbacks.onFocusManagementEnhanced?.(enhancement)
|
|
334
|
+
})
|
|
335
|
+
}, 200)
|
|
336
|
+
}, [enableFocusManagement, callbacks])
|
|
337
|
+
|
|
338
|
+
// Calculate accessibility score
|
|
339
|
+
const calculateAccessibilityScore = useCallback(() => {
|
|
340
|
+
const totalFeatures = accessibilityFeatures.length
|
|
341
|
+
const enabledFeatures = accessibilityFeatures.filter(f => f.enabled).length
|
|
342
|
+
const activeFeatures = accessibilityState.activeFeatures.length
|
|
343
|
+
|
|
344
|
+
let score = 0
|
|
345
|
+
|
|
346
|
+
// Base score from enabled features
|
|
347
|
+
score += (enabledFeatures / totalFeatures) * 60
|
|
348
|
+
|
|
349
|
+
// Bonus for active features
|
|
350
|
+
score += Math.min(activeFeatures * 5, 30)
|
|
351
|
+
|
|
352
|
+
// Bonus for system preferences
|
|
353
|
+
if (accessibilityState.isHighContrast) score += 5
|
|
354
|
+
if (accessibilityState.isReducedMotion) score += 3
|
|
355
|
+
if (accessibilityState.isVoiceControl) score += 2
|
|
356
|
+
|
|
357
|
+
score = Math.min(score, 100)
|
|
358
|
+
|
|
359
|
+
setAccessibilityState(prev => ({
|
|
360
|
+
...prev,
|
|
361
|
+
accessibilityScore: Math.round(score)
|
|
362
|
+
}))
|
|
363
|
+
|
|
364
|
+
callbacks.onAccessibilityScoreChanged?.(score)
|
|
365
|
+
return score
|
|
366
|
+
}, [accessibilityFeatures, accessibilityState.activeFeatures, accessibilityState.isHighContrast, accessibilityState.isReducedMotion, accessibilityState.isVoiceControl, callbacks])
|
|
367
|
+
|
|
368
|
+
// Auto-enhance accessibility
|
|
369
|
+
const autoEnhanceAccessibility = useCallback(() => {
|
|
370
|
+
enableARIASupport()
|
|
371
|
+
enableKeyboardNavigationFeature()
|
|
372
|
+
optimizeScreenReader()
|
|
373
|
+
enhanceFocusManagement()
|
|
374
|
+
}, [enableARIASupport, enableKeyboardNavigation, optimizeScreenReader, enhanceFocusManagement])
|
|
375
|
+
|
|
376
|
+
// Get accessibility recommendations
|
|
377
|
+
const getAccessibilityRecommendations = useCallback(() => {
|
|
378
|
+
const recommendations: string[] = []
|
|
379
|
+
|
|
380
|
+
if (accessibilityState.accessibilityScore < 70) {
|
|
381
|
+
recommendations.push('Accessibility score is low, consider enabling more features')
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (!accessibilityState.isHighContrast && enableHighContrast) {
|
|
385
|
+
recommendations.push('High contrast mode is not active, consider enabling it')
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (!accessibilityState.isReducedMotion && enableReducedMotion) {
|
|
389
|
+
recommendations.push('Reduced motion is not active, consider enabling it')
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (accessibilityFeatures.filter(f => f.type === 'aria' && !f.enabled).length > 0) {
|
|
393
|
+
recommendations.push('Some ARIA features are disabled, consider enabling them')
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return recommendations
|
|
397
|
+
}, [accessibilityState.accessibilityScore, accessibilityState.isHighContrast, accessibilityState.isReducedMotion, accessibilityFeatures, enableHighContrast, enableReducedMotion])
|
|
398
|
+
|
|
399
|
+
// Initialize on mount
|
|
400
|
+
useEffect(() => {
|
|
401
|
+
initializeAccessibilityFeatures()
|
|
402
|
+
monitorSystemPreferences()
|
|
403
|
+
}, [initializeAccessibilityFeatures, monitorSystemPreferences])
|
|
404
|
+
|
|
405
|
+
// Auto-enhance on mount
|
|
406
|
+
useEffect(() => {
|
|
407
|
+
autoEnhanceAccessibility()
|
|
408
|
+
}, [autoEnhanceAccessibility])
|
|
409
|
+
|
|
410
|
+
// Calculate score when features change
|
|
411
|
+
useEffect(() => {
|
|
412
|
+
calculateAccessibilityScore()
|
|
413
|
+
}, [accessibilityFeatures, calculateAccessibilityScore])
|
|
414
|
+
|
|
415
|
+
// Cleanup on unmount
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
return () => {
|
|
418
|
+
if (accessibilityTimerRef.current) {
|
|
419
|
+
clearTimeout(accessibilityTimerRef.current)
|
|
420
|
+
}
|
|
421
|
+
if (motionQueryRef.current) {
|
|
422
|
+
motionQueryRef.current.removeEventListener('change', () => {})
|
|
423
|
+
}
|
|
424
|
+
if (contrastQueryRef.current) {
|
|
425
|
+
contrastQueryRef.current.removeEventListener('change', () => {})
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}, [])
|
|
429
|
+
|
|
430
|
+
return {
|
|
431
|
+
// State
|
|
432
|
+
accessibilityFeatures,
|
|
433
|
+
accessibilityState,
|
|
434
|
+
isEnhancing,
|
|
435
|
+
enhancements,
|
|
436
|
+
|
|
437
|
+
// Functions
|
|
438
|
+
enableARIASupport,
|
|
439
|
+
enableKeyboardNavigation,
|
|
440
|
+
optimizeScreenReader,
|
|
441
|
+
enhanceFocusManagement,
|
|
442
|
+
autoEnhanceAccessibility,
|
|
443
|
+
|
|
444
|
+
// Utility functions
|
|
445
|
+
isFeatureEnabled: (featureId: string) => accessibilityFeatures.find(f => f.id === featureId)?.enabled || false,
|
|
446
|
+
getFeatureByName: (name: string) => accessibilityFeatures.find(f => f.name.toLowerCase().includes(name.toLowerCase())),
|
|
447
|
+
getAccessibilityScore: () => accessibilityState.accessibilityScore,
|
|
448
|
+
isAccessibilityOptimal: () => accessibilityState.accessibilityScore >= 80,
|
|
449
|
+
getAccessibilityRecommendations,
|
|
450
|
+
clearEnhancements: () => setEnhancements([])
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export default useInputAccessibility
|
|
455
|
+
|