import { useEffect } from 'react'; import type { MutableRefObject } from 'react'; import { isTagTransferEvent, getActiveDragState, } from '../features/tagging/tagTransfer'; interface UseWorkspaceDragDropArgs { shellRef: MutableRefObject; } const useWorkspaceDragDrop = ({ shellRef, }: UseWorkspaceDragDropArgs) => { useEffect(() => { const host = shellRef.current; if (!host) { return; } // Allow drop on workspace (global app shell) const handleTagDragOver = (event: DragEvent) => { if (!isTagTransferEvent(event)) { return; } const { sourceDocId } = getActiveDragState(); // Only allow "Move" (removal) if the tag came from a document if (sourceDocId) { event.preventDefault(); // Necessary to allow dropping if (event.dataTransfer) { event.dataTransfer.dropEffect = 'move'; } } }; const handleTagDragEnter = (event: DragEvent) => { if (!isTagTransferEvent(event)) { return; } const { sourceDocId } = getActiveDragState(); if (sourceDocId) { event.preventDefault(); if (event.dataTransfer) { event.dataTransfer.dropEffect = 'move'; } } }; const handleTagDrop = (event: DragEvent) => { if (!isTagTransferEvent(event)) { return; } const { sourceDocId } = getActiveDragState(); if (sourceDocId) { // Consume the event so the browser reports 'move' back to the source event.preventDefault(); } }; // Use bubbling (false) so children can stopPropagation host.addEventListener('dragenter', handleTagDragEnter, false); host.addEventListener('dragover', handleTagDragOver, false); host.addEventListener('drop', handleTagDrop, false); return () => { host.removeEventListener('dragenter', handleTagDragEnter, false); host.removeEventListener('dragover', handleTagDragOver, false); host.removeEventListener('drop', handleTagDrop, false); }; }, [shellRef]); return {}; }; export default useWorkspaceDragDrop;