@stfrigerio/sito-template 0.1.26 → 0.1.28

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 (37) hide show
  1. package/dist/components/atoms/Button/Button.d.ts +3 -0
  2. package/dist/components/atoms/Button/Button.d.ts.map +1 -1
  3. package/dist/components/atoms/Button/Button.stories.d.ts +1 -0
  4. package/dist/components/atoms/Button/Button.stories.d.ts.map +1 -1
  5. package/dist/components/atoms/Checkbox/Checkbox.d.ts +3 -0
  6. package/dist/components/atoms/Checkbox/Checkbox.d.ts.map +1 -1
  7. package/dist/components/atoms/DateInput/DateInput.d.ts +4 -1
  8. package/dist/components/atoms/DateInput/DateInput.d.ts.map +1 -1
  9. package/dist/components/atoms/NumberStepper/NumberStepper.d.ts +68 -0
  10. package/dist/components/atoms/NumberStepper/NumberStepper.d.ts.map +1 -1
  11. package/dist/components/atoms/NumberStepper/NumberStepper.stories.d.ts +8 -0
  12. package/dist/components/atoms/NumberStepper/NumberStepper.stories.d.ts.map +1 -1
  13. package/dist/components/atoms/SelectInput/SelectInput.d.ts +4 -1
  14. package/dist/components/atoms/SelectInput/SelectInput.d.ts.map +1 -1
  15. package/dist/components/atoms/Slider/Slider.d.ts +4 -1
  16. package/dist/components/atoms/Slider/Slider.d.ts.map +1 -1
  17. package/dist/components/atoms/SoundDemo/SoundDemo.stories.d.ts +17 -0
  18. package/dist/components/atoms/SoundDemo/SoundDemo.stories.d.ts.map +1 -0
  19. package/dist/components/atoms/TextArea/TextArea.d.ts +3 -1
  20. package/dist/components/atoms/TextArea/TextArea.d.ts.map +1 -1
  21. package/dist/components/atoms/TextInput/TextInput.d.ts +6 -3
  22. package/dist/components/atoms/TextInput/TextInput.d.ts.map +1 -1
  23. package/dist/components/atoms/Toggle/Toggle.d.ts +10 -1
  24. package/dist/components/atoms/Toggle/Toggle.d.ts.map +1 -1
  25. package/dist/components/atoms/ToggleButton/ToggleButton.d.ts +3 -0
  26. package/dist/components/atoms/ToggleButton/ToggleButton.d.ts.map +1 -1
  27. package/dist/components/molecules/TimeInput/TimeInput.d.ts +2 -1
  28. package/dist/components/molecules/TimeInput/TimeInput.d.ts.map +1 -1
  29. package/dist/index.esm.js +720 -29
  30. package/dist/index.esm.js.map +1 -1
  31. package/dist/index.js +720 -29
  32. package/dist/index.js.map +1 -1
  33. package/dist/utils/soundUtils.d.ts +39 -0
  34. package/dist/utils/soundUtils.d.ts.map +1 -0
  35. package/dist/utils/useSound.d.ts +22 -0
  36. package/dist/utils/useSound.d.ts.map +1 -0
  37. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -53,6 +53,527 @@ const ThemeProvider = ({ children, defaultTheme = 'light' }) => {
53
53
 
54
54
  var styles$r = {"button":"Button-module_button__c6nkW","primary":"Button-module_primary__pMqAs","secondary":"Button-module_secondary__mBWx9","outline":"Button-module_outline__NGGGN","ghost":"Button-module_ghost__u2QBF","danger":"Button-module_danger__2ewhr","small":"Button-module_small__ZI9RX","medium":"Button-module_medium__Wnf9t","large":"Button-module_large__cQCpA","fullWidth":"Button-module_fullWidth__N8vYg","loading":"Button-module_loading__hcSI4","spinner":"Button-module_spinner__HtM96","spin":"Button-module_spin__jblrj","iconLeft":"Button-module_iconLeft__Fpz-y","iconRight":"Button-module_iconRight__kTfjS"};
55
55
 
56
+ const SOUND_PACKS = {
57
+ digital: {
58
+ click: {
59
+ tones: [
60
+ { freq: 440, duration: 0.1, type: 'sine', volume: 0.4 }
61
+ ]
62
+ },
63
+ hover: {
64
+ tones: [
65
+ { freq: 880, duration: 0.04, type: 'sine', volume: 0.3 }
66
+ ]
67
+ },
68
+ success: {
69
+ tones: [
70
+ { freq: 523.25, duration: 0.15, type: 'sine', delay: 0 },
71
+ { freq: 659.25, duration: 0.15, type: 'sine', delay: 0.1 },
72
+ { freq: 783.99, duration: 0.2, type: 'sine', delay: 0.2 }
73
+ ]
74
+ },
75
+ error: {
76
+ tones: [
77
+ { freq: 329.63, duration: 0.2, type: 'sawtooth', volume: 0.4 },
78
+ { freq: 246.94, duration: 0.25, type: 'sawtooth', volume: 0.3, delay: 0.15 }
79
+ ]
80
+ },
81
+ warning: {
82
+ tones: [
83
+ { freq: 554.37, duration: 0.15, type: 'triangle' },
84
+ { freq: 554.37, duration: 0.15, type: 'triangle', delay: 0.2 }
85
+ ]
86
+ },
87
+ toggle: {
88
+ tones: [
89
+ { freq: 493.88, duration: 0.12, type: 'sine' },
90
+ { freq: 587.33, duration: 0.1, type: 'sine', delay: 0.08 }
91
+ ]
92
+ },
93
+ type: {
94
+ tones: [
95
+ { freq: () => 800 + Math.random() * 400, duration: 0.08, type: 'square', volume: 0.5 },
96
+ { freq: 1600, duration: 0.03, type: 'sine', volume: 0.3, delay: 0.02 }
97
+ ]
98
+ },
99
+ delete: {
100
+ tones: [
101
+ { freq: 350, duration: 0.08, type: 'triangle', volume: 0.3 }
102
+ ]
103
+ },
104
+ celebration: {
105
+ tones: [
106
+ { freq: 523.25, duration: 0.2, type: 'sine', delay: 0 },
107
+ { freq: 659.25, duration: 0.2, type: 'sine', delay: 0.15 },
108
+ { freq: 783.99, duration: 0.2, type: 'sine', delay: 0.3 },
109
+ { freq: 1046.5, duration: 0.3, type: 'sine', delay: 0.45 }
110
+ ]
111
+ },
112
+ milestone: {
113
+ tones: [
114
+ { freq: 698.46, duration: 0.2, type: 'triangle' },
115
+ { freq: 880, duration: 0.25, type: 'triangle', delay: 0.15 }
116
+ ]
117
+ }
118
+ },
119
+ fantasy: {
120
+ click: {
121
+ tones: [
122
+ // Magical chime
123
+ { freq: 1174.66, duration: 0.15, type: 'triangle', volume: 0.3 }, // D6
124
+ { freq: 1567.98, duration: 0.1, type: 'sine', volume: 0.2, delay: 0.05 }, // G6
125
+ { freq: 2093, duration: 0.08, type: 'sine', volume: 0.15, delay: 0.08 } // C7
126
+ ]
127
+ },
128
+ hover: {
129
+ tones: [
130
+ // Fairy dust sprinkle
131
+ { freq: 2637.02, duration: 0.03, type: 'sine', volume: 0.2 }, // E7
132
+ { freq: 3135.96, duration: 0.025, type: 'sine', volume: 0.15, delay: 0.02 } // G7
133
+ ]
134
+ },
135
+ success: {
136
+ tones: [
137
+ // Triumphant fanfare
138
+ { freq: 523.25, duration: 0.2, type: 'triangle', delay: 0 }, // C5
139
+ { freq: 659.25, duration: 0.2, type: 'triangle', delay: 0.15 }, // E5
140
+ { freq: 783.99, duration: 0.2, type: 'triangle', delay: 0.3 }, // G5
141
+ { freq: 1046.5, duration: 0.35, type: 'sine', delay: 0.45 }, // C6
142
+ { freq: 1318.51, duration: 0.15, type: 'sine', volume: 0.3, delay: 0.6 } // E6 harmony
143
+ ]
144
+ },
145
+ error: {
146
+ tones: [
147
+ // Dark spell fail
148
+ { freq: 138.59, duration: 0.3, type: 'sawtooth', volume: 0.4 }, // C#3
149
+ { freq: 103.83, duration: 0.4, type: 'sawtooth', volume: 0.3, delay: 0.2 }, // G#2
150
+ { freq: 87.31, duration: 0.2, type: 'triangle', volume: 0.2, delay: 0.4 } // F2
151
+ ]
152
+ },
153
+ warning: {
154
+ tones: [
155
+ // Mystical alert
156
+ { freq: 466.16, duration: 0.2, type: 'triangle', volume: 0.5 }, // A#4
157
+ { freq: 622.25, duration: 0.15, type: 'sine', delay: 0.15 }, // D#5
158
+ { freq: 466.16, duration: 0.2, type: 'triangle', volume: 0.4, delay: 0.25 } // A#4
159
+ ]
160
+ },
161
+ toggle: {
162
+ tones: [
163
+ // Magic switch
164
+ { freq: 698.46, duration: 0.15, type: 'sine' }, // F5
165
+ { freq: 1046.5, duration: 0.12, type: 'triangle', delay: 0.1 }, // C6
166
+ { freq: 1396.91, duration: 0.08, type: 'sine', volume: 0.3, delay: 0.18 } // F6
167
+ ]
168
+ },
169
+ type: {
170
+ tones: [
171
+ // Quill on parchment
172
+ { freq: () => 2000 + Math.random() * 500, duration: 0.04, type: 'triangle', volume: 0.3 },
173
+ { freq: () => 3000 + Math.random() * 200, duration: 0.02, type: 'sine', volume: 0.2, delay: 0.01 }
174
+ ]
175
+ },
176
+ delete: {
177
+ tones: [
178
+ // Magic erase
179
+ { freq: 880, duration: 0.1, type: 'triangle', volume: 0.3 },
180
+ { freq: 440, duration: 0.08, type: 'sine', volume: 0.2, delay: 0.05 }
181
+ ]
182
+ },
183
+ celebration: {
184
+ tones: [
185
+ // Victory fanfare
186
+ { freq: 392, duration: 0.25, type: 'triangle', delay: 0 }, // G4
187
+ { freq: 523.25, duration: 0.25, type: 'triangle', delay: 0.2 }, // C5
188
+ { freq: 659.25, duration: 0.25, type: 'triangle', delay: 0.4 }, // E5
189
+ { freq: 783.99, duration: 0.25, type: 'sine', delay: 0.6 }, // G5
190
+ { freq: 1046.5, duration: 0.4, type: 'sine', delay: 0.8 }, // C6
191
+ { freq: 1318.51, duration: 0.2, type: 'sine', volume: 0.4, delay: 1.0 } // E6
192
+ ]
193
+ },
194
+ milestone: {
195
+ tones: [
196
+ // Achievement unlocked
197
+ { freq: 523.25, duration: 0.2, type: 'triangle' }, // C5
198
+ { freq: 783.99, duration: 0.2, type: 'triangle', delay: 0.15 }, // G5
199
+ { freq: 1046.5, duration: 0.3, type: 'sine', delay: 0.3 } // C6
200
+ ]
201
+ }
202
+ },
203
+ retro: {
204
+ click: {
205
+ tones: [
206
+ // 8-bit beep
207
+ { freq: 800, duration: 0.05, type: 'square', volume: 0.4 },
208
+ { freq: 400, duration: 0.03, type: 'square', volume: 0.3, delay: 0.03 }
209
+ ]
210
+ },
211
+ hover: {
212
+ tones: [
213
+ { freq: 1200, duration: 0.03, type: 'square', volume: 0.2 }
214
+ ]
215
+ },
216
+ success: {
217
+ tones: [
218
+ // Classic level up
219
+ { freq: 440, duration: 0.1, type: 'square', delay: 0 },
220
+ { freq: 554.37, duration: 0.1, type: 'square', delay: 0.1 },
221
+ { freq: 659.25, duration: 0.1, type: 'square', delay: 0.2 },
222
+ { freq: 880, duration: 0.2, type: 'square', delay: 0.3 }
223
+ ]
224
+ },
225
+ error: {
226
+ tones: [
227
+ // Retro fail
228
+ { freq: 200, duration: 0.3, type: 'square', volume: 0.5 },
229
+ { freq: 150, duration: 0.4, type: 'square', volume: 0.4, delay: 0.2 }
230
+ ]
231
+ },
232
+ warning: {
233
+ tones: [
234
+ { freq: 600, duration: 0.1, type: 'square' },
235
+ { freq: 600, duration: 0.1, type: 'square', delay: 0.15 },
236
+ { freq: 600, duration: 0.1, type: 'square', delay: 0.3 }
237
+ ]
238
+ },
239
+ toggle: {
240
+ tones: [
241
+ { freq: 400, duration: 0.08, type: 'square' },
242
+ { freq: 800, duration: 0.08, type: 'square', delay: 0.06 }
243
+ ]
244
+ },
245
+ type: {
246
+ tones: [
247
+ { freq: () => 500 + Math.random() * 100, duration: 0.04, type: 'square', volume: 0.3 }
248
+ ]
249
+ },
250
+ delete: {
251
+ tones: [
252
+ { freq: 300, duration: 0.06, type: 'square', volume: 0.3 }
253
+ ]
254
+ },
255
+ celebration: {
256
+ tones: [
257
+ // Victory jingle
258
+ { freq: 659.25, duration: 0.1, type: 'square', delay: 0 },
259
+ { freq: 783.99, duration: 0.1, type: 'square', delay: 0.1 },
260
+ { freq: 987.77, duration: 0.1, type: 'square', delay: 0.2 },
261
+ { freq: 1318.51, duration: 0.3, type: 'square', delay: 0.3 }
262
+ ]
263
+ },
264
+ milestone: {
265
+ tones: [
266
+ { freq: 523.25, duration: 0.15, type: 'square' },
267
+ { freq: 1046.5, duration: 0.2, type: 'square', delay: 0.1 }
268
+ ]
269
+ }
270
+ },
271
+ minimal: {
272
+ click: {
273
+ tones: [
274
+ { freq: 1000, duration: 0.03, type: 'sine', volume: 0.3 }
275
+ ]
276
+ },
277
+ hover: {
278
+ tones: [
279
+ { freq: 1500, duration: 0.02, type: 'sine', volume: 0.15 }
280
+ ]
281
+ },
282
+ success: {
283
+ tones: [
284
+ { freq: 800, duration: 0.15, type: 'sine', volume: 0.3 },
285
+ { freq: 1200, duration: 0.1, type: 'sine', volume: 0.2, delay: 0.1 }
286
+ ]
287
+ },
288
+ error: {
289
+ tones: [
290
+ { freq: 300, duration: 0.2, type: 'sine', volume: 0.3 }
291
+ ]
292
+ },
293
+ warning: {
294
+ tones: [
295
+ { freq: 600, duration: 0.15, type: 'sine', volume: 0.35 }
296
+ ]
297
+ },
298
+ toggle: {
299
+ tones: [
300
+ { freq: 700, duration: 0.08, type: 'sine', volume: 0.3 }
301
+ ]
302
+ },
303
+ type: {
304
+ tones: [
305
+ { freq: 1800, duration: 0.02, type: 'sine', volume: 0.2 }
306
+ ]
307
+ },
308
+ delete: {
309
+ tones: [
310
+ { freq: 400, duration: 0.05, type: 'sine', volume: 0.25 }
311
+ ]
312
+ },
313
+ celebration: {
314
+ tones: [
315
+ { freq: 800, duration: 0.2, type: 'sine', volume: 0.3 },
316
+ { freq: 1200, duration: 0.2, type: 'sine', volume: 0.25, delay: 0.15 }
317
+ ]
318
+ },
319
+ milestone: {
320
+ tones: [
321
+ { freq: 1000, duration: 0.2, type: 'sine', volume: 0.3 }
322
+ ]
323
+ }
324
+ },
325
+ mechanical: {
326
+ click: {
327
+ tones: [
328
+ // Mechanical keyboard click
329
+ { freq: 4000, duration: 0.01, type: 'square', volume: 0.3 },
330
+ { freq: 800, duration: 0.04, type: 'sawtooth', volume: 0.4, delay: 0.01 },
331
+ { freq: 200, duration: 0.03, type: 'triangle', volume: 0.2, delay: 0.02 }
332
+ ]
333
+ },
334
+ hover: {
335
+ tones: [
336
+ { freq: 3000, duration: 0.02, type: 'sawtooth', volume: 0.1 }
337
+ ]
338
+ },
339
+ success: {
340
+ tones: [
341
+ // Gear engagement
342
+ { freq: 200, duration: 0.05, type: 'sawtooth', delay: 0 },
343
+ { freq: 400, duration: 0.05, type: 'sawtooth', delay: 0.05 },
344
+ { freq: 600, duration: 0.05, type: 'sawtooth', delay: 0.1 },
345
+ { freq: 800, duration: 0.15, type: 'triangle', delay: 0.15 }
346
+ ]
347
+ },
348
+ error: {
349
+ tones: [
350
+ // Grinding gears
351
+ { freq: 150, duration: 0.2, type: 'sawtooth', volume: 0.5 },
352
+ { freq: 100, duration: 0.15, type: 'square', volume: 0.3, delay: 0.1 },
353
+ { freq: 80, duration: 0.1, type: 'sawtooth', volume: 0.2, delay: 0.2 }
354
+ ]
355
+ },
356
+ warning: {
357
+ tones: [
358
+ // Steam whistle
359
+ { freq: 800, duration: 0.3, type: 'sawtooth', volume: 0.4 },
360
+ { freq: 1200, duration: 0.2, type: 'triangle', volume: 0.3, delay: 0 }
361
+ ]
362
+ },
363
+ toggle: {
364
+ tones: [
365
+ // Switch flip
366
+ { freq: 600, duration: 0.02, type: 'square', volume: 0.5 },
367
+ { freq: 300, duration: 0.05, type: 'triangle', delay: 0.02 },
368
+ { freq: 150, duration: 0.03, type: 'sawtooth', volume: 0.3, delay: 0.05 }
369
+ ]
370
+ },
371
+ type: {
372
+ tones: [
373
+ // Typewriter key
374
+ { freq: () => 3000 + Math.random() * 1000, duration: 0.01, type: 'square', volume: 0.4 },
375
+ { freq: () => 400 + Math.random() * 200, duration: 0.03, type: 'sawtooth', volume: 0.3, delay: 0.01 }
376
+ ]
377
+ },
378
+ delete: {
379
+ tones: [
380
+ { freq: 250, duration: 0.08, type: 'sawtooth', volume: 0.35 }
381
+ ]
382
+ },
383
+ celebration: {
384
+ tones: [
385
+ // Machine startup
386
+ { freq: 100, duration: 0.1, type: 'sawtooth', delay: 0 },
387
+ { freq: 200, duration: 0.1, type: 'sawtooth', delay: 0.1 },
388
+ { freq: 400, duration: 0.1, type: 'sawtooth', delay: 0.2 },
389
+ { freq: 800, duration: 0.1, type: 'triangle', delay: 0.3 },
390
+ { freq: 1200, duration: 0.2, type: 'sine', delay: 0.4 }
391
+ ]
392
+ },
393
+ milestone: {
394
+ tones: [
395
+ // Pneumatic hiss
396
+ { freq: 3000, duration: 0.05, type: 'sawtooth', volume: 0.3 },
397
+ { freq: 1000, duration: 0.15, type: 'triangle', delay: 0.05 },
398
+ { freq: 500, duration: 0.1, type: 'sine', delay: 0.15 }
399
+ ]
400
+ }
401
+ }
402
+ };
403
+ class SoundManager {
404
+ constructor() {
405
+ this.audioContext = null;
406
+ this.config = {
407
+ enabled: false,
408
+ volume: 0.5,
409
+ soundPack: 'digital'
410
+ };
411
+ this.init();
412
+ }
413
+ static getInstance() {
414
+ if (!SoundManager.instance) {
415
+ SoundManager.instance = new SoundManager();
416
+ }
417
+ return SoundManager.instance;
418
+ }
419
+ init() {
420
+ try {
421
+ // AudioContext will be created on first user interaction
422
+ this.audioContext = null;
423
+ }
424
+ catch (error) {
425
+ console.warn('Audio not supported:', error);
426
+ this.config.enabled = false;
427
+ }
428
+ }
429
+ ensureAudioContext() {
430
+ if (!this.audioContext && this.config.enabled) {
431
+ try {
432
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
433
+ }
434
+ catch (error) {
435
+ console.warn('Could not create audio context:', error);
436
+ this.config.enabled = false;
437
+ }
438
+ }
439
+ }
440
+ playTone(frequency, duration, type = 'sine', volume, delay = 0) {
441
+ if (!this.config.enabled)
442
+ return;
443
+ this.ensureAudioContext();
444
+ if (!this.audioContext)
445
+ return;
446
+ const finalVolume = (volume ?? this.config.volume ?? 0.5) * 0.2; // Scale down for comfort
447
+ try {
448
+ const oscillator = this.audioContext.createOscillator();
449
+ const gainNode = this.audioContext.createGain();
450
+ oscillator.connect(gainNode);
451
+ gainNode.connect(this.audioContext.destination);
452
+ oscillator.frequency.value = frequency;
453
+ oscillator.type = type;
454
+ const startTime = this.audioContext.currentTime + delay;
455
+ gainNode.gain.setValueAtTime(0, startTime);
456
+ gainNode.gain.linearRampToValueAtTime(finalVolume, startTime + 0.01);
457
+ gainNode.gain.exponentialRampToValueAtTime(0.001, startTime + duration);
458
+ oscillator.start(startTime);
459
+ oscillator.stop(startTime + duration);
460
+ }
461
+ catch (error) {
462
+ console.debug('Could not play sound:', error);
463
+ }
464
+ }
465
+ playFromDefinition(definition) {
466
+ definition.tones.forEach(tone => {
467
+ const frequency = typeof tone.freq === 'function' ? tone.freq() : tone.freq;
468
+ this.playTone(frequency, tone.duration, tone.type, tone.volume, tone.delay || 0);
469
+ });
470
+ }
471
+ play(soundType) {
472
+ if (!this.config.enabled)
473
+ return;
474
+ const pack = SOUND_PACKS[this.config.soundPack || 'digital'];
475
+ const soundDef = pack[soundType];
476
+ if (soundDef) {
477
+ this.playFromDefinition(soundDef);
478
+ }
479
+ else {
480
+ // Fallback to digital pack for unknown sounds
481
+ const digitalSound = SOUND_PACKS.digital[soundType];
482
+ if (digitalSound) {
483
+ this.playFromDefinition(digitalSound);
484
+ }
485
+ }
486
+ }
487
+ // Special effect sounds
488
+ celebration() {
489
+ if (!this.config.enabled)
490
+ return;
491
+ const pack = SOUND_PACKS[this.config.soundPack || 'digital'];
492
+ this.playFromDefinition(pack.celebration);
493
+ }
494
+ milestone() {
495
+ if (!this.config.enabled)
496
+ return;
497
+ const pack = SOUND_PACKS[this.config.soundPack || 'digital'];
498
+ this.playFromDefinition(pack.milestone);
499
+ }
500
+ configure(config) {
501
+ this.config = { ...this.config, ...config };
502
+ }
503
+ getConfig() {
504
+ return this.config;
505
+ }
506
+ setVolume(volume) {
507
+ this.config.volume = Math.max(0, Math.min(1, volume));
508
+ }
509
+ setEnabled(enabled) {
510
+ this.config.enabled = enabled;
511
+ if (enabled) {
512
+ this.ensureAudioContext();
513
+ }
514
+ }
515
+ setSoundPack(pack) {
516
+ this.config.soundPack = pack;
517
+ }
518
+ getSoundPack() {
519
+ return this.config.soundPack || 'digital';
520
+ }
521
+ isEnabled() {
522
+ return this.config.enabled || false;
523
+ }
524
+ getAvailablePacks() {
525
+ return ['digital', 'fantasy', 'retro', 'minimal', 'mechanical'];
526
+ }
527
+ }
528
+ const soundManager = SoundManager.getInstance();
529
+
530
+ function useSound(options) {
531
+ const lastPlayedRef = React.useRef({});
532
+ const debounceMs = options?.debounceMs || 50;
533
+ React.useEffect(() => {
534
+ if (options?.enabled !== undefined) {
535
+ soundManager.setEnabled(options.enabled);
536
+ }
537
+ if (options?.volume !== undefined) {
538
+ soundManager.setVolume(options.volume);
539
+ }
540
+ }, [options?.enabled, options?.volume]);
541
+ const playSound = React.useCallback((soundType) => {
542
+ const now = Date.now();
543
+ const lastPlayed = lastPlayedRef.current[soundType] || 0;
544
+ if (now - lastPlayed > debounceMs) {
545
+ soundManager.play(soundType);
546
+ lastPlayedRef.current[soundType] = now;
547
+ }
548
+ }, [debounceMs]);
549
+ const isEnabled = React.useCallback(() => soundManager.isEnabled(), []);
550
+ const setEnabled = React.useCallback((enabled) => soundManager.setEnabled(enabled), []);
551
+ const setVolume = React.useCallback((volume) => soundManager.setVolume(volume), []);
552
+ return {
553
+ playSound,
554
+ isEnabled,
555
+ setEnabled,
556
+ setVolume
557
+ };
558
+ }
559
+ function useComponentSound(config, options) {
560
+ const { playSound } = useSound(options);
561
+ const handlers = {};
562
+ if (config?.onClick) {
563
+ handlers.onClick = () => {
564
+ const sound = typeof config.onClick === 'string' ? config.onClick : 'click';
565
+ playSound(sound);
566
+ };
567
+ }
568
+ if (config?.onHover) {
569
+ handlers.onMouseEnter = () => {
570
+ const sound = typeof config.onHover === 'string' ? config.onHover : 'hover';
571
+ playSound(sound);
572
+ };
573
+ }
574
+ return { handlers, playSound };
575
+ }
576
+
56
577
  /**
57
578
  * Button Component
58
579
  *
@@ -92,7 +613,8 @@ var styles$r = {"button":"Button-module_button__c6nkW","primary":"Button-module_
92
613
  * @param {ButtonProps} props - The props for the Button component
93
614
  * @returns {JSX.Element} The rendered Button component
94
615
  */
95
- const Button = ({ variant = 'primary', size = 'medium', fullWidth = false, loading = false, iconLeft, iconRight, children, className = '', disabled, motionProps, ...rest }) => {
616
+ const Button = ({ variant = 'primary', size = 'medium', fullWidth = false, loading = false, iconLeft, iconRight, children, className = '', disabled, motionProps, soundConfig, onClick, onMouseEnter, onFocus, ...rest }) => {
617
+ const { handlers } = useComponentSound(soundConfig);
96
618
  const buttonClasses = [
97
619
  styles$r.button,
98
620
  styles$r[variant],
@@ -101,7 +623,15 @@ const Button = ({ variant = 'primary', size = 'medium', fullWidth = false, loadi
101
623
  loading && styles$r.loading,
102
624
  className
103
625
  ].filter(Boolean).join(' ');
104
- return (jsxRuntime.jsxs(framerMotion.motion.button, { className: buttonClasses, disabled: disabled || loading, whileHover: { scale: disabled || loading ? 1 : 1.02 }, whileTap: { scale: disabled || loading ? 1 : 0.98 }, transition: { type: "spring", stiffness: 400, damping: 17 }, ...motionProps, ...rest, children: [loading && jsxRuntime.jsx("span", { className: styles$r.spinner }), iconLeft && jsxRuntime.jsx("span", { className: styles$r.iconLeft, children: iconLeft }), children, iconRight && jsxRuntime.jsx("span", { className: styles$r.iconRight, children: iconRight })] }));
626
+ const handleClick = (e) => {
627
+ handlers.onClick?.();
628
+ onClick?.(e);
629
+ };
630
+ const handleMouseEnter = (e) => {
631
+ handlers.onMouseEnter?.();
632
+ onMouseEnter?.(e);
633
+ };
634
+ return (jsxRuntime.jsxs(framerMotion.motion.button, { className: buttonClasses, disabled: disabled || loading, whileHover: { scale: disabled || loading ? 1 : 1.02 }, whileTap: { scale: disabled || loading ? 1 : 0.98 }, transition: { type: "spring", stiffness: 400, damping: 17 }, onClick: handleClick, onMouseEnter: handleMouseEnter, onFocus: onFocus, ...motionProps, ...rest, children: [loading && jsxRuntime.jsx("span", { className: styles$r.spinner }), iconLeft && jsxRuntime.jsx("span", { className: styles$r.iconLeft, children: iconLeft }), children, iconRight && jsxRuntime.jsx("span", { className: styles$r.iconRight, children: iconRight })] }));
105
635
  };
106
636
 
107
637
  var styles$q = {"card":"Card-module_card__r2DB2","hoverable":"Card-module_hoverable__X3OpS","elevated":"Card-module_elevated__hGV6-","outlined":"Card-module_outlined__ngRag","flat":"Card-module_flat__xy-xt","glass":"Card-module_glass__Sv-Vs","imageContainer":"Card-module_imageContainer__L4ma6","image":"Card-module_image__bQBt6","header":"Card-module_header__0dtj3","headerContent":"Card-module_headerContent__W7-jD","expandButton":"Card-module_expandButton__I7f49","expandIcon":"Card-module_expandIcon__Lu-OY","expandableContent":"Card-module_expandableContent__BFgO5","expandable":"Card-module_expandable__GMXzo","body":"Card-module_body__K7eL3","footer":"Card-module_footer__L5wO-","title":"Card-module_title__pW9g8","subtitle":"Card-module_subtitle__gejH4","clickable":"Card-module_clickable__Y6fm8","padding":"Card-module_padding__wtyDo","noPadding":"Card-module_noPadding__r5Qq0","loading":"Card-module_loading__S4Wng","loadingShimmer":"Card-module_loadingShimmer__Q1Osr","loadingPulse":"Card-module_loadingPulse__bXQmC"};
@@ -227,14 +757,21 @@ var styles$p = {"checkboxLabel":"Checkbox-module_checkboxLabel__4tBVg","checkbox
227
757
  * disabled={true}
228
758
  * />
229
759
  */
230
- const Checkbox = ({ checked, onChange, label, disabled = false, indeterminate = false, id, name, value }) => {
760
+ const Checkbox = ({ checked, onChange, label, disabled = false, indeterminate = false, id, name, value, soundConfig }) => {
231
761
  const checkboxRef = React.useRef(null);
762
+ const { playSound } = useComponentSound(soundConfig);
232
763
  React.useEffect(() => {
233
764
  if (checkboxRef.current) {
234
765
  checkboxRef.current.indeterminate = indeterminate;
235
766
  }
236
767
  }, [indeterminate]);
237
- return (jsxRuntime.jsxs("label", { className: styles$p.checkboxLabel, children: [jsxRuntime.jsx("input", { ref: checkboxRef, type: "checkbox", checked: checked, onChange: (e) => onChange(e.target.checked), className: styles$p.checkbox, disabled: disabled, id: id, name: name, value: value, "aria-checked": indeterminate ? 'mixed' : checked }), label && jsxRuntime.jsx("span", { className: styles$p.checkboxText, children: label })] }));
768
+ return (jsxRuntime.jsxs("label", { className: styles$p.checkboxLabel, children: [jsxRuntime.jsx("input", { ref: checkboxRef, type: "checkbox", checked: checked, onChange: (e) => {
769
+ const isChecked = e.target.checked;
770
+ onChange(isChecked);
771
+ if (soundConfig?.onClick !== false) {
772
+ playSound('toggle');
773
+ }
774
+ }, className: styles$p.checkbox, disabled: disabled, id: id, name: name, value: value, "aria-checked": indeterminate ? 'mixed' : checked }), label && jsxRuntime.jsx("span", { className: styles$p.checkboxText, children: label })] }));
238
775
  };
239
776
 
240
777
  var DefaultContext = {
@@ -408,8 +945,9 @@ var styles$o = {"dateInput":"DateInput-module_dateInput__54VPD","label":"DateInp
408
945
  * onBlur={() => validateDate(eventDate)}
409
946
  * />
410
947
  */
411
- function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus, onBlur, error = false, success = false, loading = false, disabled = false }) {
948
+ function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus, onBlur, error = false, success = false, loading = false, disabled = false, soundConfig }) {
412
949
  const hiddenDateInputRef = React.useRef(null);
950
+ const { handlers, playSound } = useComponentSound(soundConfig);
413
951
  const handleTextChange = (textValue) => {
414
952
  // Auto-format as user types
415
953
  let formatted = textValue.replace(/[^\d/]/g, '');
@@ -434,6 +972,7 @@ function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus
434
972
  }
435
973
  };
436
974
  const handleCalendarClick = () => {
975
+ playSound('click');
437
976
  // Set the hidden input to current value for calendar
438
977
  if (hiddenDateInputRef.current) {
439
978
  // If value is already ISO format, use it directly
@@ -467,7 +1006,7 @@ function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus
467
1006
  classes.push(styles$o.loading);
468
1007
  return classes.join(' ');
469
1008
  };
470
- return (jsxRuntime.jsxs("div", { className: getClassName(), children: [jsxRuntime.jsx("label", { className: styles$o.label, children: label }), jsxRuntime.jsxs("div", { className: styles$o.inputWrapper, children: [jsxRuntime.jsx("input", { type: "text", value: value.includes('-') ? formatDateToEuropean(value) : value, onChange: (e) => handleTextChange(e.target.value), onFocus: onFocus, onBlur: onBlur, placeholder: placeholder, className: styles$o.textInput, disabled: disabled || loading }), jsxRuntime.jsx("button", { type: "button", onClick: handleCalendarClick, className: styles$o.calendarButton, title: "Select date from calendar", disabled: disabled || loading, children: jsxRuntime.jsx(FiCalendar, {}) }), jsxRuntime.jsx("input", { ref: hiddenDateInputRef, type: "date", onChange: handleCalendarChange, className: styles$o.hiddenDateInput, tabIndex: -1, disabled: disabled || loading })] })] }));
1009
+ return (jsxRuntime.jsxs("div", { className: getClassName(), children: [jsxRuntime.jsx("label", { className: styles$o.label, children: label }), jsxRuntime.jsxs("div", { className: styles$o.inputWrapper, children: [jsxRuntime.jsx("input", { type: "text", value: value.includes('-') ? formatDateToEuropean(value) : value, onChange: (e) => handleTextChange(e.target.value), onFocus: onFocus, onBlur: onBlur, placeholder: placeholder, className: styles$o.textInput, disabled: disabled || loading, ...handlers }), jsxRuntime.jsx("button", { type: "button", onClick: handleCalendarClick, className: styles$o.calendarButton, title: "Select date from calendar", disabled: disabled || loading, children: jsxRuntime.jsx(FiCalendar, {}) }), jsxRuntime.jsx("input", { ref: hiddenDateInputRef, type: "date", onChange: handleCalendarChange, className: styles$o.hiddenDateInput, tabIndex: -1, disabled: disabled || loading })] })] }));
471
1010
  }
472
1011
 
473
1012
  var styles$n = {"searchableDropdown":"SearchableDropdown-module_searchableDropdown__S2Nh5","dropdownTrigger":"SearchableDropdown-module_dropdownTrigger__dihdr","open":"SearchableDropdown-module_open__P7mRt","dropdownValue":"SearchableDropdown-module_dropdownValue__ydrc2","placeholder":"SearchableDropdown-module_placeholder__BwM2W","dropdownArrow":"SearchableDropdown-module_dropdownArrow__yd5fp","dropdownMenu":"SearchableDropdown-module_dropdownMenu__2Z5cc","dropdownSearch":"SearchableDropdown-module_dropdownSearch__NRk7j","searchInput":"SearchableDropdown-module_searchInput__VS2Hw","searchIcon":"SearchableDropdown-module_searchIcon__2vKFF","dropdownOptions":"SearchableDropdown-module_dropdownOptions__6YXqF","dropdownOption":"SearchableDropdown-module_dropdownOption__YwDr-","selected":"SearchableDropdown-module_selected__31JeB","highlighted":"SearchableDropdown-module_highlighted__P0bBq","checkIcon":"SearchableDropdown-module_checkIcon__YxowK","dropdownNoResults":"SearchableDropdown-module_dropdownNoResults__WW-Da","loading":"SearchableDropdown-module_loading__xlYf0"};
@@ -626,7 +1165,8 @@ var styles$m = {"selectInput":"SelectInput-module_selectInput__s6zEg","selectWra
626
1165
  * ]}
627
1166
  * />
628
1167
  */
629
- function SelectInput({ label, value, onChange, options, placeholder = "Select...", disabled = false, error = false, success = false, loading = false, required = false }) {
1168
+ function SelectInput({ label, value, onChange, options, placeholder = "Select...", disabled = false, error = false, success = false, loading = false, required = false, soundConfig }) {
1169
+ const { handlers, playSound } = useComponentSound(soundConfig);
630
1170
  const getClassName = () => {
631
1171
  const classes = [styles$m.selectInput];
632
1172
  if (error)
@@ -637,7 +1177,10 @@ function SelectInput({ label, value, onChange, options, placeholder = "Select...
637
1177
  classes.push(styles$m.loading);
638
1178
  return classes.join(' ');
639
1179
  };
640
- return (jsxRuntime.jsxs("div", { className: getClassName(), children: [jsxRuntime.jsxs("label", { children: [label, required && jsxRuntime.jsx("span", { style: { color: 'var(--color-error)' }, children: " *" })] }), jsxRuntime.jsxs("div", { className: styles$m.selectWrapper, children: [jsxRuntime.jsxs("select", { value: value, onChange: e => onChange(e.target.value), disabled: disabled || loading, required: required, children: [jsxRuntime.jsx("option", { value: "", children: placeholder }), options.map(opt => {
1180
+ return (jsxRuntime.jsxs("div", { className: getClassName(), children: [jsxRuntime.jsxs("label", { children: [label, required && jsxRuntime.jsx("span", { style: { color: 'var(--color-error)' }, children: " *" })] }), jsxRuntime.jsxs("div", { className: styles$m.selectWrapper, children: [jsxRuntime.jsxs("select", { value: value, onChange: e => {
1181
+ playSound('click');
1182
+ onChange(e.target.value);
1183
+ }, disabled: disabled || loading, required: required, ...handlers, children: [jsxRuntime.jsx("option", { value: "", children: placeholder }), options.map(opt => {
641
1184
  const optionValue = typeof opt === 'string' ? opt : opt.value;
642
1185
  const optionLabel = typeof opt === 'string' ? opt : opt.label;
643
1186
  return (jsxRuntime.jsx("option", { value: optionValue, children: optionLabel }, optionValue));
@@ -676,7 +1219,7 @@ var styles$l = {"textareaContainer":"TextArea-module_textareaContainer__AquFj","
676
1219
  * required
677
1220
  * />
678
1221
  */
679
- function TextArea({ label, value, onChange, rows = 5, placeholder = "", required = false, maxLength, disabled = false, error = false, success = false, loading = false, focusMode = false, compact = false }) {
1222
+ function TextArea({ label, value, onChange, rows = 5, placeholder = "", required = false, maxLength, disabled = false, error = false, success = false, loading = false, focusMode = false, compact = false, className = "" }) {
680
1223
  const textareaId = `textarea-${Math.random().toString(36).substr(2, 9)}`;
681
1224
  const getContainerClassName = () => {
682
1225
  const classes = [styles$l.textareaContainer];
@@ -690,6 +1233,8 @@ function TextArea({ label, value, onChange, rows = 5, placeholder = "", required
690
1233
  classes.push(styles$l.focusMode);
691
1234
  if (compact)
692
1235
  classes.push(styles$l.compact);
1236
+ if (className)
1237
+ classes.push(className);
693
1238
  return classes.join(' ');
694
1239
  };
695
1240
  const getCharCountClassName = () => {
@@ -740,8 +1285,10 @@ var styles$k = {"textInput":"TextInput-module_textInput__b2LVM","required":"Text
740
1285
  * required
741
1286
  * />
742
1287
  */
743
- function TextInput({ label, value, onChange, type = "text", onFocus, onBlur, placeholder, error, required, disabled = false, success = false, loading = false, icon, actionButton, maxLength, autoComplete }) {
1288
+ function TextInput({ label, value, onChange, type = "text", onBlur, placeholder, error, required, disabled = false, success = false, loading = false, icon, actionButton, maxLength, autoComplete, soundConfig, enableTypingSounds = false }) {
744
1289
  const inputId = `input-${Math.random().toString(36).substr(2, 9)}`;
1290
+ const { handlers, playSound } = useComponentSound(soundConfig);
1291
+ const prevValueRef = React.useRef(value);
745
1292
  const getContainerClassName = () => {
746
1293
  const classes = [styles$k.textInput];
747
1294
  if (success)
@@ -754,7 +1301,29 @@ function TextInput({ label, value, onChange, type = "text", onFocus, onBlur, pla
754
1301
  classes.push(styles$k.withAction);
755
1302
  return classes.join(' ');
756
1303
  };
757
- return (jsxRuntime.jsxs("div", { className: getContainerClassName(), children: [jsxRuntime.jsxs("label", { htmlFor: inputId, children: [label, required && jsxRuntime.jsx("span", { className: styles$k.required, children: "*" })] }), jsxRuntime.jsxs("div", { style: { position: 'relative' }, children: [icon && jsxRuntime.jsx("div", { className: styles$k.inputIcon, children: icon }), jsxRuntime.jsx("input", { id: inputId, type: type, value: value, onChange: (e) => onChange(e.target.value), onFocus: onFocus, onBlur: onBlur, placeholder: placeholder, className: error ? styles$k.inputError : '', "aria-invalid": !!error, "aria-describedby": error ? `${inputId}-error` : undefined, disabled: disabled || loading, maxLength: maxLength, autoComplete: autoComplete }), actionButton && (jsxRuntime.jsx("button", { type: "button", className: styles$k.actionButton, onClick: actionButton.onClick, disabled: disabled || loading, children: actionButton.label }))] }), error && (jsxRuntime.jsx("span", { id: `${inputId}-error`, className: styles$k.errorMessage, children: error }))] }));
1304
+ React.useEffect(() => {
1305
+ prevValueRef.current = value;
1306
+ }, [value]);
1307
+ return (jsxRuntime.jsxs("div", { className: getContainerClassName(), children: [jsxRuntime.jsxs("label", { htmlFor: inputId, children: [label, required && jsxRuntime.jsx("span", { className: styles$k.required, children: "*" })] }), jsxRuntime.jsxs("div", { style: { position: 'relative' }, children: [icon && jsxRuntime.jsx("div", { className: styles$k.inputIcon, children: icon }), jsxRuntime.jsx("input", { id: inputId, type: type, value: value, onChange: (e) => {
1308
+ const newValue = e.target.value;
1309
+ const oldValue = prevValueRef.current;
1310
+ onChange(newValue);
1311
+ // Play typing sounds if enabled
1312
+ if (enableTypingSounds || soundConfig?.onClick) {
1313
+ if (newValue.length > oldValue.length) {
1314
+ playSound('type');
1315
+ }
1316
+ else if (newValue.length < oldValue.length) {
1317
+ playSound('delete');
1318
+ }
1319
+ }
1320
+ if (error && soundConfig?.onError) {
1321
+ playSound(typeof soundConfig.onError === 'string' ? soundConfig.onError : 'error');
1322
+ }
1323
+ }, onBlur: onBlur, placeholder: placeholder, className: error ? styles$k.inputError : '', "aria-invalid": !!error, "aria-describedby": error ? `${inputId}-error` : undefined, disabled: disabled || loading, maxLength: maxLength, autoComplete: autoComplete }), actionButton && (jsxRuntime.jsx("button", { type: "button", className: styles$k.actionButton, onClick: () => {
1324
+ handlers.onClick?.();
1325
+ actionButton.onClick();
1326
+ }, disabled: disabled || loading, children: actionButton.label }))] }), error && (jsxRuntime.jsx("span", { id: `${inputId}-error`, className: styles$k.errorMessage, children: error }))] }));
758
1327
  }
759
1328
 
760
1329
  var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggleButton":"Toggle-module_toggleButton__WUUf-","active":"Toggle-module_active__fX6Io"};
@@ -769,12 +1338,14 @@ var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggle
769
1338
  * Supports both text labels and icons for each option.
770
1339
  *
771
1340
  * @example
772
- * // Basic toggle with labels
1341
+ * // Basic toggle with labels and sound theme
773
1342
  * <Toggle
774
1343
  * isOn={darkMode}
775
1344
  * onToggle={setDarkMode}
776
1345
  * leftLabel="Light"
777
1346
  * rightLabel="Dark"
1347
+ * soundTheme="cozy"
1348
+ * enableCelebration={true}
778
1349
  * />
779
1350
  *
780
1351
  * @example
@@ -801,7 +1372,14 @@ var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggle
801
1372
  * @returns {JSX.Element} The rendered Toggle component
802
1373
  */
803
1374
  function Toggle(props) {
804
- const { isOn, onToggle, leftLabel, rightLabel, leftIcon, rightIcon, className, style } = props;
1375
+ const { isOn, onToggle, leftLabel, rightLabel, leftIcon, rightIcon, className, style, soundConfig, soundTheme, enableCelebration = false } = props;
1376
+ const leftButtonRef = React.useRef(null);
1377
+ const rightButtonRef = React.useRef(null);
1378
+ const { handlers, playSound, triggerCelebration } = useComponentSound({
1379
+ ...soundConfig,
1380
+ onToggle: soundConfig?.onToggle ?? 'toggle',
1381
+ onHover: soundConfig?.onHover ?? 'hover'
1382
+ }, { });
805
1383
  // Ensure content stays centered by merging styles
806
1384
  const buttonStyle = {
807
1385
  display: 'flex',
@@ -809,7 +1387,39 @@ function Toggle(props) {
809
1387
  justifyContent: 'center',
810
1388
  ...style
811
1389
  };
812
- return (jsxRuntime.jsxs("div", { className: `${styles$j.toggleContainer} ${className || ''}`, children: [jsxRuntime.jsxs("button", { className: `${styles$j.toggleButton} ${!isOn ? styles$j.active : ''}`, onClick: () => onToggle(false), style: buttonStyle, children: [leftIcon, leftLabel] }), jsxRuntime.jsxs("button", { className: `${styles$j.toggleButton} ${isOn ? styles$j.active : ''}`, onClick: () => onToggle(true), style: buttonStyle, children: [rightIcon, rightLabel] })] }));
1390
+ return (jsxRuntime.jsxs("div", { className: `${styles$j.toggleContainer} ${className || ''}`, children: [jsxRuntime.jsxs(framerMotion.motion.button, { ref: leftButtonRef, className: `${styles$j.toggleButton} ${!isOn ? styles$j.active : ''}`, whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, transition: { type: "spring", stiffness: 400, damping: 17 }, onClick: () => {
1391
+ const element = leftButtonRef.current;
1392
+ if (!isOn) {
1393
+ // Already on left, celebration!
1394
+ if (enableCelebration) {
1395
+ triggerCelebration(element || undefined);
1396
+ }
1397
+ else {
1398
+ playSound('boop', element || undefined);
1399
+ }
1400
+ }
1401
+ else {
1402
+ // Switching to left
1403
+ playSound('toggle', element || undefined);
1404
+ }
1405
+ onToggle(false);
1406
+ }, onMouseEnter: () => handlers.onMouseEnter?.(leftButtonRef.current || undefined), style: buttonStyle, children: [jsxRuntime.jsx(framerMotion.motion.div, { animate: { scale: !isOn ? 1.1 : 1, rotate: !isOn ? [0, -5, 5, 0] : 0 }, transition: { duration: 0.3 }, children: leftIcon }), leftLabel] }), jsxRuntime.jsxs(framerMotion.motion.button, { ref: rightButtonRef, className: `${styles$j.toggleButton} ${isOn ? styles$j.active : ''}`, whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, transition: { type: "spring", stiffness: 400, damping: 17 }, onClick: () => {
1407
+ const element = rightButtonRef.current;
1408
+ if (isOn) {
1409
+ // Already on right, celebration!
1410
+ if (enableCelebration) {
1411
+ triggerCelebration(element || undefined);
1412
+ }
1413
+ else {
1414
+ playSound('ding', element || undefined);
1415
+ }
1416
+ }
1417
+ else {
1418
+ // Switching to right
1419
+ playSound('success', element || undefined);
1420
+ }
1421
+ onToggle(true);
1422
+ }, onMouseEnter: () => handlers.onMouseEnter?.(rightButtonRef.current || undefined), style: buttonStyle, children: [jsxRuntime.jsx(framerMotion.motion.div, { animate: { scale: isOn ? 1.1 : 1, rotate: isOn ? [0, 5, -5, 0] : 0 }, transition: { duration: 0.3 }, children: rightIcon }), rightLabel] })] }));
813
1423
  }
814
1424
 
815
1425
  var styles$i = {"container":"NumberStepper-module_container__WSGlU","header":"NumberStepper-module_header__qXI1Y","icon":"NumberStepper-module_icon__vHgsw","label":"NumberStepper-module_label__AYr3g","stepper":"NumberStepper-module_stepper__oQhTp","disabled":"NumberStepper-module_disabled__kGB-g","button":"NumberStepper-module_button__YcjRt","buttonIcon":"NumberStepper-module_buttonIcon__odXec","valueContainer":"NumberStepper-module_valueContainer__87w2D","valueWrapper":"NumberStepper-module_valueWrapper__TH65N","value":"NumberStepper-module_value__BxJeD","limits":"NumberStepper-module_limits__-UrRE","limit":"NumberStepper-module_limit__7nbIP","small":"NumberStepper-module_small__P-k96","large":"NumberStepper-module_large__Lz6lk","outlined":"NumberStepper-module_outlined__CIXv7","filled":"NumberStepper-module_filled__IxOg-","minimal":"NumberStepper-module_minimal__y47-W","custom":"NumberStepper-module_custom__XGSVg","vertical":"NumberStepper-module_vertical__nBcL7","pulse":"NumberStepper-module_pulse__51oUo"};
@@ -843,10 +1453,76 @@ var styles$i = {"container":"NumberStepper-module_container__WSGlU","header":"Nu
843
1453
  * icon="📦"
844
1454
  * />
845
1455
  *
1456
+ * @example
1457
+ * // With custom styles
1458
+ * <NumberStepper
1459
+ * value={volume}
1460
+ * onChange={setVolume}
1461
+ * min={0}
1462
+ * max={100}
1463
+ * label="Volume"
1464
+ * icon="🔊"
1465
+ * customStyles={{
1466
+ * container: {
1467
+ * background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
1468
+ * padding: '20px',
1469
+ * borderRadius: '16px',
1470
+ * },
1471
+ * label: { color: 'white', fontWeight: 'bold' },
1472
+ * button: {
1473
+ * background: 'rgba(255,255,255,0.2)',
1474
+ * color: 'white',
1475
+ * },
1476
+ * buttonHover: {
1477
+ * background: 'rgba(255,255,255,0.3)',
1478
+ * },
1479
+ * value: {
1480
+ * color: 'white',
1481
+ * fontSize: '24px',
1482
+ * fontWeight: 'bold',
1483
+ * },
1484
+ * }}
1485
+ * />
1486
+ *
1487
+ * @example
1488
+ * // Custom variant with horizontal layout
1489
+ * <NumberStepper
1490
+ * value={discount}
1491
+ * onChange={setDiscount}
1492
+ * min={0}
1493
+ * max={100}
1494
+ * step={5}
1495
+ * label="Discount %"
1496
+ * icon="🏷️"
1497
+ * variant="custom"
1498
+ * customStyles={{
1499
+ * container: {
1500
+ * display: 'flex',
1501
+ * alignItems: 'center',
1502
+ * gap: '16px',
1503
+ * },
1504
+ * header: { flex: 1, marginBottom: 0 },
1505
+ * }}
1506
+ * />
1507
+ *
1508
+ * @example
1509
+ * // With custom buttons
1510
+ * <NumberStepper
1511
+ * value={rating}
1512
+ * onChange={setRating}
1513
+ * min={1}
1514
+ * max={5}
1515
+ * customButtons={{
1516
+ * decrement: <span>👎</span>,
1517
+ * increment: <span>👍</span>,
1518
+ * }}
1519
+ * />
1520
+ *
846
1521
  * @param {NumberStepperProps} props - The props for the NumberStepper component
847
1522
  * @returns {JSX.Element} The rendered NumberStepper component
848
1523
  */
849
- const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step = 1, label, icon, disabled = false, size = 'medium', variant = 'default', showPlusMinus = false, allowKeyboard = true, className = '', customStyles = {}, customButtons = {}, hideLimits = false, layout = 'horizontal', }) => {
1524
+ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step = 1, label, icon, disabled = false, size = 'medium', variant = 'default', showPlusMinus = false, allowKeyboard = true, className = '', customStyles = {}, customButtons = {}, hideLimits = false, layout = 'horizontal', soundConfig }) => {
1525
+ const { handlers, playSound } = useComponentSound(soundConfig);
850
1526
  const [isIncrementing, setIsIncrementing] = React.useState(false);
851
1527
  const [isDecrementing, setIsDecrementing] = React.useState(false);
852
1528
  const [displayValue, setDisplayValue] = React.useState(value);
@@ -856,19 +1532,21 @@ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step
856
1532
  const handleIncrement = React.useCallback(() => {
857
1533
  if (disabled || value >= max)
858
1534
  return;
1535
+ playSound('click');
859
1536
  const newValue = Math.min(value + step, max);
860
1537
  onChange(newValue);
861
1538
  setIsIncrementing(true);
862
1539
  setTimeout(() => setIsIncrementing(false), 200);
863
- }, [value, onChange, max, step, disabled]);
1540
+ }, [value, onChange, max, step, disabled, playSound]);
864
1541
  const handleDecrement = React.useCallback(() => {
865
1542
  if (disabled || value <= min)
866
1543
  return;
1544
+ playSound('click');
867
1545
  const newValue = Math.max(value - step, min);
868
1546
  onChange(newValue);
869
1547
  setIsDecrementing(true);
870
1548
  setTimeout(() => setIsDecrementing(false), 200);
871
- }, [value, onChange, min, step, disabled]);
1549
+ }, [value, onChange, min, step, disabled, playSound]);
872
1550
  const handleKeyDown = React.useCallback((e) => {
873
1551
  if (!allowKeyboard || disabled)
874
1552
  return;
@@ -940,13 +1618,18 @@ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step
940
1618
  const [isButtonHovered, setIsButtonHovered] = React.useState(null);
941
1619
  const isDecrementDisabled = disabled || value <= min;
942
1620
  const isIncrementDisabled = disabled || value >= max;
943
- return (jsxRuntime.jsxs("div", { className: containerClasses, style: customStyles.container, children: [(label || icon) && (jsxRuntime.jsxs("div", { className: styles$i.header, style: customStyles.header, children: [icon && jsxRuntime.jsx("span", { className: styles$i.icon, style: customStyles.icon, children: icon }), label && jsxRuntime.jsx("label", { className: styles$i.label, style: customStyles.label, children: label })] })), jsxRuntime.jsxs("div", { className: styles$i.stepper, style: customStyles.stepper, onKeyDown: handleKeyDown, tabIndex: disabled ? -1 : 0, children: [jsxRuntime.jsx(framerMotion.motion.button, { className: styles$i.button, style: {
944
- ...customStyles.button,
945
- ...(isButtonHovered === 'decrement' && customStyles.buttonHover)
946
- }, onMouseEnter: () => setIsButtonHovered('decrement'), onMouseLeave: () => setIsButtonHovered(null), onClick: handleDecrement, disabled: isDecrementDisabled, whileTap: !isDecrementDisabled ? { scale: 0.9 } : undefined, animate: isDecrementing ? { scale: [1, 1.2, 1] } : undefined, transition: { duration: 0.2 }, "aria-label": "Decrease value", children: customButtons.decrement || (showPlusMinus ? (jsxRuntime.jsx("span", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, children: "\u2212" })) : (jsxRuntime.jsx("svg", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, viewBox: "0 0 24 24", fill: "none", children: jsxRuntime.jsx("path", { d: "M15 18L9 12L15 6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }))) }), jsxRuntime.jsx("div", { className: styles$i.valueContainer, style: customStyles.valueContainer, children: jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: jsxRuntime.jsx(framerMotion.motion.div, { initial: { y: isIncrementing ? 10 : isDecrementing ? -10 : 0, opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: isIncrementing ? -10 : isDecrementing ? 10 : 0, opacity: 0 }, transition: { duration: 0.15 }, className: styles$i.valueWrapper, children: jsxRuntime.jsx("input", { type: "text", className: styles$i.value, style: customStyles.value, value: displayValue, onChange: handleInputChange, onBlur: handleInputBlur, disabled: disabled, "aria-label": label || "Number input", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": value }) }, value) }) }), jsxRuntime.jsx(framerMotion.motion.button, { className: styles$i.button, style: {
947
- ...customStyles.button,
948
- ...(isButtonHovered === 'increment' && customStyles.buttonHover)
949
- }, onMouseEnter: () => setIsButtonHovered('increment'), onMouseLeave: () => setIsButtonHovered(null), onClick: handleIncrement, disabled: isIncrementDisabled, whileTap: !isIncrementDisabled ? { scale: 0.9 } : undefined, animate: isIncrementing ? { scale: [1, 1.2, 1] } : undefined, transition: { duration: 0.2 }, "aria-label": "Increase value", children: customButtons.increment || (showPlusMinus ? (jsxRuntime.jsx("span", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, children: "+" })) : (jsxRuntime.jsx("svg", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, viewBox: "0 0 24 24", fill: "none", children: jsxRuntime.jsx("path", { d: "M9 18L15 12L9 6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }))) })] }), !hideLimits && (min !== -Infinity || max !== Infinity) && (jsxRuntime.jsxs("div", { className: styles$i.limits, style: customStyles.limits, children: [jsxRuntime.jsx("span", { className: styles$i.limit, children: min !== -Infinity && `Min: ${min}` }), jsxRuntime.jsx("span", { className: styles$i.limit, children: max !== Infinity && `Max: ${max}` })] }))] }));
1621
+ const stepperContent = (jsxRuntime.jsxs("div", { className: styles$i.stepper, style: customStyles.stepper, onKeyDown: handleKeyDown, tabIndex: disabled ? -1 : 0, ...handlers, children: [jsxRuntime.jsx(framerMotion.motion.button, { className: styles$i.button, style: {
1622
+ ...customStyles.button,
1623
+ ...(isButtonHovered === 'decrement' && customStyles.buttonHover)
1624
+ }, onMouseEnter: () => setIsButtonHovered('decrement'), onMouseLeave: () => setIsButtonHovered(null), onClick: handleDecrement, disabled: isDecrementDisabled, whileTap: !isDecrementDisabled ? { scale: 0.9 } : undefined, animate: isDecrementing ? { scale: [1, 1.2, 1] } : undefined, transition: { duration: 0.2 }, "aria-label": "Decrease value", children: customButtons.decrement || (showPlusMinus ? (jsxRuntime.jsx("span", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, children: "\u2212" })) : (jsxRuntime.jsx("svg", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, viewBox: "0 0 24 24", fill: "none", children: jsxRuntime.jsx("path", { d: "M15 18L9 12L15 6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }))) }), jsxRuntime.jsx("div", { className: styles$i.valueContainer, style: customStyles.valueContainer, children: jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: jsxRuntime.jsx(framerMotion.motion.div, { initial: { y: isIncrementing ? 10 : isDecrementing ? -10 : 0, opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: isIncrementing ? -10 : isDecrementing ? 10 : 0, opacity: 0 }, transition: { duration: 0.15 }, className: styles$i.valueWrapper, children: jsxRuntime.jsx("input", { type: "text", className: styles$i.value, style: customStyles.value, value: displayValue, onChange: handleInputChange, onBlur: handleInputBlur, disabled: disabled, "aria-label": label || "Number input", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": value }) }, value) }) }), jsxRuntime.jsx(framerMotion.motion.button, { className: styles$i.button, style: {
1625
+ ...customStyles.button,
1626
+ ...(isButtonHovered === 'increment' && customStyles.buttonHover)
1627
+ }, onMouseEnter: () => setIsButtonHovered('increment'), onMouseLeave: () => setIsButtonHovered(null), onClick: handleIncrement, disabled: isIncrementDisabled, whileTap: !isIncrementDisabled ? { scale: 0.9 } : undefined, animate: isIncrementing ? { scale: [1, 1.2, 1] } : undefined, transition: { duration: 0.2 }, "aria-label": "Increase value", children: customButtons.increment || (showPlusMinus ? (jsxRuntime.jsx("span", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, children: "+" })) : (jsxRuntime.jsx("svg", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, viewBox: "0 0 24 24", fill: "none", children: jsxRuntime.jsx("path", { d: "M9 18L15 12L9 6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }))) })] }));
1628
+ // For custom variant with horizontal layout, render differently
1629
+ if (variant === 'custom' && (label || icon)) {
1630
+ return (jsxRuntime.jsxs("div", { className: containerClasses, style: { ...customStyles.container, display: 'flex', alignItems: 'center' }, children: [jsxRuntime.jsxs("div", { className: styles$i.header, style: { ...customStyles.header, flex: 1, marginBottom: 0 }, children: [icon && jsxRuntime.jsx("span", { className: styles$i.icon, style: customStyles.icon, children: icon }), label && jsxRuntime.jsx("label", { className: styles$i.label, style: customStyles.label, children: label })] }), stepperContent, !hideLimits && (min !== -Infinity || max !== Infinity) && (jsxRuntime.jsxs("div", { className: styles$i.limits, style: customStyles.limits, children: [jsxRuntime.jsx("span", { className: styles$i.limit, children: min !== -Infinity && `Min: ${min}` }), jsxRuntime.jsx("span", { className: styles$i.limit, children: max !== Infinity && `Max: ${max}` })] }))] }));
1631
+ }
1632
+ return (jsxRuntime.jsxs("div", { className: containerClasses, style: customStyles.container, children: [(label || icon) && (jsxRuntime.jsxs("div", { className: styles$i.header, style: customStyles.header, children: [icon && jsxRuntime.jsx("span", { className: styles$i.icon, style: customStyles.icon, children: icon }), label && jsxRuntime.jsx("label", { className: styles$i.label, style: customStyles.label, children: label })] })), stepperContent, !hideLimits && (min !== -Infinity || max !== Infinity) && (jsxRuntime.jsxs("div", { className: styles$i.limits, style: customStyles.limits, children: [jsxRuntime.jsx("span", { className: styles$i.limit, children: min !== -Infinity && `Min: ${min}` }), jsxRuntime.jsx("span", { className: styles$i.limit, children: max !== Infinity && `Max: ${max}` })] }))] }));
950
1633
  };
951
1634
 
952
1635
  var styles$h = {"button":"ToggleButton-module_button__DTuyY","background":"ToggleButton-module_background__NwfTp","content":"ToggleButton-module_content__NHqIN","iconWrapper":"ToggleButton-module_iconWrapper__yN4sP","icon":"ToggleButton-module_icon__r8juX","label":"ToggleButton-module_label__4mPJP","hideMobile":"ToggleButton-module_hideMobile__GFAc3","checkmark":"ToggleButton-module_checkmark__ZJwf-","ripple":"ToggleButton-module_ripple__2-faB","small":"ToggleButton-module_small__MhfoN","large":"ToggleButton-module_large__A3naL","default":"ToggleButton-module_default__q8QaZ","active":"ToggleButton-module_active__4DjlR","outlined":"ToggleButton-module_outlined__OtqJB","filled":"ToggleButton-module_filled__LySNn","ghost":"ToggleButton-module_ghost__9KXcb","active-primary":"ToggleButton-module_active-primary__vXMP7","active-secondary":"ToggleButton-module_active-secondary__9Ttdx","active-success":"ToggleButton-module_active-success__oi0rr","active-danger":"ToggleButton-module_active-danger__VUdxr","active-warning":"ToggleButton-module_active-warning__77nSu","animation-scale":"ToggleButton-module_animation-scale__j-3mJ","scaleAnimation":"ToggleButton-module_scaleAnimation__Ms1j2","animation-rotate":"ToggleButton-module_animation-rotate__pBmfc","rotateAnimation":"ToggleButton-module_rotateAnimation__xWZJ5","animation-flip":"ToggleButton-module_animation-flip__ErAbm","flipAnimation":"ToggleButton-module_flipAnimation__qwDTb","disabled":"ToggleButton-module_disabled__Gv5ji"};
@@ -985,7 +1668,8 @@ var styles$h = {"button":"ToggleButton-module_button__DTuyY","background":"Toggl
985
1668
  * @param {ToggleButtonProps} props - The props for the ToggleButton component
986
1669
  * @returns {JSX.Element} The rendered ToggleButton component
987
1670
  */
988
- const ToggleButton = ({ active, onClick, icon, label, disabled = false, size = 'medium', variant = 'default', activeColor = 'primary', showCheckmark = false, animation = 'scale', className = '', style = {}, color, tooltip, hideLabelOnMobile = false, }) => {
1671
+ const ToggleButton = ({ active, onClick, icon, label, disabled = false, size = 'medium', variant = 'default', activeColor = 'primary', showCheckmark = false, animation = 'scale', className = '', style = {}, color, tooltip, hideLabelOnMobile = false, soundConfig }) => {
1672
+ const { handlers, playSound } = useComponentSound(soundConfig);
989
1673
  const buttonClasses = [
990
1674
  styles$h.button,
991
1675
  styles$h[size],
@@ -1059,7 +1743,10 @@ const ToggleButton = ({ active, onClick, icon, label, disabled = false, size = '
1059
1743
  '--toggle-bg-color': active ? `${color}20` : 'transparent'
1060
1744
  })
1061
1745
  };
1062
- return (jsxRuntime.jsxs(framerMotion.motion.button, { className: buttonClasses, style: dynamicStyle, onClick: onClick, disabled: disabled, whileHover: !disabled ? { scale: 1.05 } : undefined, whileTap: !disabled ? { scale: 0.95 } : undefined, title: tooltip, "aria-pressed": active, "aria-label": label, children: [jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.background, variants: backgroundVariants, initial: "inactive", animate: active ? "active" : "inactive" }), jsxRuntime.jsxs("div", { className: styles$h.content, children: [icon && (jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.iconWrapper, variants: iconVariants[animation], initial: "inactive", animate: active ? "active" : "inactive", transition: { duration: 0.3 }, children: typeof icon === 'string' ? (jsxRuntime.jsx("span", { className: styles$h.icon, children: icon })) : (jsxRuntime.jsx("div", { className: styles$h.icon, children: icon })) })), label && jsxRuntime.jsx("span", { className: labelClasses, children: label }), jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showCheckmark && active && (jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.checkmark, variants: checkmarkVariants, initial: "hidden", animate: "visible", exit: "hidden", children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", children: jsxRuntime.jsx("path", { d: "M20 6L9 17L4 12", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }) }) })) })] }), jsxRuntime.jsx(framerMotion.AnimatePresence, { children: active && (jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.ripple, initial: { scale: 0, opacity: 0.5 }, animate: { scale: 2, opacity: 0 }, exit: { scale: 0, opacity: 0 }, transition: { duration: 0.6 } })) })] }));
1746
+ return (jsxRuntime.jsxs(framerMotion.motion.button, { className: buttonClasses, style: dynamicStyle, onClick: () => {
1747
+ playSound('toggle');
1748
+ onClick();
1749
+ }, disabled: disabled, whileHover: !disabled ? { scale: 1.05 } : undefined, whileTap: !disabled ? { scale: 0.95 } : undefined, title: tooltip, "aria-pressed": active, "aria-label": label, ...handlers, children: [jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.background, variants: backgroundVariants, initial: "inactive", animate: active ? "active" : "inactive" }), jsxRuntime.jsxs("div", { className: styles$h.content, children: [icon && (jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.iconWrapper, variants: iconVariants[animation], initial: "inactive", animate: active ? "active" : "inactive", transition: { duration: 0.3 }, children: typeof icon === 'string' ? (jsxRuntime.jsx("span", { className: styles$h.icon, children: icon })) : (jsxRuntime.jsx("div", { className: styles$h.icon, children: icon })) })), label && jsxRuntime.jsx("span", { className: labelClasses, children: label }), jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showCheckmark && active && (jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.checkmark, variants: checkmarkVariants, initial: "hidden", animate: "visible", exit: "hidden", children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", children: jsxRuntime.jsx("path", { d: "M20 6L9 17L4 12", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }) }) })) })] }), jsxRuntime.jsx(framerMotion.AnimatePresence, { children: active && (jsxRuntime.jsx(framerMotion.motion.div, { className: styles$h.ripple, initial: { scale: 0, opacity: 0.5 }, animate: { scale: 2, opacity: 0 }, exit: { scale: 0, opacity: 0 }, transition: { duration: 0.6 } })) })] }));
1063
1750
  };
1064
1751
 
1065
1752
  var styles$g = {"slider":"Slider-module_slider__RD4G7","label":"Slider-module_label__j4H8M","sliderContainer":"Slider-module_sliderContainer__kQICC","track":"Slider-module_track__fQ-oP","fill":"Slider-module_fill__AYR4-","shimmer":"Slider-module_shimmer__271tL","input":"Slider-module_input__fqY-G","thumb":"Slider-module_thumb__yQJho","ripple":"Slider-module_ripple__gVS04","tooltip":"Slider-module_tooltip__ZubHR","tooltipArrow":"Slider-module_tooltipArrow__1aV9s","valueDisplay":"Slider-module_valueDisplay__V6caL","labelsContainer":"Slider-module_labelsContainer__F6ojF","labelItem":"Slider-module_labelItem__FuEaY","size-sm":"Slider-module_size-sm__Y2bmS","size-lg":"Slider-module_size-lg__RSnPf","disabled":"Slider-module_disabled__gxYoH","loading":"Slider-module_loading__6FkKb","loadingTrack":"Slider-module_loadingTrack__8ItT2","loadingIndicator":"Slider-module_loadingIndicator__Elydq"};
@@ -1098,7 +1785,8 @@ var styles$g = {"slider":"Slider-module_slider__RD4G7","label":"Slider-module_la
1098
1785
  * colorFunction={(val) => `hsl(${val * 24}, 70%, 50%)`}
1099
1786
  * />
1100
1787
  */
1101
- function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValue = false, valueFormatter, labels = [], config = {}, disabled = false, className = '', style = {}, loading = false, colorFunction, showTooltip = false, tooltipContent }) {
1788
+ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValue = false, valueFormatter, labels = [], config = {}, disabled = false, className = '', style = {}, loading = false, colorFunction, showTooltip = false, tooltipContent, soundConfig }) {
1789
+ const { handlers, playSound } = useComponentSound(soundConfig);
1102
1790
  const [isDragging, setIsDragging] = React.useState(false);
1103
1791
  const [showTooltipState, setShowTooltipState] = React.useState(false);
1104
1792
  const sliderRef = React.useRef(null);
@@ -1125,6 +1813,7 @@ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValu
1125
1813
  if (disabled || loading)
1126
1814
  return;
1127
1815
  const newValue = Number(e.target.value);
1816
+ playSound('click');
1128
1817
  onChange(newValue);
1129
1818
  };
1130
1819
  // Handle mouse events for enhanced interactions
@@ -1167,7 +1856,7 @@ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValu
1167
1856
  damping: 30
1168
1857
  }, whileHover: {
1169
1858
  boxShadow: `inset 0 0 0 1px rgba(255,255,255,0.2)`
1170
- } }) }), jsxRuntime.jsx("input", { type: "range", min: min, max: max, step: step, value: value, onChange: handleChange, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, className: styles$g.input, disabled: disabled, "aria-label": label }), jsxRuntime.jsx(framerMotion.motion.div, { className: styles$g.thumb, style: {
1859
+ } }) }), jsxRuntime.jsx("input", { type: "range", min: min, max: max, step: step, value: value, onChange: handleChange, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, ...handlers, className: styles$g.input, disabled: disabled, "aria-label": label }), jsxRuntime.jsx(framerMotion.motion.div, { className: styles$g.thumb, style: {
1171
1860
  left: `${percentage}%`,
1172
1861
  backgroundColor: dynamicColor,
1173
1862
  borderColor: colors.thumb || dynamicColor
@@ -1660,7 +2349,7 @@ function TimePickerModal({ isOpen, onClose, value, onChange }) {
1660
2349
 
1661
2350
  var styles$b = {"timeInput":"TimeInput-module_timeInput__h1DpT","label":"TimeInput-module_label__d4rZw","required":"TimeInput-module_required__rc1vq","inputWrapper":"TimeInput-module_inputWrapper__4RPAn","textInput":"TimeInput-module_textInput__M3eBZ","clockButton":"TimeInput-module_clockButton__3qoub","error":"TimeInput-module_error__gJnpk","success":"TimeInput-module_success__np-lF","loading":"TimeInput-module_loading__Wb1DC","disabled":"TimeInput-module_disabled__wxiZ-"};
1662
2351
 
1663
- function TimeInput({ label, value, onChange, placeholder = "14:30", onFocus, onBlur, error = false, success = false, loading = false, disabled = false, required = false }) {
2352
+ function TimeInput({ label, value, onChange, placeholder = "14:30", onFocus, onBlur, error = false, success = false, loading = false, disabled = false, required = false, className = "" }) {
1664
2353
  const [showPicker, setShowPicker] = React.useState(false);
1665
2354
  const formatTime24 = (time) => {
1666
2355
  if (!time)
@@ -1720,6 +2409,8 @@ function TimeInput({ label, value, onChange, placeholder = "14:30", onFocus, onB
1720
2409
  classes.push(styles$b.loading);
1721
2410
  if (disabled)
1722
2411
  classes.push(styles$b.disabled);
2412
+ if (className)
2413
+ classes.push(className);
1723
2414
  return classes.join(' ');
1724
2415
  };
1725
2416
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: getContainerClassName(), children: [jsxRuntime.jsxs("label", { className: styles$b.label, children: [label, required && jsxRuntime.jsx("span", { className: styles$b.required, children: "*" })] }), jsxRuntime.jsxs("div", { className: styles$b.inputWrapper, children: [jsxRuntime.jsx("input", { type: "text", value: value, onChange: (e) => handleTextChange(e.target.value), onFocus: onFocus, onBlur: onBlur, placeholder: placeholder, className: styles$b.textInput, maxLength: 5, disabled: disabled || loading, "aria-invalid": error, "aria-required": required, inputMode: "numeric", pattern: "[0-9:]*" }), jsxRuntime.jsx("button", { type: "button", onClick: handleClockClick, className: styles$b.clockButton, title: "Open time picker", disabled: disabled || loading, "aria-label": "Open time picker", children: jsxRuntime.jsx(FiClock, { size: 20 }) })] })] }), jsxRuntime.jsx(TimePickerModal, { isOpen: showPicker, onClose: () => setShowPicker(false), value: value, onChange: onChange })] }));