@stfrigerio/sito-template 0.1.27 → 0.1.29

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 (33) 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.d.ts +4 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.esm.js +639 -22
  26. package/dist/index.esm.js.map +1 -1
  27. package/dist/index.js +641 -21
  28. package/dist/index.js.map +1 -1
  29. package/dist/utils/soundUtils.d.ts +39 -0
  30. package/dist/utils/soundUtils.d.ts.map +1 -0
  31. package/dist/utils/useSound.d.ts +22 -0
  32. package/dist/utils/useSound.d.ts.map +1 -0
  33. 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 { handlers, 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));
@@ -742,8 +1285,10 @@ var styles$k = {"textInput":"TextInput-module_textInput__b2LVM","required":"Text
742
1285
  * required
743
1286
  * />
744
1287
  */
745
- 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 }) {
746
1289
  const inputId = `input-${Math.random().toString(36).substr(2, 9)}`;
1290
+ const { handlers, playSound } = useComponentSound(soundConfig);
1291
+ const prevValueRef = React.useRef(value);
747
1292
  const getContainerClassName = () => {
748
1293
  const classes = [styles$k.textInput];
749
1294
  if (success)
@@ -756,7 +1301,29 @@ function TextInput({ label, value, onChange, type = "text", onFocus, onBlur, pla
756
1301
  classes.push(styles$k.withAction);
757
1302
  return classes.join(' ');
758
1303
  };
759
- 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 }))] }));
760
1327
  }
761
1328
 
762
1329
  var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggleButton":"Toggle-module_toggleButton__WUUf-","active":"Toggle-module_active__fX6Io"};
@@ -771,12 +1338,14 @@ var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggle
771
1338
  * Supports both text labels and icons for each option.
772
1339
  *
773
1340
  * @example
774
- * // Basic toggle with labels
1341
+ * // Basic toggle with labels and sound theme
775
1342
  * <Toggle
776
1343
  * isOn={darkMode}
777
1344
  * onToggle={setDarkMode}
778
1345
  * leftLabel="Light"
779
1346
  * rightLabel="Dark"
1347
+ * soundTheme="cozy"
1348
+ * enableCelebration={true}
780
1349
  * />
781
1350
  *
782
1351
  * @example
@@ -803,7 +1372,14 @@ var styles$j = {"toggleContainer":"Toggle-module_toggleContainer__QxqQb","toggle
803
1372
  * @returns {JSX.Element} The rendered Toggle component
804
1373
  */
805
1374
  function Toggle(props) {
806
- 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
+ }, { });
807
1383
  // Ensure content stays centered by merging styles
808
1384
  const buttonStyle = {
809
1385
  display: 'flex',
@@ -811,7 +1387,39 @@ function Toggle(props) {
811
1387
  justifyContent: 'center',
812
1388
  ...style
813
1389
  };
814
- 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] })] }));
815
1423
  }
816
1424
 
817
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"};
@@ -913,7 +1521,8 @@ var styles$i = {"container":"NumberStepper-module_container__WSGlU","header":"Nu
913
1521
  * @param {NumberStepperProps} props - The props for the NumberStepper component
914
1522
  * @returns {JSX.Element} The rendered NumberStepper component
915
1523
  */
916
- 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);
917
1526
  const [isIncrementing, setIsIncrementing] = React.useState(false);
918
1527
  const [isDecrementing, setIsDecrementing] = React.useState(false);
919
1528
  const [displayValue, setDisplayValue] = React.useState(value);
@@ -923,19 +1532,21 @@ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step
923
1532
  const handleIncrement = React.useCallback(() => {
924
1533
  if (disabled || value >= max)
925
1534
  return;
1535
+ playSound('click');
926
1536
  const newValue = Math.min(value + step, max);
927
1537
  onChange(newValue);
928
1538
  setIsIncrementing(true);
929
1539
  setTimeout(() => setIsIncrementing(false), 200);
930
- }, [value, onChange, max, step, disabled]);
1540
+ }, [value, onChange, max, step, disabled, playSound]);
931
1541
  const handleDecrement = React.useCallback(() => {
932
1542
  if (disabled || value <= min)
933
1543
  return;
1544
+ playSound('click');
934
1545
  const newValue = Math.max(value - step, min);
935
1546
  onChange(newValue);
936
1547
  setIsDecrementing(true);
937
1548
  setTimeout(() => setIsDecrementing(false), 200);
938
- }, [value, onChange, min, step, disabled]);
1549
+ }, [value, onChange, min, step, disabled, playSound]);
939
1550
  const handleKeyDown = React.useCallback((e) => {
940
1551
  if (!allowKeyboard || disabled)
941
1552
  return;
@@ -1007,7 +1618,7 @@ const NumberStepper = ({ value, onChange, min = -Infinity, max = Infinity, step
1007
1618
  const [isButtonHovered, setIsButtonHovered] = React.useState(null);
1008
1619
  const isDecrementDisabled = disabled || value <= min;
1009
1620
  const isIncrementDisabled = disabled || value >= max;
1010
- const stepperContent = (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: {
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: {
1011
1622
  ...customStyles.button,
1012
1623
  ...(isButtonHovered === 'decrement' && customStyles.buttonHover)
1013
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: {
@@ -1057,7 +1668,8 @@ var styles$h = {"button":"ToggleButton-module_button__DTuyY","background":"Toggl
1057
1668
  * @param {ToggleButtonProps} props - The props for the ToggleButton component
1058
1669
  * @returns {JSX.Element} The rendered ToggleButton component
1059
1670
  */
1060
- 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);
1061
1673
  const buttonClasses = [
1062
1674
  styles$h.button,
1063
1675
  styles$h[size],
@@ -1131,7 +1743,10 @@ const ToggleButton = ({ active, onClick, icon, label, disabled = false, size = '
1131
1743
  '--toggle-bg-color': active ? `${color}20` : 'transparent'
1132
1744
  })
1133
1745
  };
1134
- 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 } })) })] }));
1135
1750
  };
1136
1751
 
1137
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"};
@@ -1170,7 +1785,8 @@ var styles$g = {"slider":"Slider-module_slider__RD4G7","label":"Slider-module_la
1170
1785
  * colorFunction={(val) => `hsl(${val * 24}, 70%, 50%)`}
1171
1786
  * />
1172
1787
  */
1173
- 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);
1174
1790
  const [isDragging, setIsDragging] = React.useState(false);
1175
1791
  const [showTooltipState, setShowTooltipState] = React.useState(false);
1176
1792
  const sliderRef = React.useRef(null);
@@ -1197,6 +1813,7 @@ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValu
1197
1813
  if (disabled || loading)
1198
1814
  return;
1199
1815
  const newValue = Number(e.target.value);
1816
+ playSound('click');
1200
1817
  onChange(newValue);
1201
1818
  };
1202
1819
  // Handle mouse events for enhanced interactions
@@ -1239,7 +1856,7 @@ function Slider({ value, onChange, min = 0, max = 100, step = 1, label, showValu
1239
1856
  damping: 30
1240
1857
  }, whileHover: {
1241
1858
  boxShadow: `inset 0 0 0 1px rgba(255,255,255,0.2)`
1242
- } }) }), 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: {
1243
1860
  left: `${percentage}%`,
1244
1861
  backgroundColor: dynamicColor,
1245
1862
  borderColor: colors.thumb || dynamicColor
@@ -4314,5 +4931,8 @@ exports.ThemeSwitcher = ThemeSwitcher;
4314
4931
  exports.TimeInput = TimeInput;
4315
4932
  exports.Toggle = Toggle;
4316
4933
  exports.ToggleButton = ToggleButton;
4934
+ exports.soundManager = soundManager;
4935
+ exports.useComponentSound = useComponentSound;
4936
+ exports.useSound = useSound;
4317
4937
  exports.useTheme = useTheme$1;
4318
4938
  //# sourceMappingURL=index.js.map