@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.
- package/dist/cjs/index.js +432 -269
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/AnimationCanvas/index.d.ts +9 -4
- package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
- package/dist/cjs/types/components/AnimationKnob/index.d.ts +2 -0
- package/dist/cjs/types/components/AnimationKnob/index.d.ts.map +1 -1
- package/dist/cjs/types/components/DragObserver/index.d.ts +3 -1
- package/dist/cjs/types/components/DragObserver/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Knob/index.d.ts +2 -0
- package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts +7 -0
- package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts.map +1 -0
- package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts +7 -0
- package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts.map +1 -0
- package/dist/cjs/types/components/NumberInput/Stepper.d.ts +8 -0
- package/dist/cjs/types/components/NumberInput/Stepper.d.ts.map +1 -0
- package/dist/cjs/types/components/NumberInput/context.d.ts +27 -0
- package/dist/cjs/types/components/NumberInput/context.d.ts.map +1 -0
- package/dist/cjs/types/components/NumberInput/index.d.ts +31 -16
- package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/BlackKey.d.ts +1 -0
- package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/KeyLabel.d.ts +2 -0
- package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts +2 -0
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/index.d.ts +6 -4
- package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/key.d.ts +8 -2
- package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts +2 -0
- package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/Scale.d.ts +2 -0
- package/dist/cjs/types/components/Slider/Scale.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/ScaleOption.d.ts +2 -0
- package/dist/cjs/types/components/Slider/ScaleOption.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/Thumb.d.ts +4 -0
- package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/Track.d.ts +6 -1
- package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/context.d.ts +15 -12
- package/dist/cjs/types/components/Slider/context.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/index.d.ts +8 -5
- package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
- package/dist/cjs/types/components/WheelObserver/index.d.ts +1 -0
- package/dist/cjs/types/components/WheelObserver/index.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/Area.d.ts +2 -0
- package/dist/cjs/types/components/XYPad/Area.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/Thumb.d.ts +3 -0
- package/dist/cjs/types/components/XYPad/Thumb.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/index.d.ts +4 -0
- package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -1
- package/dist/cjs/types/hooks/useAnimationFrame.d.ts +3 -0
- package/dist/cjs/types/hooks/useAnimationFrame.d.ts.map +1 -0
- package/dist/cjs/types/hooks/useDrag.d.ts +15 -0
- package/dist/cjs/types/hooks/useDrag.d.ts.map +1 -0
- package/dist/cjs/types/hooks/useRefCallbackEvent.d.ts +1 -4
- package/dist/cjs/types/hooks/useRefCallbackEvent.d.ts.map +1 -1
- package/dist/esm/index.js +430 -260
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/AnimationCanvas/index.d.ts +9 -4
- package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
- package/dist/esm/types/components/AnimationKnob/index.d.ts +2 -0
- package/dist/esm/types/components/AnimationKnob/index.d.ts.map +1 -1
- package/dist/esm/types/components/DragObserver/index.d.ts +3 -1
- package/dist/esm/types/components/DragObserver/index.d.ts.map +1 -1
- package/dist/esm/types/components/Knob/index.d.ts +2 -0
- package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts +7 -0
- package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts.map +1 -0
- package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts +7 -0
- package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts.map +1 -0
- package/dist/esm/types/components/NumberInput/Stepper.d.ts +8 -0
- package/dist/esm/types/components/NumberInput/Stepper.d.ts.map +1 -0
- package/dist/esm/types/components/NumberInput/context.d.ts +27 -0
- package/dist/esm/types/components/NumberInput/context.d.ts.map +1 -0
- package/dist/esm/types/components/NumberInput/index.d.ts +31 -16
- package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/BlackKey.d.ts +1 -0
- package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/KeyLabel.d.ts +2 -0
- package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/WhiteKey.d.ts +2 -0
- package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/index.d.ts +6 -4
- package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/key.d.ts +8 -2
- package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts +2 -0
- package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/Scale.d.ts +2 -0
- package/dist/esm/types/components/Slider/Scale.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/ScaleOption.d.ts +2 -0
- package/dist/esm/types/components/Slider/ScaleOption.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/Thumb.d.ts +4 -0
- package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/Track.d.ts +6 -1
- package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/context.d.ts +15 -12
- package/dist/esm/types/components/Slider/context.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/index.d.ts +8 -5
- package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
- package/dist/esm/types/components/WheelObserver/index.d.ts +1 -0
- package/dist/esm/types/components/WheelObserver/index.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/Area.d.ts +2 -0
- package/dist/esm/types/components/XYPad/Area.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/Thumb.d.ts +3 -0
- package/dist/esm/types/components/XYPad/Thumb.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/index.d.ts +4 -0
- package/dist/esm/types/components/XYPad/index.d.ts.map +1 -1
- package/dist/esm/types/hooks/useAnimationFrame.d.ts +3 -0
- package/dist/esm/types/hooks/useAnimationFrame.d.ts.map +1 -0
- package/dist/esm/types/hooks/useDrag.d.ts +15 -0
- package/dist/esm/types/hooks/useDrag.d.ts.map +1 -0
- package/dist/esm/types/hooks/useRefCallbackEvent.d.ts +1 -4
- package/dist/esm/types/hooks/useRefCallbackEvent.d.ts.map +1 -1
- package/dist/styles/index.css +110 -14
- package/package.json +5 -2
- package/src/components/AnimationCanvas/index.tsx +13 -4
- package/src/components/AnimationKnob/index.tsx +24 -42
- package/src/components/DragObserver/index.tsx +14 -52
- package/src/components/Knob/index.tsx +23 -40
- package/src/components/NumberInput/DecrementStepper.tsx +52 -0
- package/src/components/NumberInput/IncrementStepper.tsx +52 -0
- package/src/components/NumberInput/Stepper.tsx +25 -0
- package/src/components/NumberInput/context.tsx +150 -0
- package/src/components/NumberInput/index.css +102 -14
- package/src/components/NumberInput/index.tsx +164 -55
- package/src/components/Piano/BlackKey.tsx +13 -10
- package/src/components/Piano/KeyLabel.tsx +2 -0
- package/src/components/Piano/WhiteKey.tsx +14 -10
- package/src/components/Piano/index.tsx +13 -11
- package/src/components/Piano/key.ts +8 -2
- package/src/components/Piano/keyboardShortcuts.ts +2 -0
- package/src/components/Slider/Scale.tsx +8 -6
- package/src/components/Slider/ScaleOption.tsx +8 -6
- package/src/components/Slider/Thumb.tsx +7 -3
- package/src/components/Slider/Track.tsx +27 -15
- package/src/components/Slider/context.tsx +65 -51
- package/src/components/Slider/index.css +8 -0
- package/src/components/Slider/index.tsx +19 -10
- package/src/components/WheelObserver/index.tsx +1 -0
- package/src/components/XYPad/Area.tsx +2 -0
- package/src/components/XYPad/Thumb.tsx +3 -0
- package/src/components/XYPad/index.tsx +6 -2
- package/src/hooks/useAnimationFrame.ts +18 -0
- package/src/hooks/useDrag.ts +92 -0
- 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$
|
|
195
|
-
const next = toFixed$
|
|
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$
|
|
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
|
-
|
|
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
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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: (
|
|
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
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
572
|
+
const onDrag = React.useCallback((_x, y) => {
|
|
560
573
|
if (!onChange || readonly)
|
|
561
574
|
return;
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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: (
|
|
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
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
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:
|
|
686
|
-
formatValue:
|
|
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 =
|
|
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
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
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
|
-
|
|
722
|
-
*/
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
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
|
-
|
|
730
|
-
const
|
|
731
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
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 (
|
|
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,
|
|
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 (
|
|
777
|
-
|
|
912
|
+
if (__onPlayNote)
|
|
913
|
+
__onPlayNote(__note);
|
|
778
914
|
},
|
|
779
915
|
stop() {
|
|
780
916
|
setPlayed(false);
|
|
781
|
-
if (
|
|
782
|
-
|
|
917
|
+
if (__onStopNote)
|
|
918
|
+
__onStopNote(__note);
|
|
783
919
|
},
|
|
784
920
|
played() {
|
|
785
921
|
return played;
|
|
786
922
|
},
|
|
787
923
|
};
|
|
788
|
-
}, [__disabled, __note,
|
|
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 (
|
|
810
|
-
|
|
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 (
|
|
817
|
-
|
|
952
|
+
if (__onPlayNote)
|
|
953
|
+
__onPlayNote(__note);
|
|
818
954
|
}
|
|
819
955
|
}, onPointerUp: () => {
|
|
820
956
|
if (__disabled)
|
|
821
957
|
return;
|
|
822
958
|
setPlayed(false);
|
|
823
|
-
if (
|
|
824
|
-
|
|
959
|
+
if (__onStopNote)
|
|
960
|
+
__onStopNote(__note);
|
|
825
961
|
}, onPointerLeave: () => {
|
|
826
962
|
if (__disabled)
|
|
827
963
|
return;
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
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,
|
|
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 (
|
|
844
|
-
|
|
982
|
+
if (__onPlayNote)
|
|
983
|
+
__onPlayNote(__note);
|
|
845
984
|
},
|
|
846
985
|
stop() {
|
|
847
986
|
setPlayed(false);
|
|
848
|
-
if (
|
|
849
|
-
|
|
987
|
+
if (__onStopNote)
|
|
988
|
+
__onStopNote(__note);
|
|
850
989
|
},
|
|
851
990
|
played() {
|
|
852
991
|
return played;
|
|
853
992
|
},
|
|
854
993
|
};
|
|
855
|
-
}, [__disabled, __note,
|
|
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 (
|
|
877
|
-
|
|
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 (
|
|
884
|
-
|
|
1022
|
+
if (__onPlayNote)
|
|
1023
|
+
__onPlayNote(__note);
|
|
885
1024
|
}
|
|
886
1025
|
}, onPointerUp: () => {
|
|
887
1026
|
if (__disabled)
|
|
888
1027
|
return;
|
|
889
1028
|
setPlayed(false);
|
|
890
|
-
if (
|
|
891
|
-
|
|
1029
|
+
if (__onStopNote)
|
|
1030
|
+
__onStopNote(__note);
|
|
892
1031
|
}, onPointerLeave: () => {
|
|
893
1032
|
if (__disabled)
|
|
894
1033
|
return;
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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,
|
|
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,
|
|
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
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
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 =
|
|
1101
|
-
const max =
|
|
1102
|
-
const skew =
|
|
1103
|
-
const vertical =
|
|
1104
|
-
const reverse =
|
|
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$
|
|
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 =
|
|
1116
|
-
const max =
|
|
1117
|
-
const step =
|
|
1118
|
-
const vertical =
|
|
1119
|
-
const reverse =
|
|
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 =
|
|
1136
|
-
const disabled =
|
|
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
|
-
|
|
1162
|
-
|
|
1163
|
-
const
|
|
1164
|
-
const
|
|
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,
|
|
1171
|
-
|
|
1172
|
-
|
|
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$
|
|
1187
|
-
const rev = toFixed$
|
|
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(
|
|
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$
|
|
1383
|
-
const percentY = toFixed$
|
|
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.
|
|
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.
|
|
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
|