import { invariant } from '../invariant'; import getHomeLocation from './get-home-location'; import type { DraggableDimension, DroppableDimension, DraggableDimensionMap, DragImpact, DisplacedBy, Viewport, DraggableIdMap, DisplacementGroups, LiftEffect, } from '../types'; import getDraggablesInsideDroppable from './get-draggables-inside-droppable'; import getDisplacedBy from './get-displaced-by'; import getDisplacementGroups from './get-displacement-groups'; interface Args { draggable: DraggableDimension; home: DroppableDimension; draggables: DraggableDimensionMap; viewport: Viewport; } interface Result { afterCritical: LiftEffect; 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, ); // in a list that does not start at 0 the descriptor.index might be different from the index in the list // eg a list could be: [2,3,4]. A descriptor.index of '2' would actually be in index '0' of the list const rawIndex: number = insideHome.indexOf(draggable); invariant(rawIndex !== -1, 'Expected draggable to be inside home list'); const afterDragging: DraggableDimension[] = insideHome.slice(rawIndex + 1); const effected: DraggableIdMap = afterDragging.reduce( (previous: DraggableIdMap, item: DraggableDimension): DraggableIdMap => { previous[item.descriptor.id] = true; return previous; }, {}, ); const afterCritical: LiftEffect = { inVirtualList: home.descriptor.mode === 'virtual', displacedBy, effected, }; const displaced: DisplacementGroups = getDisplacementGroups({ afterDragging, destination: home, displacedBy, last: null, 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, }); const impact: DragImpact = { displaced, displacedBy, at: { type: 'REORDER', destination: getHomeLocation(draggable.descriptor), }, }; return { impact, afterCritical }; };