The key
for a drop target is the element. At any one time, only a single drop target for a
particular entity type (eg files) can be attached to the same element.
// ✅ Using the same element as a drop target for elements and for files
const cleanup = combine(
dropTargetForElements({
element: myElement,
}),
dropTargetForExternal({
element: myElement,
}),
);
// ❌ Using the same element for two drop targets of the same entity type is not allowed
const cleanup = combine(
dropTargetForElements({
element: myElement,
}),
// ⚠️ A warning will be logged if this is detected
dropTargetForElements({
element: myElement,
}),
);
During a drag operation, if a drop target is removed and readded on the same element
, then
@atlaskit/pragmatic-drag-and-drop
will treat the added drop target as if it was the same drop
target.
const monitor = monitorForElements({
onDragStart: () => console.log('monitor:start'),
onDropTargetChange: () => console.log('monitor:change'),
onDrop: () => console.log('monitor:drop'),
});
const cleanup1 = dropTargetForElements({
element: A,
onDragStart: () => console.log('A1:start'),
onDropTargetChange: () => console.log('A1:change'),
onDrop: () => console.log('A1:drop'),
});
// a drag starts
// console.log → 'A1:start', 'monitor:start'
// drop target is removed during a drag
cleanup1();
// console.log not called (no change event is fired)
const cleanup2 = dropTargetForElements({
element: A,
onDragStart: () => console.log('A2:start'),
onDropTargetChange: () => console.log('A2:change'),
onDrop: () => console.log('A2:drop'),
});
// a dragover occurs
// console.log → 'A2:drag', 'monitor:drag'
// 👆 note: no 'change' event occured, A2 is treated as A1
The key
for a draggable
is the element. An element can only be used for a single draggable
.
// ❌ Using the same element for two draggables
draggable({
element: myElement,
}),
// ⚠️ A warning will be logged if this is detected
draggable({
element: myElement,
}),
);
During a drag operation, if the dragging draggable
is removed and readded on the same element
,
then @atlaskit/pragmatic-drag-and-drop
will treat the added draggable
as if it was the original
draggable
.
const monitor = monitorForElements({
onDragStart: () => console.log('monitor:start'),
onDrop: () => console.log('monitor:drop'),
});
const cleanup1 = draggable({
element: A,
onDragStart: () => console.log('A1:start'),
onDrop: () => console.log('A1:drop'),
});
// a drag starts
// console.log → 'A1:start', 'monitor:start'
// drop target is removed during a drag
cleanup1();
// console.log not called (no change event is fired)
const cleanup2 = dropTargetForElements({
element: A,
onDragStart: () => console.log('A2:start'),
onDrop: () => console.log('A2:drop'),
});
// a drop occurs
// console.log → 'A2:drop', 'monitor:drop'
// 👆 note: the drop event occured on 'A2' even though it was not the same `draggable()` as the original drag
Remounting a draggable
common in react
where you might do something like this:
function Card() {
const ref = useRef();
const [dragCount, setCount] = useState(0);
useEffect(() => {
return draggable({
element,
onDragStart: () => setCount(dragCount + 1),
});
// when dragCount changes our `draggable` will be remounted
}, [dragCount]);
return <div ref={ref}>I have been dragged {dragCount} times</div>;
}
This is a contrived example, because you could avoid the remounting in this case by doing this:
function Card() {
const ref = useRef();
const [dragCount, setCount] = useState(0);
useEffect(() => {
return draggable({
element,
onDragStart: () => setCount((current) => current + 1),
});
// no longer need to remount when `dragCount` changes
}, []);
return <div ref={ref}>I have been dragged {dragCount} times</div>;
}
Each call to create a monitor will create a new monitor, even if the monitor definition is shared.
There is no key
for monitors.
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
const args = {
onGenerateDragPreview: () => console.log('monitor:preview'),
};
// these two monitors are sharing the same `args` reference
// but they will both create an independent monitor
const cleanup1 = monitorForElements(args);
const cleanup2 = monitorForElements(args);
// → A drag starts
// console.log:
// - 'monitor:preview'
// - 'monitor:preview'
// → A drag finishes
// removing one monitor
cleanup1();
// → Another drag starts
// console.log:
// - 'monitor:preview'
// 👆 one monitor is still active