@tremolo-ui/react 0.3.0 → 0.4.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 CHANGED
@@ -27,8 +27,8 @@ let react = require("react");
27
27
  react = __toESM(react);
28
28
  let react_jsx_runtime = require("react/jsx-runtime");
29
29
  let _tremolo_ui_functions = require("@tremolo-ui/functions");
30
- let zustand = require("zustand");
31
30
  let _tremolo_ui_dom = require("@tremolo-ui/dom");
31
+ let zustand = require("zustand");
32
32
  //#region src/components/AnimationCanvas/canvas.ts
33
33
  const drawingState = [
34
34
  "strokeStyle",
@@ -180,110 +180,55 @@ function useCallbackRef(callback, deps = []) {
180
180
  return (0, react.useCallback)((...args) => callbackRef.current?.(...args), deps);
181
181
  }
182
182
  //#endregion
183
- //#region src/hooks/useEventListener.ts
184
- function useEventListener(target, event, handler, options) {
185
- const listener = useCallbackRef(handler);
183
+ //#region src/hooks/useDrag.ts
184
+ /**
185
+ * Track a pointer drag on an element.
186
+ *
187
+ * @returns a ref callback to attach to the element being dragged
188
+ */
189
+ function useDrag({ threshold = 1, cursor, onDrag, onDragStart, onDragEnd }) {
190
+ const dragHandler = useCallbackRef(onDrag);
191
+ const dragStartHandler = useCallbackRef(onDragStart);
192
+ const dragEndHandler = useCallbackRef(onDragEnd);
193
+ const [node, setNode] = (0, react.useState)(null);
186
194
  (0, react.useEffect)(() => {
187
- const node = typeof target === "function" ? target() : target ?? document;
188
195
  if (!node) return;
189
- node.addEventListener(event, listener, options);
190
- return () => {
191
- node.removeEventListener(event, listener, options);
192
- };
196
+ const instance = (0, _tremolo_ui_dom.createDrag)(node, {
197
+ threshold,
198
+ cursor,
199
+ onDragStart: () => dragStartHandler(),
200
+ onDrag: ({ x, y, deltaX, deltaY }) => dragHandler(x, y, deltaX, deltaY),
201
+ onDragEnd: () => dragEndHandler()
202
+ });
203
+ return () => instance.destroy();
193
204
  }, [
194
- event,
195
- target,
196
- options,
197
- listener
205
+ node,
206
+ threshold,
207
+ cursor,
208
+ dragHandler,
209
+ dragStartHandler,
210
+ dragEndHandler
198
211
  ]);
199
- return () => {
200
- (typeof target === "function" ? target() : target ?? document)?.removeEventListener(event, listener, options);
201
- };
212
+ return setNode;
202
213
  }
203
214
  //#endregion
204
- //#region src/hooks/useRefCallbackEvent.ts
205
- function useRefCallbackEvent(event, handler, options, deps = []) {
206
- return (0, react.useMemo)(() => {
207
- let cleanup;
208
- return (node) => {
209
- if (!node) {
210
- cleanup?.();
211
- return;
212
- }
213
- node.addEventListener(event, handler, options);
214
- cleanup = () => {
215
- node.removeEventListener(event, handler, options);
216
- };
217
- };
218
- }, deps);
219
- }
220
- //#endregion
221
- //#region src/hooks/useDrag.ts
215
+ //#region src/hooks/useWheel.ts
222
216
  /**
223
- * @returns [refCallback, pointerDownHandler]
217
+ * Listen to wheel events on an element.
218
+ *
219
+ * The listener is not passive, so the handler may call `preventDefault()`.
220
+ *
221
+ * @returns a ref callback to attach to the element
224
222
  */
225
- function useDrag({ threshold: _threshold = 1, onDrag, onDragStart, onDragEnd }) {
226
- const dragOffsetX = (0, react.useRef)(void 0);
227
- const dragOffsetY = (0, react.useRef)(void 0);
228
- const dragStartX = (0, react.useRef)(0);
229
- const dragStartY = (0, react.useRef)(0);
230
- const threshold = Math.max(_threshold, 1);
231
- const handleDrag = (0, react.useCallback)((event, first = false) => {
232
- const isTouch = event instanceof TouchEvent;
233
- if (isTouch && event.cancelable) event.preventDefault();
234
- const screenX = isTouch ? event.touches[0].screenX : event.screenX;
235
- const screenY = isTouch ? event.touches[0].screenY : event.screenY;
236
- let deltaX = 0;
237
- let deltaY = 0;
238
- if (first) {
239
- dragStartX.current = screenX;
240
- dragStartY.current = screenY;
241
- }
242
- if (dragOffsetX.current) {
243
- deltaX = screenX - dragOffsetX.current;
244
- dragOffsetX.current = screenX;
245
- }
246
- if (dragOffsetY.current) {
247
- deltaY = screenY - dragOffsetY.current;
248
- dragOffsetY.current = screenY;
249
- }
250
- if (Math.abs(deltaX) < threshold && Math.abs(deltaY) < threshold) return;
251
- onDrag?.(screenX - dragStartX.current, screenY - dragStartY.current, deltaX, deltaY);
252
- }, [threshold, onDrag]);
253
- const pointerDownHandler = (0, react.useCallback)((event) => {
254
- dragOffsetX.current = event.screenX;
255
- dragOffsetY.current = event.screenY;
256
- handleDrag(event, true);
257
- onDragStart?.();
258
- }, [handleDrag, onDragStart]);
259
- const refHandler = useRefCallbackEvent("touchmove", handleDrag, { passive: false }, [onDrag]);
260
- useEventListener(globalThis.window, "mousemove", handleDrag);
261
- useEventListener(globalThis.window, "pointerup", () => {
262
- dragOffsetX.current = void 0;
263
- dragOffsetY.current = void 0;
264
- onDragEnd?.();
265
- });
266
- return [refHandler, pointerDownHandler];
267
- }
268
- //#endregion
269
- //#region src/components/DragObserver/index.tsx
270
- function DragObserver(props) {
271
- const { as: Component = "div", threshold = 1, onDrag, onDragStart, onDragEnd, children, onPointerDown, ...attributes } = props;
272
- const [refCallback, pointerDownHandler] = useDrag({
273
- threshold,
274
- onDrag,
275
- onDragStart,
276
- onDragEnd
277
- });
278
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
279
- ref: refCallback,
280
- onPointerDown: (e) => {
281
- pointerDownHandler(e);
282
- onPointerDown?.(e);
283
- },
284
- ...attributes,
285
- children
286
- });
223
+ function useWheel(onWheel) {
224
+ const wheelHandler = useCallbackRef(onWheel);
225
+ const [node, setNode] = (0, react.useState)(null);
226
+ (0, react.useEffect)(() => {
227
+ if (!node) return;
228
+ const instance = (0, _tremolo_ui_dom.createWheel)(node, (event) => wheelHandler(event));
229
+ return () => instance.destroy();
230
+ }, [node, wheelHandler]);
231
+ return setNode;
287
232
  }
288
233
  //#endregion
289
234
  //#region src/components/_util/index.ts
@@ -293,22 +238,6 @@ function addUserSelectNone() {
293
238
  function removeUserSelectNone() {
294
239
  window.document.body.classList.remove("tremolo-user-select-none");
295
240
  }
296
- const cursorStyles = {
297
- grabbing: "tremolo-cursor-grabbing",
298
- grab: "tremolo-cursor-grab",
299
- pointer: "tremolo-cursor-pointer",
300
- move: "tremolo-cursor-move",
301
- none: "tremolo-cursor-none"
302
- };
303
- function setCursorStyle(type) {
304
- resetCursorStyle();
305
- window.document.body.classList.add(cursorStyles[type]);
306
- }
307
- function resetCursorStyle() {
308
- Object.values(cursorStyles).forEach((s) => {
309
- window.document.body.classList.remove(s);
310
- });
311
- }
312
241
  function calcDrawingState({ value, min, max, skew, startValue, angleRange }) {
313
242
  const p = (0, _tremolo_ui_functions.normalizeValue)(value, min, max, skew);
314
243
  const s = (0, _tremolo_ui_functions.normalizeValue)(startValue, min, max, skew);
@@ -518,32 +447,26 @@ const Knob = {
518
447
  readonly,
519
448
  updateValueByEvent
520
449
  ]);
521
- const [touchMoveRefCallback, pointerDownHandler] = useDrag({
450
+ const dragRefCallback = useDrag({
451
+ cursor: readonly ? void 0 : externalStyles.cursor,
522
452
  onDrag,
523
453
  onDragStart: () => {
524
454
  setDragging(true);
525
455
  valueRef.current = (0, _tremolo_ui_functions.normalizeValue)(value, min, max, skew);
526
456
  if (externalStyles.userSelectNone) addUserSelectNone();
527
- if (externalStyles.cursor) setCursorStyle(externalStyles.cursor);
528
457
  },
529
458
  onDragEnd: () => {
530
459
  setDragging(false);
531
460
  if (externalStyles.userSelectNone) removeUserSelectNone();
532
- if (externalStyles.cursor) resetCursorStyle();
533
461
  }
534
462
  });
535
- const wheelRefCallback = useRefCallbackEvent("wheel", (event) => {
463
+ const wheelRefCallback = useWheel((event) => {
536
464
  if (!wheel || readonly) return;
537
465
  event.preventDefault();
538
466
  if (!onChange || event.deltaY == 0) return;
539
467
  const x = Math.sign(event.deltaY) * -wheel[1];
540
468
  onChange(updateValueByEvent(wheel[0], x));
541
- }, { passive: false }, [
542
- wheel,
543
- onChange,
544
- readonly,
545
- updateValueByEvent
546
- ]);
469
+ });
547
470
  (0, react.useImperativeHandle)(forwardedRef, () => {
548
471
  return {
549
472
  focus() {
@@ -566,7 +489,7 @@ const Knob = {
566
489
  ref: (elm) => {
567
490
  elmRef.current = elm;
568
491
  wheelRefCallback(elm);
569
- touchMoveRefCallback(elm);
492
+ dragRefCallback(elm);
570
493
  },
571
494
  className: (0, clsx.default)("tremolo-knob", className),
572
495
  tabIndex: 0,
@@ -582,10 +505,7 @@ const Knob = {
582
505
  height: size,
583
506
  ...style
584
507
  },
585
- onPointerDown: (event) => {
586
- pointerDownHandler(event);
587
- onPointerDown?.(event);
588
- },
508
+ onPointerDown,
589
509
  onDoubleClick: (event) => {
590
510
  if (enableDoubleClickDefault && onChange) onChange(defaultValue);
591
511
  onDoubleClick?.(event);
@@ -722,6 +642,27 @@ function useNumberInputContext(selector) {
722
642
  return (0, zustand.useStore)(store, selector);
723
643
  }
724
644
  //#endregion
645
+ //#region src/hooks/useEventListener.ts
646
+ function useEventListener(target, event, handler, options) {
647
+ const listener = useCallbackRef(handler);
648
+ (0, react.useEffect)(() => {
649
+ const node = typeof target === "function" ? target() : target ?? document;
650
+ if (!node) return;
651
+ node.addEventListener(event, listener, options);
652
+ return () => {
653
+ node.removeEventListener(event, listener, options);
654
+ };
655
+ }, [
656
+ event,
657
+ target,
658
+ options,
659
+ listener
660
+ ]);
661
+ return () => {
662
+ (typeof target === "function" ? target() : target ?? document)?.removeEventListener(event, listener, options);
663
+ };
664
+ }
665
+ //#endregion
725
666
  //#region src/hooks/useInterval.ts
726
667
  function useInterval(callback, delay) {
727
668
  const savedCallback = (0, react.useRef)(callback);
@@ -867,19 +808,14 @@ const InternalInput = (0, react.forwardRef)(({ disabled, readonly, selectWithFoc
867
808
  onChange,
868
809
  updateValueByEvent
869
810
  ]);
870
- const wheelRefCallback = useRefCallbackEvent("wheel", (event) => {
811
+ const wheelRefCallback = useWheel((event) => {
871
812
  if (!wheel || readonly) return;
872
813
  event.preventDefault();
873
814
  if (!onChange || event.deltaY == 0) return;
874
815
  const x = Math.sign(event.deltaY) * -wheel[1];
875
816
  const parsed = parseValue(String(updateValueByEvent(wheel[0], x)));
876
817
  onChange?.(parsed.rawValue, parsed.formatValue);
877
- }, { passive: false }, [
878
- wheel,
879
- readonly,
880
- onChange,
881
- updateValueByEvent
882
- ]);
818
+ });
883
819
  (0, react.useImperativeHandle)(ref, () => {
884
820
  return {
885
821
  focus() {
@@ -997,6 +933,23 @@ const NumberInput = {
997
933
  DecrementStepper
998
934
  };
999
935
  //#endregion
936
+ //#region src/hooks/useRefCallbackEvent.ts
937
+ function useRefCallbackEvent(event, handler, options, deps = []) {
938
+ return (0, react.useMemo)(() => {
939
+ let cleanup;
940
+ return (node) => {
941
+ if (!node) {
942
+ cleanup?.();
943
+ return;
944
+ }
945
+ node.addEventListener(event, handler, options);
946
+ cleanup = () => {
947
+ node.removeEventListener(event, handler, options);
948
+ };
949
+ };
950
+ }, deps);
951
+ }
952
+ //#endregion
1000
953
  //#region src/hooks/usePianoDrag.ts
1001
954
  /**
1002
955
  * Internal
@@ -1453,42 +1406,57 @@ function Container({ className, children, ...props }) {
1453
1406
  }
1454
1407
  //#endregion
1455
1408
  //#region src/hooks/useDragWithElement.ts
1456
- function useDragWithElement({ baseElementRef, onDrag, onDragStart, onDragEnd }) {
1409
+ /**
1410
+ * Track a pointer drag, reporting the position normalized against
1411
+ * the bounding rect of `baseElementRef`.
1412
+ *
1413
+ * @returns a ref callback for the element that starts the drag, and whether a drag is in progress
1414
+ */
1415
+ function useDragWithElement({ baseElementRef, updateOnPointerDown = false, cursor, onDrag, onDragStart, onDragEnd }) {
1457
1416
  const [dragging, setDragging] = (0, react.useState)(false);
1458
1417
  const normalizedX = (0, react.useRef)(0);
1459
1418
  const normalizedY = (0, react.useRef)(0);
1460
- const handleDrag = (0, react.useCallback)((event) => {
1461
- if (!baseElementRef.current || !dragging) return;
1462
- const isTouch = event instanceof TouchEvent;
1463
- if (isTouch && event.cancelable) event.preventDefault();
1464
- const { left, top, right, bottom } = baseElementRef.current.getBoundingClientRect();
1465
- const mouseX = isTouch ? event.touches[0].clientX : event.clientX;
1466
- const mouseY = isTouch ? event.touches[0].clientY : event.clientY;
1467
- const nx = (0, _tremolo_ui_functions.normalizeValue)(mouseX, left, right);
1468
- const ny = (0, _tremolo_ui_functions.normalizeValue)(mouseY, top, bottom);
1469
- normalizedX.current = nx;
1470
- normalizedY.current = ny;
1471
- onDrag(nx, ny);
1419
+ const dragHandler = useCallbackRef(onDrag);
1420
+ const dragStartHandler = useCallbackRef(onDragStart);
1421
+ const dragEndHandler = useCallbackRef(onDragEnd);
1422
+ const update = (0, react.useCallback)((clientX, clientY) => {
1423
+ const base = baseElementRef.current;
1424
+ if (!base) return false;
1425
+ const { left, top, right, bottom } = base.getBoundingClientRect();
1426
+ normalizedX.current = (0, _tremolo_ui_functions.normalizeValue)(clientX, left, right);
1427
+ normalizedY.current = (0, _tremolo_ui_functions.normalizeValue)(clientY, top, bottom);
1428
+ return true;
1429
+ }, [baseElementRef]);
1430
+ const [node, setNode] = (0, react.useState)(null);
1431
+ (0, react.useEffect)(() => {
1432
+ if (!node) return;
1433
+ const instance = (0, _tremolo_ui_dom.createDrag)(node, {
1434
+ cursor,
1435
+ onDragStart: ({ clientX, clientY }) => {
1436
+ setDragging(true);
1437
+ if (update(clientX, clientY) && updateOnPointerDown) dragHandler(normalizedX.current, normalizedY.current);
1438
+ dragStartHandler(normalizedX.current, normalizedY.current);
1439
+ },
1440
+ onDrag: ({ clientX, clientY }) => {
1441
+ if (update(clientX, clientY)) dragHandler(normalizedX.current, normalizedY.current);
1442
+ },
1443
+ onDragEnd: () => {
1444
+ setDragging(false);
1445
+ dragEndHandler(normalizedX.current, normalizedY.current);
1446
+ }
1447
+ });
1448
+ return () => instance.destroy();
1472
1449
  }, [
1473
- onDrag,
1474
- baseElementRef,
1475
- dragging
1450
+ node,
1451
+ update,
1452
+ updateOnPointerDown,
1453
+ cursor,
1454
+ dragHandler,
1455
+ dragStartHandler,
1456
+ dragEndHandler
1476
1457
  ]);
1477
- const refHandler = useRefCallbackEvent("touchmove", handleDrag, { passive: false }, [onDrag]);
1478
- const pointerDownHandler = (0, react.useCallback)((event) => {
1479
- setDragging(true);
1480
- handleDrag(event);
1481
- onDragStart?.(normalizedX.current, normalizedY.current);
1482
- }, [handleDrag, onDragStart]);
1483
- useEventListener(globalThis.window, "pointermove", handleDrag);
1484
- useEventListener(globalThis.window, "pointerup", () => {
1485
- if (!dragging) return;
1486
- setDragging(false);
1487
- onDragEnd?.(normalizedX.current, normalizedY.current);
1488
- });
1489
1458
  return {
1490
- refHandler,
1491
- pointerDownHandler,
1459
+ refCallback: setNode,
1492
1460
  dragging
1493
1461
  };
1494
1462
  }
@@ -1506,8 +1474,9 @@ function Point({ value, min, max, size, width = 16, height = 16, color, disabled
1506
1474
  const externalStyles = usePointsEditorContext((s) => s.externalStyles);
1507
1475
  const __disabled = usePointsEditorContext((s) => s.disabled);
1508
1476
  const __readonly = usePointsEditorContext((s) => s.readonly);
1509
- const { refHandler: touchMoveRefCallback, pointerDownHandler, dragging } = useDragWithElement({
1477
+ const { refCallback: dragRefCallback, dragging } = useDragWithElement({
1510
1478
  baseElementRef: containerElementRef,
1479
+ cursor: readonly ? void 0 : externalStyles.cursor,
1511
1480
  onDrag: (x, y) => {
1512
1481
  if (readonly) return;
1513
1482
  onChange?.(clampPoint({
@@ -1518,7 +1487,6 @@ function Point({ value, min, max, size, width = 16, height = 16, color, disabled
1518
1487
  onDragStart: (x, y) => {
1519
1488
  if (readonly) return;
1520
1489
  if (externalStyles.userSelectNone) addUserSelectNone();
1521
- if (externalStyles.cursor) setCursorStyle(externalStyles.cursor);
1522
1490
  onDragStart?.(clampPoint({
1523
1491
  x,
1524
1492
  y
@@ -1527,7 +1495,6 @@ function Point({ value, min, max, size, width = 16, height = 16, color, disabled
1527
1495
  onDragEnd: (x, y) => {
1528
1496
  if (readonly) return;
1529
1497
  if (externalStyles.userSelectNone) removeUserSelectNone();
1530
- if (externalStyles.cursor) resetCursorStyle();
1531
1498
  onDragEnd?.(clampPoint({
1532
1499
  x,
1533
1500
  y
@@ -1536,9 +1503,7 @@ function Point({ value, min, max, size, width = 16, height = 16, color, disabled
1536
1503
  });
1537
1504
  const colors = { "--color": color };
1538
1505
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1539
- ref: (div) => {
1540
- touchMoveRefCallback(div);
1541
- },
1506
+ ref: dragRefCallback,
1542
1507
  className: (0, clsx.default)("tremolo-points-editor-point", className),
1543
1508
  tabIndex: 0,
1544
1509
  "aria-disabled": disabled != void 0 ? disabled : __disabled,
@@ -1552,10 +1517,7 @@ function Point({ value, min, max, size, width = 16, height = 16, color, disabled
1552
1517
  top: `${value.y * 100}%`,
1553
1518
  ...style
1554
1519
  },
1555
- onPointerDown: (event) => {
1556
- pointerDownHandler(event);
1557
- onPointerDown?.(event);
1558
- },
1520
+ onPointerDown,
1559
1521
  ...props
1560
1522
  });
1561
1523
  }
@@ -1856,24 +1818,24 @@ const Slider = {
1856
1818
  reverse,
1857
1819
  updateValueByEvent
1858
1820
  ]);
1859
- const { refHandler: touchMoveRefCallback, pointerDownHandler } = useDragWithElement({
1821
+ const { refCallback: dragRefCallback } = useDragWithElement({
1860
1822
  baseElementRef: trackElementRef,
1823
+ cursor: readonly ? void 0 : externalStyles.cursor,
1824
+ updateOnPointerDown: true,
1861
1825
  onDrag,
1862
1826
  onDragStart: (nx, ny) => {
1863
1827
  if (readonly) return;
1864
1828
  if (externalStyles.userSelectNone) addUserSelectNone();
1865
- if (externalStyles.cursor) setCursorStyle(externalStyles.cursor);
1866
1829
  thumbRef.current?.focus();
1867
1830
  onDragStart?.((0, _tremolo_ui_functions.clamp)((0, _tremolo_ui_functions.stepValue)((0, _tremolo_ui_functions.rawValue)(vertical ? ny : nx, min, max, skew), step), min, max));
1868
1831
  },
1869
1832
  onDragEnd: (nx, ny) => {
1870
1833
  if (readonly) return;
1871
1834
  if (externalStyles.userSelectNone) removeUserSelectNone();
1872
- if (externalStyles.cursor) resetCursorStyle();
1873
1835
  onDragEnd?.((0, _tremolo_ui_functions.clamp)((0, _tremolo_ui_functions.stepValue)((0, _tremolo_ui_functions.rawValue)(vertical ? ny : nx, min, max, skew), step), min, max));
1874
1836
  }
1875
1837
  });
1876
- const wheelRefCallback = useRefCallbackEvent("wheel", (event) => {
1838
+ const wheelRefCallback = useWheel((event) => {
1877
1839
  if (!wheel || !onChange || readonly) return;
1878
1840
  event.preventDefault();
1879
1841
  let x;
@@ -1884,13 +1846,7 @@ const Slider = {
1884
1846
  }
1885
1847
  if (vertical && reverse) x *= -1;
1886
1848
  onChange(updateValueByEvent(wheel[0], x));
1887
- }, { passive: false }, [
1888
- wheel,
1889
- vertical,
1890
- readonly,
1891
- onChange,
1892
- updateValueByEvent
1893
- ]);
1849
+ });
1894
1850
  (0, react.useImperativeHandle)(forwardedRef, () => {
1895
1851
  return {
1896
1852
  focus() {
@@ -1914,7 +1870,7 @@ const Slider = {
1914
1870
  className: (0, clsx.default)("tremolo-slider", className),
1915
1871
  ref: (div) => {
1916
1872
  wheelRefCallback(div);
1917
- touchMoveRefCallback(div);
1873
+ dragRefCallback(div);
1918
1874
  },
1919
1875
  tabIndex: -1,
1920
1876
  role: "slider",
@@ -1928,10 +1884,7 @@ const Slider = {
1928
1884
  margin: `calc(${(0, _tremolo_ui_functions.styleHelper)(thumbProps?.size ?? 22)} / 2)`,
1929
1885
  ...style
1930
1886
  },
1931
- onPointerDown: (event) => {
1932
- pointerDownHandler(event);
1933
- onPointerDown?.(event);
1934
- },
1887
+ onPointerDown,
1935
1888
  onKeyDown: (event) => {
1936
1889
  handleKeyDown(event);
1937
1890
  onKeyDown?.(event);
@@ -2006,29 +1959,6 @@ function composeRefs(...refs) {
2006
1959
  };
2007
1960
  }
2008
1961
  //#endregion
2009
- //#region src/components/WheelObserver/index.tsx
2010
- /**
2011
- * @example
2012
- * <WheelObserver
2013
- * onWheel={(event) => {
2014
- * event.preventDefault()
2015
- * console.log(event.deltaY)
2016
- * }
2017
- * >
2018
- * <div>Wheel here</div>
2019
- * </WheelObserver>
2020
- */
2021
- function WheelObserver(props) {
2022
- const { as: Component = "div", children, onWheel, ref, ...attributes } = props;
2023
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
2024
- ref: composeRefs(ref, useRefCallbackEvent("wheel", (event) => {
2025
- if (onWheel) onWheel(event);
2026
- }, { passive: false }, [onWheel])),
2027
- ...attributes,
2028
- children
2029
- });
2030
- }
2031
- //#endregion
2032
1962
  //#region src/components/XYPad/Area.tsx
2033
1963
  function Area({ width = 120, height = 120, color, children, className, style, __thumb, ...props }) {
2034
1964
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -2180,13 +2110,14 @@ const XYPad = {
2180
2110
  y,
2181
2111
  updateValueByEvent
2182
2112
  ]);
2183
- const { refHandler: touchMoveRefCallback, pointerDownHandler } = useDragWithElement({
2113
+ const { refCallback: dragRefCallback } = useDragWithElement({
2184
2114
  baseElementRef: areaElementRef,
2115
+ cursor: readonly ? void 0 : externalStyles.cursor,
2116
+ updateOnPointerDown: true,
2185
2117
  onDrag,
2186
2118
  onDragStart: (nx, ny) => {
2187
2119
  if (readonly) return;
2188
2120
  if (externalStyles.userSelectNone) addUserSelectNone();
2189
- if (externalStyles.cursor) setCursorStyle(externalStyles.cursor);
2190
2121
  thumbRef.current?.focus();
2191
2122
  const valueX = (0, _tremolo_ui_functions.clamp)((0, _tremolo_ui_functions.stepValue)((0, _tremolo_ui_functions.rawValue)(nx, x.min, x.max, x.skew), x.step), x.min, x.max);
2192
2123
  const valueY = (0, _tremolo_ui_functions.clamp)((0, _tremolo_ui_functions.stepValue)((0, _tremolo_ui_functions.rawValue)(ny, y.min, y.max, y.skew), y.step), y.min, y.max);
@@ -2195,13 +2126,12 @@ const XYPad = {
2195
2126
  onDragEnd: (nx, ny) => {
2196
2127
  if (readonly) return;
2197
2128
  if (externalStyles.userSelectNone) removeUserSelectNone();
2198
- if (externalStyles.cursor) resetCursorStyle();
2199
2129
  const valueX = (0, _tremolo_ui_functions.clamp)((0, _tremolo_ui_functions.stepValue)((0, _tremolo_ui_functions.rawValue)(nx, x.min, x.max, x.skew), x.step), x.min, x.max);
2200
2130
  const valueY = (0, _tremolo_ui_functions.clamp)((0, _tremolo_ui_functions.stepValue)((0, _tremolo_ui_functions.rawValue)(ny, y.min, y.max, y.skew), y.step), y.min, y.max);
2201
2131
  onDragEnd?.(valueX, valueY);
2202
2132
  }
2203
2133
  });
2204
- const wheelRefCallback = useRefCallbackEvent("wheel", (event) => {
2134
+ const wheelRefCallback = useWheel((event) => {
2205
2135
  if (!onChange || readonly) return;
2206
2136
  const target = event.shiftKey ? x : y;
2207
2137
  if (!target.wheel) return;
@@ -2212,13 +2142,7 @@ const XYPad = {
2212
2142
  const newValue = updateValueByEvent(target.wheel[0], target, delta);
2213
2143
  if (event.shiftKey) onChange(newValue, y.value);
2214
2144
  else onChange(x.value, newValue);
2215
- }, { passive: false }, [
2216
- x,
2217
- y,
2218
- onChange,
2219
- readonly,
2220
- updateValueByEvent
2221
- ]);
2145
+ });
2222
2146
  (0, react.useImperativeHandle)(forwardedRef, () => {
2223
2147
  return {
2224
2148
  focus() {
@@ -2232,7 +2156,7 @@ const XYPad = {
2232
2156
  }, []);
2233
2157
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2234
2158
  className: (0, clsx.default)("tremolo-xy-pad", className),
2235
- ref: composeRefs(rootRef, wheelRefCallback, touchMoveRefCallback),
2159
+ ref: composeRefs(rootRef, wheelRefCallback, dragRefCallback),
2236
2160
  tabIndex: -1,
2237
2161
  "aria-disabled": disabled,
2238
2162
  "aria-readonly": readonly,
@@ -2242,10 +2166,7 @@ const XYPad = {
2242
2166
  WebkitTapHighlightColor: "transparent",
2243
2167
  ...style
2244
2168
  },
2245
- onPointerDown: (event) => {
2246
- pointerDownHandler(event);
2247
- onPointerDown?.(event);
2248
- },
2169
+ onPointerDown,
2249
2170
  onKeyDown: (event) => {
2250
2171
  handleKeyDown(event);
2251
2172
  onKeyDown?.(event);
@@ -2347,7 +2268,6 @@ function useMIDIMessage(midiAccess, onMIDIMessage) {
2347
2268
  }
2348
2269
  //#endregion
2349
2270
  exports.AnimationCanvas = AnimationCanvas;
2350
- exports.DragObserver = DragObserver;
2351
2271
  exports.Knob = Knob;
2352
2272
  Object.defineProperty(exports, "NOT_SUPPORTED", {
2353
2273
  enumerable: true,
@@ -2366,7 +2286,6 @@ exports.Piano = Piano;
2366
2286
  exports.PointsEditor = PointsEditor;
2367
2287
  exports.SHORTCUTS = SHORTCUTS;
2368
2288
  exports.Slider = Slider;
2369
- exports.WheelObserver = WheelObserver;
2370
2289
  exports.XYPad = XYPad;
2371
2290
  exports.clampPoint = clampPoint;
2372
2291
  exports.getNoteRangeArray = getNoteRangeArray;
@@ -2380,5 +2299,6 @@ exports.useMIDIAccess = useMIDIAccess;
2380
2299
  exports.useMIDIInput = useMIDIInput;
2381
2300
  exports.useMIDIMessage = useMIDIMessage;
2382
2301
  exports.useSliderContext = useSliderContext;
2302
+ exports.useWheel = useWheel;
2383
2303
 
2384
2304
  //# sourceMappingURL=index.cjs.map