Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 62x 62x 62x 62x 62x 62x 62x 62x 254x 254x 181x 73x 62x 62x | import * as React from 'react';
interface Offset {
x: number;
y: number;
}
interface DragState {
startX: number;
startY: number;
initialOffset: Offset;
}
interface UseDraggableProps {
enabled?: boolean;
}
interface UseDraggableReturn {
offset: React.RefObject<Offset>;
internalRef: React.RefObject<HTMLDivElement>;
handlePointerDown: (e: React.PointerEvent<HTMLDivElement>) => void;
setRefs: (node: HTMLDivElement) => void;
initialTransform: string | undefined;
}
export function useDraggable(
props: UseDraggableProps,
ref?: React.ForwardedRef<HTMLDivElement>
): UseDraggableReturn {
const { enabled = false } = props;
const offsetRef = React.useRef<Offset>({ x: 0, y: 0 });
const internalRef = React.useRef<HTMLDivElement>(null);
const dragState = React.useRef<DragState | null>(null);
const handlePointerMove = React.useCallback((e: PointerEvent) => {
Iif (!dragState.current) {
return;
}
const deltaX = e.clientX - dragState.current.startX;
const deltaY = e.clientY - dragState.current.startY;
const newOffset = {
x: dragState.current.initialOffset.x + deltaX,
y: dragState.current.initialOffset.y + deltaY,
};
offsetRef.current = newOffset;
Iif (internalRef.current) {
internalRef.current.style.transform = `translate(-50%, -50%) translate(${newOffset.x}px, ${newOffset.y}px)`;
}
}, []);
const handlePointerUp = React.useCallback(() => {
Iif (internalRef.current) {
internalRef.current.style.transition = '';
}
window.removeEventListener('pointermove', handlePointerMove);
window.removeEventListener('pointerup', handlePointerUp);
dragState.current = null;
}, [handlePointerMove]);
const handlePointerDown = React.useCallback(
(e: React.PointerEvent<HTMLDivElement>) => {
const target = e.target as HTMLElement;
Iif (!target.closest('.drag-handle')) {
return;
}
Iif (internalRef.current) {
internalRef.current.style.transition = 'none';
}
dragState.current = {
startX: e.clientX,
startY: e.clientY,
initialOffset: { ...offsetRef.current },
};
window.addEventListener('pointermove', handlePointerMove);
window.addEventListener('pointerup', handlePointerUp);
},
[handlePointerMove, handlePointerUp]
);
const setRefs = React.useCallback(
(node: HTMLDivElement) => {
internalRef.current = node;
if (typeof ref === 'function') {
ref(node);
} else Iif (ref) {
(ref as React.MutableRefObject<HTMLDivElement | null>).current = node;
}
},
[ref]
);
const initialTransform = enabled
? `translate(-50%, -50%) translate(${offsetRef.current.x}px, ${offsetRef.current.y}px)`
: undefined;
return {
offset: offsetRef,
internalRef,
handlePointerDown,
setRefs,
initialTransform,
};
}
|