@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.4 → 0.1.5
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,535 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface LoadingAccessibilityConfig {
|
|
4
|
+
enableScreenReaderSupport?: boolean
|
|
5
|
+
enableReducedMotionSupport?: boolean
|
|
6
|
+
enableFocusManagement?: boolean
|
|
7
|
+
enableAriaSupport?: boolean
|
|
8
|
+
enableVoiceControl?: boolean
|
|
9
|
+
enableHighContrast?: boolean
|
|
10
|
+
enableKeyboardNavigation?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AccessibilityFeature {
|
|
14
|
+
id: string
|
|
15
|
+
name: string
|
|
16
|
+
type: 'screen-reader' | 'reduced-motion' | 'focus' | 'aria' | 'voice' | 'contrast' | 'keyboard'
|
|
17
|
+
enabled: boolean
|
|
18
|
+
description: string
|
|
19
|
+
impact: 'low' | 'medium' | 'high'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AccessibilityState {
|
|
23
|
+
screenReaderActive: boolean
|
|
24
|
+
reducedMotionEnabled: boolean
|
|
25
|
+
focusTrapped: boolean
|
|
26
|
+
ariaLabelsActive: boolean
|
|
27
|
+
voiceControlActive: boolean
|
|
28
|
+
highContrastMode: boolean
|
|
29
|
+
keyboardNavigationActive: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface LoadingAccessibilityCallbacks {
|
|
33
|
+
onScreenReaderEnhanced?: (feature: string) => void
|
|
34
|
+
onReducedMotionApplied?: (feature: string) => void
|
|
35
|
+
onFocusManaged?: (feature: string) => void
|
|
36
|
+
onAriaEnhanced?: (feature: string) => void
|
|
37
|
+
onVoiceControlEnabled?: (feature: string) => void
|
|
38
|
+
onHighContrastApplied?: (feature: string) => void
|
|
39
|
+
onKeyboardNavigationEnabled?: (feature: string) => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const useLoadingAccessibility = (
|
|
43
|
+
config: LoadingAccessibilityConfig = {},
|
|
44
|
+
callbacks: LoadingAccessibilityCallbacks = {}
|
|
45
|
+
) => {
|
|
46
|
+
const {
|
|
47
|
+
enableScreenReaderSupport = true,
|
|
48
|
+
enableReducedMotionSupport = true,
|
|
49
|
+
enableFocusManagement = true,
|
|
50
|
+
enableAriaSupport = true,
|
|
51
|
+
enableVoiceControl = true,
|
|
52
|
+
enableHighContrast = true,
|
|
53
|
+
enableKeyboardNavigation = true
|
|
54
|
+
} = config
|
|
55
|
+
|
|
56
|
+
const [accessibilityState, setAccessibilityState] = useState<AccessibilityState>({
|
|
57
|
+
screenReaderActive: false,
|
|
58
|
+
reducedMotionEnabled: false,
|
|
59
|
+
focusTrapped: false,
|
|
60
|
+
ariaLabelsActive: false,
|
|
61
|
+
voiceControlActive: false,
|
|
62
|
+
highContrastMode: false,
|
|
63
|
+
keyboardNavigationActive: false
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const [accessibilityFeatures, setAccessibilityFeatures] = useState<AccessibilityFeature[]>([])
|
|
67
|
+
const [isEnhancing, setIsEnhancing] = useState(false)
|
|
68
|
+
const [activeFeatures, setActiveFeatures] = useState<string[]>([])
|
|
69
|
+
const [accessibilityScore, setAccessibilityScore] = useState(0)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
const accessibilityTimerRef = useRef<number | null>(null)
|
|
73
|
+
const motionQueryRef = useRef<MediaQueryList | null>(null)
|
|
74
|
+
const contrastQueryRef = useRef<MediaQueryList | null>(null)
|
|
75
|
+
|
|
76
|
+
// Screen reader support
|
|
77
|
+
const enableScreenReaderSupportFeature = useCallback(() => {
|
|
78
|
+
if (!enableScreenReaderSupport) return
|
|
79
|
+
|
|
80
|
+
setIsEnhancing(true)
|
|
81
|
+
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
const screenReaderFeatures: AccessibilityFeature[] = [
|
|
84
|
+
{
|
|
85
|
+
id: 'sr-loading-states',
|
|
86
|
+
name: 'Loading State Descriptions',
|
|
87
|
+
type: 'screen-reader',
|
|
88
|
+
enabled: true,
|
|
89
|
+
description: 'Comprehensive loading state descriptions for screen readers',
|
|
90
|
+
impact: 'high'
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'sr-progress-indication',
|
|
94
|
+
name: 'Progress Indication',
|
|
95
|
+
type: 'screen-reader',
|
|
96
|
+
enabled: true,
|
|
97
|
+
description: 'Clear progress indication for screen reader users',
|
|
98
|
+
impact: 'high'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 'sr-status-updates',
|
|
102
|
+
name: 'Status Updates',
|
|
103
|
+
type: 'screen-reader',
|
|
104
|
+
enabled: true,
|
|
105
|
+
description: 'Real-time status updates for loading processes',
|
|
106
|
+
impact: 'medium'
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
setAccessibilityFeatures(prev => [...prev, ...screenReaderFeatures])
|
|
111
|
+
setActiveFeatures(prev => [...prev, ...screenReaderFeatures.map(f => f.name)])
|
|
112
|
+
setAccessibilityState(prev => ({ ...prev, screenReaderActive: true }))
|
|
113
|
+
setIsEnhancing(false)
|
|
114
|
+
|
|
115
|
+
screenReaderFeatures.forEach(feature => {
|
|
116
|
+
callbacks.onScreenReaderEnhanced?.(feature.description)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
}, 300)
|
|
120
|
+
}, [enableScreenReaderSupport, callbacks])
|
|
121
|
+
|
|
122
|
+
// Reduced motion support
|
|
123
|
+
const enableReducedMotionSupportFeature = useCallback(() => {
|
|
124
|
+
if (!enableReducedMotionSupport) return
|
|
125
|
+
|
|
126
|
+
setIsEnhancing(true)
|
|
127
|
+
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
const reducedMotionFeatures: AccessibilityFeature[] = [
|
|
130
|
+
{
|
|
131
|
+
id: 'rm-animations',
|
|
132
|
+
name: 'Reduced Motion Animations',
|
|
133
|
+
type: 'reduced-motion',
|
|
134
|
+
enabled: true,
|
|
135
|
+
description: 'Loading animations adapted for reduced motion preferences',
|
|
136
|
+
impact: 'high'
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: 'rm-transitions',
|
|
140
|
+
name: 'Reduced Motion Transitions',
|
|
141
|
+
type: 'reduced-motion',
|
|
142
|
+
enabled: true,
|
|
143
|
+
description: 'Smooth transitions that respect motion preferences',
|
|
144
|
+
impact: 'medium'
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: 'rm-loading-states',
|
|
148
|
+
name: 'Reduced Motion Loading States',
|
|
149
|
+
type: 'reduced-motion',
|
|
150
|
+
enabled: true,
|
|
151
|
+
description: 'Loading states optimized for motion sensitivity',
|
|
152
|
+
impact: 'medium'
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
setAccessibilityFeatures(prev => [...prev, ...reducedMotionFeatures])
|
|
157
|
+
setActiveFeatures(prev => [...prev, ...reducedMotionFeatures.map(f => f.name)])
|
|
158
|
+
setAccessibilityState(prev => ({ ...prev, reducedMotionEnabled: true }))
|
|
159
|
+
setIsEnhancing(false)
|
|
160
|
+
|
|
161
|
+
reducedMotionFeatures.forEach(feature => {
|
|
162
|
+
callbacks.onReducedMotionApplied?.(feature.description)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
}, 250)
|
|
166
|
+
}, [enableReducedMotionSupport, callbacks])
|
|
167
|
+
|
|
168
|
+
// Focus management
|
|
169
|
+
const enableFocusManagementFeature = useCallback(() => {
|
|
170
|
+
if (!enableFocusManagement) return
|
|
171
|
+
|
|
172
|
+
setIsEnhancing(true)
|
|
173
|
+
|
|
174
|
+
setTimeout(() => {
|
|
175
|
+
const focusFeatures: AccessibilityFeature[] = [
|
|
176
|
+
{
|
|
177
|
+
id: 'focus-trapping',
|
|
178
|
+
name: 'Focus Trapping',
|
|
179
|
+
type: 'focus',
|
|
180
|
+
enabled: true,
|
|
181
|
+
description: 'Focus trapped within loading states for keyboard navigation',
|
|
182
|
+
impact: 'high'
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: 'focus-indicators',
|
|
186
|
+
name: 'Focus Indicators',
|
|
187
|
+
type: 'focus',
|
|
188
|
+
enabled: true,
|
|
189
|
+
description: 'Clear focus indicators for loading elements',
|
|
190
|
+
impact: 'medium'
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: 'focus-order',
|
|
194
|
+
name: 'Logical Focus Order',
|
|
195
|
+
type: 'focus',
|
|
196
|
+
enabled: true,
|
|
197
|
+
description: 'Logical focus order for loading state elements',
|
|
198
|
+
impact: 'medium'
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
setAccessibilityFeatures(prev => [...prev, ...focusFeatures])
|
|
203
|
+
setActiveFeatures(prev => [...prev, ...focusFeatures.map(f => f.name)])
|
|
204
|
+
setAccessibilityState(prev => ({ ...prev, focusTrapped: true }))
|
|
205
|
+
setIsEnhancing(false)
|
|
206
|
+
|
|
207
|
+
focusFeatures.forEach(feature => {
|
|
208
|
+
callbacks.onFocusManaged?.(feature.description)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
}, 200)
|
|
212
|
+
}, [enableFocusManagement, callbacks])
|
|
213
|
+
|
|
214
|
+
// ARIA support
|
|
215
|
+
const enableAriaSupportFeature = useCallback(() => {
|
|
216
|
+
if (!enableAriaSupport) return
|
|
217
|
+
|
|
218
|
+
setIsEnhancing(true)
|
|
219
|
+
|
|
220
|
+
setTimeout(() => {
|
|
221
|
+
const ariaFeatures: AccessibilityFeature[] = [
|
|
222
|
+
{
|
|
223
|
+
id: 'aria-labels',
|
|
224
|
+
name: 'ARIA Labels',
|
|
225
|
+
type: 'aria',
|
|
226
|
+
enabled: true,
|
|
227
|
+
description: 'Comprehensive ARIA labels for loading states',
|
|
228
|
+
impact: 'high'
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: 'aria-live',
|
|
232
|
+
name: 'ARIA Live Regions',
|
|
233
|
+
type: 'aria',
|
|
234
|
+
enabled: true,
|
|
235
|
+
description: 'Live regions for dynamic loading updates',
|
|
236
|
+
impact: 'high'
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: 'aria-progress',
|
|
240
|
+
name: 'ARIA Progress Indicators',
|
|
241
|
+
type: 'aria',
|
|
242
|
+
enabled: true,
|
|
243
|
+
description: 'Progress indicators with ARIA support',
|
|
244
|
+
impact: 'medium'
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: 'aria-status',
|
|
248
|
+
name: 'ARIA Status Updates',
|
|
249
|
+
type: 'aria',
|
|
250
|
+
enabled: true,
|
|
251
|
+
description: 'Status updates with ARIA announcements',
|
|
252
|
+
impact: 'medium'
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
|
|
256
|
+
setAccessibilityFeatures(prev => [...prev, ...ariaFeatures])
|
|
257
|
+
setActiveFeatures(prev => [...prev, ...ariaFeatures.map(f => f.name)])
|
|
258
|
+
setAccessibilityState(prev => ({ ...prev, ariaLabelsActive: true }))
|
|
259
|
+
setIsEnhancing(false)
|
|
260
|
+
|
|
261
|
+
ariaFeatures.forEach(feature => {
|
|
262
|
+
callbacks.onAriaEnhanced?.(feature.description)
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
}, 180)
|
|
266
|
+
}, [enableAriaSupport, callbacks])
|
|
267
|
+
|
|
268
|
+
// Voice control support
|
|
269
|
+
const enableVoiceControlFeature = useCallback(() => {
|
|
270
|
+
if (!enableVoiceControl) return
|
|
271
|
+
|
|
272
|
+
setIsEnhancing(true)
|
|
273
|
+
|
|
274
|
+
setTimeout(() => {
|
|
275
|
+
const voiceFeatures: AccessibilityFeature[] = [
|
|
276
|
+
{
|
|
277
|
+
id: 'voice-commands',
|
|
278
|
+
name: 'Voice Commands',
|
|
279
|
+
type: 'voice',
|
|
280
|
+
enabled: true,
|
|
281
|
+
description: 'Voice commands for loading state control',
|
|
282
|
+
impact: 'medium'
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
id: 'voice-feedback',
|
|
286
|
+
name: 'Voice Feedback',
|
|
287
|
+
type: 'voice',
|
|
288
|
+
enabled: true,
|
|
289
|
+
description: 'Voice feedback for loading progress',
|
|
290
|
+
impact: 'medium'
|
|
291
|
+
}
|
|
292
|
+
]
|
|
293
|
+
|
|
294
|
+
setAccessibilityFeatures(prev => [...prev, ...voiceFeatures])
|
|
295
|
+
setActiveFeatures(prev => [...prev, ...voiceFeatures.map(f => f.name)])
|
|
296
|
+
setAccessibilityState(prev => ({ ...prev, voiceControlActive: true }))
|
|
297
|
+
setIsEnhancing(false)
|
|
298
|
+
|
|
299
|
+
voiceFeatures.forEach(feature => {
|
|
300
|
+
callbacks.onVoiceControlEnabled?.(feature.description)
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
}, 150)
|
|
304
|
+
}, [enableVoiceControl, callbacks])
|
|
305
|
+
|
|
306
|
+
// High contrast support
|
|
307
|
+
const enableHighContrastFeature = useCallback(() => {
|
|
308
|
+
if (!enableHighContrast) return
|
|
309
|
+
|
|
310
|
+
setIsEnhancing(true)
|
|
311
|
+
|
|
312
|
+
setTimeout(() => {
|
|
313
|
+
const contrastFeatures: AccessibilityFeature[] = [
|
|
314
|
+
{
|
|
315
|
+
id: 'high-contrast',
|
|
316
|
+
name: 'High Contrast Mode',
|
|
317
|
+
type: 'contrast',
|
|
318
|
+
enabled: true,
|
|
319
|
+
description: 'High contrast loading states for better visibility',
|
|
320
|
+
impact: 'medium'
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: 'contrast-optimization',
|
|
324
|
+
name: 'Contrast Optimization',
|
|
325
|
+
type: 'contrast',
|
|
326
|
+
enabled: true,
|
|
327
|
+
description: 'Optimized contrast ratios for accessibility',
|
|
328
|
+
impact: 'low'
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
setAccessibilityFeatures(prev => [...prev, ...contrastFeatures])
|
|
333
|
+
setActiveFeatures(prev => [...prev, ...contrastFeatures.map(f => f.name)])
|
|
334
|
+
setAccessibilityState(prev => ({ ...prev, highContrastMode: true }))
|
|
335
|
+
setIsEnhancing(false)
|
|
336
|
+
|
|
337
|
+
contrastFeatures.forEach(feature => {
|
|
338
|
+
callbacks.onHighContrastApplied?.(feature.description)
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
}, 120)
|
|
342
|
+
}, [enableHighContrast, callbacks])
|
|
343
|
+
|
|
344
|
+
// Keyboard navigation support
|
|
345
|
+
const enableKeyboardNavigationFeature = useCallback(() => {
|
|
346
|
+
if (!enableKeyboardNavigation) return
|
|
347
|
+
|
|
348
|
+
setIsEnhancing(true)
|
|
349
|
+
|
|
350
|
+
setTimeout(() => {
|
|
351
|
+
const keyboardFeatures: AccessibilityFeature[] = [
|
|
352
|
+
{
|
|
353
|
+
id: 'keyboard-shortcuts',
|
|
354
|
+
name: 'Keyboard Shortcuts',
|
|
355
|
+
type: 'keyboard',
|
|
356
|
+
enabled: true,
|
|
357
|
+
description: 'Keyboard shortcuts for loading state control',
|
|
358
|
+
impact: 'medium'
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
id: 'keyboard-navigation',
|
|
362
|
+
name: 'Keyboard Navigation',
|
|
363
|
+
type: 'keyboard',
|
|
364
|
+
enabled: true,
|
|
365
|
+
description: 'Full keyboard navigation for loading states',
|
|
366
|
+
impact: 'high'
|
|
367
|
+
}
|
|
368
|
+
]
|
|
369
|
+
|
|
370
|
+
setAccessibilityFeatures(prev => [...prev, ...keyboardFeatures])
|
|
371
|
+
setActiveFeatures(prev => [...prev, ...keyboardFeatures.map(f => f.name)])
|
|
372
|
+
setAccessibilityState(prev => ({ ...prev, keyboardNavigationActive: true }))
|
|
373
|
+
setIsEnhancing(false)
|
|
374
|
+
|
|
375
|
+
keyboardFeatures.forEach(feature => {
|
|
376
|
+
callbacks.onKeyboardNavigationEnabled?.(feature.description)
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
}, 100)
|
|
380
|
+
}, [enableKeyboardNavigation, callbacks])
|
|
381
|
+
|
|
382
|
+
// Auto-enable accessibility features
|
|
383
|
+
const autoEnableAccessibility = useCallback(() => {
|
|
384
|
+
enableScreenReaderSupportFeature()
|
|
385
|
+
enableReducedMotionSupportFeature()
|
|
386
|
+
enableFocusManagementFeature()
|
|
387
|
+
enableAriaSupportFeature()
|
|
388
|
+
enableVoiceControlFeature()
|
|
389
|
+
enableHighContrastFeature()
|
|
390
|
+
enableKeyboardNavigationFeature()
|
|
391
|
+
}, [
|
|
392
|
+
enableScreenReaderSupportFeature,
|
|
393
|
+
enableReducedMotionSupportFeature,
|
|
394
|
+
enableFocusManagementFeature,
|
|
395
|
+
enableAriaSupportFeature,
|
|
396
|
+
enableVoiceControlFeature,
|
|
397
|
+
enableHighContrastFeature,
|
|
398
|
+
enableKeyboardNavigationFeature
|
|
399
|
+
])
|
|
400
|
+
|
|
401
|
+
// Calculate accessibility score
|
|
402
|
+
const calculateAccessibilityScore = useCallback(() => {
|
|
403
|
+
const totalFeatures = accessibilityFeatures.length
|
|
404
|
+
const enabledFeatures = accessibilityFeatures.filter(f => f.enabled).length
|
|
405
|
+
|
|
406
|
+
if (totalFeatures === 0) return 0
|
|
407
|
+
|
|
408
|
+
const score = Math.round((enabledFeatures / totalFeatures) * 100)
|
|
409
|
+
setAccessibilityScore(score)
|
|
410
|
+
return score
|
|
411
|
+
}, [accessibilityFeatures])
|
|
412
|
+
|
|
413
|
+
// Update accessibility score when features change
|
|
414
|
+
useEffect(() => {
|
|
415
|
+
calculateAccessibilityScore()
|
|
416
|
+
}, [accessibilityFeatures, calculateAccessibilityScore])
|
|
417
|
+
|
|
418
|
+
// Monitor system preferences
|
|
419
|
+
useEffect(() => {
|
|
420
|
+
// Monitor reduced motion preference
|
|
421
|
+
if (enableReducedMotionSupport) {
|
|
422
|
+
motionQueryRef.current = window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
423
|
+
|
|
424
|
+
const handleMotionChange = (e: MediaQueryListEvent) => {
|
|
425
|
+
if (e.matches) {
|
|
426
|
+
enableReducedMotionSupportFeature()
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
motionQueryRef.current.addEventListener('change', handleMotionChange)
|
|
431
|
+
|
|
432
|
+
// Check initial state
|
|
433
|
+
if (motionQueryRef.current.matches) {
|
|
434
|
+
enableReducedMotionSupportFeature()
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return () => {
|
|
438
|
+
motionQueryRef.current?.removeEventListener('change', handleMotionChange)
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}, [enableReducedMotionSupport, enableReducedMotionSupportFeature])
|
|
442
|
+
|
|
443
|
+
// Monitor high contrast preference
|
|
444
|
+
useEffect(() => {
|
|
445
|
+
if (enableHighContrast) {
|
|
446
|
+
contrastQueryRef.current = window.matchMedia('(prefers-contrast: high)')
|
|
447
|
+
|
|
448
|
+
const handleContrastChange = (e: MediaQueryListEvent) => {
|
|
449
|
+
if (e.matches) {
|
|
450
|
+
enableHighContrastFeature()
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
contrastQueryRef.current.addEventListener('change', handleContrastChange)
|
|
455
|
+
|
|
456
|
+
// Check initial state
|
|
457
|
+
if (contrastQueryRef.current.matches) {
|
|
458
|
+
enableHighContrastFeature()
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return () => {
|
|
462
|
+
contrastQueryRef.current?.removeEventListener('change', handleContrastChange)
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}, [enableHighContrast, enableHighContrastFeature])
|
|
466
|
+
|
|
467
|
+
// Auto-enable on mount
|
|
468
|
+
useEffect(() => {
|
|
469
|
+
autoEnableAccessibility()
|
|
470
|
+
}, [autoEnableAccessibility])
|
|
471
|
+
|
|
472
|
+
// Cleanup on unmount
|
|
473
|
+
useEffect(() => {
|
|
474
|
+
return () => {
|
|
475
|
+
if (accessibilityTimerRef.current) {
|
|
476
|
+
clearTimeout(accessibilityTimerRef.current)
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}, [])
|
|
480
|
+
|
|
481
|
+
return {
|
|
482
|
+
// State
|
|
483
|
+
accessibilityState,
|
|
484
|
+
accessibilityFeatures,
|
|
485
|
+
isEnhancing,
|
|
486
|
+
activeFeatures,
|
|
487
|
+
accessibilityScore,
|
|
488
|
+
|
|
489
|
+
// Functions
|
|
490
|
+
enableScreenReaderSupport: enableScreenReaderSupportFeature,
|
|
491
|
+
enableReducedMotionSupport: enableReducedMotionSupportFeature,
|
|
492
|
+
enableFocusManagement: enableFocusManagementFeature,
|
|
493
|
+
enableAriaSupport: enableAriaSupportFeature,
|
|
494
|
+
enableVoiceControl: enableVoiceControlFeature,
|
|
495
|
+
enableHighContrast: enableHighContrastFeature,
|
|
496
|
+
enableKeyboardNavigation: enableKeyboardNavigationFeature,
|
|
497
|
+
autoEnableAccessibility,
|
|
498
|
+
|
|
499
|
+
// Utility functions
|
|
500
|
+
isScreenReaderActive: () => accessibilityState.screenReaderActive,
|
|
501
|
+
isReducedMotionEnabled: () => accessibilityState.reducedMotionEnabled,
|
|
502
|
+
isFocusManaged: () => accessibilityState.focusTrapped,
|
|
503
|
+
isAriaEnhanced: () => accessibilityState.ariaLabelsActive,
|
|
504
|
+
isVoiceControlActive: () => accessibilityState.voiceControlActive,
|
|
505
|
+
isHighContrastMode: () => accessibilityState.highContrastMode,
|
|
506
|
+
isKeyboardNavigationActive: () => accessibilityState.keyboardNavigationActive,
|
|
507
|
+
getAccessibilityScore: () => accessibilityScore,
|
|
508
|
+
getAccessibilityRecommendations: () => {
|
|
509
|
+
const recommendations: string[] = []
|
|
510
|
+
|
|
511
|
+
if (accessibilityScore < 50) {
|
|
512
|
+
recommendations.push('Enable more accessibility features for better user experience')
|
|
513
|
+
recommendations.push('Consider implementing screen reader support')
|
|
514
|
+
recommendations.push('Add ARIA labels for loading states')
|
|
515
|
+
} else if (accessibilityScore < 80) {
|
|
516
|
+
recommendations.push('Enable remaining accessibility features')
|
|
517
|
+
recommendations.push('Consider voice control support')
|
|
518
|
+
recommendations.push('Optimize keyboard navigation')
|
|
519
|
+
} else {
|
|
520
|
+
recommendations.push('Excellent accessibility coverage')
|
|
521
|
+
recommendations.push('Consider advanced accessibility features')
|
|
522
|
+
recommendations.push('Monitor for new accessibility standards')
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return recommendations
|
|
526
|
+
},
|
|
527
|
+
clearAccessibilityFeatures: () => {
|
|
528
|
+
setAccessibilityFeatures([])
|
|
529
|
+
setActiveFeatures([])
|
|
530
|
+
setAccessibilityScore(0)
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
export default useLoadingAccessibility
|