import { invariant } from '../../../../invariant'; import type { DraggableDimension, DroppableDimension, DraggableDimensionMap, DragImpact, LiftEffect, Viewport, ImpactLocation, } from '../../../../types'; import calculateReorderImpact from '../../../calculate-drag-impact/calculate-reorder-impact'; import fromCombine from './from-combine'; import fromReorder from './from-reorder'; export interface Args { isMovingForward: boolean; isInHomeList: boolean; draggable: DraggableDimension; draggables: DraggableDimensionMap; destination: DroppableDimension; insideDestination: DraggableDimension[]; previousImpact: DragImpact; viewport: Viewport; afterCritical: LiftEffect; } export default ({ isMovingForward, isInHomeList, draggable, draggables, destination, insideDestination, previousImpact, viewport, afterCritical, }: Args): DragImpact | null => { const wasAt: ImpactLocation | null = previousImpact.at; invariant(wasAt, 'Cannot move in direction without previous impact location'); if (wasAt.type === 'REORDER') { const newIndex: number | null = fromReorder({ isMovingForward, isInHomeList, location: wasAt.destination, insideDestination, }); // TODO: can we just pass new index on? if (newIndex == null) { return null; } return calculateReorderImpact({ draggable, insideDestination, destination, viewport, last: previousImpact.displaced, displacedBy: previousImpact.displacedBy, index: newIndex, }); } // COMBINE const newIndex: number | null = fromCombine({ isMovingForward, destination, displaced: previousImpact.displaced, draggables, combine: wasAt.combine, afterCritical, }); if (newIndex == null) { return null; } return calculateReorderImpact({ draggable, insideDestination, destination, viewport, last: previousImpact.displaced, displacedBy: previousImpact.displacedBy, index: newIndex, }); };