Skip to content

Instantly share code, notes, and snippets.

@airtonix
Created February 3, 2023 10:49
Show Gist options
  • Save airtonix/7ede03c0310a03e62981bc3786577ffc to your computer and use it in GitHub Desktop.
Save airtonix/7ede03c0310a03e62981bc3786577ffc to your computer and use it in GitHub Desktop.
import type { RefObject } from "react";
import { useCallback } from "react";
import { useState, useEffect } from "react";
type UseDragOptions = {
onPointerDown?: (event: PointerEvent) => void;
onPointerUp?: (event: PointerEvent) => void;
onPointerMove?: (event: PointerEvent) => void;
onDrag?: (event: DragEvent) => void;
};
export function useDrag(
ref: RefObject<HTMLElement>,
deps = [],
options: UseDragOptions = {}
) {
const [isDragging, setIsDragging] = useState(false);
const handlePointerDown = useCallback(
(event: PointerEvent) => {
setIsDragging(true);
if (typeof options.onPointerDown !== "function") return;
options.onPointerDown(event);
},
[options]
);
const handlePointerUp = useCallback(
(event: PointerEvent) => {
setIsDragging(false);
if (typeof options.onPointerUp !== "function") return;
options.onPointerUp(event);
},
[options]
);
const handlePointerMove = useCallback(
(event: PointerEvent) => {
if (typeof options.onPointerMove === "function") {
options.onPointerMove(event);
}
if (isDragging && typeof options.onDrag === "function") {
options.onDrag({ ...event, dataTransfer: null });
}
},
[isDragging, options]
);
useEffect(() => {
if (!ref) return;
const element = ref.current;
if (element) {
element.addEventListener("pointerdown", handlePointerDown);
element.addEventListener("pointerup", handlePointerUp);
element.addEventListener("pointermove", handlePointerMove);
return () => {
element.removeEventListener("pointerdown", handlePointerDown);
element.removeEventListener("pointerup", handlePointerUp);
element.removeEventListener("pointermove", handlePointerMove);
};
}
return () => {
return;
};
}, [
...deps,
handlePointerDown,
handlePointerMove,
handlePointerUp,
isDragging,
ref,
]);
return { isDragging };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment