You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
2.4 KiB

import { useMemo } from 'react';
import { invariant } from '@react-dnd/invariant';
import { registerSource } from '../../common/registration';
import { useDragDropManager } from './useDragDropManager';
import { DragSourceMonitorImpl } from '../../common/DragSourceMonitorImpl';
import { SourceConnector } from '../../common/SourceConnector';
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
export function useDragSourceMonitor() {
const manager = useDragDropManager();
const monitor = useMemo(() => new DragSourceMonitorImpl(manager), [manager]);
const connector = useMemo(() => new SourceConnector(manager.getBackend()), [
manager,
]);
return [monitor, connector];
}
export function useDragHandler(spec, monitor, connector) {
const manager = useDragDropManager();
const handler = useMemo(() => {
return {
beginDrag() {
const { begin, item } = spec.current;
if (begin) {
const beginResult = begin(monitor);
invariant(beginResult == null || typeof beginResult === 'object', 'dragSpec.begin() must either return an object, undefined, or null');
return beginResult || item || {};
}
return item || {};
},
canDrag() {
if (typeof spec.current.canDrag === 'boolean') {
return spec.current.canDrag;
}
else if (typeof spec.current.canDrag === 'function') {
return spec.current.canDrag(monitor);
}
else {
return true;
}
},
isDragging(globalMonitor, target) {
const { isDragging } = spec.current;
return isDragging
? isDragging(monitor)
: target === globalMonitor.getSourceId();
},
endDrag() {
const { end } = spec.current;
if (end) {
end(monitor.getItem(), monitor);
}
connector.reconnect();
},
};
}, []);
useIsomorphicLayoutEffect(function registerHandler() {
const [handlerId, unregister] = registerSource(spec.current.item.type, handler, manager);
monitor.receiveHandlerId(handlerId);
connector.receiveHandlerId(handlerId);
return unregister;
}, []);
}