framer-motion
Version:
A simple and powerful JavaScript animation library
61 lines (58 loc) • 2.42 kB
JavaScript
import { Feature, VisualElementDragControls } from 'motion-dom';
import { noop } from 'motion-utils';
class DragGesture extends Feature {
constructor(node) {
super(node);
this.removeGroupControls = noop;
this.removeListeners = noop;
this.controls = new VisualElementDragControls(node);
}
mount() {
// If we've been provided a DragControls for manual control over the drag gesture,
// subscribe this component to it on mount.
const { dragControls } = this.node.getProps();
if (dragControls) {
this.removeGroupControls = dragControls.subscribe(this.controls);
}
this.removeListeners = this.controls.addListeners() || noop;
}
update() {
const { dragControls, drag } = this.node.getProps();
const { dragControls: prevDragControls, drag: prevDrag } = this.node.prevProps || {};
if (dragControls !== prevDragControls) {
this.removeGroupControls();
if (dragControls) {
this.removeGroupControls = dragControls.subscribe(this.controls);
}
}
/**
* If drag is disabled mid-gesture, for instance from onDrag, end the
* gesture as if released. This must happen before this render's
* layout change is processed, otherwise the element is still
* animation-blocked, so it jumps to its new layout and keeps that
* jump as a drag offset, which release wouldn't animate away as
* drag is now disabled.
*/
if (prevDrag && !drag)
this.controls.stop(undefined, undefined, prevDrag);
}
unmount() {
this.removeGroupControls();
this.removeListeners();
/**
* In React 19, during list reorder reconciliation, components may
* briefly unmount and remount while the drag is still active. If we're
* actively dragging, we should NOT end the pan session - it will
* continue tracking pointer events via its window-level listeners.
*
* The pan session will be properly cleaned up when:
* 1. The drag ends naturally (pointerup/pointercancel)
* 2. The component is truly removed from the DOM
*/
if (!this.controls.isDragging) {
this.controls.endPanSession();
}
}
}
export { DragGesture };
//# sourceMappingURL=index.mjs.map