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 | 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x 1x 1x | 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; Iif (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, }; } |