@tremolo-ui/react 0.0.9 → 0.0.10

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 (148) hide show
  1. package/dist/cjs/index.js +432 -269
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/AnimationCanvas/index.d.ts +9 -4
  4. package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
  5. package/dist/cjs/types/components/AnimationKnob/index.d.ts +2 -0
  6. package/dist/cjs/types/components/AnimationKnob/index.d.ts.map +1 -1
  7. package/dist/cjs/types/components/DragObserver/index.d.ts +3 -1
  8. package/dist/cjs/types/components/DragObserver/index.d.ts.map +1 -1
  9. package/dist/cjs/types/components/Knob/index.d.ts +2 -0
  10. package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
  11. package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts +7 -0
  12. package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts.map +1 -0
  13. package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts +7 -0
  14. package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts.map +1 -0
  15. package/dist/cjs/types/components/NumberInput/Stepper.d.ts +8 -0
  16. package/dist/cjs/types/components/NumberInput/Stepper.d.ts.map +1 -0
  17. package/dist/cjs/types/components/NumberInput/context.d.ts +27 -0
  18. package/dist/cjs/types/components/NumberInput/context.d.ts.map +1 -0
  19. package/dist/cjs/types/components/NumberInput/index.d.ts +31 -16
  20. package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
  21. package/dist/cjs/types/components/Piano/BlackKey.d.ts +1 -0
  22. package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -1
  23. package/dist/cjs/types/components/Piano/KeyLabel.d.ts +2 -0
  24. package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -1
  25. package/dist/cjs/types/components/Piano/WhiteKey.d.ts +2 -0
  26. package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -1
  27. package/dist/cjs/types/components/Piano/index.d.ts +6 -4
  28. package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
  29. package/dist/cjs/types/components/Piano/key.d.ts +8 -2
  30. package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
  31. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts +2 -0
  32. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
  33. package/dist/cjs/types/components/Slider/Scale.d.ts +2 -0
  34. package/dist/cjs/types/components/Slider/Scale.d.ts.map +1 -1
  35. package/dist/cjs/types/components/Slider/ScaleOption.d.ts +2 -0
  36. package/dist/cjs/types/components/Slider/ScaleOption.d.ts.map +1 -1
  37. package/dist/cjs/types/components/Slider/Thumb.d.ts +4 -0
  38. package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
  39. package/dist/cjs/types/components/Slider/Track.d.ts +6 -1
  40. package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
  41. package/dist/cjs/types/components/Slider/context.d.ts +15 -12
  42. package/dist/cjs/types/components/Slider/context.d.ts.map +1 -1
  43. package/dist/cjs/types/components/Slider/index.d.ts +8 -5
  44. package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
  45. package/dist/cjs/types/components/WheelObserver/index.d.ts +1 -0
  46. package/dist/cjs/types/components/WheelObserver/index.d.ts.map +1 -1
  47. package/dist/cjs/types/components/XYPad/Area.d.ts +2 -0
  48. package/dist/cjs/types/components/XYPad/Area.d.ts.map +1 -1
  49. package/dist/cjs/types/components/XYPad/Thumb.d.ts +3 -0
  50. package/dist/cjs/types/components/XYPad/Thumb.d.ts.map +1 -1
  51. package/dist/cjs/types/components/XYPad/index.d.ts +4 -0
  52. package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -1
  53. package/dist/cjs/types/hooks/useAnimationFrame.d.ts +3 -0
  54. package/dist/cjs/types/hooks/useAnimationFrame.d.ts.map +1 -0
  55. package/dist/cjs/types/hooks/useDrag.d.ts +15 -0
  56. package/dist/cjs/types/hooks/useDrag.d.ts.map +1 -0
  57. package/dist/cjs/types/hooks/useRefCallbackEvent.d.ts +1 -4
  58. package/dist/cjs/types/hooks/useRefCallbackEvent.d.ts.map +1 -1
  59. package/dist/esm/index.js +430 -260
  60. package/dist/esm/index.js.map +1 -1
  61. package/dist/esm/types/components/AnimationCanvas/index.d.ts +9 -4
  62. package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
  63. package/dist/esm/types/components/AnimationKnob/index.d.ts +2 -0
  64. package/dist/esm/types/components/AnimationKnob/index.d.ts.map +1 -1
  65. package/dist/esm/types/components/DragObserver/index.d.ts +3 -1
  66. package/dist/esm/types/components/DragObserver/index.d.ts.map +1 -1
  67. package/dist/esm/types/components/Knob/index.d.ts +2 -0
  68. package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
  69. package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts +7 -0
  70. package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts.map +1 -0
  71. package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts +7 -0
  72. package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts.map +1 -0
  73. package/dist/esm/types/components/NumberInput/Stepper.d.ts +8 -0
  74. package/dist/esm/types/components/NumberInput/Stepper.d.ts.map +1 -0
  75. package/dist/esm/types/components/NumberInput/context.d.ts +27 -0
  76. package/dist/esm/types/components/NumberInput/context.d.ts.map +1 -0
  77. package/dist/esm/types/components/NumberInput/index.d.ts +31 -16
  78. package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
  79. package/dist/esm/types/components/Piano/BlackKey.d.ts +1 -0
  80. package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -1
  81. package/dist/esm/types/components/Piano/KeyLabel.d.ts +2 -0
  82. package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -1
  83. package/dist/esm/types/components/Piano/WhiteKey.d.ts +2 -0
  84. package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -1
  85. package/dist/esm/types/components/Piano/index.d.ts +6 -4
  86. package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
  87. package/dist/esm/types/components/Piano/key.d.ts +8 -2
  88. package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
  89. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts +2 -0
  90. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
  91. package/dist/esm/types/components/Slider/Scale.d.ts +2 -0
  92. package/dist/esm/types/components/Slider/Scale.d.ts.map +1 -1
  93. package/dist/esm/types/components/Slider/ScaleOption.d.ts +2 -0
  94. package/dist/esm/types/components/Slider/ScaleOption.d.ts.map +1 -1
  95. package/dist/esm/types/components/Slider/Thumb.d.ts +4 -0
  96. package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
  97. package/dist/esm/types/components/Slider/Track.d.ts +6 -1
  98. package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
  99. package/dist/esm/types/components/Slider/context.d.ts +15 -12
  100. package/dist/esm/types/components/Slider/context.d.ts.map +1 -1
  101. package/dist/esm/types/components/Slider/index.d.ts +8 -5
  102. package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
  103. package/dist/esm/types/components/WheelObserver/index.d.ts +1 -0
  104. package/dist/esm/types/components/WheelObserver/index.d.ts.map +1 -1
  105. package/dist/esm/types/components/XYPad/Area.d.ts +2 -0
  106. package/dist/esm/types/components/XYPad/Area.d.ts.map +1 -1
  107. package/dist/esm/types/components/XYPad/Thumb.d.ts +3 -0
  108. package/dist/esm/types/components/XYPad/Thumb.d.ts.map +1 -1
  109. package/dist/esm/types/components/XYPad/index.d.ts +4 -0
  110. package/dist/esm/types/components/XYPad/index.d.ts.map +1 -1
  111. package/dist/esm/types/hooks/useAnimationFrame.d.ts +3 -0
  112. package/dist/esm/types/hooks/useAnimationFrame.d.ts.map +1 -0
  113. package/dist/esm/types/hooks/useDrag.d.ts +15 -0
  114. package/dist/esm/types/hooks/useDrag.d.ts.map +1 -0
  115. package/dist/esm/types/hooks/useRefCallbackEvent.d.ts +1 -4
  116. package/dist/esm/types/hooks/useRefCallbackEvent.d.ts.map +1 -1
  117. package/dist/styles/index.css +110 -14
  118. package/package.json +5 -2
  119. package/src/components/AnimationCanvas/index.tsx +13 -4
  120. package/src/components/AnimationKnob/index.tsx +24 -42
  121. package/src/components/DragObserver/index.tsx +14 -52
  122. package/src/components/Knob/index.tsx +23 -40
  123. package/src/components/NumberInput/DecrementStepper.tsx +52 -0
  124. package/src/components/NumberInput/IncrementStepper.tsx +52 -0
  125. package/src/components/NumberInput/Stepper.tsx +25 -0
  126. package/src/components/NumberInput/context.tsx +150 -0
  127. package/src/components/NumberInput/index.css +102 -14
  128. package/src/components/NumberInput/index.tsx +164 -55
  129. package/src/components/Piano/BlackKey.tsx +13 -10
  130. package/src/components/Piano/KeyLabel.tsx +2 -0
  131. package/src/components/Piano/WhiteKey.tsx +14 -10
  132. package/src/components/Piano/index.tsx +13 -11
  133. package/src/components/Piano/key.ts +8 -2
  134. package/src/components/Piano/keyboardShortcuts.ts +2 -0
  135. package/src/components/Slider/Scale.tsx +8 -6
  136. package/src/components/Slider/ScaleOption.tsx +8 -6
  137. package/src/components/Slider/Thumb.tsx +7 -3
  138. package/src/components/Slider/Track.tsx +27 -15
  139. package/src/components/Slider/context.tsx +65 -51
  140. package/src/components/Slider/index.css +8 -0
  141. package/src/components/Slider/index.tsx +19 -10
  142. package/src/components/WheelObserver/index.tsx +1 -0
  143. package/src/components/XYPad/Area.tsx +2 -0
  144. package/src/components/XYPad/Thumb.tsx +3 -0
  145. package/src/components/XYPad/index.tsx +6 -2
  146. package/src/hooks/useAnimationFrame.ts +18 -0
  147. package/src/hooks/useDrag.ts +92 -0
  148. package/src/hooks/useRefCallbackEvent.ts +4 -7
package/dist/cjs/index.js CHANGED
@@ -86,7 +86,7 @@ function AnimationCanvas(_a) {
86
86
  const context = canvas.getContext('2d', options);
87
87
  if (!context)
88
88
  throw new Error('Cannot get canvas context.');
89
- const dpr = window.devicePixelRatio;
89
+ const dpr = globalThis.window.devicePixelRatio;
90
90
  if (relativeSize) {
91
91
  const parent = canvas.parentElement;
92
92
  if (!parent)
@@ -99,6 +99,7 @@ function AnimationCanvas(_a) {
99
99
  // https://zenn.dev/megeton/articles/be1c677e174c84#%E6%A0%B9%E6%9C%AC%E7%9A%84%E3%81%AB-resizeobserver-loop-limit-exceeded-%E3%81%8C%E5%87%BA%E3%82%8B%E5%95%8F%E9%A1%8C%E3%81%AB%E5%90%91%E3%81%8D%E5%90%88%E3%81%86
100
100
  for (const entry of entries) {
101
101
  // Prevents loss of some context when the canvas is resized
102
+ // TODO: saving scale and translate
102
103
  const contextMemo = {};
103
104
  for (const prop of drawingState) {
104
105
  contextMemo[prop] = context[prop];
@@ -191,15 +192,15 @@ function stepValue(value, step) {
191
192
  throw new RangeError('requirements: step > 0');
192
193
  const quotient = Math.floor(value / step);
193
194
  const decimalDigits = (_a = decimalPart$1(step)) === null || _a === void 0 ? void 0 : _a.length;
194
- const v = toFixed$2(quotient * step, decimalDigits);
195
- const next = toFixed$2((quotient + 1) * step, decimalDigits);
195
+ const v = toFixed$1(quotient * step, decimalDigits);
196
+ const next = toFixed$1((quotient + 1) * step, decimalDigits);
196
197
  return Math.abs(value - v) < Math.abs(value - next) ? v : next;
197
198
  }
198
199
  /**
199
200
  *
200
201
  * @category Math
201
202
  */
202
- function toFixed$2(x, fractionDigits) {
203
+ function toFixed$1(x, fractionDigits) {
203
204
  return Number(x.toFixed(fractionDigits));
204
205
  }
205
206
  /**
@@ -286,7 +287,7 @@ function parseNoteName(noteName) {
286
287
  };
287
288
  }
288
289
  /**
289
- *
290
+ * Convert noteName to noteNumber
290
291
  * @category MIDI
291
292
  */
292
293
  function noteNumber(noteName) {
@@ -296,7 +297,7 @@ function noteNumber(noteName) {
296
297
  return noteIndex + 12 * (Number(octave) + 1) + accidentalValue;
297
298
  }
298
299
  /**
299
- *
300
+ * Convert noteNumber to noteName
300
301
  * @category MIDI
301
302
  */
302
303
  function noteName(noteNumber) {
@@ -305,6 +306,7 @@ function noteName(noteNumber) {
305
306
  return noteNames[noteIndex] + octave;
306
307
  }
307
308
  /**
309
+ * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
308
310
  * @category MIDI
309
311
  */
310
312
  function isWhiteKey(note) {
@@ -367,6 +369,55 @@ function useRefCallbackEvent(event, handler, options, deps = []) {
367
369
  }, deps);
368
370
  }
369
371
 
372
+ /**
373
+ * @returns [refCallback, pointerDownHandler]
374
+ */
375
+ function useDrag({ threshold = 1, onDrag, onDragStart, onDragEnd, }) {
376
+ const dragOffsetX = React.useRef(undefined);
377
+ const dragOffsetY = React.useRef(undefined);
378
+ const dragStartX = React.useRef(0);
379
+ const dragStartY = React.useRef(0);
380
+ const handleDrag = React.useCallback((event, first = false) => {
381
+ const isTouch = event instanceof TouchEvent;
382
+ if (isTouch && event.cancelable)
383
+ event.preventDefault();
384
+ const screenX = isTouch ? event.touches[0].screenX : event.screenX;
385
+ const screenY = isTouch ? event.touches[0].screenY : event.screenY;
386
+ let deltaX = 0;
387
+ let deltaY = 0;
388
+ if (first) {
389
+ dragStartX.current = screenX;
390
+ dragStartY.current = screenY;
391
+ }
392
+ if (dragOffsetX.current) {
393
+ deltaX = screenX - dragOffsetX.current;
394
+ dragOffsetX.current = screenX;
395
+ }
396
+ if (dragOffsetY.current) {
397
+ deltaY = screenY - dragOffsetY.current;
398
+ dragOffsetY.current = screenY;
399
+ }
400
+ if (Math.abs(deltaX) < threshold && Math.abs(deltaY) < threshold)
401
+ return;
402
+ if (onDrag)
403
+ onDrag(screenX - dragStartX.current, screenY - dragStartY.current, deltaX, deltaY);
404
+ }, [threshold, onDrag]);
405
+ const refHandler = useRefCallbackEvent('touchmove', handleDrag, { passive: false }, [onDrag]);
406
+ const pointerDownHandler = React.useCallback((event) => {
407
+ dragOffsetX.current = event.screenX;
408
+ dragOffsetY.current = event.screenY;
409
+ handleDrag(event, true);
410
+ onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart();
411
+ }, [handleDrag, onDragStart]);
412
+ useEventListener(globalThis.window, 'mousemove', handleDrag);
413
+ useEventListener(globalThis.window, 'pointerup', () => {
414
+ dragOffsetX.current = undefined;
415
+ dragOffsetY.current = undefined;
416
+ onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd();
417
+ });
418
+ return [refHandler, pointerDownHandler];
419
+ }
420
+
370
421
  function addNoSelect() {
371
422
  document.body.classList.add('tremolo-no-select');
372
423
  }
@@ -376,34 +427,21 @@ function removeNoSelect() {
376
427
 
377
428
  /**
378
429
  * simple rotary Knob.
430
+ * @category AnimationKnob
379
431
  */
380
432
  function AnimationKnob(_a) {
381
433
  var { value, min, max, defaultValue = min, startValue = min, step = 1, skew = 1, size, width = 50, height = 50, activeColor = '#7998ec', inactiveColor = '#eee', bg = '#ccc', thumb = '#4e76e6', lineWeight = 6, thumbWeight = 4, draw, bodyNoSelect = true, wheel = ['raw', 1], keyboard = ['raw', 1], enableDoubleClickDefault = true, style, className, onChange } = _a, props = __rest(_a, ["value", "min", "max", "defaultValue", "startValue", "step", "skew", "size", "width", "height", "activeColor", "inactiveColor", "bg", "thumb", "lineWeight", "thumbWeight", "draw", "bodyNoSelect", "wheel", "keyboard", "enableDoubleClickDefault", "style", "className", "onChange"]);
382
434
  // -- state and ref ---
383
- // const [privateValue, setPrivateValue] = useState(value);
384
- const dragOffsetY = React.useRef(undefined);
435
+ const valueRef = React.useRef(0);
385
436
  // --- interpret props ---
386
- // const percent = normalizeValue(value, min, max, skew)
387
437
  const isRelativeSize = typeof (size !== null && size !== void 0 ? size : width) == 'string' || typeof height == 'string';
388
- const handleEvent = (event) => {
389
- const isTouch = event instanceof TouchEvent;
390
- if (isTouch && event.cancelable)
391
- event.preventDefault();
392
- if (dragOffsetY.current) {
393
- if (bodyNoSelect)
394
- addNoSelect();
395
- const screenY = isTouch ? event.touches[0].screenY : event.screenY;
396
- const delta = dragOffsetY.current - screenY;
397
- if (Math.abs(delta) < 1)
398
- return;
399
- dragOffsetY.current = screenY;
400
- const n = normalizeValue(value, min, max, skew);
401
- const v = rawValue(n + delta / 100, min, max, skew);
402
- const v2 = clamp(stepValue(v, step), min, max);
403
- if (onChange)
404
- onChange(v2);
405
- }
406
- };
438
+ const onDrag = React.useCallback((_x, y) => {
439
+ if (!onChange)
440
+ return;
441
+ const v = rawValue(valueRef.current - y / 100, min, max, skew);
442
+ const v2 = clamp(stepValue(v, step), min, max);
443
+ onChange(v2);
444
+ }, [max, min, onChange, skew, step]);
407
445
  const handleKeyDown = React.useCallback((event) => {
408
446
  if (!keyboard || !onChange)
409
447
  return;
@@ -423,6 +461,18 @@ function AnimationKnob(_a) {
423
461
  }
424
462
  }, [value, min, max, step, skew, keyboard, onChange]);
425
463
  // --- hooks ---
464
+ const [touchMoveRefCallback, pointerDownHandler] = useDrag({
465
+ onDrag: onDrag,
466
+ onDragStart: () => {
467
+ valueRef.current = normalizeValue(value, min, max, skew);
468
+ if (bodyNoSelect)
469
+ addNoSelect();
470
+ },
471
+ onDragEnd: () => {
472
+ if (bodyNoSelect)
473
+ removeNoSelect();
474
+ },
475
+ });
426
476
  const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
427
477
  if (!wheel)
428
478
  return;
@@ -439,20 +489,10 @@ function AnimationKnob(_a) {
439
489
  if (onChange)
440
490
  onChange(clamp(stepValue(v, step), min, max));
441
491
  }, { passive: false }, [wheel, value, min, max, skew, step, onChange]);
442
- const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleEvent, { passive: false }, [value, min, max, skew, step, onChange, bodyNoSelect]);
443
- useEventListener(window, 'mousemove', handleEvent);
444
- useEventListener(window, 'pointerup', () => {
445
- dragOffsetY.current = undefined;
446
- if (bodyNoSelect)
447
- removeNoSelect();
448
- });
449
492
  return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-animation-knob', className), ref: (div) => {
450
493
  wheelRefCallback(div);
451
494
  touchMoveRefCallback(div);
452
- }, role: "slider", tabIndex: 0, "aria-valuenow": value, "aria-valuemax": max, "aria-valuemin": min, style: Object.assign({ display: 'inline-block', width: size !== null && size !== void 0 ? size : width, height: size !== null && size !== void 0 ? size : height, cursor: 'pointer', WebkitTapHighlightColor: 'transparent' }, style), onPointerDown: (event) => {
453
- dragOffsetY.current = event.screenY;
454
- handleEvent(event);
455
- }, onDoubleClick: () => {
495
+ }, role: "slider", tabIndex: 0, "aria-valuenow": value, "aria-valuemax": max, "aria-valuemin": min, style: Object.assign({ display: 'inline-block', width: size !== null && size !== void 0 ? size : width, height: size !== null && size !== void 0 ? size : height, cursor: 'pointer', WebkitTapHighlightColor: 'transparent' }, style), onPointerDown: pointerDownHandler, onDoubleClick: () => {
456
496
  if (enableDoubleClickDefault && onChange) {
457
497
  onChange(defaultValue);
458
498
  }
@@ -505,49 +545,22 @@ function AnimationKnob(_a) {
505
545
  } })) })));
506
546
  }
507
547
 
548
+ /** @category DragObserver */
508
549
  function DragObserver(props) {
509
- const { children, onDrag, onDragStart, onDragEnd, as: Component = 'div' } = props, attributes = __rest(props, ["children", "onDrag", "onDragStart", "onDragEnd", "as"]);
510
- const dragOffsetX = React.useRef(undefined);
511
- const dragOffsetY = React.useRef(undefined);
512
- const handleEvent = (event) => {
513
- const isTouch = event instanceof TouchEvent;
514
- if (isTouch && event.cancelable)
515
- event.preventDefault();
516
- const screenX = isTouch ? event.touches[0].screenX : event.screenX;
517
- const screenY = isTouch ? event.touches[0].screenY : event.screenY;
518
- let deltaX = 0, deltaY = 0;
519
- if (dragOffsetX.current) {
520
- deltaX = screenX - dragOffsetX.current;
521
- dragOffsetX.current = screenX;
522
- }
523
- if (dragOffsetY.current) {
524
- deltaY = screenY - dragOffsetY.current;
525
- dragOffsetY.current = screenY;
526
- }
527
- if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1)
528
- return;
529
- if (onDrag)
530
- onDrag(deltaX, deltaY);
531
- };
532
- const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleEvent, { passive: false }, [onDrag]);
533
- useEventListener(window, 'mousemove', handleEvent);
534
- useEventListener(window, 'pointerup', () => {
535
- dragOffsetX.current = undefined;
536
- dragOffsetY.current = undefined;
537
- onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd();
550
+ const { as: Component = 'div', threshold = 1, children, onDrag, onDragStart, onDragEnd } = props, attributes = __rest(props, ["as", "threshold", "children", "onDrag", "onDragStart", "onDragEnd"]);
551
+ const [refCallback, pointerDownHandler] = useDrag({
552
+ threshold: threshold,
553
+ onDrag: onDrag,
554
+ onDragStart: onDragStart,
555
+ onDragEnd: onDragEnd,
538
556
  });
539
- return (jsxRuntime.jsx(Component, Object.assign({ ref: touchMoveRefCallback, onPointerDown: (event) => {
540
- dragOffsetX.current = event.screenX;
541
- dragOffsetY.current = event.screenY;
542
- handleEvent(event);
543
- onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart();
544
- } }, attributes, { children: children })));
557
+ return (jsxRuntime.jsx(Component, Object.assign({ ref: refCallback, onPointerDown: pointerDownHandler }, attributes, { children: children })));
545
558
  }
546
559
 
560
+ /** @category Knob */
547
561
  function Knob(_a) {
548
562
  var { value, min, max, step = 1, skew = 1, defaultValue = min, startValue = min, size = 50, bodyNoSelect = true, wheel = ['raw', 1], keyboard = ['raw', 1], enableDoubleClickDefault = true, disabled = false, readonly = false, activeLine, inactiveLine, thumb, thumbLine, onChange, className, classes } = _a, props = __rest(_a, ["value", "min", "max", "step", "skew", "defaultValue", "startValue", "size", "bodyNoSelect", "wheel", "keyboard", "enableDoubleClickDefault", "disabled", "readonly", "activeLine", "inactiveLine", "thumb", "thumbLine", "onChange", "className", "classes"]);
549
- // -- state and ref ---
550
- const dragOffsetY = React.useRef(undefined);
563
+ const valueRef = React.useRef(0);
551
564
  // --- interpret props ---
552
565
  const padding = 8; // %
553
566
  const thumbLineWeight = 6; // %
@@ -556,26 +569,13 @@ function Knob(_a) {
556
569
  const p = normalizeValue(value, min, max, skew);
557
570
  const s = normalizeValue(startValue, min, max, skew);
558
571
  // --- internal functions ---
559
- const handleEvent = (event) => {
572
+ const onDrag = React.useCallback((_x, y) => {
560
573
  if (!onChange || readonly)
561
574
  return;
562
- const isTouch = event instanceof TouchEvent;
563
- if (isTouch && event.cancelable)
564
- event.preventDefault();
565
- if (dragOffsetY.current) {
566
- if (bodyNoSelect)
567
- addNoSelect();
568
- const screenY = isTouch ? event.touches[0].screenY : event.screenY;
569
- const delta = dragOffsetY.current - screenY;
570
- if (Math.abs(delta) < 1)
571
- return;
572
- dragOffsetY.current = screenY;
573
- const n = normalizeValue(value, min, max, skew);
574
- const v = rawValue(n + delta / 100, min, max, skew);
575
- const v2 = clamp(stepValue(v, step), min, max);
576
- onChange(v2);
577
- }
578
- };
575
+ const v = rawValue(valueRef.current - y / 100, min, max, skew);
576
+ const v2 = clamp(stepValue(v, step), min, max);
577
+ onChange(v2);
578
+ }, [max, min, onChange, readonly, skew, step]);
579
579
  const handleKeyDown = React.useCallback((event) => {
580
580
  if (!keyboard || !onChange || readonly)
581
581
  return;
@@ -595,6 +595,18 @@ function Knob(_a) {
595
595
  }
596
596
  }, [value, min, max, step, skew, keyboard, readonly, onChange]);
597
597
  // --- hooks ---
598
+ const [touchMoveRefCallback, pointerDownHandler] = useDrag({
599
+ onDrag: onDrag,
600
+ onDragStart: () => {
601
+ valueRef.current = normalizeValue(value, min, max, skew);
602
+ if (bodyNoSelect)
603
+ addNoSelect();
604
+ },
605
+ onDragEnd: () => {
606
+ if (bodyNoSelect)
607
+ removeNoSelect();
608
+ },
609
+ });
598
610
  const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
599
611
  if (!wheel)
600
612
  return;
@@ -611,13 +623,6 @@ function Knob(_a) {
611
623
  if (onChange)
612
624
  onChange(clamp(stepValue(v, step), min, max));
613
625
  }, { passive: false }, [wheel, value, min, max, skew, step, onChange]);
614
- const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleEvent, { passive: false }, [value, min, max, skew, step, onChange, bodyNoSelect]);
615
- useEventListener(window, 'mousemove', handleEvent);
616
- useEventListener(window, 'pointerup', () => {
617
- dragOffsetY.current = undefined;
618
- if (bodyNoSelect)
619
- removeNoSelect();
620
- });
621
626
  const center = size / 2;
622
627
  const r1 = -135;
623
628
  const r2 = -135 + Math.min(p, s) * 270;
@@ -634,34 +639,17 @@ function Knob(_a) {
634
639
  return (jsxRuntime.jsxs("svg", Object.assign({ className: clsx('tremolo-knob', className), ref: (div) => {
635
640
  wheelRefCallback(div);
636
641
  touchMoveRefCallback(div);
637
- }, width: size, height: size, tabIndex: 0, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled, "aria-readonly": readonly, onPointerDown: (event) => {
638
- dragOffsetY.current = event.screenY;
639
- handleEvent(event);
640
- }, onDoubleClick: () => {
642
+ }, width: size, height: size, tabIndex: 0, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled, "aria-readonly": readonly, onPointerDown: pointerDownHandler, onDoubleClick: () => {
641
643
  if (enableDoubleClickDefault && onChange) {
642
644
  onChange(defaultValue);
643
645
  }
644
646
  }, onKeyDown: handleKeyDown, onContextMenu: (e) => e.preventDefault() }, props, { children: [startValue > min && (jsxRuntime.jsx("path", { className: clsx('tremolo-knob-inactive-line', classes === null || classes === void 0 ? void 0 : classes.inactiveLine), d: `M ${x1} ${y1} A ${center} ${center} -135 ${r2 - r1 > 180 ? 1 : 0} 1 ${x2}, ${y2}`, fill: "none", stroke: inactiveLine || 'currentColor', strokeWidth: lineWeight })), jsxRuntime.jsx("path", { className: clsx('tremolo-knob-active-line', classes === null || classes === void 0 ? void 0 : classes.activeLine), d: `M ${x2} ${y2} A ${center} ${center} -135 ${r3 - r2 > 180 ? 1 : 0} 1 ${x3}, ${y3}`, fill: "none", stroke: activeLine || 'currentColor', strokeWidth: lineWeight }), startValue < max && (jsxRuntime.jsx("path", { className: clsx('tremolo-knob-inactive-line', classes === null || classes === void 0 ? void 0 : classes.inactiveLine), d: `M ${x3} ${y3} A ${center} ${center} -135 ${r4 - r3 > 180 ? 1 : 0} 1 ${x4}, ${y4}`, fill: "none", stroke: inactiveLine || 'currentColor', strokeWidth: lineWeight })), jsxRuntime.jsxs("svg", { className: clsx('tremolo-knob-thumb', classes === null || classes === void 0 ? void 0 : classes.thumb), children: [jsxRuntime.jsx("circle", { cx: "50%", cy: "50%", r: `${50 - padding}%`, fill: thumb || 'currentColor' }), jsxRuntime.jsx("line", { className: clsx('tremolo-knob-thumb-line', classes === null || classes === void 0 ? void 0 : classes.thumbLine), x1: "50%", y1: `${padding}%`, x2: "50%", y2: `${thumbLength}%`, stroke: thumbLine || 'currentColor', strokeWidth: `${thumbLineWeight}%`, transform: `rotate(${ -135 + p * 270})`, "transform-origin": "50% 50%" })] })] })));
645
647
  }
646
648
 
647
- /**
648
- * clamp value between min and max
649
- * @category Math
650
- */
651
- /**
652
- *
653
- * @category Math
654
- */
655
- function toFixed$1(x, fractionDigits) {
656
- return Number(x.toFixed(fractionDigits));
657
- }
658
-
659
649
  /**
660
650
  * @module NumberInput
661
651
  */
662
652
  function selectUnit(units, value) {
663
- if (typeof units == 'string')
664
- return [units, 1];
665
653
  let i = 0;
666
654
  for (; i < units.length; i++) {
667
655
  if (Math.abs(units[i][1]) > Math.abs(value))
@@ -669,46 +657,33 @@ function selectUnit(units, value) {
669
657
  }
670
658
  return units[Math.max(0, i - 1)];
671
659
  }
672
- function parseValue(inputString, units, digit, defaultValue = 0) {
673
- let str = inputString.trim();
674
- if (str == '')
675
- str = String(defaultValue);
676
- if (!units) {
677
- return {
678
- rawValue: Number(str) || defaultValue,
679
- formatValue: str,
680
- unit: '',
681
- };
682
- }
683
- else if (typeof units == 'string') {
660
+ function parseValue(inputString, units, digit) {
661
+ var _a;
662
+ const str = inputString.trim();
663
+ if (!units || typeof units == 'string') {
664
+ const m = str.match(/-?\d+(\.\d+)?/);
665
+ let v = Number((_a = m === null || m === void 0 ? void 0 : m[0]) !== null && _a !== void 0 ? _a : '0');
666
+ v = isNaN(v) ? 0 : v;
684
667
  return {
685
- rawValue: Number(str) || defaultValue,
686
- formatValue: `${str}${units}`,
687
- unit: units,
668
+ rawValue: v,
669
+ formatValue: (digit != undefined ? v.toFixed(digit) : v) + (units !== null && units !== void 0 ? units : ''),
670
+ unit: units !== null && units !== void 0 ? units : '',
688
671
  };
689
672
  }
690
673
  const unitList = units.map(([u, _s]) => u);
691
674
  const scaleList = units.map(([_u, s]) => s);
692
- let rawValue = defaultValue;
693
- let formatValue = `${scaleList[0]}`;
675
+ let rawValue = 0;
694
676
  let unit = unitList[0];
677
+ let formatValue = (digit != undefined ? rawValue.toFixed(digit) : rawValue) + unit;
695
678
  const m = str.match(/^(-?\d+(\.\d+)?)\s*(\w*)$/);
696
679
  if (m) {
697
680
  rawValue = Number(m[1]) || 0;
698
- const inputUnit = m[3];
699
- if (inputUnit != '' && unitList.indexOf(inputUnit) != -1) {
700
- rawValue *= scaleList[unitList.indexOf(inputUnit)];
701
- const s = selectUnit(units, rawValue);
702
- const v = rawValue / s[1];
703
- formatValue = `${digit != undefined ? toFixed$1(v, digit) : v}${s[0]}`;
704
- unit = s[0];
705
- }
706
- else {
707
- const [u, scale] = selectUnit(units, rawValue);
708
- const v = rawValue / scale;
709
- formatValue = `${digit != undefined ? toFixed$1(v, digit) : v}${u}`;
710
- unit = u;
711
- }
681
+ const uIndex = unitList.indexOf(m[3]);
682
+ rawValue *= uIndex != -1 ? scaleList[uIndex] : 1;
683
+ const [u, scale] = selectUnit(units, rawValue);
684
+ const v = rawValue / scale;
685
+ formatValue = (digit != undefined ? v.toFixed(digit) : v) + u;
686
+ unit = u;
712
687
  }
713
688
  return {
714
689
  rawValue: rawValue,
@@ -717,44 +692,203 @@ function parseValue(inputString, units, digit, defaultValue = 0) {
717
692
  };
718
693
  }
719
694
 
720
- /**
721
- * Input with some useful functions for entering numerical values.
722
- */
723
- function NumberInput(_a) {
724
- var { value, min, max, step, defaultValue = min, units, disabled = false, placeholder, readOnly, tabIndex, typeNumber = false, digit, selectWithFocus = 'none', blurWithEnter = true, className, onChange, onFocus, onBlur } = _a, props = __rest(_a, ["value", "min", "max", "step", "defaultValue", "units", "disabled", "placeholder", "readOnly", "tabIndex", "typeNumber", "digit", "selectWithFocus", "blurWithEnter", "className", "onChange", "onFocus", "onBlur"]);
725
- const [showValue, setShowValue] = React.useState(parseValue(String(value), units, digit, defaultValue).formatValue);
726
- const calculatedTypeNumber = units ? false : typeNumber;
727
- return (jsxRuntime.jsx("input", Object.assign({ className: clsx('tremolo-number-input', className), value: showValue, min: min, max: max, step: step, type: calculatedTypeNumber ? 'number' : 'text', spellCheck: 'false', disabled: disabled, placeholder: placeholder, readOnly: readOnly, tabIndex: tabIndex, onChange: (event) => {
695
+ const createStoreImpl = (createState) => {
696
+ let state;
697
+ const listeners = /* @__PURE__ */ new Set();
698
+ const setState = (partial, replace) => {
699
+ const nextState = typeof partial === "function" ? partial(state) : partial;
700
+ if (!Object.is(nextState, state)) {
701
+ const previousState = state;
702
+ state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
703
+ listeners.forEach((listener) => listener(state, previousState));
704
+ }
705
+ };
706
+ const getState = () => state;
707
+ const getInitialState = () => initialState;
708
+ const subscribe = (listener) => {
709
+ listeners.add(listener);
710
+ return () => listeners.delete(listener);
711
+ };
712
+ const api = { setState, getState, getInitialState, subscribe };
713
+ const initialState = state = createState(setState, getState, api);
714
+ return api;
715
+ };
716
+ const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
717
+
718
+ const identity = (arg) => arg;
719
+ function useStore(api, selector = identity) {
720
+ const slice = React.useSyncExternalStore(
721
+ api.subscribe,
722
+ () => selector(api.getState()),
723
+ () => selector(api.getInitialState())
724
+ );
725
+ React.useDebugValue(slice);
726
+ return slice;
727
+ }
728
+
729
+ function safeClamp(value, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) {
730
+ return clamp(value, min, max);
731
+ }
732
+ const createNumberInputStore = (initProps) => {
733
+ const DEFAULT_PROPS = {
734
+ value: '',
735
+ valueAsNumber: 0,
736
+ min: 0,
737
+ max: 0,
738
+ step: 1,
739
+ keepWithinRange: true,
740
+ onChange: (_v, _t) => { },
741
+ };
742
+ return createStore()((set) => (Object.assign(Object.assign(Object.assign(Object.assign({}, DEFAULT_PROPS), initProps), {
743
+ value: parseValue(String((initProps === null || initProps === void 0 ? void 0 : initProps.value) || ''), initProps === null || initProps === void 0 ? void 0 : initProps.units, initProps === null || initProps === void 0 ? void 0 : initProps.digit).formatValue,
744
+ valueAsNumber: parseValue(String((initProps === null || initProps === void 0 ? void 0 : initProps.value) || ''), initProps === null || initProps === void 0 ? void 0 : initProps.units, initProps === null || initProps === void 0 ? void 0 : initProps.digit).rawValue,
745
+ }), { increment: () => set((state) => {
746
+ var _a, _b;
747
+ let next = parseValue(state.value, state.units, state.digit).rawValue +
748
+ ((_a = state.step) !== null && _a !== void 0 ? _a : 1);
749
+ if (state.keepWithinRange) {
750
+ next = safeClamp(next, state.min, state.max);
751
+ }
752
+ const v = parseValue(String(next), state.units, state.digit).formatValue;
753
+ (_b = state === null || state === void 0 ? void 0 : state.onChange) === null || _b === void 0 ? void 0 : _b.call(state, next, v);
754
+ return {
755
+ value: v,
756
+ valueAsNumber: next,
757
+ };
758
+ }), decrement: () => set((state) => {
759
+ var _a, _b;
760
+ let next = parseValue(state.value, state.units, state.digit).rawValue -
761
+ ((_a = state.step) !== null && _a !== void 0 ? _a : 1);
762
+ if (state.keepWithinRange) {
763
+ next = safeClamp(next, state.min, state.max);
764
+ }
765
+ const v = parseValue(String(next), state.units, state.digit).formatValue;
766
+ (_b = state === null || state === void 0 ? void 0 : state.onChange) === null || _b === void 0 ? void 0 : _b.call(state, next, v);
767
+ return {
768
+ value: v,
769
+ valueAsNumber: next,
770
+ };
771
+ }), change: (value) => set((state) => {
772
+ const v = value !== null && value !== void 0 ? value : '';
773
+ return {
774
+ value: v,
775
+ valueAsNumber: parseValue(v, state.units, state.digit).rawValue,
776
+ };
777
+ }) })));
778
+ };
779
+ const NumberInputContext = React.createContext(null);
780
+ function NumberInputProvider(_a) {
781
+ var { children } = _a, props = __rest(_a, ["children"]);
782
+ const storeRef = React.useRef();
783
+ if (!storeRef.current) {
784
+ storeRef.current = createNumberInputStore(props);
785
+ }
786
+ React.useEffect(() => {
787
+ if (storeRef.current) {
788
+ const parsed = parseValue(String((props === null || props === void 0 ? void 0 : props.value) || ''), props === null || props === void 0 ? void 0 : props.units, props === null || props === void 0 ? void 0 : props.digit);
789
+ storeRef.current.setState(Object.assign(Object.assign({}, props), {
790
+ value: parsed.formatValue,
791
+ valueAsNumber: parsed.rawValue,
792
+ }));
793
+ }
794
+ else {
795
+ storeRef.current = createNumberInputStore(props);
796
+ }
797
+ }, [props]);
798
+ return (jsxRuntime.jsx(NumberInputContext.Provider, { value: storeRef.current, children: children }));
799
+ }
800
+ /** @category NumberInput */
801
+ function useNumberInputContext(selector) {
802
+ const store = React.useContext(NumberInputContext);
803
+ if (!store)
804
+ throw new Error('Missing NumberInputContext.Provider in the tree');
805
+ return useStore(store, selector);
806
+ }
807
+
808
+ function Stepper(_a) {
809
+ var { dynamic = true, children, className } = _a, props = __rest(_a, ["dynamic", "children", "className"]);
810
+ return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-number-input-stepper', className), "data-dynamic": dynamic }, props, { children: children })));
811
+ }
812
+
813
+ function IncrementStepper(_a) {
814
+ var { size = 12, children, className } = _a, props = __rest(_a, ["size", "children", "className"]);
815
+ const max = useNumberInputContext((s) => s.max);
816
+ const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber);
817
+ const keepWithinRange = useNumberInputContext((s) => s.keepWithinRange);
818
+ const increment = useNumberInputContext((s) => s.increment);
819
+ // TODO: add long press event
820
+ return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-number-input-increment-stepper', className), role: "button", tabIndex: -1, "aria-disabled": keepWithinRange && valueAsNumber >= (max !== null && max !== void 0 ? max : Number.MAX_SAFE_INTEGER), onPointerDown: increment }, props, { children: children || (jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "18 15 12 9 6 15" }) })) })));
821
+ }
822
+
823
+ function DecrementStepper(_a) {
824
+ var { size = 12, children, className } = _a, props = __rest(_a, ["size", "children", "className"]);
825
+ const min = useNumberInputContext((s) => s.min);
826
+ const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber);
827
+ const keepWithinRange = useNumberInputContext((s) => s.keepWithinRange);
828
+ const decrement = useNumberInputContext((s) => s.decrement);
829
+ // TODO: add long press event
830
+ return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-number-input-decrement-stepper', className), role: "button", tabIndex: -1, "aria-disabled": keepWithinRange && valueAsNumber <= (min !== null && min !== void 0 ? min : Number.MIN_SAFE_INTEGER), onPointerDown: decrement }, props, { children: children || (jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" }) })) })));
831
+ }
832
+
833
+ function InternalInput(_a) {
834
+ var { min, max, step, defaultValue, units, disabled, digit, selectWithFocus, blurOnEnter, keepWithinRange, clampValueOnBlur, wheel, keyboard, wrapperClassName, className, onChange, onFocus, onBlur, children: _children } = _a, props = __rest(_a, ["min", "max", "step", "defaultValue", "units", "disabled", "digit", "selectWithFocus", "blurOnEnter", "keepWithinRange", "clampValueOnBlur", "wheel", "keyboard", "wrapperClassName", "className", "onChange", "onFocus", "onBlur", "children"]);
835
+ const [editing, setEditing] = React.useState(false);
836
+ const value = useNumberInputContext((s) => s.value);
837
+ const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber);
838
+ const change = useNumberInputContext((s) => s.change);
839
+ const error = React.useMemo(() => {
840
+ if (editing)
841
+ return false;
842
+ const v = valueAsNumber;
843
+ return (min !== null && min !== void 0 ? min : -Infinity) > v || v > (max !== null && max !== void 0 ? max : Infinity);
844
+ }, [editing, max, min, valueAsNumber]);
845
+ return (jsxRuntime.jsx("input", Object.assign({ className: clsx('tremolo-number-input', className), value: value, min: min, max: max, step: step, type: "text", disabled: disabled, tabIndex: -1, "data-error": error, onChange: (event) => {
728
846
  const v = event.currentTarget.value;
729
- setShowValue(v);
730
- const newValue = clamp(parseValue(v, units, digit, defaultValue).rawValue, min !== null && min !== void 0 ? min : -Infinity, max !== null && max !== void 0 ? max : Infinity);
731
- if (onChange)
732
- onChange(newValue, event);
847
+ change(v);
848
+ const valueAsNumber = parseValue(v, units, digit).rawValue;
849
+ onChange === null || onChange === void 0 ? void 0 : onChange(valueAsNumber, v);
733
850
  }, onFocus: (event) => {
851
+ setEditing(true);
734
852
  const v = event.currentTarget.value;
735
- const parsed = parseValue(v, units, digit, defaultValue);
853
+ const parsed = parseValue(v, units, digit);
736
854
  if (selectWithFocus == 'all') {
737
855
  event.currentTarget.setSelectionRange(0, v.length);
738
856
  }
739
857
  else if (selectWithFocus == 'number') {
740
858
  event.currentTarget.setSelectionRange(0, parsed.formatValue.length - parsed.unit.length);
741
859
  }
742
- if (onFocus)
743
- onFocus(parsed.rawValue, event);
860
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(parsed.rawValue, parsed.formatValue, event);
744
861
  }, onBlur: (event) => {
862
+ setEditing(false);
745
863
  // update value
746
- const v = event.currentTarget.value;
747
- const parsed = parseValue(v, units, digit, defaultValue);
748
- setShowValue(parsed.formatValue);
749
- if (onBlur)
750
- onBlur(parsed.rawValue, event);
864
+ let v = parseValue(event.currentTarget.value, units, digit).rawValue;
865
+ if (clampValueOnBlur) {
866
+ v = safeClamp(v, min, max);
867
+ }
868
+ const parsed = parseValue(String(v), units, digit);
869
+ change(parsed.formatValue);
870
+ if (clampValueOnBlur) {
871
+ onChange === null || onChange === void 0 ? void 0 : onChange(parsed.rawValue, parsed.formatValue);
872
+ }
873
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(parsed.rawValue, parsed.formatValue, event);
751
874
  }, onKeyDown: (event) => {
752
- if (blurWithEnter && event.key == 'Enter') {
875
+ if (blurOnEnter && event.key == 'Enter') {
753
876
  event.currentTarget.blur();
754
877
  }
755
878
  } }, props)));
756
879
  }
880
+ /**
881
+ * Input with some useful functions for entering numerical values.
882
+ * @category NumberInput
883
+ */
884
+ function NumberInput(_a) {
885
+ var { value, min, max, step = 1, defaultValue, units, disabled = false, digit, selectWithFocus = 'none', blurOnEnter = true, keepWithinRange = true, clampValueOnBlur = true, wheel = ['raw', 1], keyboard = ['raw', 1], wrapperClassName, className, onChange, onFocus, onBlur, children } = _a, props = __rest(_a, ["value", "min", "max", "step", "defaultValue", "units", "disabled", "digit", "selectWithFocus", "blurOnEnter", "keepWithinRange", "clampValueOnBlur", "wheel", "keyboard", "wrapperClassName", "className", "onChange", "onFocus", "onBlur", "children"]);
886
+ return (jsxRuntime.jsx(NumberInputProvider, { value: String(value), min: min, max: max, step: step, units: units, digit: digit, keepWithinRange: keepWithinRange, onChange: onChange, children: jsxRuntime.jsxs("div", { className: clsx('tremolo-number-input-wrapper', wrapperClassName),
887
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
888
+ tabIndex: 0, "data-stepper": !!children, children: [jsxRuntime.jsx(InternalInput, Object.assign({ min: min, max: max, step: step, defaultValue: defaultValue, units: units, disabled: disabled, digit: digit, selectWithFocus: selectWithFocus, blurOnEnter: blurOnEnter, keepWithinRange: keepWithinRange, clampValueOnBlur: clampValueOnBlur, wheel: wheel, keyboard: keyboard, wrapperClassName: wrapperClassName, className: className, onChange: onChange, onFocus: onFocus, onBlur: onBlur }, props)), children] }) }));
889
+ }
757
890
 
891
+ /** @category Piano */
758
892
  function KeyLabel(_a) {
759
893
  var { label, className, wrapperClassName, wrapperStyle, __note, __index, __label } = _a, props = __rest(_a, ["label", "className", "wrapperClassName", "wrapperStyle", "__note", "__index", "__label"]);
760
894
  const content = label
@@ -763,9 +897,11 @@ function KeyLabel(_a) {
763
897
  return ((content != undefined || content != null) && (jsxRuntime.jsx("div", { className: clsx('tremolo-piano-key-label-wrapper', wrapperClassName), style: wrapperStyle, children: jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-piano-key-label', className) }, props, { children: content })) })));
764
898
  }
765
899
 
900
+ /** @category Piano */
766
901
  const defaultWhiteKeyWidth = 40;
902
+ /** @category Piano */
767
903
  const WhiteKey = React.forwardRef((_a, ref) => {
768
- var { width = defaultWhiteKeyWidth, height = '100%', className, style, children, __glissando, __position, __note, __disabled, __index, __fill, __width, __playNote, __stopNote, __label } = _a, props = __rest(_a, ["width", "height", "className", "style", "children", "__glissando", "__position", "__note", "__disabled", "__index", "__fill", "__width", "__playNote", "__stopNote", "__label"]);
904
+ var { width = defaultWhiteKeyWidth, height = '100%', className, style, children, __glissando, __position, __note, __disabled, __index, __fill, __width, __onPlayNote, __onStopNote, __label } = _a, props = __rest(_a, ["width", "height", "className", "style", "children", "__glissando", "__position", "__note", "__disabled", "__index", "__fill", "__width", "__onPlayNote", "__onStopNote", "__label"]);
769
905
  const [played, setPlayed] = React.useState(false);
770
906
  React.useImperativeHandle(ref, () => {
771
907
  return {
@@ -773,19 +909,19 @@ const WhiteKey = React.forwardRef((_a, ref) => {
773
909
  if (__disabled)
774
910
  return;
775
911
  setPlayed(true);
776
- if (__playNote)
777
- __playNote(__note);
912
+ if (__onPlayNote)
913
+ __onPlayNote(__note);
778
914
  },
779
915
  stop() {
780
916
  setPlayed(false);
781
- if (__stopNote)
782
- __stopNote(__note);
917
+ if (__onStopNote)
918
+ __onStopNote(__note);
783
919
  },
784
920
  played() {
785
921
  return played;
786
922
  },
787
923
  };
788
- }, [__disabled, __note, __playNote, __stopNote, played]);
924
+ }, [__disabled, __note, __onPlayNote, __onStopNote, played]);
789
925
  let keyLabelProps = {};
790
926
  if (children != undefined) {
791
927
  React.Children.forEach(children, (child) => {
@@ -806,33 +942,36 @@ const WhiteKey = React.forwardRef((_a, ref) => {
806
942
  if (__disabled)
807
943
  return;
808
944
  setPlayed(true);
809
- if (__playNote)
810
- __playNote(__note);
945
+ if (__onPlayNote)
946
+ __onPlayNote(__note);
811
947
  }, onPointerEnter: () => {
812
948
  if (__disabled)
813
949
  return;
814
950
  if (__glissando) {
815
951
  setPlayed(true);
816
- if (__playNote)
817
- __playNote(__note);
952
+ if (__onPlayNote)
953
+ __onPlayNote(__note);
818
954
  }
819
955
  }, onPointerUp: () => {
820
956
  if (__disabled)
821
957
  return;
822
958
  setPlayed(false);
823
- if (__stopNote)
824
- __stopNote(__note);
959
+ if (__onStopNote)
960
+ __onStopNote(__note);
825
961
  }, onPointerLeave: () => {
826
962
  if (__disabled)
827
963
  return;
828
- setPlayed(false);
829
- if (__stopNote)
830
- __stopNote(__note);
964
+ if (__glissando) {
965
+ setPlayed(false);
966
+ if (__onStopNote)
967
+ __onStopNote(__note);
968
+ }
831
969
  } }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
832
970
  });
833
971
 
972
+ /** @category Piano */
834
973
  const BlackKey = React.forwardRef((_a, ref) => {
835
- var { width = defaultWhiteKeyWidth * 0.65, height = '60%', className, style, children, __glissando, __position, __note, __disabled, __index, __fill, __width, __playNote, __stopNote, __label } = _a, props = __rest(_a, ["width", "height", "className", "style", "children", "__glissando", "__position", "__note", "__disabled", "__index", "__fill", "__width", "__playNote", "__stopNote", "__label"]);
974
+ var { width = defaultWhiteKeyWidth * 0.65, height = '60%', className, style, children, __glissando, __position, __note, __disabled, __index, __fill, __width, __onPlayNote, __onStopNote, __label } = _a, props = __rest(_a, ["width", "height", "className", "style", "children", "__glissando", "__position", "__note", "__disabled", "__index", "__fill", "__width", "__onPlayNote", "__onStopNote", "__label"]);
836
975
  const [played, setPlayed] = React.useState(false);
837
976
  React.useImperativeHandle(ref, () => {
838
977
  return {
@@ -840,19 +979,19 @@ const BlackKey = React.forwardRef((_a, ref) => {
840
979
  if (__disabled)
841
980
  return;
842
981
  setPlayed(true);
843
- if (__playNote)
844
- __playNote(__note);
982
+ if (__onPlayNote)
983
+ __onPlayNote(__note);
845
984
  },
846
985
  stop() {
847
986
  setPlayed(false);
848
- if (__stopNote)
849
- __stopNote(__note);
987
+ if (__onStopNote)
988
+ __onStopNote(__note);
850
989
  },
851
990
  played() {
852
991
  return played;
853
992
  },
854
993
  };
855
- }, [__disabled, __note, __playNote, __stopNote, played]);
994
+ }, [__disabled, __note, __onPlayNote, __onStopNote, played]);
856
995
  let keyLabelProps = {};
857
996
  if (children != undefined) {
858
997
  React.Children.forEach(children, (child) => {
@@ -873,31 +1012,34 @@ const BlackKey = React.forwardRef((_a, ref) => {
873
1012
  if (__disabled)
874
1013
  return;
875
1014
  setPlayed(true);
876
- if (__playNote)
877
- __playNote(__note);
1015
+ if (__onPlayNote)
1016
+ __onPlayNote(__note);
878
1017
  }, onPointerEnter: () => {
879
1018
  if (__disabled)
880
1019
  return;
881
1020
  if (__glissando) {
882
1021
  setPlayed(true);
883
- if (__playNote)
884
- __playNote(__note);
1022
+ if (__onPlayNote)
1023
+ __onPlayNote(__note);
885
1024
  }
886
1025
  }, onPointerUp: () => {
887
1026
  if (__disabled)
888
1027
  return;
889
1028
  setPlayed(false);
890
- if (__stopNote)
891
- __stopNote(__note);
1029
+ if (__onStopNote)
1030
+ __onStopNote(__note);
892
1031
  }, onPointerLeave: () => {
893
1032
  if (__disabled)
894
1033
  return;
895
- setPlayed(false);
896
- if (__stopNote)
897
- __stopNote(__note);
1034
+ if (__glissando) {
1035
+ setPlayed(false);
1036
+ if (__onStopNote)
1037
+ __onStopNote(__note);
1038
+ }
898
1039
  } }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
899
1040
  });
900
1041
 
1042
+ /** @category Piano */
901
1043
  const Shortcuts = {
902
1044
  HOME_ROW: {
903
1045
  keys: [
@@ -922,8 +1064,9 @@ const Shortcuts = {
922
1064
  },
923
1065
  };
924
1066
 
1067
+ /** @category Piano */
925
1068
  function Piano(_a) {
926
- var { noteRange, glissando = true, midiMax = 127, keyboardShortcuts, fill = false, height = fill ? '100%' : 160, style, className, playNote, stopNote, label, children } = _a, props = __rest(_a, ["noteRange", "glissando", "midiMax", "keyboardShortcuts", "fill", "height", "style", "className", "playNote", "stopNote", "label", "children"]);
1069
+ var { noteRange, glissando = true, midiMax = 127, keyboardShortcuts, fill = false, height = fill ? '100%' : 160, style, className, onPlayNote, onStopNote, label, children } = _a, props = __rest(_a, ["noteRange", "glissando", "midiMax", "keyboardShortcuts", "fill", "height", "style", "className", "onPlayNote", "onStopNote", "label", "children"]);
927
1070
  // -- state and ref ---
928
1071
  const [pressed, setPressed] = React.useState(false);
929
1072
  const [whiteNoteWidth, setWhiteNoteWidth] = React.useState(-1);
@@ -998,7 +1141,7 @@ function Piano(_a) {
998
1141
  setWhiteNoteWidth((whiteKeyProps === null || whiteKeyProps === void 0 ? void 0 : whiteKeyProps.width) || defaultWhiteKeyWidth);
999
1142
  }
1000
1143
  }, [fill, whiteKeyProps === null || whiteKeyProps === void 0 ? void 0 : whiteKeyProps.width, whiteNoteCount]);
1001
- useEventListener(window, 'keydown', (e) => {
1144
+ useEventListener(globalThis.window, 'keydown', (e) => {
1002
1145
  var _a, _b, _c, _d;
1003
1146
  if (e.repeat)
1004
1147
  return;
@@ -1011,7 +1154,7 @@ function Piano(_a) {
1011
1154
  }
1012
1155
  }
1013
1156
  });
1014
- useEventListener(window, 'keyup', (e) => {
1157
+ useEventListener(globalThis.window, 'keyup', (e) => {
1015
1158
  var _a, _b;
1016
1159
  if (e.repeat)
1017
1160
  return;
@@ -1031,35 +1174,46 @@ function Piano(_a) {
1031
1174
  props.onPointerUp(e);
1032
1175
  setPressed(false);
1033
1176
  } }, props, { children: noteRangeArray.map((note, index) => {
1034
- return isWhiteKey(note) ? (jsxRuntime.jsx(WhiteKey, Object.assign({ ref: keyRefs.current[index], __glissando: glissando && pressed, __position: notePosition(note), __note: note, __disabled: note > midiMax, __index: index, __fill: fill, __width: whiteNoteWidth, __playNote: playNote, __stopNote: stopNote, __label: label }, whiteKeyProps), note)) : (jsxRuntime.jsx(BlackKey, Object.assign({ ref: keyRefs.current[index], __glissando: glissando && pressed, __position: notePosition(note), __note: note, __disabled: note > midiMax, __index: index, __fill: fill, __width: whiteNoteWidth * 0.65, __playNote: playNote, __stopNote: stopNote, __label: label }, blackKeyProps), note));
1177
+ return isWhiteKey(note) ? (jsxRuntime.jsx(WhiteKey, Object.assign({ ref: keyRefs.current[index], __glissando: glissando && pressed, __position: notePosition(note), __note: note, __disabled: note > midiMax, __index: index, __fill: fill, __width: whiteNoteWidth, __onPlayNote: onPlayNote, __onStopNote: onStopNote, __label: label }, whiteKeyProps), note)) : (jsxRuntime.jsx(BlackKey, Object.assign({ ref: keyRefs.current[index], __glissando: glissando && pressed, __position: notePosition(note), __note: note, __disabled: note > midiMax, __index: index, __fill: fill, __width: whiteNoteWidth * 0.65, __onPlayNote: onPlayNote, __onStopNote: onStopNote, __label: label }, blackKeyProps), note));
1035
1178
  }) })));
1036
1179
  }
1037
1180
 
1038
- const minContext = React.createContext(0);
1039
- const maxContext = React.createContext(0);
1040
- const stepContext = React.createContext(0);
1041
- const skewContext = React.createContext(0);
1042
- const verticalContext = React.createContext(false);
1043
- const reverseContext = React.createContext(false);
1044
- const disabledContext = React.createContext(false);
1045
- function SliderValuesProvider({ min: _min, max: _max, step: _step, skew: _skew, vertical: _vertical, reverse: _reverse, disabled: _disabled, children, }) {
1046
- const [min] = React.useState(_min);
1047
- const [max] = React.useState(_max);
1048
- const [step] = React.useState(_step);
1049
- const [skew] = React.useState(_skew);
1050
- const [vertical] = React.useState(_vertical);
1051
- const [reverse] = React.useState(_reverse);
1052
- const [disabled] = React.useState(_disabled);
1053
- return (jsxRuntime.jsx(minContext.Provider, { value: min, children: jsxRuntime.jsx(maxContext.Provider, { value: max, children: jsxRuntime.jsx(stepContext.Provider, { value: step, children: jsxRuntime.jsx(skewContext.Provider, { value: skew, children: jsxRuntime.jsx(verticalContext.Provider, { value: vertical, children: jsxRuntime.jsx(reverseContext.Provider, { value: reverse, children: jsxRuntime.jsx(disabledContext.Provider, { value: disabled, children: children }) }) }) }) }) }) }));
1181
+ const createSliderStore = (initProps) => {
1182
+ const DEFAULT_PROPS = {
1183
+ min: 0,
1184
+ max: 0,
1185
+ step: 0,
1186
+ skew: 0,
1187
+ vertical: false,
1188
+ reverse: false,
1189
+ disabled: false,
1190
+ };
1191
+ return createStore()((set) => (Object.assign(Object.assign(Object.assign({}, DEFAULT_PROPS), initProps), { updateMin: (min) => set(() => ({ min: min })), updateMax: (max) => set(() => ({ max: max })), updateStep: (step) => set(() => ({ step: step })), updateSkew: (skew) => set(() => ({ skew: skew })), updateVertical: (vertical) => set(() => ({ vertical: vertical })), updateReverse: (reverse) => set(() => ({ reverse: reverse })), updateDisabled: (disabled) => set(() => ({ disabled: disabled })) })));
1192
+ };
1193
+ const SliderContext = React.createContext(null);
1194
+ function SliderProvider(_a) {
1195
+ var { children } = _a, props = __rest(_a, ["children"]);
1196
+ const storeRef = React.useRef();
1197
+ if (!storeRef.current) {
1198
+ storeRef.current = createSliderStore(props);
1199
+ }
1200
+ React.useEffect(() => {
1201
+ if (storeRef.current) {
1202
+ storeRef.current.setState(props);
1203
+ }
1204
+ else {
1205
+ storeRef.current = createSliderStore(props);
1206
+ }
1207
+ }, [props]);
1208
+ return (jsxRuntime.jsx(SliderContext.Provider, { value: storeRef.current, children: children }));
1209
+ }
1210
+ /** @category Slider */
1211
+ function useSliderContext(selector) {
1212
+ const store = React.useContext(SliderContext);
1213
+ if (!store)
1214
+ throw new Error('Missing SliderContext.Provider in the tree');
1215
+ return useStore(store, selector);
1054
1216
  }
1055
- const useMin = () => React.useContext(minContext);
1056
- const useMax = () => React.useContext(maxContext);
1057
- const useStep = () => React.useContext(stepContext);
1058
- const useSkew = () => React.useContext(skewContext);
1059
- const useVertical = () => React.useContext(verticalContext);
1060
- // export const useSetVertical = () => useContext(setVerticalContext)
1061
- const useReverse = () => React.useContext(reverseContext);
1062
- const useDisabled = () => React.useContext(disabledContext);
1063
1217
 
1064
1218
  /**
1065
1219
  * clamp value between min and max
@@ -1095,28 +1249,30 @@ function generateOptionsList(options, min, max, step) {
1095
1249
  return optionsList;
1096
1250
  }
1097
1251
 
1252
+ /** @category Slider */
1098
1253
  function ScaleOption(_a) {
1099
1254
  var { value, type = 'mark-number', label, thickness = 1, length = '0.5rem', gap = 2, labelWidth, classes, styles, className, style } = _a, props = __rest(_a, ["value", "type", "label", "thickness", "length", "gap", "labelWidth", "classes", "styles", "className", "style"]);
1100
- const min = useMin();
1101
- const max = useMax();
1102
- const skew = useSkew();
1103
- const vertical = useVertical();
1104
- const reverse = useReverse();
1255
+ const min = useSliderContext((s) => s.min);
1256
+ const max = useSliderContext((s) => s.max);
1257
+ const skew = useSliderContext((s) => s.skew);
1258
+ const vertical = useSliderContext((s) => s.vertical);
1259
+ const reverse = useSliderContext((s) => s.reverse);
1105
1260
  const calcPercent = React.useCallback((rawValue) => {
1106
- return toFixed$2(xor(vertical, reverse)
1261
+ return toFixed$1(xor(vertical, reverse)
1107
1262
  ? 100 - normalizeValue(rawValue, min, max, skew) * 100
1108
1263
  : normalizeValue(rawValue, min, max, skew) * 100);
1109
1264
  }, [vertical, reverse, max, min, skew]);
1110
1265
  return (jsxRuntime.jsxs("div", Object.assign({ className: clsx('tremolo-slider-scale-option', className), style: Object.assign({ left: !vertical ? `${calcPercent(value)}%` : undefined, top: vertical ? `${calcPercent(value)}%` : undefined }, style), "data-vertical": vertical }, props, { children: [type != 'number' && (jsxRuntime.jsx("div", { className: clsx('tremolo-slider-scale-option-mark', classes === null || classes === void 0 ? void 0 : classes.mark), style: Object.assign({ width: !vertical ? thickness : length, height: vertical ? thickness : length, marginBottom: !vertical ? gap : undefined, marginRight: vertical ? gap : undefined }, styles === null || styles === void 0 ? void 0 : styles.mark), "data-vertical": vertical })), type != 'mark' && (jsxRuntime.jsx("div", { className: clsx('tremolo-slider-scale-option-label', classes === null || classes === void 0 ? void 0 : classes.label), style: Object.assign({ width: labelWidth }, styles === null || styles === void 0 ? void 0 : styles.label), children: label || value }))] })));
1111
1266
  }
1112
1267
 
1268
+ /** @category Slider */
1113
1269
  function Scale(_a) {
1114
1270
  var { gap = 6, options, children, className, style } = _a, props = __rest(_a, ["gap", "options", "children", "className", "style"]);
1115
- const min = useMin();
1116
- const max = useMax();
1117
- const step = useStep();
1118
- const vertical = useVertical();
1119
- const reverse = useReverse();
1271
+ const min = useSliderContext((s) => s.min);
1272
+ const max = useSliderContext((s) => s.max);
1273
+ const step = useSliderContext((s) => s.step);
1274
+ const vertical = useSliderContext((s) => s.vertical);
1275
+ const reverse = useSliderContext((s) => s.reverse);
1120
1276
  const optionsList = options
1121
1277
  ? generateOptionsList(options, min, max, step)
1122
1278
  : [];
@@ -1129,11 +1285,13 @@ function Scale(_a) {
1129
1285
  : children })));
1130
1286
  }
1131
1287
 
1288
+ /** @category Slider */
1132
1289
  const defaultThumbSize = 22;
1290
+ /** @category Slider */
1133
1291
  const SliderThumb = React.forwardRef(({ size, width = defaultThumbSize, height = defaultThumbSize, children, className, style, __percent, }, ref) => {
1134
1292
  const wrapperRef = React.useRef(null);
1135
- const vertical = useVertical();
1136
- const disabled = useDisabled();
1293
+ const vertical = useSliderContext((s) => s.vertical);
1294
+ const disabled = useSliderContext((s) => s.disabled);
1137
1295
  React.useImperativeHandle(ref, () => {
1138
1296
  return {
1139
1297
  focus() {
@@ -1156,24 +1314,30 @@ const SliderThumb = React.forwardRef(({ size, width = defaultThumbSize, height =
1156
1314
  tabIndex: 0, "aria-disabled": disabled, style: Object.assign({ width: size !== null && size !== void 0 ? size : width, height: size !== null && size !== void 0 ? size : height }, style) })) }));
1157
1315
  });
1158
1316
 
1317
+ /** @category Slider */
1159
1318
  const defaultLength = 140;
1319
+ /** @category Slider */
1160
1320
  const defaultThickness = 10;
1161
- function SliderTrack({ length = defaultLength, thickness = defaultThickness, active, inactive, children, className, style, __thumb, __percent, }) {
1162
- const vertical = useVertical();
1163
- const reverse = useReverse();
1164
- const disabled = useDisabled();
1321
+ /** @category Slider */
1322
+ function SliderTrack({ length = defaultLength, thickness = defaultThickness, active, inactive, children, className, style, defaultStyle = true, __thumb, __percent = 0, }) {
1323
+ const vertical = useSliderContext((s) => s.vertical);
1324
+ const reverse = useSliderContext((s) => s.reverse);
1325
+ const disabled = useSliderContext((s) => s.disabled);
1165
1326
  const direction = vertical ? 'bottom' : 'right';
1166
1327
  const colors = {
1167
1328
  '--active': active,
1168
1329
  '--inactive': inactive,
1169
1330
  };
1170
- return (jsxRuntime.jsxs("div", { className: clsx('tremolo-slider-track', className), "aria-disabled": disabled, style: Object.assign(Object.assign(Object.assign({}, colors), { background: xor(vertical, reverse)
1171
- ? `linear-gradient(to ${direction}, var(--inactive, #eee) ${__percent}%, var(--active, #7998ec) ${__percent}%)`
1172
- : `linear-gradient(to ${direction}, var(--active, #7998ec) ${__percent}%, var(--inactive, #eee) ${__percent}%)`, borderRadius: styleHelper(thickness, '/', 2), width: !vertical ? length : thickness, height: vertical ? length : thickness }), style), children: [children, __thumb] }));
1331
+ return (jsxRuntime.jsxs("div", { className: clsx('tremolo-slider-track', className), "aria-disabled": disabled, "data-vertical": vertical, style: !defaultStyle
1332
+ ? style
1333
+ : Object.assign(Object.assign(Object.assign({}, colors), { background: xor(vertical, reverse)
1334
+ ? `linear-gradient(to ${direction}, var(--inactive, #eee) ${__percent}%, var(--active, #7998ec) ${__percent}%)`
1335
+ : `linear-gradient(to ${direction}, var(--active, #7998ec) ${__percent}%, var(--inactive, #eee) ${__percent}%)`, borderRadius: styleHelper(thickness, '/', 2), width: !vertical ? length : thickness, height: vertical ? length : thickness }), style), children: [children, __thumb] }));
1173
1336
  }
1174
1337
 
1175
1338
  /**
1176
1339
  * Customizable slider
1340
+ * @category Slider
1177
1341
  */
1178
1342
  const Slider = React.forwardRef((_a, ref) => {
1179
1343
  var _b, _c, _d;
@@ -1183,8 +1347,8 @@ const Slider = React.forwardRef((_a, ref) => {
1183
1347
  const thumbRef = React.useRef(null);
1184
1348
  const thumbDragged = React.useRef(false);
1185
1349
  // --- interpret props ---
1186
- const p = toFixed$2(normalizeValue(value, min, max, skew) * 100);
1187
- const rev = toFixed$2(100 - p);
1350
+ const p = toFixed$1(normalizeValue(value, min, max, skew) * 100);
1351
+ const rev = toFixed$1(100 - p);
1188
1352
  // NOTE
1189
1353
  // normal -> normal (right)
1190
1354
  // vertical -> rev (up)
@@ -1287,10 +1451,10 @@ const Slider = React.forwardRef((_a, ref) => {
1287
1451
  }, {
1288
1452
  passive: false,
1289
1453
  }, [wheel, value, min, max, skew, step]);
1290
- useEventListener(window, 'mousemove', (event) => {
1454
+ useEventListener(globalThis.window, 'mousemove', (event) => {
1291
1455
  handleValue(event);
1292
1456
  });
1293
- useEventListener(window, 'mouseup', () => {
1457
+ useEventListener(globalThis.window, 'mouseup', () => {
1294
1458
  thumbDragged.current = false;
1295
1459
  if (bodyNoSelect)
1296
1460
  removeNoSelect();
@@ -1307,7 +1471,7 @@ const Slider = React.forwardRef((_a, ref) => {
1307
1471
  },
1308
1472
  };
1309
1473
  }, []);
1310
- return (jsxRuntime.jsx(SliderValuesProvider, { min: min, max: max, step: step, skew: skew, vertical: vertical, reverse: reverse, disabled: disabled, children: jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-slider', className), ref: (div) => {
1474
+ return (jsxRuntime.jsx(SliderProvider, { min: min, max: max, step: step, skew: skew, vertical: vertical, reverse: reverse, disabled: disabled, children: jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-slider', className), ref: (div) => {
1311
1475
  wheelRefCallback(div);
1312
1476
  touchMoveRefCallback(div);
1313
1477
  }, tabIndex: -1, role: "slider", "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": vertical ? 'vertical' : 'horizontal', "aria-disabled": disabled, "aria-readonly": readonly, style: Object.assign({ margin: `calc(${styleHelper((_b = thumbProps === null || thumbProps === void 0 ? void 0 : thumbProps.size) !== null && _b !== void 0 ? _b : 22)} / 2)` }, style), onPointerDown: (event) => {
@@ -1316,9 +1480,12 @@ const Slider = React.forwardRef((_a, ref) => {
1316
1480
  }, onKeyDown: handleKeyDown, onFocus: (_c = thumbRef.current) === null || _c === void 0 ? void 0 : _c.focus, onBlur: (_d = thumbRef.current) === null || _d === void 0 ? void 0 : _d.blur }, props, { children: jsxRuntime.jsxs("div", { style: {
1317
1481
  display: 'flex',
1318
1482
  flexDirection: vertical ? 'row' : 'column',
1483
+ width: !vertical ? '100%' : undefined,
1484
+ height: vertical ? '100%' : undefined,
1319
1485
  }, children: [jsxRuntime.jsx("div", { className: "tremolo-slider-track-wrapper", ref: trackElementRef, children: jsxRuntime.jsx(SliderTrack, Object.assign({ __percent: percent, __thumb: jsxRuntime.jsx(SliderThumb, Object.assign({ ref: thumbRef, __percent: percent }, thumbProps)) }, trackProps)) }), scaleComponent] }) })) }));
1320
1486
  });
1321
1487
 
1488
+ /** @category WheelObserver */
1322
1489
  function WheelObserver(props) {
1323
1490
  const { children, onWheel, as: Component = 'div' } = props, attributes = __rest(props, ["children", "onWheel", "as"]);
1324
1491
  const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
@@ -1328,10 +1495,12 @@ function WheelObserver(props) {
1328
1495
  return (jsxRuntime.jsx(Component, Object.assign({ ref: wheelRefCallback }, attributes, { children: children })));
1329
1496
  }
1330
1497
 
1498
+ /** @category XYPad */
1331
1499
  function XYPadArea({ width = 120, height = 120, bg = '#eee', children, className, style, __thumb, }) {
1332
1500
  return (jsxRuntime.jsxs("div", { className: clsx('tremolo-xy-pad-area', className), style: Object.assign({ position: 'relative', width: width, height: height, background: bg }, style), children: [children, __thumb] }));
1333
1501
  }
1334
1502
 
1503
+ /** @category XYPad */
1335
1504
  const XYPadThumb = React.forwardRef(({ size, width = 22, height = 22, children, wrapperClassName, wrapperStyle, className, style, __disabled, __css, }, ref) => {
1336
1505
  const wrapperRef = React.useRef(null);
1337
1506
  React.useImperativeHandle(ref, () => {
@@ -1362,6 +1531,7 @@ const defaultValueOptions = {
1362
1531
  };
1363
1532
  /**
1364
1533
  * Simple XYPad
1534
+ * @category XYPad
1365
1535
  */
1366
1536
  const XYPad = React.forwardRef((_a, ref) => {
1367
1537
  var _b, _c, _d;
@@ -1379,8 +1549,8 @@ const XYPad = React.forwardRef((_a, ref) => {
1379
1549
  // --- interpret props ---
1380
1550
  const nx = normalizeValue(x.value, x.min, x.max, x.skew);
1381
1551
  const ny = normalizeValue(y.value, y.min, y.max, y.skew);
1382
- const percentX = toFixed$2((x.reverse ? 1 - nx : nx) * 100);
1383
- const percentY = toFixed$2((y.reverse ? 1 - ny : ny) * 100);
1552
+ const percentX = toFixed$1((x.reverse ? 1 - nx : nx) * 100);
1553
+ const percentY = toFixed$1((y.reverse ? 1 - ny : ny) * 100);
1384
1554
  let areaProps = {}, thumbProps = {};
1385
1555
  if (children != undefined) {
1386
1556
  React.Children.forEach(children, (child) => {
@@ -1487,10 +1657,10 @@ const XYPad = React.forwardRef((_a, ref) => {
1487
1657
  }, {
1488
1658
  passive: false,
1489
1659
  }, [x, y]);
1490
- useEventListener(window, 'mousemove', (event) => {
1660
+ useEventListener(globalThis.window, 'mousemove', (event) => {
1491
1661
  handleValue(event);
1492
1662
  });
1493
- useEventListener(window, 'mouseup', () => {
1663
+ useEventListener(globalThis.window, 'mouseup', () => {
1494
1664
  thumbDragged.current = false;
1495
1665
  if (bodyNoSelect)
1496
1666
  removeNoSelect();
@@ -1524,7 +1694,9 @@ const XYPad = React.forwardRef((_a, ref) => {
1524
1694
  exports.AnimationCanvas = AnimationCanvas;
1525
1695
  exports.AnimationKnob = AnimationKnob;
1526
1696
  exports.BlackKey = BlackKey;
1697
+ exports.DecrementStepper = DecrementStepper;
1527
1698
  exports.DragObserver = DragObserver;
1699
+ exports.IncrementStepper = IncrementStepper;
1528
1700
  exports.KeyLabel = KeyLabel;
1529
1701
  exports.Knob = Knob;
1530
1702
  exports.NumberInput = NumberInput;
@@ -1535,20 +1707,11 @@ exports.Shortcuts = Shortcuts;
1535
1707
  exports.Slider = Slider;
1536
1708
  exports.SliderThumb = SliderThumb;
1537
1709
  exports.SliderTrack = SliderTrack;
1538
- exports.SliderValuesProvider = SliderValuesProvider;
1710
+ exports.Stepper = Stepper;
1539
1711
  exports.WheelObserver = WheelObserver;
1540
1712
  exports.WhiteKey = WhiteKey;
1541
1713
  exports.XYPad = XYPad;
1542
1714
  exports.XYPadArea = XYPadArea;
1543
1715
  exports.XYPadThumb = XYPadThumb;
1544
- exports.defaultLength = defaultLength;
1545
- exports.defaultThickness = defaultThickness;
1546
- exports.defaultThumbSize = defaultThumbSize;
1547
- exports.useDisabled = useDisabled;
1548
- exports.useMax = useMax;
1549
- exports.useMin = useMin;
1550
- exports.useReverse = useReverse;
1551
- exports.useSkew = useSkew;
1552
- exports.useStep = useStep;
1553
- exports.useVertical = useVertical;
1716
+ exports.useSliderContext = useSliderContext;
1554
1717
  //# sourceMappingURL=index.js.map