@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
|
@@ -5,42 +5,45 @@ import { Button } from './button'
|
|
|
5
5
|
import { Card, CardContent } from './card'
|
|
6
6
|
import { useTouchFriendlyInterface } from '../../hooks/use-touch-friendly-interface'
|
|
7
7
|
|
|
8
|
-
export const TouchFriendlyInterfaceDemo= () => {
|
|
8
|
+
export const TouchFriendlyInterfaceDemo: React.FC = () => {
|
|
9
9
|
const [activeDemo, setActiveDemo] = useState<'targets' | 'interactions' | 'performance' | 'accessibility'>('targets')
|
|
10
10
|
const [formData, setFormData] = useState({
|
|
11
|
-
name,
|
|
12
|
-
email,
|
|
13
|
-
message
|
|
11
|
+
name: '',
|
|
12
|
+
email: '',
|
|
13
|
+
message: ''
|
|
14
|
+
})
|
|
14
15
|
const [toggleState, setToggleState] = useState(false)
|
|
15
16
|
const [sliderValue, setSliderValue] = useState(50)
|
|
16
17
|
|
|
17
18
|
const { touchTargetState, touchInteractionState, isOptimizing, optimizations } = useTouchFriendlyInterface({
|
|
18
|
-
minSize,
|
|
19
|
-
spacing,
|
|
20
|
-
feedback,
|
|
21
|
-
performance,
|
|
22
|
-
accessibility
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
minSize: 44,
|
|
20
|
+
spacing: 'default',
|
|
21
|
+
feedback: 'scale',
|
|
22
|
+
performance: true,
|
|
23
|
+
accessibility: true
|
|
24
|
+
}, {
|
|
25
|
+
onTouchTargetOptimized: (config) => {
|
|
26
|
+
console.log('Touch target optimized:', config)
|
|
25
27
|
},
|
|
26
|
-
onTouchInteractionDetected) => {
|
|
27
|
-
console.log('Touch interaction detected, interaction)
|
|
28
|
+
onTouchInteractionDetected: (interaction) => {
|
|
29
|
+
console.log('Touch interaction detected:', interaction)
|
|
28
30
|
},
|
|
29
|
-
onPerformanceOptimized) => {
|
|
30
|
-
console.log('Performance optimized, score)
|
|
31
|
+
onPerformanceOptimized: (score) => {
|
|
32
|
+
console.log('Performance optimized:', score)
|
|
31
33
|
},
|
|
32
|
-
onAccessibilityEnhanced) => {
|
|
33
|
-
console.log('Accessibility enhanced, feature)
|
|
34
|
+
onAccessibilityEnhanced: (feature) => {
|
|
35
|
+
console.log('Accessibility enhanced:', feature)
|
|
34
36
|
}
|
|
35
37
|
})
|
|
36
38
|
|
|
37
|
-
const handleInputChange = (field, value) => {
|
|
38
|
-
setFormData(prev => ({ ...prev, [field]}))
|
|
39
|
+
const handleInputChange = (field: string, value: string) => {
|
|
40
|
+
setFormData(prev => ({ ...prev, [field]: value }))
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
const renderTargetComplianceDemo = () => (
|
|
42
44
|
<div className="space-y-6">
|
|
43
|
-
<div className="grid grid-cols-1 md
|
|
45
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
46
|
+
<div className="space-y-4">
|
|
44
47
|
<h3 className="text-lg font-semibold text-cs-text-primary">44px Target Compliance</h3>
|
|
45
48
|
|
|
46
49
|
<div className="space-y-3">
|
|
@@ -52,10 +55,12 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
52
55
|
Default Button (48px)
|
|
53
56
|
</Button>
|
|
54
57
|
|
|
55
|
-
<Button size="lg" variant="outline" className="touch-target touch-interaction touch-performance min-h-[56px] min-w-[56px] bg-transparent border border-cs-border text-cs-text-primary hover
|
|
58
|
+
<Button size="lg" variant="outline" className="touch-target touch-interaction touch-performance min-h-[56px] min-w-[56px] bg-transparent border border-cs-border text-cs-text-primary hover:bg-cs-hover-bg">
|
|
59
|
+
Large Button (56px)
|
|
56
60
|
</Button>
|
|
57
61
|
|
|
58
|
-
<Button size="lg" variant="ghost" className="touch-target touch-interaction touch-performance min-h-[64px] min-w-[64px] bg-transparent text-cs-text-primary hover
|
|
62
|
+
<Button size="lg" variant="ghost" className="touch-target touch-interaction touch-performance min-h-[64px] min-w-[64px] bg-transparent text-cs-text-primary hover:bg-cs-hover-bg">
|
|
63
|
+
Extra Large Button (64px)
|
|
59
64
|
</Button>
|
|
60
65
|
</div>
|
|
61
66
|
</div>
|
|
@@ -88,7 +93,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
88
93
|
</div>
|
|
89
94
|
</div>
|
|
90
95
|
|
|
91
|
-
<div className="grid grid-cols-1 md
|
|
96
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
97
|
+
<div className="space-y-4">
|
|
92
98
|
<h3 className="text-lg font-semibold text-cs-text-primary">Interactive Cards</h3>
|
|
93
99
|
|
|
94
100
|
<div className="space-y-3">
|
|
@@ -125,14 +131,15 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
125
131
|
role="switch"
|
|
126
132
|
aria-checked={toggleState}
|
|
127
133
|
onClick={() => setToggleState(!toggleState)}
|
|
128
|
-
className="touch-target touch-interaction touch-performance touch-feedback relative inline-flex items-center justify-center rounded-full transition-colors min-h-[48px] min-w-[48px] focus
|
|
129
|
-
|
|
134
|
+
className="touch-target touch-interaction touch-performance touch-feedback relative inline-flex items-center justify-center rounded-full transition-colors min-h-[48px] min-w-[48px] focus:outline-none focus:ring-2 focus:ring-cs-primary focus:ring-offset-2"
|
|
135
|
+
style={{
|
|
136
|
+
backgroundColor: toggleState ? 'var(--cs-primary)' : 'var(--cs-border)'
|
|
130
137
|
}}
|
|
131
138
|
>
|
|
132
139
|
<span
|
|
133
140
|
className="inline-block rounded-full bg-white shadow transform transition-transform w-6 h-6"
|
|
134
141
|
style={{
|
|
135
|
-
transform)' )'
|
|
142
|
+
transform: toggleState ? 'translateX(24px)' : 'translateX(0)'
|
|
136
143
|
}}
|
|
137
144
|
/>
|
|
138
145
|
</button>
|
|
@@ -140,7 +147,7 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
140
147
|
</div>
|
|
141
148
|
|
|
142
149
|
<div className="space-y-2">
|
|
143
|
-
<label className="text-sm font-medium">Slider Value}</label>
|
|
150
|
+
<label className="text-sm font-medium">Slider Value: {sliderValue}</label>
|
|
144
151
|
<input
|
|
145
152
|
type="range"
|
|
146
153
|
value={sliderValue}
|
|
@@ -148,7 +155,7 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
148
155
|
min={0}
|
|
149
156
|
max={100}
|
|
150
157
|
step={1}
|
|
151
|
-
className="touch-target touch-interaction touch-performance touch-feedback w-full h-2 bg-cs-border rounded-lg appearance-none cursor-pointer focus]"
|
|
158
|
+
className="touch-target touch-interaction touch-performance touch-feedback w-full h-2 bg-cs-border rounded-lg appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-cs-primary min-h-[48px]"
|
|
152
159
|
/>
|
|
153
160
|
</div>
|
|
154
161
|
</div>
|
|
@@ -159,25 +166,30 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
159
166
|
|
|
160
167
|
const renderTouchInteractionsDemo = () => (
|
|
161
168
|
<div className="space-y-6">
|
|
162
|
-
<div className="grid grid-cols-1 md
|
|
169
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
170
|
+
<div className="space-y-4">
|
|
163
171
|
<h3 className="text-lg font-semibold text-cs-text-primary">Touch State</h3>
|
|
164
172
|
|
|
165
173
|
<div className="space-y-3">
|
|
166
174
|
<div className="p-4 bg-cs-surface-bg rounded-lg border border-cs-border">
|
|
167
175
|
<div className="grid grid-cols-2 gap-4 text-sm">
|
|
168
176
|
<div>
|
|
169
|
-
<span className="font-medium">Touching
|
|
170
|
-
|
|
177
|
+
<span className="font-medium">Touching:</span>
|
|
178
|
+
<span className={`ml-2 ${touchInteractionState.isTouching ? 'text-cs-success' : 'text-cs-text-secondary'}`}>
|
|
179
|
+
{touchInteractionState.isTouching ? 'Yes' : 'No'}
|
|
171
180
|
</span>
|
|
172
181
|
</div>
|
|
173
182
|
<div>
|
|
174
|
-
<span className="font-medium">Touch Count
|
|
183
|
+
<span className="font-medium">Touch Count:</span>
|
|
184
|
+
<span className="ml-2 text-cs-text-primary">{touchInteractionState.touchCount}</span>
|
|
175
185
|
</div>
|
|
176
186
|
<div>
|
|
177
|
-
<span className="font-medium">Duration
|
|
187
|
+
<span className="font-medium">Duration:</span>
|
|
188
|
+
<span className="ml-2 text-cs-text-primary">{touchInteractionState.touchDuration.toFixed(0)}ms</span>
|
|
178
189
|
</div>
|
|
179
190
|
<div>
|
|
180
|
-
<span className="font-medium">Velocity
|
|
191
|
+
<span className="font-medium">Velocity:</span>
|
|
192
|
+
<span className="ml-2 text-cs-text-primary">{touchInteractionState.touchVelocity.toFixed(2)}px/ms</span>
|
|
181
193
|
</div>
|
|
182
194
|
</div>
|
|
183
195
|
</div>
|
|
@@ -191,13 +203,21 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
191
203
|
<div className="p-4 bg-cs-surface-bg rounded-lg border border-cs-border">
|
|
192
204
|
<div className="text-center">
|
|
193
205
|
<div className="text-2xl font-bold text-cs-primary mb-2">
|
|
194
|
-
{touchInteractionState.gestureType === 'none' ? '👆'
|
|
206
|
+
{touchInteractionState.gestureType === 'none' ? '👆' :
|
|
207
|
+
touchInteractionState.gestureType === 'tap' ? '👆' :
|
|
208
|
+
touchInteractionState.gestureType === 'double-tap' ? '👆👆' :
|
|
209
|
+
touchInteractionState.gestureType === 'long-press' ? '⏰' :
|
|
210
|
+
touchInteractionState.gestureType === 'swipe' ? '👈👉' : '🤏'}
|
|
195
211
|
</div>
|
|
196
212
|
<div className="text-lg font-semibold capitalize">
|
|
197
213
|
{touchInteractionState.gestureType.replace('-', ' ')}
|
|
198
214
|
</div>
|
|
199
215
|
<div className="text-sm text-cs-text-secondary">
|
|
200
|
-
{touchInteractionState.gestureType === 'none' ? 'Touch to detect gesture'
|
|
216
|
+
{touchInteractionState.gestureType === 'none' ? 'Touch to detect gesture' :
|
|
217
|
+
touchInteractionState.gestureType === 'tap' ? 'Quick touch detected' :
|
|
218
|
+
touchInteractionState.gestureType === 'double-tap' ? 'Double touch detected' :
|
|
219
|
+
touchInteractionState.gestureType === 'long-press' ? 'Long press detected' :
|
|
220
|
+
touchInteractionState.gestureType === 'swipe' ? 'Swipe gesture detected' : 'Pinch detected'}
|
|
201
221
|
</div>
|
|
202
222
|
</div>
|
|
203
223
|
</div>
|
|
@@ -208,19 +228,20 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
208
228
|
<div className="space-y-4">
|
|
209
229
|
<h3 className="text-lg font-semibold text-cs-text-primary">Touch Coordinates</h3>
|
|
210
230
|
|
|
211
|
-
<div className="grid grid-cols-1 md
|
|
231
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
232
|
+
<div className="p-4 bg-cs-surface-bg rounded-lg border border-cs-border">
|
|
212
233
|
<h4 className="font-medium mb-2">Start Position</h4>
|
|
213
234
|
<div className="text-sm space-y-1">
|
|
214
|
-
<div>X}px</div>
|
|
215
|
-
<div>Y}px</div>
|
|
235
|
+
<div>X: {touchInteractionState.touchStartX}px</div>
|
|
236
|
+
<div>Y: {touchInteractionState.touchStartY}px</div>
|
|
216
237
|
</div>
|
|
217
238
|
</div>
|
|
218
239
|
|
|
219
240
|
<div className="p-4 bg-cs-surface-bg rounded-lg border border-cs-border">
|
|
220
241
|
<h4 className="font-medium mb-2">Current Position</h4>
|
|
221
242
|
<div className="text-sm space-y-1">
|
|
222
|
-
<div>X}px</div>
|
|
223
|
-
<div>Y}px</div>
|
|
243
|
+
<div>X: {touchInteractionState.touchCurrentX}px</div>
|
|
244
|
+
<div>Y: {touchInteractionState.touchCurrentY}px</div>
|
|
224
245
|
</div>
|
|
225
246
|
</div>
|
|
226
247
|
</div>
|
|
@@ -230,7 +251,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
230
251
|
|
|
231
252
|
const renderPerformanceDemo = () => (
|
|
232
253
|
<div className="space-y-6">
|
|
233
|
-
<div className="grid grid-cols-1 md
|
|
254
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
255
|
+
<div className="space-y-4">
|
|
234
256
|
<h3 className="text-lg font-semibold text-cs-text-primary">Performance Metrics</h3>
|
|
235
257
|
|
|
236
258
|
<div className="space-y-3">
|
|
@@ -239,7 +261,9 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
239
261
|
<div className="flex justify-between items-center">
|
|
240
262
|
<span className="text-sm font-medium">Performance Score</span>
|
|
241
263
|
<span className={`text-lg font-bold ${
|
|
242
|
-
touchTargetState.performanceScore >= 80 ? 'text-cs-success'
|
|
264
|
+
touchTargetState.performanceScore >= 80 ? 'text-cs-success' :
|
|
265
|
+
touchTargetState.performanceScore >= 60 ? 'text-cs-warning' : 'text-cs-error'
|
|
266
|
+
}`}>
|
|
243
267
|
{touchTargetState.performanceScore}/100
|
|
244
268
|
</span>
|
|
245
269
|
</div>
|
|
@@ -247,13 +271,16 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
247
271
|
<div className="w-full bg-cs-border rounded-full h-2">
|
|
248
272
|
<div
|
|
249
273
|
className={`h-2 rounded-full transition-all duration-300 ${
|
|
250
|
-
touchTargetState.performanceScore >= 80 ? 'bg-cs-success'
|
|
251
|
-
|
|
274
|
+
touchTargetState.performanceScore >= 80 ? 'bg-cs-success' :
|
|
275
|
+
touchTargetState.performanceScore >= 60 ? 'bg-cs-warning' : 'bg-cs-error'
|
|
276
|
+
}`}
|
|
277
|
+
style={{ width: `${touchTargetState.performanceScore}%` }}
|
|
252
278
|
/>
|
|
253
279
|
</div>
|
|
254
280
|
|
|
255
281
|
<div className="text-xs text-cs-text-secondary">
|
|
256
|
-
{touchTargetState.performanceScore >= 80 ? 'Excellent performance'
|
|
282
|
+
{touchTargetState.performanceScore >= 80 ? 'Excellent performance' :
|
|
283
|
+
touchTargetState.performanceScore >= 60 ? 'Good performance' : 'Needs optimization'}
|
|
257
284
|
</div>
|
|
258
285
|
</div>
|
|
259
286
|
</div>
|
|
@@ -273,8 +300,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
273
300
|
|
|
274
301
|
<div className="flex justify-between items-center">
|
|
275
302
|
<span className="text-sm">Compliance</span>
|
|
276
|
-
<span className={`font-medium ${touchTargetState.size >= 44 ? 'text-cs-success' }`}>
|
|
277
|
-
{touchTargetState.size >= 44 ? '✅ Compliant' }
|
|
303
|
+
<span className={`font-medium ${touchTargetState.size >= 44 ? 'text-cs-success' : 'text-cs-error'}`}>
|
|
304
|
+
{touchTargetState.size >= 44 ? '✅ Compliant' : '❌ Non-compliant'}
|
|
278
305
|
</span>
|
|
279
306
|
</div>
|
|
280
307
|
|
|
@@ -302,7 +329,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
302
329
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-cs-primary mx-auto mb-2"></div>
|
|
303
330
|
<div className="text-sm text-cs-text-secondary">Optimizing touch targets...</div>
|
|
304
331
|
</div>
|
|
305
|
-
)
|
|
332
|
+
) : optimizations.length > 0 ? (
|
|
333
|
+
<div className="space-y-2">
|
|
306
334
|
{optimizations.map((optimization, index) => (
|
|
307
335
|
<div key={index} className="flex items-center space-x-2 text-sm">
|
|
308
336
|
<span className="text-cs-success">✅</span>
|
|
@@ -310,7 +338,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
310
338
|
</div>
|
|
311
339
|
))}
|
|
312
340
|
</div>
|
|
313
|
-
)
|
|
341
|
+
) : (
|
|
342
|
+
<div className="text-center py-4 text-cs-text-secondary">
|
|
314
343
|
No optimizations applied yet
|
|
315
344
|
</div>
|
|
316
345
|
)}
|
|
@@ -321,7 +350,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
321
350
|
|
|
322
351
|
const renderAccessibilityDemo = () => (
|
|
323
352
|
<div className="space-y-6">
|
|
324
|
-
<div className="grid grid-cols-1 md
|
|
353
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
354
|
+
<div className="space-y-4">
|
|
325
355
|
<h3 className="text-lg font-semibold text-cs-text-primary">Accessibility Features</h3>
|
|
326
356
|
|
|
327
357
|
<div className="space-y-3">
|
|
@@ -329,8 +359,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
329
359
|
<div className="space-y-2">
|
|
330
360
|
<div className="flex justify-between items-center">
|
|
331
361
|
<span className="text-sm">ARIA Support</span>
|
|
332
|
-
<span className={`font-medium ${touchTargetState.isAccessible ? 'text-cs-success' }`}>
|
|
333
|
-
{touchTargetState.isAccessible ? '✅ Enabled' }
|
|
362
|
+
<span className={`font-medium ${touchTargetState.isAccessible ? 'text-cs-success' : 'text-cs-warning'}`}>
|
|
363
|
+
{touchTargetState.isAccessible ? '✅ Enabled' : '⚠️ Disabled'}
|
|
334
364
|
</span>
|
|
335
365
|
</div>
|
|
336
366
|
|
|
@@ -361,8 +391,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
361
391
|
<div className="space-y-2">
|
|
362
392
|
<div className="flex justify-between items-center">
|
|
363
393
|
<span className="text-sm">44px Minimum</span>
|
|
364
|
-
<span className={`font-medium ${touchTargetState.size >= 44 ? 'text-cs-success' }`}>
|
|
365
|
-
{touchTargetState.size >= 44 ? '✅ Met' }
|
|
394
|
+
<span className={`font-medium ${touchTargetState.size >= 44 ? 'text-cs-success' : 'text-cs-error'}`}>
|
|
395
|
+
{touchTargetState.size >= 44 ? '✅ Met' : '❌ Not Met'}
|
|
366
396
|
</span>
|
|
367
397
|
</div>
|
|
368
398
|
|
|
@@ -389,7 +419,9 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
389
419
|
<div className="space-y-4">
|
|
390
420
|
<h3 className="text-lg font-semibold text-cs-text-primary">Interactive Test</h3>
|
|
391
421
|
|
|
392
|
-
<div className="grid grid-cols-1 md
|
|
422
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
423
|
+
<Button
|
|
424
|
+
size="default"
|
|
393
425
|
className="touch-target touch-friendly-button touch-interaction touch-performance touch-feedback min-h-[48px] min-w-[48px]"
|
|
394
426
|
aria-label="Test button with scale feedback"
|
|
395
427
|
>
|
|
@@ -408,7 +440,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
408
440
|
<Button
|
|
409
441
|
size="default"
|
|
410
442
|
variant="outline"
|
|
411
|
-
className="touch-target touch-interaction touch-performance touch-state-hover touch-state-active min-h-[48px] min-w-[48px] bg-transparent border border-cs-border text-cs-text-primary hover
|
|
443
|
+
className="touch-target touch-interaction touch-performance touch-state-hover touch-state-active min-h-[48px] min-w-[48px] bg-transparent border border-cs-border text-cs-text-primary hover:bg-cs-hover-bg"
|
|
444
|
+
aria-label="Test button with color feedback"
|
|
412
445
|
>
|
|
413
446
|
Color Feedback
|
|
414
447
|
</Button>
|
|
@@ -438,7 +471,8 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
438
471
|
className={`px-4 py-2 rounded-lg font-medium transition-colors ${
|
|
439
472
|
activeDemo === demo
|
|
440
473
|
? 'bg-cs-primary text-white'
|
|
441
|
-
|
|
474
|
+
: 'bg-cs-surface-bg text-cs-text-primary hover:bg-cs-hover-bg'
|
|
475
|
+
}`}
|
|
442
476
|
>
|
|
443
477
|
{demo === 'targets' && '🎯 Target Compliance'}
|
|
444
478
|
{demo === 'interactions' && '👆 Touch Interactions'}
|
|
@@ -460,17 +494,21 @@ export const TouchFriendlyInterfaceDemo= () => {
|
|
|
460
494
|
<div className="p-4 bg-cs-surface-bg rounded-lg border border-cs-border">
|
|
461
495
|
<div className="flex flex-wrap items-center justify-between gap-4 text-sm">
|
|
462
496
|
<div className="flex items-center space-x-4">
|
|
463
|
-
<span className="font-medium">Status
|
|
464
|
-
|
|
497
|
+
<span className="font-medium">Status:</span>
|
|
498
|
+
<Badge variant={touchTargetState.isOptimized ? 'default' : 'secondary'}>
|
|
499
|
+
{touchTargetState.isOptimized ? 'Optimized' : 'Optimizing...'}
|
|
465
500
|
</Badge>
|
|
466
|
-
<Badge variant={touchTargetState.isAccessible ? 'default' }>
|
|
467
|
-
{touchTargetState.isAccessible ? 'Accessible' }
|
|
501
|
+
<Badge variant={touchTargetState.isAccessible ? 'default' : 'secondary'}>
|
|
502
|
+
{touchTargetState.isAccessible ? 'Accessible' : 'Enhancing...'}
|
|
468
503
|
</Badge>
|
|
469
504
|
</div>
|
|
470
505
|
|
|
471
506
|
<div className="flex items-center space-x-4">
|
|
472
|
-
<span className="font-medium">Performance
|
|
473
|
-
|
|
507
|
+
<span className="font-medium">Performance:</span>
|
|
508
|
+
<span className={`font-bold ${
|
|
509
|
+
touchTargetState.performanceScore >= 80 ? 'text-cs-success' :
|
|
510
|
+
touchTargetState.performanceScore >= 60 ? 'text-cs-warning' : 'text-cs-error'
|
|
511
|
+
}`}>
|
|
474
512
|
{touchTargetState.performanceScore}%
|
|
475
513
|
</span>
|
|
476
514
|
</div>
|
|
@@ -4,34 +4,40 @@ import { useTouchFriendlyInterface } from '../../hooks/use-touch-friendly-interf
|
|
|
4
4
|
|
|
5
5
|
// Touch-Friendly Button Component
|
|
6
6
|
export interface TouchFriendlyButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
7
|
-
variant
|
|
7
|
+
variant?: 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive'
|
|
8
|
+
size?: 'sm' | 'default' | 'lg' | 'xl'
|
|
9
|
+
feedback?: 'scale' | 'ripple' | 'color' | 'none'
|
|
10
|
+
children: React.ReactNode
|
|
11
|
+
}
|
|
8
12
|
|
|
9
13
|
export const TouchFriendlyButton = forwardRef<HTMLButtonElement, TouchFriendlyButtonProps>(
|
|
10
14
|
({ className, variant = 'default', size = 'default', feedback = 'scale', children, ...props }, ref) => {
|
|
11
15
|
const { isTouchTargetCompliant, getTouchTargetSize } = useTouchFriendlyInterface({
|
|
12
|
-
minSize,
|
|
16
|
+
minSize: 44,
|
|
13
17
|
feedback
|
|
14
18
|
})
|
|
15
19
|
|
|
16
20
|
const baseClasses = 'touch-target touch-friendly-button touch-interaction touch-performance'
|
|
17
21
|
const feedbackClasses = {
|
|
18
|
-
scale,
|
|
19
|
-
ripple,
|
|
20
|
-
color,
|
|
21
|
-
none
|
|
22
|
+
scale: 'touch-feedback',
|
|
23
|
+
ripple: 'touch-ripple',
|
|
24
|
+
color: 'touch-state-hover touch-state-active',
|
|
25
|
+
none: ''
|
|
26
|
+
}
|
|
22
27
|
|
|
23
28
|
const variantClasses = {
|
|
24
|
-
default,
|
|
25
|
-
secondary,
|
|
26
|
-
outline,
|
|
27
|
-
ghost,
|
|
28
|
-
destructive
|
|
29
|
+
default: 'touch-friendly-button',
|
|
30
|
+
secondary: 'touch-friendly-button-secondary',
|
|
31
|
+
outline: 'touch-target touch-spacing bg-transparent border border-cs-border text-cs-text-primary hover:bg-cs-hover-bg',
|
|
32
|
+
ghost: 'touch-target touch-spacing bg-transparent text-cs-text-primary hover:bg-cs-hover-bg',
|
|
33
|
+
destructive: 'touch-target touch-spacing bg-cs-error text-white hover:bg-cs-error-hover'
|
|
34
|
+
}
|
|
29
35
|
|
|
30
36
|
const sizeClasses = {
|
|
31
|
-
sm] min-w-[44px] px-3 py-2 text-sm',
|
|
32
|
-
default] min-w-[48px] px-4 py-3 text-base',
|
|
33
|
-
lg] min-w-[56px] px-6 py-4 text-lg',
|
|
34
|
-
xl] min-w-[64px] px-8 py-5 text-xl'
|
|
37
|
+
sm: 'min-h-[44px] min-w-[44px] px-3 py-2 text-sm',
|
|
38
|
+
default: 'min-h-[48px] min-w-[48px] px-4 py-3 text-base',
|
|
39
|
+
lg: 'min-h-[56px] min-w-[56px] px-6 py-4 text-lg',
|
|
40
|
+
xl: 'min-h-[64px] min-w-[64px] px-8 py-5 text-xl'
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
return (
|
|
@@ -45,8 +51,8 @@ export const TouchFriendlyButton = forwardRef<HTMLButtonElement, TouchFriendlyBu
|
|
|
45
51
|
className
|
|
46
52
|
)}
|
|
47
53
|
style={{
|
|
48
|
-
minHeight)}px`,
|
|
49
|
-
minWidth)}px`
|
|
54
|
+
minHeight: `${getTouchTargetSize()}px`,
|
|
55
|
+
minWidth: `${getTouchTargetSize()}px`
|
|
50
56
|
}}
|
|
51
57
|
{...props}
|
|
52
58
|
>
|
|
@@ -65,26 +71,29 @@ TouchFriendlyButton.displayName = 'TouchFriendlyButton'
|
|
|
65
71
|
|
|
66
72
|
// Touch-Friendly Input Component
|
|
67
73
|
export interface TouchFriendlyInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
|
|
68
|
-
touchSize
|
|
74
|
+
touchSize?: 'sm' | 'default' | 'lg'
|
|
75
|
+
feedback?: 'scale' | 'ripple' | 'color' | 'none'
|
|
76
|
+
}
|
|
69
77
|
|
|
70
78
|
export const TouchFriendlyInput = forwardRef<HTMLInputElement, TouchFriendlyInputProps>(
|
|
71
79
|
({ className, touchSize = 'default', feedback = 'scale', ...props }, ref) => {
|
|
72
80
|
const { getTouchTargetSize } = useTouchFriendlyInterface({
|
|
73
|
-
minSize,
|
|
81
|
+
minSize: 44,
|
|
74
82
|
feedback
|
|
75
83
|
})
|
|
76
84
|
|
|
77
85
|
const baseClasses = 'touch-target touch-friendly-input touch-interaction touch-performance'
|
|
78
86
|
const feedbackClasses = {
|
|
79
|
-
scale,
|
|
80
|
-
ripple,
|
|
81
|
-
color,
|
|
82
|
-
none
|
|
87
|
+
scale: 'touch-feedback',
|
|
88
|
+
ripple: 'touch-ripple',
|
|
89
|
+
color: 'touch-state-hover touch-state-focus',
|
|
90
|
+
none: ''
|
|
91
|
+
}
|
|
83
92
|
|
|
84
93
|
const sizeClasses = {
|
|
85
|
-
sm] min-w-[44px] px-3 py-2 text-sm',
|
|
86
|
-
default] min-w-[48px] px-4 py-3 text-base',
|
|
87
|
-
lg] min-w-[56px] px-6 py-4 text-lg'
|
|
94
|
+
sm: 'min-h-[44px] min-w-[44px] px-3 py-2 text-sm',
|
|
95
|
+
default: 'min-h-[48px] min-w-[48px] px-4 py-3 text-base',
|
|
96
|
+
lg: 'min-h-[56px] min-w-[56px] px-6 py-4 text-lg'
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
return (
|
|
@@ -97,8 +106,8 @@ export const TouchFriendlyInput = forwardRef<HTMLInputElement, TouchFriendlyInpu
|
|
|
97
106
|
className
|
|
98
107
|
)}
|
|
99
108
|
style={{
|
|
100
|
-
minHeight)}px`,
|
|
101
|
-
minWidth)}px`
|
|
109
|
+
minHeight: `${getTouchTargetSize()}px`,
|
|
110
|
+
minWidth: `${getTouchTargetSize()}px`
|
|
102
111
|
}}
|
|
103
112
|
{...props}
|
|
104
113
|
/>
|
|
@@ -110,29 +119,37 @@ TouchFriendlyInput.displayName = 'TouchFriendlyInput'
|
|
|
110
119
|
|
|
111
120
|
// Touch-Friendly Card Component
|
|
112
121
|
export interface TouchFriendlyCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
113
|
-
size
|
|
122
|
+
size?: 'sm' | 'default' | 'lg'
|
|
123
|
+
feedback?: 'scale' | 'ripple' | 'color' | 'none'
|
|
124
|
+
interactive?: boolean
|
|
125
|
+
}
|
|
114
126
|
|
|
115
127
|
export const TouchFriendlyCard = forwardRef<HTMLDivElement, TouchFriendlyCardProps>(
|
|
116
128
|
({ className, size = 'default', feedback = 'scale', interactive = false, children, ...props }, ref) => {
|
|
117
129
|
const { isTouchTargetCompliant, getTouchTargetSize } = useTouchFriendlyInterface({
|
|
118
|
-
minSize,
|
|
130
|
+
minSize: 44,
|
|
119
131
|
feedback
|
|
120
132
|
})
|
|
121
133
|
|
|
122
134
|
const baseClasses = 'touch-friendly-card touch-interaction touch-performance'
|
|
123
135
|
const feedbackClasses = interactive ? {
|
|
124
|
-
scale,
|
|
125
|
-
ripple,
|
|
126
|
-
color,
|
|
127
|
-
none
|
|
136
|
+
scale: 'touch-feedback',
|
|
137
|
+
ripple: 'touch-ripple',
|
|
138
|
+
color: 'touch-state-hover touch-state-active',
|
|
139
|
+
none: ''
|
|
140
|
+
} : { scale: '', ripple: '', color: '', none: '' }
|
|
128
141
|
|
|
129
142
|
const sizeClasses = {
|
|
130
|
-
sm] min-w-[44px] p-3',
|
|
131
|
-
default] min-w-[48px] p-4',
|
|
132
|
-
lg] min-w-[56px] p-6'
|
|
143
|
+
sm: 'min-h-[44px] min-w-[44px] p-3',
|
|
144
|
+
default: 'min-h-[48px] min-w-[48px] p-4',
|
|
145
|
+
lg: 'min-h-[56px] min-w-[56px] p-6'
|
|
133
146
|
}
|
|
134
147
|
|
|
135
|
-
const interactiveClasses = interactive ? 'cursor-pointer'
|
|
148
|
+
const interactiveClasses = interactive ? 'cursor-pointer' : ''
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div
|
|
152
|
+
ref={ref}
|
|
136
153
|
className={cn(
|
|
137
154
|
baseClasses,
|
|
138
155
|
feedbackClasses[feedback],
|
|
@@ -141,8 +158,8 @@ export const TouchFriendlyCard = forwardRef<HTMLDivElement, TouchFriendlyCardPro
|
|
|
141
158
|
className
|
|
142
159
|
)}
|
|
143
160
|
style={{
|
|
144
|
-
minHeight)}px`,
|
|
145
|
-
minWidth)}px`
|
|
161
|
+
minHeight: `${getTouchTargetSize()}px`,
|
|
162
|
+
minWidth: `${getTouchTargetSize()}px`
|
|
146
163
|
}}
|
|
147
164
|
{...props}
|
|
148
165
|
>
|
|
@@ -161,20 +178,23 @@ TouchFriendlyCard.displayName = 'TouchFriendlyCard'
|
|
|
161
178
|
|
|
162
179
|
// Touch-Friendly Toggle Component
|
|
163
180
|
export interface TouchFriendlyToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
164
|
-
checked
|
|
165
|
-
|
|
181
|
+
checked?: boolean
|
|
182
|
+
onCheckedChange?: (checked: boolean) => void
|
|
183
|
+
size?: 'sm' | 'default' | 'lg'
|
|
184
|
+
}
|
|
166
185
|
|
|
167
186
|
export const TouchFriendlyToggle = forwardRef<HTMLButtonElement, TouchFriendlyToggleProps>(
|
|
168
187
|
({ className, checked = false, onCheckedChange, size = 'default', ...props }, ref) => {
|
|
169
188
|
const { isTouchTargetCompliant, getTouchTargetSize } = useTouchFriendlyInterface({
|
|
170
|
-
minSize,
|
|
171
|
-
feedback
|
|
189
|
+
minSize: 44,
|
|
190
|
+
feedback: 'scale'
|
|
191
|
+
})
|
|
172
192
|
|
|
173
193
|
const baseClasses = 'touch-target touch-interaction touch-performance touch-feedback'
|
|
174
194
|
const sizeClasses = {
|
|
175
|
-
sm] min-w-[44px]',
|
|
176
|
-
default] min-w-[48px]',
|
|
177
|
-
lg] min-w-[56px]'
|
|
195
|
+
sm: 'min-h-[44px] min-w-[44px]',
|
|
196
|
+
default: 'min-h-[48px] min-w-[48px]',
|
|
197
|
+
lg: 'min-h-[56px] min-w-[56px]'
|
|
178
198
|
}
|
|
179
199
|
|
|
180
200
|
const handleClick = () => {
|
|
@@ -191,13 +211,13 @@ export const TouchFriendlyToggle = forwardRef<HTMLButtonElement, TouchFriendlyTo
|
|
|
191
211
|
baseClasses,
|
|
192
212
|
sizeClasses[size],
|
|
193
213
|
'relative inline-flex items-center justify-center rounded-full transition-colors',
|
|
194
|
-
checked ? 'bg-cs-primary' ,
|
|
195
|
-
'focus,
|
|
214
|
+
checked ? 'bg-cs-primary' : 'bg-cs-border',
|
|
215
|
+
'focus:outline-none focus:ring-2 focus:ring-cs-primary focus:ring-offset-2',
|
|
196
216
|
className
|
|
197
217
|
)}
|
|
198
218
|
style={{
|
|
199
|
-
minHeight)}px`,
|
|
200
|
-
minWidth)}px`
|
|
219
|
+
minHeight: `${getTouchTargetSize()}px`,
|
|
220
|
+
minWidth: `${getTouchTargetSize()}px`
|
|
201
221
|
}}
|
|
202
222
|
onClick={handleClick}
|
|
203
223
|
{...props}
|
|
@@ -205,8 +225,9 @@ export const TouchFriendlyToggle = forwardRef<HTMLButtonElement, TouchFriendlyTo
|
|
|
205
225
|
<span
|
|
206
226
|
className={cn(
|
|
207
227
|
'inline-block rounded-full bg-white shadow transform transition-transform',
|
|
208
|
-
size === 'sm' ? 'w-5 h-5' === 'default' ? 'w-6 h-6' ,
|
|
209
|
-
checked ? 'translate-x-full'
|
|
228
|
+
size === 'sm' ? 'w-5 h-5' : size === 'default' ? 'w-6 h-6' : 'w-7 h-7',
|
|
229
|
+
checked ? 'translate-x-full' : 'translate-x-0'
|
|
230
|
+
)}
|
|
210
231
|
/>
|
|
211
232
|
{!isTouchTargetCompliant() && (
|
|
212
233
|
<span className="text-xs text-cs-warning absolute -bottom-6 left-1/2 transform -translate-x-1/2">
|
|
@@ -222,19 +243,22 @@ TouchFriendlyToggle.displayName = 'TouchFriendlyToggle'
|
|
|
222
243
|
|
|
223
244
|
// Touch-Friendly Slider Component
|
|
224
245
|
export interface TouchFriendlySliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {
|
|
225
|
-
touchSize
|
|
246
|
+
touchSize?: 'sm' | 'default' | 'lg'
|
|
247
|
+
showValue?: boolean
|
|
248
|
+
}
|
|
226
249
|
|
|
227
250
|
export const TouchFriendlySlider = forwardRef<HTMLInputElement, TouchFriendlySliderProps>(
|
|
228
251
|
({ className, touchSize = 'default', showValue = true, ...props }, ref) => {
|
|
229
252
|
const { isTouchTargetCompliant, getTouchTargetSize } = useTouchFriendlyInterface({
|
|
230
|
-
minSize,
|
|
231
|
-
feedback
|
|
253
|
+
minSize: 44,
|
|
254
|
+
feedback: 'scale'
|
|
255
|
+
})
|
|
232
256
|
|
|
233
257
|
const baseClasses = 'touch-target touch-interaction touch-performance touch-feedback'
|
|
234
258
|
const sizeClasses = {
|
|
235
|
-
sm] min-w-[44px]',
|
|
236
|
-
default] min-w-[48px]',
|
|
237
|
-
lg] min-w-[56px]'
|
|
259
|
+
sm: 'min-h-[44px] min-w-[44px]',
|
|
260
|
+
default: 'min-h-[48px] min-w-[48px]',
|
|
261
|
+
lg: 'min-h-[56px] min-w-[56px]'
|
|
238
262
|
}
|
|
239
263
|
|
|
240
264
|
return (
|
|
@@ -246,11 +270,11 @@ export const TouchFriendlySlider = forwardRef<HTMLInputElement, TouchFriendlySli
|
|
|
246
270
|
baseClasses,
|
|
247
271
|
sizeClasses[touchSize],
|
|
248
272
|
'w-full h-2 bg-cs-border rounded-lg appearance-none cursor-pointer',
|
|
249
|
-
'focus,
|
|
273
|
+
'focus:outline-none focus:ring-2 focus:ring-cs-primary',
|
|
250
274
|
className
|
|
251
275
|
)}
|
|
252
276
|
style={{
|
|
253
|
-
minHeight)}px`
|
|
277
|
+
minHeight: `${getTouchTargetSize()}px`
|
|
254
278
|
}}
|
|
255
279
|
{...props}
|
|
256
280
|
/>
|