import type { Position } from 'css-box-model'; import type { Viewport, DraggableDimension, DroppableDimension, Scrollable, DroppableDimensionMap, DroppableId, } from '../../types'; import { add } from '../position'; import offsetDraggable from './offset-draggable'; import getFrame from '../get-frame'; interface Args { additions: DraggableDimension[]; updatedDroppables: DroppableDimensionMap; viewport: Viewport; } export default ({ additions, updatedDroppables, viewport, }: Args): DraggableDimension[] => { // We need to adjust collected draggables so that they // match the model we had when the drag started. // When a draggable is dynamically collected it does not have // the same relative client position. We need to unwind // any changes in window scroll and droppable scroll so that // the newly collected draggables fit in with our other draggables // and give the same dimensions that would have had if they were // collected at the start of the drag. // Need to undo the displacement caused by window scroll changes const windowScrollChange: Position = viewport.scroll.diff.value; // These modified droppables have already had their scroll changes correctly updated return additions.map((draggable: DraggableDimension): DraggableDimension => { const droppableId: DroppableId = draggable.descriptor.droppableId; const modified: DroppableDimension = updatedDroppables[droppableId]; const frame: Scrollable = getFrame(modified); const droppableScrollChange: Position = frame.scroll.diff.value; const totalChange: Position = add( windowScrollChange, droppableScrollChange, ); const moved: DraggableDimension = offsetDraggable({ draggable, offset: totalChange, initialWindowScroll: viewport.scroll.initial, }); return moved; }); };