@tremolo-ui/react 0.0.11 → 0.0.12
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 +428 -196
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/AnimationCanvas/index.d.ts +2 -2
- package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
- package/dist/cjs/types/components/AnimationKnob/index.d.ts +10 -3
- package/dist/cjs/types/components/AnimationKnob/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Knob/index.d.ts +13 -3
- package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts +2 -0
- package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts +2 -0
- package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/InternalInput.d.ts +18 -0
- package/dist/cjs/types/components/NumberInput/InternalInput.d.ts.map +1 -0
- package/dist/cjs/types/components/NumberInput/Stepper.d.ts +2 -0
- package/dist/cjs/types/components/NumberInput/Stepper.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/context.d.ts +3 -2
- package/dist/cjs/types/components/NumberInput/context.d.ts.map +1 -1
- package/dist/cjs/types/components/NumberInput/index.d.ts +12 -3
- package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/index.d.ts +7 -4
- package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/key.d.ts +4 -0
- package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
- package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts +2 -2
- package/dist/cjs/types/components/Slider/Scale.d.ts +1 -3
- package/dist/cjs/types/components/Slider/Scale.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/Thumb.d.ts +1 -0
- package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/Track.d.ts +2 -2
- package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
- package/dist/cjs/types/components/Slider/index.d.ts +5 -1
- package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
- package/dist/cjs/types/components/WheelObserver/index.d.ts +3 -3
- package/dist/cjs/types/components/WheelObserver/index.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/Area.d.ts +3 -3
- package/dist/cjs/types/components/XYPad/Area.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/Thumb.d.ts +1 -0
- package/dist/cjs/types/components/XYPad/Thumb.d.ts.map +1 -1
- package/dist/cjs/types/components/XYPad/index.d.ts +6 -1
- package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -1
- package/dist/cjs/types/hooks/useInterval.d.ts +2 -0
- package/dist/cjs/types/hooks/useInterval.d.ts.map +1 -0
- package/dist/cjs/types/hooks/useLongPress.d.ts +2 -0
- package/dist/cjs/types/hooks/useLongPress.d.ts.map +1 -0
- package/dist/cjs/types/index.d.ts +5 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/esm/index.js +424 -197
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/AnimationCanvas/index.d.ts +2 -2
- package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
- package/dist/esm/types/components/AnimationKnob/index.d.ts +10 -3
- package/dist/esm/types/components/AnimationKnob/index.d.ts.map +1 -1
- package/dist/esm/types/components/Knob/index.d.ts +13 -3
- package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts +2 -0
- package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts +2 -0
- package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/InternalInput.d.ts +18 -0
- package/dist/esm/types/components/NumberInput/InternalInput.d.ts.map +1 -0
- package/dist/esm/types/components/NumberInput/Stepper.d.ts +2 -0
- package/dist/esm/types/components/NumberInput/Stepper.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/context.d.ts +3 -2
- package/dist/esm/types/components/NumberInput/context.d.ts.map +1 -1
- package/dist/esm/types/components/NumberInput/index.d.ts +12 -3
- package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/index.d.ts +7 -4
- package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/key.d.ts +4 -0
- package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
- package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts +2 -2
- package/dist/esm/types/components/Slider/Scale.d.ts +1 -3
- package/dist/esm/types/components/Slider/Scale.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/Thumb.d.ts +1 -0
- package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/Track.d.ts +2 -2
- package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
- package/dist/esm/types/components/Slider/index.d.ts +5 -1
- package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
- package/dist/esm/types/components/WheelObserver/index.d.ts +3 -3
- package/dist/esm/types/components/WheelObserver/index.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/Area.d.ts +3 -3
- package/dist/esm/types/components/XYPad/Area.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/Thumb.d.ts +1 -0
- package/dist/esm/types/components/XYPad/Thumb.d.ts.map +1 -1
- package/dist/esm/types/components/XYPad/index.d.ts +6 -1
- package/dist/esm/types/components/XYPad/index.d.ts.map +1 -1
- package/dist/esm/types/hooks/useInterval.d.ts +2 -0
- package/dist/esm/types/hooks/useInterval.d.ts.map +1 -0
- package/dist/esm/types/hooks/useLongPress.d.ts +2 -0
- package/dist/esm/types/hooks/useLongPress.d.ts.map +1 -0
- package/dist/esm/types/index.d.ts +5 -0
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/styles/index.css +115 -33
- package/package.json +2 -2
- package/src/components/AnimationCanvas/index.tsx +14 -6
- package/src/components/AnimationKnob/index.tsx +216 -187
- package/src/components/Knob/index.tsx +230 -171
- package/src/components/NumberInput/DecrementStepper.tsx +9 -2
- package/src/components/NumberInput/IncrementStepper.tsx +9 -2
- package/src/components/NumberInput/InternalInput.tsx +219 -0
- package/src/components/NumberInput/Stepper.tsx +2 -0
- package/src/components/NumberInput/context.tsx +20 -8
- package/src/components/NumberInput/index.css +76 -22
- package/src/components/NumberInput/index.tsx +94 -162
- package/src/components/Piano/BlackKey.tsx +14 -0
- package/src/components/Piano/WhiteKey.tsx +14 -0
- package/src/components/Piano/index.css +22 -6
- package/src/components/Piano/index.tsx +19 -21
- package/src/components/Piano/key.ts +5 -0
- package/src/components/Piano/keyboardShortcuts.ts +2 -2
- package/src/components/Slider/Scale.tsx +1 -4
- package/src/components/Slider/Thumb.tsx +4 -0
- package/src/components/Slider/Track.tsx +5 -2
- package/src/components/Slider/index.css +5 -2
- package/src/components/Slider/index.tsx +51 -26
- package/src/components/WheelObserver/index.tsx +4 -2
- package/src/components/XYPad/Area.tsx +7 -6
- package/src/components/XYPad/Thumb.tsx +6 -0
- package/src/components/XYPad/index.css +12 -2
- package/src/components/XYPad/index.tsx +57 -41
- package/src/hooks/useInterval.ts +27 -0
- package/src/hooks/useLongPress.ts +31 -0
- package/src/index.ts +6 -0
- package/src/styles/index.css +0 -1
package/dist/cjs/index.js
CHANGED
|
@@ -69,7 +69,7 @@ function setDprConfig(canvas, context, width, height, dpr) {
|
|
|
69
69
|
canvas.style.height = `${height}px`;
|
|
70
70
|
}
|
|
71
71
|
function AnimationCanvas(_a) {
|
|
72
|
-
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"]);
|
|
72
|
+
var { width = 100, height = 100, relativeSize = false, reduceFlickering = true, options, init, draw, className, onContextMenu = (event) => event.preventDefault() } = _a, props = __rest(_a, ["width", "height", "relativeSize", "reduceFlickering", "options", "init", "draw", "className", "onContextMenu"]);
|
|
73
73
|
const canvasRef = React.useRef(null);
|
|
74
74
|
const memoCanvasRef = React.useRef(null);
|
|
75
75
|
const reqIdRef = React.useRef(-1);
|
|
@@ -118,7 +118,11 @@ function AnimationCanvas(_a) {
|
|
|
118
118
|
for (const prop of drawingState) {
|
|
119
119
|
context[prop] = contextMemo[prop];
|
|
120
120
|
}
|
|
121
|
-
if (reduceFlickering &&
|
|
121
|
+
if (reduceFlickering &&
|
|
122
|
+
memoContext &&
|
|
123
|
+
memoCanvas &&
|
|
124
|
+
memoCanvas.width > 0 &&
|
|
125
|
+
memoCanvas.height > 0) {
|
|
122
126
|
context.drawImage(memoContext.canvas, 0, 0);
|
|
123
127
|
}
|
|
124
128
|
}
|
|
@@ -150,7 +154,7 @@ function AnimationCanvas(_a) {
|
|
|
150
154
|
};
|
|
151
155
|
}
|
|
152
156
|
}, [loop, init, options, reduceFlickering, relativeSize]);
|
|
153
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("canvas", Object.assign({ className: clsx('tremolo-animation-canvas', className), width: relativeSize ? 0 : width, height: relativeSize ? 0 : height, ref: canvasRef }, props)), relativeSize && reduceFlickering && (jsxRuntime.jsx("canvas", { style: { display: 'none' }, ref: memoCanvasRef }))] }));
|
|
157
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("canvas", Object.assign({ className: clsx('tremolo-animation-canvas', className), width: relativeSize ? 0 : width, height: relativeSize ? 0 : height, ref: canvasRef, onContextMenu: onContextMenu }, props)), relativeSize && reduceFlickering && (jsxRuntime.jsx("canvas", { style: { display: 'none' }, ref: memoCanvasRef }))] }));
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
/**
|
|
@@ -258,7 +262,7 @@ function xor(a = false, b = false) {
|
|
|
258
262
|
/**
|
|
259
263
|
* @category MIDI
|
|
260
264
|
*/
|
|
261
|
-
const
|
|
265
|
+
const noteKeys = [
|
|
262
266
|
'C',
|
|
263
267
|
'C#',
|
|
264
268
|
'D',
|
|
@@ -292,18 +296,16 @@ function parseNoteName(noteName) {
|
|
|
292
296
|
*/
|
|
293
297
|
function noteNumber(noteName) {
|
|
294
298
|
const { letter, accidental, octave } = parseNoteName(noteName);
|
|
295
|
-
const noteIndex =
|
|
299
|
+
const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase());
|
|
296
300
|
const accidentalValue = (accidental[0] == 'b' ? -1 : 1) * accidental.length;
|
|
297
301
|
return noteIndex + 12 * (Number(octave) + 1) + accidentalValue;
|
|
298
302
|
}
|
|
299
303
|
/**
|
|
300
|
-
* Convert noteNumber to
|
|
304
|
+
* Convert noteNumber to noteKey
|
|
301
305
|
* @category MIDI
|
|
302
306
|
*/
|
|
303
|
-
function
|
|
304
|
-
|
|
305
|
-
const octave = Math.floor(noteNumber / 12) - 1;
|
|
306
|
-
return noteNames[noteIndex] + octave;
|
|
307
|
+
function noteKey(noteNumber) {
|
|
308
|
+
return noteKeys[mod(noteNumber, 12)];
|
|
307
309
|
}
|
|
308
310
|
/**
|
|
309
311
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
@@ -426,13 +428,14 @@ function removeNoSelect() {
|
|
|
426
428
|
}
|
|
427
429
|
|
|
428
430
|
/**
|
|
429
|
-
*
|
|
431
|
+
* Animatable rotary knob.
|
|
430
432
|
* @category AnimationKnob
|
|
431
433
|
*/
|
|
432
|
-
|
|
434
|
+
const AnimationKnob = React.forwardRef((_a, ref) => {
|
|
433
435
|
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"]);
|
|
434
436
|
// -- state and ref ---
|
|
435
437
|
const valueRef = React.useRef(0);
|
|
438
|
+
const elmRef = React.useRef(null);
|
|
436
439
|
// --- interpret props ---
|
|
437
440
|
const isRelativeSize = typeof (size !== null && size !== void 0 ? size : width) == 'string' || typeof height == 'string';
|
|
438
441
|
const onDrag = React.useCallback((_x, y) => {
|
|
@@ -489,14 +492,27 @@ function AnimationKnob(_a) {
|
|
|
489
492
|
if (onChange)
|
|
490
493
|
onChange(clamp(stepValue(v, step), min, max));
|
|
491
494
|
}, { passive: false }, [wheel, value, min, max, skew, step, onChange]);
|
|
495
|
+
React.useImperativeHandle(ref, () => {
|
|
496
|
+
return {
|
|
497
|
+
focus() {
|
|
498
|
+
var _a;
|
|
499
|
+
(_a = elmRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
500
|
+
},
|
|
501
|
+
blur() {
|
|
502
|
+
var _a;
|
|
503
|
+
(_a = elmRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
504
|
+
},
|
|
505
|
+
};
|
|
506
|
+
}, []);
|
|
492
507
|
return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-animation-knob', className), ref: (div) => {
|
|
508
|
+
elmRef.current = div;
|
|
493
509
|
wheelRefCallback(div);
|
|
494
510
|
touchMoveRefCallback(div);
|
|
495
511
|
}, 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: () => {
|
|
496
512
|
if (enableDoubleClickDefault && onChange) {
|
|
497
513
|
onChange(defaultValue);
|
|
498
514
|
}
|
|
499
|
-
}, onKeyDown: handleKeyDown
|
|
515
|
+
}, onKeyDown: handleKeyDown }, props, { children: jsxRuntime.jsx(AnimationCanvas, Object.assign({}, (isRelativeSize
|
|
500
516
|
? { relativeSize: true }
|
|
501
517
|
: {
|
|
502
518
|
width: size !== null && size !== void 0 ? size : width,
|
|
@@ -543,7 +559,7 @@ function AnimationKnob(_a) {
|
|
|
543
559
|
ctx.lineWidth = thumbWeight;
|
|
544
560
|
ctx.stroke();
|
|
545
561
|
} })) })));
|
|
546
|
-
}
|
|
562
|
+
});
|
|
547
563
|
|
|
548
564
|
/** @category DragObserver */
|
|
549
565
|
function DragObserver(props) {
|
|
@@ -557,15 +573,20 @@ function DragObserver(props) {
|
|
|
557
573
|
return (jsxRuntime.jsx(Component, Object.assign({ ref: refCallback, onPointerDown: pointerDownHandler }, attributes, { children: children })));
|
|
558
574
|
}
|
|
559
575
|
|
|
560
|
-
/**
|
|
561
|
-
|
|
562
|
-
|
|
576
|
+
/**
|
|
577
|
+
* Interactive rotary knob component implemented in SVG.
|
|
578
|
+
*
|
|
579
|
+
* @category Knob
|
|
580
|
+
*/
|
|
581
|
+
const Knob = React.forwardRef((_a, ref) => {
|
|
582
|
+
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, onKeyDown, onPointerDown, onDoubleClick, 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", "onKeyDown", "onPointerDown", "onDoubleClick", "className", "classes"]);
|
|
563
583
|
const valueRef = React.useRef(0);
|
|
584
|
+
const elmRef = React.useRef(null);
|
|
564
585
|
// --- interpret props ---
|
|
565
586
|
const padding = 8; // %
|
|
566
587
|
const thumbLineWeight = 6; // %
|
|
567
|
-
const
|
|
568
|
-
const lineWeight =
|
|
588
|
+
const thumbLineLength = 35; // %
|
|
589
|
+
const lineWeight = size * 0.06; // px
|
|
569
590
|
const p = normalizeValue(value, min, max, skew);
|
|
570
591
|
const s = normalizeValue(startValue, min, max, skew);
|
|
571
592
|
// --- internal functions ---
|
|
@@ -576,6 +597,17 @@ function Knob(_a) {
|
|
|
576
597
|
const v2 = clamp(stepValue(v, step), min, max);
|
|
577
598
|
onChange(v2);
|
|
578
599
|
}, [max, min, onChange, readonly, skew, step]);
|
|
600
|
+
const updateValueByEvent = React.useCallback((eventType, x) => {
|
|
601
|
+
let newValue;
|
|
602
|
+
if (eventType == 'normalized') {
|
|
603
|
+
const n = normalizeValue(value, min, max, skew);
|
|
604
|
+
newValue = rawValue(n + x, min, max, skew);
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
newValue = value + x;
|
|
608
|
+
}
|
|
609
|
+
return clamp(stepValue(newValue, step), min, max);
|
|
610
|
+
}, [max, min, skew, step, value]);
|
|
579
611
|
const handleKeyDown = React.useCallback((event) => {
|
|
580
612
|
if (!keyboard || !onChange || readonly)
|
|
581
613
|
return;
|
|
@@ -583,17 +615,9 @@ function Knob(_a) {
|
|
|
583
615
|
if (['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'].includes(key)) {
|
|
584
616
|
event.preventDefault();
|
|
585
617
|
const x = key == 'ArrowRight' || key == 'ArrowUp' ? keyboard[1] : -keyboard[1];
|
|
586
|
-
|
|
587
|
-
if (keyboard[0] == 'normalized') {
|
|
588
|
-
const n = normalizeValue(value, min, max, skew);
|
|
589
|
-
v = rawValue(n + x, min, max, skew);
|
|
590
|
-
}
|
|
591
|
-
else {
|
|
592
|
-
v = value + x;
|
|
593
|
-
}
|
|
594
|
-
onChange(clamp(stepValue(v, step), min, max));
|
|
618
|
+
onChange(updateValueByEvent(keyboard[0], x));
|
|
595
619
|
}
|
|
596
|
-
}, [
|
|
620
|
+
}, [keyboard, onChange, readonly, updateValueByEvent]);
|
|
597
621
|
// --- hooks ---
|
|
598
622
|
const [touchMoveRefCallback, pointerDownHandler] = useDrag({
|
|
599
623
|
onDrag: onDrag,
|
|
@@ -608,21 +632,26 @@ function Knob(_a) {
|
|
|
608
632
|
},
|
|
609
633
|
});
|
|
610
634
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
611
|
-
if (!wheel)
|
|
635
|
+
if (!wheel || readonly)
|
|
612
636
|
return;
|
|
613
637
|
event.preventDefault();
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
638
|
+
if (!onChange || event.deltaY == 0)
|
|
639
|
+
return;
|
|
640
|
+
const x = Math.sign(event.deltaY) * -wheel[1];
|
|
641
|
+
onChange(updateValueByEvent(wheel[0], x));
|
|
642
|
+
}, { passive: false }, [wheel, onChange, readonly, updateValueByEvent]);
|
|
643
|
+
React.useImperativeHandle(ref, () => {
|
|
644
|
+
return {
|
|
645
|
+
focus() {
|
|
646
|
+
var _a;
|
|
647
|
+
(_a = elmRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
648
|
+
},
|
|
649
|
+
blur() {
|
|
650
|
+
var _a;
|
|
651
|
+
(_a = elmRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
652
|
+
},
|
|
653
|
+
};
|
|
654
|
+
}, []);
|
|
626
655
|
const center = size / 2;
|
|
627
656
|
const r1 = -135;
|
|
628
657
|
const r2 = -135 + Math.min(p, s) * 270;
|
|
@@ -637,13 +666,62 @@ function Knob(_a) {
|
|
|
637
666
|
const x4 = center + center * Math.cos(radian(r4 - 90));
|
|
638
667
|
const y4 = center + center * Math.sin(radian(r4 - 90));
|
|
639
668
|
return (jsxRuntime.jsxs("svg", Object.assign({ className: clsx('tremolo-knob', className), ref: (div) => {
|
|
669
|
+
elmRef.current = div;
|
|
640
670
|
wheelRefCallback(div);
|
|
641
671
|
touchMoveRefCallback(div);
|
|
642
|
-
}, width: size, height: size, tabIndex: 0, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled, "aria-readonly": readonly, onPointerDown:
|
|
672
|
+
}, width: size, height: size, tabIndex: 0, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled, "aria-readonly": readonly, onPointerDown: (event) => {
|
|
673
|
+
pointerDownHandler(event);
|
|
674
|
+
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
675
|
+
}, onDoubleClick: (event) => {
|
|
643
676
|
if (enableDoubleClickDefault && onChange) {
|
|
644
677
|
onChange(defaultValue);
|
|
645
678
|
}
|
|
646
|
-
|
|
679
|
+
onDoubleClick === null || onDoubleClick === void 0 ? void 0 : onDoubleClick(event);
|
|
680
|
+
}, onKeyDown: (event) => {
|
|
681
|
+
handleKeyDown(event);
|
|
682
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
|
|
683
|
+
} }, 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: `${thumbLineLength}%`, stroke: thumbLine || 'currentColor', strokeWidth: `${thumbLineWeight}%`,
|
|
684
|
+
// NOTE
|
|
685
|
+
// https://bugs.webkit.org/show_bug.cgi?id=201854
|
|
686
|
+
// https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/transform-origin#browser_compatibility
|
|
687
|
+
style: {
|
|
688
|
+
transform: `rotate(${ -135 + p * 270}deg)`,
|
|
689
|
+
transformOrigin: '50% 50%',
|
|
690
|
+
} })] })] })));
|
|
691
|
+
});
|
|
692
|
+
|
|
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;
|
|
647
725
|
}
|
|
648
726
|
|
|
649
727
|
/**
|
|
@@ -692,40 +770,6 @@ function parseValue(inputString, units, digit) {
|
|
|
692
770
|
};
|
|
693
771
|
}
|
|
694
772
|
|
|
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
773
|
function safeClamp(value, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) {
|
|
730
774
|
return clamp(value, min, max);
|
|
731
775
|
}
|
|
@@ -736,6 +780,7 @@ const createNumberInputStore = (initProps) => {
|
|
|
736
780
|
min: 0,
|
|
737
781
|
max: 0,
|
|
738
782
|
step: 1,
|
|
783
|
+
readonly: false,
|
|
739
784
|
keepWithinRange: true,
|
|
740
785
|
onChange: (_v, _t) => { },
|
|
741
786
|
};
|
|
@@ -744,8 +789,10 @@ const createNumberInputStore = (initProps) => {
|
|
|
744
789
|
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
790
|
}), { increment: () => set((state) => {
|
|
746
791
|
var _a, _b;
|
|
747
|
-
|
|
748
|
-
|
|
792
|
+
if (state.readonly)
|
|
793
|
+
return {};
|
|
794
|
+
const current = parseValue(state.value, state.units, state.digit).rawValue;
|
|
795
|
+
let next = current + ((_a = state.step) !== null && _a !== void 0 ? _a : 1);
|
|
749
796
|
if (state.keepWithinRange) {
|
|
750
797
|
next = safeClamp(next, state.min, state.max);
|
|
751
798
|
}
|
|
@@ -757,8 +804,10 @@ const createNumberInputStore = (initProps) => {
|
|
|
757
804
|
};
|
|
758
805
|
}), decrement: () => set((state) => {
|
|
759
806
|
var _a, _b;
|
|
760
|
-
|
|
761
|
-
|
|
807
|
+
if (state.readonly)
|
|
808
|
+
return {};
|
|
809
|
+
const current = parseValue(state.value, state.units, state.digit).rawValue;
|
|
810
|
+
let next = current - ((_a = state.step) !== null && _a !== void 0 ? _a : 1);
|
|
762
811
|
if (state.keepWithinRange) {
|
|
763
812
|
next = safeClamp(next, state.min, state.max);
|
|
764
813
|
}
|
|
@@ -769,6 +818,8 @@ const createNumberInputStore = (initProps) => {
|
|
|
769
818
|
valueAsNumber: next,
|
|
770
819
|
};
|
|
771
820
|
}), change: (value) => set((state) => {
|
|
821
|
+
if (state.readonly)
|
|
822
|
+
return {};
|
|
772
823
|
const v = value !== null && value !== void 0 ? value : '';
|
|
773
824
|
return {
|
|
774
825
|
value: v,
|
|
@@ -805,36 +856,17 @@ function useNumberInputContext(selector) {
|
|
|
805
856
|
return useStore(store, selector);
|
|
806
857
|
}
|
|
807
858
|
|
|
808
|
-
|
|
809
|
-
var {
|
|
810
|
-
|
|
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"]);
|
|
859
|
+
const InternalInput = React.forwardRef((_a, ref) => {
|
|
860
|
+
var { disabled, readonly, selectWithFocus, blurOnEnter, clampValueOnBlur, wheel, keyboard, className, onChange, onFocus, onBlur, onKeyDown, children: _children } = _a, props = __rest(_a, ["disabled", "readonly", "selectWithFocus", "blurOnEnter", "clampValueOnBlur", "wheel", "keyboard", "className", "onChange", "onFocus", "onBlur", "onKeyDown", "children"]);
|
|
861
|
+
const elmRef = React.useRef(null);
|
|
835
862
|
const [editing, setEditing] = React.useState(false);
|
|
836
863
|
const value = useNumberInputContext((s) => s.value);
|
|
837
864
|
const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber);
|
|
865
|
+
const min = useNumberInputContext((s) => s.min);
|
|
866
|
+
const max = useNumberInputContext((s) => s.max);
|
|
867
|
+
const step = useNumberInputContext((s) => s.step);
|
|
868
|
+
const units = useNumberInputContext((s) => s.units);
|
|
869
|
+
const digit = useNumberInputContext((s) => s.digit);
|
|
838
870
|
const change = useNumberInputContext((s) => s.change);
|
|
839
871
|
const error = React.useMemo(() => {
|
|
840
872
|
if (editing)
|
|
@@ -842,11 +874,71 @@ function InternalInput(_a) {
|
|
|
842
874
|
const v = valueAsNumber;
|
|
843
875
|
return (min !== null && min !== void 0 ? min : -Infinity) > v || v > (max !== null && max !== void 0 ? max : Infinity);
|
|
844
876
|
}, [editing, max, min, valueAsNumber]);
|
|
845
|
-
|
|
877
|
+
const updateValueByEvent = React.useCallback((eventType, x) => {
|
|
878
|
+
let newValue;
|
|
879
|
+
if (eventType == 'normalized') {
|
|
880
|
+
if (!min || !max) {
|
|
881
|
+
throw new Error('required parameter: min, max'); // TODO
|
|
882
|
+
}
|
|
883
|
+
const n = normalizeValue(valueAsNumber, min, max);
|
|
884
|
+
newValue = rawValue(n + x, min, max);
|
|
885
|
+
return clamp(stepValue(newValue, step), min, max);
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
newValue = valueAsNumber + x;
|
|
889
|
+
return stepValue(newValue, step);
|
|
890
|
+
}
|
|
891
|
+
}, [max, min, step, valueAsNumber]);
|
|
892
|
+
const handleKeyDown = React.useCallback((event) => {
|
|
893
|
+
if (!keyboard || !onChange || readonly)
|
|
894
|
+
return;
|
|
895
|
+
const key = event.key;
|
|
896
|
+
if (!['ArrowUp', 'ArrowDown'].includes(key))
|
|
897
|
+
return;
|
|
898
|
+
event.preventDefault();
|
|
899
|
+
const x = key == 'ArrowUp' ? keyboard[1] : -keyboard[1];
|
|
900
|
+
const parsed = parseValue(String(updateValueByEvent(keyboard[0], x)));
|
|
901
|
+
console.log('key control');
|
|
902
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(parsed.rawValue, parsed.formatValue);
|
|
903
|
+
}, [keyboard, readonly, onChange, updateValueByEvent]);
|
|
904
|
+
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
905
|
+
if (!wheel || readonly)
|
|
906
|
+
return;
|
|
907
|
+
event.preventDefault();
|
|
908
|
+
if (!onChange || event.deltaY == 0)
|
|
909
|
+
return;
|
|
910
|
+
const x = Math.sign(event.deltaY) * -wheel[1];
|
|
911
|
+
const parsed = parseValue(String(updateValueByEvent(wheel[0], x)));
|
|
912
|
+
console.log('wheel control');
|
|
913
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(parsed.rawValue, parsed.formatValue);
|
|
914
|
+
}, { passive: false }, [wheel, readonly, onChange, updateValueByEvent]);
|
|
915
|
+
React.useImperativeHandle(ref, () => {
|
|
916
|
+
return {
|
|
917
|
+
focus() {
|
|
918
|
+
var _a;
|
|
919
|
+
(_a = elmRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
920
|
+
},
|
|
921
|
+
blur() {
|
|
922
|
+
var _a;
|
|
923
|
+
(_a = elmRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
924
|
+
},
|
|
925
|
+
};
|
|
926
|
+
}, []);
|
|
927
|
+
return (jsxRuntime.jsx("input", Object.assign({ ref: (input) => {
|
|
928
|
+
elmRef.current = input;
|
|
929
|
+
wheelRefCallback(input);
|
|
930
|
+
}, className: clsx('tremolo-number-input', className), value: value, min: min, max: max, step: step, type: "text", "aria-disabled": disabled, "aria-readonly": readonly, tabIndex: -1, "data-error": error, onChange: (event) => {
|
|
931
|
+
if (readonly)
|
|
932
|
+
return;
|
|
846
933
|
const v = event.currentTarget.value;
|
|
934
|
+
const cursorPos = event.target.selectionStart;
|
|
847
935
|
change(v);
|
|
848
936
|
const valueAsNumber = parseValue(v, units, digit).rawValue;
|
|
849
937
|
onChange === null || onChange === void 0 ? void 0 : onChange(valueAsNumber, v);
|
|
938
|
+
if (cursorPos) {
|
|
939
|
+
event.target.selectionStart = cursorPos;
|
|
940
|
+
event.target.selectionEnd = cursorPos;
|
|
941
|
+
}
|
|
850
942
|
}, onFocus: (event) => {
|
|
851
943
|
setEditing(true);
|
|
852
944
|
const v = event.currentTarget.value;
|
|
@@ -875,18 +967,97 @@ function InternalInput(_a) {
|
|
|
875
967
|
if (blurOnEnter && event.key == 'Enter') {
|
|
876
968
|
event.currentTarget.blur();
|
|
877
969
|
}
|
|
970
|
+
handleKeyDown(event);
|
|
971
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
|
|
878
972
|
} }, props)));
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
/** @category NumberInput */
|
|
976
|
+
function Stepper(_a) {
|
|
977
|
+
var { dynamic = true, children, className } = _a, props = __rest(_a, ["dynamic", "children", "className"]);
|
|
978
|
+
return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-number-input-stepper', className), "data-dynamic": dynamic }, props, { children: children })));
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
function useInterval(callback, delay) {
|
|
982
|
+
const savedCallback = React.useRef(callback);
|
|
983
|
+
// Remember the latest callback if it changes.
|
|
984
|
+
React.useEffect(() => {
|
|
985
|
+
savedCallback.current = callback;
|
|
986
|
+
}, [callback]);
|
|
987
|
+
// Set up the interval.
|
|
988
|
+
React.useEffect(() => {
|
|
989
|
+
// Don't schedule if no delay is specified.
|
|
990
|
+
// Note: 0 is a valid value for delay.
|
|
991
|
+
if (delay === null) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
const id = setInterval(() => {
|
|
995
|
+
savedCallback.current();
|
|
996
|
+
}, delay);
|
|
997
|
+
return () => {
|
|
998
|
+
clearInterval(id);
|
|
999
|
+
};
|
|
1000
|
+
}, [delay]);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
function useLongPress(callback, initialDelay = 500, interval = 40) {
|
|
1004
|
+
const [pressed, setPressed] = React.useState(false);
|
|
1005
|
+
const [delay, setDelay] = React.useState(initialDelay);
|
|
1006
|
+
useInterval(() => {
|
|
1007
|
+
callback();
|
|
1008
|
+
setDelay(interval);
|
|
1009
|
+
}, pressed ? delay : null);
|
|
1010
|
+
useEventListener(globalThis.window, 'pointerup', () => {
|
|
1011
|
+
setPressed(false);
|
|
1012
|
+
setDelay(initialDelay);
|
|
1013
|
+
});
|
|
1014
|
+
return React.useCallback(() => {
|
|
1015
|
+
callback();
|
|
1016
|
+
setPressed(true);
|
|
1017
|
+
}, [callback]);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/** @category NumberInput */
|
|
1021
|
+
function IncrementStepper(_a) {
|
|
1022
|
+
var { size = 12, children, className } = _a, props = __rest(_a, ["size", "children", "className"]);
|
|
1023
|
+
const max = useNumberInputContext((s) => s.max);
|
|
1024
|
+
const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber);
|
|
1025
|
+
const readonly = useNumberInputContext((s) => s.readonly);
|
|
1026
|
+
const keepWithinRange = useNumberInputContext((s) => s.keepWithinRange);
|
|
1027
|
+
const increment = useNumberInputContext((s) => s.increment);
|
|
1028
|
+
const press = useLongPress(increment);
|
|
1029
|
+
return (
|
|
1030
|
+
// eslint-disable-next-line jsx-a11y/role-supports-aria-props
|
|
1031
|
+
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), "aria-readonly": readonly, onPointerDown: press }, 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" }) })) })));
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/** @category NumberInput */
|
|
1035
|
+
function DecrementStepper(_a) {
|
|
1036
|
+
var { size = 12, children, className } = _a, props = __rest(_a, ["size", "children", "className"]);
|
|
1037
|
+
const min = useNumberInputContext((s) => s.min);
|
|
1038
|
+
const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber);
|
|
1039
|
+
const readonly = useNumberInputContext((s) => s.readonly);
|
|
1040
|
+
const keepWithinRange = useNumberInputContext((s) => s.keepWithinRange);
|
|
1041
|
+
const decrement = useNumberInputContext((s) => s.decrement);
|
|
1042
|
+
const press = useLongPress(decrement);
|
|
1043
|
+
return (
|
|
1044
|
+
// eslint-disable-next-line jsx-a11y/role-supports-aria-props
|
|
1045
|
+
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), "aria-readonly": readonly, onPointerDown: press }, 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" }) })) })));
|
|
879
1046
|
}
|
|
1047
|
+
|
|
880
1048
|
/**
|
|
881
1049
|
* Input with some useful functions for entering numerical values.
|
|
882
1050
|
* @category NumberInput
|
|
883
1051
|
*/
|
|
884
|
-
|
|
885
|
-
var { value, min, max, step = 1,
|
|
886
|
-
|
|
1052
|
+
const NumberInput = React.forwardRef((_a, ref) => {
|
|
1053
|
+
var { value, min, max, step = 1, units, readonly = false, disabled = false, digit, variant = 'outline', selectWithFocus = 'none', blurOnEnter = true, keepWithinRange = true, clampValueOnBlur = true, wheel = ['raw', 1], keyboard = ['raw', 1], activeColor, wrapperClassName, className, onChange, onFocus, onBlur, children } = _a, props = __rest(_a, ["value", "min", "max", "step", "units", "readonly", "disabled", "digit", "variant", "selectWithFocus", "blurOnEnter", "keepWithinRange", "clampValueOnBlur", "wheel", "keyboard", "activeColor", "wrapperClassName", "className", "onChange", "onFocus", "onBlur", "children"]);
|
|
1054
|
+
const colors = {
|
|
1055
|
+
'--active-color': activeColor,
|
|
1056
|
+
};
|
|
1057
|
+
return (jsxRuntime.jsx(NumberInputProvider, { value: String(value), min: min, max: max, step: step, units: units, digit: digit, readonly: readonly, keepWithinRange: keepWithinRange, onChange: onChange, children: jsxRuntime.jsxs("div", { className: clsx('tremolo-number-input-wrapper', wrapperClassName),
|
|
887
1058
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
888
|
-
tabIndex: 0, "data-stepper": !!children, children: [jsxRuntime.jsx(InternalInput, Object.assign({
|
|
889
|
-
}
|
|
1059
|
+
tabIndex: 0, style: Object.assign({}, colors), "data-stepper": !!children, "data-variant": variant, children: [jsxRuntime.jsx(InternalInput, Object.assign({ ref: ref, readonly: readonly, disabled: disabled, selectWithFocus: selectWithFocus, blurOnEnter: blurOnEnter, clampValueOnBlur: clampValueOnBlur, wheel: wheel, keyboard: keyboard, className: className, onChange: onChange, onFocus: onFocus, onBlur: onBlur }, props)), children] }) }));
|
|
1060
|
+
});
|
|
890
1061
|
|
|
891
1062
|
/** @category Piano */
|
|
892
1063
|
function KeyLabel(_a) {
|
|
@@ -901,8 +1072,14 @@ function KeyLabel(_a) {
|
|
|
901
1072
|
const defaultWhiteKeyWidth = 40;
|
|
902
1073
|
/** @category Piano */
|
|
903
1074
|
const WhiteKey = React.forwardRef((_a, ref) => {
|
|
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"]);
|
|
1075
|
+
var { width = defaultWhiteKeyWidth, height = '100%', bg, color, activeBg, activeColor, className, style, children, __glissando, __position, __note, __disabled, __index, __fill, __width, __onPlayNote, __onStopNote, __label, onContextMenu = (e) => e.preventDefault() } = _a, props = __rest(_a, ["width", "height", "bg", "color", "activeBg", "activeColor", "className", "style", "children", "__glissando", "__position", "__note", "__disabled", "__index", "__fill", "__width", "__onPlayNote", "__onStopNote", "__label", "onContextMenu"]);
|
|
905
1076
|
const [played, setPlayed] = React.useState(false);
|
|
1077
|
+
const colors = {
|
|
1078
|
+
'--bg': bg,
|
|
1079
|
+
'--color': color,
|
|
1080
|
+
'--active-bg': activeBg,
|
|
1081
|
+
'--active-color': activeColor,
|
|
1082
|
+
};
|
|
906
1083
|
React.useImperativeHandle(ref, () => {
|
|
907
1084
|
return {
|
|
908
1085
|
play() {
|
|
@@ -938,7 +1115,7 @@ const WhiteKey = React.forwardRef((_a, ref) => {
|
|
|
938
1115
|
}
|
|
939
1116
|
});
|
|
940
1117
|
}
|
|
941
|
-
return (jsxRuntime.jsx("div", Object.assign({ className: clsx(`tremolo-piano-white-key`, className), "aria-disabled": __disabled, "data-active": played, style: Object.assign({ left: __position, width: __fill ? __width : (width !== null && width !== void 0 ? width : __width), height: height }, style), onPointerDown: () => {
|
|
1118
|
+
return (jsxRuntime.jsx("div", Object.assign({ className: clsx(`tremolo-piano-white-key`, className), "aria-disabled": __disabled, "data-active": played, style: Object.assign(Object.assign(Object.assign({}, colors), { left: __position, width: __fill ? __width : (width !== null && width !== void 0 ? width : __width), height: height }), style), onPointerDown: () => {
|
|
942
1119
|
if (__disabled)
|
|
943
1120
|
return;
|
|
944
1121
|
setPlayed(true);
|
|
@@ -966,13 +1143,19 @@ const WhiteKey = React.forwardRef((_a, ref) => {
|
|
|
966
1143
|
if (__onStopNote)
|
|
967
1144
|
__onStopNote(__note);
|
|
968
1145
|
}
|
|
969
|
-
} }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
|
|
1146
|
+
}, onContextMenu: onContextMenu }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
|
|
970
1147
|
});
|
|
971
1148
|
|
|
972
1149
|
/** @category Piano */
|
|
973
1150
|
const BlackKey = React.forwardRef((_a, ref) => {
|
|
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"]);
|
|
1151
|
+
var { width = defaultWhiteKeyWidth * 0.65, height = '60%', bg, color, activeBg, activeColor, className, style, children, __glissando, __position, __note, __disabled, __index, __fill, __width, __onPlayNote, __onStopNote, __label, onContextMenu = (e) => e.preventDefault() } = _a, props = __rest(_a, ["width", "height", "bg", "color", "activeBg", "activeColor", "className", "style", "children", "__glissando", "__position", "__note", "__disabled", "__index", "__fill", "__width", "__onPlayNote", "__onStopNote", "__label", "onContextMenu"]);
|
|
975
1152
|
const [played, setPlayed] = React.useState(false);
|
|
1153
|
+
const colors = {
|
|
1154
|
+
'--bg': bg,
|
|
1155
|
+
'--color': color,
|
|
1156
|
+
'--active-bg': activeBg,
|
|
1157
|
+
'--active-color': activeColor,
|
|
1158
|
+
};
|
|
976
1159
|
React.useImperativeHandle(ref, () => {
|
|
977
1160
|
return {
|
|
978
1161
|
play() {
|
|
@@ -1008,7 +1191,7 @@ const BlackKey = React.forwardRef((_a, ref) => {
|
|
|
1008
1191
|
}
|
|
1009
1192
|
});
|
|
1010
1193
|
}
|
|
1011
|
-
return (jsxRuntime.jsx("div", Object.assign({ className: clsx(`tremolo-piano-black-key`, className), "aria-disabled": __disabled, "data-active": played, style: Object.assign({ left: __position, width: __fill ? __width : (width !== null && width !== void 0 ? width : __width), height: height }, style), onPointerDown: () => {
|
|
1194
|
+
return (jsxRuntime.jsx("div", Object.assign({ className: clsx(`tremolo-piano-black-key`, className), "aria-disabled": __disabled, "data-active": played, style: Object.assign(Object.assign(Object.assign({}, colors), { left: __position, width: __fill ? __width : (width !== null && width !== void 0 ? width : __width), height: height }), style), onPointerDown: () => {
|
|
1012
1195
|
if (__disabled)
|
|
1013
1196
|
return;
|
|
1014
1197
|
setPlayed(true);
|
|
@@ -1036,11 +1219,11 @@ const BlackKey = React.forwardRef((_a, ref) => {
|
|
|
1036
1219
|
if (__onStopNote)
|
|
1037
1220
|
__onStopNote(__note);
|
|
1038
1221
|
}
|
|
1039
|
-
} }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
|
|
1222
|
+
}, onContextMenu: onContextMenu }, props, { children: jsxRuntime.jsx(KeyLabel, Object.assign({ __note: __note, __label: __label, __index: __index }, keyLabelProps)) })));
|
|
1040
1223
|
});
|
|
1041
1224
|
|
|
1042
1225
|
/** @category Piano */
|
|
1043
|
-
const
|
|
1226
|
+
const SHORTCUTS = {
|
|
1044
1227
|
HOME_ROW: {
|
|
1045
1228
|
keys: [
|
|
1046
1229
|
'a',
|
|
@@ -1064,9 +1247,12 @@ const Shortcuts = {
|
|
|
1064
1247
|
},
|
|
1065
1248
|
};
|
|
1066
1249
|
|
|
1067
|
-
/**
|
|
1250
|
+
/**
|
|
1251
|
+
* Customizable piano component.
|
|
1252
|
+
* @category Piano
|
|
1253
|
+
*/
|
|
1068
1254
|
function Piano(_a) {
|
|
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"]);
|
|
1255
|
+
var { noteRange, glissando = true, midiMax = 127, keyboardShortcuts, fill = false, height = fill ? '100%' : 160, style, className, onPlayNote, onStopNote, label, children, onPointerUp, onPointerDown } = _a, props = __rest(_a, ["noteRange", "glissando", "midiMax", "keyboardShortcuts", "fill", "height", "style", "className", "onPlayNote", "onStopNote", "label", "children", "onPointerUp", "onPointerDown"]);
|
|
1070
1256
|
// -- state and ref ---
|
|
1071
1257
|
const [pressed, setPressed] = React.useState(false);
|
|
1072
1258
|
const [whiteNoteWidth, setWhiteNoteWidth] = React.useState(-1);
|
|
@@ -1113,15 +1299,11 @@ function Piano(_a) {
|
|
|
1113
1299
|
'A#': 5.85,
|
|
1114
1300
|
B: 6,
|
|
1115
1301
|
};
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
};
|
|
1120
|
-
const _noteName = toNoteName(note);
|
|
1121
|
-
const firstNoteName = toNoteName(noteRange.first);
|
|
1122
|
-
const pos = pitchPositions[_noteName] - pitchPositions[firstNoteName];
|
|
1302
|
+
const targetNoteKey = noteKey(note);
|
|
1303
|
+
const firstNoteKey = noteKey(noteRange.first);
|
|
1304
|
+
const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey];
|
|
1123
1305
|
const octave = Math.floor((note - noteRange.first) / 12);
|
|
1124
|
-
const octaveOffset =
|
|
1306
|
+
const octaveOffset = noteKeys.indexOf(firstNoteKey) > noteKeys.indexOf(targetNoteKey) ? 1 : 0;
|
|
1125
1307
|
const length = whiteNoteWidth + 3;
|
|
1126
1308
|
return pos * length + (octave + octaveOffset) * 7 * length;
|
|
1127
1309
|
}
|
|
@@ -1136,6 +1318,9 @@ function Piano(_a) {
|
|
|
1136
1318
|
setWhiteNoteWidth(w / whiteNoteCount - 3);
|
|
1137
1319
|
});
|
|
1138
1320
|
resizeObserver.observe(parent);
|
|
1321
|
+
return () => {
|
|
1322
|
+
resizeObserver.unobserve(parent);
|
|
1323
|
+
};
|
|
1139
1324
|
}
|
|
1140
1325
|
else {
|
|
1141
1326
|
setWhiteNoteWidth((whiteKeyProps === null || whiteKeyProps === void 0 ? void 0 : whiteKeyProps.width) || defaultWhiteKeyWidth);
|
|
@@ -1166,13 +1351,11 @@ function Piano(_a) {
|
|
|
1166
1351
|
}
|
|
1167
1352
|
});
|
|
1168
1353
|
return (jsxRuntime.jsx("div", Object.assign({ ref: pianoRef, className: clsx('tremolo-piano', className), style: Object.assign({ width: fill ? '100%' : (whiteNoteWidth + 3) * whiteNoteCount, height: height }, style), onPointerDown: (e) => {
|
|
1169
|
-
if (props.onPointerDown)
|
|
1170
|
-
props.onPointerDown(e);
|
|
1171
1354
|
setPressed(true);
|
|
1355
|
+
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(e);
|
|
1172
1356
|
}, onPointerUp: (e) => {
|
|
1173
|
-
if (props.onPointerUp)
|
|
1174
|
-
props.onPointerUp(e);
|
|
1175
1357
|
setPressed(false);
|
|
1358
|
+
onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp(e);
|
|
1176
1359
|
} }, props, { children: noteRangeArray.map((note, index) => {
|
|
1177
1360
|
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));
|
|
1178
1361
|
}) })));
|
|
@@ -1289,7 +1472,7 @@ function Scale(_a) {
|
|
|
1289
1472
|
/** @category Slider */
|
|
1290
1473
|
const defaultThumbSize = 22;
|
|
1291
1474
|
/** @category Slider */
|
|
1292
|
-
const SliderThumb = React.forwardRef(({ size, width = defaultThumbSize, height = defaultThumbSize, children, className, style, __percent, }, ref) => {
|
|
1475
|
+
const SliderThumb = React.forwardRef(({ size, width = defaultThumbSize, height = defaultThumbSize, color, children, className, style, __percent, }, ref) => {
|
|
1293
1476
|
const wrapperRef = React.useRef(null);
|
|
1294
1477
|
const vertical = useSliderContext((s) => s.vertical);
|
|
1295
1478
|
const disabled = useSliderContext((s) => s.disabled);
|
|
@@ -1313,13 +1496,14 @@ const SliderThumb = React.forwardRef(({ size, width = defaultThumbSize, height =
|
|
|
1313
1496
|
// default slider thumb
|
|
1314
1497
|
jsxRuntime.jsx("div", { ref: wrapperRef, className: clsx('tremolo-slider-thumb', className),
|
|
1315
1498
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
1316
|
-
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) })) }));
|
|
1499
|
+
tabIndex: 0, "aria-disabled": disabled, "aria-readonly": readonly, style: Object.assign(Object.assign({ '--color': color }, { width: size !== null && size !== void 0 ? size : width, height: size !== null && size !== void 0 ? size : height }), style) })) }));
|
|
1317
1500
|
});
|
|
1318
1501
|
|
|
1319
1502
|
const defaultLength = 140;
|
|
1320
1503
|
const defaultThickness = 10;
|
|
1321
1504
|
/** @category Slider */
|
|
1322
|
-
function SliderTrack(
|
|
1505
|
+
function SliderTrack(_a) {
|
|
1506
|
+
var { length = defaultLength, thickness = defaultThickness, active, inactive, children, className, style, defaultStyle = true, __thumb, __percent = 0 } = _a, props = __rest(_a, ["length", "thickness", "active", "inactive", "children", "className", "style", "defaultStyle", "__thumb", "__percent"]);
|
|
1323
1507
|
const vertical = useSliderContext((s) => s.vertical);
|
|
1324
1508
|
const reverse = useSliderContext((s) => s.reverse);
|
|
1325
1509
|
const disabled = useSliderContext((s) => s.disabled);
|
|
@@ -1328,11 +1512,11 @@ function SliderTrack({ length = defaultLength, thickness = defaultThickness, act
|
|
|
1328
1512
|
'--active': active,
|
|
1329
1513
|
'--inactive': inactive,
|
|
1330
1514
|
};
|
|
1331
|
-
return (jsxRuntime.jsxs("div", { className: clsx('tremolo-slider-track', className), "aria-disabled": disabled, "data-vertical": vertical, style: !defaultStyle
|
|
1515
|
+
return (jsxRuntime.jsxs("div", Object.assign({ className: clsx('tremolo-slider-track', className), "aria-disabled": disabled, "data-vertical": vertical, style: !defaultStyle
|
|
1332
1516
|
? style
|
|
1333
1517
|
: Object.assign(Object.assign(Object.assign({}, colors), { background: xor(vertical, reverse)
|
|
1334
1518
|
? `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] }));
|
|
1519
|
+
: `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) }, props, { children: [children, __thumb] })));
|
|
1336
1520
|
}
|
|
1337
1521
|
|
|
1338
1522
|
/**
|
|
@@ -1340,8 +1524,8 @@ function SliderTrack({ length = defaultLength, thickness = defaultThickness, act
|
|
|
1340
1524
|
* @category Slider
|
|
1341
1525
|
*/
|
|
1342
1526
|
const Slider = React.forwardRef((_a, ref) => {
|
|
1343
|
-
var _b
|
|
1344
|
-
var { value, min, max, step = 1, skew = 1, vertical = false, reverse = false,
|
|
1527
|
+
var _b;
|
|
1528
|
+
var { value, min, max, step = 1, skew = 1, vertical = false, reverse = false, bodyNoSelect = true, wheel = ['raw', 1], keyboard = ['raw', 1], disabled = false, readonly = false, onChange, onDragStart, onDragEnd, className, style, children, onFocus, onBlur, onPointerDown, onKeyDown } = _a, props = __rest(_a, ["value", "min", "max", "step", "skew", "vertical", "reverse", "bodyNoSelect", "wheel", "keyboard", "disabled", "readonly", "onChange", "onDragStart", "onDragEnd", "className", "style", "children", "onFocus", "onBlur", "onPointerDown", "onKeyDown"]);
|
|
1345
1529
|
// -- state and ref ---
|
|
1346
1530
|
const trackElementRef = React.useRef(null);
|
|
1347
1531
|
const thumbRef = React.useRef(null);
|
|
@@ -1400,8 +1584,21 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1400
1584
|
? normalizeValue(mouseY, y1, y2)
|
|
1401
1585
|
: normalizeValue(mouseX, x1, x2);
|
|
1402
1586
|
const v = rawValue(displayReversed ? 1 - n : n, min, max, skew);
|
|
1403
|
-
|
|
1587
|
+
const v2 = clamp(stepValue(v, step), min, max);
|
|
1588
|
+
onChange(v2);
|
|
1589
|
+
return v2;
|
|
1404
1590
|
};
|
|
1591
|
+
const updateValueByEvent = React.useCallback((eventType, x) => {
|
|
1592
|
+
let newValue;
|
|
1593
|
+
if (eventType == 'normalized') {
|
|
1594
|
+
const n = normalizeValue(value, min, max, skew);
|
|
1595
|
+
newValue = rawValue(n + x, min, max, skew);
|
|
1596
|
+
}
|
|
1597
|
+
else {
|
|
1598
|
+
newValue = value + x;
|
|
1599
|
+
}
|
|
1600
|
+
return clamp(stepValue(newValue, step), min, max);
|
|
1601
|
+
}, [max, min, skew, step, value]);
|
|
1405
1602
|
const handleKeyDown = React.useCallback((event) => {
|
|
1406
1603
|
if (!keyboard || !onChange || readonly)
|
|
1407
1604
|
return;
|
|
@@ -1411,17 +1608,9 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1411
1608
|
let x = key == 'ArrowRight' || key == 'ArrowUp' ? keyboard[1] : -keyboard[1];
|
|
1412
1609
|
if (reverse)
|
|
1413
1610
|
x *= -1;
|
|
1414
|
-
|
|
1415
|
-
if (keyboard[0] == 'normalized') {
|
|
1416
|
-
const n = normalizeValue(value, min, max, skew);
|
|
1417
|
-
v = rawValue(n + x, min, max, skew);
|
|
1418
|
-
}
|
|
1419
|
-
else {
|
|
1420
|
-
v = value + x;
|
|
1421
|
-
}
|
|
1422
|
-
onChange(clamp(stepValue(v, step), min, max));
|
|
1611
|
+
onChange(updateValueByEvent(keyboard[0], x));
|
|
1423
1612
|
}
|
|
1424
|
-
}, [
|
|
1613
|
+
}, [keyboard, onChange, readonly, reverse, updateValueByEvent]);
|
|
1425
1614
|
// --- hooks ---
|
|
1426
1615
|
const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleValue, { passive: false }, [min, max, skew, step, vertical, reverse, onChange, readonly]);
|
|
1427
1616
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
@@ -1439,23 +1628,18 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1439
1628
|
}
|
|
1440
1629
|
if (vertical && reverse)
|
|
1441
1630
|
x *= -1;
|
|
1442
|
-
|
|
1443
|
-
if (wheel[0] == 'normalized') {
|
|
1444
|
-
const n = normalizeValue(value, min, max, skew);
|
|
1445
|
-
v = rawValue(n + x, min, max, skew);
|
|
1446
|
-
}
|
|
1447
|
-
else {
|
|
1448
|
-
v = value + x;
|
|
1449
|
-
}
|
|
1450
|
-
onChange(clamp(stepValue(v, step), min, max));
|
|
1631
|
+
onChange(updateValueByEvent(wheel[0], x));
|
|
1451
1632
|
}, {
|
|
1452
1633
|
passive: false,
|
|
1453
|
-
}, [wheel,
|
|
1634
|
+
}, [wheel, vertical, readonly, onChange, updateValueByEvent]);
|
|
1454
1635
|
useEventListener(globalThis.window, 'mousemove', (event) => {
|
|
1455
1636
|
handleValue(event);
|
|
1456
1637
|
});
|
|
1457
1638
|
useEventListener(globalThis.window, 'mouseup', () => {
|
|
1639
|
+
if (!thumbDragged.current || readonly)
|
|
1640
|
+
return;
|
|
1458
1641
|
thumbDragged.current = false;
|
|
1642
|
+
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(value);
|
|
1459
1643
|
if (bodyNoSelect)
|
|
1460
1644
|
removeNoSelect();
|
|
1461
1645
|
});
|
|
@@ -1476,8 +1660,22 @@ const Slider = React.forwardRef((_a, ref) => {
|
|
|
1476
1660
|
touchMoveRefCallback(div);
|
|
1477
1661
|
}, 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) => {
|
|
1478
1662
|
thumbDragged.current = true;
|
|
1479
|
-
handleValue(event);
|
|
1480
|
-
|
|
1663
|
+
const v = handleValue(event);
|
|
1664
|
+
if (!readonly)
|
|
1665
|
+
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart(v !== null && v !== void 0 ? v : value);
|
|
1666
|
+
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
1667
|
+
}, onKeyDown: (event) => {
|
|
1668
|
+
handleKeyDown(event);
|
|
1669
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
|
|
1670
|
+
}, onFocus: (event) => {
|
|
1671
|
+
var _a;
|
|
1672
|
+
(_a = thumbRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1673
|
+
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
1674
|
+
}, onBlur: (event) => {
|
|
1675
|
+
var _a;
|
|
1676
|
+
(_a = thumbRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
1677
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
1678
|
+
} }, props, { children: jsxRuntime.jsxs("div", { style: {
|
|
1481
1679
|
display: 'flex',
|
|
1482
1680
|
flexDirection: vertical ? 'row' : 'column',
|
|
1483
1681
|
width: !vertical ? '100%' : undefined,
|
|
@@ -1496,12 +1694,14 @@ function WheelObserver(props) {
|
|
|
1496
1694
|
}
|
|
1497
1695
|
|
|
1498
1696
|
/** @category XYPad */
|
|
1499
|
-
function XYPadArea(
|
|
1500
|
-
|
|
1697
|
+
function XYPadArea(_a) {
|
|
1698
|
+
var { width = 120, height = 120, color, children, className, style, __thumb } = _a, props = __rest(_a, ["width", "height", "color", "children", "className", "style", "__thumb"]);
|
|
1699
|
+
return (jsxRuntime.jsxs("div", Object.assign({ className: clsx('tremolo-xy-pad-area', className), style: Object.assign(Object.assign({ '--color': color }, { width: width, height: height }), style) }, props, { children: [children, __thumb] })));
|
|
1501
1700
|
}
|
|
1502
1701
|
|
|
1503
1702
|
/** @category XYPad */
|
|
1504
|
-
const XYPadThumb = React.forwardRef((
|
|
1703
|
+
const XYPadThumb = React.forwardRef((_a, ref) => {
|
|
1704
|
+
var { size, width = 22, height = 22, color, children, wrapperClassName, wrapperStyle, className, style, __disabled, __css } = _a, props = __rest(_a, ["size", "width", "height", "color", "children", "wrapperClassName", "wrapperStyle", "className", "style", "__disabled", "__css"]);
|
|
1505
1705
|
const wrapperRef = React.useRef(null);
|
|
1506
1706
|
React.useImperativeHandle(ref, () => {
|
|
1507
1707
|
return {
|
|
@@ -1515,11 +1715,11 @@ const XYPadThumb = React.forwardRef(({ size, width = 22, height = 22, children,
|
|
|
1515
1715
|
},
|
|
1516
1716
|
};
|
|
1517
1717
|
}, []);
|
|
1518
|
-
return (jsxRuntime.jsx("div", { className: clsx('tremolo-xy-pad-thumb-wrapper', wrapperClassName), style: Object.assign(Object.assign({}, __css), wrapperStyle), children: children ? (children) : (
|
|
1718
|
+
return (jsxRuntime.jsx("div", Object.assign({ className: clsx('tremolo-xy-pad-thumb-wrapper', wrapperClassName), style: Object.assign(Object.assign({}, __css), wrapperStyle) }, props, { children: children ? (children) : (
|
|
1519
1719
|
// default thumb
|
|
1520
1720
|
jsxRuntime.jsx("div", { ref: wrapperRef, className: clsx('tremolo-xy-pad-thumb', className),
|
|
1521
1721
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
1522
|
-
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) })) }));
|
|
1722
|
+
tabIndex: 0, "aria-disabled": __disabled, style: Object.assign(Object.assign({ '--color': color }, { width: size !== null && size !== void 0 ? size : width, height: size !== null && size !== void 0 ? size : height }), style) })) })));
|
|
1523
1723
|
});
|
|
1524
1724
|
|
|
1525
1725
|
const defaultValueOptions = {
|
|
@@ -1534,8 +1734,8 @@ const defaultValueOptions = {
|
|
|
1534
1734
|
* @category XYPad
|
|
1535
1735
|
*/
|
|
1536
1736
|
const XYPad = React.forwardRef((_a, ref) => {
|
|
1537
|
-
var _b
|
|
1538
|
-
var { x: _x, y: _y, className, style, bodyNoSelect = true, disabled = false, readonly = false, onChange, children } = _a, props = __rest(_a, ["x", "y", "className", "style", "bodyNoSelect", "disabled", "readonly", "onChange", "children"]);
|
|
1737
|
+
var _b;
|
|
1738
|
+
var { x: _x, y: _y, className, style, bodyNoSelect = true, disabled = false, readonly = false, onChange, onDragStart, onDragEnd, onPointerDown, onKeyDown, onFocus, onBlur, children } = _a, props = __rest(_a, ["x", "y", "className", "style", "bodyNoSelect", "disabled", "readonly", "onChange", "onDragStart", "onDragEnd", "onPointerDown", "onKeyDown", "onFocus", "onBlur", "children"]);
|
|
1539
1739
|
const x = React.useMemo(() => {
|
|
1540
1740
|
return Object.assign(Object.assign({}, defaultValueOptions), _x);
|
|
1541
1741
|
}, [_x]);
|
|
@@ -1592,7 +1792,19 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1592
1792
|
const newX = clamp(stepValue(vx, x.step), x.min, x.max);
|
|
1593
1793
|
const newY = clamp(stepValue(vy, y.step), y.min, y.max);
|
|
1594
1794
|
onChange(newX, newY);
|
|
1795
|
+
return [newX, newY];
|
|
1595
1796
|
};
|
|
1797
|
+
const updateValueByEvent = React.useCallback((eventType, target, x) => {
|
|
1798
|
+
let v;
|
|
1799
|
+
if (eventType == 'normalized') {
|
|
1800
|
+
const n = normalizeValue(target.value, target.min, target.max, target.skew);
|
|
1801
|
+
v = rawValue(n + x, target.min, target.max, target.skew);
|
|
1802
|
+
}
|
|
1803
|
+
else {
|
|
1804
|
+
v = target.value + x;
|
|
1805
|
+
}
|
|
1806
|
+
return clamp(stepValue(v, target.step), target.min, target.max);
|
|
1807
|
+
}, []);
|
|
1596
1808
|
const handleKeyDown = React.useCallback((event) => {
|
|
1597
1809
|
if (!onChange || readonly)
|
|
1598
1810
|
return;
|
|
@@ -1608,15 +1820,7 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1608
1820
|
delta *= -1;
|
|
1609
1821
|
if (target.reverse)
|
|
1610
1822
|
delta *= -1;
|
|
1611
|
-
|
|
1612
|
-
if (target.keyboard[0] == 'normalized') {
|
|
1613
|
-
const n = normalizeValue(target.value, target.min, target.max, target.skew);
|
|
1614
|
-
v = rawValue(n + delta, target.min, target.max, target.skew);
|
|
1615
|
-
}
|
|
1616
|
-
else {
|
|
1617
|
-
v = target.value + delta;
|
|
1618
|
-
}
|
|
1619
|
-
const newValue = clamp(stepValue(v, target.step), target.min, target.max);
|
|
1823
|
+
const newValue = updateValueByEvent(target.keyboard[0], target, delta);
|
|
1620
1824
|
if (isHorizontal) {
|
|
1621
1825
|
onChange(newValue, y.value);
|
|
1622
1826
|
}
|
|
@@ -1624,7 +1828,7 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1624
1828
|
onChange(x.value, newValue);
|
|
1625
1829
|
}
|
|
1626
1830
|
}
|
|
1627
|
-
}, [x, y,
|
|
1831
|
+
}, [onChange, readonly, x, y, updateValueByEvent]);
|
|
1628
1832
|
// --- hooks ---
|
|
1629
1833
|
const touchMoveRefCallback = useRefCallbackEvent('touchmove', handleValue, { passive: false }, [x, onChange, readonly]);
|
|
1630
1834
|
const wheelRefCallback = useRefCallbackEvent('wheel', (event) => {
|
|
@@ -1639,15 +1843,7 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1639
1843
|
delta *= -1;
|
|
1640
1844
|
if (target.reverse)
|
|
1641
1845
|
delta *= -1;
|
|
1642
|
-
|
|
1643
|
-
if (target.wheel[0] == 'normalized') {
|
|
1644
|
-
const n = normalizeValue(target.value, target.min, target.max, target.skew);
|
|
1645
|
-
v = rawValue(n + delta, target.min, target.max, target.skew);
|
|
1646
|
-
}
|
|
1647
|
-
else {
|
|
1648
|
-
v = target.value + delta;
|
|
1649
|
-
}
|
|
1650
|
-
const newValue = clamp(stepValue(v, target.step), target.min, target.max);
|
|
1846
|
+
const newValue = updateValueByEvent(target.wheel[0], target, delta);
|
|
1651
1847
|
if (event.shiftKey) {
|
|
1652
1848
|
onChange(newValue, y.value);
|
|
1653
1849
|
}
|
|
@@ -1656,12 +1852,15 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1656
1852
|
}
|
|
1657
1853
|
}, {
|
|
1658
1854
|
passive: false,
|
|
1659
|
-
}, [x, y]);
|
|
1855
|
+
}, [x, y, onChange, readonly, updateValueByEvent]);
|
|
1660
1856
|
useEventListener(globalThis.window, 'mousemove', (event) => {
|
|
1661
1857
|
handleValue(event);
|
|
1662
1858
|
});
|
|
1663
1859
|
useEventListener(globalThis.window, 'mouseup', () => {
|
|
1860
|
+
if (!thumbDragged.current || readonly)
|
|
1861
|
+
return;
|
|
1664
1862
|
thumbDragged.current = false;
|
|
1863
|
+
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(x.value, y.value);
|
|
1665
1864
|
if (bodyNoSelect)
|
|
1666
1865
|
removeNoSelect();
|
|
1667
1866
|
});
|
|
@@ -1683,14 +1882,42 @@ const XYPad = React.forwardRef((_a, ref) => {
|
|
|
1683
1882
|
wheelRefCallback(div);
|
|
1684
1883
|
touchMoveRefCallback(div);
|
|
1685
1884
|
}, tabIndex: -1, "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)`, cursor: readonly ? 'not-allowed' : 'pointer', WebkitTapHighlightColor: 'transparent' }, style), onPointerDown: (event) => {
|
|
1885
|
+
var _a, _b;
|
|
1686
1886
|
thumbDragged.current = true;
|
|
1687
|
-
handleValue(event);
|
|
1688
|
-
|
|
1887
|
+
const v = handleValue(event);
|
|
1888
|
+
if (!readonly)
|
|
1889
|
+
onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart((_a = v === null || v === void 0 ? void 0 : v[0]) !== null && _a !== void 0 ? _a : x.value, (_b = v === null || v === void 0 ? void 0 : v[1]) !== null && _b !== void 0 ? _b : y.value);
|
|
1890
|
+
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
1891
|
+
}, onKeyDown: (event) => {
|
|
1892
|
+
handleKeyDown(event);
|
|
1893
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
|
|
1894
|
+
}, onFocus: (event) => {
|
|
1895
|
+
var _a;
|
|
1896
|
+
(_a = thumbRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1897
|
+
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
1898
|
+
}, onBlur: (event) => {
|
|
1899
|
+
var _a;
|
|
1900
|
+
(_a = thumbRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
1901
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
1902
|
+
} }, props, { children: jsxRuntime.jsx("div", { className: "tremolo-xy-pad-area-wrapper", ref: areaElementRef, children: jsxRuntime.jsx(XYPadArea, Object.assign({ __thumb: jsxRuntime.jsx(XYPadThumb, Object.assign({ ref: thumbRef, __disabled: disabled, __css: {
|
|
1689
1903
|
top: `${percentY}%`,
|
|
1690
1904
|
left: `${percentX}%`,
|
|
1691
1905
|
} }, thumbProps)) }, areaProps)) }) })));
|
|
1692
1906
|
});
|
|
1693
1907
|
|
|
1908
|
+
const useAnimationFrame = (callback = () => { }, deps = []) => {
|
|
1909
|
+
const reqIdRef = React.useRef(-1);
|
|
1910
|
+
const loop = React.useCallback(() => {
|
|
1911
|
+
reqIdRef.current = requestAnimationFrame(loop);
|
|
1912
|
+
callback();
|
|
1913
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1914
|
+
}, [callback, ...deps]);
|
|
1915
|
+
React.useEffect(() => {
|
|
1916
|
+
reqIdRef.current = requestAnimationFrame(loop);
|
|
1917
|
+
return () => cancelAnimationFrame(reqIdRef.current);
|
|
1918
|
+
}, [loop]);
|
|
1919
|
+
};
|
|
1920
|
+
|
|
1694
1921
|
exports.AnimationCanvas = AnimationCanvas;
|
|
1695
1922
|
exports.AnimationKnob = AnimationKnob;
|
|
1696
1923
|
exports.BlackKey = BlackKey;
|
|
@@ -1701,9 +1928,9 @@ exports.KeyLabel = KeyLabel;
|
|
|
1701
1928
|
exports.Knob = Knob;
|
|
1702
1929
|
exports.NumberInput = NumberInput;
|
|
1703
1930
|
exports.Piano = Piano;
|
|
1931
|
+
exports.SHORTCUTS = SHORTCUTS;
|
|
1704
1932
|
exports.Scale = Scale;
|
|
1705
1933
|
exports.ScaleOption = ScaleOption;
|
|
1706
|
-
exports.Shortcuts = Shortcuts;
|
|
1707
1934
|
exports.Slider = Slider;
|
|
1708
1935
|
exports.SliderThumb = SliderThumb;
|
|
1709
1936
|
exports.SliderTrack = SliderTrack;
|
|
@@ -1713,5 +1940,10 @@ exports.WhiteKey = WhiteKey;
|
|
|
1713
1940
|
exports.XYPad = XYPad;
|
|
1714
1941
|
exports.XYPadArea = XYPadArea;
|
|
1715
1942
|
exports.XYPadThumb = XYPadThumb;
|
|
1943
|
+
exports.useAnimationFrame = useAnimationFrame;
|
|
1944
|
+
exports.useDrag = useDrag;
|
|
1945
|
+
exports.useEventListener = useEventListener;
|
|
1946
|
+
exports.useInterval = useInterval;
|
|
1947
|
+
exports.useLongPress = useLongPress;
|
|
1716
1948
|
exports.useSliderContext = useSliderContext;
|
|
1717
1949
|
//# sourceMappingURL=index.js.map
|