'use client'; import * as React from 'react'; import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; import { getEventClientCoords, isMouseEvent, isTouchEvent, useAnimationFrame } from '@fluentui/react-utilities'; export function useTableColumnResizeMouseHandler(columnResizeState) { const mouseX = React.useRef(0); const currentWidth = React.useRef(0); const colId = React.useRef(undefined); const [dragging, setDragging] = React.useState(false); const { targetDocument } = useFluent(); const { getColumnWidth, setColumnWidth } = columnResizeState; const recalculatePosition = React.useCallback((e)=>{ const { clientX } = getEventClientCoords(e); const dx = clientX - mouseX.current; // Update the local width for the column and set it currentWidth.current += dx; colId.current && setColumnWidth(e, { columnId: colId.current, width: currentWidth.current }); mouseX.current = clientX; }, [ setColumnWidth ]); const [requestRecalcFrame] = useAnimationFrame(); const onDrag = React.useCallback((e)=>{ // Using requestAnimationFrame here drastically improves resizing experience on slower CPUs requestRecalcFrame(()=>recalculatePosition(e)); }, [ requestRecalcFrame, recalculatePosition ]); const onDragEnd = React.useCallback((event)=>{ if (isMouseEvent(event)) { targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.removeEventListener('mouseup', onDragEnd); targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.removeEventListener('mousemove', onDrag); } if (isTouchEvent(event)) { targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.removeEventListener('touchend', onDragEnd); targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.removeEventListener('touchmove', onDrag); } setDragging(false); }, [ onDrag, targetDocument ]); const getOnMouseDown = React.useCallback((columnId)=>(event)=>{ // Keep the width locally so that we decouple the calculation of the next with from rendering. // This makes the whole experience much faster and more precise currentWidth.current = getColumnWidth(columnId); mouseX.current = getEventClientCoords(event).clientX; colId.current = columnId; if (isMouseEvent(event)) { // ignore other buttons than primary mouse button if (event.target !== event.currentTarget || event.button !== 0) { return; } targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.addEventListener('mouseup', onDragEnd); targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.addEventListener('mousemove', onDrag); setDragging(true); } if (isTouchEvent(event)) { targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.addEventListener('touchend', onDragEnd); targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.addEventListener('touchmove', onDrag); setDragging(true); } }, [ getColumnWidth, onDrag, onDragEnd, targetDocument ]); return { getOnMouseDown, dragging }; }