import { useEffect } from 'octane'; import type { DragDropEventHandlers, Data } from '@dnd-kit/abstract'; import type { Draggable, Droppable, DragDropManager } from '@dnd-kit/dom'; import type { CleanupFunction } from '@dnd-kit/state'; import { subSlot } from '../../internal'; import { useDragDropManager } from './useDragDropManager'; type EventNameOverrides = { beforedragstart: 'onBeforeDragStart' }; type EventHandlerName = T extends keyof EventNameOverrides ? EventNameOverrides[T] : T extends `drag${infer Second}${infer Rest}` ? `onDrag${Uppercase}${Rest}` : `on${Capitalize}`; type Events< T extends Data, U extends Draggable, V extends Droppable, W extends DragDropManager, > = DragDropEventHandlers; export type EventHandlers< T extends Data = Data, U extends Draggable = Draggable, V extends Droppable = Droppable, W extends DragDropManager = DragDropManager, > = { [K in keyof Events as EventHandlerName]: Events[K]; }; export function useDragDropMonitor< T extends Data = Data, U extends Draggable = Draggable, V extends Droppable = Droppable, W extends DragDropManager = DragDropManager, >(handlers: Partial>, slot?: symbol): void { const manager = useDragDropManager(); useEffect( () => { if (!manager) { if (process.env.NODE_ENV !== 'production') { console.warn( 'useDragDropMonitor hook was called outside of a DragDropProvider. ' + 'Make sure your app is wrapped in a DragDropProvider component.', ); } return; } const cleanup = Object.entries(handlers).reduce( (entries, [handlerName, handler]) => { if (handler) { const eventName = handlerName.replace(/^on/, '').toLowerCase() as keyof Events< T, U, V, W >; entries.push(manager.monitor.addEventListener(eventName, handler as any)); } return entries; }, [], ); return () => cleanup.forEach((dispose) => dispose()); }, [manager, handlers], subSlot(slot, 'effect'), ); }