feat: add touch handling
This commit is contained in:
parent
bd3892e314
commit
811be2f59b
@ -1,5 +1,6 @@
|
|||||||
import React, {
|
import React, {
|
||||||
ComponentPropsWithoutRef,
|
ComponentPropsWithoutRef,
|
||||||
|
TouchEvent as ReactTouchEvent,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
@ -171,6 +172,7 @@ const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|||||||
const [state, setState] = useContext(DrawerContext);
|
const [state, setState] = useContext(DrawerContext);
|
||||||
const [dragState, setDragState] = useState({
|
const [dragState, setDragState] = useState({
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
|
prevTouch: { x: 0, y: 0 },
|
||||||
delta: 0,
|
delta: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -188,11 +190,23 @@ const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|||||||
setDragState({
|
setDragState({
|
||||||
isDragging: true,
|
isDragging: true,
|
||||||
delta: 0,
|
delta: 0,
|
||||||
|
prevTouch: { x: 0, y: 0 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTouchStart(e: ReactTouchEvent<HTMLDivElement>) {
|
||||||
|
setState((prev) => ({ ...prev, isDragging: true }));
|
||||||
|
setDragState({
|
||||||
|
isDragging: true,
|
||||||
|
delta: 0,
|
||||||
|
prevTouch: { x: e.touches[0].pageX, y: e.touches[0].pageY },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function onMouseUp(e: MouseEvent) {
|
function onMouseUp(e: TouchEvent): void;
|
||||||
|
function onMouseUp(e: MouseEvent): void;
|
||||||
|
function onMouseUp(e: TouchEvent | MouseEvent) {
|
||||||
if (
|
if (
|
||||||
e.target instanceof Element &&
|
e.target instanceof Element &&
|
||||||
internalRef.current &&
|
internalRef.current &&
|
||||||
@ -220,15 +234,22 @@ const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|||||||
setDragState({
|
setDragState({
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
delta: 0,
|
delta: 0,
|
||||||
|
prevTouch: { x: 0, y: 0 },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseMove(e: MouseEvent) {
|
function onMouseMove(e: TouchEvent): void;
|
||||||
|
function onMouseMove(e: MouseEvent): void;
|
||||||
|
function onMouseMove(e: MouseEvent | TouchEvent) {
|
||||||
if (dragState.isDragging) {
|
if (dragState.isDragging) {
|
||||||
setDragState((prev) => {
|
setDragState((prev) => {
|
||||||
let movement = ["top", "bottom"].includes(position)
|
let movement = ["top", "bottom"].includes(position)
|
||||||
? e.movementY
|
? "movementY" in e
|
||||||
: e.movementX;
|
? e.movementY
|
||||||
|
: e.touches[0].pageY - prev.prevTouch.y
|
||||||
|
: "movementX" in e
|
||||||
|
? e.movementX
|
||||||
|
: e.touches[0].pageX - prev.prevTouch.x;
|
||||||
if (
|
if (
|
||||||
(["top", "left"].includes(position) &&
|
(["top", "left"].includes(position) &&
|
||||||
dragState.delta >= 0 &&
|
dragState.delta >= 0 &&
|
||||||
@ -243,6 +264,11 @@ const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
delta: prev.delta + movement,
|
delta: prev.delta + movement,
|
||||||
|
...("touches" in e
|
||||||
|
? {
|
||||||
|
prevTouch: { x: e.touches[0].pageX, y: e.touches[0].pageY },
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -268,9 +294,13 @@ const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|||||||
|
|
||||||
window.addEventListener("mousemove", onMouseMove);
|
window.addEventListener("mousemove", onMouseMove);
|
||||||
window.addEventListener("mouseup", onMouseUp);
|
window.addEventListener("mouseup", onMouseUp);
|
||||||
|
window.addEventListener("touchmove", onMouseMove);
|
||||||
|
window.addEventListener("touchend", onMouseUp);
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("mousemove", onMouseMove);
|
window.removeEventListener("mousemove", onMouseMove);
|
||||||
window.removeEventListener("mouseup", onMouseUp);
|
window.removeEventListener("mouseup", onMouseUp);
|
||||||
|
window.removeEventListener("touchmove", onMouseMove);
|
||||||
|
window.removeEventListener("touchend", onMouseUp);
|
||||||
};
|
};
|
||||||
}, [state, dragState]);
|
}, [state, dragState]);
|
||||||
|
|
||||||
@ -337,6 +367,7 @@ const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|||||||
dragState.isDragging &&
|
dragState.isDragging &&
|
||||||
setState((prev) => ({ ...prev, leaveWhileDragging: false }))
|
setState((prev) => ({ ...prev, leaveWhileDragging: false }))
|
||||||
}
|
}
|
||||||
|
onTouchStart={onTouchStart}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user