위젯영역 리사이즈
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import {
|
||||
adjustAdjacentGridFr,
|
||||
FLOATING_WIDGET_CELL_MIN_H,
|
||||
FLOATING_WIDGET_CELL_MIN_W,
|
||||
FLOATING_WIDGET_GRID_GAP,
|
||||
} from '../types/floatingWidget';
|
||||
import { bindWindowDrag, isPrimaryPointerButton } from '../utils/pointerDrag';
|
||||
|
||||
type SplitAxis = 'col' | 'row';
|
||||
|
||||
interface Options {
|
||||
onColFrChange: (next: number[]) => void;
|
||||
onRowFrChange: (next: number[]) => void;
|
||||
getColFr: () => number[];
|
||||
getRowFr: () => number[];
|
||||
getBodySize: () => { width: number; height: number };
|
||||
}
|
||||
|
||||
export function useFloatingWidgetGridSplit({
|
||||
onColFrChange,
|
||||
onRowFrChange,
|
||||
getColFr,
|
||||
getRowFr,
|
||||
getBodySize,
|
||||
}: Options) {
|
||||
const unbindDragRef = useRef<(() => void) | null>(null);
|
||||
|
||||
const endDrag = useCallback(() => {
|
||||
unbindDragRef.current?.();
|
||||
unbindDragRef.current = null;
|
||||
document.body.style.cursor = '';
|
||||
document.body.style.userSelect = '';
|
||||
}, []);
|
||||
|
||||
useEffect(() => () => {
|
||||
unbindDragRef.current?.();
|
||||
document.body.style.cursor = '';
|
||||
document.body.style.userSelect = '';
|
||||
}, []);
|
||||
|
||||
const startSplit = useCallback((
|
||||
e: React.PointerEvent,
|
||||
axis: SplitAxis,
|
||||
index: number,
|
||||
) => {
|
||||
if (!isPrimaryPointerButton(e)) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const handle = e.currentTarget as HTMLElement;
|
||||
try {
|
||||
handle.setPointerCapture(e.pointerId);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
handle.classList.add('fw-grid-splitter--active');
|
||||
|
||||
const startX = e.clientX;
|
||||
const startY = e.clientY;
|
||||
const startColFr = [...getColFr()];
|
||||
const startRowFr = [...getRowFr()];
|
||||
const startSize = getBodySize();
|
||||
|
||||
document.body.style.cursor = axis === 'col' ? 'col-resize' : 'row-resize';
|
||||
document.body.style.userSelect = 'none';
|
||||
|
||||
unbindDragRef.current?.();
|
||||
unbindDragRef.current = bindWindowDrag(
|
||||
(xy) => {
|
||||
if (axis === 'col') {
|
||||
const delta = xy.x - startX;
|
||||
onColFrChange(adjustAdjacentGridFr(
|
||||
startColFr,
|
||||
index,
|
||||
delta,
|
||||
startSize.width,
|
||||
FLOATING_WIDGET_GRID_GAP,
|
||||
FLOATING_WIDGET_CELL_MIN_W,
|
||||
));
|
||||
return;
|
||||
}
|
||||
const delta = xy.y - startY;
|
||||
onRowFrChange(adjustAdjacentGridFr(
|
||||
startRowFr,
|
||||
index,
|
||||
delta,
|
||||
startSize.height,
|
||||
FLOATING_WIDGET_GRID_GAP,
|
||||
FLOATING_WIDGET_CELL_MIN_H,
|
||||
));
|
||||
},
|
||||
() => {
|
||||
handle.classList.remove('fw-grid-splitter--active');
|
||||
endDrag();
|
||||
},
|
||||
{ preventTouchScroll: true },
|
||||
);
|
||||
}, [endDrag, getBodySize, getColFr, getRowFr, onColFrChange, onRowFrChange]);
|
||||
|
||||
const onColSplitPointerDown = useCallback(
|
||||
(index: number) => (e: React.PointerEvent) => startSplit(e, 'col', index),
|
||||
[startSplit],
|
||||
);
|
||||
|
||||
const onRowSplitPointerDown = useCallback(
|
||||
(index: number) => (e: React.PointerEvent) => startSplit(e, 'row', index),
|
||||
[startSplit],
|
||||
);
|
||||
|
||||
return { onColSplitPointerDown, onRowSplitPointerDown };
|
||||
}
|
||||
Reference in New Issue
Block a user