react-beautiful-dnd-next
Version:
Beautiful and accessible drag and drop for lists with React
88 lines (78 loc) • 2.19 kB
JavaScript
// @flow
import getHomeLocation from './get-home-location';
import type {
DraggableDimension,
DroppableDimension,
DraggableDimensionMap,
DragImpact,
Displacement,
DisplacedBy,
Viewport,
DragMovement,
DraggableIdMap,
OnLift,
} from '../types';
import noImpact from './no-impact';
import getDraggablesInsideDroppable from './get-draggables-inside-droppable';
import getDisplacedBy from './get-displaced-by';
import getDisplacementMap from './get-displacement-map';
import getDisplacement from './get-displacement';
type Args = {|
draggable: DraggableDimension,
home: DroppableDimension,
draggables: DraggableDimensionMap,
viewport: Viewport,
|};
type Result = {|
onLift: OnLift,
impact: DragImpact,
|};
export default ({ draggable, home, draggables, viewport }: Args): Result => {
const displacedBy: DisplacedBy = getDisplacedBy(
home.axis,
draggable.displaceBy,
);
const insideHome: DraggableDimension[] = getDraggablesInsideDroppable(
home.descriptor.id,
draggables,
);
const originallyDisplaced: DraggableDimension[] = insideHome.slice(
draggable.descriptor.index + 1,
);
const wasDisplaced: DraggableIdMap = originallyDisplaced.reduce(
(previous: DraggableIdMap, item: DraggableDimension): DraggableIdMap => {
previous[item.descriptor.id] = true;
return previous;
},
{},
);
const onLift: OnLift = {
displacedBy,
wasDisplaced,
};
const displaced: Displacement[] = originallyDisplaced.map(
(dimension: DraggableDimension): Displacement =>
getDisplacement({
draggable: dimension,
destination: home,
previousImpact: noImpact,
viewport: viewport.frame,
// originally we do not want any animation as we want
// everything to be fixed in the same position that
// it started in
forceShouldAnimate: false,
onLift,
}),
);
const movement: DragMovement = {
displaced,
map: getDisplacementMap(displaced),
displacedBy,
};
const impact: DragImpact = {
movement,
destination: getHomeLocation(draggable.descriptor),
merge: null,
};
return { impact, onLift };
};