RYP / src /components /Compiler /useResizable.ts
Soumya79's picture
Upload 1361 files
f91a684 verified
import { useCallback, useEffect, useRef, useState } from 'react';
type Direction = 'horizontal' | 'vertical';
interface UseResizableOptions {
direction: Direction;
initialSize: number;
minSize: number;
maxSize: number;
/** If true, the "size" represents the *second* panel (e.g. right panel width). */
reverse?: boolean;
}
export default function useResizable({
direction,
initialSize,
minSize,
maxSize,
reverse = false,
}: UseResizableOptions) {
const [size, setSize] = useState(initialSize);
const [isDragging, setIsDragging] = useState(false);
const startPos = useRef(0);
const startSize = useRef(0);
const onMouseDown = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
setIsDragging(true);
startPos.current = direction === 'horizontal' ? e.clientY : e.clientX;
startSize.current = size;
},
[direction, size],
);
useEffect(() => {
if (!isDragging) return;
const onMouseMove = (e: MouseEvent) => {
const currentPos = direction === 'horizontal' ? e.clientY : e.clientX;
const delta = currentPos - startPos.current;
const adjust = reverse ? -delta : delta;
const next = Math.min(maxSize, Math.max(minSize, startSize.current + adjust));
setSize(next);
};
const onMouseUp = () => setIsDragging(false);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
document.body.style.cursor = direction === 'horizontal' ? 'row-resize' : 'col-resize';
document.body.style.userSelect = 'none';
return () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
document.body.style.cursor = '';
document.body.style.userSelect = '';
};
}, [isDragging, direction, minSize, maxSize, reverse]);
return { size, isDragging, onMouseDown };
}