@hello-pangea/dnd
Version:
Beautiful and accessible drag and drop for lists with React
77 lines (67 loc) • 1.72 kB
text/typescript
import type {
DropReason,
DragImpact,
Viewport,
DroppableDimension,
DraggableDimensionMap,
LiftEffect,
} from '../../../types';
import recompute from '../../update-displacement-visibility/recompute';
import { emptyGroups } from '../../no-impact';
interface Args {
draggables: DraggableDimensionMap;
home: DroppableDimension;
reason: DropReason;
lastImpact: DragImpact;
onLiftImpact: DragImpact;
viewport: Viewport;
afterCritical: LiftEffect;
}
export interface Result {
impact: DragImpact;
didDropInsideDroppable: boolean;
}
export default ({
draggables,
reason,
lastImpact,
home,
viewport,
onLiftImpact,
}: Args): Result => {
if (!lastImpact.at || reason !== 'DROP') {
// Dropping outside of a list or the drag was cancelled
// Going to use the on lift impact
// Need to recompute the visibility of the original impact
// What is visible can be different to when the drag started
const recomputedHomeImpact: DragImpact = recompute({
draggables,
impact: onLiftImpact,
destination: home,
viewport,
// We need the draggables to animate back to their positions
forceShouldAnimate: true,
});
return {
impact: recomputedHomeImpact,
didDropInsideDroppable: false,
};
}
// use the existing impact
if (lastImpact.at.type === 'REORDER') {
return {
impact: lastImpact,
didDropInsideDroppable: true,
};
}
// When merging we remove the movement so that everything
// will animate closed
const withoutMovement: DragImpact = {
...lastImpact,
displaced: emptyGroups,
};
return {
impact: withoutMovement,
didDropInsideDroppable: true,
};
};