@hello-pangea/dnd
Version:
Beautiful and accessible drag and drop for lists with React
86 lines (80 loc) • 2.04 kB
text/typescript
import { invariant } from '../../../../invariant';
import type {
DraggableDimension,
DroppableDimension,
DraggableDimensionMap,
DragImpact,
LiftEffect,
Viewport,
ImpactLocation,
} from '../../../../types';
import calculateReorderImpact from '../../../calculate-drag-impact/calculate-reorder-impact';
import fromCombine from './from-combine';
import fromReorder from './from-reorder';
export interface Args {
isMovingForward: boolean;
isInHomeList: boolean;
draggable: DraggableDimension;
draggables: DraggableDimensionMap;
destination: DroppableDimension;
insideDestination: DraggableDimension[];
previousImpact: DragImpact;
viewport: Viewport;
afterCritical: LiftEffect;
}
export default ({
isMovingForward,
isInHomeList,
draggable,
draggables,
destination,
insideDestination,
previousImpact,
viewport,
afterCritical,
}: Args): DragImpact | null => {
const wasAt: ImpactLocation | null = previousImpact.at;
invariant(wasAt, 'Cannot move in direction without previous impact location');
if (wasAt.type === 'REORDER') {
const newIndex: number | null = fromReorder({
isMovingForward,
isInHomeList,
location: wasAt.destination,
insideDestination,
});
// TODO: can we just pass new index on?
if (newIndex == null) {
return null;
}
return calculateReorderImpact({
draggable,
insideDestination,
destination,
viewport,
last: previousImpact.displaced,
displacedBy: previousImpact.displacedBy,
index: newIndex,
});
}
// COMBINE
const newIndex: number | null = fromCombine({
isMovingForward,
destination,
displaced: previousImpact.displaced,
draggables,
combine: wasAt.combine,
afterCritical,
});
if (newIndex == null) {
return null;
}
return calculateReorderImpact({
draggable,
insideDestination,
destination,
viewport,
last: previousImpact.displaced,
displacedBy: previousImpact.displacedBy,
index: newIndex,
});
};