UNPKG

react-beautiful-dnd-next

Version:

Beautiful and accessible drag and drop for lists with React

114 lines (100 loc) 2.77 kB
// @flow import invariant from 'tiny-invariant'; import type { DraggableDimension, DroppableDimension, DraggableDimensionMap, DragImpact, DisplacedBy, Displacement, OnLift, } from '../../../../types'; import type { Instruction } from './move-to-next-index-types'; import getDisplacementMap from '../../../get-displacement-map'; import { addClosest, removeClosest } from '../update-displacement'; import getDisplacedBy from '../../../get-displaced-by'; import fromReorder from './from-reorder'; import fromCombine from './from-combine'; import removeDraggableFromList from '../../../remove-draggable-from-list'; export type Args = {| isMovingForward: boolean, isInHomeList: boolean, draggable: DraggableDimension, draggables: DraggableDimensionMap, destination: DroppableDimension, insideDestination: DraggableDimension[], previousImpact: DragImpact, onLift: OnLift, |}; export default ({ isMovingForward, isInHomeList, draggable, draggables, destination, insideDestination, previousImpact, onLift, }: Args): ?DragImpact => { const instruction: ?Instruction = (() => { // moving from reorder if (previousImpact.destination) { return fromReorder({ isMovingForward, isInHomeList, draggable, location: previousImpact.destination, insideDestination, }); } // moving from merge if (previousImpact.merge) { return fromCombine({ isMovingForward, destination, previousImpact, draggables, merge: previousImpact.merge, onLift, }); } invariant('Cannot move to next spot without a destination or merge'); return null; })(); if (instruction == null) { return null; } const { proposedIndex, modifyDisplacement } = instruction; const displacedBy: DisplacedBy = getDisplacedBy( destination.axis, draggable.displaceBy, ); const displaced: Displacement[] = (() => { const lastDisplaced: Displacement[] = previousImpact.movement.displaced; if (!modifyDisplacement) { return lastDisplaced; } if (isMovingForward) { return removeClosest(lastDisplaced); } // moving backwards - will increase the amount of displaced items const withoutDraggable: DraggableDimension[] = removeDraggableFromList( draggable, insideDestination, ); const atProposedIndex: DraggableDimension = withoutDraggable[proposedIndex]; return addClosest(atProposedIndex, lastDisplaced); })(); return { movement: { displacedBy, displaced, map: getDisplacementMap(displaced), }, destination: { droppableId: destination.descriptor.id, index: proposedIndex, }, merge: null, }; };