UNPKG

rsuite

Version:

A suite of react components

82 lines (80 loc) 2.3 kB
'use client'; import { useRef, useEffect, useCallback, useState } from 'react'; import PointerMoveTracker from 'dom-lib/PointerMoveTracker'; import addStyle from 'dom-lib/addStyle'; import getWidth from 'dom-lib/getWidth'; import { useEventCallback } from "../internals/hooks/index.js"; const useDrag = props => { const rootRef = useRef(null); const tooltipRef = useRef(null); const { tooltip, disabled, onDragMove, onDragEnd, onDragStart, keepTooltipOpen } = props; const [active, setActive] = useState(false); const moveTracker = useRef(null); // Release the move event const releaseMoves = useCallback(() => { moveTracker.current?.releaseMoves(); moveTracker.current = null; }, []); const setTooltipPosition = useCallback(() => { const tooltipElement = tooltipRef.current; if (tooltip && tooltipElement) { const width = getWidth(tooltipElement); // Set the position of the tooltip addStyle(tooltipElement, '--rs-tooltip-offset', `-${width / 2}px`); } }, [tooltip]); const handleDragMove = useEventCallback((_deltaX, _deltaY, event) => { if (moveTracker.current?.isDragging()) { onDragMove?.(event, rootRef.current?.dataset); setTooltipPosition(); } }); const handleDragEnd = useEventCallback(event => { setActive(false); releaseMoves(); onDragEnd?.(event, rootRef.current?.dataset); }); const getMouseMoveTracker = useCallback(() => { return moveTracker.current || new PointerMoveTracker(document.body, { onMove: handleDragMove, onMoveEnd: handleDragEnd, useTouchEvent: true }); }, [handleDragEnd, handleDragMove]); const onMoveStart = useEventCallback(event => { if (disabled) { return; } moveTracker.current = getMouseMoveTracker(); moveTracker.current?.captureMoves(event); rootRef.current?.focus(); setActive(true); onDragStart?.(event); }); const onMouseEnter = useEventCallback(() => { setTooltipPosition(); }); useEffect(() => { if (keepTooltipOpen) { onMouseEnter(); } return () => { releaseMoves(); }; }, [releaseMoves, keepTooltipOpen]); return { active, rootRef, tooltipRef, onMoveStart, onMouseEnter }; }; export default useDrag;