UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

98 lines (97 loc) 3.95 kB
import * as React from 'react'; import { DROP_ZONE_BASE_ATTRIBUTES } from "./constants.js"; export function useDropZone({ disabled, ref, onDragEnter, onDragOver, onDragLeave, onDrop, }) { const [isDraggingOver, setIsDraggingOver] = React.useState(false); const nestingCounterRef = React.useRef(0); const handleDragEnterNative = React.useCallback((event) => { if (disabled) { return; } nestingCounterRef.current++; const dataTransfer = event.dataTransfer; if (dataTransfer) { dataTransfer.dropEffect = DROP_ZONE_BASE_ATTRIBUTES['aria-dropeffect']; } setIsDraggingOver(true); onDragEnter?.(event); }, [disabled, onDragEnter]); const handleDragEnter = React.useCallback((event) => { handleDragEnterNative(event.nativeEvent); }, [handleDragEnterNative]); const handleDragOverNative = React.useCallback((event) => { if (disabled) { return; } const dataTransfer = event.dataTransfer; if (dataTransfer) { dataTransfer.dropEffect = DROP_ZONE_BASE_ATTRIBUTES['aria-dropeffect']; } event.preventDefault(); onDragOver?.(event); }, [disabled, onDragOver]); const handleDragOver = React.useCallback((event) => { handleDragOverNative(event.nativeEvent); }, [handleDragOverNative]); const handleDragLeaveNative = React.useCallback((event) => { nestingCounterRef.current = Math.max(nestingCounterRef.current - 1, 0); if (nestingCounterRef.current === 0) { setIsDraggingOver(false); } if (disabled) { return; } onDragLeave?.(event); }, [disabled, onDragLeave]); const handleDragLeave = React.useCallback((event) => { handleDragLeaveNative(event.nativeEvent); }, [handleDragLeaveNative]); const handleDropNative = React.useCallback((event) => { setIsDraggingOver(false); nestingCounterRef.current = 0; if (disabled) { return; } event.preventDefault(); onDrop?.(event); }, [disabled, onDrop]); const handleDrop = React.useCallback((event) => { handleDropNative(event.nativeEvent); }, [handleDropNative]); React.useEffect(() => { const dropZoneElement = ref?.current; if (!dropZoneElement) { return undefined; } dropZoneElement.addEventListener('dragenter', handleDragEnterNative); dropZoneElement.addEventListener('dragover', handleDragOverNative); dropZoneElement.addEventListener('dragleave', handleDragLeaveNative); dropZoneElement.addEventListener('drop', handleDropNative); for (const [attribute, value] of Object.entries(DROP_ZONE_BASE_ATTRIBUTES)) { dropZoneElement.setAttribute(attribute, value.toString()); } return () => { dropZoneElement.removeEventListener('dragenter', handleDragEnterNative); dropZoneElement.removeEventListener('dragover', handleDragOverNative); dropZoneElement.removeEventListener('dragleave', handleDragLeaveNative); dropZoneElement.removeEventListener('drop', handleDropNative); }; }, [handleDragEnterNative, handleDragLeaveNative, handleDragOverNative, handleDropNative, ref]); const droppableProps = React.useMemo(() => ({ ...DROP_ZONE_BASE_ATTRIBUTES, onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, }), [handleDragEnter, handleDragOver, handleDragLeave, handleDrop]); const getDroppableProps = React.useCallback(() => droppableProps, [droppableProps]); if (ref) { return { isDraggingOver, }; } return { isDraggingOver, getDroppableProps, }; } //# sourceMappingURL=useDropZone.js.map