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 | import { useState, useEffect, useRef, useCallback } from "react"; type ResizeDirection = "left" | "right" | "top" | "bottom"; const useResizable = ({ initialSize, minSize = 0, maxSize = Infinity, direction = "right", onResize, onResizeComplete, }: { initialSize: number; minSize: number; maxSize: number; direction: ResizeDirection; onResize?: (newValue: number) => void; onResizeComplete?: (newValue: number) => void; }): [ number, React.Dispatch<React.SetStateAction<number>>, (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void ] => { const [size, setSize] = useState(initialSize); const [isResizing, setIsResizing] = useState(false); const startSize = useRef<number>(0); const startOffset = useRef<number>(0); const clampSize = useCallback( (size: number) => { return Math.max(minSize, Math.min(maxSize, size)); }, [maxSize, minSize] ); const updateSize = useCallback( (newSize: number) => { onResize?.(clampSize(newSize)); setSize(newSize); }, [clampSize, onResize] ); const onDragStart = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => { if (direction === "left" || direction === "right") { startOffset.current = e.pageX; } else { startOffset.current = e.pageY; } startSize.current = size; setIsResizing(true); setSize(clampSize(size)); }; const onDragMove = useCallback( (e: MouseEvent) => { if (direction === "left") { updateSize(startSize.current - (e.pageX - startOffset.current)); } else if (direction === "right") { updateSize(startSize.current + (e.pageX - startOffset.current)); } else if (direction === "top") { updateSize(startSize.current - (e.pageY - startOffset.current)); } else Iif (direction === "bottom") { updateSize(startSize.current + (e.pageY - startOffset.current)); } }, [direction, updateSize] ); const onDragStop = useCallback(() => { setIsResizing(false); setSize(clampSize(size)); onResizeComplete?.(clampSize(size)); }, [clampSize, onResizeComplete, size]); useEffect(() => { Iif (isResizing) { window.addEventListener("mousemove", onDragMove); window.addEventListener("mouseup", onDragStop); return () => { window.removeEventListener("mousemove", onDragMove); window.removeEventListener("mouseup", onDragStop); }; } }, [isResizing, onDragMove, onDragStop, size]); return [clampSize(size), setSize, onDragStart]; }; export default useResizable; |