@tremolo-ui/react 0.8.0 → 0.9.0
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/index.cjs +416 -252
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +256 -110
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +256 -110
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +368 -203
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/components/AnimationCanvas/index.tsx +4 -18
- package/src/components/FileInput/index.tsx +4 -1
- package/src/components/Knob/Thumb.tsx +19 -19
- package/src/components/Knob/index.tsx +85 -41
- package/src/components/NumberInput/InputField.tsx +9 -7
- package/src/components/NumberInput/Stepper.tsx +30 -6
- package/src/components/NumberInput/StepperButton.tsx +12 -4
- package/src/components/NumberInput/context.tsx +24 -2
- package/src/components/NumberInput/index.tsx +142 -27
- package/src/components/Piano/index.tsx +24 -7
- package/src/components/PointsEditor/Container.tsx +1 -1
- package/src/components/PointsEditor/Point.tsx +61 -30
- package/src/components/PointsEditor/context.tsx +3 -4
- package/src/components/PointsEditor/index.tsx +14 -15
- package/src/components/Slider/Marks.tsx +3 -2
- package/src/components/Slider/MarksOption.tsx +3 -2
- package/src/components/Slider/Thumb.tsx +20 -11
- package/src/components/Slider/Track.tsx +15 -13
- package/src/components/Slider/context.tsx +3 -3
- package/src/components/Slider/index.tsx +85 -48
- package/src/components/XYPad/Thumb.tsx +18 -8
- package/src/components/XYPad/context.tsx +1 -1
- package/src/components/XYPad/index.tsx +74 -42
- package/src/components/_util/VisuallyHiddenRangeInput.tsx +1 -1
- package/src/hooks/_internal/useChangeGesture.ts +93 -0
- package/src/hooks/_internal/useCheckSteps.ts +1 -1
- package/src/hooks/useAnimationFrame.ts +37 -15
- package/src/hooks/useEventListener.ts +93 -22
- package/src/hooks/useWheel.ts +4 -4
- package/src/index.ts +9 -5
- package/src/hooks/useInterval.ts +0 -27
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ let react = require("react");
|
|
|
26
26
|
react = __toESM(react, 1);
|
|
27
27
|
let _tremolo_ui_dom = require("@tremolo-ui/dom");
|
|
28
28
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
29
|
+
let _tremolo_ui_dom_internal = require("@tremolo-ui/dom/internal");
|
|
29
30
|
let _tremolo_ui_functions = require("@tremolo-ui/functions");
|
|
30
31
|
//#region src/components/AnimationCanvas/index.tsx
|
|
31
32
|
/**
|
|
@@ -231,7 +232,7 @@ const FileInput = {
|
|
|
231
232
|
disabled
|
|
232
233
|
}), [inputId, disabled]);
|
|
233
234
|
function handleChange(event) {
|
|
234
|
-
const { accepted, rejected } = (0,
|
|
235
|
+
const { accepted, rejected } = (0, _tremolo_ui_dom_internal.partitionByAccept)(Array.from(event.target.files ?? []), accept);
|
|
235
236
|
event.target.value = "";
|
|
236
237
|
if (accepted.length > 0) onChange?.(accepted);
|
|
237
238
|
if (rejected.length > 0) onReject?.(rejected);
|
|
@@ -248,7 +249,7 @@ const FileInput = {
|
|
|
248
249
|
accept,
|
|
249
250
|
multiple,
|
|
250
251
|
disabled,
|
|
251
|
-
style:
|
|
252
|
+
style: _tremolo_ui_dom_internal.visuallyHiddenStyle,
|
|
252
253
|
"aria-label": ariaLabel,
|
|
253
254
|
"aria-labelledby": ariaLabelledby,
|
|
254
255
|
"aria-describedby": ariaDescribedby,
|
|
@@ -260,6 +261,57 @@ const FileInput = {
|
|
|
260
261
|
Trigger
|
|
261
262
|
};
|
|
262
263
|
//#endregion
|
|
264
|
+
//#region src/hooks/_internal/useChangeGesture.ts
|
|
265
|
+
/**
|
|
266
|
+
* The core's change gesture, reporting the control's value to
|
|
267
|
+
* `onChangeStart` / `onChangeEnd`. The start gets the value before the change,
|
|
268
|
+
* the end the last one reported.
|
|
269
|
+
*
|
|
270
|
+
* Internal
|
|
271
|
+
* @private
|
|
272
|
+
*/
|
|
273
|
+
function useChangeGesture(value, { onChangeStart, onChangeEnd, changeEndDelay }, inactive) {
|
|
274
|
+
const [instance] = (0, react.useState)(() => (0, _tremolo_ui_dom.createChangeGesture)());
|
|
275
|
+
const latest = (0, react.useRef)({
|
|
276
|
+
value,
|
|
277
|
+
onChangeStart,
|
|
278
|
+
onChangeEnd
|
|
279
|
+
});
|
|
280
|
+
const lastValue = (0, react.useRef)(value);
|
|
281
|
+
(0, react.useInsertionEffect)(() => {
|
|
282
|
+
latest.current = {
|
|
283
|
+
value,
|
|
284
|
+
onChangeStart,
|
|
285
|
+
onChangeEnd
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
(0, react.useEffect)(() => {
|
|
289
|
+
instance.update({
|
|
290
|
+
endDelay: changeEndDelay,
|
|
291
|
+
onStart: (source) => {
|
|
292
|
+
lastValue.current = latest.current.value;
|
|
293
|
+
latest.current.onChangeStart?.(latest.current.value, source);
|
|
294
|
+
},
|
|
295
|
+
onEnd: (source) => latest.current.onChangeEnd?.(lastValue.current, source)
|
|
296
|
+
});
|
|
297
|
+
}, [instance, changeEndDelay]);
|
|
298
|
+
(0, react.useEffect)(() => {
|
|
299
|
+
if (inactive) instance.end();
|
|
300
|
+
}, [instance, inactive]);
|
|
301
|
+
(0, react.useEffect)(() => () => instance.end(), [instance]);
|
|
302
|
+
const changed = (0, react.useCallback)((next) => {
|
|
303
|
+
lastValue.current = next;
|
|
304
|
+
}, []);
|
|
305
|
+
return (0, react.useMemo)(() => ({
|
|
306
|
+
hold: instance.hold,
|
|
307
|
+
pulse: instance.pulse,
|
|
308
|
+
instant: instance.instant,
|
|
309
|
+
end: instance.end,
|
|
310
|
+
active: instance.active,
|
|
311
|
+
changed
|
|
312
|
+
}), [instance, changed]);
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
263
315
|
//#region src/hooks/_internal/useCheckSteps.ts
|
|
264
316
|
/**
|
|
265
317
|
* Warn, in development only, when a key press or a wheel notch cannot produce
|
|
@@ -273,7 +325,7 @@ function useCheckSteps(options) {
|
|
|
273
325
|
(0, react.useEffect)(() => {
|
|
274
326
|
try {
|
|
275
327
|
if (process.env.NODE_ENV === "production") return;
|
|
276
|
-
for (const warning of (0,
|
|
328
|
+
for (const warning of (0, _tremolo_ui_dom_internal.checkSteps)(options)) console.warn(warning);
|
|
277
329
|
} catch {}
|
|
278
330
|
}, [
|
|
279
331
|
component,
|
|
@@ -374,7 +426,10 @@ function useWheel(onWheel, { requireFocus = false, target } = {}) {
|
|
|
374
426
|
(0, react.useEffect)(() => {
|
|
375
427
|
const element = target ? target.current : node;
|
|
376
428
|
if (!element) return;
|
|
377
|
-
const instance = (0, _tremolo_ui_dom.createWheel)(element,
|
|
429
|
+
const instance = (0, _tremolo_ui_dom.createWheel)(element, {
|
|
430
|
+
onWheel: (event) => wheelHandler(event),
|
|
431
|
+
requireFocus
|
|
432
|
+
});
|
|
378
433
|
return () => instance.destroy();
|
|
379
434
|
}, [
|
|
380
435
|
node,
|
|
@@ -497,7 +552,7 @@ function SVGRoot({ children, style, ...props }) {
|
|
|
497
552
|
}
|
|
498
553
|
//#endregion
|
|
499
554
|
//#region src/components/Knob/Thumb.tsx
|
|
500
|
-
function Thumb$2({ className,
|
|
555
|
+
function Thumb$2({ className, color = "currentColor", lineColor = "currentColor", size = 84, lineWeight = 6, lineLength = 35, classes, ...props }) {
|
|
501
556
|
useCheckPlacement("Knob.Thumb", "Knob.SVGRoot");
|
|
502
557
|
const angleRange = useKnobContext((s) => s.angleRange);
|
|
503
558
|
const p = useKnobContext((s) => s.p);
|
|
@@ -508,16 +563,16 @@ function Thumb$2({ className, thumb = "currentColor", thumbLine = "currentColor"
|
|
|
508
563
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
509
564
|
cx: "50%",
|
|
510
565
|
cy: "50%",
|
|
511
|
-
r: `${
|
|
512
|
-
fill:
|
|
566
|
+
r: `${size / 2}%`,
|
|
567
|
+
fill: color
|
|
513
568
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
514
|
-
className: classes?.
|
|
569
|
+
className: classes?.line,
|
|
515
570
|
x1: "50%",
|
|
516
|
-
y1: `${(_tremolo_ui_dom.KNOB_VIEWBOX_SIZE - (0, _tremolo_ui_functions.clamp)(
|
|
571
|
+
y1: `${(_tremolo_ui_dom.KNOB_VIEWBOX_SIZE - (0, _tremolo_ui_functions.clamp)(size, 0, 100)) / 2}%`,
|
|
517
572
|
x2: "50%",
|
|
518
|
-
y2: `${
|
|
519
|
-
stroke:
|
|
520
|
-
strokeWidth: `${
|
|
573
|
+
y2: `${lineLength}%`,
|
|
574
|
+
stroke: lineColor,
|
|
575
|
+
strokeWidth: `${lineWeight}%`,
|
|
521
576
|
style: {
|
|
522
577
|
transform: `rotate(${r1 + p * angleRange}deg)`,
|
|
523
578
|
transformOrigin: "50% 50%"
|
|
@@ -527,7 +582,6 @@ function Thumb$2({ className, thumb = "currentColor", thumbLine = "currentColor"
|
|
|
527
582
|
}
|
|
528
583
|
//#endregion
|
|
529
584
|
//#region src/components/Knob/index.tsx
|
|
530
|
-
const defaultExternalStyles$2 = { cursor: "grabbing" };
|
|
531
585
|
/**
|
|
532
586
|
* The wheel only acts while the focus is inside, so that scrolling a page past
|
|
533
587
|
* the control does not change its value.
|
|
@@ -537,13 +591,9 @@ const WHEEL_OPTIONS$2 = { requireFocus: true };
|
|
|
537
591
|
* Interactive rotary knob component implemented in SVG.
|
|
538
592
|
*/
|
|
539
593
|
const Knob = {
|
|
540
|
-
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min, max, step = 1, scale = _tremolo_ui_functions.linearScale,
|
|
594
|
+
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min, max, step = 1, scale = _tremolo_ui_functions.linearScale, resetValue, startValue = min, size, dragCursor = "grabbing", wheel = _tremolo_ui_dom.DEFAULT_WHEEL_OPTIONS, keyboard = _tremolo_ui_dom.DEFAULT_KEYBOARD_OPTIONS, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, pointerLock = false, disabled = false, readOnly = false, angleRange = 270, onChange, onChangeStart, onChangeEnd, changeEndDelay, onKeyDown, onPointerDown, onDoubleClick, className, style, children, actionsRef, ...props }, forwardedRef) => {
|
|
541
595
|
const elmRef = (0, react.useRef)(null);
|
|
542
|
-
const
|
|
543
|
-
...defaultExternalStyles$2,
|
|
544
|
-
..._externalStyles
|
|
545
|
-
};
|
|
546
|
-
const inactive = disabled || readonly;
|
|
596
|
+
const inactive = disabled || readOnly;
|
|
547
597
|
const range = (0, react.useMemo)(() => ({
|
|
548
598
|
min,
|
|
549
599
|
max,
|
|
@@ -561,18 +611,30 @@ const Knob = {
|
|
|
561
611
|
keyboard,
|
|
562
612
|
wheel
|
|
563
613
|
});
|
|
614
|
+
const gesture = useChangeGesture(value, {
|
|
615
|
+
onChangeStart,
|
|
616
|
+
onChangeEnd,
|
|
617
|
+
changeEndDelay
|
|
618
|
+
}, inactive);
|
|
619
|
+
const change = (0, react.useCallback)((next) => {
|
|
620
|
+
gesture.changed(next);
|
|
621
|
+
onChange?.(next);
|
|
622
|
+
}, [gesture, onChange]);
|
|
564
623
|
const handleKeyDown = (0, react.useCallback)((event) => {
|
|
565
624
|
if (!keyboard || !onChange || inactive) return;
|
|
566
|
-
const direction = (0,
|
|
625
|
+
const direction = (0, _tremolo_ui_dom_internal.arrowKeyDirection)(event.key);
|
|
567
626
|
if (direction === null) return;
|
|
568
627
|
event.preventDefault();
|
|
569
|
-
|
|
628
|
+
gesture.pulse("keyboard");
|
|
629
|
+
change((0, _tremolo_ui_dom_internal.applyDelta)(value, direction, keyboard, range, event));
|
|
570
630
|
}, [
|
|
571
631
|
keyboard,
|
|
572
632
|
onChange,
|
|
573
633
|
inactive,
|
|
574
634
|
value,
|
|
575
|
-
range
|
|
635
|
+
range,
|
|
636
|
+
gesture,
|
|
637
|
+
change
|
|
576
638
|
]);
|
|
577
639
|
const { refCallback: dragRefCallback, dragging } = useDragValue({
|
|
578
640
|
axis: (0, react.useMemo)(() => [range, {
|
|
@@ -580,25 +642,30 @@ const Knob = {
|
|
|
580
642
|
reverse: true
|
|
581
643
|
}], [range]),
|
|
582
644
|
getValue: () => [value, value],
|
|
583
|
-
sensitivity: (state) => (0,
|
|
645
|
+
sensitivity: (state) => (0, _tremolo_ui_dom_internal.selectModifier)(dragSensitivity, state.event).value,
|
|
584
646
|
threshold: 1,
|
|
585
|
-
cursor: inactive ? void 0 :
|
|
647
|
+
cursor: inactive ? void 0 : dragCursor,
|
|
586
648
|
pointerLock: inactive ? false : pointerLock,
|
|
587
649
|
shouldStart: () => !inactive,
|
|
588
650
|
onChange: (v) => {
|
|
589
651
|
if (inactive) return;
|
|
590
|
-
|
|
591
|
-
}
|
|
652
|
+
change(v[1]);
|
|
653
|
+
},
|
|
654
|
+
onDragStart: () => {
|
|
655
|
+
if (!inactive) gesture.hold("pointer");
|
|
656
|
+
},
|
|
657
|
+
onDragEnd: () => gesture.end()
|
|
592
658
|
});
|
|
593
659
|
const wheelRefCallback = useWheel((event) => {
|
|
594
660
|
if (!wheel || inactive) return;
|
|
595
|
-
const direction = (0,
|
|
661
|
+
const direction = (0, _tremolo_ui_dom_internal.wheelDirection)(event);
|
|
596
662
|
if (direction === null) return;
|
|
597
663
|
event.preventDefault();
|
|
598
664
|
if (!onChange) return;
|
|
599
|
-
|
|
665
|
+
gesture.pulse("wheel");
|
|
666
|
+
change((0, _tremolo_ui_dom_internal.applyDelta)(value, direction, wheel, range, event));
|
|
600
667
|
}, WHEEL_OPTIONS$2);
|
|
601
|
-
const rootRefCallback = require_compose_refs.useComposedRefs(elmRef, dragRefCallback, wheelRefCallback);
|
|
668
|
+
const rootRefCallback = require_compose_refs.useComposedRefs(forwardedRef, elmRef, dragRefCallback, wheelRefCallback);
|
|
602
669
|
const context = (0, react.useMemo)(() => {
|
|
603
670
|
const config = {
|
|
604
671
|
value,
|
|
@@ -622,7 +689,7 @@ const Knob = {
|
|
|
622
689
|
startValue,
|
|
623
690
|
angleRange
|
|
624
691
|
]);
|
|
625
|
-
(0, react.useImperativeHandle)(
|
|
692
|
+
(0, react.useImperativeHandle)(actionsRef, () => {
|
|
626
693
|
return {
|
|
627
694
|
focus() {
|
|
628
695
|
if (!disabled) elmRef.current?.focus();
|
|
@@ -643,17 +710,17 @@ const Knob = {
|
|
|
643
710
|
"aria-valuemin": min,
|
|
644
711
|
"aria-valuemax": max,
|
|
645
712
|
"aria-disabled": disabled,
|
|
646
|
-
"aria-readonly":
|
|
713
|
+
"aria-readonly": readOnly,
|
|
647
714
|
"data-disabled": disabled ? "" : void 0,
|
|
648
|
-
"data-readonly":
|
|
715
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
649
716
|
"data-dragging": dragging ? "" : void 0,
|
|
650
717
|
style: {
|
|
651
|
-
"--knob-size": (0,
|
|
718
|
+
"--knob-size": (0, _tremolo_ui_dom_internal.cssLength)(size),
|
|
652
719
|
...style
|
|
653
720
|
},
|
|
654
721
|
onPointerDown,
|
|
655
722
|
onDoubleClick: (event) => {
|
|
656
|
-
if (!inactive &&
|
|
723
|
+
if (!inactive && resetValue !== null && onChange) gesture.instant("doubleClick", () => change(resetValue ?? startValue));
|
|
657
724
|
onDoubleClick?.(event);
|
|
658
725
|
},
|
|
659
726
|
onKeyDown: (event) => {
|
|
@@ -679,6 +746,11 @@ function useNumberInputContext(selector) {
|
|
|
679
746
|
if (!context) throw new Error("Missing NumberInputContext.Provider in the tree");
|
|
680
747
|
return selector ? selector(context) : context;
|
|
681
748
|
}
|
|
749
|
+
const NumberInputGestureContext = /* @__PURE__ */ (0, react.createContext)(null);
|
|
750
|
+
const NumberInputGestureProvider = NumberInputGestureContext.Provider;
|
|
751
|
+
function useNumberInputGesture() {
|
|
752
|
+
return (0, react.useContext)(NumberInputGestureContext);
|
|
753
|
+
}
|
|
682
754
|
const StepperContext = /* @__PURE__ */ (0, react.createContext)(null);
|
|
683
755
|
const StepperProvider = StepperContext.Provider;
|
|
684
756
|
function useStepperContext() {
|
|
@@ -723,8 +795,9 @@ function useLongPress(callback, initialDelay = 500, interval = 40) {
|
|
|
723
795
|
* in which way they move the value and which arrow they draw.
|
|
724
796
|
*/
|
|
725
797
|
function StepperButton({ direction, variant, icon, className, style, children, onPointerDown, ...props }) {
|
|
726
|
-
const { step, disabled,
|
|
798
|
+
const { step, disabled, readOnly, atMin, atMax, nudge } = useNumberInputContext();
|
|
727
799
|
const stepper = useStepperContext();
|
|
800
|
+
const gesture = useNumberInputGesture();
|
|
728
801
|
const press = useLongPress(() => {
|
|
729
802
|
if (stepper?.moved()) return;
|
|
730
803
|
nudge(direction, ["raw", step]);
|
|
@@ -736,10 +809,13 @@ function StepperButton({ direction, variant, icon, className, style, children, o
|
|
|
736
809
|
"aria-label": direction > 0 ? "Increment" : "Decrement",
|
|
737
810
|
"aria-disabled": disabled || (direction > 0 ? atMax : atMin),
|
|
738
811
|
"data-disabled": disabled || (direction > 0 ? atMax : atMin) ? "" : void 0,
|
|
739
|
-
"data-readonly":
|
|
812
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
740
813
|
style,
|
|
741
814
|
onPointerDown: (event) => {
|
|
742
|
-
if (!disabled && !
|
|
815
|
+
if (!disabled && !readOnly) {
|
|
816
|
+
gesture?.press();
|
|
817
|
+
press(event);
|
|
818
|
+
}
|
|
743
819
|
onPointerDown?.(event);
|
|
744
820
|
},
|
|
745
821
|
...props,
|
|
@@ -795,7 +871,8 @@ function IncrementStepper(props) {
|
|
|
795
871
|
* (`selectOnFocus`, `unformatOnFocus`, `keepCaretOnStep`, `blurOnEnter`).
|
|
796
872
|
*/
|
|
797
873
|
const InputField = /* @__PURE__ */ (0, react.forwardRef)(function InputField({ className, style, onChange, onFocus, onBlur, onKeyDown, ...props }, forwardedRef) {
|
|
798
|
-
const { value, min, max, step, disabled,
|
|
874
|
+
const { value, min, max, step, disabled, readOnly, keyboard, selectOnFocus, unformatOnFocus, keepCaretOnStep, blurOnEnter, text, editing, outOfRange, setDraft, commitDraft, nudge, inputRef } = useNumberInputContext();
|
|
875
|
+
const gesture = useNumberInputGesture();
|
|
799
876
|
const [focused, setFocused] = (0, react.useState)(false);
|
|
800
877
|
const shown = unformatOnFocus && focused && !editing ? String(value) : text;
|
|
801
878
|
(0, react.useEffect)(() => {
|
|
@@ -804,7 +881,7 @@ const InputField = /* @__PURE__ */ (0, react.forwardRef)(function InputField({ c
|
|
|
804
881
|
if (!input) return;
|
|
805
882
|
if (selectOnFocus === "all") input.setSelectionRange(0, input.value.length);
|
|
806
883
|
else {
|
|
807
|
-
const span = (0,
|
|
884
|
+
const span = (0, _tremolo_ui_dom_internal.numberSpan)(input.value);
|
|
808
885
|
if (span) input.setSelectionRange(span.start, span.end);
|
|
809
886
|
}
|
|
810
887
|
}, [
|
|
@@ -823,7 +900,7 @@ const InputField = /* @__PURE__ */ (0, react.forwardRef)(function InputField({ c
|
|
|
823
900
|
caretAfterStep.current = null;
|
|
824
901
|
const input = inputRef.current;
|
|
825
902
|
if (!input || input.value === pending.from) return;
|
|
826
|
-
const caret = (0,
|
|
903
|
+
const caret = (0, _tremolo_ui_dom_internal.caretAtDecimalOffset)(input.value, pending.offset);
|
|
827
904
|
input.setSelectionRange(caret, caret);
|
|
828
905
|
});
|
|
829
906
|
const composedRef = require_compose_refs.useComposedRefs(forwardedRef, inputRef);
|
|
@@ -835,11 +912,11 @@ const InputField = /* @__PURE__ */ (0, react.forwardRef)(function InputField({ c
|
|
|
835
912
|
role: "spinbutton",
|
|
836
913
|
value: shown,
|
|
837
914
|
disabled,
|
|
838
|
-
readOnly
|
|
915
|
+
readOnly,
|
|
839
916
|
"aria-disabled": disabled,
|
|
840
|
-
"aria-readonly":
|
|
917
|
+
"aria-readonly": readOnly,
|
|
841
918
|
"data-disabled": disabled ? "" : void 0,
|
|
842
|
-
"data-readonly":
|
|
919
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
843
920
|
"aria-valuenow": value,
|
|
844
921
|
"aria-valuemin": min,
|
|
845
922
|
"aria-valuemax": max,
|
|
@@ -866,13 +943,14 @@ const InputField = /* @__PURE__ */ (0, react.forwardRef)(function InputField({ c
|
|
|
866
943
|
if (key === "Enter") {
|
|
867
944
|
commitDraft();
|
|
868
945
|
if (blurOnEnter) event.currentTarget.blur();
|
|
869
|
-
} else if (keyboard && !disabled && !
|
|
946
|
+
} else if (keyboard && !disabled && !readOnly && (key === "ArrowUp" || key === "ArrowDown") && !event.nativeEvent.isComposing) {
|
|
870
947
|
event.preventDefault();
|
|
871
948
|
const input = event.currentTarget;
|
|
872
949
|
if (keepCaretOnStep && input.selectionStart !== null) caretAfterStep.current = {
|
|
873
|
-
offset: (0,
|
|
950
|
+
offset: (0, _tremolo_ui_dom_internal.caretDecimalOffset)(input.value, input.selectionStart),
|
|
874
951
|
from: input.value
|
|
875
952
|
};
|
|
953
|
+
gesture?.key();
|
|
876
954
|
nudge(key === "ArrowUp" ? 1 : -1, keyboard, event);
|
|
877
955
|
}
|
|
878
956
|
onKeyDown?.(event);
|
|
@@ -890,9 +968,9 @@ const InputField = /* @__PURE__ */ (0, react.forwardRef)(function InputField({ c
|
|
|
890
968
|
* The drag lives here rather than on `InputField` because `createDrag` turns
|
|
891
969
|
* off text selection on whatever element it is attached to.
|
|
892
970
|
*/
|
|
893
|
-
const Stepper = /* @__PURE__ */ (0, react.forwardRef)(function Stepper({ className, style, children, ...props }, forwardedRef) {
|
|
894
|
-
const { value, disabled,
|
|
895
|
-
const enabled = drag !== null && !disabled && !
|
|
971
|
+
const Stepper = /* @__PURE__ */ (0, react.forwardRef)(function Stepper({ className, style, children, onPointerDown, ...props }, forwardedRef) {
|
|
972
|
+
const { value, disabled, readOnly, drag, dragSensitivity, pointerLock, dragCursor, rawRange, changeValue } = useNumberInputContext();
|
|
973
|
+
const enabled = drag !== null && !disabled && !readOnly;
|
|
896
974
|
const [node, setNode] = (0, react.useState)(null);
|
|
897
975
|
const instanceRef = (0, react.useRef)(null);
|
|
898
976
|
const latest = (0, react.useRef)({
|
|
@@ -903,7 +981,8 @@ const Stepper = /* @__PURE__ */ (0, react.forwardRef)(function Stepper({ classNa
|
|
|
903
981
|
range: rawRange,
|
|
904
982
|
pixels: drag ?? 1,
|
|
905
983
|
sensitivity: dragSensitivity,
|
|
906
|
-
pointerLock
|
|
984
|
+
pointerLock,
|
|
985
|
+
cursor: dragCursor
|
|
907
986
|
};
|
|
908
987
|
const optionsRef = (0, react.useRef)(options);
|
|
909
988
|
(0, react.useEffect)(() => {
|
|
@@ -916,7 +995,7 @@ const Stepper = /* @__PURE__ */ (0, react.forwardRef)(function Stepper({ classNa
|
|
|
916
995
|
});
|
|
917
996
|
(0, react.useEffect)(() => {
|
|
918
997
|
if (!node || !enabled) return;
|
|
919
|
-
const instance = (0,
|
|
998
|
+
const instance = (0, _tremolo_ui_dom_internal.createStepperDrag)(node, {
|
|
920
999
|
...optionsRef.current,
|
|
921
1000
|
getValue: () => latest.current.value,
|
|
922
1001
|
onChange: (next) => latest.current.changeValue(next)
|
|
@@ -927,6 +1006,7 @@ const Stepper = /* @__PURE__ */ (0, react.forwardRef)(function Stepper({ classNa
|
|
|
927
1006
|
instance.destroy();
|
|
928
1007
|
};
|
|
929
1008
|
}, [node, enabled]);
|
|
1009
|
+
const gesture = useNumberInputGesture();
|
|
930
1010
|
const composedRef = require_compose_refs.useComposedRefs(forwardedRef, setNode);
|
|
931
1011
|
const context = (0, react.useMemo)(() => ({ moved: () => instanceRef.current?.moved() ?? false }), []);
|
|
932
1012
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StepperProvider, {
|
|
@@ -935,6 +1015,10 @@ const Stepper = /* @__PURE__ */ (0, react.forwardRef)(function Stepper({ classNa
|
|
|
935
1015
|
ref: composedRef,
|
|
936
1016
|
className,
|
|
937
1017
|
style,
|
|
1018
|
+
onPointerDown: (event) => {
|
|
1019
|
+
if (enabled) gesture?.press();
|
|
1020
|
+
onPointerDown?.(event);
|
|
1021
|
+
},
|
|
938
1022
|
...props,
|
|
939
1023
|
children
|
|
940
1024
|
})
|
|
@@ -947,17 +1031,22 @@ const defaultFormat = (value) => String(value);
|
|
|
947
1031
|
* Input with some useful functions for entering numerical values.
|
|
948
1032
|
*/
|
|
949
1033
|
const NumberInput = {
|
|
950
|
-
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min, max, step = 1, scale = _tremolo_ui_functions.linearScale, format: formatProp, parse: parseProp, clampValue = true, wheel = _tremolo_ui_dom.DEFAULT_WHEEL_OPTIONS, keyboard = _tremolo_ui_dom.DEFAULT_KEYBOARD_OPTIONS, drag = 1, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, pointerLock = false, selectOnFocus = "none", unformatOnFocus = false, keepCaretOnStep = false, blurOnEnter = true, disabled = false,
|
|
1034
|
+
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min, max, step = 1, scale = _tremolo_ui_functions.linearScale, format: formatProp, parse: parseProp, clampValue = true, wheel = _tremolo_ui_dom.DEFAULT_WHEEL_OPTIONS, keyboard = _tremolo_ui_dom.DEFAULT_KEYBOARD_OPTIONS, drag = 1, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, pointerLock = false, dragCursor = "ns-resize", selectOnFocus = "none", unformatOnFocus = false, keepCaretOnStep = false, blurOnEnter = true, disabled = false, readOnly = false, className, style, onChange, onChangeStart, onChangeEnd, changeEndDelay, children, actionsRef, ...props }, forwardedRef) => {
|
|
951
1035
|
const inputRef = (0, react.useRef)(null);
|
|
952
1036
|
/**
|
|
953
1037
|
* The text being typed. The only state here: it is not a copy of `value`,
|
|
954
1038
|
* but the half-finished entry that has no value to be derived from yet.
|
|
955
1039
|
*/
|
|
956
1040
|
const [draft, setDraft] = (0, react.useState)(null);
|
|
957
|
-
const inactive = disabled ||
|
|
1041
|
+
const inactive = disabled || readOnly;
|
|
1042
|
+
const gesture = useChangeGesture(value, {
|
|
1043
|
+
onChangeStart,
|
|
1044
|
+
onChangeEnd,
|
|
1045
|
+
changeEndDelay
|
|
1046
|
+
}, inactive);
|
|
958
1047
|
const format = formatProp ?? defaultFormat;
|
|
959
|
-
const parse = parseProp ??
|
|
960
|
-
const { normalized: range, raw: rawRange } = (0, react.useMemo)(() => (0,
|
|
1048
|
+
const parse = parseProp ?? _tremolo_ui_dom_internal.parseNumberText;
|
|
1049
|
+
const { normalized: range, raw: rawRange } = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.numberInputRanges)({
|
|
961
1050
|
min,
|
|
962
1051
|
max,
|
|
963
1052
|
step,
|
|
@@ -993,7 +1082,7 @@ const NumberInput = {
|
|
|
993
1082
|
});
|
|
994
1083
|
const text = draft ?? format(value);
|
|
995
1084
|
const editing = draft !== null;
|
|
996
|
-
const bounds = (0,
|
|
1085
|
+
const bounds = (0, _tremolo_ui_dom_internal.numberInputBounds)(value, {
|
|
997
1086
|
min,
|
|
998
1087
|
max,
|
|
999
1088
|
clampValue
|
|
@@ -1004,30 +1093,45 @@ const NumberInput = {
|
|
|
1004
1093
|
if (inactive) return;
|
|
1005
1094
|
setDraft(next);
|
|
1006
1095
|
const parsed = parse(next);
|
|
1007
|
-
if (Number.isFinite(parsed))
|
|
1096
|
+
if (!Number.isFinite(parsed)) return;
|
|
1097
|
+
if (parsed !== value) {
|
|
1098
|
+
gesture.pulse("keyboard");
|
|
1099
|
+
gesture.changed(parsed);
|
|
1100
|
+
}
|
|
1101
|
+
onChange?.(parsed);
|
|
1008
1102
|
}, [
|
|
1009
1103
|
inactive,
|
|
1010
1104
|
parse,
|
|
1011
|
-
onChange
|
|
1105
|
+
onChange,
|
|
1106
|
+
value,
|
|
1107
|
+
gesture
|
|
1012
1108
|
]);
|
|
1013
1109
|
const changeValue = (0, react.useCallback)((next) => {
|
|
1014
1110
|
if (inactive) return;
|
|
1015
1111
|
setDraft(null);
|
|
1016
|
-
if (next
|
|
1112
|
+
if (next === value) return;
|
|
1113
|
+
gesture.changed(next);
|
|
1114
|
+
onChange?.(next);
|
|
1017
1115
|
}, [
|
|
1018
1116
|
inactive,
|
|
1019
1117
|
value,
|
|
1020
|
-
onChange
|
|
1118
|
+
onChange,
|
|
1119
|
+
gesture
|
|
1021
1120
|
]);
|
|
1022
1121
|
const commitDraft = (0, react.useCallback)(() => {
|
|
1023
1122
|
if (draft === null || inactive) return;
|
|
1024
|
-
const committed = (0,
|
|
1123
|
+
const committed = (0, _tremolo_ui_dom_internal.commitNumberInputText)(draft, parse, {
|
|
1025
1124
|
min,
|
|
1026
1125
|
max,
|
|
1027
1126
|
clampValue
|
|
1028
1127
|
});
|
|
1029
|
-
if (committed === null)
|
|
1030
|
-
|
|
1128
|
+
if (committed === null) {
|
|
1129
|
+
setDraft(null);
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (committed !== value) gesture.pulse("keyboard");
|
|
1133
|
+
changeValue(committed);
|
|
1134
|
+
gesture.end();
|
|
1031
1135
|
}, [
|
|
1032
1136
|
draft,
|
|
1033
1137
|
inactive,
|
|
@@ -1035,19 +1139,22 @@ const NumberInput = {
|
|
|
1035
1139
|
clampValue,
|
|
1036
1140
|
min,
|
|
1037
1141
|
max,
|
|
1038
|
-
changeValue
|
|
1142
|
+
changeValue,
|
|
1143
|
+
value,
|
|
1144
|
+
gesture
|
|
1039
1145
|
]);
|
|
1040
1146
|
const nudge = (0, react.useCallback)((direction, option, modifiers) => {
|
|
1041
|
-
changeValue((0,
|
|
1147
|
+
changeValue((0, _tremolo_ui_dom_internal.nudgeNumberInput)(value, direction, option, ranges, modifiers));
|
|
1042
1148
|
}, [
|
|
1043
1149
|
changeValue,
|
|
1044
1150
|
value,
|
|
1045
1151
|
ranges
|
|
1046
1152
|
]);
|
|
1047
1153
|
const wheelRefCallback = useWheel((event) => {
|
|
1048
|
-
const direction = (0,
|
|
1154
|
+
const direction = (0, _tremolo_ui_dom_internal.wheelDirection)(event);
|
|
1049
1155
|
if (!wheel || inactive || direction === null) return;
|
|
1050
1156
|
event.preventDefault();
|
|
1157
|
+
gesture.pulse("wheel");
|
|
1051
1158
|
nudge(direction, wheel, event);
|
|
1052
1159
|
}, { requireFocus: true });
|
|
1053
1160
|
const context = (0, react.useMemo)(() => ({
|
|
@@ -1057,7 +1164,7 @@ const NumberInput = {
|
|
|
1057
1164
|
step,
|
|
1058
1165
|
scale,
|
|
1059
1166
|
disabled,
|
|
1060
|
-
|
|
1167
|
+
readOnly,
|
|
1061
1168
|
clampValue,
|
|
1062
1169
|
range,
|
|
1063
1170
|
rawRange,
|
|
@@ -1067,6 +1174,7 @@ const NumberInput = {
|
|
|
1067
1174
|
outOfRange,
|
|
1068
1175
|
dragSensitivity,
|
|
1069
1176
|
pointerLock,
|
|
1177
|
+
dragCursor,
|
|
1070
1178
|
selectOnFocus,
|
|
1071
1179
|
unformatOnFocus,
|
|
1072
1180
|
keepCaretOnStep,
|
|
@@ -1088,7 +1196,7 @@ const NumberInput = {
|
|
|
1088
1196
|
step,
|
|
1089
1197
|
scale,
|
|
1090
1198
|
disabled,
|
|
1091
|
-
|
|
1199
|
+
readOnly,
|
|
1092
1200
|
clampValue,
|
|
1093
1201
|
range,
|
|
1094
1202
|
rawRange,
|
|
@@ -1101,6 +1209,7 @@ const NumberInput = {
|
|
|
1101
1209
|
drag,
|
|
1102
1210
|
dragSensitivity,
|
|
1103
1211
|
pointerLock,
|
|
1212
|
+
dragCursor,
|
|
1104
1213
|
selectOnFocus,
|
|
1105
1214
|
unformatOnFocus,
|
|
1106
1215
|
keepCaretOnStep,
|
|
@@ -1112,7 +1221,8 @@ const NumberInput = {
|
|
|
1112
1221
|
changeValue,
|
|
1113
1222
|
nudge
|
|
1114
1223
|
]);
|
|
1115
|
-
|
|
1224
|
+
const rootRefCallback = require_compose_refs.useComposedRefs(forwardedRef, wheelRefCallback);
|
|
1225
|
+
(0, react.useImperativeHandle)(actionsRef, () => {
|
|
1116
1226
|
return {
|
|
1117
1227
|
focus() {
|
|
1118
1228
|
if (!disabled) inputRef.current?.focus();
|
|
@@ -1122,16 +1232,39 @@ const NumberInput = {
|
|
|
1122
1232
|
}
|
|
1123
1233
|
};
|
|
1124
1234
|
}, [disabled]);
|
|
1235
|
+
const pressed = (0, react.useRef)(false);
|
|
1236
|
+
const gestureContext = (0, react.useMemo)(() => ({
|
|
1237
|
+
press: () => {
|
|
1238
|
+
if (inactive) return;
|
|
1239
|
+
gesture.hold("pointer");
|
|
1240
|
+
if (pressed.current) return;
|
|
1241
|
+
pressed.current = true;
|
|
1242
|
+
const release = () => {
|
|
1243
|
+
pressed.current = false;
|
|
1244
|
+
gesture.end();
|
|
1245
|
+
window.removeEventListener("pointerup", release);
|
|
1246
|
+
window.removeEventListener("pointercancel", release);
|
|
1247
|
+
};
|
|
1248
|
+
window.addEventListener("pointerup", release);
|
|
1249
|
+
window.addEventListener("pointercancel", release);
|
|
1250
|
+
},
|
|
1251
|
+
key: () => {
|
|
1252
|
+
if (!inactive) gesture.pulse("keyboard");
|
|
1253
|
+
}
|
|
1254
|
+
}), [gesture, inactive]);
|
|
1125
1255
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberInputProvider, {
|
|
1126
1256
|
value: context,
|
|
1127
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1257
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberInputGestureProvider, {
|
|
1258
|
+
value: gestureContext,
|
|
1259
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1260
|
+
ref: rootRefCallback,
|
|
1261
|
+
className,
|
|
1262
|
+
"data-disabled": disabled ? "" : void 0,
|
|
1263
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1264
|
+
style,
|
|
1265
|
+
...props,
|
|
1266
|
+
children
|
|
1267
|
+
})
|
|
1135
1268
|
})
|
|
1136
1269
|
});
|
|
1137
1270
|
}),
|
|
@@ -1143,12 +1276,12 @@ const NumberInput = {
|
|
|
1143
1276
|
/**
|
|
1144
1277
|
* Customizable piano component.
|
|
1145
1278
|
*/
|
|
1146
|
-
const Piano = { Root: /* @__PURE__ */ (0, react.forwardRef)(function Root({ noteRange, glissando = true, midiMax = 127, keyboardShortcuts, keyboardShortcutsScope = "root", resizable = false, whiteKeyWidth = 40, keyGap = 1, blackKeyWidthRatio = .65, blackKeyHeightRatio = .6, style, className, label, keyProps, classes, onPlayNote, onStopNote, ...props }, forwardedRef) {
|
|
1279
|
+
const Piano = { Root: /* @__PURE__ */ (0, react.forwardRef)(function Root({ noteRange, glissando = true, midiMax = 127, keyboardShortcuts, keyboardShortcutsScope = "root", resizable = false, whiteKeyWidth = 40, keyGap = 1, blackKeyWidthRatio = .65, blackKeyHeightRatio = .6, style, className, label, keyProps, classes, onPlayNote, onStopNote, actionsRef, ...props }, forwardedRef) {
|
|
1147
1280
|
const [node, setNode] = (0, react.useState)(null);
|
|
1148
1281
|
const [activeNotes, setActiveNotes] = (0, react.useState)([]);
|
|
1149
1282
|
/** Set while `resizable` is on, measured from the parent. */
|
|
1150
1283
|
const [resizedKeyWidth, setResizedKeyWidth] = (0, react.useState)(whiteKeyWidth);
|
|
1151
|
-
const notes = (0, react.useMemo)(() => (0,
|
|
1284
|
+
const notes = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.getNoteRangeArray)(noteRange), [noteRange]);
|
|
1152
1285
|
const layout = (0, react.useMemo)(() => ({
|
|
1153
1286
|
noteRange,
|
|
1154
1287
|
whiteKeyWidth: resizable ? resizedKeyWidth : whiteKeyWidth,
|
|
@@ -1216,7 +1349,7 @@ const Piano = { Root: /* @__PURE__ */ (0, react.forwardRef)(function Root({ note
|
|
|
1216
1349
|
const parent = node.parentElement;
|
|
1217
1350
|
if (!parent) throw new Error("doesn't have a parent element.");
|
|
1218
1351
|
const resizeObserver = new ResizeObserver(() => {
|
|
1219
|
-
setResizedKeyWidth((0,
|
|
1352
|
+
setResizedKeyWidth((0, _tremolo_ui_dom_internal.fitWhiteKeyWidth)(node.clientWidth, {
|
|
1220
1353
|
noteRange: {
|
|
1221
1354
|
first,
|
|
1222
1355
|
last
|
|
@@ -1235,7 +1368,8 @@ const Piano = { Root: /* @__PURE__ */ (0, react.forwardRef)(function Root({ note
|
|
|
1235
1368
|
keyGap,
|
|
1236
1369
|
blackKeyWidthRatio
|
|
1237
1370
|
]);
|
|
1238
|
-
|
|
1371
|
+
const rootRefCallback = require_compose_refs.useComposedRefs(forwardedRef, setNode);
|
|
1372
|
+
(0, react.useImperativeHandle)(actionsRef, () => ({
|
|
1239
1373
|
playNote: (note, velocity) => instanceRef.current?.noteOn(note, {
|
|
1240
1374
|
source: "api",
|
|
1241
1375
|
velocity
|
|
@@ -1243,13 +1377,13 @@ const Piano = { Root: /* @__PURE__ */ (0, react.forwardRef)(function Root({ note
|
|
|
1243
1377
|
stopNote: (note) => instanceRef.current?.noteOff(note, { source: "api" })
|
|
1244
1378
|
}), []);
|
|
1245
1379
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1246
|
-
ref:
|
|
1380
|
+
ref: rootRefCallback,
|
|
1247
1381
|
className,
|
|
1248
1382
|
"data-resizable": resizable ? "" : void 0,
|
|
1249
1383
|
role: "group",
|
|
1250
1384
|
tabIndex: 0,
|
|
1251
1385
|
style: {
|
|
1252
|
-
width: resizable ? "100%" : (0,
|
|
1386
|
+
width: resizable ? "100%" : (0, _tremolo_ui_dom_internal.pianoWidth)(layout),
|
|
1253
1387
|
position: "relative",
|
|
1254
1388
|
...style
|
|
1255
1389
|
},
|
|
@@ -1276,7 +1410,7 @@ const Piano = { Root: /* @__PURE__ */ (0, react.forwardRef)(function Root({ note
|
|
|
1276
1410
|
zIndex: keyType === "white" ? 1 : 2,
|
|
1277
1411
|
...keyStyle,
|
|
1278
1412
|
left: (0, _tremolo_ui_dom.notePosition)(note, layout),
|
|
1279
|
-
width: keyType === "white" ? layout.whiteKeyWidth : (0,
|
|
1413
|
+
width: keyType === "white" ? layout.whiteKeyWidth : (0, _tremolo_ui_dom_internal.blackKeyWidth)(layout),
|
|
1280
1414
|
height: keyType === "white" ? "100%" : `${blackKeyHeightRatio * 100}%`
|
|
1281
1415
|
},
|
|
1282
1416
|
children: content !== "" && content !== null && content !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -1319,7 +1453,7 @@ function usePointsEditorContext(selector) {
|
|
|
1319
1453
|
const Container = /* @__PURE__ */ (0, react.forwardRef)(function Container({ children, className, style, ...props }, forwardedRef) {
|
|
1320
1454
|
const { containerRef, disabled, selectable, editor } = usePointsEditorContext();
|
|
1321
1455
|
const { refCallback: dragRefCallback } = useDragValue({
|
|
1322
|
-
axis:
|
|
1456
|
+
axis: _tremolo_ui_dom_internal.POINT_AXIS,
|
|
1323
1457
|
baseElementRef: containerRef,
|
|
1324
1458
|
shouldStart: (event) => !disabled && !editor.isPointElement(event.target),
|
|
1325
1459
|
onDragStart: ([x, y], state) => {
|
|
@@ -1335,7 +1469,7 @@ const Container = /* @__PURE__ */ (0, react.forwardRef)(function Container({ chi
|
|
|
1335
1469
|
onDragEnd: () => editor.endSelectionBox()
|
|
1336
1470
|
});
|
|
1337
1471
|
useWheel((event) => {
|
|
1338
|
-
const move = (0,
|
|
1472
|
+
const move = (0, _tremolo_ui_dom_internal.wheelMove)(event);
|
|
1339
1473
|
if (!move) return;
|
|
1340
1474
|
const axis = move.axis === 0 ? "x" : "y";
|
|
1341
1475
|
if (editor.nudgeFocusedPoint(axis, move.direction, event)) event.preventDefault();
|
|
@@ -1363,7 +1497,7 @@ const VisuallyHiddenRangeInput = /* @__PURE__ */ (0, react.forwardRef)((props, r
|
|
|
1363
1497
|
...props,
|
|
1364
1498
|
ref,
|
|
1365
1499
|
type: "range",
|
|
1366
|
-
style:
|
|
1500
|
+
style: _tremolo_ui_dom_internal.visuallyHiddenStyle
|
|
1367
1501
|
}));
|
|
1368
1502
|
//#endregion
|
|
1369
1503
|
//#region src/components/PointsEditor/Point.tsx
|
|
@@ -1374,17 +1508,27 @@ const VisuallyHiddenRangeInput = /* @__PURE__ */ (0, react.forwardRef)((props, r
|
|
|
1374
1508
|
function perAxis(value, axis) {
|
|
1375
1509
|
return typeof value === "string" ? value : value?.[axis];
|
|
1376
1510
|
}
|
|
1377
|
-
function Point({ value, children, id: idProp, min, max, color, disabled: _disabled,
|
|
1378
|
-
const { containerRef,
|
|
1511
|
+
function Point({ value, children, id: idProp, min, max, color, disabled: _disabled, readOnly: _readOnly, wheel: _wheel, keyboard: _keyboard, "aria-label": ariaLabel, "aria-valuetext": ariaValuetext, onChange, onChangeStart, onChangeEnd, changeEndDelay, className, style, onPointerDown, onKeyDown, onFocus, ...props }) {
|
|
1512
|
+
const { containerRef, dragCursor, disabled: rootDisabled, readOnly: rootReadOnly, wheel: rootWheel, keyboard: rootKeyboard, dragSensitivity, selection, editor } = usePointsEditorContext();
|
|
1379
1513
|
const generatedId = (0, react.useId)();
|
|
1380
1514
|
const id = idProp ?? generatedId;
|
|
1381
1515
|
const selected = selection.includes(id);
|
|
1382
1516
|
const disabled = _disabled ?? rootDisabled;
|
|
1383
|
-
const
|
|
1384
|
-
const inactive = disabled ||
|
|
1517
|
+
const readOnly = _readOnly ?? rootReadOnly;
|
|
1518
|
+
const inactive = disabled || readOnly;
|
|
1385
1519
|
const wheel = _wheel === void 0 ? rootWheel : _wheel;
|
|
1386
1520
|
const keyboard = _keyboard === void 0 ? rootKeyboard : _keyboard;
|
|
1387
1521
|
useCheckPlacement("PointsEditor.Point", "PointsEditor.Container");
|
|
1522
|
+
const current = (0, _tremolo_ui_dom_internal.clampPoint)(value, min, max);
|
|
1523
|
+
const gesture = useChangeGesture(current, {
|
|
1524
|
+
onChangeStart,
|
|
1525
|
+
onChangeEnd,
|
|
1526
|
+
changeEndDelay
|
|
1527
|
+
}, inactive);
|
|
1528
|
+
const handleChange = (next) => {
|
|
1529
|
+
gesture.changed(next);
|
|
1530
|
+
onChange?.(next);
|
|
1531
|
+
};
|
|
1388
1532
|
const [element, setElement] = (0, react.useState)(null);
|
|
1389
1533
|
const xInputRef = (0, react.useRef)(null);
|
|
1390
1534
|
const yInputRef = (0, react.useRef)(null);
|
|
@@ -1393,9 +1537,10 @@ function Point({ value, children, id: idProp, min, max, color, disabled: _disabl
|
|
|
1393
1537
|
min,
|
|
1394
1538
|
max,
|
|
1395
1539
|
readonly: inactive,
|
|
1396
|
-
onChange,
|
|
1540
|
+
onChange: onChange ? handleChange : void 0,
|
|
1397
1541
|
element,
|
|
1398
|
-
wheel
|
|
1542
|
+
wheel,
|
|
1543
|
+
beforeWheel: () => gesture.pulse("wheel")
|
|
1399
1544
|
});
|
|
1400
1545
|
(0, react.useEffect)(() => {
|
|
1401
1546
|
registration.current = {
|
|
@@ -1403,19 +1548,20 @@ function Point({ value, children, id: idProp, min, max, color, disabled: _disabl
|
|
|
1403
1548
|
min,
|
|
1404
1549
|
max,
|
|
1405
1550
|
readonly: inactive,
|
|
1406
|
-
onChange,
|
|
1551
|
+
onChange: onChange ? handleChange : void 0,
|
|
1407
1552
|
element,
|
|
1408
|
-
wheel
|
|
1553
|
+
wheel,
|
|
1554
|
+
beforeWheel: () => gesture.pulse("wheel")
|
|
1409
1555
|
};
|
|
1410
1556
|
});
|
|
1411
1557
|
(0, react.useEffect)(() => editor.registerPoint(id, () => registration.current), [id, editor]);
|
|
1412
1558
|
/** Where the pointer was when the drag started, to measure the move from. */
|
|
1413
1559
|
const pointerOrigin = (0, react.useRef)(null);
|
|
1414
1560
|
const { refCallback: dragRefCallback, dragging } = useDragValue({
|
|
1415
|
-
axis:
|
|
1561
|
+
axis: _tremolo_ui_dom_internal.POINT_AXIS,
|
|
1416
1562
|
baseElementRef: containerRef,
|
|
1417
|
-
sensitivity: (state) => (0,
|
|
1418
|
-
cursor: inactive ? void 0 :
|
|
1563
|
+
sensitivity: (state) => (0, _tremolo_ui_dom_internal.selectModifier)(dragSensitivity, state.event).value,
|
|
1564
|
+
cursor: inactive ? void 0 : dragCursor,
|
|
1419
1565
|
shouldStart: () => !disabled,
|
|
1420
1566
|
onChange: ([x, y]) => {
|
|
1421
1567
|
const origin = pointerOrigin.current;
|
|
@@ -1432,29 +1578,27 @@ function Point({ value, children, id: idProp, min, max, color, disabled: _disabl
|
|
|
1432
1578
|
y
|
|
1433
1579
|
};
|
|
1434
1580
|
xInputRef.current?.focus();
|
|
1435
|
-
if (inactive)
|
|
1436
|
-
onDragStart?.((0, _tremolo_ui_dom.clampPoint)(value, min, max));
|
|
1581
|
+
if (!inactive) gesture.hold("pointer");
|
|
1437
1582
|
},
|
|
1438
1583
|
onDragEnd: () => {
|
|
1439
1584
|
pointerOrigin.current = null;
|
|
1440
|
-
|
|
1441
|
-
onDragEnd?.((0, _tremolo_ui_dom.clampPoint)(value, min, max));
|
|
1585
|
+
gesture.end();
|
|
1442
1586
|
}
|
|
1443
1587
|
});
|
|
1444
1588
|
const refCallback = require_compose_refs.useComposedRefs(dragRefCallback, setElement);
|
|
1445
1589
|
const handleKeyDown = (event) => {
|
|
1446
|
-
const move = (0,
|
|
1590
|
+
const move = (0, _tremolo_ui_dom_internal.arrowKeyMove)(event.key);
|
|
1447
1591
|
if (!move) return;
|
|
1448
1592
|
event.preventDefault();
|
|
1449
1593
|
if (!onChange || inactive || !keyboard) return;
|
|
1594
|
+
gesture.pulse("keyboard");
|
|
1450
1595
|
editor.nudgePoint(id, move.axis === 0 ? "x" : "y", move.direction, keyboard, event);
|
|
1451
1596
|
};
|
|
1452
|
-
const current = (0, _tremolo_ui_dom.clampPoint)(value, min, max);
|
|
1453
1597
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1454
1598
|
ref: refCallback,
|
|
1455
1599
|
className,
|
|
1456
1600
|
"data-disabled": disabled ? "" : void 0,
|
|
1457
|
-
"data-readonly":
|
|
1601
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1458
1602
|
tabIndex: -1,
|
|
1459
1603
|
"data-dragging": dragging ? "" : void 0,
|
|
1460
1604
|
"data-selected": selected ? "" : void 0,
|
|
@@ -1484,12 +1628,12 @@ function Point({ value, children, id: idProp, min, max, color, disabled: _disabl
|
|
|
1484
1628
|
max: max?.[axis] ?? 1,
|
|
1485
1629
|
step: "any",
|
|
1486
1630
|
disabled,
|
|
1487
|
-
"aria-readonly":
|
|
1631
|
+
"aria-readonly": readOnly,
|
|
1488
1632
|
"aria-orientation": axis === "x" ? "horizontal" : "vertical",
|
|
1489
1633
|
"aria-label": perAxis(ariaLabel, axis) ?? axis,
|
|
1490
1634
|
"aria-valuetext": perAxis(ariaValuetext, axis),
|
|
1491
1635
|
onChange: (event) => {
|
|
1492
|
-
if (
|
|
1636
|
+
if (readOnly) {
|
|
1493
1637
|
event.currentTarget.value = String(current[axis]);
|
|
1494
1638
|
return;
|
|
1495
1639
|
}
|
|
@@ -1538,9 +1682,8 @@ const EMPTY = [];
|
|
|
1538
1682
|
* Multiple Point Controller
|
|
1539
1683
|
*/
|
|
1540
1684
|
const PointsEditor = {
|
|
1541
|
-
Root: /* @__PURE__ */ (0, react.forwardRef)(({ disabled = false,
|
|
1685
|
+
Root: /* @__PURE__ */ (0, react.forwardRef)(({ disabled = false, readOnly = false, wheel = _tremolo_ui_dom_internal.POINTS_EDITOR_DEFAULT_WHEEL, keyboard = _tremolo_ui_dom_internal.POINTS_EDITOR_DEFAULT_KEYBOARD, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, selectable = false, selection: selectionProp, defaultSelection, onSelectionChange, dragCursor = "grabbing", style, className, children, ...props }, forwardedRef) => {
|
|
1542
1686
|
const containerRef = (0, react.useRef)(null);
|
|
1543
|
-
const { cursor = "grabbing" } = externalStyles ?? {};
|
|
1544
1687
|
const controlled = selectionProp !== void 0;
|
|
1545
1688
|
const [ownSelection, setOwnSelection] = (0, react.useState)(defaultSelection ?? []);
|
|
1546
1689
|
const selection = selectable ? selectionProp ?? ownSelection : EMPTY;
|
|
@@ -1559,11 +1702,11 @@ const PointsEditor = {
|
|
|
1559
1702
|
(0, react.useEffect)(() => () => editor.destroy(), [editor]);
|
|
1560
1703
|
const context = (0, react.useMemo)(() => ({
|
|
1561
1704
|
disabled,
|
|
1562
|
-
|
|
1705
|
+
readOnly,
|
|
1563
1706
|
wheel,
|
|
1564
1707
|
keyboard,
|
|
1565
1708
|
dragSensitivity,
|
|
1566
|
-
|
|
1709
|
+
dragCursor,
|
|
1567
1710
|
containerRef,
|
|
1568
1711
|
selectable,
|
|
1569
1712
|
selection,
|
|
@@ -1571,11 +1714,11 @@ const PointsEditor = {
|
|
|
1571
1714
|
selectionBox
|
|
1572
1715
|
}), [
|
|
1573
1716
|
disabled,
|
|
1574
|
-
|
|
1717
|
+
readOnly,
|
|
1575
1718
|
wheel,
|
|
1576
1719
|
keyboard,
|
|
1577
1720
|
dragSensitivity,
|
|
1578
|
-
|
|
1721
|
+
dragCursor,
|
|
1579
1722
|
selectable,
|
|
1580
1723
|
selection,
|
|
1581
1724
|
editor,
|
|
@@ -1587,7 +1730,7 @@ const PointsEditor = {
|
|
|
1587
1730
|
ref: forwardedRef,
|
|
1588
1731
|
className,
|
|
1589
1732
|
"data-disabled": disabled ? "" : void 0,
|
|
1590
|
-
"data-readonly":
|
|
1733
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1591
1734
|
style: {
|
|
1592
1735
|
position: "relative",
|
|
1593
1736
|
...style
|
|
@@ -1618,7 +1761,7 @@ function MarksOption({ value, mark = true, label, thickness, length, gap, classe
|
|
|
1618
1761
|
const min = useSliderContext((s) => s.min);
|
|
1619
1762
|
const max = useSliderContext((s) => s.max);
|
|
1620
1763
|
const scale = useSliderContext((s) => s.scale);
|
|
1621
|
-
const vertical = useSliderContext((s) => s.vertical);
|
|
1764
|
+
const vertical = useSliderContext((s) => s.orientation === "vertical");
|
|
1622
1765
|
const reverse = useSliderContext((s) => s.reverse);
|
|
1623
1766
|
const percent = (0, _tremolo_ui_dom.valuePercent)(value, {
|
|
1624
1767
|
min,
|
|
@@ -1628,9 +1771,9 @@ function MarksOption({ value, mark = true, label, thickness, length, gap, classe
|
|
|
1628
1771
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1629
1772
|
className,
|
|
1630
1773
|
style: {
|
|
1631
|
-
"--thickness": (0,
|
|
1632
|
-
"--length": (0,
|
|
1633
|
-
"--gap": (0,
|
|
1774
|
+
"--thickness": (0, _tremolo_ui_dom_internal.cssLength)(thickness),
|
|
1775
|
+
"--length": (0, _tremolo_ui_dom_internal.cssLength)(length),
|
|
1776
|
+
"--gap": (0, _tremolo_ui_dom_internal.cssLength)(gap),
|
|
1634
1777
|
position: "absolute",
|
|
1635
1778
|
translate: vertical ? "var(--translate, 0 -50%)" : "var(--translate, -50% 0)",
|
|
1636
1779
|
zIndex: 10,
|
|
@@ -1657,15 +1800,15 @@ function Marks({ gap, options, children, className, style, ...props }) {
|
|
|
1657
1800
|
const min = useSliderContext((s) => s.min);
|
|
1658
1801
|
const max = useSliderContext((s) => s.max);
|
|
1659
1802
|
const step = useSliderContext((s) => s.step);
|
|
1660
|
-
const vertical = useSliderContext((s) => s.vertical);
|
|
1803
|
+
const vertical = useSliderContext((s) => s.orientation === "vertical");
|
|
1661
1804
|
const reverse = useSliderContext((s) => s.reverse);
|
|
1662
|
-
const optionsList = options ? (0,
|
|
1805
|
+
const optionsList = options ? (0, _tremolo_ui_dom_internal.sliderMarks)(options, min, max, step) : [];
|
|
1663
1806
|
if (vertical !== reverse) optionsList.reverse();
|
|
1664
1807
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1665
1808
|
className,
|
|
1666
1809
|
"data-orientation": vertical ? "vertical" : "horizontal",
|
|
1667
1810
|
style: {
|
|
1668
|
-
"--gap": (0,
|
|
1811
|
+
"--gap": (0, _tremolo_ui_dom_internal.cssLength)(gap),
|
|
1669
1812
|
position: "relative",
|
|
1670
1813
|
...style
|
|
1671
1814
|
},
|
|
@@ -1684,9 +1827,9 @@ function Marks({ gap, options, children, className, style, ...props }) {
|
|
|
1684
1827
|
}
|
|
1685
1828
|
//#endregion
|
|
1686
1829
|
//#region src/components/Slider/Thumb.tsx
|
|
1687
|
-
const Thumb$1 = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, children, className, style, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-valuetext": ariaValuetext, ...props }, forwardedRef) {
|
|
1830
|
+
const Thumb$1 = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, children, className, style, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-valuetext": ariaValuetext, actionsRef, ...props }, forwardedRef) {
|
|
1688
1831
|
const inputRef = (0, react.useRef)(null);
|
|
1689
|
-
const { value, min, max, step,
|
|
1832
|
+
const { value, min, max, step, orientation, disabled, readOnly, onChange, percent, thumbRef } = useSliderContext();
|
|
1690
1833
|
useCheckPlacement("Slider.Thumb", "Slider.Track");
|
|
1691
1834
|
const methods = () => ({
|
|
1692
1835
|
focus() {
|
|
@@ -1696,12 +1839,13 @@ const Thumb$1 = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, ch
|
|
|
1696
1839
|
inputRef.current?.blur();
|
|
1697
1840
|
}
|
|
1698
1841
|
});
|
|
1699
|
-
(0, react.useImperativeHandle)(
|
|
1842
|
+
(0, react.useImperativeHandle)(actionsRef, methods, [disabled]);
|
|
1700
1843
|
(0, react.useImperativeHandle)(thumbRef, methods, [disabled]);
|
|
1701
1844
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1845
|
+
ref: forwardedRef,
|
|
1702
1846
|
className,
|
|
1703
1847
|
"data-disabled": disabled ? "" : void 0,
|
|
1704
|
-
"data-readonly":
|
|
1848
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1705
1849
|
...props,
|
|
1706
1850
|
style: {
|
|
1707
1851
|
"--color": color,
|
|
@@ -1709,8 +1853,8 @@ const Thumb$1 = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, ch
|
|
|
1709
1853
|
translate: "var(--translate, -50% -50%)",
|
|
1710
1854
|
zIndex: 100,
|
|
1711
1855
|
...style,
|
|
1712
|
-
top: vertical ? `${percent}%` : "50%",
|
|
1713
|
-
left:
|
|
1856
|
+
top: orientation === "vertical" ? `${percent}%` : "50%",
|
|
1857
|
+
left: orientation === "vertical" ? "50%" : `${percent}%`
|
|
1714
1858
|
},
|
|
1715
1859
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(VisuallyHiddenRangeInput, {
|
|
1716
1860
|
ref: inputRef,
|
|
@@ -1719,14 +1863,14 @@ const Thumb$1 = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, ch
|
|
|
1719
1863
|
max,
|
|
1720
1864
|
step,
|
|
1721
1865
|
disabled,
|
|
1722
|
-
"aria-readonly":
|
|
1723
|
-
"aria-orientation":
|
|
1866
|
+
"aria-readonly": readOnly,
|
|
1867
|
+
"aria-orientation": orientation,
|
|
1724
1868
|
"aria-label": ariaLabel,
|
|
1725
1869
|
"aria-labelledby": ariaLabelledby,
|
|
1726
1870
|
"aria-describedby": ariaDescribedby,
|
|
1727
1871
|
"aria-valuetext": ariaValuetext,
|
|
1728
1872
|
onChange: (event) => {
|
|
1729
|
-
if (
|
|
1873
|
+
if (readOnly) {
|
|
1730
1874
|
event.currentTarget.value = String(value);
|
|
1731
1875
|
return;
|
|
1732
1876
|
}
|
|
@@ -1737,20 +1881,20 @@ const Thumb$1 = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, ch
|
|
|
1737
1881
|
});
|
|
1738
1882
|
//#endregion
|
|
1739
1883
|
//#region src/components/Slider/Track.tsx
|
|
1740
|
-
const Track = /* @__PURE__ */ (0, react.forwardRef)(function Track({ length, thickness,
|
|
1741
|
-
const {
|
|
1884
|
+
const Track = /* @__PURE__ */ (0, react.forwardRef)(function Track({ length, thickness, activeColor, inactiveColor, children, className, style, ...props }, forwardedRef) {
|
|
1885
|
+
const { orientation, reverse, disabled, percent, trackRef } = useSliderContext();
|
|
1742
1886
|
const composedRef = require_compose_refs.useComposedRefs(forwardedRef, trackRef);
|
|
1743
1887
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1744
1888
|
ref: composedRef,
|
|
1745
1889
|
className,
|
|
1746
1890
|
"data-disabled": disabled ? "" : void 0,
|
|
1747
|
-
"data-orientation":
|
|
1748
|
-
"data-flipped": vertical !== reverse ? "" : void 0,
|
|
1891
|
+
"data-orientation": orientation,
|
|
1892
|
+
"data-flipped": orientation === "vertical" !== reverse ? "" : void 0,
|
|
1749
1893
|
style: {
|
|
1750
|
-
"--active":
|
|
1751
|
-
"--inactive":
|
|
1752
|
-
"--length": (0,
|
|
1753
|
-
"--thickness": (0,
|
|
1894
|
+
"--active-color": activeColor,
|
|
1895
|
+
"--inactive-color": inactiveColor,
|
|
1896
|
+
"--length": (0, _tremolo_ui_dom_internal.cssLength)(length),
|
|
1897
|
+
"--thickness": (0, _tremolo_ui_dom_internal.cssLength)(thickness),
|
|
1754
1898
|
"--percent": `${percent}%`,
|
|
1755
1899
|
position: "relative",
|
|
1756
1900
|
...style
|
|
@@ -1764,7 +1908,6 @@ const Track = /* @__PURE__ */ (0, react.forwardRef)(function Track({ length, thi
|
|
|
1764
1908
|
});
|
|
1765
1909
|
//#endregion
|
|
1766
1910
|
//#region src/components/Slider/index.tsx
|
|
1767
|
-
const defaultExternalStyles$1 = { cursor: "pointer" };
|
|
1768
1911
|
/**
|
|
1769
1912
|
* The wheel only acts while the focus is inside, so that scrolling a page past
|
|
1770
1913
|
* the control does not change its value.
|
|
@@ -1774,14 +1917,11 @@ const WHEEL_OPTIONS$1 = { requireFocus: true };
|
|
|
1774
1917
|
* Customizable slider
|
|
1775
1918
|
*/
|
|
1776
1919
|
const Slider = {
|
|
1777
|
-
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min, max, step = 1, scale = _tremolo_ui_functions.linearScale,
|
|
1920
|
+
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min, max, step = 1, scale = _tremolo_ui_functions.linearScale, orientation = "horizontal", reverse = false, dragCursor = "pointer", wheel = _tremolo_ui_dom.DEFAULT_WHEEL_OPTIONS, keyboard = _tremolo_ui_dom.DEFAULT_KEYBOARD_OPTIONS, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, disabled = false, readOnly = false, onChange, onChangeStart, onChangeEnd, changeEndDelay, className, style, children, onFocus, onBlur, onPointerDown, onKeyDown, actionsRef, ...props }, forwardedRef) => {
|
|
1778
1921
|
const trackRef = (0, react.useRef)(null);
|
|
1779
1922
|
const thumbRef = (0, react.useRef)(null);
|
|
1780
|
-
const
|
|
1781
|
-
|
|
1782
|
-
..._externalStyles
|
|
1783
|
-
};
|
|
1784
|
-
const inactive = disabled || readonly;
|
|
1923
|
+
const inactive = disabled || readOnly;
|
|
1924
|
+
const vertical = orientation === "vertical";
|
|
1785
1925
|
const displayReversed = vertical !== reverse;
|
|
1786
1926
|
const percent = (0, _tremolo_ui_dom.valuePercent)(value, {
|
|
1787
1927
|
min,
|
|
@@ -1807,60 +1947,70 @@ const Slider = {
|
|
|
1807
1947
|
keyboard,
|
|
1808
1948
|
wheel
|
|
1809
1949
|
});
|
|
1950
|
+
const gesture = useChangeGesture(value, {
|
|
1951
|
+
onChangeStart,
|
|
1952
|
+
onChangeEnd,
|
|
1953
|
+
changeEndDelay
|
|
1954
|
+
}, inactive);
|
|
1955
|
+
const change = (0, react.useCallback)((next) => {
|
|
1956
|
+
gesture.changed(next);
|
|
1957
|
+
onChange?.(next);
|
|
1958
|
+
}, [gesture, onChange]);
|
|
1810
1959
|
const handleKeyDown = (0, react.useCallback)((event) => {
|
|
1811
|
-
const direction = (0,
|
|
1960
|
+
const direction = (0, _tremolo_ui_dom_internal.arrowKeyDirection)(event.key);
|
|
1812
1961
|
if (direction === null) return;
|
|
1813
1962
|
event.preventDefault();
|
|
1814
1963
|
if (!keyboard || !onChange || inactive) return;
|
|
1815
|
-
|
|
1964
|
+
gesture.pulse("keyboard");
|
|
1965
|
+
change((0, _tremolo_ui_dom_internal.applyDelta)(value, reverse ? -direction : direction, keyboard, axis, event));
|
|
1816
1966
|
}, [
|
|
1817
1967
|
keyboard,
|
|
1818
1968
|
onChange,
|
|
1819
1969
|
inactive,
|
|
1820
1970
|
reverse,
|
|
1821
1971
|
value,
|
|
1822
|
-
axis
|
|
1972
|
+
axis,
|
|
1973
|
+
gesture,
|
|
1974
|
+
change
|
|
1823
1975
|
]);
|
|
1824
1976
|
const valueOf = (v) => v[vertical ? 1 : 0];
|
|
1825
1977
|
const { refCallback: dragRefCallback } = useDragValue({
|
|
1826
1978
|
axis,
|
|
1827
1979
|
baseElementRef: trackRef,
|
|
1828
|
-
cursor: inactive ? void 0 :
|
|
1980
|
+
cursor: inactive ? void 0 : dragCursor,
|
|
1829
1981
|
shouldStart: () => !inactive,
|
|
1830
|
-
sensitivity: (state) => (0,
|
|
1982
|
+
sensitivity: (state) => (0, _tremolo_ui_dom_internal.selectModifier)(dragSensitivity, state.event).value,
|
|
1831
1983
|
updateOnPointerDown: true,
|
|
1832
1984
|
onChange: (v) => {
|
|
1833
1985
|
if (inactive) return;
|
|
1834
|
-
|
|
1986
|
+
change(valueOf(v));
|
|
1835
1987
|
},
|
|
1836
|
-
onDragStart: (
|
|
1988
|
+
onDragStart: () => {
|
|
1837
1989
|
if (inactive) return;
|
|
1990
|
+
gesture.hold("pointer");
|
|
1838
1991
|
thumbRef.current?.focus();
|
|
1839
|
-
onDragStart?.(valueOf(v));
|
|
1840
1992
|
},
|
|
1841
|
-
onDragEnd: (
|
|
1842
|
-
if (inactive) return;
|
|
1843
|
-
onDragEnd?.(valueOf(v));
|
|
1844
|
-
}
|
|
1993
|
+
onDragEnd: () => gesture.end()
|
|
1845
1994
|
});
|
|
1846
1995
|
const wheelRefCallback = useWheel((event) => {
|
|
1847
1996
|
if (!wheel || !onChange || inactive) return;
|
|
1848
|
-
const direction = (0,
|
|
1997
|
+
const direction = (0, _tremolo_ui_dom_internal.wheelDirection)(event, { horizontal: !vertical });
|
|
1849
1998
|
if (direction === null) return;
|
|
1850
1999
|
event.preventDefault();
|
|
1851
|
-
|
|
2000
|
+
gesture.pulse("wheel");
|
|
2001
|
+
change((0, _tremolo_ui_dom_internal.applyDelta)(value, reverse ? -direction : direction, wheel, axis, event));
|
|
1852
2002
|
}, WHEEL_OPTIONS$1);
|
|
1853
|
-
const rootRefCallback = require_compose_refs.useComposedRefs(dragRefCallback, wheelRefCallback);
|
|
2003
|
+
const rootRefCallback = require_compose_refs.useComposedRefs(forwardedRef, dragRefCallback, wheelRefCallback);
|
|
1854
2004
|
const context = (0, react.useMemo)(() => ({
|
|
1855
2005
|
value,
|
|
1856
2006
|
min,
|
|
1857
2007
|
max,
|
|
1858
2008
|
step,
|
|
1859
2009
|
scale,
|
|
1860
|
-
|
|
2010
|
+
orientation,
|
|
1861
2011
|
reverse,
|
|
1862
2012
|
disabled,
|
|
1863
|
-
|
|
2013
|
+
readOnly,
|
|
1864
2014
|
onChange,
|
|
1865
2015
|
percent,
|
|
1866
2016
|
trackRef,
|
|
@@ -1871,14 +2021,14 @@ const Slider = {
|
|
|
1871
2021
|
max,
|
|
1872
2022
|
step,
|
|
1873
2023
|
scale,
|
|
1874
|
-
|
|
2024
|
+
orientation,
|
|
1875
2025
|
reverse,
|
|
1876
2026
|
disabled,
|
|
1877
|
-
|
|
2027
|
+
readOnly,
|
|
1878
2028
|
onChange,
|
|
1879
2029
|
percent
|
|
1880
2030
|
]);
|
|
1881
|
-
(0, react.useImperativeHandle)(
|
|
2031
|
+
(0, react.useImperativeHandle)(actionsRef, () => {
|
|
1882
2032
|
return {
|
|
1883
2033
|
focus() {
|
|
1884
2034
|
if (!disabled) thumbRef.current?.focus();
|
|
@@ -1895,9 +2045,9 @@ const Slider = {
|
|
|
1895
2045
|
ref: rootRefCallback,
|
|
1896
2046
|
role: "group",
|
|
1897
2047
|
tabIndex: -1,
|
|
1898
|
-
"data-orientation":
|
|
2048
|
+
"data-orientation": orientation,
|
|
1899
2049
|
"data-disabled": disabled ? "" : void 0,
|
|
1900
|
-
"data-readonly":
|
|
2050
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1901
2051
|
style,
|
|
1902
2052
|
onPointerDown,
|
|
1903
2053
|
onKeyDown: (event) => {
|
|
@@ -1952,15 +2102,15 @@ const Area = /* @__PURE__ */ (0, react.forwardRef)(function Area({ children, cla
|
|
|
1952
2102
|
});
|
|
1953
2103
|
//#endregion
|
|
1954
2104
|
//#region src/components/XYPad/Thumb.tsx
|
|
1955
|
-
const Thumb = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, children, className, style, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-valuetext": ariaValuetext, ...props }, forwardedRef) {
|
|
2105
|
+
const Thumb = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, children, className, style, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-valuetext": ariaValuetext, actionsRef, ...props }, forwardedRef) {
|
|
1956
2106
|
const xInputRef = (0, react.useRef)(null);
|
|
1957
2107
|
const yInputRef = (0, react.useRef)(null);
|
|
1958
|
-
const { value, min, max, step, disabled,
|
|
2108
|
+
const { value, min, max, step, disabled, readOnly, onChange, percent, thumbRef } = useXYPadContext();
|
|
1959
2109
|
useCheckPlacement("XYPad.Thumb", "XYPad.Area");
|
|
1960
|
-
const labels = (0,
|
|
1961
|
-
const labelledby = (0,
|
|
1962
|
-
const describedby = (0,
|
|
1963
|
-
const valueText = (0,
|
|
2110
|
+
const labels = (0, _tremolo_ui_dom_internal.toXY)(ariaLabel);
|
|
2111
|
+
const labelledby = (0, _tremolo_ui_dom_internal.toXY)(ariaLabelledby);
|
|
2112
|
+
const describedby = (0, _tremolo_ui_dom_internal.toXY)(ariaDescribedby);
|
|
2113
|
+
const valueText = (0, _tremolo_ui_dom_internal.toXY)(ariaValuetext);
|
|
1964
2114
|
const methods = () => ({
|
|
1965
2115
|
focus() {
|
|
1966
2116
|
if (!disabled) xInputRef.current?.focus();
|
|
@@ -1970,12 +2120,13 @@ const Thumb = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, chil
|
|
|
1970
2120
|
yInputRef.current?.blur();
|
|
1971
2121
|
}
|
|
1972
2122
|
});
|
|
1973
|
-
(0, react.useImperativeHandle)(
|
|
2123
|
+
(0, react.useImperativeHandle)(actionsRef, methods, [disabled]);
|
|
1974
2124
|
(0, react.useImperativeHandle)(thumbRef, methods, [disabled]);
|
|
1975
2125
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2126
|
+
ref: forwardedRef,
|
|
1976
2127
|
className,
|
|
1977
2128
|
"data-disabled": disabled ? "" : void 0,
|
|
1978
|
-
"data-readonly":
|
|
2129
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1979
2130
|
...props,
|
|
1980
2131
|
style: {
|
|
1981
2132
|
"--color": color,
|
|
@@ -1994,14 +2145,14 @@ const Thumb = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, chil
|
|
|
1994
2145
|
max: max[axis],
|
|
1995
2146
|
step: step[axis],
|
|
1996
2147
|
disabled,
|
|
1997
|
-
"aria-readonly":
|
|
2148
|
+
"aria-readonly": readOnly,
|
|
1998
2149
|
"aria-orientation": axis === 0 ? "horizontal" : "vertical",
|
|
1999
2150
|
"aria-label": labels[axis] ?? (axis === 0 ? "x" : "y"),
|
|
2000
2151
|
"aria-labelledby": labelledby[axis],
|
|
2001
2152
|
"aria-describedby": describedby[axis],
|
|
2002
2153
|
"aria-valuetext": valueText[axis],
|
|
2003
2154
|
onChange: (event) => {
|
|
2004
|
-
if (
|
|
2155
|
+
if (readOnly) {
|
|
2005
2156
|
event.currentTarget.value = String(value[axis]);
|
|
2006
2157
|
return;
|
|
2007
2158
|
}
|
|
@@ -2014,7 +2165,6 @@ const Thumb = /* @__PURE__ */ (0, react.forwardRef)(function Thumb({ color, chil
|
|
|
2014
2165
|
});
|
|
2015
2166
|
//#endregion
|
|
2016
2167
|
//#region src/components/XYPad/index.tsx
|
|
2017
|
-
const defaultExternalStyles = { cursor: "pointer" };
|
|
2018
2168
|
/**
|
|
2019
2169
|
* The wheel only acts while the focus is inside, so that scrolling a page past
|
|
2020
2170
|
* the control does not change its value.
|
|
@@ -2024,20 +2174,25 @@ const WHEEL_OPTIONS = { requireFocus: true };
|
|
|
2024
2174
|
* Simple XYPad
|
|
2025
2175
|
*/
|
|
2026
2176
|
const XYPad = {
|
|
2027
|
-
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min: _min, max: _max, step: _step = 1, scale: _scale = _tremolo_ui_functions.linearScale, reverse: _reverse = false, wheel = _tremolo_ui_dom.DEFAULT_WHEEL_OPTIONS, keyboard = _tremolo_ui_dom.DEFAULT_KEYBOARD_OPTIONS, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, className, style,
|
|
2177
|
+
Root: /* @__PURE__ */ (0, react.forwardRef)(({ value, min: _min, max: _max, step: _step = 1, scale: _scale = _tremolo_ui_functions.linearScale, reverse: _reverse = false, wheel = _tremolo_ui_dom.DEFAULT_WHEEL_OPTIONS, keyboard = _tremolo_ui_dom.DEFAULT_KEYBOARD_OPTIONS, dragSensitivity = _tremolo_ui_dom.DEFAULT_DRAG_SENSITIVITY, className, style, dragCursor = "pointer", disabled = false, readOnly = false, onChange, onChangeStart, onChangeEnd, changeEndDelay, onPointerDown, onKeyDown, onFocus, onBlur, children, actionsRef, ...props }, forwardedRef) => {
|
|
2028
2178
|
const rootRef = (0, react.useRef)(null);
|
|
2029
2179
|
const areaRef = (0, react.useRef)(null);
|
|
2030
2180
|
const thumbRef = (0, react.useRef)(null);
|
|
2031
|
-
const
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
const
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2181
|
+
const inactive = disabled || readOnly;
|
|
2182
|
+
const gesture = useChangeGesture(value, {
|
|
2183
|
+
onChangeStart,
|
|
2184
|
+
onChangeEnd,
|
|
2185
|
+
changeEndDelay
|
|
2186
|
+
}, inactive);
|
|
2187
|
+
const change = (0, react.useCallback)((next) => {
|
|
2188
|
+
gesture.changed(next);
|
|
2189
|
+
onChange?.(next);
|
|
2190
|
+
}, [gesture, onChange]);
|
|
2191
|
+
const min = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.toXY)(_min), [_min]);
|
|
2192
|
+
const max = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.toXY)(_max), [_max]);
|
|
2193
|
+
const step = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.toXY)(_step), [_step]);
|
|
2194
|
+
const scale = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.toXY)(_scale), [_scale]);
|
|
2195
|
+
const reverse = (0, react.useMemo)(() => (0, _tremolo_ui_dom_internal.toXY)(_reverse), [_reverse]);
|
|
2041
2196
|
const percent = (0, react.useMemo)(() => [0, 1].map((i) => (0, _tremolo_ui_dom.valuePercent)(value[i], {
|
|
2042
2197
|
min: min[i],
|
|
2043
2198
|
max: max[i],
|
|
@@ -2078,55 +2233,56 @@ const XYPad = {
|
|
|
2078
2233
|
});
|
|
2079
2234
|
const withAxis = (0, react.useCallback)((axis, next) => axis === 0 ? [next, value[1]] : [value[0], next], [value]);
|
|
2080
2235
|
/** @param i 0 = x, 1 = y */
|
|
2081
|
-
const nudge = (0, react.useCallback)((i, direction, option, modifiers) => withAxis(i, (0,
|
|
2236
|
+
const nudge = (0, react.useCallback)((i, direction, option, modifiers) => withAxis(i, (0, _tremolo_ui_dom_internal.applyDelta)(value[i], direction, option, axis[i], modifiers)), [
|
|
2082
2237
|
value,
|
|
2083
2238
|
axis,
|
|
2084
2239
|
withAxis
|
|
2085
2240
|
]);
|
|
2086
2241
|
const handleKeyDown = (0, react.useCallback)((event) => {
|
|
2087
|
-
const move = (0,
|
|
2242
|
+
const move = (0, _tremolo_ui_dom_internal.arrowKeyMove)(event.key);
|
|
2088
2243
|
if (!move) return;
|
|
2089
2244
|
event.preventDefault();
|
|
2090
2245
|
if (!onChange || inactive || !keyboard) return;
|
|
2091
2246
|
const { axis: i, direction } = move;
|
|
2092
|
-
|
|
2247
|
+
gesture.pulse("keyboard");
|
|
2248
|
+
change(nudge(i, reverse[i] ? -direction : direction, keyboard, event));
|
|
2093
2249
|
}, [
|
|
2094
2250
|
onChange,
|
|
2095
2251
|
inactive,
|
|
2096
2252
|
keyboard,
|
|
2097
2253
|
reverse,
|
|
2098
|
-
nudge
|
|
2254
|
+
nudge,
|
|
2255
|
+
gesture,
|
|
2256
|
+
change
|
|
2099
2257
|
]);
|
|
2100
2258
|
const { refCallback: dragRefCallback } = useDragValue({
|
|
2101
2259
|
axis,
|
|
2102
2260
|
baseElementRef: areaRef,
|
|
2103
|
-
sensitivity: (state) => (0,
|
|
2261
|
+
sensitivity: (state) => (0, _tremolo_ui_dom_internal.selectModifier)(dragSensitivity, state.event).value,
|
|
2104
2262
|
updateOnPointerDown: true,
|
|
2105
|
-
cursor: inactive ? void 0 :
|
|
2263
|
+
cursor: inactive ? void 0 : dragCursor,
|
|
2106
2264
|
shouldStart: () => !inactive,
|
|
2107
2265
|
onChange: (v) => {
|
|
2108
2266
|
if (inactive) return;
|
|
2109
|
-
|
|
2267
|
+
change(v);
|
|
2110
2268
|
},
|
|
2111
|
-
onDragStart: (
|
|
2269
|
+
onDragStart: () => {
|
|
2112
2270
|
if (inactive) return;
|
|
2271
|
+
gesture.hold("pointer");
|
|
2113
2272
|
thumbRef.current?.focus();
|
|
2114
|
-
onDragStart?.(v);
|
|
2115
2273
|
},
|
|
2116
|
-
onDragEnd: (
|
|
2117
|
-
if (inactive) return;
|
|
2118
|
-
onDragEnd?.(v);
|
|
2119
|
-
}
|
|
2274
|
+
onDragEnd: () => gesture.end()
|
|
2120
2275
|
});
|
|
2121
2276
|
const wheelRefCallback = useWheel((event) => {
|
|
2122
2277
|
if (!onChange || inactive || !wheel) return;
|
|
2123
|
-
const move = (0,
|
|
2278
|
+
const move = (0, _tremolo_ui_dom_internal.wheelMove)(event);
|
|
2124
2279
|
if (!move) return;
|
|
2125
2280
|
event.preventDefault();
|
|
2126
2281
|
const { axis: i, direction } = move;
|
|
2127
|
-
|
|
2282
|
+
gesture.pulse("wheel");
|
|
2283
|
+
change(nudge(i, reverse[i] ? -direction : direction, wheel, event));
|
|
2128
2284
|
}, WHEEL_OPTIONS);
|
|
2129
|
-
const rootRefCallback = require_compose_refs.useComposedRefs(rootRef, dragRefCallback, wheelRefCallback);
|
|
2285
|
+
const rootRefCallback = require_compose_refs.useComposedRefs(forwardedRef, rootRef, dragRefCallback, wheelRefCallback);
|
|
2130
2286
|
const context = (0, react.useMemo)(() => ({
|
|
2131
2287
|
value,
|
|
2132
2288
|
min,
|
|
@@ -2135,7 +2291,7 @@ const XYPad = {
|
|
|
2135
2291
|
scale,
|
|
2136
2292
|
reverse,
|
|
2137
2293
|
disabled,
|
|
2138
|
-
|
|
2294
|
+
readOnly,
|
|
2139
2295
|
onChange,
|
|
2140
2296
|
percent,
|
|
2141
2297
|
areaRef,
|
|
@@ -2148,19 +2304,18 @@ const XYPad = {
|
|
|
2148
2304
|
scale,
|
|
2149
2305
|
reverse,
|
|
2150
2306
|
disabled,
|
|
2151
|
-
|
|
2307
|
+
readOnly,
|
|
2152
2308
|
onChange,
|
|
2153
2309
|
percent
|
|
2154
2310
|
]);
|
|
2155
|
-
(0, react.useImperativeHandle)(
|
|
2311
|
+
(0, react.useImperativeHandle)(actionsRef, () => {
|
|
2156
2312
|
return {
|
|
2157
2313
|
focus() {
|
|
2158
2314
|
if (!disabled) thumbRef.current?.focus();
|
|
2159
2315
|
},
|
|
2160
2316
|
blur() {
|
|
2161
2317
|
thumbRef.current?.blur();
|
|
2162
|
-
}
|
|
2163
|
-
original: rootRef
|
|
2318
|
+
}
|
|
2164
2319
|
};
|
|
2165
2320
|
}, [disabled]);
|
|
2166
2321
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(XYPadProvider, {
|
|
@@ -2171,7 +2326,7 @@ const XYPad = {
|
|
|
2171
2326
|
role: "group",
|
|
2172
2327
|
tabIndex: -1,
|
|
2173
2328
|
"data-disabled": disabled ? "" : void 0,
|
|
2174
|
-
"data-readonly":
|
|
2329
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
2175
2330
|
style,
|
|
2176
2331
|
onPointerDown,
|
|
2177
2332
|
onKeyDown: (event) => {
|
|
@@ -2196,17 +2351,30 @@ const XYPad = {
|
|
|
2196
2351
|
};
|
|
2197
2352
|
//#endregion
|
|
2198
2353
|
//#region src/hooks/useAnimationFrame.ts
|
|
2199
|
-
|
|
2200
|
-
|
|
2354
|
+
/**
|
|
2355
|
+
* Call `callback` on every animation frame for as long as the component is
|
|
2356
|
+
* mounted.
|
|
2357
|
+
*
|
|
2358
|
+
* The callback is read on every frame, so it can be written inline and see
|
|
2359
|
+
* the latest render without restarting the loop.
|
|
2360
|
+
*
|
|
2361
|
+
* @param callback receives the frame's timestamp and the milliseconds since
|
|
2362
|
+
* the previous frame, which is `0` on the first one
|
|
2363
|
+
*/
|
|
2364
|
+
function useAnimationFrame(callback, { disabled = false } = {}) {
|
|
2201
2365
|
const runCallback = useCallbackRef(callback);
|
|
2202
2366
|
(0, react.useEffect)(() => {
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2367
|
+
if (disabled) return;
|
|
2368
|
+
let frameId = 0;
|
|
2369
|
+
let previous;
|
|
2370
|
+
const loop = (timestamp) => {
|
|
2371
|
+
frameId = requestAnimationFrame(loop);
|
|
2372
|
+
runCallback(timestamp, previous === void 0 ? 0 : timestamp - previous);
|
|
2373
|
+
previous = timestamp;
|
|
2206
2374
|
};
|
|
2207
|
-
|
|
2208
|
-
return () => cancelAnimationFrame(
|
|
2209
|
-
}, [runCallback,
|
|
2375
|
+
frameId = requestAnimationFrame(loop);
|
|
2376
|
+
return () => cancelAnimationFrame(frameId);
|
|
2377
|
+
}, [runCallback, disabled]);
|
|
2210
2378
|
}
|
|
2211
2379
|
//#endregion
|
|
2212
2380
|
//#region src/hooks/useDrag.ts
|
|
@@ -2246,43 +2414,40 @@ function useDrag({ threshold = 1, cursor, pointerLock, onDrag, onDragStart, onDr
|
|
|
2246
2414
|
//#region src/hooks/useEventListener.ts
|
|
2247
2415
|
function useEventListener(target, event, handler, options) {
|
|
2248
2416
|
const listener = useCallbackRef(handler);
|
|
2249
|
-
const
|
|
2417
|
+
const registrationRef = (0, react.useRef)(null);
|
|
2418
|
+
const { capture = false, once, passive } = typeof options === "boolean" ? { capture: options } : options ?? {};
|
|
2250
2419
|
(0, react.useEffect)(() => {
|
|
2251
|
-
const node = typeof target === "function" ? target() : target
|
|
2420
|
+
const node = typeof target === "function" ? target() : target;
|
|
2421
|
+
const current = registrationRef.current;
|
|
2422
|
+
if (current && current.node === node && current.event === event && current.capture === capture && current.once === once && current.passive === passive) return;
|
|
2423
|
+
current?.remove();
|
|
2424
|
+
registrationRef.current = null;
|
|
2252
2425
|
if (!node) return;
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2426
|
+
const listenerOptions = {
|
|
2427
|
+
capture,
|
|
2428
|
+
once,
|
|
2429
|
+
passive
|
|
2256
2430
|
};
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2431
|
+
node.addEventListener(event, listener, listenerOptions);
|
|
2432
|
+
registrationRef.current = {
|
|
2433
|
+
node,
|
|
2434
|
+
event,
|
|
2435
|
+
capture,
|
|
2436
|
+
once,
|
|
2437
|
+
passive,
|
|
2438
|
+
remove: () => node.removeEventListener(event, listener, listenerOptions)
|
|
2261
2439
|
};
|
|
2262
|
-
}
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
const savedCallback = (0, react.useRef)(callback);
|
|
2274
|
-
(0, react.useEffect)(() => {
|
|
2275
|
-
savedCallback.current = callback;
|
|
2276
|
-
}, [callback]);
|
|
2277
|
-
(0, react.useEffect)(() => {
|
|
2278
|
-
if (delay === null) return;
|
|
2279
|
-
const id = setInterval(() => {
|
|
2280
|
-
savedCallback.current();
|
|
2281
|
-
}, delay);
|
|
2282
|
-
return () => {
|
|
2283
|
-
clearInterval(id);
|
|
2284
|
-
};
|
|
2285
|
-
}, [delay]);
|
|
2440
|
+
});
|
|
2441
|
+
(0, react.useEffect)(() => () => {
|
|
2442
|
+
registrationRef.current?.remove();
|
|
2443
|
+
registrationRef.current = null;
|
|
2444
|
+
}, []);
|
|
2445
|
+
return (0, react.useCallback)(() => {
|
|
2446
|
+
const current = registrationRef.current;
|
|
2447
|
+
if (!current) return;
|
|
2448
|
+
current.remove();
|
|
2449
|
+
current.remove = () => {};
|
|
2450
|
+
}, []);
|
|
2286
2451
|
}
|
|
2287
2452
|
//#endregion
|
|
2288
2453
|
//#region src/hooks/useMIDIAccess.ts
|
|
@@ -2436,7 +2601,6 @@ exports.useDragValue = useDragValue;
|
|
|
2436
2601
|
exports.useDropZone = useDropZone;
|
|
2437
2602
|
exports.useEventListener = useEventListener;
|
|
2438
2603
|
exports.useFileInputContext = useFileInputContext;
|
|
2439
|
-
exports.useInterval = useInterval;
|
|
2440
2604
|
exports.useKnobContext = useKnobContext;
|
|
2441
2605
|
exports.useLongPress = useLongPress;
|
|
2442
2606
|
exports.useMIDIAccess = useMIDIAccess;
|