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.
35 lines
1.5 KiB
35 lines
1.5 KiB
import { useRef, useMemo } from 'react';
|
|
import { invariant } from '@react-dnd/invariant';
|
|
import { useMonitorOutput } from './internal/useMonitorOutput';
|
|
import { useIsomorphicLayoutEffect } from './internal/useIsomorphicLayoutEffect';
|
|
import { useDragSourceMonitor, useDragHandler } from './internal/drag';
|
|
/**
|
|
* useDragSource hook
|
|
* @param sourceSpec The drag source specification *
|
|
*/
|
|
export function useDrag(spec) {
|
|
const specRef = useRef(spec);
|
|
specRef.current = spec;
|
|
// TODO: wire options into createSourceConnector
|
|
invariant(spec.item != null, 'item must be defined');
|
|
invariant(spec.item.type != null, 'item type must be defined');
|
|
const [monitor, connector] = useDragSourceMonitor();
|
|
useDragHandler(specRef, monitor, connector);
|
|
const result = useMonitorOutput(monitor, specRef.current.collect || (() => ({})), () => connector.reconnect());
|
|
const connectDragSource = useMemo(() => connector.hooks.dragSource(), [
|
|
connector,
|
|
]);
|
|
const connectDragPreview = useMemo(() => connector.hooks.dragPreview(), [
|
|
connector,
|
|
]);
|
|
useIsomorphicLayoutEffect(() => {
|
|
connector.dragSourceOptions = specRef.current.options || null;
|
|
connector.reconnect();
|
|
}, [connector]);
|
|
useIsomorphicLayoutEffect(() => {
|
|
connector.dragPreviewOptions = specRef.current.previewOptions || null;
|
|
connector.reconnect();
|
|
}, [connector]);
|
|
return [result, connectDragSource, connectDragPreview];
|
|
}
|