@stfrigerio/sito-template 0.1.27 → 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 (31) 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 +3 -0
  10. package/dist/components/atoms/NumberStepper/NumberStepper.d.ts.map +1 -1
  11. package/dist/components/atoms/SelectInput/SelectInput.d.ts +4 -1
  12. package/dist/components/atoms/SelectInput/SelectInput.d.ts.map +1 -1
  13. package/dist/components/atoms/Slider/Slider.d.ts +4 -1
  14. package/dist/components/atoms/Slider/Slider.d.ts.map +1 -1
  15. package/dist/components/atoms/SoundDemo/SoundDemo.stories.d.ts +17 -0
  16. package/dist/components/atoms/SoundDemo/SoundDemo.stories.d.ts.map +1 -0
  17. package/dist/components/atoms/TextInput/TextInput.d.ts +6 -3
  18. package/dist/components/atoms/TextInput/TextInput.d.ts.map +1 -1
  19. package/dist/components/atoms/Toggle/Toggle.d.ts +10 -1
  20. package/dist/components/atoms/Toggle/Toggle.d.ts.map +1 -1
  21. package/dist/components/atoms/ToggleButton/ToggleButton.d.ts +3 -0
  22. package/dist/components/atoms/ToggleButton/ToggleButton.d.ts.map +1 -1
  23. package/dist/index.esm.js +638 -21
  24. package/dist/index.esm.js.map +1 -1
  25. package/dist/index.js +638 -21
  26. package/dist/index.js.map +1 -1
  27. package/dist/utils/soundUtils.d.ts +39 -0
  28. package/dist/utils/soundUtils.d.ts.map +1 -0
  29. package/dist/utils/useSound.d.ts +22 -0
  30. package/dist/utils/useSound.d.ts.map +1 -0
  31. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -32,6 +32,527 @@ const ThemeProvider = ({ children, defaultTheme = 'light' }) => {
32
32
 
33
33
  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"};
34
34
 
35
+ const SOUND_PACKS = {
36
+ digital: {
37
+ click: {
38
+ tones: [
39
+ { freq: 440, duration: 0.1, type: 'sine', volume: 0.4 }
40
+ ]
41
+ },
42
+ hover: {
43
+ tones: [
44
+ { freq: 880, duration: 0.04, type: 'sine', volume: 0.3 }
45
+ ]
46
+ },
47
+ success: {
48
+ tones: [
49
+ { freq: 523.25, duration: 0.15, type: 'sine', delay: 0 },
50
+ { freq: 659.25, duration: 0.15, type: 'sine', delay: 0.1 },
51
+ { freq: 783.99, duration: 0.2, type: 'sine', delay: 0.2 }
52
+ ]
53
+ },
54
+ error: {
55
+ tones: [
56
+ { freq: 329.63, duration: 0.2, type: 'sawtooth', volume: 0.4 },
57
+ { freq: 246.94, duration: 0.25, type: 'sawtooth', volume: 0.3, delay: 0.15 }
58
+ ]
59
+ },
60
+ warning: {
61
+ tones: [
62
+ { freq: 554.37, duration: 0.15, type: 'triangle' },
63
+ { freq: 554.37, duration: 0.15, type: 'triangle', delay: 0.2 }
64
+ ]
65
+ },
66
+ toggle: {
67
+ tones: [
68
+ { freq: 493.88, duration: 0.12, type: 'sine' },
69
+ { freq: 587.33, duration: 0.1, type: 'sine', delay: 0.08 }
70
+ ]
71
+ },
72
+ type: {
73
+ tones: [
74
+ { freq: () => 800 + Math.random() * 400, duration: 0.08, type: 'square', volume: 0.5 },
75
+ { freq: 1600, duration: 0.03, type: 'sine', volume: 0.3, delay: 0.02 }
76
+ ]
77
+ },
78
+ delete: {
79
+ tones: [
80
+ { freq: 350, duration: 0.08, type: 'triangle', volume: 0.3 }
81
+ ]
82
+ },
83
+ celebration: {
84
+ tones: [
85
+ { freq: 523.25, duration: 0.2, type: 'sine', delay: 0 },
86
+ { freq: 659.25, duration: 0.2, type: 'sine', delay: 0.15 },
87
+ { freq: 783.99, duration: 0.2, type: 'sine', delay: 0.3 },
88
+ { freq: 1046.5, duration: 0.3, type: 'sine', delay: 0.45 }
89
+ ]
90
+ },
91
+ milestone: {
92
+ tones: [
93
+ { freq: 698.46, duration: 0.2, type: 'triangle' },
94
+ { freq: 880, duration: 0.25, type: 'triangle', delay: 0.15 }
95
+ ]
96
+ }
97
+ },
98
+ fantasy: {
99
+ click: {
100
+ tones: [
101
+ // Magical chime
102
+ { freq: 1174.66, duration: 0.15, type: 'triangle', volume: 0.3 }, // D6
103
+ { freq: 1567.98, duration: 0.1, type: 'sine', volume: 0.2, delay: 0.05 }, // G6
104
+ { freq: 2093, duration: 0.08, type: 'sine', volume: 0.15, delay: 0.08 } // C7
105
+ ]
106
+ },
107
+ hover: {
108
+ tones: [
109
+ // Fairy dust sprinkle
110
+ { freq: 2637.02, duration: 0.03, type: 'sine', volume: 0.2 }, // E7
111
+ { freq: 3135.96, duration: 0.025, type: 'sine', volume: 0.15, delay: 0.02 } // G7
112
+ ]
113
+ },
114
+ success: {
115
+ tones: [
116
+ // Triumphant fanfare
117
+ { freq: 523.25, duration: 0.2, type: 'triangle', delay: 0 }, // C5
118
+ { freq: 659.25, duration: 0.2, type: 'triangle', delay: 0.15 }, // E5
119
+ { freq: 783.99, duration: 0.2, type: 'triangle', delay: 0.3 }, // G5
120
+ { freq: 1046.5, duration: 0.35, type: 'sine', delay: 0.45 }, // C6
121
+ { freq: 1318.51, duration: 0.15, type: 'sine', volume: 0.3, delay: 0.6 } // E6 harmony
122
+ ]
123
+ },
124
+ error: {
125
+ tones: [
126
+ // Dark spell fail
127
+ { freq: 138.59, duration: 0.3, type: 'sawtooth', volume: 0.4 }, // C#3
128
+ { freq: 103.83, duration: 0.4, type: 'sawtooth', volume: 0.3, delay: 0.2 }, // G#2
129
+ { freq: 87.31, duration: 0.2, type: 'triangle', volume: 0.2, delay: 0.4 } // F2
130
+ ]
131
+ },
132
+ warning: {
133
+ tones: [
134
+ // Mystical alert
135
+ { freq: 466.16, duration: 0.2, type: 'triangle', volume: 0.5 }, // A#4
136
+ { freq: 622.25, duration: 0.15, type: 'sine', delay: 0.15 }, // D#5
137
+ { freq: 466.16, duration: 0.2, type: 'triangle', volume: 0.4, delay: 0.25 } // A#4
138
+ ]
139
+ },
140
+ toggle: {
141
+ tones: [
142
+ // Magic switch
143
+ { freq: 698.46, duration: 0.15, type: 'sine' }, // F5
144
+ { freq: 1046.5, duration: 0.12, type: 'triangle', delay: 0.1 }, // C6
145
+ { freq: 1396.91, duration: 0.08, type: 'sine', volume: 0.3, delay: 0.18 } // F6
146
+ ]
147
+ },
148
+ type: {
149
+ tones: [
150
+ // Quill on parchment
151
+ { freq: () => 2000 + Math.random() * 500, duration: 0.04, type: 'triangle', volume: 0.3 },
152
+ { freq: () => 3000 + Math.random() * 200, duration: 0.02, type: 'sine', volume: 0.2, delay: 0.01 }
153
+ ]
154
+ },
155
+ delete: {
156
+ tones: [
157
+ // Magic erase
158
+ { freq: 880, duration: 0.1, type: 'triangle', volume: 0.3 },
159
+ { freq: 440, duration: 0.08, type: 'sine', volume: 0.2, delay: 0.05 }
160
+ ]
161
+ },
162
+ celebration: {
163
+ tones: [
164
+ // Victory fanfare
165
+ { freq: 392, duration: 0.25, type: 'triangle', delay: 0 }, // G4
166
+ { freq: 523.25, duration: 0.25, type: 'triangle', delay: 0.2 }, // C5
167
+ { freq: 659.25, duration: 0.25, type: 'triangle', delay: 0.4 }, // E5
168
+ { freq: 783.99, duration: 0.25, type: 'sine', delay: 0.6 }, // G5
169
+ { freq: 1046.5, duration: 0.4, type: 'sine', delay: 0.8 }, // C6
170
+ { freq: 1318.51, duration: 0.2, type: 'sine', volume: 0.4, delay: 1.0 } // E6
171
+ ]
172
+ },
173
+ milestone: {
174
+ tones: [
175
+ // Achievement unlocked
176
+ { freq: 523.25, duration: 0.2, type: 'triangle' }, // C5
177
+ { freq: 783.99, duration: 0.2, type: 'triangle', delay: 0.15 }, // G5
178
+ { freq: 1046.5, duration: 0.3, type: 'sine', delay: 0.3 } // C6
179
+ ]
180
+ }
181
+ },
182
+ retro: {
183
+ click: {
184
+ tones: [
185
+ // 8-bit beep
186
+ { freq: 800, duration: 0.05, type: 'square', volume: 0.4 },
187
+ { freq: 400, duration: 0.03, type: 'square', volume: 0.3, delay: 0.03 }
188
+ ]
189
+ },
190
+ hover: {
191
+ tones: [
192
+ { freq: 1200, duration: 0.03, type: 'square', volume: 0.2 }
193
+ ]
194
+ },
195
+ success: {
196
+ tones: [
197
+ // Classic level up
198
+ { freq: 440, duration: 0.1, type: 'square', delay: 0 },
199
+ { freq: 554.37, duration: 0.1, type: 'square', delay: 0.1 },
200
+ { freq: 659.25, duration: 0.1, type: 'square', delay: 0.2 },
201
+ { freq: 880, duration: 0.2, type: 'square', delay: 0.3 }
202
+ ]
203
+ },
204
+ error: {
205
+ tones: [
206
+ // Retro fail
207
+ { freq: 200, duration: 0.3, type: 'square', volume: 0.5 },
208
+ { freq: 150, duration: 0.4, type: 'square', volume: 0.4, delay: 0.2 }
209
+ ]
210
+ },
211
+ warning: {
212
+ tones: [
213
+ { freq: 600, duration: 0.1, type: 'square' },
214
+ { freq: 600, duration: 0.1, type: 'square', delay: 0.15 },
215
+ { freq: 600, duration: 0.1, type: 'square', delay: 0.3 }
216
+ ]
217
+ },
218
+ toggle: {
219
+ tones: [
220
+ { freq: 400, duration: 0.08, type: 'square' },
221
+ { freq: 800, duration: 0.08, type: 'square', delay: 0.06 }
222
+ ]
223
+ },
224
+ type: {
225
+ tones: [
226
+ { freq: () => 500 + Math.random() * 100, duration: 0.04, type: 'square', volume: 0.3 }
227
+ ]
228
+ },
229
+ delete: {
230
+ tones: [
231
+ { freq: 300, duration: 0.06, type: 'square', volume: 0.3 }
232
+ ]
233
+ },
234
+ celebration: {
235
+ tones: [
236
+ // Victory jingle
237
+ { freq: 659.25, duration: 0.1, type: 'square', delay: 0 },
238
+ { freq: 783.99, duration: 0.1, type: 'square', delay: 0.1 },
239
+ { freq: 987.77, duration: 0.1, type: 'square', delay: 0.2 },
240
+ { freq: 1318.51, duration: 0.3, type: 'square', delay: 0.3 }
241
+ ]
242
+ },
243
+ milestone: {
244
+ tones: [
245
+ { freq: 523.25, duration: 0.15, type: 'square' },
246
+ { freq: 1046.5, duration: 0.2, type: 'square', delay: 0.1 }
247
+ ]
248
+ }
249
+ },
250
+ minimal: {
251
+ click: {
252
+ tones: [
253
+ { freq: 1000, duration: 0.03, type: 'sine', volume: 0.3 }
254
+ ]
255
+ },
256
+ hover: {
257
+ tones: [
258
+ { freq: 1500, duration: 0.02, type: 'sine', volume: 0.15 }
259
+ ]
260
+ },
261
+ success: {
262
+ tones: [
263
+ { freq: 800, duration: 0.15, type: 'sine', volume: 0.3 },
264
+ { freq: 1200, duration: 0.1, type: 'sine', volume: 0.2, delay: 0.1 }
265
+ ]
266
+ },
267
+ error: {
268
+ tones: [
269
+ { freq: 300, duration: 0.2, type: 'sine', volume: 0.3 }
270
+ ]
271
+ },
272
+ warning: {
273
+ tones: [
274
+ { freq: 600, duration: 0.15, type: 'sine', volume: 0.35 }
275
+ ]
276
+ },
277
+ toggle: {
278
+ tones: [
279
+ { freq: 700, duration: 0.08, type: 'sine', volume: 0.3 }
280
+ ]
281
+ },
282
+ type: {
283
+ tones: [
284
+ { freq: 1800, duration: 0.02, type: 'sine', volume: 0.2 }
285
+ ]
286
+ },
287
+ delete: {
288
+ tones: [
289
+ { freq: 400, duration: 0.05, type: 'sine', volume: 0.25 }
290
+ ]
291
+ },
292
+ celebration: {
293
+ tones: [
294
+ { freq: 800, duration: 0.2, type: 'sine', volume: 0.3 },
295
+ { freq: 1200, duration: 0.2, type: 'sine', volume: 0.25, delay: 0.15 }
296
+ ]
297
+ },
298
+ milestone: {
299
+ tones: [
300
+ { freq: 1000, duration: 0.2, type: 'sine', volume: 0.3 }
301
+ ]
302
+ }
303
+ },
304
+ mechanical: {
305
+ click: {
306
+ tones: [
307
+ // Mechanical keyboard click
308
+ { freq: 4000, duration: 0.01, type: 'square', volume: 0.3 },
309
+ { freq: 800, duration: 0.04, type: 'sawtooth', volume: 0.4, delay: 0.01 },
310
+ { freq: 200, duration: 0.03, type: 'triangle', volume: 0.2, delay: 0.02 }
311
+ ]
312
+ },
313
+ hover: {
314
+ tones: [
315
+ { freq: 3000, duration: 0.02, type: 'sawtooth', volume: 0.1 }
316
+ ]
317
+ },
318
+ success: {
319
+ tones: [
320
+ // Gear engagement
321
+ { freq: 200, duration: 0.05, type: 'sawtooth', delay: 0 },
322
+ { freq: 400, duration: 0.05, type: 'sawtooth', delay: 0.05 },
323
+ { freq: 600, duration: 0.05, type: 'sawtooth', delay: 0.1 },
324
+ { freq: 800, duration: 0.15, type: 'triangle', delay: 0.15 }
325
+ ]
326
+ },
327
+ error: {
328
+ tones: [
329
+ // Grinding gears
330
+ { freq: 150, duration: 0.2, type: 'sawtooth', volume: 0.5 },
331
+ { freq: 100, duration: 0.15, type: 'square', volume: 0.3, delay: 0.1 },
332
+ { freq: 80, duration: 0.1, type: 'sawtooth', volume: 0.2, delay: 0.2 }
333
+ ]
334
+ },
335
+ warning: {
336
+ tones: [
337
+ // Steam whistle
338
+ { freq: 800, duration: 0.3, type: 'sawtooth', volume: 0.4 },
339
+ { freq: 1200, duration: 0.2, type: 'triangle', volume: 0.3, delay: 0 }
340
+ ]
341
+ },
342
+ toggle: {
343
+ tones: [
344
+ // Switch flip
345
+ { freq: 600, duration: 0.02, type: 'square', volume: 0.5 },
346
+ { freq: 300, duration: 0.05, type: 'triangle', delay: 0.02 },
347
+ { freq: 150, duration: 0.03, type: 'sawtooth', volume: 0.3, delay: 0.05 }
348
+ ]
349
+ },
350
+ type: {
351
+ tones: [
352
+ // Typewriter key
353
+ { freq: () => 3000 + Math.random() * 1000, duration: 0.01, type: 'square', volume: 0.4 },
354
+ { freq: () => 400 + Math.random() * 200, duration: 0.03, type: 'sawtooth', volume: 0.3, delay: 0.01 }
355
+ ]
356
+ },
357
+ delete: {
358
+ tones: [
359
+ { freq: 250, duration: 0.08, type: 'sawtooth', volume: 0.35 }
360
+ ]
361
+ },
362
+ celebration: {
363
+ tones: [
364
+ // Machine startup
365
+ { freq: 100, duration: 0.1, type: 'sawtooth', delay: 0 },
366
+ { freq: 200, duration: 0.1, type: 'sawtooth', delay: 0.1 },
367
+ { freq: 400, duration: 0.1, type: 'sawtooth', delay: 0.2 },
368
+ { freq: 800, duration: 0.1, type: 'triangle', delay: 0.3 },
369
+ { freq: 1200, duration: 0.2, type: 'sine', delay: 0.4 }
370
+ ]
371
+ },
372
+ milestone: {
373
+ tones: [
374
+ // Pneumatic hiss
375
+ { freq: 3000, duration: 0.05, type: 'sawtooth', volume: 0.3 },
376
+ { freq: 1000, duration: 0.15, type: 'triangle', delay: 0.05 },
377
+ { freq: 500, duration: 0.1, type: 'sine', delay: 0.15 }
378
+ ]
379
+ }
380
+ }
381
+ };
382
+ class SoundManager {
383
+ constructor() {
384
+ this.audioContext = null;
385
+ this.config = {
386
+ enabled: false,
387
+ volume: 0.5,
388
+ soundPack: 'digital'
389
+ };
390
+ this.init();
391
+ }
392
+ static getInstance() {
393
+ if (!SoundManager.instance) {
394
+ SoundManager.instance = new SoundManager();
395
+ }
396
+ return SoundManager.instance;
397
+ }
398
+ init() {
399
+ try {
400
+ // AudioContext will be created on first user interaction
401
+ this.audioContext = null;
402
+ }
403
+ catch (error) {
404
+ console.warn('Audio not supported:', error);
405
+ this.config.enabled = false;
406
+ }
407
+ }
408
+ ensureAudioContext() {
409
+ if (!this.audioContext && this.config.enabled) {
410
+ try {
411
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
412
+ }
413
+ catch (error) {
414
+ console.warn('Could not create audio context:', error);
415
+ this.config.enabled = false;
416
+ }
417
+ }
418
+ }
419
+ playTone(frequency, duration, type = 'sine', volume, delay = 0) {
420
+ if (!this.config.enabled)
421
+ return;
422
+ this.ensureAudioContext();
423
+ if (!this.audioContext)
424
+ return;
425
+ const finalVolume = (volume ?? this.config.volume ?? 0.5) * 0.2; // Scale down for comfort
426
+ try {
427
+ const oscillator = this.audioContext.createOscillator();
428
+ const gainNode = this.audioContext.createGain();
429
+ oscillator.connect(gainNode);
430
+ gainNode.connect(this.audioContext.destination);
431
+ oscillator.frequency.value = frequency;
432
+ oscillator.type = type;
433
+ const startTime = this.audioContext.currentTime + delay;
434
+ gainNode.gain.setValueAtTime(0, startTime);
435
+ gainNode.gain.linearRampToValueAtTime(finalVolume, startTime + 0.01);
436
+ gainNode.gain.exponentialRampToValueAtTime(0.001, startTime + duration);
437
+ oscillator.start(startTime);
438
+ oscillator.stop(startTime + duration);
439
+ }
440
+ catch (error) {
441
+ console.debug('Could not play sound:', error);
442
+ }
443
+ }
444
+ playFromDefinition(definition) {
445
+ definition.tones.forEach(tone => {
446
+ const frequency = typeof tone.freq === 'function' ? tone.freq() : tone.freq;
447
+ this.playTone(frequency, tone.duration, tone.type, tone.volume, tone.delay || 0);
448
+ });
449
+ }
450
+ play(soundType) {
451
+ if (!this.config.enabled)
452
+ return;
453
+ const pack = SOUND_PACKS[this.config.soundPack || 'digital'];
454
+ const soundDef = pack[soundType];
455
+ if (soundDef) {
456
+ this.playFromDefinition(soundDef);
457
+ }
458
+ else {
459
+ // Fallback to digital pack for unknown sounds
460
+ const digitalSound = SOUND_PACKS.digital[soundType];
461
+ if (digitalSound) {
462
+ this.playFromDefinition(digitalSound);
463
+ }
464
+ }
465
+ }
466
+ // Special effect sounds
467
+ celebration() {
468
+ if (!this.config.enabled)
469
+ return;
470
+ const pack = SOUND_PACKS[this.config.soundPack || 'digital'];
471
+ this.playFromDefinition(pack.celebration);
472
+ }
473
+ milestone() {
474
+ if (!this.config.enabled)
475
+ return;
476
+ const pack = SOUND_PACKS[this.config.soundPack || 'digital'];
477
+ this.playFromDefinition(pack.milestone);
478
+ }
479
+ configure(config) {
480
+ this.config = { ...this.config, ...config };
481
+ }
482
+ getConfig() {
483
+ return this.config;
484
+ }
485
+ setVolume(volume) {
486
+ this.config.volume = Math.max(0, Math.min(1, volume));
487
+ }
488
+ setEnabled(enabled) {
489
+ this.config.enabled = enabled;
490
+ if (enabled) {
491
+ this.ensureAudioContext();
492
+ }
493
+ }
494
+ setSoundPack(pack) {
495
+ this.config.soundPack = pack;
496
+ }
497
+ getSoundPack() {
498
+ return this.config.soundPack || 'digital';
499
+ }
500
+ isEnabled() {
501
+ return this.config.enabled || false;
502
+ }
503
+ getAvailablePacks() {
504
+ return ['digital', 'fantasy', 'retro', 'minimal', 'mechanical'];
505
+ }
506
+ }
507
+ const soundManager = SoundManager.getInstance();
508
+
509
+ function useSound(options) {
510
+ const lastPlayedRef = useRef({});
511
+ const debounceMs = options?.debounceMs || 50;
512
+ useEffect(() => {
513
+ if (options?.enabled !== undefined) {
514
+ soundManager.setEnabled(options.enabled);
515
+ }
516
+ if (options?.volume !== undefined) {
517
+ soundManager.setVolume(options.volume);
518
+ }
519
+ }, [options?.enabled, options?.volume]);
520
+ const playSound = useCallback((soundType) => {
521
+ const now = Date.now();
522
+ const lastPlayed = lastPlayedRef.current[soundType] || 0;
523
+ if (now - lastPlayed > debounceMs) {
524
+ soundManager.play(soundType);
525
+ lastPlayedRef.current[soundType] = now;
526
+ }
527
+ }, [debounceMs]);
528
+ const isEnabled = useCallback(() => soundManager.isEnabled(), []);
529
+ const setEnabled = useCallback((enabled) => soundManager.setEnabled(enabled), []);
530
+ const setVolume = useCallback((volume) => soundManager.setVolume(volume), []);
531
+ return {
532
+ playSound,
533
+ isEnabled,
534
+ setEnabled,
535
+ setVolume
536
+ };
537
+ }
538
+ function useComponentSound(config, options) {
539
+ const { playSound } = useSound(options);
540
+ const handlers = {};
541
+ if (config?.onClick) {
542
+ handlers.onClick = () => {
543
+ const sound = typeof config.onClick === 'string' ? config.onClick : 'click';
544
+ playSound(sound);
545
+ };
546
+ }
547
+ if (config?.onHover) {
548
+ handlers.onMouseEnter = () => {
549
+ const sound = typeof config.onHover === 'string' ? config.onHover : 'hover';
550
+ playSound(sound);
551
+ };
552
+ }
553
+ return { handlers, playSound };
554
+ }
555
+
35
556
  /**
36
557
  * Button Component
37
558
  *
@@ -71,7 +592,8 @@ var styles$r = {"button":"Button-module_button__c6nkW","primary":"Button-module_
71
592
  * @param {ButtonProps} props - The props for the Button component
72
593
  * @returns {JSX.Element} The rendered Button component
73
594
  */
74
- const Button = ({ variant = 'primary', size = 'medium', fullWidth = false, loading = false, iconLeft, iconRight, children, className = '', disabled, motionProps, ...rest }) => {
595
+ const Button = ({ variant = 'primary', size = 'medium', fullWidth = false, loading = false, iconLeft, iconRight, children, className = '', disabled, motionProps, soundConfig, onClick, onMouseEnter, onFocus, ...rest }) => {
596
+ const { handlers } = useComponentSound(soundConfig);
75
597
  const buttonClasses = [
76
598
  styles$r.button,
77
599
  styles$r[variant],
@@ -80,7 +602,15 @@ const Button = ({ variant = 'primary', size = 'medium', fullWidth = false, loadi
80
602
  loading && styles$r.loading,
81
603
  className
82
604
  ].filter(Boolean).join(' ');
83
- return (jsxs(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 && jsx("span", { className: styles$r.spinner }), iconLeft && jsx("span", { className: styles$r.iconLeft, children: iconLeft }), children, iconRight && jsx("span", { className: styles$r.iconRight, children: iconRight })] }));
605
+ const handleClick = (e) => {
606
+ handlers.onClick?.();
607
+ onClick?.(e);
608
+ };
609
+ const handleMouseEnter = (e) => {
610
+ handlers.onMouseEnter?.();
611
+ onMouseEnter?.(e);
612
+ };
613
+ return (jsxs(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 && jsx("span", { className: styles$r.spinner }), iconLeft && jsx("span", { className: styles$r.iconLeft, children: iconLeft }), children, iconRight && jsx("span", { className: styles$r.iconRight, children: iconRight })] }));
84
614
  };
85
615
 
86
616
  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"};
@@ -206,14 +736,21 @@ var styles$p = {"checkboxLabel":"Checkbox-module_checkboxLabel__4tBVg","checkbox
206
736
  * disabled={true}
207
737
  * />
208
738
  */
209
- const Checkbox = ({ checked, onChange, label, disabled = false, indeterminate = false, id, name, value }) => {
739
+ const Checkbox = ({ checked, onChange, label, disabled = false, indeterminate = false, id, name, value, soundConfig }) => {
210
740
  const checkboxRef = useRef(null);
741
+ const { playSound } = useComponentSound(soundConfig);
211
742
  useEffect(() => {
212
743
  if (checkboxRef.current) {
213
744
  checkboxRef.current.indeterminate = indeterminate;
214
745
  }
215
746
  }, [indeterminate]);
216
- return (jsxs("label", { className: styles$p.checkboxLabel, children: [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 && jsx("span", { className: styles$p.checkboxText, children: label })] }));
747
+ return (jsxs("label", { className: styles$p.checkboxLabel, children: [jsx("input", { ref: checkboxRef, type: "checkbox", checked: checked, onChange: (e) => {
748
+ const isChecked = e.target.checked;
749
+ onChange(isChecked);
750
+ if (soundConfig?.onClick !== false) {
751
+ playSound('toggle');
752
+ }
753
+ }, className: styles$p.checkbox, disabled: disabled, id: id, name: name, value: value, "aria-checked": indeterminate ? 'mixed' : checked }), label && jsx("span", { className: styles$p.checkboxText, children: label })] }));
217
754
  };
218
755
 
219
756
  var DefaultContext = {
@@ -387,8 +924,9 @@ var styles$o = {"dateInput":"DateInput-module_dateInput__54VPD","label":"DateInp
387
924
  * onBlur={() => validateDate(eventDate)}
388
925
  * />
389
926
  */
390
- function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus, onBlur, error = false, success = false, loading = false, disabled = false }) {
927
+ function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus, onBlur, error = false, success = false, loading = false, disabled = false, soundConfig }) {
391
928
  const hiddenDateInputRef = useRef(null);
929
+ const { handlers, playSound } = useComponentSound(soundConfig);
392
930
  const handleTextChange = (textValue) => {
393
931
  // Auto-format as user types
394
932
  let formatted = textValue.replace(/[^\d/]/g, '');
@@ -413,6 +951,7 @@ function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus
413
951
  }
414
952
  };
415
953
  const handleCalendarClick = () => {
954
+ playSound('click');
416
955
  // Set the hidden input to current value for calendar
417
956
  if (hiddenDateInputRef.current) {
418
957
  // If value is already ISO format, use it directly
@@ -446,7 +985,7 @@ function DateInput({ label, value, onChange, placeholder = "25/12/2024", onFocus
446
985
  classes.push(styles$o.loading);
447
986
  return classes.join(' ');
448
987
  };
449
- return (jsxs("div", { className: getClassName(), children: [jsx("label", { className: styles$o.label, children: label }), jsxs("div", { className: styles$o.inputWrapper, children: [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 }), jsx("button", { type: "button", onClick: handleCalendarClick, className: styles$o.calendarButton, title: "Select date from calendar", disabled: disabled || loading, children: jsx(FiCalendar, {}) }), jsx("input", { ref: hiddenDateInputRef, type: "date", onChange: handleCalendarChange, className: styles$o.hiddenDateInput, tabIndex: -1, disabled: disabled || loading })] })] }));
988
+ return (jsxs("div", { className: getClassName(), children: [jsx("label", { className: styles$o.label, children: label }), jsxs("div", { className: styles$o.inputWrapper, children: [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 }), jsx("button", { type: "button", onClick: handleCalendarClick, className: styles$o.calendarButton, title: "Select date from calendar", disabled: disabled || loading, children: jsx(FiCalendar, {}) }), jsx("input", { ref: hiddenDateInputRef, type: "date", onChange: handleCalendarChange, className: styles$o.hiddenDateInput, tabIndex: -1, disabled: disabled || loading })] })] }));
450
989
  }
451
990
 
452
991
  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"};
@@ -605,7 +1144,8 @@ var styles$m = {"selectInput":"SelectInput-module_selectInput__s6zEg","selectWra
605
1144
  * ]}
606
1145
  * />
607
1146
  */
608
- function SelectInput({ label, value, onChange, options, placeholder = "Select...", disabled = false, error = false, success = false, loading = false, required = false }) {
1147
+ function SelectInput({ label, value, onChange, options, placeholder = "Select...", disabled = false, error = false, success = false, loading = false, required = false, soundConfig }) {
1148
+ const { handlers, playSound } = useComponentSound(soundConfig);
609
1149
  const getClassName = () => {
610
1150
  const classes = [styles$m.selectInput];
611
1151
  if (error)
@@ -616,7 +1156,10 @@ function SelectInput({ label, value, onChange, options, placeholder = "Select...
616
1156
  classes.push(styles$m.loading);
617
1157
  return classes.join(' ');
618
1158
  };
619
- return (jsxs("div", { className: getClassName(), children: [jsxs("label", { children: [label, required && jsx("span", { style: { color: 'var(--color-error)' }, children: " *" })] }), jsxs("div", { className: styles$m.selectWrapper, children: [jsxs("select", { value: value, onChange: e => onChange(e.target.value), disabled: disabled || loading, required: required, children: [jsx("option", { value: "", children: placeholder }), options.map(opt => {
1159
+ return (jsxs("div", { className: getClassName(), children: [jsxs("label", { children: [label, required && jsx("span", { style: { color: 'var(--color-error)' }, children: " *" })] }), jsxs("div", { className: styles$m.selectWrapper, children: [jsxs("select", { value: value, onChange: e => {
1160
+ playSound('click');
1161
+ onChange(e.target.value);
1162
+ }, disabled: disabled || loading, required: required, ...handlers, children: [jsx("option", { value: "", children: placeholder }), options.map(opt => {
620
1163
  const optionValue = typeof opt === 'string' ? opt : opt.value;
621
1164
  const optionLabel = typeof opt === 'string' ? opt : opt.label;
622
1165
  return (jsx("option", { value: optionValue, children: optionLabel }, optionValue));
@@ -721,8 +1264,10 @@ var styles$k = {"textInput":"TextInput-module_textInput__b2LVM","required":"Text
721
1264
  * required
722
1265
  * />
723
1266
  */
724
- function TextInput({ label, value, onChange, type = "text", onFocus, onBlur, placeholder, error, required, disabled = false, success = false, loading = false, icon, actionButton, maxLength, autoComplete }) {
1267
+ function TextInput({ label, value, onChange, type = "text", onBlur, placeholder, error, required, disabled = false, success = false, loading = false, icon, actionButton, maxLength, autoComplete, soundConfig, enableTypingSounds = false }) {
725
1268
  const inputId = `input-${Math.random().toString(36).substr(2, 9)}`;
1269
+ const { handlers, playSound } = useComponentSound(soundConfig);
1270
+ const prevValueRef = React.useRef(value);
726
1271
  const getContainerClassName = () => {
727
1272
  const classes = [styles$k.textInput];
728
1273
  if (success)
@@ -735,7 +1280,29 @@ function TextInput({ label, value, onChange, type = "text", onFocus, onBlur, pla
735
1280
  classes.push(styles$k.withAction);
736
1281
  return classes.join(' ');
737
1282
  };
738
- return (jsxs("div", { className: getContainerClassName(), children: [jsxs("label", { htmlFor: inputId, children: [label, required && jsx("span", { className: styles$k.required, children: "*" })] }), jsxs("div", { style: { position: 'relative' }, children: [icon && jsx("div", { className: styles$k.inputIcon, children: icon }), 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 && (jsx("button", { type: "button", className: styles$k.actionButton, onClick: actionButton.onClick, disabled: disabled || loading, children: actionButton.label }))] }), error && (jsx("span", { id: `${inputId}-error`, className: styles$k.errorMessage, children: error }))] }));
1283
+ React.useEffect(() => {
1284
+ prevValueRef.current = value;
1285
+ }, [value]);
1286
+ return (jsxs("div", { className: getContainerClassName(), children: [jsxs("label", { htmlFor: inputId, children: [label, required && jsx("span", { className: styles$k.required, children: "*" })] }), jsxs("div", { style: { position: 'relative' }, children: [icon && jsx("div", { className: styles$k.inputIcon, children: icon }), jsx("input", { id: inputId, type: type, value: value, onChange: (e) => {
1287
+ const newValue = e.target.value;
1288
+ const oldValue = prevValueRef.current;
1289
+ onChange(newValue);
1290
+ // Play typing sounds if enabled
1291
+ if (enableTypingSounds || soundConfig?.onClick) {
1292
+ if (newValue.length > oldValue.length) {
1293
+ playSound('type');
1294
+ }
1295
+ else if (newValue.length < oldValue.length) {
1296
+ playSound('delete');
1297
+ }
1298
+ }
1299
+ if (error && soundConfig?.onError) {
1300
+ playSound(typeof soundConfig.onError === 'string' ? soundConfig.onError : 'error');
1301
+ }
1302
+ }, 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 && (jsx("button", { type: "button", className: styles$k.actionButton, onClick: () => {
1303
+ handlers.onClick?.();
1304
+ actionButton.onClick();
1305
+ }, disabled: disabled || loading, children: actionButton.label }))] }), error && (jsx("span", { id: `${inputId}-error`, className: styles$k.errorMessage, children: error }))] }));
739
1306
  }
740
1307
 
741
1308
  var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggleButton":"Toggle-module_toggleButton__WUUf-","active":"Toggle-module_active__fX6Io"};
@@ -750,12 +1317,14 @@ var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggle
750
1317
  * Supports both text labels and icons for each option.
751
1318
  *
752
1319
  * @example
753
- * // Basic toggle with labels
1320
+ * // Basic toggle with labels and sound theme
754
1321
  * <Toggle
755
1322
  * isOn={darkMode}
756
1323
  * onToggle={setDarkMode}
757
1324
  * leftLabel="Light"
758
1325
  * rightLabel="Dark"
1326
+ * soundTheme="cozy"
1327
+ * enableCelebration={true}
759
1328
  * />
760
1329
  *
761
1330
  * @example
@@ -782,7 +1351,14 @@ var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggle
782
1351
  * @returns {JSX.Element} The rendered Toggle component
783
1352
  */
784
1353
  function Toggle(props) {
785
- const { isOn, onToggle, leftLabel, rightLabel, leftIcon, rightIcon, className, style } = props;
1354
+ const { isOn, onToggle, leftLabel, rightLabel, leftIcon, rightIcon, className, style, soundConfig, soundTheme, enableCelebration = false } = props;
1355
+ const leftButtonRef = useRef(null);
1356
+ const rightButtonRef = useRef(null);
1357
+ const { handlers, playSound, triggerCelebration } = useComponentSound({
1358
+ ...soundConfig,
1359
+ onToggle: soundConfig?.onToggle ?? 'toggle',
1360
+ onHover: soundConfig?.onHover ?? 'hover'
1361
+ }, { });
786
1362
  // Ensure content stays centered by merging styles
787
1363
  const buttonStyle = {
788
1364
  display: 'flex',
@@ -790,7 +1366,39 @@ function Toggle(props) {
790
1366
  justifyContent: 'center',
791
1367
  ...style
792
1368
  };
793
- return (jsxs("div", { className: `${styles$j.toggleContainer} ${className || ''}`, children: [jsxs("button", { className: `${styles$j.toggleButton} ${!isOn ? styles$j.active : ''}`, onClick: () => onToggle(false), style: buttonStyle, children: [leftIcon, leftLabel] }), jsxs("button", { className: `${styles$j.toggleButton} ${isOn ? styles$j.active : ''}`, onClick: () => onToggle(true), style: buttonStyle, children: [rightIcon, rightLabel] })] }));
1369
+ return (jsxs("div", { className: `${styles$j.toggleContainer} ${className || ''}`, children: [jsxs(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: () => {
1370
+ const element = leftButtonRef.current;
1371
+ if (!isOn) {
1372
+ // Already on left, celebration!
1373
+ if (enableCelebration) {
1374
+ triggerCelebration(element || undefined);
1375
+ }
1376
+ else {
1377
+ playSound('boop', element || undefined);
1378
+ }
1379
+ }
1380
+ else {
1381
+ // Switching to left
1382
+ playSound('toggle', element || undefined);
1383
+ }
1384
+ onToggle(false);
1385
+ }, onMouseEnter: () => handlers.onMouseEnter?.(leftButtonRef.current || undefined), style: buttonStyle, children: [jsx(motion.div, { animate: { scale: !isOn ? 1.1 : 1, rotate: !isOn ? [0, -5, 5, 0] : 0 }, transition: { duration: 0.3 }, children: leftIcon }), leftLabel] }), jsxs(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: () => {
1386
+ const element = rightButtonRef.current;
1387
+ if (isOn) {
1388
+ // Already on right, celebration!
1389
+ if (enableCelebration) {
1390
+ triggerCelebration(element || undefined);
1391
+ }
1392
+ else {
1393
+ playSound('ding', element || undefined);
1394
+ }
1395
+ }
1396
+ else {
1397
+ // Switching to right
1398
+ playSound('success', element || undefined);
1399
+ }
1400
+ onToggle(true);
1401
+ }, onMouseEnter: () => handlers.onMouseEnter?.(rightButtonRef.current || undefined), style: buttonStyle, children: [jsx(motion.div, { animate: { scale: isOn ? 1.1 : 1, rotate: isOn ? [0, 5, -5, 0] : 0 }, transition: { duration: 0.3 }, children: rightIcon }), rightLabel] })] }));
794
1402
  }
795
1403
 
796
1404
  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"};
@@ -892,7 +1500,8 @@ var styles$i = {"container":"NumberStepper-module_container__WSGlU","header":"Nu
892
1500
  * @param {NumberStepperProps} props - The props for the NumberStepper component
893
1501
  * @returns {JSX.Element} The rendered NumberStepper component
894
1502
  */
895
- 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', }) => {
1503
+ 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 }) => {
1504
+ const { handlers, playSound } = useComponentSound(soundConfig);
896
1505
  const [isIncrementing, setIsIncrementing] = useState(false);
897
1506
  const [isDecrementing, setIsDecrementing] = useState(false);
898
1507
  const [displayValue, setDisplayValue] = useState(value);
@@ -902,19 +1511,21 @@ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step
902
1511
  const handleIncrement = useCallback(() => {
903
1512
  if (disabled || value >= max)
904
1513
  return;
1514
+ playSound('click');
905
1515
  const newValue = Math.min(value + step, max);
906
1516
  onChange(newValue);
907
1517
  setIsIncrementing(true);
908
1518
  setTimeout(() => setIsIncrementing(false), 200);
909
- }, [value, onChange, max, step, disabled]);
1519
+ }, [value, onChange, max, step, disabled, playSound]);
910
1520
  const handleDecrement = useCallback(() => {
911
1521
  if (disabled || value <= min)
912
1522
  return;
1523
+ playSound('click');
913
1524
  const newValue = Math.max(value - step, min);
914
1525
  onChange(newValue);
915
1526
  setIsDecrementing(true);
916
1527
  setTimeout(() => setIsDecrementing(false), 200);
917
- }, [value, onChange, min, step, disabled]);
1528
+ }, [value, onChange, min, step, disabled, playSound]);
918
1529
  const handleKeyDown = useCallback((e) => {
919
1530
  if (!allowKeyboard || disabled)
920
1531
  return;
@@ -986,7 +1597,7 @@ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step
986
1597
  const [isButtonHovered, setIsButtonHovered] = useState(null);
987
1598
  const isDecrementDisabled = disabled || value <= min;
988
1599
  const isIncrementDisabled = disabled || value >= max;
989
- const stepperContent = (jsxs("div", { className: styles$i.stepper, style: customStyles.stepper, onKeyDown: handleKeyDown, tabIndex: disabled ? -1 : 0, children: [jsx(motion.button, { className: styles$i.button, style: {
1600
+ const stepperContent = (jsxs("div", { className: styles$i.stepper, style: customStyles.stepper, onKeyDown: handleKeyDown, tabIndex: disabled ? -1 : 0, ...handlers, children: [jsx(motion.button, { className: styles$i.button, style: {
990
1601
  ...customStyles.button,
991
1602
  ...(isButtonHovered === 'decrement' && customStyles.buttonHover)
992
1603
  }, 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 ? (jsx("span", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, children: "\u2212" })) : (jsx("svg", { className: styles$i.buttonIcon, style: customStyles.buttonIcon, viewBox: "0 0 24 24", fill: "none", children: jsx("path", { d: "M15 18L9 12L15 6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }))) }), jsx("div", { className: styles$i.valueContainer, style: customStyles.valueContainer, children: jsx(AnimatePresence, { mode: "wait", children: jsx(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: 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) }) }), jsx(motion.button, { className: styles$i.button, style: {
@@ -1036,7 +1647,8 @@ var styles$h = {"button":"ToggleButton-module_button__DTuyY","background":"Toggl
1036
1647
  * @param {ToggleButtonProps} props - The props for the ToggleButton component
1037
1648
  * @returns {JSX.Element} The rendered ToggleButton component
1038
1649
  */
1039
- const ToggleButton = ({ active, onClick, icon, label, disabled = false, size = 'medium', variant = 'default', activeColor = 'primary', showCheckmark = false, animation = 'scale', className = '', style = {}, color, tooltip, hideLabelOnMobile = false, }) => {
1650
+ 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 }) => {
1651
+ const { handlers, playSound } = useComponentSound(soundConfig);
1040
1652
  const buttonClasses = [
1041
1653
  styles$h.button,
1042
1654
  styles$h[size],
@@ -1110,7 +1722,10 @@ const ToggleButton = ({ active, onClick, icon, label, disabled = false, size = '
1110
1722
  '--toggle-bg-color': active ? `${color}20` : 'transparent'
1111
1723
  })
1112
1724
  };
1113
- return (jsxs(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: [jsx(motion.div, { className: styles$h.background, variants: backgroundVariants, initial: "inactive", animate: active ? "active" : "inactive" }), jsxs("div", { className: styles$h.content, children: [icon && (jsx(motion.div, { className: styles$h.iconWrapper, variants: iconVariants[animation], initial: "inactive", animate: active ? "active" : "inactive", transition: { duration: 0.3 }, children: typeof icon === 'string' ? (jsx("span", { className: styles$h.icon, children: icon })) : (jsx("div", { className: styles$h.icon, children: icon })) })), label && jsx("span", { className: labelClasses, children: label }), jsx(AnimatePresence, { children: showCheckmark && active && (jsx(motion.div, { className: styles$h.checkmark, variants: checkmarkVariants, initial: "hidden", animate: "visible", exit: "hidden", children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", children: jsx("path", { d: "M20 6L9 17L4 12", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }) }) })) })] }), jsx(AnimatePresence, { children: active && (jsx(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 } })) })] }));
1725
+ return (jsxs(motion.button, { className: buttonClasses, style: dynamicStyle, onClick: () => {
1726
+ playSound('toggle');
1727
+ onClick();
1728
+ }, disabled: disabled, whileHover: !disabled ? { scale: 1.05 } : undefined, whileTap: !disabled ? { scale: 0.95 } : undefined, title: tooltip, "aria-pressed": active, "aria-label": label, ...handlers, children: [jsx(motion.div, { className: styles$h.background, variants: backgroundVariants, initial: "inactive", animate: active ? "active" : "inactive" }), jsxs("div", { className: styles$h.content, children: [icon && (jsx(motion.div, { className: styles$h.iconWrapper, variants: iconVariants[animation], initial: "inactive", animate: active ? "active" : "inactive", transition: { duration: 0.3 }, children: typeof icon === 'string' ? (jsx("span", { className: styles$h.icon, children: icon })) : (jsx("div", { className: styles$h.icon, children: icon })) })), label && jsx("span", { className: labelClasses, children: label }), jsx(AnimatePresence, { children: showCheckmark && active && (jsx(motion.div, { className: styles$h.checkmark, variants: checkmarkVariants, initial: "hidden", animate: "visible", exit: "hidden", children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", children: jsx("path", { d: "M20 6L9 17L4 12", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }) }) })) })] }), jsx(AnimatePresence, { children: active && (jsx(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 } })) })] }));
1114
1729
  };
1115
1730
 
1116
1731
  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"};
@@ -1149,7 +1764,8 @@ var styles$g = {"slider":"Slider-module_slider__RD4G7","label":"Slider-module_la
1149
1764
  * colorFunction={(val) => `hsl(${val * 24}, 70%, 50%)`}
1150
1765
  * />
1151
1766
  */
1152
- 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 }) {
1767
+ 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 }) {
1768
+ const { handlers, playSound } = useComponentSound(soundConfig);
1153
1769
  const [isDragging, setIsDragging] = useState(false);
1154
1770
  const [showTooltipState, setShowTooltipState] = useState(false);
1155
1771
  const sliderRef = useRef(null);
@@ -1176,6 +1792,7 @@ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValu
1176
1792
  if (disabled || loading)
1177
1793
  return;
1178
1794
  const newValue = Number(e.target.value);
1795
+ playSound('click');
1179
1796
  onChange(newValue);
1180
1797
  };
1181
1798
  // Handle mouse events for enhanced interactions
@@ -1218,7 +1835,7 @@ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValu
1218
1835
  damping: 30
1219
1836
  }, whileHover: {
1220
1837
  boxShadow: `inset 0 0 0 1px rgba(255,255,255,0.2)`
1221
- } }) }), 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 }), jsx(motion.div, { className: styles$g.thumb, style: {
1838
+ } }) }), 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 }), jsx(motion.div, { className: styles$g.thumb, style: {
1222
1839
  left: `${percentage}%`,
1223
1840
  backgroundColor: dynamicColor,
1224
1841
  borderColor: colors.thumb || dynamicColor