@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.4 → 0.1.6

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.
Files changed (164) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +131 -131
  3. package/dist/index.esm.js +148 -148
  4. package/dist/index.js +148 -148
  5. package/dist/styles.css +1 -1
  6. package/package.json +1 -1
  7. package/src/components/ui/accessibility-demo.tsx +271 -0
  8. package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
  9. package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
  10. package/src/components/ui/advanced-transition-system.tsx +395 -0
  11. package/src/components/ui/animation/animated-container.tsx +166 -0
  12. package/src/components/ui/animation/index.ts +19 -0
  13. package/src/components/ui/animation/staggered-container.tsx +68 -0
  14. package/src/components/ui/animation-demo.tsx +250 -0
  15. package/src/components/ui/badge.tsx +33 -0
  16. package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
  17. package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
  18. package/src/components/ui/button.tsx +36 -0
  19. package/src/components/ui/card.tsx +207 -0
  20. package/src/components/ui/checkbox.tsx +30 -0
  21. package/src/components/ui/color-preview.tsx +411 -0
  22. package/src/components/ui/data-display/chart.tsx +653 -0
  23. package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
  24. package/src/components/ui/data-display/data-grid.tsx +680 -0
  25. package/src/components/ui/data-display/list.tsx +456 -0
  26. package/src/components/ui/data-display/table.tsx +482 -0
  27. package/src/components/ui/data-display/timeline.tsx +441 -0
  28. package/src/components/ui/data-display/tree.tsx +602 -0
  29. package/src/components/ui/data-display/types.ts +536 -0
  30. package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
  31. package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
  32. package/src/components/ui/feedback/alert.tsx +157 -0
  33. package/src/components/ui/feedback/progress.tsx +292 -0
  34. package/src/components/ui/feedback/skeleton.tsx +185 -0
  35. package/src/components/ui/feedback/toast.tsx +280 -0
  36. package/src/components/ui/feedback/types.ts +125 -0
  37. package/src/components/ui/font-preview.tsx +288 -0
  38. package/src/components/ui/form-demo.tsx +553 -0
  39. package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
  40. package/src/components/ui/input.tsx +35 -0
  41. package/src/components/ui/label.tsx +16 -0
  42. package/src/components/ui/layout-demo.tsx +367 -0
  43. package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
  44. package/src/components/ui/layouts/desktop-layout.tsx +224 -0
  45. package/src/components/ui/layouts/index.ts +10 -0
  46. package/src/components/ui/layouts/mobile-layout.tsx +162 -0
  47. package/src/components/ui/layouts/tablet-layout.tsx +197 -0
  48. package/src/components/ui/mobile-form-validation.tsx +451 -0
  49. package/src/components/ui/mobile-input-demo.tsx +201 -0
  50. package/src/components/ui/mobile-input.tsx +281 -0
  51. package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
  52. package/src/components/ui/navigation/breadcrumb.tsx +158 -0
  53. package/src/components/ui/navigation/index.ts +36 -0
  54. package/src/components/ui/navigation/menu.tsx +374 -0
  55. package/src/components/ui/navigation/navigation-demo.tsx +324 -0
  56. package/src/components/ui/navigation/pagination.tsx +272 -0
  57. package/src/components/ui/navigation/sidebar.tsx +383 -0
  58. package/src/components/ui/navigation/stepper.tsx +303 -0
  59. package/src/components/ui/navigation/tabs.tsx +205 -0
  60. package/src/components/ui/navigation/types.ts +299 -0
  61. package/src/components/ui/overlay/backdrop.tsx +81 -0
  62. package/src/components/ui/overlay/focus-manager.tsx +143 -0
  63. package/src/components/ui/overlay/index.ts +36 -0
  64. package/src/components/ui/overlay/modal.tsx +270 -0
  65. package/src/components/ui/overlay/overlay-manager.tsx +110 -0
  66. package/src/components/ui/overlay/popover.tsx +462 -0
  67. package/src/components/ui/overlay/portal.tsx +79 -0
  68. package/src/components/ui/overlay/tooltip.tsx +303 -0
  69. package/src/components/ui/overlay/types.ts +196 -0
  70. package/src/components/ui/performance-demo.tsx +596 -0
  71. package/src/components/ui/semantic-input-system-demo.tsx +502 -0
  72. package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
  73. package/src/components/ui/tablet-layout.tsx +192 -0
  74. package/src/components/ui/theme-customizer.tsx +386 -0
  75. package/src/components/ui/theme-preview.tsx +310 -0
  76. package/src/components/ui/theme-switcher.tsx +264 -0
  77. package/src/components/ui/theme-toggle.tsx +38 -0
  78. package/src/components/ui/token-demo.tsx +195 -0
  79. package/src/components/ui/touch-demo.tsx +462 -0
  80. package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
  81. package/src/components/ui/touch-friendly-interface.tsx +296 -0
  82. package/src/hooks/index.ts +190 -0
  83. package/src/hooks/use-accessibility-support.ts +518 -0
  84. package/src/hooks/use-adaptive-layout.ts +289 -0
  85. package/src/hooks/use-advanced-patterns.ts +294 -0
  86. package/src/hooks/use-advanced-transition-system.ts +393 -0
  87. package/src/hooks/use-animation-profile.ts +288 -0
  88. package/src/hooks/use-battery-animations.ts +384 -0
  89. package/src/hooks/use-battery-conscious-loading.ts +475 -0
  90. package/src/hooks/use-battery-optimization.ts +330 -0
  91. package/src/hooks/use-battery-status.ts +299 -0
  92. package/src/hooks/use-component-performance.ts +344 -0
  93. package/src/hooks/use-device-loading-states.ts +459 -0
  94. package/src/hooks/use-device.tsx +110 -0
  95. package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
  96. package/src/hooks/use-form-feedback.ts +403 -0
  97. package/src/hooks/use-form-performance.ts +513 -0
  98. package/src/hooks/use-frame-rate.ts +251 -0
  99. package/src/hooks/use-gestures.ts +338 -0
  100. package/src/hooks/use-hardware-acceleration.ts +341 -0
  101. package/src/hooks/use-input-accessibility.ts +455 -0
  102. package/src/hooks/use-input-performance.ts +506 -0
  103. package/src/hooks/use-layout-performance.ts +319 -0
  104. package/src/hooks/use-loading-accessibility.ts +535 -0
  105. package/src/hooks/use-loading-performance.ts +473 -0
  106. package/src/hooks/use-memory-usage.ts +287 -0
  107. package/src/hooks/use-mobile-form-layout.ts +464 -0
  108. package/src/hooks/use-mobile-form-validation.ts +518 -0
  109. package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
  110. package/src/hooks/use-mobile-layout.ts +302 -0
  111. package/src/hooks/use-mobile-optimization.ts +406 -0
  112. package/src/hooks/use-mobile-skeleton.ts +402 -0
  113. package/src/hooks/use-mobile-touch.ts +414 -0
  114. package/src/hooks/use-performance-throttling.ts +348 -0
  115. package/src/hooks/use-performance.ts +316 -0
  116. package/src/hooks/use-reusable-architecture.ts +414 -0
  117. package/src/hooks/use-semantic-input-types.ts +357 -0
  118. package/src/hooks/use-semantic-input.ts +565 -0
  119. package/src/hooks/use-tablet-layout.ts +384 -0
  120. package/src/hooks/use-touch-friendly-input.ts +524 -0
  121. package/src/hooks/use-touch-friendly-interface.ts +331 -0
  122. package/src/hooks/use-touch-optimization.ts +375 -0
  123. package/src/index.ts +279 -279
  124. package/src/lib/utils.ts +6 -0
  125. package/src/themes/README.md +272 -0
  126. package/src/themes/ThemeContext.tsx +31 -0
  127. package/src/themes/ThemeProvider.tsx +232 -0
  128. package/src/themes/accessibility/index.ts +27 -0
  129. package/src/themes/accessibility.ts +259 -0
  130. package/src/themes/aria-patterns.ts +420 -0
  131. package/src/themes/base-themes.ts +55 -0
  132. package/src/themes/colorManager.ts +380 -0
  133. package/src/themes/examples/dark-theme.ts +154 -0
  134. package/src/themes/examples/minimal-theme.ts +108 -0
  135. package/src/themes/focus-management.ts +701 -0
  136. package/src/themes/fontLoader.ts +201 -0
  137. package/src/themes/high-contrast.ts +621 -0
  138. package/src/themes/index.ts +19 -0
  139. package/src/themes/inheritance.ts +227 -0
  140. package/src/themes/keyboard-navigation.ts +550 -0
  141. package/src/themes/motion-reduction.ts +662 -0
  142. package/src/themes/navigation.ts +238 -0
  143. package/src/themes/screen-reader.ts +645 -0
  144. package/src/themes/systemThemeDetector.ts +182 -0
  145. package/src/themes/themeCSSUpdater.ts +262 -0
  146. package/src/themes/themePersistence.ts +238 -0
  147. package/src/themes/themes/default.ts +586 -0
  148. package/src/themes/themes/harvey.ts +554 -0
  149. package/src/themes/themes/stan-design.ts +683 -0
  150. package/src/themes/types.ts +460 -0
  151. package/src/themes/useSystemTheme.ts +48 -0
  152. package/src/themes/useTheme.ts +87 -0
  153. package/src/themes/validation.ts +462 -0
  154. package/src/tokens/index.ts +34 -0
  155. package/src/tokens/tokenExporter.ts +397 -0
  156. package/src/tokens/tokenGenerator.ts +276 -0
  157. package/src/tokens/tokenManager.ts +248 -0
  158. package/src/tokens/tokenValidator.ts +543 -0
  159. package/src/tokens/types.ts +78 -0
  160. package/src/utils/bundle-analyzer.ts +260 -0
  161. package/src/utils/bundle-splitting.ts +483 -0
  162. package/src/utils/lazy-loading.ts +441 -0
  163. package/src/utils/performance-monitor.ts +513 -0
  164. package/src/utils/tree-shaking.ts +274 -0
@@ -0,0 +1,414 @@
1
+ import { useState, useEffect, useCallback, useRef } from 'react'
2
+
3
+ export interface MobileTouchConfig {
4
+ enableTouchFeedback: boolean
5
+ enableGestureHints: boolean
6
+ enableTouchSounds: boolean
7
+ enableHapticFeedback: boolean
8
+ touchFeedbackDelay: number
9
+ gestureHintTimeout: number
10
+ maxTouchPoints: number
11
+ }
12
+
13
+ export interface TouchFeedbackState {
14
+ isPressed: boolean
15
+ feedbackType: 'none' | 'scale' | 'ripple' | 'glow'
16
+ feedbackIntensity: 'light' | 'medium' | 'strong'
17
+ lastTouchPosition: { x: number; y: number } | null
18
+ }
19
+
20
+ export interface GestureHint {
21
+ type: 'swipe' | 'pinch' | 'longPress' | 'doubleTap' | 'tap'
22
+ message: string
23
+ position: { x: number; y: number }
24
+ timeout: number
25
+ }
26
+
27
+ export interface MobileTouchCallbacks {
28
+ onTouchFeedback?: (state: TouchFeedbackState) => void
29
+ onGestureHint?: (hint: GestureHint) => void
30
+ onTouchStart?: (position: { x: number; y: number }) => void
31
+ onTouchEnd?: (position: { x: number; y: number }) => void
32
+ onTouchMove?: (position: { x: number; y: number }) => void
33
+ }
34
+
35
+ export interface MobileTouchState {
36
+ isActive: boolean
37
+ touchCount: number
38
+ currentFeedback: TouchFeedbackState
39
+ activeGestureHints: GestureHint[]
40
+ deviceCapabilities: {
41
+ supportsTouch: boolean
42
+ supportsHaptics: boolean
43
+ supportsAudio: boolean
44
+ maxTouchPoints: number
45
+ }
46
+ }
47
+
48
+ export const useMobileTouch = (
49
+ elementRef: React.RefObject<HTMLElement>,
50
+ callbacks: MobileTouchCallbacks = {},
51
+ config: Partial<MobileTouchConfig> = {}
52
+ ) => {
53
+ const defaultConfig: MobileTouchConfig = {
54
+ enableTouchFeedback: true,
55
+ enableGestureHints: true,
56
+ enableTouchSounds: false,
57
+ enableHapticFeedback: true,
58
+ touchFeedbackDelay: 100,
59
+ gestureHintTimeout: 3000,
60
+ maxTouchPoints: 5,
61
+ ...config
62
+ }
63
+
64
+ // Device info available if needed for future enhancements
65
+ // const device = useDevice()
66
+ const [mobileTouchState, setMobileTouchState] = useState<MobileTouchState>({
67
+ isActive: false,
68
+ touchCount: 0,
69
+ currentFeedback: {
70
+ isPressed: false,
71
+ feedbackType: 'none',
72
+ feedbackIntensity: 'medium',
73
+ lastTouchPosition: null
74
+ },
75
+ activeGestureHints: [],
76
+ deviceCapabilities: {
77
+ supportsTouch: false,
78
+ supportsHaptics: false,
79
+ supportsAudio: false,
80
+ maxTouchPoints: 0
81
+ }
82
+ })
83
+
84
+ const touchStartTimeRef = useRef<number>(0)
85
+ const touchFeedbackTimerRef = useRef<NodeJS.Timeout | null>(null)
86
+ const gestureHintTimersRef = useRef<Map<string, NodeJS.Timeout>>(new Map())
87
+ const audioContextRef = useRef<AudioContext | null>(null)
88
+
89
+ // Initialize device capabilities
90
+ useEffect(() => {
91
+ const capabilities = {
92
+ supportsTouch: 'ontouchstart' in window,
93
+ supportsHaptics: 'vibrate' in navigator,
94
+ supportsAudio: 'AudioContext' in window || 'webkitAudioContext' in window,
95
+ maxTouchPoints: navigator.maxTouchPoints || 0
96
+ }
97
+
98
+ setMobileTouchState(prev => ({
99
+ ...prev,
100
+ deviceCapabilities: capabilities
101
+ }))
102
+
103
+ // Initialize audio context if supported
104
+ if (capabilities.supportsAudio) {
105
+ audioContextRef.current = new (window.AudioContext || (window as any).webkitAudioContext)()
106
+ }
107
+ }, [])
108
+
109
+ // Trigger haptic feedback
110
+ const triggerHapticFeedback = useCallback((intensity: 'light' | 'medium' | 'strong' = 'medium') => {
111
+ if (!defaultConfig.enableHapticFeedback || !mobileTouchState.deviceCapabilities.supportsHaptics) return
112
+
113
+ const vibrationPattern = {
114
+ light: 20,
115
+ medium: 50,
116
+ strong: 100
117
+ }
118
+
119
+ try {
120
+ navigator.vibrate(vibrationPattern[intensity])
121
+ } catch (error) {
122
+ console.warn('Haptic feedback not supported:', error)
123
+ }
124
+ }, [defaultConfig.enableHapticFeedback, mobileTouchState.deviceCapabilities.supportsHaptics])
125
+
126
+ // Trigger touch sound
127
+ const triggerTouchSound = useCallback((type: 'tap' | 'press' | 'release' = 'tap') => {
128
+ if (!defaultConfig.enableTouchSounds || !audioContextRef.current) return
129
+
130
+ try {
131
+ const audioContext = audioContextRef.current
132
+ const oscillator = audioContext.createOscillator()
133
+ const gainNode = audioContext.createGain()
134
+
135
+ oscillator.connect(gainNode)
136
+ gainNode.connect(audioContext.destination)
137
+
138
+ // Different sounds for different touch types
139
+ const soundConfig = {
140
+ tap: { frequency: 800, duration: 0.1, volume: 0.1 },
141
+ press: { frequency: 600, duration: 0.2, volume: 0.15 },
142
+ release: { frequency: 1000, duration: 0.08, volume: 0.08 }
143
+ }
144
+
145
+ const config = soundConfig[type]
146
+ oscillator.frequency.setValueAtTime(config.frequency, audioContext.currentTime)
147
+ gainNode.gain.setValueAtTime(config.volume, audioContext.currentTime)
148
+
149
+ oscillator.start(audioContext.currentTime)
150
+ oscillator.stop(audioContext.currentTime + config.duration)
151
+ } catch (error) {
152
+ console.warn('Touch sound not supported:', error)
153
+ }
154
+ }, [defaultConfig.enableTouchSounds])
155
+
156
+ // Update touch feedback state
157
+ const updateTouchFeedback = useCallback((feedback: Partial<TouchFeedbackState>) => {
158
+ setMobileTouchState(prev => ({
159
+ ...prev,
160
+ currentFeedback: { ...prev.currentFeedback, ...feedback }
161
+ }))
162
+
163
+ callbacks.onTouchFeedback?.(mobileTouchState.currentFeedback)
164
+ }, [callbacks, mobileTouchState.currentFeedback])
165
+
166
+ // Add gesture hint
167
+ const addGestureHint = useCallback((hint: Omit<GestureHint, 'timeout'>) => {
168
+ if (!defaultConfig.enableGestureHints) return
169
+
170
+ const hintWithTimeout = {
171
+ ...hint,
172
+ timeout: Date.now() + defaultConfig.gestureHintTimeout
173
+ }
174
+
175
+ setMobileTouchState(prev => ({
176
+ ...prev,
177
+ activeGestureHints: [...prev.activeGestureHints, hintWithTimeout]
178
+ }))
179
+
180
+ // Set timer to remove hint
181
+ const timer = setTimeout(() => {
182
+ removeGestureHint(hint.type)
183
+ }, defaultConfig.gestureHintTimeout)
184
+
185
+ gestureHintTimersRef.current.set(hint.type, timer)
186
+ callbacks.onGestureHint?.(hintWithTimeout)
187
+ }, [defaultConfig.enableGestureHints, defaultConfig.gestureHintTimeout, callbacks])
188
+
189
+ // Remove gesture hint
190
+ const removeGestureHint = useCallback((type: string) => {
191
+ setMobileTouchState(prev => ({
192
+ ...prev,
193
+ activeGestureHints: prev.activeGestureHints.filter(hint => hint.type !== type)
194
+ }))
195
+
196
+ const timer = gestureHintTimersRef.current.get(type)
197
+ if (timer) {
198
+ clearTimeout(timer)
199
+ gestureHintTimersRef.current.delete(type)
200
+ }
201
+ }, [])
202
+
203
+ // Handle touch start
204
+ const handleTouchStart = useCallback((event: TouchEvent) => {
205
+ const touch = event.touches[0]
206
+ const position = { x: touch.clientX, y: touch.clientY }
207
+
208
+ touchStartTimeRef.current = Date.now()
209
+
210
+ setMobileTouchState(prev => ({
211
+ ...prev,
212
+ isActive: true,
213
+ touchCount: event.touches.length
214
+ }))
215
+
216
+ // Update feedback state
217
+ if (defaultConfig.enableTouchFeedback) {
218
+ updateTouchFeedback({
219
+ isPressed: true,
220
+ feedbackType: 'scale',
221
+ feedbackIntensity: 'medium',
222
+ lastTouchPosition: position
223
+ })
224
+
225
+ // Set feedback timer
226
+ touchFeedbackTimerRef.current = setTimeout(() => {
227
+ updateTouchFeedback({
228
+ feedbackType: 'ripple',
229
+ feedbackIntensity: 'strong'
230
+ })
231
+ }, defaultConfig.touchFeedbackDelay)
232
+ }
233
+
234
+ // Trigger feedback
235
+ triggerHapticFeedback('light')
236
+ triggerTouchSound('press')
237
+
238
+ callbacks.onTouchStart?.(position)
239
+ }, [defaultConfig.enableTouchFeedback, defaultConfig.touchFeedbackDelay, updateTouchFeedback, triggerHapticFeedback, triggerTouchSound, callbacks])
240
+
241
+ // Handle touch move
242
+ const handleTouchMove = useCallback((event: TouchEvent) => {
243
+ const touch = event.touches[0]
244
+ const position = { x: touch.clientX, y: touch.clientY }
245
+
246
+ // Update feedback state
247
+ if (defaultConfig.enableTouchFeedback) {
248
+ updateTouchFeedback({
249
+ lastTouchPosition: position
250
+ })
251
+ }
252
+
253
+ callbacks.onTouchMove?.(position)
254
+ }, [defaultConfig.enableTouchFeedback, updateTouchFeedback, callbacks])
255
+
256
+ // Handle touch end
257
+ const handleTouchEnd = useCallback((event: TouchEvent) => {
258
+ const touch = event.changedTouches[0]
259
+ const position = { x: touch.clientX, y: touch.clientY }
260
+ const touchDuration = Date.now() - touchStartTimeRef.current
261
+
262
+ // Clear feedback timer
263
+ if (touchFeedbackTimerRef.current) {
264
+ clearTimeout(touchFeedbackTimerRef.current)
265
+ touchFeedbackTimerRef.current = null
266
+ }
267
+
268
+ // Update feedback state
269
+ if (defaultConfig.enableTouchFeedback) {
270
+ updateTouchFeedback({
271
+ isPressed: false,
272
+ feedbackType: 'none',
273
+ feedbackIntensity: 'medium'
274
+ })
275
+ }
276
+
277
+ // Determine touch type and provide appropriate feedback
278
+ if (touchDuration < 200) {
279
+ // Quick tap
280
+ triggerHapticFeedback('light')
281
+ triggerTouchSound('tap')
282
+
283
+ // Show tap hint
284
+ addGestureHint({
285
+ type: 'tap',
286
+ message: 'Quick tap detected',
287
+ position
288
+ })
289
+ } else if (touchDuration > 500) {
290
+ // Long press
291
+ triggerHapticFeedback('strong')
292
+ triggerTouchSound('release')
293
+
294
+ // Show long press hint
295
+ addGestureHint({
296
+ type: 'longPress',
297
+ message: 'Long press detected',
298
+ position
299
+ })
300
+ } else {
301
+ // Regular press
302
+ triggerHapticFeedback('medium')
303
+ triggerTouchSound('release')
304
+ }
305
+
306
+ setMobileTouchState(prev => ({
307
+ ...prev,
308
+ isActive: false,
309
+ touchCount: Math.max(0, prev.touchCount - 1)
310
+ }))
311
+
312
+ callbacks.onTouchEnd?.(position)
313
+ }, [defaultConfig.enableTouchFeedback, updateTouchFeedback, triggerHapticFeedback, triggerTouchSound, addGestureHint, callbacks])
314
+
315
+ // Set up touch event listeners
316
+ useEffect(() => {
317
+ const element = elementRef.current
318
+ if (!element || !mobileTouchState.deviceCapabilities.supportsTouch) return
319
+
320
+ element.addEventListener('touchstart', handleTouchStart, { passive: false })
321
+ element.addEventListener('touchmove', handleTouchMove, { passive: false })
322
+ element.addEventListener('touchend', handleTouchEnd, { passive: false })
323
+
324
+ return () => {
325
+ element.removeEventListener('touchstart', handleTouchStart)
326
+ element.removeEventListener('touchmove', handleTouchMove)
327
+ element.removeEventListener('touchend', handleTouchEnd)
328
+
329
+ // Clean up timers
330
+ if (touchFeedbackTimerRef.current) {
331
+ clearTimeout(touchFeedbackTimerRef.current)
332
+ }
333
+
334
+ gestureHintTimersRef.current.forEach(timer => clearTimeout(timer))
335
+ gestureHintTimersRef.current.clear()
336
+ }
337
+ }, [
338
+ elementRef,
339
+ mobileTouchState.deviceCapabilities.supportsTouch,
340
+ handleTouchStart,
341
+ handleTouchMove,
342
+ handleTouchEnd
343
+ ])
344
+
345
+ // Clean up on unmount
346
+ useEffect(() => {
347
+ return () => {
348
+ if (touchFeedbackTimerRef.current) {
349
+ clearTimeout(touchFeedbackTimerRef.current)
350
+ }
351
+
352
+ gestureHintTimersRef.current.forEach(timer => clearTimeout(timer))
353
+ gestureHintTimersRef.current.clear()
354
+ }
355
+ }, [])
356
+
357
+ // Utility functions
358
+ const clearAllGestureHints = useCallback(() => {
359
+ gestureHintTimersRef.current.forEach(timer => clearTimeout(timer))
360
+ gestureHintTimersRef.current.clear()
361
+
362
+ setMobileTouchState(prev => ({
363
+ ...prev,
364
+ activeGestureHints: []
365
+ }))
366
+ }, [])
367
+
368
+ const getTouchFeedbackClasses = useCallback(() => {
369
+ const { currentFeedback } = mobileTouchState
370
+
371
+ if (!currentFeedback.isPressed) return ''
372
+
373
+ const classes = ['touch-feedback']
374
+
375
+ if (currentFeedback.feedbackType === 'scale') {
376
+ classes.push('touch-pressed')
377
+ } else if (currentFeedback.feedbackType === 'ripple') {
378
+ classes.push('touch-ripple', 'touch-active')
379
+ }
380
+
381
+ return classes.join(' ')
382
+ }, [mobileTouchState.currentFeedback])
383
+
384
+ return {
385
+ mobileTouchState,
386
+ updateTouchFeedback,
387
+ addGestureHint,
388
+ removeGestureHint,
389
+ clearAllGestureHints,
390
+ getTouchFeedbackClasses,
391
+ triggerHapticFeedback,
392
+ triggerTouchSound
393
+ }
394
+ }
395
+
396
+ // Convenience hook for basic mobile touch
397
+ export const useBasicMobileTouch = (elementRef: React.RefObject<HTMLElement>) => {
398
+ return useMobileTouch(elementRef, {}, {
399
+ enableTouchFeedback: true,
400
+ enableGestureHints: false,
401
+ enableTouchSounds: false,
402
+ enableHapticFeedback: true
403
+ })
404
+ }
405
+
406
+ // Convenience hook for enhanced mobile touch
407
+ export const useEnhancedMobileTouch = (elementRef: React.RefObject<HTMLElement>) => {
408
+ return useMobileTouch(elementRef, {}, {
409
+ enableTouchFeedback: true,
410
+ enableGestureHints: true,
411
+ enableTouchSounds: true,
412
+ enableHapticFeedback: true
413
+ })
414
+ }