UNPKG

react-beautiful-dnd

Version:

Beautiful, accessible drag and drop for lists with React.js

82 lines (72 loc) 2.06 kB
// @flow import { type Position } from 'css-box-model'; import type { DragMovement, DraggableDimension, DroppableDimension, DragImpact, Axis, Displacement, Viewport, } from '../../types'; import { patch } from '../position'; import getDisplacement from '../get-displacement'; import withDroppableScroll from '../with-droppable-scroll'; type Args = {| pageBorderBoxCenter: Position, draggable: DraggableDimension, destination: DroppableDimension, insideDestination: DraggableDimension[], previousImpact: DragImpact, viewport: Viewport, |}; export default ({ pageBorderBoxCenter, draggable, destination, insideDestination, previousImpact, viewport, }: Args): DragImpact => { const axis: Axis = destination.axis; // We need to know what point to use to compare to the other // draggables in the list. // To do this we need to consider any displacement caused by // a change in scroll in the droppable we are currently over. const currentCenter: Position = withDroppableScroll( destination, pageBorderBoxCenter, ); const displaced: Displacement[] = insideDestination .filter( (child: DraggableDimension): boolean => { // Items will be displaced forward if they sit ahead of the dragging item const threshold: number = child.page.borderBox[axis.end]; return threshold > currentCenter[axis.line]; }, ) .map( (dimension: DraggableDimension): Displacement => getDisplacement({ draggable: dimension, destination, previousImpact, viewport: viewport.frame, }), ); const newIndex: number = insideDestination.length - displaced.length; const movement: DragMovement = { amount: patch(axis.line, draggable.page.marginBox[axis.size]), displaced, isBeyondStartPosition: false, }; const impact: DragImpact = { movement, direction: axis.direction, destination: { droppableId: destination.descriptor.id, index: newIndex, }, }; return impact; };