import type { Position, Rect } from 'css-box-model'; import type { DroppableId, DraggableDimension, DroppableDimension, DraggableDimensionMap, DroppableDimensionMap, DragImpact, Viewport, LiftEffect, } from '../../types'; import getDroppableOver from '../get-droppable-over'; import getDraggablesInsideDroppable from '../get-draggables-inside-droppable'; import withDroppableScroll from '../with-scroll-change/with-droppable-scroll'; import getReorderImpact from './get-reorder-impact'; import getCombineImpact from './get-combine-impact'; import noImpact from '../no-impact'; import { offsetRectByPosition } from '../rect'; interface Args { pageOffset: Position; draggable: DraggableDimension; // all dimensions in system draggables: DraggableDimensionMap; droppables: DroppableDimensionMap; previousImpact: DragImpact; viewport: Viewport; afterCritical: LiftEffect; } export default ({ pageOffset, draggable, draggables, droppables, previousImpact, viewport, afterCritical, }: Args): DragImpact => { const pageBorderBox: Rect = offsetRectByPosition( draggable.page.borderBox, pageOffset, ); const destinationId: DroppableId | null = getDroppableOver({ pageBorderBox, draggable, droppables, }); // not dragging over anything if (!destinationId) { // A big design decision was made here to collapse the home list // when not over any list. This yielded the most consistently beautiful experience. return noImpact; } const destination: DroppableDimension = droppables[destinationId]; const insideDestination: DraggableDimension[] = getDraggablesInsideDroppable( destination.descriptor.id, draggables, ); // Where the element actually is now. // Need to take into account the change of scroll in the droppable const pageBorderBoxWithDroppableScroll: Rect = withDroppableScroll( destination, pageBorderBox, ); // checking combine first so we combine before any reordering return ( getCombineImpact({ pageBorderBoxWithDroppableScroll, draggable, previousImpact, destination, insideDestination, afterCritical, }) || getReorderImpact({ pageBorderBoxWithDroppableScroll, draggable, destination, insideDestination, last: previousImpact.displaced, viewport, afterCritical, }) ); };