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