@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.2.9 → 0.2.11
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/components/ui/accessibility-demo.esm.js +30 -24
- package/dist/components/ui/accessibility-demo.js +30 -24
- package/dist/components/ui/advanced-component-architecture-demo.esm.js +235 -179
- package/dist/components/ui/advanced-component-architecture-demo.js +235 -179
- package/dist/components/ui/advanced-transition-system-demo.esm.js +110 -64
- package/dist/components/ui/advanced-transition-system-demo.js +110 -64
- package/dist/components/ui/advanced-transition-system.esm.js +166 -122
- package/dist/components/ui/advanced-transition-system.js +166 -122
- package/dist/components/ui/animation/animated-container.esm.js +52 -29
- package/dist/components/ui/animation/animated-container.js +52 -29
- package/dist/components/ui/animation/staggered-container.esm.js +18 -9
- package/dist/components/ui/animation/staggered-container.js +18 -9
- package/dist/components/ui/animation-demo.esm.js +67 -35
- package/dist/components/ui/animation-demo.js +67 -35
- package/dist/components/ui/badge.esm.js +9 -6
- package/dist/components/ui/badge.js +9 -6
- package/dist/components/ui/battery-conscious-animation-demo.esm.js +122 -87
- package/dist/components/ui/battery-conscious-animation-demo.js +122 -87
- package/dist/components/ui/border-radius-shadow-demo.esm.js +23 -12
- package/dist/components/ui/border-radius-shadow-demo.js +23 -12
- package/dist/components/ui/button.esm.js +8 -2
- package/dist/components/ui/button.js +8 -2
- package/dist/components/ui/card.esm.js +33 -8
- package/dist/components/ui/card.js +33 -8
- package/dist/components/ui/checkbox.esm.js +3 -3
- package/dist/components/ui/checkbox.js +3 -3
- package/dist/components/ui/color-preview.esm.js +68 -45
- package/dist/components/ui/color-preview.js +68 -45
- package/dist/components/ui/data-display/chart.esm.js +112 -84
- package/dist/components/ui/data-display/chart.js +112 -84
- package/dist/components/ui/data-display/data-grid-simple.esm.js +1 -1
- package/dist/components/ui/data-display/data-grid-simple.js +1 -1
- package/dist/components/ui/data-display/data-grid.esm.js +80 -67
- package/dist/components/ui/data-display/data-grid.js +80 -67
- package/dist/components/ui/data-display/list.esm.js +53 -45
- package/dist/components/ui/data-display/list.js +53 -45
- package/dist/components/ui/data-display/table.esm.js +62 -54
- package/dist/components/ui/data-display/table.js +62 -54
- package/dist/components/ui/data-display/timeline.esm.js +39 -34
- package/dist/components/ui/data-display/timeline.js +39 -34
- package/dist/components/ui/data-display/tree.esm.js +116 -84
- package/dist/components/ui/data-display/tree.js +116 -84
- package/dist/components/ui/data-display/types.esm.js +389 -364
- package/dist/components/ui/data-display/types.js +389 -364
- package/dist/components/ui/enterprise-mobile-experience-demo.esm.js +120 -70
- package/dist/components/ui/enterprise-mobile-experience-demo.js +120 -70
- package/dist/components/ui/enterprise-mobile-experience.esm.js +124 -73
- package/dist/components/ui/enterprise-mobile-experience.js +124 -73
- package/dist/components/ui/feedback/alert.esm.js +22 -15
- package/dist/components/ui/feedback/alert.js +22 -15
- package/dist/components/ui/feedback/progress.esm.js +47 -24
- package/dist/components/ui/feedback/progress.js +47 -24
- package/dist/components/ui/feedback/skeleton.esm.js +39 -29
- package/dist/components/ui/feedback/skeleton.js +39 -29
- package/dist/components/ui/feedback/toast.esm.js +62 -38
- package/dist/components/ui/feedback/toast.js +62 -38
- package/dist/components/ui/feedback/types.esm.js +83 -83
- package/dist/components/ui/feedback/types.js +83 -83
- package/dist/components/ui/font-preview.esm.js +41 -39
- package/dist/components/ui/font-preview.js +41 -39
- package/dist/components/ui/form-demo.esm.js +150 -113
- package/dist/components/ui/form-demo.js +150 -113
- package/dist/components/ui/hardware-acceleration-demo.esm.js +137 -87
- package/dist/components/ui/hardware-acceleration-demo.js +137 -87
- package/dist/components/ui/input.esm.js +4 -1
- package/dist/components/ui/input.js +4 -1
- package/dist/components/ui/layout-demo.esm.js +81 -56
- package/dist/components/ui/layout-demo.js +81 -56
- package/dist/components/ui/layouts/adaptive-layout.esm.js +27 -8
- package/dist/components/ui/layouts/adaptive-layout.js +27 -8
- package/dist/components/ui/layouts/desktop-layout.esm.js +39 -19
- package/dist/components/ui/layouts/desktop-layout.js +39 -19
- package/dist/components/ui/layouts/mobile-layout.esm.js +19 -9
- package/dist/components/ui/layouts/mobile-layout.js +19 -9
- package/dist/components/ui/layouts/tablet-layout.esm.js +28 -14
- package/dist/components/ui/layouts/tablet-layout.js +28 -14
- package/dist/components/ui/mobile-form-validation.esm.js +120 -87
- package/dist/components/ui/mobile-form-validation.js +120 -87
- package/dist/components/ui/mobile-input-demo.esm.js +19 -13
- package/dist/components/ui/mobile-input-demo.js +19 -13
- package/dist/components/ui/mobile-input.esm.js +185 -120
- package/dist/components/ui/mobile-input.js +185 -120
- package/dist/components/ui/mobile-skeleton-loading-demo.esm.js +128 -111
- package/dist/components/ui/mobile-skeleton-loading-demo.js +128 -111
- package/dist/components/ui/navigation/breadcrumb.esm.js +17 -14
- package/dist/components/ui/navigation/breadcrumb.js +17 -14
- package/dist/components/ui/navigation/index.esm.js +0 -1
- package/dist/components/ui/navigation/index.js +0 -1
- package/dist/components/ui/navigation/menu.esm.js +49 -35
- package/dist/components/ui/navigation/menu.js +49 -35
- package/dist/components/ui/navigation/navigation-demo.esm.js +81 -74
- package/dist/components/ui/navigation/navigation-demo.js +81 -74
- package/dist/components/ui/navigation/pagination.esm.js +62 -50
- package/dist/components/ui/navigation/pagination.js +62 -50
- package/dist/components/ui/navigation/sidebar.esm.js +56 -42
- package/dist/components/ui/navigation/sidebar.js +56 -42
- package/dist/components/ui/navigation/stepper.esm.js +34 -23
- package/dist/components/ui/navigation/stepper.js +34 -23
- package/dist/components/ui/navigation/tabs.esm.js +32 -21
- package/dist/components/ui/navigation/tabs.js +32 -21
- package/dist/components/ui/navigation/types.esm.js +196 -195
- package/dist/components/ui/navigation/types.js +196 -195
- package/dist/components/ui/overlay/backdrop.esm.js +17 -16
- package/dist/components/ui/overlay/backdrop.js +17 -16
- package/dist/components/ui/overlay/focus-manager.esm.js +21 -19
- package/dist/components/ui/overlay/focus-manager.js +21 -19
- package/dist/components/ui/overlay/index.esm.js +0 -2
- package/dist/components/ui/overlay/index.js +0 -2
- package/dist/components/ui/overlay/modal.esm.js +38 -34
- package/dist/components/ui/overlay/modal.js +38 -34
- package/dist/components/ui/overlay/overlay-manager.esm.js +25 -20
- package/dist/components/ui/overlay/overlay-manager.js +25 -20
- package/dist/components/ui/overlay/popover.esm.js +74 -58
- package/dist/components/ui/overlay/popover.js +74 -58
- package/dist/components/ui/overlay/portal.esm.js +7 -7
- package/dist/components/ui/overlay/portal.js +7 -7
- package/dist/components/ui/overlay/tooltip.esm.js +54 -39
- package/dist/components/ui/overlay/tooltip.js +54 -39
- package/dist/components/ui/overlay/types.esm.js +132 -131
- package/dist/components/ui/overlay/types.js +132 -131
- package/dist/components/ui/performance-demo.esm.js +135 -88
- package/dist/components/ui/performance-demo.js +135 -88
- package/dist/components/ui/semantic-input-system-demo.esm.js +117 -80
- package/dist/components/ui/semantic-input-system-demo.js +117 -80
- package/dist/components/ui/theme-customizer.esm.js +84 -52
- package/dist/components/ui/theme-customizer.js +84 -52
- package/dist/components/ui/theme-preview.esm.js +95 -43
- package/dist/components/ui/theme-preview.js +95 -43
- package/dist/components/ui/theme-switcher.esm.js +70 -44
- package/dist/components/ui/theme-switcher.js +70 -44
- package/dist/components/ui/theme-toggle.esm.js +3 -3
- package/dist/components/ui/theme-toggle.js +3 -3
- package/dist/components/ui/token-demo.esm.js +33 -21
- package/dist/components/ui/token-demo.js +33 -21
- package/dist/components/ui/touch-demo.esm.js +102 -73
- package/dist/components/ui/touch-demo.js +102 -73
- package/dist/components/ui/touch-friendly-interface-demo.esm.js +102 -64
- package/dist/components/ui/touch-friendly-interface-demo.js +102 -64
- package/dist/components/ui/touch-friendly-interface.esm.js +85 -61
- package/dist/components/ui/touch-friendly-interface.js +85 -61
- package/dist/hooks/use-accessibility-support.esm.js +115 -85
- package/dist/hooks/use-accessibility-support.js +115 -85
- package/dist/hooks/use-adaptive-layout.esm.js +56 -33
- package/dist/hooks/use-adaptive-layout.js +56 -33
- package/dist/hooks/use-advanced-patterns.esm.js +57 -42
- package/dist/hooks/use-advanced-patterns.js +57 -42
- package/dist/hooks/use-advanced-transition-system.esm.js +112 -71
- package/dist/hooks/use-advanced-transition-system.js +112 -71
- package/dist/hooks/use-animation-profile.esm.js +63 -34
- package/dist/hooks/use-animation-profile.js +63 -34
- package/dist/hooks/use-battery-animations.esm.js +80 -55
- package/dist/hooks/use-battery-animations.js +80 -55
- package/dist/hooks/use-battery-conscious-loading.esm.js +166 -123
- package/dist/hooks/use-battery-conscious-loading.js +166 -123
- package/dist/hooks/use-battery-optimization.esm.js +78 -55
- package/dist/hooks/use-battery-optimization.js +78 -55
- package/dist/hooks/use-battery-status.esm.js +73 -51
- package/dist/hooks/use-battery-status.js +73 -51
- package/dist/hooks/use-component-performance.esm.js +62 -47
- package/dist/hooks/use-component-performance.js +62 -47
- package/dist/hooks/use-device-loading-states.esm.js +152 -109
- package/dist/hooks/use-device-loading-states.js +152 -109
- package/dist/hooks/use-device.esm.js +25 -14
- package/dist/hooks/use-device.js +25 -14
- package/dist/hooks/use-enterprise-mobile-experience.esm.js +137 -88
- package/dist/hooks/use-enterprise-mobile-experience.js +137 -88
- package/dist/hooks/use-form-feedback.esm.js +124 -81
- package/dist/hooks/use-form-feedback.js +124 -81
- package/dist/hooks/use-form-performance.esm.js +127 -92
- package/dist/hooks/use-form-performance.js +127 -92
- package/dist/hooks/use-frame-rate.esm.js +56 -37
- package/dist/hooks/use-frame-rate.js +56 -37
- package/dist/hooks/use-gestures.esm.js +96 -72
- package/dist/hooks/use-gestures.js +96 -72
- package/dist/hooks/use-hardware-acceleration.esm.js +65 -37
- package/dist/hooks/use-hardware-acceleration.js +65 -37
- package/dist/hooks/use-input-accessibility.esm.js +157 -119
- package/dist/hooks/use-input-accessibility.js +157 -119
- package/dist/hooks/use-input-performance.esm.js +139 -104
- package/dist/hooks/use-input-performance.js +139 -104
- package/dist/hooks/use-layout-performance.esm.js +50 -29
- package/dist/hooks/use-layout-performance.js +50 -29
- package/dist/hooks/use-loading-accessibility.esm.js +209 -169
- package/dist/hooks/use-loading-accessibility.js +209 -169
- package/dist/hooks/use-loading-performance.esm.js +117 -93
- package/dist/hooks/use-loading-performance.js +117 -93
- package/dist/hooks/use-memory-usage.esm.js +57 -38
- package/dist/hooks/use-memory-usage.js +57 -38
- package/dist/hooks/use-mobile-form-layout.esm.js +111 -74
- package/dist/hooks/use-mobile-form-layout.js +111 -74
- package/dist/hooks/use-mobile-form-validation.esm.js +211 -144
- package/dist/hooks/use-mobile-form-validation.js +211 -144
- package/dist/hooks/use-mobile-keyboard-optimization.esm.js +154 -113
- package/dist/hooks/use-mobile-keyboard-optimization.js +154 -113
- package/dist/hooks/use-mobile-layout.esm.js +73 -51
- package/dist/hooks/use-mobile-layout.js +73 -51
- package/dist/hooks/use-mobile-optimization.esm.js +72 -44
- package/dist/hooks/use-mobile-optimization.js +72 -44
- package/dist/hooks/use-mobile-skeleton.esm.js +97 -64
- package/dist/hooks/use-mobile-skeleton.js +97 -64
- package/dist/hooks/use-mobile-touch.esm.js +128 -93
- package/dist/hooks/use-mobile-touch.js +128 -93
- package/dist/hooks/use-performance-throttling.esm.js +72 -48
- package/dist/hooks/use-performance-throttling.js +72 -48
- package/dist/hooks/use-performance.esm.js +90 -52
- package/dist/hooks/use-performance.js +90 -52
- package/dist/hooks/use-reusable-architecture.esm.js +94 -65
- package/dist/hooks/use-reusable-architecture.js +94 -65
- package/dist/hooks/use-semantic-input-types.esm.js +166 -124
- package/dist/hooks/use-semantic-input-types.js +166 -124
- package/dist/hooks/use-semantic-input.esm.js +178 -126
- package/dist/hooks/use-semantic-input.js +178 -126
- package/dist/hooks/use-tablet-layout.esm.js +67 -38
- package/dist/hooks/use-tablet-layout.js +67 -38
- package/dist/hooks/use-touch-friendly-input.esm.js +193 -149
- package/dist/hooks/use-touch-friendly-input.js +193 -149
- package/dist/hooks/use-touch-friendly-interface.esm.js +99 -67
- package/dist/hooks/use-touch-friendly-interface.js +99 -67
- package/dist/hooks/use-touch-optimization.esm.js +99 -72
- package/dist/hooks/use-touch-optimization.js +99 -72
- package/dist/index.esm.js +157 -281
- package/dist/index.js +157 -281
- package/dist/lib/utils.esm.js +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/plugins/theme-css-generator.esm.js +104 -55
- package/dist/plugins/theme-css-generator.js +104 -55
- package/dist/provider.esm.js +4 -4
- package/dist/provider.js +4 -4
- package/dist/styles.css +1 -1
- package/dist/theme.esm.js +633 -468
- package/dist/theme.js +633 -468
- package/dist/themes/ThemeContext.esm.js +15 -15
- package/dist/themes/ThemeContext.js +15 -15
- package/dist/themes/ThemeProvider.esm.js +25 -22
- package/dist/themes/ThemeProvider.js +25 -22
- package/dist/themes/accessibility.esm.js +147 -108
- package/dist/themes/accessibility.js +147 -108
- package/dist/themes/aria-patterns.esm.js +198 -162
- package/dist/themes/aria-patterns.js +198 -162
- package/dist/themes/base-themes.esm.js +14 -11
- package/dist/themes/base-themes.js +14 -11
- package/dist/themes/colorManager.esm.js +101 -83
- package/dist/themes/colorManager.js +101 -83
- package/dist/themes/examples/dark-theme.esm.js +133 -103
- package/dist/themes/examples/dark-theme.js +133 -103
- package/dist/themes/examples/minimal-theme.esm.js +83 -61
- package/dist/themes/examples/minimal-theme.js +83 -61
- package/dist/themes/focus-management.esm.js +202 -143
- package/dist/themes/focus-management.js +202 -143
- package/dist/themes/fontLoader.esm.js +28 -19
- package/dist/themes/fontLoader.js +28 -19
- package/dist/themes/high-contrast.esm.js +152 -104
- package/dist/themes/high-contrast.js +152 -104
- package/dist/themes/index.esm.js +1 -1
- package/dist/themes/index.js +1 -1
- package/dist/themes/inheritance.esm.js +35 -27
- package/dist/themes/inheritance.js +35 -27
- package/dist/themes/keyboard-navigation.esm.js +152 -123
- package/dist/themes/keyboard-navigation.js +152 -123
- package/dist/themes/motion-reduction.esm.js +193 -133
- package/dist/themes/motion-reduction.js +193 -133
- package/dist/themes/navigation.esm.js +146 -146
- package/dist/themes/navigation.js +146 -146
- package/dist/themes/screen-reader.esm.js +159 -94
- package/dist/themes/screen-reader.js +159 -94
- package/dist/themes/systemThemeDetector.esm.js +42 -34
- package/dist/themes/systemThemeDetector.js +42 -34
- package/dist/themes/themeCSSUpdater.esm.js +21 -9
- package/dist/themes/themeCSSUpdater.js +21 -9
- package/dist/themes/themePersistence.esm.js +68 -47
- package/dist/themes/themePersistence.js +68 -47
- package/dist/themes/themes/stan-design.esm.js +633 -468
- package/dist/themes/themes/stan-design.js +633 -468
- package/dist/themes/types.esm.js +301 -287
- package/dist/themes/types.js +301 -287
- package/dist/themes/useSystemTheme.esm.js +4 -4
- package/dist/themes/useSystemTheme.js +4 -4
- package/dist/themes/useTheme.esm.js +4 -4
- package/dist/themes/useTheme.js +4 -4
- package/dist/themes/validation.esm.js +128 -77
- package/dist/themes/validation.js +128 -77
- package/dist/tokens/index.esm.js +1 -2
- package/dist/tokens/index.js +1 -2
- package/dist/tokens/tokenExporter.esm.js +87 -61
- package/dist/tokens/tokenExporter.js +87 -61
- package/dist/tokens/tokenGenerator.esm.js +86 -77
- package/dist/tokens/tokenGenerator.js +86 -77
- package/dist/tokens/tokenManager.esm.js +64 -51
- package/dist/tokens/tokenManager.js +64 -51
- package/dist/tokens/tokenValidator.esm.js +193 -147
- package/dist/tokens/tokenValidator.js +193 -147
- package/dist/tokens/types.esm.js +49 -35
- package/dist/tokens/types.js +49 -35
- package/dist/utils/bundle-analyzer.esm.js +83 -65
- package/dist/utils/bundle-analyzer.js +83 -65
- package/dist/utils/bundle-splitting.esm.js +142 -117
- package/dist/utils/bundle-splitting.js +142 -117
- package/dist/utils/lazy-loading.esm.js +132 -106
- package/dist/utils/lazy-loading.js +132 -106
- package/dist/utils/performance-monitor.esm.js +170 -129
- package/dist/utils/performance-monitor.js +170 -129
- package/dist/utils/tree-shaking.esm.js +69 -61
- package/dist/utils/tree-shaking.js +69 -61
- package/package.json +1 -1
- package/src/index.ts +146 -146
|
@@ -1,54 +1,71 @@
|
|
|
1
1
|
import { useState, useCallback, useRef, useEffect, KeyboardEvent } from 'react'
|
|
2
2
|
|
|
3
3
|
export interface AccessibilitySupportConfig {
|
|
4
|
-
enableAriaSupport
|
|
4
|
+
enableAriaSupport?: boolean
|
|
5
|
+
enableKeyboardNavigation?: boolean
|
|
6
|
+
enableScreenReaderSupport?: boolean
|
|
7
|
+
enableFocusManagement?: boolean
|
|
8
|
+
enableHighContrast?: boolean
|
|
9
|
+
enableReducedMotion?: boolean
|
|
10
|
+
enableVoiceControl?: boolean
|
|
11
|
+
}
|
|
5
12
|
|
|
6
13
|
export interface AccessibilityState {
|
|
7
|
-
hasAriaLabels
|
|
14
|
+
hasAriaLabels: boolean
|
|
15
|
+
hasKeyboardNavigation: boolean
|
|
16
|
+
hasScreenReaderSupport: boolean
|
|
17
|
+
hasFocusManagement: boolean
|
|
18
|
+
isHighContrast: boolean
|
|
19
|
+
isReducedMotion: boolean
|
|
20
|
+
isVoiceControlEnabled: boolean
|
|
21
|
+
accessibilityLevel: 'basic' | 'enhanced' | 'advanced'
|
|
22
|
+
}
|
|
8
23
|
|
|
9
24
|
export interface AccessibilityFeatures {
|
|
10
|
-
ariaLabels, string>
|
|
11
|
-
keyboardShortcuts, string>
|
|
12
|
-
focusableElements
|
|
25
|
+
ariaLabels: Map<string, string>
|
|
26
|
+
keyboardShortcuts: Map<string, string>
|
|
27
|
+
focusableElements: Set<string>
|
|
28
|
+
screenReaderText: Map<string, string>
|
|
13
29
|
}
|
|
14
30
|
|
|
15
31
|
export interface AccessibilitySupportCallbacks {
|
|
16
|
-
onAriaEnhanced
|
|
17
|
-
onKeyboardNavigationEnabled
|
|
18
|
-
onScreenReaderEnhanced
|
|
19
|
-
onFocusManagementImproved
|
|
20
|
-
onAccessibilityWarning
|
|
32
|
+
onAriaEnhanced?: (feature: string) => void
|
|
33
|
+
onKeyboardNavigationEnabled?: (feature: string) => void
|
|
34
|
+
onScreenReaderEnhanced?: (feature: string) => void
|
|
35
|
+
onFocusManagementImproved?: (feature: string) => void
|
|
36
|
+
onAccessibilityWarning?: (warning: string) => void
|
|
21
37
|
}
|
|
22
38
|
|
|
23
39
|
export const useAccessibilitySupport = (
|
|
24
|
-
config= {},
|
|
25
|
-
callbacks= {}
|
|
40
|
+
config: AccessibilitySupportConfig = {},
|
|
41
|
+
callbacks: AccessibilitySupportCallbacks = {}
|
|
26
42
|
) => {
|
|
27
43
|
const {
|
|
28
44
|
enableAriaSupport = true,
|
|
29
|
-
enableKeyboardNavigation= true,
|
|
45
|
+
enableKeyboardNavigation: enableKeyboardNav = true,
|
|
30
46
|
enableScreenReaderSupport = true,
|
|
31
47
|
enableFocusManagement = true,
|
|
32
|
-
enableHighContrast= true,
|
|
33
|
-
enableReducedMotion= true,
|
|
34
|
-
enableVoiceControl= true
|
|
48
|
+
enableHighContrast: enableHighContrastMode = true,
|
|
49
|
+
enableReducedMotion: enableReducedMotionMode = true,
|
|
50
|
+
enableVoiceControl: enableVoiceControlMode = true
|
|
35
51
|
} = config
|
|
36
52
|
|
|
37
53
|
const [state, setState] = useState<AccessibilityState>({
|
|
38
|
-
hasAriaLabels,
|
|
39
|
-
hasKeyboardNavigation,
|
|
40
|
-
hasScreenReaderSupport,
|
|
41
|
-
hasFocusManagement,
|
|
42
|
-
isHighContrast,
|
|
43
|
-
isReducedMotion,
|
|
44
|
-
isVoiceControlEnabled,
|
|
45
|
-
accessibilityLevel
|
|
54
|
+
hasAriaLabels: false,
|
|
55
|
+
hasKeyboardNavigation: false,
|
|
56
|
+
hasScreenReaderSupport: false,
|
|
57
|
+
hasFocusManagement: false,
|
|
58
|
+
isHighContrast: false,
|
|
59
|
+
isReducedMotion: false,
|
|
60
|
+
isVoiceControlEnabled: false,
|
|
61
|
+
accessibilityLevel: 'basic'
|
|
62
|
+
})
|
|
46
63
|
|
|
47
64
|
const [features, setFeatures] = useState<AccessibilityFeatures>({
|
|
48
|
-
ariaLabels),
|
|
49
|
-
keyboardShortcuts),
|
|
50
|
-
focusableElements),
|
|
51
|
-
screenReaderText)
|
|
65
|
+
ariaLabels: new Map(),
|
|
66
|
+
keyboardShortcuts: new Map(),
|
|
67
|
+
focusableElements: new Set(),
|
|
68
|
+
screenReaderText: new Map()
|
|
52
69
|
})
|
|
53
70
|
|
|
54
71
|
const [isEnhancing, setIsEnhancing] = useState(false)
|
|
@@ -56,12 +73,12 @@ export const useAccessibilitySupport = (
|
|
|
56
73
|
const [accessibilityWarnings, setAccessibilityWarnings] = useState<string[]>([])
|
|
57
74
|
|
|
58
75
|
const focusableElementsRef = useRef<Set<HTMLElement>>(new Set())
|
|
59
|
-
const keyboardListenersRef = useRef<Map<string, (event) => void>>(new Map())
|
|
76
|
+
const keyboardListenersRef = useRef<Map<string, (event: KeyboardEvent) => void>>(new Map())
|
|
60
77
|
|
|
61
78
|
// ARIA support
|
|
62
79
|
const enhanceAriaSupport = useCallback((
|
|
63
|
-
elementId,
|
|
64
|
-
ariaAttributes, string>
|
|
80
|
+
elementId: string,
|
|
81
|
+
ariaAttributes: Record<string, string>
|
|
65
82
|
) => {
|
|
66
83
|
if (!enableAriaSupport) return false
|
|
67
84
|
|
|
@@ -78,13 +95,14 @@ export const useAccessibilitySupport = (
|
|
|
78
95
|
setEnhancements(prev => [...prev, ...ariaEnhancements])
|
|
79
96
|
setState(prev => ({
|
|
80
97
|
...prev,
|
|
81
|
-
hasAriaLabels,
|
|
82
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
98
|
+
hasAriaLabels: true,
|
|
99
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
100
|
+
}))
|
|
83
101
|
|
|
84
102
|
// Update features
|
|
85
103
|
setFeatures(prev => ({
|
|
86
104
|
...prev,
|
|
87
|
-
ariaLabels, JSON.stringify(ariaAttributes)))
|
|
105
|
+
ariaLabels: new Map(prev.ariaLabels.set(elementId, JSON.stringify(ariaAttributes)))
|
|
88
106
|
}))
|
|
89
107
|
|
|
90
108
|
setIsEnhancing(false)
|
|
@@ -99,8 +117,8 @@ export const useAccessibilitySupport = (
|
|
|
99
117
|
|
|
100
118
|
// Keyboard navigation
|
|
101
119
|
const enableKeyboardNavigationFeature = useCallback((
|
|
102
|
-
elementId,
|
|
103
|
-
shortcuts, string>
|
|
120
|
+
elementId: string,
|
|
121
|
+
shortcuts: Record<string, string>
|
|
104
122
|
) => {
|
|
105
123
|
if (!enableKeyboardNav) return false
|
|
106
124
|
|
|
@@ -117,13 +135,14 @@ export const useAccessibilitySupport = (
|
|
|
117
135
|
setEnhancements(prev => [...prev, ...keyboardEnhancements])
|
|
118
136
|
setState(prev => ({
|
|
119
137
|
...prev,
|
|
120
|
-
hasKeyboardNavigation,
|
|
121
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
138
|
+
hasKeyboardNavigation: true,
|
|
139
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
140
|
+
}))
|
|
122
141
|
|
|
123
142
|
// Update features
|
|
124
143
|
setFeatures(prev => ({
|
|
125
144
|
...prev,
|
|
126
|
-
keyboardShortcuts, JSON.stringify(shortcuts)))
|
|
145
|
+
keyboardShortcuts: new Map(prev.keyboardShortcuts.set(elementId, JSON.stringify(shortcuts)))
|
|
127
146
|
}))
|
|
128
147
|
|
|
129
148
|
setIsEnhancing(false)
|
|
@@ -138,8 +157,9 @@ export const useAccessibilitySupport = (
|
|
|
138
157
|
|
|
139
158
|
// Screen reader support
|
|
140
159
|
const enhanceScreenReaderSupport = useCallback((
|
|
141
|
-
elementId,
|
|
142
|
-
screenReaderText
|
|
160
|
+
elementId: string,
|
|
161
|
+
screenReaderText: string
|
|
162
|
+
) => {
|
|
143
163
|
if (!enableScreenReaderSupport) return false
|
|
144
164
|
|
|
145
165
|
setIsEnhancing(true)
|
|
@@ -155,13 +175,14 @@ export const useAccessibilitySupport = (
|
|
|
155
175
|
setEnhancements(prev => [...prev, ...screenReaderEnhancements])
|
|
156
176
|
setState(prev => ({
|
|
157
177
|
...prev,
|
|
158
|
-
hasScreenReaderSupport,
|
|
159
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
178
|
+
hasScreenReaderSupport: true,
|
|
179
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
180
|
+
}))
|
|
160
181
|
|
|
161
182
|
// Update features
|
|
162
183
|
setFeatures(prev => ({
|
|
163
184
|
...prev,
|
|
164
|
-
screenReaderText, screenReaderText))
|
|
185
|
+
screenReaderText: new Map(prev.screenReaderText.set(elementId, screenReaderText))
|
|
165
186
|
}))
|
|
166
187
|
|
|
167
188
|
setIsEnhancing(false)
|
|
@@ -176,8 +197,9 @@ export const useAccessibilitySupport = (
|
|
|
176
197
|
|
|
177
198
|
// Focus management
|
|
178
199
|
const improveFocusManagement = useCallback((
|
|
179
|
-
elementId,
|
|
180
|
-
focusStrategy
|
|
200
|
+
elementId: string,
|
|
201
|
+
focusStrategy: 'trap' | 'cycle' | 'skip' | 'highlight'
|
|
202
|
+
) => {
|
|
181
203
|
if (!enableFocusManagement) return false
|
|
182
204
|
|
|
183
205
|
setIsEnhancing(true)
|
|
@@ -193,13 +215,14 @@ export const useAccessibilitySupport = (
|
|
|
193
215
|
setEnhancements(prev => [...prev, ...focusEnhancements])
|
|
194
216
|
setState(prev => ({
|
|
195
217
|
...prev,
|
|
196
|
-
hasFocusManagement,
|
|
197
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
218
|
+
hasFocusManagement: true,
|
|
219
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
220
|
+
}))
|
|
198
221
|
|
|
199
222
|
// Update features
|
|
200
223
|
setFeatures(prev => ({
|
|
201
224
|
...prev,
|
|
202
|
-
focusableElements))
|
|
225
|
+
focusableElements: new Set(prev.focusableElements.add(elementId))
|
|
203
226
|
}))
|
|
204
227
|
|
|
205
228
|
setIsEnhancing(false)
|
|
@@ -229,8 +252,9 @@ export const useAccessibilitySupport = (
|
|
|
229
252
|
setEnhancements(prev => [...prev, ...highContrastEnhancements])
|
|
230
253
|
setState(prev => ({
|
|
231
254
|
...prev,
|
|
232
|
-
isHighContrast,
|
|
233
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
255
|
+
isHighContrast: true,
|
|
256
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
257
|
+
}))
|
|
234
258
|
|
|
235
259
|
setIsEnhancing(false)
|
|
236
260
|
|
|
@@ -259,8 +283,9 @@ export const useAccessibilitySupport = (
|
|
|
259
283
|
setEnhancements(prev => [...prev, ...reducedMotionEnhancements])
|
|
260
284
|
setState(prev => ({
|
|
261
285
|
...prev,
|
|
262
|
-
isReducedMotion,
|
|
263
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
286
|
+
isReducedMotion: true,
|
|
287
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
288
|
+
}))
|
|
264
289
|
|
|
265
290
|
setIsEnhancing(false)
|
|
266
291
|
|
|
@@ -289,8 +314,9 @@ export const useAccessibilitySupport = (
|
|
|
289
314
|
setEnhancements(prev => [...prev, ...voiceControlEnhancements])
|
|
290
315
|
setState(prev => ({
|
|
291
316
|
...prev,
|
|
292
|
-
isVoiceControlEnabled,
|
|
293
|
-
accessibilityLevel=== 'basic' ? 'enhanced'
|
|
317
|
+
isVoiceControlEnabled: true,
|
|
318
|
+
accessibilityLevel: prev.accessibilityLevel === 'basic' ? 'enhanced' : 'advanced'
|
|
319
|
+
}))
|
|
294
320
|
|
|
295
321
|
setIsEnhancing(false)
|
|
296
322
|
|
|
@@ -305,10 +331,11 @@ export const useAccessibilitySupport = (
|
|
|
305
331
|
// Accessibility validation
|
|
306
332
|
const validateAccessibility = useCallback(() => {
|
|
307
333
|
const validation = {
|
|
308
|
-
isValid,
|
|
309
|
-
warnings] as string[],
|
|
310
|
-
errors] as string[],
|
|
311
|
-
score
|
|
334
|
+
isValid: true,
|
|
335
|
+
warnings: [] as string[],
|
|
336
|
+
errors: [] as string[],
|
|
337
|
+
score: 0
|
|
338
|
+
}
|
|
312
339
|
|
|
313
340
|
// Check ARIA support
|
|
314
341
|
if (!state.hasAriaLabels) {
|
|
@@ -346,16 +373,18 @@ export const useAccessibilitySupport = (
|
|
|
346
373
|
// Accessibility analysis
|
|
347
374
|
const analyzeAccessibility = useCallback(() => {
|
|
348
375
|
const analysis = {
|
|
349
|
-
level,
|
|
350
|
-
features
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
376
|
+
level: state.accessibilityLevel,
|
|
377
|
+
features: {
|
|
378
|
+
aria: state.hasAriaLabels,
|
|
379
|
+
keyboard: state.hasKeyboardNavigation,
|
|
380
|
+
screenReader: state.hasScreenReaderSupport,
|
|
381
|
+
focus: state.hasFocusManagement,
|
|
382
|
+
highContrast: state.isHighContrast,
|
|
383
|
+
reducedMotion: state.isReducedMotion,
|
|
384
|
+
voiceControl: state.isVoiceControlEnabled
|
|
385
|
+
},
|
|
386
|
+
coverage: 0,
|
|
387
|
+
recommendations: [] as string[]
|
|
359
388
|
}
|
|
360
389
|
|
|
361
390
|
// Calculate coverage
|
|
@@ -410,11 +439,12 @@ export const useAccessibilitySupport = (
|
|
|
410
439
|
setEnhancements(prev => [...prev, ...autoEnhancements])
|
|
411
440
|
setState(prev => ({
|
|
412
441
|
...prev,
|
|
413
|
-
hasAriaLabels,
|
|
414
|
-
hasKeyboardNavigation,
|
|
415
|
-
hasScreenReaderSupport,
|
|
416
|
-
hasFocusManagement,
|
|
417
|
-
accessibilityLevel
|
|
442
|
+
hasAriaLabels: true,
|
|
443
|
+
hasKeyboardNavigation: true,
|
|
444
|
+
hasScreenReaderSupport: true,
|
|
445
|
+
hasFocusManagement: true,
|
|
446
|
+
accessibilityLevel: 'enhanced'
|
|
447
|
+
}))
|
|
418
448
|
|
|
419
449
|
setIsEnhancing(false)
|
|
420
450
|
|
|
@@ -428,7 +458,7 @@ export const useAccessibilitySupport = (
|
|
|
428
458
|
useEffect(() => {
|
|
429
459
|
// Check for high contrast preference
|
|
430
460
|
if (enableHighContrastMode) {
|
|
431
|
-
const highContrastQuery = window.matchMedia('(prefers-contrast)')
|
|
461
|
+
const highContrastQuery = window.matchMedia('(prefers-contrast: high)')
|
|
432
462
|
if (highContrastQuery.matches) {
|
|
433
463
|
enableHighContrastFeature()
|
|
434
464
|
}
|
|
@@ -436,7 +466,7 @@ export const useAccessibilitySupport = (
|
|
|
436
466
|
|
|
437
467
|
// Check for reduced motion preference
|
|
438
468
|
if (enableReducedMotionMode) {
|
|
439
|
-
const reducedMotionQuery = window.matchMedia('(prefers-reduced-motion)')
|
|
469
|
+
const reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
440
470
|
if (reducedMotionQuery.matches) {
|
|
441
471
|
enableReducedMotionFeature()
|
|
442
472
|
}
|
|
@@ -461,12 +491,12 @@ export const useAccessibilitySupport = (
|
|
|
461
491
|
|
|
462
492
|
// Enhancement functions
|
|
463
493
|
enhanceAriaSupport,
|
|
464
|
-
enableKeyboardNavigation,
|
|
494
|
+
enableKeyboardNavigation: enableKeyboardNavigationFeature,
|
|
465
495
|
enhanceScreenReaderSupport,
|
|
466
496
|
improveFocusManagement,
|
|
467
|
-
enableHighContrast,
|
|
468
|
-
enableReducedMotion,
|
|
469
|
-
enableVoiceControl,
|
|
497
|
+
enableHighContrast: enableHighContrastFeature,
|
|
498
|
+
enableReducedMotion: enableReducedMotionFeature,
|
|
499
|
+
enableVoiceControl: enableVoiceControlFeature,
|
|
470
500
|
autoEnhanceAccessibility,
|
|
471
501
|
|
|
472
502
|
// Analysis and validation
|
|
@@ -474,14 +504,14 @@ export const useAccessibilitySupport = (
|
|
|
474
504
|
analyzeAccessibility,
|
|
475
505
|
|
|
476
506
|
// Utility functions
|
|
477
|
-
isAccessibilityEnhanced) => state.accessibilityLevel !== 'basic',
|
|
478
|
-
getAccessibilityLevel) => state.accessibilityLevel,
|
|
479
|
-
getAccessibilityScore) => {
|
|
507
|
+
isAccessibilityEnhanced: () => state.accessibilityLevel !== 'basic',
|
|
508
|
+
getAccessibilityLevel: () => state.accessibilityLevel,
|
|
509
|
+
getAccessibilityScore: () => {
|
|
480
510
|
const validation = validateAccessibility()
|
|
481
511
|
return validation.score
|
|
482
512
|
},
|
|
483
|
-
clearEnhancements) => setEnhancements([]),
|
|
484
|
-
clearWarnings) => setAccessibilityWarnings([])
|
|
513
|
+
clearEnhancements: () => setEnhancements([]),
|
|
514
|
+
clearWarnings: () => setAccessibilityWarnings([])
|
|
485
515
|
}
|
|
486
516
|
}
|
|
487
517
|
|
|
@@ -5,23 +5,43 @@ export type Orientation = 'portrait' | 'landscape'
|
|
|
5
5
|
export type ScreenSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
6
6
|
|
|
7
7
|
export interface AdaptiveLayoutState {
|
|
8
|
-
deviceType
|
|
8
|
+
deviceType: DeviceType
|
|
9
|
+
orientation: Orientation
|
|
10
|
+
screenSize: ScreenSize
|
|
11
|
+
width: number
|
|
12
|
+
height: number
|
|
13
|
+
isTouchDevice: boolean
|
|
14
|
+
isHighDensity: boolean
|
|
15
|
+
isLowPower: boolean
|
|
16
|
+
performanceScore: number
|
|
17
|
+
}
|
|
9
18
|
|
|
10
19
|
export interface AdaptiveLayoutConfig {
|
|
11
|
-
enablePerformanceOptimization
|
|
20
|
+
enablePerformanceOptimization?: boolean
|
|
21
|
+
enableTouchOptimization?: boolean
|
|
22
|
+
enableBatteryOptimization?: boolean
|
|
23
|
+
enableMemoryOptimization?: boolean
|
|
24
|
+
breakpoints?: {
|
|
25
|
+
xs: number
|
|
26
|
+
sm: number
|
|
27
|
+
md: number
|
|
28
|
+
lg: number
|
|
29
|
+
xl: number
|
|
30
|
+
'2xl': number
|
|
31
|
+
}
|
|
12
32
|
}
|
|
13
33
|
|
|
14
34
|
export interface AdaptiveLayoutCallbacks {
|
|
15
|
-
onDeviceChange
|
|
16
|
-
onOrientationChange
|
|
17
|
-
onScreenSizeChange
|
|
18
|
-
onPerformanceChange
|
|
19
|
-
onBatteryChange
|
|
35
|
+
onDeviceChange?: (deviceType: DeviceType) => void
|
|
36
|
+
onOrientationChange?: (orientation: Orientation) => void
|
|
37
|
+
onScreenSizeChange?: (screenSize: ScreenSize) => void
|
|
38
|
+
onPerformanceChange?: (score: number) => void
|
|
39
|
+
onBatteryChange?: (isLow: boolean) => void
|
|
20
40
|
}
|
|
21
41
|
|
|
22
42
|
export const useAdaptiveLayout = (
|
|
23
|
-
config= {},
|
|
24
|
-
callbacks= {}
|
|
43
|
+
config: AdaptiveLayoutConfig = {},
|
|
44
|
+
callbacks: AdaptiveLayoutCallbacks = {}
|
|
25
45
|
) => {
|
|
26
46
|
const {
|
|
27
47
|
enablePerformanceOptimization = true,
|
|
@@ -29,34 +49,36 @@ export const useAdaptiveLayout = (
|
|
|
29
49
|
enableBatteryOptimization = true,
|
|
30
50
|
enableMemoryOptimization = true,
|
|
31
51
|
breakpoints = {
|
|
32
|
-
xs,
|
|
33
|
-
sm,
|
|
34
|
-
md,
|
|
35
|
-
lg,
|
|
36
|
-
xl,
|
|
37
|
-
'2xl'
|
|
52
|
+
xs: 0,
|
|
53
|
+
sm: 640,
|
|
54
|
+
md: 768,
|
|
55
|
+
lg: 1024,
|
|
56
|
+
xl: 1280,
|
|
57
|
+
'2xl': 1536
|
|
58
|
+
}
|
|
38
59
|
} = config
|
|
39
60
|
|
|
40
61
|
const [state, setState] = useState<AdaptiveLayoutState>({
|
|
41
|
-
deviceType,
|
|
42
|
-
orientation,
|
|
43
|
-
screenSize,
|
|
44
|
-
width,
|
|
45
|
-
height,
|
|
46
|
-
isTouchDevice,
|
|
47
|
-
isHighDensity,
|
|
48
|
-
isLowPower,
|
|
49
|
-
performanceScore
|
|
62
|
+
deviceType: 'desktop',
|
|
63
|
+
orientation: 'landscape',
|
|
64
|
+
screenSize: 'lg',
|
|
65
|
+
width: 0,
|
|
66
|
+
height: 0,
|
|
67
|
+
isTouchDevice: false,
|
|
68
|
+
isHighDensity: false,
|
|
69
|
+
isLowPower: false,
|
|
70
|
+
performanceScore: 100
|
|
71
|
+
})
|
|
50
72
|
|
|
51
73
|
// Device detection
|
|
52
|
-
const detectDevice = useCallback((width, _height)=> {
|
|
74
|
+
const detectDevice = useCallback((width: number, _height: number): DeviceType => {
|
|
53
75
|
if (width < breakpoints.md) return 'mobile'
|
|
54
76
|
if (width < breakpoints.lg) return 'tablet'
|
|
55
77
|
return 'desktop'
|
|
56
78
|
}, [breakpoints])
|
|
57
79
|
|
|
58
80
|
// Screen size detection
|
|
59
|
-
const detectScreenSize = useCallback((width)=> {
|
|
81
|
+
const detectScreenSize = useCallback((width: number): ScreenSize => {
|
|
60
82
|
if (width < breakpoints.sm) return 'xs'
|
|
61
83
|
if (width < breakpoints.md) return 'sm'
|
|
62
84
|
if (width < breakpoints.lg) return 'md'
|
|
@@ -66,17 +88,17 @@ export const useAdaptiveLayout = (
|
|
|
66
88
|
}, [breakpoints])
|
|
67
89
|
|
|
68
90
|
// Touch device detection
|
|
69
|
-
const detectTouchDevice = useCallback(()=> {
|
|
91
|
+
const detectTouchDevice = useCallback((): boolean => {
|
|
70
92
|
return 'ontouchstart' in window || navigator.maxTouchPoints > 0
|
|
71
93
|
}, [])
|
|
72
94
|
|
|
73
95
|
// High density display detection
|
|
74
|
-
const detectHighDensity = useCallback(()=> {
|
|
96
|
+
const detectHighDensity = useCallback((): boolean => {
|
|
75
97
|
return window.devicePixelRatio > 1
|
|
76
98
|
}, [])
|
|
77
99
|
|
|
78
100
|
// Battery status detection
|
|
79
|
-
const detectBatteryStatus = useCallback(async ()=> {
|
|
101
|
+
const detectBatteryStatus = useCallback(async (): Promise<boolean> => {
|
|
80
102
|
if ('getBattery' in navigator) {
|
|
81
103
|
try {
|
|
82
104
|
const battery = await (navigator as any).getBattery()
|
|
@@ -89,7 +111,7 @@ export const useAdaptiveLayout = (
|
|
|
89
111
|
}, [])
|
|
90
112
|
|
|
91
113
|
// Performance monitoring
|
|
92
|
-
const measurePerformance = useCallback(async ()=> {
|
|
114
|
+
const measurePerformance = useCallback(async (): Promise<number> => {
|
|
93
115
|
if (!enablePerformanceOptimization) return 100
|
|
94
116
|
|
|
95
117
|
const startTime = performance.now()
|
|
@@ -109,7 +131,7 @@ export const useAdaptiveLayout = (
|
|
|
109
131
|
}, [enablePerformanceOptimization])
|
|
110
132
|
|
|
111
133
|
// Memory usage monitoring
|
|
112
|
-
const measureMemoryUsage = useCallback(()=> {
|
|
134
|
+
const measureMemoryUsage = useCallback((): number => {
|
|
113
135
|
if (!enableMemoryOptimization || !('memory' in performance)) return 0
|
|
114
136
|
|
|
115
137
|
const memory = (performance as any).memory
|
|
@@ -122,12 +144,13 @@ export const useAdaptiveLayout = (
|
|
|
122
144
|
const height = window.innerHeight
|
|
123
145
|
const deviceType = detectDevice(width, height)
|
|
124
146
|
const screenSize = detectScreenSize(width)
|
|
125
|
-
const orientation = width > height ? 'landscape'
|
|
147
|
+
const orientation = width > height ? 'landscape' : 'portrait'
|
|
148
|
+
const isTouchDevice = detectTouchDevice()
|
|
126
149
|
const isHighDensity = detectHighDensity()
|
|
127
150
|
const isLowPower = await detectBatteryStatus()
|
|
128
151
|
const performanceScore = await measurePerformance()
|
|
129
152
|
|
|
130
|
-
const newState= {
|
|
153
|
+
const newState: AdaptiveLayoutState = {
|
|
131
154
|
deviceType,
|
|
132
155
|
orientation,
|
|
133
156
|
screenSize,
|
|
@@ -5,23 +5,43 @@ export type Orientation = 'portrait' | 'landscape'
|
|
|
5
5
|
export type ScreenSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
6
6
|
|
|
7
7
|
export interface AdaptiveLayoutState {
|
|
8
|
-
deviceType
|
|
8
|
+
deviceType: DeviceType
|
|
9
|
+
orientation: Orientation
|
|
10
|
+
screenSize: ScreenSize
|
|
11
|
+
width: number
|
|
12
|
+
height: number
|
|
13
|
+
isTouchDevice: boolean
|
|
14
|
+
isHighDensity: boolean
|
|
15
|
+
isLowPower: boolean
|
|
16
|
+
performanceScore: number
|
|
17
|
+
}
|
|
9
18
|
|
|
10
19
|
export interface AdaptiveLayoutConfig {
|
|
11
|
-
enablePerformanceOptimization
|
|
20
|
+
enablePerformanceOptimization?: boolean
|
|
21
|
+
enableTouchOptimization?: boolean
|
|
22
|
+
enableBatteryOptimization?: boolean
|
|
23
|
+
enableMemoryOptimization?: boolean
|
|
24
|
+
breakpoints?: {
|
|
25
|
+
xs: number
|
|
26
|
+
sm: number
|
|
27
|
+
md: number
|
|
28
|
+
lg: number
|
|
29
|
+
xl: number
|
|
30
|
+
'2xl': number
|
|
31
|
+
}
|
|
12
32
|
}
|
|
13
33
|
|
|
14
34
|
export interface AdaptiveLayoutCallbacks {
|
|
15
|
-
onDeviceChange
|
|
16
|
-
onOrientationChange
|
|
17
|
-
onScreenSizeChange
|
|
18
|
-
onPerformanceChange
|
|
19
|
-
onBatteryChange
|
|
35
|
+
onDeviceChange?: (deviceType: DeviceType) => void
|
|
36
|
+
onOrientationChange?: (orientation: Orientation) => void
|
|
37
|
+
onScreenSizeChange?: (screenSize: ScreenSize) => void
|
|
38
|
+
onPerformanceChange?: (score: number) => void
|
|
39
|
+
onBatteryChange?: (isLow: boolean) => void
|
|
20
40
|
}
|
|
21
41
|
|
|
22
42
|
export const useAdaptiveLayout = (
|
|
23
|
-
config= {},
|
|
24
|
-
callbacks= {}
|
|
43
|
+
config: AdaptiveLayoutConfig = {},
|
|
44
|
+
callbacks: AdaptiveLayoutCallbacks = {}
|
|
25
45
|
) => {
|
|
26
46
|
const {
|
|
27
47
|
enablePerformanceOptimization = true,
|
|
@@ -29,34 +49,36 @@ export const useAdaptiveLayout = (
|
|
|
29
49
|
enableBatteryOptimization = true,
|
|
30
50
|
enableMemoryOptimization = true,
|
|
31
51
|
breakpoints = {
|
|
32
|
-
xs,
|
|
33
|
-
sm,
|
|
34
|
-
md,
|
|
35
|
-
lg,
|
|
36
|
-
xl,
|
|
37
|
-
'2xl'
|
|
52
|
+
xs: 0,
|
|
53
|
+
sm: 640,
|
|
54
|
+
md: 768,
|
|
55
|
+
lg: 1024,
|
|
56
|
+
xl: 1280,
|
|
57
|
+
'2xl': 1536
|
|
58
|
+
}
|
|
38
59
|
} = config
|
|
39
60
|
|
|
40
61
|
const [state, setState] = useState<AdaptiveLayoutState>({
|
|
41
|
-
deviceType,
|
|
42
|
-
orientation,
|
|
43
|
-
screenSize,
|
|
44
|
-
width,
|
|
45
|
-
height,
|
|
46
|
-
isTouchDevice,
|
|
47
|
-
isHighDensity,
|
|
48
|
-
isLowPower,
|
|
49
|
-
performanceScore
|
|
62
|
+
deviceType: 'desktop',
|
|
63
|
+
orientation: 'landscape',
|
|
64
|
+
screenSize: 'lg',
|
|
65
|
+
width: 0,
|
|
66
|
+
height: 0,
|
|
67
|
+
isTouchDevice: false,
|
|
68
|
+
isHighDensity: false,
|
|
69
|
+
isLowPower: false,
|
|
70
|
+
performanceScore: 100
|
|
71
|
+
})
|
|
50
72
|
|
|
51
73
|
// Device detection
|
|
52
|
-
const detectDevice = useCallback((width, _height)=> {
|
|
74
|
+
const detectDevice = useCallback((width: number, _height: number): DeviceType => {
|
|
53
75
|
if (width < breakpoints.md) return 'mobile'
|
|
54
76
|
if (width < breakpoints.lg) return 'tablet'
|
|
55
77
|
return 'desktop'
|
|
56
78
|
}, [breakpoints])
|
|
57
79
|
|
|
58
80
|
// Screen size detection
|
|
59
|
-
const detectScreenSize = useCallback((width)=> {
|
|
81
|
+
const detectScreenSize = useCallback((width: number): ScreenSize => {
|
|
60
82
|
if (width < breakpoints.sm) return 'xs'
|
|
61
83
|
if (width < breakpoints.md) return 'sm'
|
|
62
84
|
if (width < breakpoints.lg) return 'md'
|
|
@@ -66,17 +88,17 @@ export const useAdaptiveLayout = (
|
|
|
66
88
|
}, [breakpoints])
|
|
67
89
|
|
|
68
90
|
// Touch device detection
|
|
69
|
-
const detectTouchDevice = useCallback(()=> {
|
|
91
|
+
const detectTouchDevice = useCallback((): boolean => {
|
|
70
92
|
return 'ontouchstart' in window || navigator.maxTouchPoints > 0
|
|
71
93
|
}, [])
|
|
72
94
|
|
|
73
95
|
// High density display detection
|
|
74
|
-
const detectHighDensity = useCallback(()=> {
|
|
96
|
+
const detectHighDensity = useCallback((): boolean => {
|
|
75
97
|
return window.devicePixelRatio > 1
|
|
76
98
|
}, [])
|
|
77
99
|
|
|
78
100
|
// Battery status detection
|
|
79
|
-
const detectBatteryStatus = useCallback(async ()=> {
|
|
101
|
+
const detectBatteryStatus = useCallback(async (): Promise<boolean> => {
|
|
80
102
|
if ('getBattery' in navigator) {
|
|
81
103
|
try {
|
|
82
104
|
const battery = await (navigator as any).getBattery()
|
|
@@ -89,7 +111,7 @@ export const useAdaptiveLayout = (
|
|
|
89
111
|
}, [])
|
|
90
112
|
|
|
91
113
|
// Performance monitoring
|
|
92
|
-
const measurePerformance = useCallback(async ()=> {
|
|
114
|
+
const measurePerformance = useCallback(async (): Promise<number> => {
|
|
93
115
|
if (!enablePerformanceOptimization) return 100
|
|
94
116
|
|
|
95
117
|
const startTime = performance.now()
|
|
@@ -109,7 +131,7 @@ export const useAdaptiveLayout = (
|
|
|
109
131
|
}, [enablePerformanceOptimization])
|
|
110
132
|
|
|
111
133
|
// Memory usage monitoring
|
|
112
|
-
const measureMemoryUsage = useCallback(()=> {
|
|
134
|
+
const measureMemoryUsage = useCallback((): number => {
|
|
113
135
|
if (!enableMemoryOptimization || !('memory' in performance)) return 0
|
|
114
136
|
|
|
115
137
|
const memory = (performance as any).memory
|
|
@@ -122,12 +144,13 @@ export const useAdaptiveLayout = (
|
|
|
122
144
|
const height = window.innerHeight
|
|
123
145
|
const deviceType = detectDevice(width, height)
|
|
124
146
|
const screenSize = detectScreenSize(width)
|
|
125
|
-
const orientation = width > height ? 'landscape'
|
|
147
|
+
const orientation = width > height ? 'landscape' : 'portrait'
|
|
148
|
+
const isTouchDevice = detectTouchDevice()
|
|
126
149
|
const isHighDensity = detectHighDensity()
|
|
127
150
|
const isLowPower = await detectBatteryStatus()
|
|
128
151
|
const performanceScore = await measurePerformance()
|
|
129
152
|
|
|
130
|
-
const newState= {
|
|
153
|
+
const newState: AdaptiveLayoutState = {
|
|
131
154
|
deviceType,
|
|
132
155
|
orientation,
|
|
133
156
|
screenSize,
|