@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,117 +1,124 @@
|
|
|
1
1
|
// Keyboard key constants
|
|
2
2
|
export const KEY_CODES = {
|
|
3
3
|
// Navigation keys
|
|
4
|
-
TAB,
|
|
5
|
-
SHIFT_TAB,
|
|
6
|
-
ARROW_UP,
|
|
7
|
-
ARROW_DOWN,
|
|
8
|
-
ARROW_LEFT,
|
|
9
|
-
ARROW_RIGHT,
|
|
10
|
-
HOME,
|
|
11
|
-
END,
|
|
12
|
-
PAGE_UP,
|
|
13
|
-
PAGE_DOWN,
|
|
4
|
+
TAB: 'Tab',
|
|
5
|
+
SHIFT_TAB: 'Shift+Tab',
|
|
6
|
+
ARROW_UP: 'ArrowUp',
|
|
7
|
+
ARROW_DOWN: 'ArrowDown',
|
|
8
|
+
ARROW_LEFT: 'ArrowLeft',
|
|
9
|
+
ARROW_RIGHT: 'ArrowRight',
|
|
10
|
+
HOME: 'Home',
|
|
11
|
+
END: 'End',
|
|
12
|
+
PAGE_UP: 'PageUp',
|
|
13
|
+
PAGE_DOWN: 'PageDown',
|
|
14
14
|
|
|
15
15
|
// Action keys
|
|
16
|
-
ENTER,
|
|
17
|
-
SPACE,
|
|
18
|
-
ESCAPE,
|
|
19
|
-
BACKSPACE,
|
|
20
|
-
DELETE,
|
|
16
|
+
ENTER: 'Enter',
|
|
17
|
+
SPACE: ' ',
|
|
18
|
+
ESCAPE: 'Escape',
|
|
19
|
+
BACKSPACE: 'Backspace',
|
|
20
|
+
DELETE: 'Delete',
|
|
21
21
|
|
|
22
22
|
// Modifier keys
|
|
23
|
-
SHIFT,
|
|
24
|
-
CTRL,
|
|
25
|
-
ALT,
|
|
26
|
-
META,
|
|
23
|
+
SHIFT: 'Shift',
|
|
24
|
+
CTRL: 'Control',
|
|
25
|
+
ALT: 'Alt',
|
|
26
|
+
META: 'Meta',
|
|
27
27
|
|
|
28
28
|
// Function keys
|
|
29
|
-
F1,
|
|
30
|
-
F2,
|
|
31
|
-
F3,
|
|
32
|
-
F4,
|
|
33
|
-
F5,
|
|
34
|
-
F6,
|
|
35
|
-
F7,
|
|
36
|
-
F8,
|
|
37
|
-
F9,
|
|
38
|
-
F10,
|
|
39
|
-
F11,
|
|
40
|
-
F12
|
|
29
|
+
F1: 'F1',
|
|
30
|
+
F2: 'F2',
|
|
31
|
+
F3: 'F3',
|
|
32
|
+
F4: 'F4',
|
|
33
|
+
F5: 'F5',
|
|
34
|
+
F6: 'F6',
|
|
35
|
+
F7: 'F7',
|
|
36
|
+
F8: 'F8',
|
|
37
|
+
F9: 'F9',
|
|
38
|
+
F10: 'F10',
|
|
39
|
+
F11: 'F11',
|
|
40
|
+
F12: 'F12'
|
|
41
|
+
} as const;
|
|
41
42
|
|
|
42
43
|
// Keyboard navigation patterns
|
|
43
44
|
export const NAVIGATION_PATTERNS = {
|
|
44
45
|
// List navigation
|
|
45
|
-
LIST
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
LIST: {
|
|
47
|
+
NEXT: [KEY_CODES.ARROW_DOWN, KEY_CODES.ARROW_RIGHT],
|
|
48
|
+
PREVIOUS: [KEY_CODES.ARROW_UP, KEY_CODES.ARROW_LEFT],
|
|
49
|
+
FIRST: [KEY_CODES.HOME],
|
|
50
|
+
LAST: [KEY_CODES.END],
|
|
51
|
+
SELECT: [KEY_CODES.ENTER, KEY_CODES.SPACE]
|
|
50
52
|
},
|
|
51
53
|
|
|
52
54
|
// Grid navigation
|
|
53
|
-
GRID
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
GRID: {
|
|
56
|
+
NEXT_ROW: [KEY_CODES.ARROW_DOWN],
|
|
57
|
+
PREVIOUS_ROW: [KEY_CODES.ARROW_UP],
|
|
58
|
+
NEXT_COLUMN: [KEY_CODES.ARROW_RIGHT],
|
|
59
|
+
PREVIOUS_COLUMN: [KEY_CODES.ARROW_LEFT],
|
|
60
|
+
FIRST_ROW: [KEY_CODES.HOME],
|
|
61
|
+
LAST_ROW: [KEY_CODES.END],
|
|
62
|
+
FIRST_COLUMN: [KEY_CODES.CTRL + '+' + KEY_CODES.HOME],
|
|
63
|
+
LAST_COLUMN: [KEY_CODES.CTRL + '+' + KEY_CODES.END]
|
|
61
64
|
},
|
|
62
65
|
|
|
63
66
|
// Tree navigation
|
|
64
|
-
TREE
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
TREE: {
|
|
68
|
+
EXPAND: [KEY_CODES.ARROW_RIGHT],
|
|
69
|
+
COLLAPSE: [KEY_CODES.ARROW_LEFT],
|
|
70
|
+
NEXT_ITEM: [KEY_CODES.ARROW_DOWN],
|
|
71
|
+
PREVIOUS_ITEM: [KEY_CODES.ARROW_UP],
|
|
72
|
+
FIRST_ITEM: [KEY_CODES.HOME],
|
|
73
|
+
LAST_ITEM: [KEY_CODES.END],
|
|
74
|
+
SELECT: [KEY_CODES.ENTER, KEY_CODES.SPACE]
|
|
71
75
|
},
|
|
72
76
|
|
|
73
77
|
// Tab navigation
|
|
74
|
-
TABS
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
TABS: {
|
|
79
|
+
NEXT_TAB: [KEY_CODES.ARROW_RIGHT],
|
|
80
|
+
PREVIOUS_TAB: [KEY_CODES.ARROW_LEFT],
|
|
81
|
+
FIRST_TAB: [KEY_CODES.HOME],
|
|
82
|
+
LAST_TAB: [KEY_CODES.END],
|
|
83
|
+
SELECT_TAB: [KEY_CODES.ENTER, KEY_CODES.SPACE]
|
|
79
84
|
},
|
|
80
85
|
|
|
81
86
|
// Menu navigation
|
|
82
|
-
MENU
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
MENU: {
|
|
88
|
+
OPEN: [KEY_CODES.ENTER, KEY_CODES.SPACE, KEY_CODES.ARROW_DOWN],
|
|
89
|
+
CLOSE: [KEY_CODES.ESCAPE],
|
|
90
|
+
NEXT_ITEM: [KEY_CODES.ARROW_DOWN],
|
|
91
|
+
PREVIOUS_ITEM: [KEY_CODES.ARROW_UP],
|
|
92
|
+
FIRST_ITEM: [KEY_CODES.HOME],
|
|
93
|
+
LAST_ITEM: [KEY_CODES.END],
|
|
94
|
+
SELECT: [KEY_CODES.ENTER, KEY_CODES.SPACE]
|
|
89
95
|
},
|
|
90
96
|
|
|
91
97
|
// Modal navigation
|
|
92
|
-
MODAL
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
MODAL: {
|
|
99
|
+
CLOSE: [KEY_CODES.ESCAPE],
|
|
100
|
+
NEXT_FOCUS: [KEY_CODES.TAB],
|
|
101
|
+
PREVIOUS_FOCUS: [KEY_CODES.SHIFT + '+' + KEY_CODES.TAB]
|
|
95
102
|
}
|
|
96
103
|
} as const;
|
|
97
104
|
|
|
98
105
|
// Keyboard navigation manager
|
|
99
106
|
export class KeyboardNavigationManager {
|
|
100
|
-
private focusableSelectors];
|
|
101
|
-
private currentFocusIndex;
|
|
102
|
-
private focusableElements];
|
|
103
|
-
private container;
|
|
104
|
-
private onFocusChange, index) => void) | null;
|
|
107
|
+
private focusableSelectors: string[];
|
|
108
|
+
private currentFocusIndex: number;
|
|
109
|
+
private focusableElements: HTMLElement[];
|
|
110
|
+
private container: HTMLElement | null;
|
|
111
|
+
private onFocusChange: ((element: HTMLElement, index: number) => void) | null;
|
|
105
112
|
|
|
106
113
|
constructor(
|
|
107
|
-
container
|
|
108
|
-
focusableSelectors] = [
|
|
109
|
-
'button])',
|
|
110
|
-
'input])',
|
|
111
|
-
'select])',
|
|
112
|
-
'textarea])',
|
|
114
|
+
container?: HTMLElement,
|
|
115
|
+
focusableSelectors: string[] = [
|
|
116
|
+
'button:not([disabled])',
|
|
117
|
+
'input:not([disabled])',
|
|
118
|
+
'select:not([disabled])',
|
|
119
|
+
'textarea:not([disabled])',
|
|
113
120
|
'a[href]',
|
|
114
|
-
'[tabindex]="-1"])',
|
|
121
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
115
122
|
'[contenteditable="true"]'
|
|
116
123
|
]
|
|
117
124
|
) {
|
|
@@ -125,7 +132,7 @@ export class KeyboardNavigationManager {
|
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
// Set container element
|
|
128
|
-
setContainer(container) {
|
|
135
|
+
setContainer(container: HTMLElement) {
|
|
129
136
|
this.container = container;
|
|
130
137
|
this.updateFocusableElements();
|
|
131
138
|
}
|
|
@@ -147,21 +154,23 @@ export class KeyboardNavigationManager {
|
|
|
147
154
|
}
|
|
148
155
|
|
|
149
156
|
// Set focus change callback
|
|
150
|
-
onFocusChangeCallback(callback, index) => void) {
|
|
157
|
+
onFocusChangeCallback(callback: (element: HTMLElement, index: number) => void) {
|
|
151
158
|
this.onFocusChange = callback;
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
// Get current focusable elements
|
|
155
|
-
getFocusableElements()] {
|
|
162
|
+
getFocusableElements(): HTMLElement[] {
|
|
156
163
|
return [...this.focusableElements];
|
|
157
164
|
}
|
|
158
165
|
|
|
159
166
|
// Get current focus index
|
|
160
|
-
getCurrentFocusIndex()
|
|
167
|
+
getCurrentFocusIndex(): number {
|
|
168
|
+
return this.currentFocusIndex;
|
|
161
169
|
}
|
|
162
170
|
|
|
163
171
|
// Focus first element
|
|
164
|
-
focusFirst()
|
|
172
|
+
focusFirst(): boolean {
|
|
173
|
+
if (this.focusableElements.length === 0) return false;
|
|
165
174
|
|
|
166
175
|
this.currentFocusIndex = 0;
|
|
167
176
|
const element = this.focusableElements[0];
|
|
@@ -175,7 +184,8 @@ export class KeyboardNavigationManager {
|
|
|
175
184
|
}
|
|
176
185
|
|
|
177
186
|
// Focus last element
|
|
178
|
-
focusLast()
|
|
187
|
+
focusLast(): boolean {
|
|
188
|
+
if (this.focusableElements.length === 0) return false;
|
|
179
189
|
|
|
180
190
|
this.currentFocusIndex = this.focusableElements.length - 1;
|
|
181
191
|
const element = this.focusableElements[this.currentFocusIndex];
|
|
@@ -189,7 +199,8 @@ export class KeyboardNavigationManager {
|
|
|
189
199
|
}
|
|
190
200
|
|
|
191
201
|
// Focus next element
|
|
192
|
-
focusNext()
|
|
202
|
+
focusNext(): boolean {
|
|
203
|
+
if (this.focusableElements.length === 0) return false;
|
|
193
204
|
|
|
194
205
|
const nextIndex = (this.currentFocusIndex + 1) % this.focusableElements.length;
|
|
195
206
|
this.currentFocusIndex = nextIndex;
|
|
@@ -204,11 +215,12 @@ export class KeyboardNavigationManager {
|
|
|
204
215
|
}
|
|
205
216
|
|
|
206
217
|
// Focus previous element
|
|
207
|
-
focusPrevious()
|
|
218
|
+
focusPrevious(): boolean {
|
|
219
|
+
if (this.focusableElements.length === 0) return false;
|
|
208
220
|
|
|
209
221
|
const prevIndex = this.currentFocusIndex <= 0
|
|
210
222
|
? this.focusableElements.length - 1
|
|
211
|
-
;
|
|
223
|
+
: this.currentFocusIndex - 1;
|
|
212
224
|
this.currentFocusIndex = prevIndex;
|
|
213
225
|
const element = this.focusableElements[prevIndex];
|
|
214
226
|
element.focus();
|
|
@@ -221,7 +233,8 @@ export class KeyboardNavigationManager {
|
|
|
221
233
|
}
|
|
222
234
|
|
|
223
235
|
// Focus element by index
|
|
224
|
-
focusByIndex(index
|
|
236
|
+
focusByIndex(index: number): boolean {
|
|
237
|
+
if (index < 0 || index >= this.focusableElements.length) return false;
|
|
225
238
|
|
|
226
239
|
this.currentFocusIndex = index;
|
|
227
240
|
const element = this.focusableElements[index];
|
|
@@ -235,14 +248,16 @@ export class KeyboardNavigationManager {
|
|
|
235
248
|
}
|
|
236
249
|
|
|
237
250
|
// Focus element by ID
|
|
238
|
-
focusById(id)
|
|
251
|
+
focusById(id: string): boolean {
|
|
252
|
+
const index = this.focusableElements.findIndex(element => element.id === id);
|
|
239
253
|
if (index === -1) return false;
|
|
240
254
|
|
|
241
255
|
return this.focusByIndex(index);
|
|
242
256
|
}
|
|
243
257
|
|
|
244
258
|
// Focus element by data attribute
|
|
245
|
-
focusByDataAttribute(attribute, value)
|
|
259
|
+
focusByDataAttribute(attribute: string, value: string): boolean {
|
|
260
|
+
const index = this.focusableElements.findIndex(
|
|
246
261
|
element => element.getAttribute(`data-${attribute}`) === value
|
|
247
262
|
);
|
|
248
263
|
if (index === -1) return false;
|
|
@@ -251,7 +266,8 @@ export class KeyboardNavigationManager {
|
|
|
251
266
|
}
|
|
252
267
|
|
|
253
268
|
// Handle keyboard navigation
|
|
254
|
-
handleKeyDown(event)
|
|
269
|
+
handleKeyDown(event: KeyboardEvent): boolean {
|
|
270
|
+
const key = event.key;
|
|
255
271
|
const isShift = event.shiftKey;
|
|
256
272
|
const isCtrl = event.ctrlKey;
|
|
257
273
|
|
|
@@ -334,13 +350,14 @@ export class KeyboardNavigationManager {
|
|
|
334
350
|
}
|
|
335
351
|
|
|
336
352
|
// Trap focus within container (for modals, etc.)
|
|
337
|
-
trapFocus()
|
|
353
|
+
trapFocus(): void {
|
|
354
|
+
if (!this.container) return;
|
|
338
355
|
|
|
339
356
|
// Focus first element initially
|
|
340
357
|
this.focusFirst();
|
|
341
358
|
|
|
342
359
|
// Add event listener for focus trapping
|
|
343
|
-
const handleFocus = (event) => {
|
|
360
|
+
const handleFocus = (event: FocusEvent) => {
|
|
344
361
|
const target = event.target as HTMLElement;
|
|
345
362
|
|
|
346
363
|
// If focus is outside the container, move it back
|
|
@@ -360,33 +377,37 @@ export class KeyboardNavigationManager {
|
|
|
360
377
|
}
|
|
361
378
|
|
|
362
379
|
// Release focus trap
|
|
363
|
-
releaseFocusTrap()
|
|
380
|
+
releaseFocusTrap(): void {
|
|
381
|
+
if (this.container && (this.container as any)._focusTrapCleanup) {
|
|
364
382
|
(this.container as any)._focusTrapCleanup();
|
|
365
383
|
delete (this.container as any)._focusTrapCleanup;
|
|
366
384
|
}
|
|
367
385
|
}
|
|
368
386
|
|
|
369
387
|
// Restore focus to previously focused element
|
|
370
|
-
restoreFocus()
|
|
388
|
+
restoreFocus(): void {
|
|
389
|
+
if (this.currentFocusIndex >= 0 && this.currentFocusIndex < this.focusableElements.length) {
|
|
371
390
|
this.focusableElements[this.currentFocusIndex].focus();
|
|
372
391
|
}
|
|
373
392
|
}
|
|
374
393
|
|
|
375
394
|
// Get keyboard shortcuts for accessibility
|
|
376
|
-
getKeyboardShortcuts(), string> {
|
|
395
|
+
getKeyboardShortcuts(): Record<string, string> {
|
|
377
396
|
return {
|
|
378
|
-
'Navigate Next',
|
|
379
|
-
'Navigate Previous',
|
|
380
|
-
'Navigate First',
|
|
381
|
-
'Navigate Last',
|
|
382
|
-
'Navigate Page Up',
|
|
383
|
-
'Navigate Page Down',
|
|
384
|
-
'Select/Activate',
|
|
385
|
-
'Close/Cancel'
|
|
397
|
+
'Navigate Next': 'Tab or Arrow Down/Right',
|
|
398
|
+
'Navigate Previous': 'Shift+Tab or Arrow Up/Left',
|
|
399
|
+
'Navigate First': 'Home',
|
|
400
|
+
'Navigate Last': 'End',
|
|
401
|
+
'Navigate Page Up': 'Page Up',
|
|
402
|
+
'Navigate Page Down': 'Page Down',
|
|
403
|
+
'Select/Activate': 'Enter or Space',
|
|
404
|
+
'Close/Cancel': 'Escape'
|
|
405
|
+
};
|
|
386
406
|
}
|
|
387
407
|
|
|
388
408
|
// Validate keyboard navigation
|
|
389
|
-
validateNavigation()
|
|
409
|
+
validateNavigation(): boolean {
|
|
410
|
+
if (this.focusableElements.length === 0) {
|
|
390
411
|
console.warn('No focusable elements found in container');
|
|
391
412
|
return false;
|
|
392
413
|
}
|
|
@@ -398,7 +419,7 @@ export class KeyboardNavigationManager {
|
|
|
398
419
|
});
|
|
399
420
|
|
|
400
421
|
if (invalidElements.length > 0) {
|
|
401
|
-
console.warn('Some focusable elements lack proper tabindex, invalidElements);
|
|
422
|
+
console.warn('Some focusable elements lack proper tabindex:', invalidElements);
|
|
402
423
|
return false;
|
|
403
424
|
}
|
|
404
425
|
|
|
@@ -408,16 +429,16 @@ export class KeyboardNavigationManager {
|
|
|
408
429
|
|
|
409
430
|
// Focus management utilities
|
|
410
431
|
export class KeyboardFocusManager {
|
|
411
|
-
private previousActiveElement;
|
|
412
|
-
private focusableSelectors];
|
|
413
|
-
|
|
414
|
-
constructor(focusableSelectors] = [
|
|
415
|
-
'button])',
|
|
416
|
-
'input])',
|
|
417
|
-
'select])',
|
|
418
|
-
'textarea])',
|
|
432
|
+
private previousActiveElement: Element | null;
|
|
433
|
+
private focusableSelectors: string[];
|
|
434
|
+
|
|
435
|
+
constructor(focusableSelectors: string[] = [
|
|
436
|
+
'button:not([disabled])',
|
|
437
|
+
'input:not([disabled])',
|
|
438
|
+
'select:not([disabled])',
|
|
439
|
+
'textarea:not([disabled])',
|
|
419
440
|
'a[href]',
|
|
420
|
-
'[tabindex]="-1"])',
|
|
441
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
421
442
|
'[contenteditable="true"]'
|
|
422
443
|
]) {
|
|
423
444
|
this.previousActiveElement = null;
|
|
@@ -425,11 +446,13 @@ export class KeyboardFocusManager {
|
|
|
425
446
|
}
|
|
426
447
|
|
|
427
448
|
// Store current active element
|
|
428
|
-
storeActiveElement()
|
|
449
|
+
storeActiveElement(): void {
|
|
450
|
+
this.previousActiveElement = document.activeElement;
|
|
429
451
|
}
|
|
430
452
|
|
|
431
453
|
// Restore previously active element
|
|
432
|
-
restoreActiveElement()
|
|
454
|
+
restoreActiveElement(): boolean {
|
|
455
|
+
if (this.previousActiveElement && this.previousActiveElement instanceof HTMLElement) {
|
|
433
456
|
this.previousActiveElement.focus();
|
|
434
457
|
return true;
|
|
435
458
|
}
|
|
@@ -437,7 +460,7 @@ export class KeyboardFocusManager {
|
|
|
437
460
|
}
|
|
438
461
|
|
|
439
462
|
// Get all focusable elements in a container
|
|
440
|
-
getFocusableElements(container)] {
|
|
463
|
+
getFocusableElements(container: HTMLElement): HTMLElement[] {
|
|
441
464
|
return Array.from(
|
|
442
465
|
container.querySelectorAll<HTMLElement>(this.focusableSelectors.join(','))
|
|
443
466
|
).filter(element => {
|
|
@@ -447,7 +470,8 @@ export class KeyboardFocusManager {
|
|
|
447
470
|
}
|
|
448
471
|
|
|
449
472
|
// Focus first focusable element in container
|
|
450
|
-
focusFirst(container)
|
|
473
|
+
focusFirst(container: HTMLElement): boolean {
|
|
474
|
+
const focusableElements = this.getFocusableElements(container);
|
|
451
475
|
if (focusableElements.length === 0) return false;
|
|
452
476
|
|
|
453
477
|
focusableElements[0].focus();
|
|
@@ -455,7 +479,8 @@ export class KeyboardFocusManager {
|
|
|
455
479
|
}
|
|
456
480
|
|
|
457
481
|
// Focus last focusable element in container
|
|
458
|
-
focusLast(container)
|
|
482
|
+
focusLast(container: HTMLElement): boolean {
|
|
483
|
+
const focusableElements = this.getFocusableElements(container);
|
|
459
484
|
if (focusableElements.length === 0) return false;
|
|
460
485
|
|
|
461
486
|
focusableElements[focusableElements.length - 1].focus();
|
|
@@ -463,7 +488,9 @@ export class KeyboardFocusManager {
|
|
|
463
488
|
}
|
|
464
489
|
|
|
465
490
|
// Check if element is focusable
|
|
466
|
-
isFocusable(element)
|
|
491
|
+
isFocusable(element: HTMLElement): boolean {
|
|
492
|
+
// Check if element matches focusable selectors
|
|
493
|
+
const isSelectorMatch = this.focusableSelectors.some(selector => {
|
|
467
494
|
try {
|
|
468
495
|
return element.matches(selector);
|
|
469
496
|
} catch {
|
|
@@ -484,7 +511,8 @@ export class KeyboardFocusManager {
|
|
|
484
511
|
}
|
|
485
512
|
|
|
486
513
|
// Get next focusable element
|
|
487
|
-
getNextFocusableElement(currentElement, container)
|
|
514
|
+
getNextFocusableElement(currentElement: HTMLElement, container: HTMLElement): HTMLElement | null {
|
|
515
|
+
const focusableElements = this.getFocusableElements(container);
|
|
488
516
|
const currentIndex = focusableElements.indexOf(currentElement);
|
|
489
517
|
|
|
490
518
|
if (currentIndex === -1 || currentIndex === focusableElements.length - 1) {
|
|
@@ -495,7 +523,8 @@ export class KeyboardFocusManager {
|
|
|
495
523
|
}
|
|
496
524
|
|
|
497
525
|
// Get previous focusable element
|
|
498
|
-
getPreviousFocusableElement(currentElement, container)
|
|
526
|
+
getPreviousFocusableElement(currentElement: HTMLElement, container: HTMLElement): HTMLElement | null {
|
|
527
|
+
const focusableElements = this.getFocusableElements(container);
|
|
499
528
|
const currentIndex = focusableElements.indexOf(currentElement);
|
|
500
529
|
|
|
501
530
|
if (currentIndex === -1 || currentIndex === 0) {
|