@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,16 +1,16 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useCallback } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface FocusManagerProps {
|
|
4
|
-
children;
|
|
5
|
-
isActive;
|
|
6
|
-
onFocusChange
|
|
7
|
-
trapFocus
|
|
8
|
-
restoreFocus
|
|
9
|
-
initialFocus
|
|
10
|
-
className
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
isActive: boolean;
|
|
6
|
+
onFocusChange?: (focused: boolean) => void;
|
|
7
|
+
trapFocus?: boolean;
|
|
8
|
+
restoreFocus?: boolean;
|
|
9
|
+
initialFocus?: React.RefObject<HTMLElement>;
|
|
10
|
+
className?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export const FocusManager= ({
|
|
13
|
+
export const FocusManager: React.FC<FocusManagerProps> = ({
|
|
14
14
|
children,
|
|
15
15
|
isActive,
|
|
16
16
|
onFocusChange,
|
|
@@ -28,12 +28,12 @@ export const FocusManager= ({
|
|
|
28
28
|
if (!containerRef.current) return [];
|
|
29
29
|
|
|
30
30
|
const selector = [
|
|
31
|
-
'button])',
|
|
32
|
-
'input])',
|
|
33
|
-
'select])',
|
|
34
|
-
'textarea])',
|
|
31
|
+
'button:not([disabled])',
|
|
32
|
+
'input:not([disabled])',
|
|
33
|
+
'select:not([disabled])',
|
|
34
|
+
'textarea:not([disabled])',
|
|
35
35
|
'a[href]',
|
|
36
|
-
'[tabindex]="-1"])',
|
|
36
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
37
37
|
'[contenteditable="true"]'
|
|
38
38
|
].join(', ');
|
|
39
39
|
|
|
@@ -82,7 +82,7 @@ export const FocusManager= ({
|
|
|
82
82
|
}, [isActive, restoreFocus, onFocusChange]);
|
|
83
83
|
|
|
84
84
|
// Handle keyboard navigation for focus trapping
|
|
85
|
-
const handleKeyDown = useCallback((event) => {
|
|
85
|
+
const handleKeyDown = useCallback((event: KeyboardEvent) => {
|
|
86
86
|
if (!isActive || !trapFocus || focusableElements.current.length === 0) return;
|
|
87
87
|
|
|
88
88
|
const { key, shiftKey } = event;
|
|
@@ -94,16 +94,18 @@ export const FocusManager= ({
|
|
|
94
94
|
el => el === document.activeElement
|
|
95
95
|
);
|
|
96
96
|
|
|
97
|
-
let nextIndex;
|
|
97
|
+
let nextIndex: number;
|
|
98
98
|
|
|
99
99
|
if (shiftKey) {
|
|
100
|
-
// Shift + Tab
|
|
100
|
+
// Shift + Tab: move backward
|
|
101
|
+
nextIndex = currentIndex <= 0
|
|
101
102
|
? focusableElements.current.length - 1
|
|
102
|
-
;
|
|
103
|
+
: currentIndex - 1;
|
|
103
104
|
} else {
|
|
104
|
-
// Tab
|
|
105
|
+
// Tab: move forward
|
|
106
|
+
nextIndex = currentIndex >= focusableElements.current.length - 1
|
|
105
107
|
? 0
|
|
106
|
-
;
|
|
108
|
+
: currentIndex + 1;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
focusableElements.current[nextIndex]?.focus();
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useCallback } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface FocusManagerProps {
|
|
4
|
-
children;
|
|
5
|
-
isActive;
|
|
6
|
-
onFocusChange
|
|
7
|
-
trapFocus
|
|
8
|
-
restoreFocus
|
|
9
|
-
initialFocus
|
|
10
|
-
className
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
isActive: boolean;
|
|
6
|
+
onFocusChange?: (focused: boolean) => void;
|
|
7
|
+
trapFocus?: boolean;
|
|
8
|
+
restoreFocus?: boolean;
|
|
9
|
+
initialFocus?: React.RefObject<HTMLElement>;
|
|
10
|
+
className?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export const FocusManager= ({
|
|
13
|
+
export const FocusManager: React.FC<FocusManagerProps> = ({
|
|
14
14
|
children,
|
|
15
15
|
isActive,
|
|
16
16
|
onFocusChange,
|
|
@@ -28,12 +28,12 @@ export const FocusManager= ({
|
|
|
28
28
|
if (!containerRef.current) return [];
|
|
29
29
|
|
|
30
30
|
const selector = [
|
|
31
|
-
'button])',
|
|
32
|
-
'input])',
|
|
33
|
-
'select])',
|
|
34
|
-
'textarea])',
|
|
31
|
+
'button:not([disabled])',
|
|
32
|
+
'input:not([disabled])',
|
|
33
|
+
'select:not([disabled])',
|
|
34
|
+
'textarea:not([disabled])',
|
|
35
35
|
'a[href]',
|
|
36
|
-
'[tabindex]="-1"])',
|
|
36
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
37
37
|
'[contenteditable="true"]'
|
|
38
38
|
].join(', ');
|
|
39
39
|
|
|
@@ -82,7 +82,7 @@ export const FocusManager= ({
|
|
|
82
82
|
}, [isActive, restoreFocus, onFocusChange]);
|
|
83
83
|
|
|
84
84
|
// Handle keyboard navigation for focus trapping
|
|
85
|
-
const handleKeyDown = useCallback((event) => {
|
|
85
|
+
const handleKeyDown = useCallback((event: KeyboardEvent) => {
|
|
86
86
|
if (!isActive || !trapFocus || focusableElements.current.length === 0) return;
|
|
87
87
|
|
|
88
88
|
const { key, shiftKey } = event;
|
|
@@ -94,16 +94,18 @@ export const FocusManager= ({
|
|
|
94
94
|
el => el === document.activeElement
|
|
95
95
|
);
|
|
96
96
|
|
|
97
|
-
let nextIndex;
|
|
97
|
+
let nextIndex: number;
|
|
98
98
|
|
|
99
99
|
if (shiftKey) {
|
|
100
|
-
// Shift + Tab
|
|
100
|
+
// Shift + Tab: move backward
|
|
101
|
+
nextIndex = currentIndex <= 0
|
|
101
102
|
? focusableElements.current.length - 1
|
|
102
|
-
;
|
|
103
|
+
: currentIndex - 1;
|
|
103
104
|
} else {
|
|
104
|
-
// Tab
|
|
105
|
+
// Tab: move forward
|
|
106
|
+
nextIndex = currentIndex >= focusableElements.current.length - 1
|
|
105
107
|
? 0
|
|
106
|
-
;
|
|
108
|
+
: currentIndex + 1;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
focusableElements.current[nextIndex]?.focus();
|
|
@@ -7,7 +7,7 @@ import { useOverlayManager } from './overlay-manager';
|
|
|
7
7
|
import { ModalProps, ModalHeaderProps, ModalBodyProps, ModalFooterProps } from './types';
|
|
8
8
|
|
|
9
9
|
// SVG Icons
|
|
10
|
-
const XMarkIcon}> = ({ className = 'w-6 h-6' }) => (
|
|
10
|
+
const XMarkIcon: React.FC<{ className?: string }> = ({ className = 'w-6 h-6' }) => (
|
|
11
11
|
<svg className={className} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
|
|
12
12
|
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
13
13
|
</svg>
|
|
@@ -15,15 +15,15 @@ const XMarkIcon}> = ({ className = 'w-6 h-6' }) => (
|
|
|
15
15
|
|
|
16
16
|
// Default color fallbacks
|
|
17
17
|
const getDefaultColors = () => ({
|
|
18
|
-
surface, surface, border, divider},
|
|
19
|
-
text, secondary, muted, inverse},
|
|
20
|
-
interactive, active, focus, disabled},
|
|
21
|
-
primary, 600},
|
|
22
|
-
semantic, warning, error, info}
|
|
18
|
+
surface: { background: '#ffffff', surface: '#f9fafb', border: '#e5e7eb', divider: '#e5e7eb' },
|
|
19
|
+
text: { primary: '#111827', secondary: '#6b7280', muted: '#9ca3af', inverse: '#ffffff' },
|
|
20
|
+
interactive: { hover: '#f3f4f6', active: '#e5e7eb', focus: '#3b82f6', disabled: '#d1d5db' },
|
|
21
|
+
primary: { 500: '#3b82f6', 600: '#2563eb' },
|
|
22
|
+
semantic: { success: '#10b981', warning: '#f59e0b', error: '#ef4444', info: '#3b82f6' }
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// Modal Header Component
|
|
26
|
-
export const ModalHeader= ({
|
|
26
|
+
export const ModalHeader: React.FC<ModalHeaderProps> = ({
|
|
27
27
|
title,
|
|
28
28
|
subtitle,
|
|
29
29
|
onClose,
|
|
@@ -36,8 +36,8 @@ export const ModalHeader= ({
|
|
|
36
36
|
}) => {
|
|
37
37
|
const headerClasses = [
|
|
38
38
|
'modal__header',
|
|
39
|
-
borderless ? 'modal__header--borderless' ,
|
|
40
|
-
noPadding ? 'modal__header--no-padding' ,
|
|
39
|
+
borderless ? 'modal__header--borderless' : '',
|
|
40
|
+
noPadding ? 'modal__header--no-padding' : '',
|
|
41
41
|
className
|
|
42
42
|
].filter(Boolean).join(' ');
|
|
43
43
|
|
|
@@ -72,7 +72,7 @@ export const ModalHeader= ({
|
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
// Modal Body Component
|
|
75
|
-
export const ModalBody= ({
|
|
75
|
+
export const ModalBody: React.FC<ModalBodyProps> = ({
|
|
76
76
|
children,
|
|
77
77
|
className = '',
|
|
78
78
|
padding = 'md',
|
|
@@ -81,17 +81,17 @@ export const ModalBody= ({
|
|
|
81
81
|
}) => {
|
|
82
82
|
const bodyClasses = [
|
|
83
83
|
'modal__body',
|
|
84
|
-
padding === 'none' ? 'modal__body--no-padding' ,
|
|
85
|
-
padding === 'sm' ? 'modal__body--compact' ,
|
|
86
|
-
padding === 'lg' ? 'modal__body--spacious' ,
|
|
87
|
-
scrollable ? 'modal__body--scrollable' ,
|
|
84
|
+
padding === 'none' ? 'modal__body--no-padding' : '',
|
|
85
|
+
padding === 'sm' ? 'modal__body--compact' : '',
|
|
86
|
+
padding === 'lg' ? 'modal__body--spacious' : '',
|
|
87
|
+
scrollable ? 'modal__body--scrollable' : '',
|
|
88
88
|
className
|
|
89
89
|
].filter(Boolean).join(' ');
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
92
|
<div
|
|
93
93
|
className={bodyClasses}
|
|
94
|
-
style={{ maxHeight}}
|
|
94
|
+
style={{ maxHeight: scrollable ? maxHeight : undefined }}
|
|
95
95
|
>
|
|
96
96
|
{children}
|
|
97
97
|
</div>
|
|
@@ -99,7 +99,7 @@ export const ModalBody= ({
|
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
// Modal Footer Component
|
|
102
|
-
export const ModalFooter= ({
|
|
102
|
+
export const ModalFooter: React.FC<ModalFooterProps> = ({
|
|
103
103
|
children,
|
|
104
104
|
className = '',
|
|
105
105
|
justify = 'end',
|
|
@@ -108,11 +108,11 @@ export const ModalFooter= ({
|
|
|
108
108
|
}) => {
|
|
109
109
|
const footerClasses = [
|
|
110
110
|
'modal__footer',
|
|
111
|
-
!borderTop ? 'modal__footer--borderless' ,
|
|
112
|
-
padding === 'none' ? 'modal__footer--no-padding' ,
|
|
113
|
-
justify === 'start' ? 'modal__footer--start' ,
|
|
114
|
-
justify === 'center' ? 'modal__footer--center' ,
|
|
115
|
-
justify === 'between' ? 'modal__footer--space-between' ,
|
|
111
|
+
!borderTop ? 'modal__footer--borderless' : '',
|
|
112
|
+
padding === 'none' ? 'modal__footer--no-padding' : '',
|
|
113
|
+
justify === 'start' ? 'modal__footer--start' : '',
|
|
114
|
+
justify === 'center' ? 'modal__footer--center' : '',
|
|
115
|
+
justify === 'between' ? 'modal__footer--space-between' : '',
|
|
116
116
|
className
|
|
117
117
|
].filter(Boolean).join(' ');
|
|
118
118
|
|
|
@@ -124,7 +124,7 @@ export const ModalFooter= ({
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
// Main Modal Component
|
|
127
|
-
export const Modal= ({
|
|
127
|
+
export const Modal: React.FC<ModalProps> = ({
|
|
128
128
|
isOpen,
|
|
129
129
|
onClose,
|
|
130
130
|
title,
|
|
@@ -157,9 +157,9 @@ export const Modal= ({
|
|
|
157
157
|
const getContainerClasses = () => {
|
|
158
158
|
const classes = [
|
|
159
159
|
'modal__container',
|
|
160
|
-
size ? `modal__container--size-${size}` ,
|
|
161
|
-
variant ? `modal__container--variant-${variant}` ,
|
|
162
|
-
loading ? 'modal__container--loading' ,
|
|
160
|
+
size ? `modal__container--size-${size}` : '',
|
|
161
|
+
variant ? `modal__container--variant-${variant}` : '',
|
|
162
|
+
loading ? 'modal__container--loading' : '',
|
|
163
163
|
className
|
|
164
164
|
];
|
|
165
165
|
|
|
@@ -175,7 +175,7 @@ export const Modal= ({
|
|
|
175
175
|
useEffect(() => {
|
|
176
176
|
if (!isOpen || !closeOnEscape) return;
|
|
177
177
|
|
|
178
|
-
const handleEscape = (event) => {
|
|
178
|
+
const handleEscape = (event: KeyboardEvent) => {
|
|
179
179
|
if (event.key === 'Escape') {
|
|
180
180
|
onClose();
|
|
181
181
|
}
|
|
@@ -208,11 +208,11 @@ export const Modal= ({
|
|
|
208
208
|
return null;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
const modalStyle= {
|
|
212
|
-
backgroundColor,
|
|
213
|
-
borderColor,
|
|
214
|
-
color,
|
|
215
|
-
zIndex)
|
|
211
|
+
const modalStyle: React.CSSProperties = {
|
|
212
|
+
backgroundColor: colors.surface.background,
|
|
213
|
+
borderColor: colors.surface.border,
|
|
214
|
+
color: colors.text.primary,
|
|
215
|
+
zIndex: zIndex || getTopZIndex()
|
|
216
216
|
};
|
|
217
217
|
|
|
218
218
|
return (
|
|
@@ -227,7 +227,7 @@ export const Modal= ({
|
|
|
227
227
|
/>
|
|
228
228
|
)}
|
|
229
229
|
|
|
230
|
-
<div className="modal__overlay" style={{ zIndex) }}>
|
|
230
|
+
<div className="modal__overlay" style={{ zIndex: zIndex || getTopZIndex() }}>
|
|
231
231
|
<FocusManager
|
|
232
232
|
isActive={isOpen}
|
|
233
233
|
trapFocus={trapFocus}
|
|
@@ -238,7 +238,7 @@ export const Modal= ({
|
|
|
238
238
|
ref={modalRef}
|
|
239
239
|
role="dialog"
|
|
240
240
|
aria-modal="true"
|
|
241
|
-
aria-labelledby={title ? `${modalId}-title` }
|
|
241
|
+
aria-labelledby={title ? `${modalId}-title` : undefined}
|
|
242
242
|
className={getContainerClasses()}
|
|
243
243
|
style={modalStyle}
|
|
244
244
|
onClick={(e) => e.stopPropagation()}
|
|
@@ -246,7 +246,11 @@ export const Modal= ({
|
|
|
246
246
|
{/* Render children or default layout */}
|
|
247
247
|
{React.Children.count(children) > 0 ? (
|
|
248
248
|
children
|
|
249
|
-
)
|
|
249
|
+
) : (
|
|
250
|
+
<>
|
|
251
|
+
{title && (
|
|
252
|
+
<ModalHeader
|
|
253
|
+
title={title}
|
|
250
254
|
onClose={onClose}
|
|
251
255
|
/>
|
|
252
256
|
)}
|
|
@@ -7,7 +7,7 @@ import { useOverlayManager } from './overlay-manager';
|
|
|
7
7
|
import { ModalProps, ModalHeaderProps, ModalBodyProps, ModalFooterProps } from './types';
|
|
8
8
|
|
|
9
9
|
// SVG Icons
|
|
10
|
-
const XMarkIcon}> = ({ className = 'w-6 h-6' }) => (
|
|
10
|
+
const XMarkIcon: React.FC<{ className?: string }> = ({ className = 'w-6 h-6' }) => (
|
|
11
11
|
<svg className={className} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
|
|
12
12
|
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
13
13
|
</svg>
|
|
@@ -15,15 +15,15 @@ const XMarkIcon}> = ({ className = 'w-6 h-6' }) => (
|
|
|
15
15
|
|
|
16
16
|
// Default color fallbacks
|
|
17
17
|
const getDefaultColors = () => ({
|
|
18
|
-
surface, surface, border, divider},
|
|
19
|
-
text, secondary, muted, inverse},
|
|
20
|
-
interactive, active, focus, disabled},
|
|
21
|
-
primary, 600},
|
|
22
|
-
semantic, warning, error, info}
|
|
18
|
+
surface: { background: '#ffffff', surface: '#f9fafb', border: '#e5e7eb', divider: '#e5e7eb' },
|
|
19
|
+
text: { primary: '#111827', secondary: '#6b7280', muted: '#9ca3af', inverse: '#ffffff' },
|
|
20
|
+
interactive: { hover: '#f3f4f6', active: '#e5e7eb', focus: '#3b82f6', disabled: '#d1d5db' },
|
|
21
|
+
primary: { 500: '#3b82f6', 600: '#2563eb' },
|
|
22
|
+
semantic: { success: '#10b981', warning: '#f59e0b', error: '#ef4444', info: '#3b82f6' }
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// Modal Header Component
|
|
26
|
-
export const ModalHeader= ({
|
|
26
|
+
export const ModalHeader: React.FC<ModalHeaderProps> = ({
|
|
27
27
|
title,
|
|
28
28
|
subtitle,
|
|
29
29
|
onClose,
|
|
@@ -36,8 +36,8 @@ export const ModalHeader= ({
|
|
|
36
36
|
}) => {
|
|
37
37
|
const headerClasses = [
|
|
38
38
|
'modal__header',
|
|
39
|
-
borderless ? 'modal__header--borderless' ,
|
|
40
|
-
noPadding ? 'modal__header--no-padding' ,
|
|
39
|
+
borderless ? 'modal__header--borderless' : '',
|
|
40
|
+
noPadding ? 'modal__header--no-padding' : '',
|
|
41
41
|
className
|
|
42
42
|
].filter(Boolean).join(' ');
|
|
43
43
|
|
|
@@ -72,7 +72,7 @@ export const ModalHeader= ({
|
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
// Modal Body Component
|
|
75
|
-
export const ModalBody= ({
|
|
75
|
+
export const ModalBody: React.FC<ModalBodyProps> = ({
|
|
76
76
|
children,
|
|
77
77
|
className = '',
|
|
78
78
|
padding = 'md',
|
|
@@ -81,17 +81,17 @@ export const ModalBody= ({
|
|
|
81
81
|
}) => {
|
|
82
82
|
const bodyClasses = [
|
|
83
83
|
'modal__body',
|
|
84
|
-
padding === 'none' ? 'modal__body--no-padding' ,
|
|
85
|
-
padding === 'sm' ? 'modal__body--compact' ,
|
|
86
|
-
padding === 'lg' ? 'modal__body--spacious' ,
|
|
87
|
-
scrollable ? 'modal__body--scrollable' ,
|
|
84
|
+
padding === 'none' ? 'modal__body--no-padding' : '',
|
|
85
|
+
padding === 'sm' ? 'modal__body--compact' : '',
|
|
86
|
+
padding === 'lg' ? 'modal__body--spacious' : '',
|
|
87
|
+
scrollable ? 'modal__body--scrollable' : '',
|
|
88
88
|
className
|
|
89
89
|
].filter(Boolean).join(' ');
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
92
|
<div
|
|
93
93
|
className={bodyClasses}
|
|
94
|
-
style={{ maxHeight}}
|
|
94
|
+
style={{ maxHeight: scrollable ? maxHeight : undefined }}
|
|
95
95
|
>
|
|
96
96
|
{children}
|
|
97
97
|
</div>
|
|
@@ -99,7 +99,7 @@ export const ModalBody= ({
|
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
// Modal Footer Component
|
|
102
|
-
export const ModalFooter= ({
|
|
102
|
+
export const ModalFooter: React.FC<ModalFooterProps> = ({
|
|
103
103
|
children,
|
|
104
104
|
className = '',
|
|
105
105
|
justify = 'end',
|
|
@@ -108,11 +108,11 @@ export const ModalFooter= ({
|
|
|
108
108
|
}) => {
|
|
109
109
|
const footerClasses = [
|
|
110
110
|
'modal__footer',
|
|
111
|
-
!borderTop ? 'modal__footer--borderless' ,
|
|
112
|
-
padding === 'none' ? 'modal__footer--no-padding' ,
|
|
113
|
-
justify === 'start' ? 'modal__footer--start' ,
|
|
114
|
-
justify === 'center' ? 'modal__footer--center' ,
|
|
115
|
-
justify === 'between' ? 'modal__footer--space-between' ,
|
|
111
|
+
!borderTop ? 'modal__footer--borderless' : '',
|
|
112
|
+
padding === 'none' ? 'modal__footer--no-padding' : '',
|
|
113
|
+
justify === 'start' ? 'modal__footer--start' : '',
|
|
114
|
+
justify === 'center' ? 'modal__footer--center' : '',
|
|
115
|
+
justify === 'between' ? 'modal__footer--space-between' : '',
|
|
116
116
|
className
|
|
117
117
|
].filter(Boolean).join(' ');
|
|
118
118
|
|
|
@@ -124,7 +124,7 @@ export const ModalFooter= ({
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
// Main Modal Component
|
|
127
|
-
export const Modal= ({
|
|
127
|
+
export const Modal: React.FC<ModalProps> = ({
|
|
128
128
|
isOpen,
|
|
129
129
|
onClose,
|
|
130
130
|
title,
|
|
@@ -157,9 +157,9 @@ export const Modal= ({
|
|
|
157
157
|
const getContainerClasses = () => {
|
|
158
158
|
const classes = [
|
|
159
159
|
'modal__container',
|
|
160
|
-
size ? `modal__container--size-${size}` ,
|
|
161
|
-
variant ? `modal__container--variant-${variant}` ,
|
|
162
|
-
loading ? 'modal__container--loading' ,
|
|
160
|
+
size ? `modal__container--size-${size}` : '',
|
|
161
|
+
variant ? `modal__container--variant-${variant}` : '',
|
|
162
|
+
loading ? 'modal__container--loading' : '',
|
|
163
163
|
className
|
|
164
164
|
];
|
|
165
165
|
|
|
@@ -175,7 +175,7 @@ export const Modal= ({
|
|
|
175
175
|
useEffect(() => {
|
|
176
176
|
if (!isOpen || !closeOnEscape) return;
|
|
177
177
|
|
|
178
|
-
const handleEscape = (event) => {
|
|
178
|
+
const handleEscape = (event: KeyboardEvent) => {
|
|
179
179
|
if (event.key === 'Escape') {
|
|
180
180
|
onClose();
|
|
181
181
|
}
|
|
@@ -208,11 +208,11 @@ export const Modal= ({
|
|
|
208
208
|
return null;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
const modalStyle= {
|
|
212
|
-
backgroundColor,
|
|
213
|
-
borderColor,
|
|
214
|
-
color,
|
|
215
|
-
zIndex)
|
|
211
|
+
const modalStyle: React.CSSProperties = {
|
|
212
|
+
backgroundColor: colors.surface.background,
|
|
213
|
+
borderColor: colors.surface.border,
|
|
214
|
+
color: colors.text.primary,
|
|
215
|
+
zIndex: zIndex || getTopZIndex()
|
|
216
216
|
};
|
|
217
217
|
|
|
218
218
|
return (
|
|
@@ -227,7 +227,7 @@ export const Modal= ({
|
|
|
227
227
|
/>
|
|
228
228
|
)}
|
|
229
229
|
|
|
230
|
-
<div className="modal__overlay" style={{ zIndex) }}>
|
|
230
|
+
<div className="modal__overlay" style={{ zIndex: zIndex || getTopZIndex() }}>
|
|
231
231
|
<FocusManager
|
|
232
232
|
isActive={isOpen}
|
|
233
233
|
trapFocus={trapFocus}
|
|
@@ -238,7 +238,7 @@ export const Modal= ({
|
|
|
238
238
|
ref={modalRef}
|
|
239
239
|
role="dialog"
|
|
240
240
|
aria-modal="true"
|
|
241
|
-
aria-labelledby={title ? `${modalId}-title` }
|
|
241
|
+
aria-labelledby={title ? `${modalId}-title` : undefined}
|
|
242
242
|
className={getContainerClasses()}
|
|
243
243
|
style={modalStyle}
|
|
244
244
|
onClick={(e) => e.stopPropagation()}
|
|
@@ -246,7 +246,11 @@ export const Modal= ({
|
|
|
246
246
|
{/* Render children or default layout */}
|
|
247
247
|
{React.Children.count(children) > 0 ? (
|
|
248
248
|
children
|
|
249
|
-
)
|
|
249
|
+
) : (
|
|
250
|
+
<>
|
|
251
|
+
{title && (
|
|
252
|
+
<ModalHeader
|
|
253
|
+
title={title}
|
|
250
254
|
onClose={onClose}
|
|
251
255
|
/>
|
|
252
256
|
)}
|
|
@@ -3,11 +3,11 @@ import { OverlayManagerProps, OverlayState, OverlayAction } from './types';
|
|
|
3
3
|
|
|
4
4
|
// Overlay context for managing global overlay state
|
|
5
5
|
interface OverlayContextType {
|
|
6
|
-
overlays];
|
|
7
|
-
addOverlay, zIndex) => void;
|
|
8
|
-
removeOverlay) => void;
|
|
9
|
-
getTopZIndex) => number;
|
|
10
|
-
isOverlayActive) => boolean;
|
|
6
|
+
overlays: OverlayState[];
|
|
7
|
+
addOverlay: (id: string, zIndex: number) => void;
|
|
8
|
+
removeOverlay: (id: string) => void;
|
|
9
|
+
getTopZIndex: () => number;
|
|
10
|
+
isOverlayActive: (id: string) => boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const OverlayContext = createContext<OverlayContextType | undefined>(undefined);
|
|
@@ -22,31 +22,36 @@ export const useOverlayManager = () => {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
// Overlay reducer for state management
|
|
25
|
-
const overlayReducer = (state], action)] => {
|
|
25
|
+
const overlayReducer = (state: OverlayState[], action: OverlayAction): OverlayState[] => {
|
|
26
26
|
switch (action.type) {
|
|
27
|
-
case 'ADD_OVERLAY'
|
|
27
|
+
case 'ADD_OVERLAY':
|
|
28
|
+
return [...state, { id: action.payload.id, zIndex: action.payload.zIndex || 1000 }];
|
|
28
29
|
|
|
29
|
-
case 'REMOVE_OVERLAY'
|
|
30
|
+
case 'REMOVE_OVERLAY':
|
|
31
|
+
return state.filter(overlay => overlay.id !== action.payload.id);
|
|
30
32
|
|
|
31
|
-
case 'UPDATE_Z_INDEX'
|
|
33
|
+
case 'UPDATE_Z_INDEX':
|
|
34
|
+
return state.map(overlay =>
|
|
32
35
|
overlay.id === action.payload.id
|
|
33
|
-
? { ...overlay, zIndex}
|
|
34
|
-
|
|
36
|
+
? { ...overlay, zIndex: action.payload.zIndex || overlay.zIndex }
|
|
37
|
+
: overlay
|
|
38
|
+
);
|
|
35
39
|
|
|
36
|
-
default
|
|
40
|
+
default:
|
|
41
|
+
return state;
|
|
37
42
|
}
|
|
38
43
|
};
|
|
39
44
|
|
|
40
45
|
// Overlay provider component
|
|
41
|
-
export const OverlayProvider}> = ({ children }) => {
|
|
46
|
+
export const OverlayProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
|
42
47
|
const [overlays, dispatch] = useReducer(overlayReducer, []);
|
|
43
48
|
|
|
44
|
-
const addOverlay = useCallback((id, zIndex) => {
|
|
45
|
-
dispatch({ type, payload, zIndex } });
|
|
49
|
+
const addOverlay = useCallback((id: string, zIndex: number) => {
|
|
50
|
+
dispatch({ type: 'ADD_OVERLAY', payload: { id, zIndex } });
|
|
46
51
|
}, []);
|
|
47
52
|
|
|
48
|
-
const removeOverlay = useCallback((id) => {
|
|
49
|
-
dispatch({ type, payload} });
|
|
53
|
+
const removeOverlay = useCallback((id: string) => {
|
|
54
|
+
dispatch({ type: 'REMOVE_OVERLAY', payload: { id } });
|
|
50
55
|
}, []);
|
|
51
56
|
|
|
52
57
|
const getTopZIndex = useCallback(() => {
|
|
@@ -54,11 +59,11 @@ export const OverlayProvider}> = ({ children }) => {
|
|
|
54
59
|
return Math.max(...overlays.map(o => o.zIndex)) + 1;
|
|
55
60
|
}, [overlays]);
|
|
56
61
|
|
|
57
|
-
const isOverlayActive = useCallback((id) => {
|
|
62
|
+
const isOverlayActive = useCallback((id: string) => {
|
|
58
63
|
return overlays.some(overlay => overlay.id === id);
|
|
59
64
|
}, [overlays]);
|
|
60
65
|
|
|
61
|
-
const value= {
|
|
66
|
+
const value: OverlayContextType = {
|
|
62
67
|
overlays,
|
|
63
68
|
addOverlay,
|
|
64
69
|
removeOverlay,
|
|
@@ -74,7 +79,7 @@ export const OverlayProvider}> = ({ children }) => {
|
|
|
74
79
|
};
|
|
75
80
|
|
|
76
81
|
// Overlay manager component for direct usage
|
|
77
|
-
export const OverlayManager= ({
|
|
82
|
+
export const OverlayManager: React.FC<OverlayManagerProps> = ({
|
|
78
83
|
children,
|
|
79
84
|
maxOverlays = 10,
|
|
80
85
|
onOverlayChange
|