UNPKG

@adaptabletools/adaptable-cjs

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

97 lines (96 loc) 3.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); function clamp(num, min, max) { return num <= min ? min : num >= max ? max : num; } function useDraggable({ onMove, onDrop, getBoundingRect = () => document.body.getBoundingClientRect(), handleSelector, }) { const startRef = (0, react_1.useRef)(null); const handleRef = (0, react_1.useRef)(null); const targetRef = (0, react_1.useRef)(null); const handleRefCallback = (0, react_1.useCallback)((newNode) => { const oldNode = handleRef.current; if (oldNode) { oldNode.removeEventListener('mousedown', handleMouseDown); } if (newNode) { newNode.addEventListener('mousedown', handleMouseDown); boundInitialPosition(); } handleRef.current = newNode; }, []); (0, react_1.useEffect)(() => { if (handleSelector) { /** * Element may not be yet attached. * This gives time react to render the node handle. */ setTimeout(() => { const node = targetRef?.current?.querySelector(handleSelector); node && handleRefCallback(node); }, 16); } }, [handleSelector]); const applyTransform = (dx, dy) => { if (!targetRef.current) return; targetRef.current.style.transform = `translate3d(${dx}px, ${dy}px, 0)`; }; const getTranslation = (event) => { if (!startRef.current) return { dx: 0, dy: 0 }; const { pageX, pageY, bounds } = startRef.current; return { dx: clamp(event.pageX - pageX, bounds.left, bounds.right), dy: clamp(event.pageY - pageY, bounds.top, bounds.bottom), }; }; const getTranslationBounds = (targetRect, boundingRect) => { const left = boundingRect.x - targetRect.x; const right = left + boundingRect.width - targetRect.width; const top = boundingRect.y - targetRect.y; const bottom = top + boundingRect.height - targetRect.height; return { left, right, top, bottom }; }; const handleMouseDown = (event) => { if (!targetRef.current) return; event.preventDefault(); document.addEventListener('mouseup', handleMouseUp); document.addEventListener('mousemove', handleMouseMove); const targetRect = targetRef.current.getBoundingClientRect(); const boundingRect = getBoundingRect(); startRef.current = { pageX: event.pageX, pageY: event.pageY, bounds: getTranslationBounds(targetRect, boundingRect), }; }; const handleMouseUp = (event) => { event.preventDefault(); document.removeEventListener('mouseup', handleMouseUp); document.removeEventListener('mousemove', handleMouseMove); const { dx, dy } = getTranslation(event); applyTransform(0, 0); onDrop && onDrop(dx, dy); }; const handleMouseMove = (event) => { event.preventDefault(); const { dx, dy } = getTranslation(event); applyTransform(dx, dy); onMove && onMove(event); }; const boundInitialPosition = () => { if (!targetRef.current) return; const targetRect = targetRef.current.getBoundingClientRect(); const boundingRect = getBoundingRect(); const bounds = getTranslationBounds(targetRect, boundingRect); const dx = clamp(0, bounds.left, bounds.right); const dy = clamp(0, bounds.top, bounds.bottom); if (onDrop && (dx !== 0 || dy !== 0)) onDrop(dx, dy); }; return { handleRef: handleRefCallback, targetRef, applyTransform }; } exports.default = useDraggable;