UNPKG

@zohodesk/dot

Version:

In this Library, we Provide Some Basic Components to Build Your Application

124 lines (114 loc) 3.9 kB
//Hooks from React import { useEffect, useRef, useCallback } from 'react'; //CustomFunction import { DragPosCalc } from "./utils/DraggerUtil"; //GlobalConfig import { getDotLibraryConfig } from "../../Provider/Config"; //Props import defaultProps from "./props/defaultProps"; import propTypes from "./props/propTypes"; //CSS import style from "./css/Dragger.module.css"; export default function useDragger(_ref) { let { isActive, ChildRef, boundaryLimit = getDotLibraryConfig('boundaryLimit') } = _ref; const draggableEle = useRef(null); const parentEle = useRef(null); const offset = useRef({ x: 0, y: 0 }); const draggable = useRef(false); useEffect(() => { if (isActive) { parentEle.current = ChildRef.current.closest('[data-drag-parent=true]') || getDotLibraryConfig('draggerBoundary') || document.body; } }, [isActive]); //calculateDragPosition --> To sperate Dom action const calculateDragPosition = useCallback((x, y) => { if (parentEle.current && draggableEle.current) { return DragPosCalc({ x, y, dragWrapper: parentEle.current, element: draggableEle.current, boundaryLimit }); } else { return { x, y }; } }, []); const elementDrag = useCallback(e => { e = e || window.event; e.preventDefault(); if (draggable.current) { const left = offset.current.x + e.clientX; const top = offset.current.y + e.clientY; const { x, y } = calculateDragPosition(left, top); draggableEle.current.style.left = x + 'px'; draggableEle.current.style.top = y + 'px'; } }, [calculateDragPosition]); const closeDragElement = useCallback(() => { document.removeEventListener('mouseup', closeDragElement); document.removeEventListener('mousemove', elementDrag); }, []); const dragMouseDown = useCallback(e => { e = e || window.event; // e.preventDefault(); const draggableEleRect = draggableEle.current.getBoundingClientRect(); const style = draggableEle.current.style; const { width } = draggableEleRect; const parentEleRect = parentEle ? parentEle.current.getBoundingClientRect() : { left: 0, top: 0 }; const relativeRect = { left: draggableEleRect.left - parentEleRect.left, top: draggableEleRect.top - parentEleRect.top }; const { top, left } = relativeRect; style.top = `${top}px`; style.left = `${left}px`; style.width = `${width}px`; style.bottom = 'initial'; style.right = 'initial'; style.position = 'fixed'; offset.current.x = draggableEle.current.offsetLeft - e.clientX; offset.current.y = draggableEle.current.offsetTop - e.clientY; draggable.current = true; document.addEventListener('mouseup', closeDragElement); document.addEventListener('mousemove', elementDrag); }, []); const removeListener = useCallback(draggableEle => { let dragController = draggableEle.current && draggableEle.current.querySelector('[data-drag-hook=true]'); if (dragController) { dragController.removeEventListener('mousedown', dragMouseDown); draggableEle.current = null; } }, []); useEffect(() => { if (isActive) { draggableEle.current = ChildRef.current.closest('[data-drag-container=true]'); let dragController = draggableEle.current && draggableEle.current.querySelector('[data-drag-hook=true]'); dragController && dragController.addEventListener('mousedown', dragMouseDown); dragController && dragController.classList.add(style.dragCursor); } else { removeListener(draggableEle); } return () => { removeListener(draggableEle); }; }, [ChildRef.current, isActive]); return null; } //Props useDragger.propTypes = propTypes; useDragger.defaultProps = defaultProps;