Lots of improvements
This commit is contained in:
parent
3853b5dce7
commit
b94cf17d75
33 changed files with 2587 additions and 1866 deletions
|
|
@ -7,43 +7,87 @@ interface PaneResizeHandlers {
|
|||
}
|
||||
|
||||
export function usePaneResize(
|
||||
initialWidth: number,
|
||||
minWidth: number,
|
||||
maxWidth: number,
|
||||
side: 'left' | 'right'
|
||||
): [number, PaneResizeHandlers] {
|
||||
const [width, setWidth] = useState(initialWidth);
|
||||
initialSize: number,
|
||||
minSize: number,
|
||||
maxSize: number,
|
||||
side: 'left' | 'right' | 'top' | 'bottom'
|
||||
): [number, PaneResizeHandlers, React.RefCallback<HTMLElement>] {
|
||||
const [size, setSize] = useState(initialSize);
|
||||
const draggingRef = useRef(false);
|
||||
const liveSizeRef = useRef(initialSize);
|
||||
const targetRef = useRef<HTMLElement | null>(null);
|
||||
const containerOffsetRef = useRef(0);
|
||||
const containerSizeRef = useRef(0);
|
||||
|
||||
const handlePointerDown = useCallback((e: React.PointerEvent) => {
|
||||
e.preventDefault();
|
||||
(e.target as HTMLElement).setPointerCapture(e.pointerId);
|
||||
draggingRef.current = true;
|
||||
const isVertical = side === 'top' || side === 'bottom';
|
||||
const styleProp = isVertical ? 'height' : 'width';
|
||||
|
||||
const targetCallbackRef = useCallback((el: HTMLElement | null) => {
|
||||
targetRef.current = el;
|
||||
}, []);
|
||||
|
||||
const computeSize = useCallback(
|
||||
(e: React.PointerEvent): number => {
|
||||
if (isVertical) {
|
||||
const total = containerSizeRef.current || window.innerHeight;
|
||||
const resolvedMax = maxSize <= 1 ? total * maxSize : maxSize;
|
||||
const pos = e.clientY - containerOffsetRef.current;
|
||||
return side === 'top'
|
||||
? Math.min(resolvedMax, Math.max(minSize, pos))
|
||||
: Math.min(resolvedMax, Math.max(minSize, total - pos));
|
||||
} else {
|
||||
const resolvedMax = maxSize <= 1 ? window.innerWidth * maxSize : maxSize;
|
||||
return side === 'left'
|
||||
? Math.min(resolvedMax, Math.max(minSize, e.clientX))
|
||||
: Math.min(resolvedMax, Math.max(minSize, window.innerWidth - e.clientX));
|
||||
}
|
||||
},
|
||||
[side, isVertical, minSize, maxSize]
|
||||
);
|
||||
|
||||
const handlePointerDown = useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
e.preventDefault();
|
||||
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
|
||||
draggingRef.current = true;
|
||||
if (isVertical) {
|
||||
const container = (e.currentTarget as HTMLElement).parentElement;
|
||||
if (container) {
|
||||
const rect = container.getBoundingClientRect();
|
||||
containerOffsetRef.current = rect.top;
|
||||
containerSizeRef.current = rect.height;
|
||||
}
|
||||
}
|
||||
},
|
||||
[isVertical]
|
||||
);
|
||||
|
||||
const handlePointerMove = useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
if (!draggingRef.current) return;
|
||||
const resolvedMax = maxWidth <= 1 ? window.innerWidth * maxWidth : maxWidth;
|
||||
const newWidth =
|
||||
side === 'left'
|
||||
? Math.min(resolvedMax, Math.max(minWidth, e.clientX))
|
||||
: Math.min(resolvedMax, Math.max(minWidth, window.innerWidth - e.clientX));
|
||||
setWidth(newWidth);
|
||||
const newSize = computeSize(e);
|
||||
liveSizeRef.current = newSize;
|
||||
if (targetRef.current) {
|
||||
targetRef.current.style[styleProp] = `${newSize}px`;
|
||||
} else {
|
||||
setSize(newSize);
|
||||
}
|
||||
},
|
||||
[side, minWidth, maxWidth]
|
||||
[computeSize, styleProp]
|
||||
);
|
||||
|
||||
const handlePointerUp = useCallback(() => {
|
||||
draggingRef.current = false;
|
||||
setSize(liveSizeRef.current);
|
||||
}, []);
|
||||
|
||||
return [
|
||||
width,
|
||||
size,
|
||||
{
|
||||
onPointerDown: handlePointerDown,
|
||||
onPointerMove: handlePointerMove,
|
||||
onPointerUp: handlePointerUp,
|
||||
},
|
||||
targetCallbackRef,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue