react-use-drag 0.3.2 → 0.3.5

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/README.md CHANGED
@@ -1,9 +1,21 @@
1
1
  # React use drag [![npm](https://img.shields.io/npm/v/react-use-drag.svg)](https://www.npmjs.com/package/react-use-drag) ![npm type definitions](https://img.shields.io/npm/types/react-use-drag.svg)
2
2
 
3
- Drag interactions made easier. Try interactive [CodeSandbox demo](https://codesandbox.io/p/sandbox/react-use-drag-trjpqp?file=%2Fsrc%2FApp.js).
3
+ Drag interactions made easier. Lightweight, React hook-based, and powered by Pointer Events for seamless mouse and touch support.
4
+
5
+ Try interactive [CodeSandbox demo](https://codesandbox.io/p/sandbox/react-use-drag-trjpqp?file=%2Fsrc%2FApp.js).
4
6
 
5
7
  ![UI example](https://raw.githubusercontent.com/FilipChalupa/react-use-drag/HEAD/screencast.gif)
6
8
 
9
+ ## Table of Contents
10
+
11
+ - [Installation](#installation)
12
+ - [How to use](#how-to-use)
13
+ - [API Reference](#api-reference)
14
+ - [Options](#options)
15
+ - [Return Value](#return-value)
16
+ - [Features](#features)
17
+ - [License](#license)
18
+
7
19
  ## Installation
8
20
 
9
21
  ```bash
@@ -14,23 +26,28 @@ npm install react-use-drag
14
26
 
15
27
  ```jsx
16
28
  import { useDrag } from 'react-use-drag'
29
+ import { useState, useCallback } from 'react'
17
30
 
18
31
  const App = () => {
19
32
  const [position, setPosition] = useState({ x: 0, y: 0 })
20
33
  const [positionOffset, setPositionOffset] = useState({ x: 0, y: 0 })
34
+
21
35
  const onRelativePositionChange = useCallback((x, y) => {
22
36
  setPositionOffset({ x, y })
23
37
  }, [])
38
+
24
39
  const onStart = useCallback(() => {
25
40
  console.log('Dragging has started')
26
41
  }, [])
42
+
27
43
  const onEnd = useCallback((x, y) => {
28
- setPosition((position) => ({
29
- x: position.x + x,
30
- y: position.y + y,
44
+ setPosition((pos) => ({
45
+ x: pos.x + x,
46
+ y: pos.y + y,
31
47
  }))
32
48
  setPositionOffset({ x: 0, y: 0 })
33
49
  }, [])
50
+
34
51
  const { elementProps, isMoving } = useDrag({
35
52
  onRelativePositionChange,
36
53
  onStart,
@@ -41,7 +58,8 @@ const App = () => {
41
58
  <button
42
59
  className="draggable"
43
60
  style={{
44
- translate: `translate(${position.x}px ${position.y}px)`,
61
+ transform: `translate(${position.x + positionOffset.x}px, ${position.y + positionOffset.y}px)`,
62
+ touchAction: 'none' // Recommended for mobile support
45
63
  }}
46
64
  {...elementProps}
47
65
  >
@@ -50,3 +68,35 @@ const App = () => {
50
68
  )
51
69
  }
52
70
  ```
71
+
72
+ ## API Reference
73
+
74
+ ### `useDrag(options)`
75
+
76
+ #### Options
77
+
78
+ | Property | Type | Description |
79
+ | :--- | :--- | :--- |
80
+ | `onRelativePositionChange` | `(x: number, y: number) => void` | **Required.** Called when the position changes during dragging. `x` and `y` are relative to the start position. |
81
+ | `onStart` | `() => void` | Optional. Called when the dragging interaction starts. |
82
+ | `onEnd` | `(x: number, y: number) => void` | Optional. Called when the dragging interaction ends. Receives final relative `x` and `y`. |
83
+
84
+ #### Return Value
85
+
86
+ An object containing:
87
+
88
+ | Property | Type | Description |
89
+ | :--- | :--- | :--- |
90
+ | `isMoving` | `boolean` | `true` if a drag interaction is currently active. |
91
+ | `elementProps` | `object` | Props to be spread onto the target element. Contains `onPointerDown`, `onPointerUp`, `onPointerMove`, and `onPointerCancel`. |
92
+
93
+ ## Features
94
+
95
+ - **Pointer Events:** Works with Mouse, Touch, and Pen out of the box.
96
+ - **Lightweight:** Zero dependencies (other than React) and tiny bundle size.
97
+ - **Predictable:** Simple API based on relative position changes.
98
+ - **TypeScript:** Fully typed for a great developer experience.
99
+
100
+ ## License
101
+
102
+ ISC
package/dist/index.cjs CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  var react = require('react');
4
4
 
5
+ /**
6
+ * Hook to handle drag interactions using Pointer Events.
7
+ *
8
+ * @param options - Configuration options for the drag interaction.
9
+ * @returns An object containing:
10
+ * - `isMoving`: boolean indicating if dragging is active.
11
+ * - `elementProps`: props to spread onto the draggable element.
12
+ *
13
+ * @example
14
+ * const { elementProps, isMoving } = useDrag({
15
+ * onRelativePositionChange: (x, y) => console.log('Offset:', x, y),
16
+ * })
17
+ * return <div {...elementProps} style={{ touchAction: 'none' }} />
18
+ */
5
19
  var useDrag = function (options) {
6
20
  var onRelativePositionChange = options.onRelativePositionChange, onStart = options.onStart, onEnd = options.onEnd;
7
21
  var _a = react.useState(false), isMoving = _a[0], setIsMoving = _a[1];
@@ -18,7 +32,7 @@ var useDrag = function (options) {
18
32
  event.currentTarget.setPointerCapture(event.pointerId);
19
33
  setIsMoving(true);
20
34
  onStart === null || onStart === void 0 ? void 0 : onStart();
21
- }, [onStart]);
35
+ }, [onStart, setIsMoving]);
22
36
  var handleEnd = react.useCallback(function (byCancellation) {
23
37
  if (!isMoving) {
24
38
  return undefined;
@@ -30,7 +44,7 @@ var useDrag = function (options) {
30
44
  onEnd === null || onEnd === void 0 ? void 0 : onEnd(byCancellation ? 0 : offsetPosition.x, byCancellation ? 0 : offsetPosition.y);
31
45
  setOffsetPosition({ x: 0, y: 0 });
32
46
  };
33
- }, [isMoving, offsetPosition.x, offsetPosition.y, onEnd]);
47
+ }, [isMoving, offsetPosition.x, offsetPosition.y, onEnd, setIsMoving, setOffsetPosition]);
34
48
  var onPointerUp = react.useMemo(function () { return handleEnd(false); }, [handleEnd]);
35
49
  var onPointerCancel = react.useMemo(function () { return handleEnd(true); }, [handleEnd]);
36
50
  var onPointerMove = react.useMemo(function () {
@@ -49,7 +63,7 @@ var useDrag = function (options) {
49
63
  };
50
64
  setOffsetPosition(newOffsetPosition);
51
65
  };
52
- }, [isMoving]);
66
+ }, [isMoving, setOffsetPosition]);
53
67
  react.useEffect(function () {
54
68
  onRelativePositionChange(offsetPosition.x, offsetPosition.y);
55
69
  }, [offsetPosition.x, offsetPosition.y, onRelativePositionChange]);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/useDrag.ts"],"sourcesContent":["import {\n\tPointerEvent,\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react'\n\nexport const useDrag = (options: {\n\tonRelativePositionChange: (x: number, y: number) => void\n\tonStart?: () => void\n\tonEnd?: (x: number, y: number) => void\n}) => {\n\tconst { onRelativePositionChange, onStart, onEnd } = options\n\tconst [isMoving, setIsMoving] = useState(false)\n\tconst startPosition = useRef({ x: 0, y: 0, scrollX: 0, scrollY: 0 })\n\tconst [offsetPosition, setOffsetPosition] = useState({ x: 0, y: 0 })\n\n\tconst onPointerDown = useCallback(\n\t\t(event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tstartPosition.current = {\n\t\t\t\tx: event.clientX,\n\t\t\t\ty: event.clientY,\n\t\t\t\tscrollX: window.scrollX, // @TODO: handle any parent scroll\n\t\t\t\tscrollY: window.scrollY, // @TODO: handle any parent scroll\n\t\t\t}\n\t\t\tevent.currentTarget.setPointerCapture(event.pointerId)\n\t\t\tsetIsMoving(true)\n\t\t\tonStart?.()\n\t\t},\n\t\t[onStart],\n\t)\n\n\tconst handleEnd = useCallback(\n\t\t(byCancellation: boolean) => {\n\t\t\tif (!isMoving) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetIsMoving(false)\n\t\t\t\tevent.currentTarget.releasePointerCapture(event.pointerId)\n\t\t\t\tonEnd?.(\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.x,\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.y,\n\t\t\t\t)\n\t\t\t\tsetOffsetPosition({ x: 0, y: 0 })\n\t\t\t}\n\t\t},\n\t\t[isMoving, offsetPosition.x, offsetPosition.y, onEnd],\n\t)\n\n\tconst onPointerUp = useMemo(() => handleEnd(false), [handleEnd])\n\tconst onPointerCancel = useMemo(() => handleEnd(true), [handleEnd])\n\n\tconst onPointerMove = useMemo(() => {\n\t\tif (!isMoving) {\n\t\t\treturn undefined\n\t\t}\n\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tconst newOffsetPosition = {\n\t\t\t\tx:\n\t\t\t\t\tevent.clientX +\n\t\t\t\t\twindow.scrollX -\n\t\t\t\t\t(startPosition.current.x + startPosition.current.scrollX),\n\t\t\t\ty:\n\t\t\t\t\tevent.clientY +\n\t\t\t\t\twindow.scrollY -\n\t\t\t\t\t(startPosition.current.y + startPosition.current.scrollY),\n\t\t\t}\n\t\t\tsetOffsetPosition(newOffsetPosition)\n\t\t}\n\t}, [isMoving])\n\n\tuseEffect(() => {\n\t\tonRelativePositionChange(offsetPosition.x, offsetPosition.y)\n\t}, [offsetPosition.x, offsetPosition.y, onRelativePositionChange])\n\n\tconst elementProps = useMemo(\n\t\t() => ({\n\t\t\tonPointerDown,\n\t\t\tonPointerUp,\n\t\t\tonPointerMove,\n\t\t\tonPointerCancel,\n\t\t}),\n\t\t[onPointerDown, onPointerMove, onPointerUp, onPointerCancel],\n\t)\n\n\treturn useMemo(() => ({ isMoving, elementProps }), [isMoving, elementProps])\n}\n"],"names":["useState","useRef","useCallback","useMemo","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/useDrag.ts"],"sourcesContent":["import {\n\tPointerEvent,\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react'\n\n/**\n * Options for the useDrag hook.\n */\nexport interface UseDragOptions {\n\t/** Called when the position changes during dragging. x and y are relative to the start position. */\n\tonRelativePositionChange: (x: number, y: number) => void\n\t/** Optional. Called when the dragging interaction starts. */\n\tonStart?: () => void\n\t/** Optional. Called when the dragging interaction ends. Receives final relative x and y. */\n\tonEnd?: (x: number, y: number) => void\n}\n\n/**\n * Hook to handle drag interactions using Pointer Events.\n * \n * @param options - Configuration options for the drag interaction.\n * @returns An object containing:\n * - `isMoving`: boolean indicating if dragging is active.\n * - `elementProps`: props to spread onto the draggable element.\n * \n * @example\n * const { elementProps, isMoving } = useDrag({\n * onRelativePositionChange: (x, y) => console.log('Offset:', x, y),\n * })\n * return <div {...elementProps} style={{ touchAction: 'none' }} />\n */\nexport const useDrag = (options: UseDragOptions) => {\n\tconst { onRelativePositionChange, onStart, onEnd } = options\n\tconst [isMoving, setIsMoving] = useState(false)\n\tconst startPosition = useRef({ x: 0, y: 0, scrollX: 0, scrollY: 0 })\n\tconst [offsetPosition, setOffsetPosition] = useState({ x: 0, y: 0 })\n\n\tconst onPointerDown = useCallback(\n\t\t(event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tstartPosition.current = {\n\t\t\t\tx: event.clientX,\n\t\t\t\ty: event.clientY,\n\t\t\t\tscrollX: window.scrollX, // @TODO: handle any parent scroll\n\t\t\t\tscrollY: window.scrollY, // @TODO: handle any parent scroll\n\t\t\t}\n\t\t\tevent.currentTarget.setPointerCapture(event.pointerId)\n\t\t\tsetIsMoving(true)\n\t\t\tonStart?.()\n\t\t},\n\t\t[onStart, setIsMoving],\n\t)\n\n\tconst handleEnd = useCallback(\n\t\t(byCancellation: boolean) => {\n\t\t\tif (!isMoving) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetIsMoving(false)\n\t\t\t\tevent.currentTarget.releasePointerCapture(event.pointerId)\n\t\t\t\tonEnd?.(\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.x,\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.y,\n\t\t\t\t)\n\t\t\t\tsetOffsetPosition({ x: 0, y: 0 })\n\t\t\t}\n\t\t},\n\t\t[isMoving, offsetPosition.x, offsetPosition.y, onEnd, setIsMoving, setOffsetPosition],\n\t)\n\n\tconst onPointerUp = useMemo(() => handleEnd(false), [handleEnd])\n\tconst onPointerCancel = useMemo(() => handleEnd(true), [handleEnd])\n\n\tconst onPointerMove = useMemo(() => {\n\t\tif (!isMoving) {\n\t\t\treturn undefined\n\t\t}\n\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tconst newOffsetPosition = {\n\t\t\t\tx:\n\t\t\t\t\tevent.clientX +\n\t\t\t\t\twindow.scrollX -\n\t\t\t\t\t(startPosition.current.x + startPosition.current.scrollX),\n\t\t\t\ty:\n\t\t\t\t\tevent.clientY +\n\t\t\t\t\twindow.scrollY -\n\t\t\t\t\t(startPosition.current.y + startPosition.current.scrollY),\n\t\t\t}\n\t\t\tsetOffsetPosition(newOffsetPosition)\n\t\t}\n\t}, [isMoving, setOffsetPosition])\n\n\tuseEffect(() => {\n\t\tonRelativePositionChange(offsetPosition.x, offsetPosition.y)\n\t}, [offsetPosition.x, offsetPosition.y, onRelativePositionChange])\n\n\tconst elementProps = useMemo(\n\t\t() => ({\n\t\t\tonPointerDown,\n\t\t\tonPointerUp,\n\t\t\tonPointerMove,\n\t\t\tonPointerCancel,\n\t\t}),\n\t\t[onPointerDown, onPointerMove, onPointerUp, onPointerCancel],\n\t)\n\n\treturn useMemo(() => ({ isMoving, elementProps }), [isMoving, elementProps])\n}\n"],"names":["useState","useRef","useCallback","useMemo","useEffect"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,19 @@
1
1
  import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
2
2
 
3
+ /**
4
+ * Hook to handle drag interactions using Pointer Events.
5
+ *
6
+ * @param options - Configuration options for the drag interaction.
7
+ * @returns An object containing:
8
+ * - `isMoving`: boolean indicating if dragging is active.
9
+ * - `elementProps`: props to spread onto the draggable element.
10
+ *
11
+ * @example
12
+ * const { elementProps, isMoving } = useDrag({
13
+ * onRelativePositionChange: (x, y) => console.log('Offset:', x, y),
14
+ * })
15
+ * return <div {...elementProps} style={{ touchAction: 'none' }} />
16
+ */
3
17
  var useDrag = function (options) {
4
18
  var onRelativePositionChange = options.onRelativePositionChange, onStart = options.onStart, onEnd = options.onEnd;
5
19
  var _a = useState(false), isMoving = _a[0], setIsMoving = _a[1];
@@ -16,7 +30,7 @@ var useDrag = function (options) {
16
30
  event.currentTarget.setPointerCapture(event.pointerId);
17
31
  setIsMoving(true);
18
32
  onStart === null || onStart === void 0 ? void 0 : onStart();
19
- }, [onStart]);
33
+ }, [onStart, setIsMoving]);
20
34
  var handleEnd = useCallback(function (byCancellation) {
21
35
  if (!isMoving) {
22
36
  return undefined;
@@ -28,7 +42,7 @@ var useDrag = function (options) {
28
42
  onEnd === null || onEnd === void 0 ? void 0 : onEnd(byCancellation ? 0 : offsetPosition.x, byCancellation ? 0 : offsetPosition.y);
29
43
  setOffsetPosition({ x: 0, y: 0 });
30
44
  };
31
- }, [isMoving, offsetPosition.x, offsetPosition.y, onEnd]);
45
+ }, [isMoving, offsetPosition.x, offsetPosition.y, onEnd, setIsMoving, setOffsetPosition]);
32
46
  var onPointerUp = useMemo(function () { return handleEnd(false); }, [handleEnd]);
33
47
  var onPointerCancel = useMemo(function () { return handleEnd(true); }, [handleEnd]);
34
48
  var onPointerMove = useMemo(function () {
@@ -47,7 +61,7 @@ var useDrag = function (options) {
47
61
  };
48
62
  setOffsetPosition(newOffsetPosition);
49
63
  };
50
- }, [isMoving]);
64
+ }, [isMoving, setOffsetPosition]);
51
65
  useEffect(function () {
52
66
  onRelativePositionChange(offsetPosition.x, offsetPosition.y);
53
67
  }, [offsetPosition.x, offsetPosition.y, onRelativePositionChange]);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/useDrag.ts"],"sourcesContent":["import {\n\tPointerEvent,\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react'\n\nexport const useDrag = (options: {\n\tonRelativePositionChange: (x: number, y: number) => void\n\tonStart?: () => void\n\tonEnd?: (x: number, y: number) => void\n}) => {\n\tconst { onRelativePositionChange, onStart, onEnd } = options\n\tconst [isMoving, setIsMoving] = useState(false)\n\tconst startPosition = useRef({ x: 0, y: 0, scrollX: 0, scrollY: 0 })\n\tconst [offsetPosition, setOffsetPosition] = useState({ x: 0, y: 0 })\n\n\tconst onPointerDown = useCallback(\n\t\t(event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tstartPosition.current = {\n\t\t\t\tx: event.clientX,\n\t\t\t\ty: event.clientY,\n\t\t\t\tscrollX: window.scrollX, // @TODO: handle any parent scroll\n\t\t\t\tscrollY: window.scrollY, // @TODO: handle any parent scroll\n\t\t\t}\n\t\t\tevent.currentTarget.setPointerCapture(event.pointerId)\n\t\t\tsetIsMoving(true)\n\t\t\tonStart?.()\n\t\t},\n\t\t[onStart],\n\t)\n\n\tconst handleEnd = useCallback(\n\t\t(byCancellation: boolean) => {\n\t\t\tif (!isMoving) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetIsMoving(false)\n\t\t\t\tevent.currentTarget.releasePointerCapture(event.pointerId)\n\t\t\t\tonEnd?.(\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.x,\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.y,\n\t\t\t\t)\n\t\t\t\tsetOffsetPosition({ x: 0, y: 0 })\n\t\t\t}\n\t\t},\n\t\t[isMoving, offsetPosition.x, offsetPosition.y, onEnd],\n\t)\n\n\tconst onPointerUp = useMemo(() => handleEnd(false), [handleEnd])\n\tconst onPointerCancel = useMemo(() => handleEnd(true), [handleEnd])\n\n\tconst onPointerMove = useMemo(() => {\n\t\tif (!isMoving) {\n\t\t\treturn undefined\n\t\t}\n\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tconst newOffsetPosition = {\n\t\t\t\tx:\n\t\t\t\t\tevent.clientX +\n\t\t\t\t\twindow.scrollX -\n\t\t\t\t\t(startPosition.current.x + startPosition.current.scrollX),\n\t\t\t\ty:\n\t\t\t\t\tevent.clientY +\n\t\t\t\t\twindow.scrollY -\n\t\t\t\t\t(startPosition.current.y + startPosition.current.scrollY),\n\t\t\t}\n\t\t\tsetOffsetPosition(newOffsetPosition)\n\t\t}\n\t}, [isMoving])\n\n\tuseEffect(() => {\n\t\tonRelativePositionChange(offsetPosition.x, offsetPosition.y)\n\t}, [offsetPosition.x, offsetPosition.y, onRelativePositionChange])\n\n\tconst elementProps = useMemo(\n\t\t() => ({\n\t\t\tonPointerDown,\n\t\t\tonPointerUp,\n\t\t\tonPointerMove,\n\t\t\tonPointerCancel,\n\t\t}),\n\t\t[onPointerDown, onPointerMove, onPointerUp, onPointerCancel],\n\t)\n\n\treturn useMemo(() => ({ isMoving, elementProps }), [isMoving, elementProps])\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/useDrag.ts"],"sourcesContent":["import {\n\tPointerEvent,\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react'\n\n/**\n * Options for the useDrag hook.\n */\nexport interface UseDragOptions {\n\t/** Called when the position changes during dragging. x and y are relative to the start position. */\n\tonRelativePositionChange: (x: number, y: number) => void\n\t/** Optional. Called when the dragging interaction starts. */\n\tonStart?: () => void\n\t/** Optional. Called when the dragging interaction ends. Receives final relative x and y. */\n\tonEnd?: (x: number, y: number) => void\n}\n\n/**\n * Hook to handle drag interactions using Pointer Events.\n * \n * @param options - Configuration options for the drag interaction.\n * @returns An object containing:\n * - `isMoving`: boolean indicating if dragging is active.\n * - `elementProps`: props to spread onto the draggable element.\n * \n * @example\n * const { elementProps, isMoving } = useDrag({\n * onRelativePositionChange: (x, y) => console.log('Offset:', x, y),\n * })\n * return <div {...elementProps} style={{ touchAction: 'none' }} />\n */\nexport const useDrag = (options: UseDragOptions) => {\n\tconst { onRelativePositionChange, onStart, onEnd } = options\n\tconst [isMoving, setIsMoving] = useState(false)\n\tconst startPosition = useRef({ x: 0, y: 0, scrollX: 0, scrollY: 0 })\n\tconst [offsetPosition, setOffsetPosition] = useState({ x: 0, y: 0 })\n\n\tconst onPointerDown = useCallback(\n\t\t(event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tstartPosition.current = {\n\t\t\t\tx: event.clientX,\n\t\t\t\ty: event.clientY,\n\t\t\t\tscrollX: window.scrollX, // @TODO: handle any parent scroll\n\t\t\t\tscrollY: window.scrollY, // @TODO: handle any parent scroll\n\t\t\t}\n\t\t\tevent.currentTarget.setPointerCapture(event.pointerId)\n\t\t\tsetIsMoving(true)\n\t\t\tonStart?.()\n\t\t},\n\t\t[onStart, setIsMoving],\n\t)\n\n\tconst handleEnd = useCallback(\n\t\t(byCancellation: boolean) => {\n\t\t\tif (!isMoving) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetIsMoving(false)\n\t\t\t\tevent.currentTarget.releasePointerCapture(event.pointerId)\n\t\t\t\tonEnd?.(\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.x,\n\t\t\t\t\tbyCancellation ? 0 : offsetPosition.y,\n\t\t\t\t)\n\t\t\t\tsetOffsetPosition({ x: 0, y: 0 })\n\t\t\t}\n\t\t},\n\t\t[isMoving, offsetPosition.x, offsetPosition.y, onEnd, setIsMoving, setOffsetPosition],\n\t)\n\n\tconst onPointerUp = useMemo(() => handleEnd(false), [handleEnd])\n\tconst onPointerCancel = useMemo(() => handleEnd(true), [handleEnd])\n\n\tconst onPointerMove = useMemo(() => {\n\t\tif (!isMoving) {\n\t\t\treturn undefined\n\t\t}\n\t\treturn (event: PointerEvent<HTMLElement>) => {\n\t\t\tevent.preventDefault()\n\t\t\tconst newOffsetPosition = {\n\t\t\t\tx:\n\t\t\t\t\tevent.clientX +\n\t\t\t\t\twindow.scrollX -\n\t\t\t\t\t(startPosition.current.x + startPosition.current.scrollX),\n\t\t\t\ty:\n\t\t\t\t\tevent.clientY +\n\t\t\t\t\twindow.scrollY -\n\t\t\t\t\t(startPosition.current.y + startPosition.current.scrollY),\n\t\t\t}\n\t\t\tsetOffsetPosition(newOffsetPosition)\n\t\t}\n\t}, [isMoving, setOffsetPosition])\n\n\tuseEffect(() => {\n\t\tonRelativePositionChange(offsetPosition.x, offsetPosition.y)\n\t}, [offsetPosition.x, offsetPosition.y, onRelativePositionChange])\n\n\tconst elementProps = useMemo(\n\t\t() => ({\n\t\t\tonPointerDown,\n\t\t\tonPointerUp,\n\t\t\tonPointerMove,\n\t\t\tonPointerCancel,\n\t\t}),\n\t\t[onPointerDown, onPointerMove, onPointerUp, onPointerCancel],\n\t)\n\n\treturn useMemo(() => ({ isMoving, elementProps }), [isMoving, elementProps])\n}\n"],"names":[],"mappings":";;AAqBA;;;;;;;;;;;;;AAaG;AACI,IAAM,OAAO,GAAG,UAAC,OAAuB,EAAA;AACtC,IAAA,IAAA,wBAAwB,GAAqB,OAAO,CAAA,wBAA5B,EAAE,OAAO,GAAY,OAAO,CAAA,OAAnB,EAAE,KAAK,GAAK,OAAO,MAAZ,CAAY;IACtD,IAAA,EAAA,GAA0B,QAAQ,CAAC,KAAK,CAAC,EAAxC,QAAQ,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,WAAW,GAAA,EAAA,CAAA,CAAA,CAAmB,CAAA;IAC/C,IAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;AAC9D,IAAA,IAAA,KAAsC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAA7D,cAAc,QAAA,EAAE,iBAAiB,QAA4B,CAAA;AAEpE,IAAA,IAAM,aAAa,GAAG,WAAW,CAChC,UAAC,KAAgC,EAAA;QAChC,KAAK,CAAC,cAAc,EAAE,CAAA;QACtB,aAAa,CAAC,OAAO,GAAG;YACvB,CAAC,EAAE,KAAK,CAAC,OAAO;YAChB,CAAC,EAAE,KAAK,CAAC,OAAO;AAChB,YAAA,OAAO,EAAE,MAAM,CAAC,OAAO;AACvB,YAAA,OAAO,EAAE,MAAM,CAAC,OAAO;SACvB,CAAA;QACD,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACtD,WAAW,CAAC,IAAI,CAAC,CAAA;AACjB,QAAA,OAAO,KAAP,IAAA,IAAA,OAAO,KAAP,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,OAAO,EAAI,CAAA;AACZ,KAAC,EACD,CAAC,OAAO,EAAE,WAAW,CAAC,CACtB,CAAA;AAED,IAAA,IAAM,SAAS,GAAG,WAAW,CAC5B,UAAC,cAAuB,EAAA;QACvB,IAAI,CAAC,QAAQ,EAAE;AACd,YAAA,OAAO,SAAS,CAAA;SAChB;AACD,QAAA,OAAO,UAAC,KAAgC,EAAA;YACvC,KAAK,CAAC,cAAc,EAAE,CAAA;YACtB,WAAW,CAAC,KAAK,CAAC,CAAA;YAClB,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;AAC1D,YAAA,KAAK,KAAL,IAAA,IAAA,KAAK,KAAL,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,KAAK,CACJ,cAAc,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,EACrC,cAAc,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,CACrC,CAAA;YACD,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;AAClC,SAAC,CAAA;AACF,KAAC,EACD,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,CAAC,CACrF,CAAA;AAED,IAAA,IAAM,WAAW,GAAG,OAAO,CAAC,YAAA,EAAM,OAAA,SAAS,CAAC,KAAK,CAAC,GAAA,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;AAChE,IAAA,IAAM,eAAe,GAAG,OAAO,CAAC,YAAA,EAAM,OAAA,SAAS,CAAC,IAAI,CAAC,GAAA,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAEnE,IAAM,aAAa,GAAG,OAAO,CAAC,YAAA;QAC7B,IAAI,CAAC,QAAQ,EAAE;AACd,YAAA,OAAO,SAAS,CAAA;SAChB;AACD,QAAA,OAAO,UAAC,KAAgC,EAAA;YACvC,KAAK,CAAC,cAAc,EAAE,CAAA;AACtB,YAAA,IAAM,iBAAiB,GAAG;gBACzB,CAAC,EACA,KAAK,CAAC,OAAO;AACb,oBAAA,MAAM,CAAC,OAAO;qBACb,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBAC1D,CAAC,EACA,KAAK,CAAC,OAAO;AACb,oBAAA,MAAM,CAAC,OAAO;qBACb,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;aAC1D,CAAA;YACD,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;AACrC,SAAC,CAAA;AACF,KAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAA;AAEjC,IAAA,SAAS,CAAC,YAAA;QACT,wBAAwB,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;AAC7D,KAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAAA;AAElE,IAAA,IAAM,YAAY,GAAG,OAAO,CAC3B,YAAA,EAAM,QAAC;AACN,QAAA,aAAa,EAAA,aAAA;AACb,QAAA,WAAW,EAAA,WAAA;AACX,QAAA,aAAa,EAAA,aAAA;AACb,QAAA,eAAe,EAAA,eAAA;AACf,KAAA,EALK,EAKJ,EACF,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,CAAC,CAC5D,CAAA;IAED,OAAO,OAAO,CAAC,YAAM,EAAA,QAAC,EAAE,QAAQ,EAAA,QAAA,EAAE,YAAY,EAAA,YAAA,EAAE,EAAC,EAAA,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAA;AAC7E;;;;"}
package/dist/useDrag.d.ts CHANGED
@@ -1,9 +1,30 @@
1
1
  import { PointerEvent } from 'react';
2
- export declare const useDrag: (options: {
2
+ /**
3
+ * Options for the useDrag hook.
4
+ */
5
+ export interface UseDragOptions {
6
+ /** Called when the position changes during dragging. x and y are relative to the start position. */
3
7
  onRelativePositionChange: (x: number, y: number) => void;
4
- onStart?: (() => void) | undefined;
5
- onEnd?: ((x: number, y: number) => void) | undefined;
6
- }) => {
8
+ /** Optional. Called when the dragging interaction starts. */
9
+ onStart?: () => void;
10
+ /** Optional. Called when the dragging interaction ends. Receives final relative x and y. */
11
+ onEnd?: (x: number, y: number) => void;
12
+ }
13
+ /**
14
+ * Hook to handle drag interactions using Pointer Events.
15
+ *
16
+ * @param options - Configuration options for the drag interaction.
17
+ * @returns An object containing:
18
+ * - `isMoving`: boolean indicating if dragging is active.
19
+ * - `elementProps`: props to spread onto the draggable element.
20
+ *
21
+ * @example
22
+ * const { elementProps, isMoving } = useDrag({
23
+ * onRelativePositionChange: (x, y) => console.log('Offset:', x, y),
24
+ * })
25
+ * return <div {...elementProps} style={{ touchAction: 'none' }} />
26
+ */
27
+ export declare const useDrag: (options: UseDragOptions) => {
7
28
  isMoving: boolean;
8
29
  elementProps: {
9
30
  onPointerDown: (event: PointerEvent<HTMLElement>) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-use-drag",
3
- "version": "0.3.2",
3
+ "version": "0.3.5",
4
4
  "description": "Drag interactions made easier.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -9,11 +9,13 @@
9
9
  "scripts": {
10
10
  "start": "rollup -c -w",
11
11
  "build": "rollup -c",
12
- "prepare": "npm run build"
12
+ "prepare": "npm run build",
13
+ "lint": "eslint .",
14
+ "type-check": "tsc --noEmit"
13
15
  },
14
16
  "repository": {
15
17
  "type": "git",
16
- "url": "https://github.com/FilipChalupa/react-use-drag.git"
18
+ "url": "git+https://github.com/FilipChalupa/react-use-drag.git"
17
19
  },
18
20
  "keywords": [
19
21
  "typescript",
@@ -28,9 +30,14 @@
28
30
  },
29
31
  "license": "ISC",
30
32
  "devDependencies": {
33
+ "@eslint/js": "^9.39.3",
31
34
  "@rollup/plugin-commonjs": "^25.0.7",
32
35
  "@rollup/plugin-node-resolve": "^15.2.3",
33
36
  "@types/react": "^18.0.10",
37
+ "eslint": "^9.39.3",
38
+ "eslint-config-prettier": "^9.1.2",
39
+ "eslint-plugin-react": "^7.37.5",
40
+ "eslint-plugin-react-hooks": "^5.2.0",
34
41
  "prettier": "^3.0.3",
35
42
  "react": "^18.1.0",
36
43
  "rollup": "^4.2.0",
@@ -38,6 +45,7 @@
38
45
  "rollup-plugin-peer-deps-external": "^2.2.4",
39
46
  "rollup-plugin-typescript2": "^0.36.0",
40
47
  "typescript": "^5.2.2",
48
+ "typescript-eslint": "^8.56.0",
41
49
  "typescript-plugin-css-modules": "^5.0.2"
42
50
  },
43
51
  "peerDependencies": {