UNPKG

react-beautiful-dnd-next

Version:

Beautiful and accessible drag and drop for lists with React

90 lines (77 loc) 2.27 kB
// @flow import type { Position } from 'css-box-model'; import type { DroppableDimension, DraggableDimension, DraggableDimensionMap, DragImpact, Displacement, Viewport, OnLift, } from '../../types'; import scrollViewport from '../scroll-viewport'; import scrollDroppable from '../droppable/scroll-droppable'; import { add } from '../position'; import getDisplacement from '../get-displacement'; import withNewDisplacement from './with-new-displacement'; type SpeculativeArgs = {| impact: DragImpact, destination: DroppableDimension, viewport: Viewport, draggables: DraggableDimensionMap, maxScrollChange: Position, onLift: OnLift, |}; export default ({ impact, viewport, destination, draggables, maxScrollChange, onLift, }: SpeculativeArgs): DragImpact => { const displaced: Displacement[] = impact.movement.displaced; const scrolledViewport: Viewport = scrollViewport( viewport, add(viewport.scroll.current, maxScrollChange), ); const scrolledDroppable: DroppableDimension = destination.frame ? scrollDroppable( destination, add(destination.frame.scroll.current, maxScrollChange), ) : destination; const updated: Displacement[] = displaced.map((entry: Displacement) => { // already visible: do not need to speculatively increase if (entry.isVisible) { return entry; } const draggable: DraggableDimension = draggables[entry.draggableId]; // check if would be visibly displaced in a scrolled droppable or viewport const withScrolledViewport: Displacement = getDisplacement({ draggable, destination, previousImpact: impact, viewport: scrolledViewport.frame, onLift, forceShouldAnimate: false, }); if (withScrolledViewport.isVisible) { return withScrolledViewport; } const withScrolledDroppable: Displacement = getDisplacement({ draggable, destination: scrolledDroppable, previousImpact: impact, viewport: viewport.frame, onLift, forceShouldAnimate: false, }); if (withScrolledDroppable.isVisible) { return withScrolledDroppable; } // still not visible return entry; }); return withNewDisplacement(impact, updated); };