react-beautiful-dnd
Version:
Beautiful, accessible drag and drop for lists with React.js
63 lines (53 loc) • 1.9 kB
JavaScript
// @flow
import { absolute, add, patch, subtract } from './position';
import type {
Axis,
Position,
Area,
} from '../types';
export type Edge = 'start' | 'end';
type Args = {|
source: Area,
sourceEdge: Edge,
destination: Area,
destinationEdge: Edge,
destinationAxis: Axis,
|}
// Being clear that this function returns the new center position
type CenterPosition = Position;
// This function will return the center position required to move
// a draggable to the edge of a dimension fragment (could be a droppable or draggable).
// The center position will be aligned to the axis.crossAxisStart value rather than
// the center position of the destination. This allows for generally a better
// experience when moving between lists of different cross axis size.
// The size difference can be caused by the presence or absence of scroll bars
export default ({
source,
sourceEdge,
destination,
destinationEdge,
destinationAxis,
}: Args): CenterPosition => {
const getCorner = (area: Area): Position => patch(
destinationAxis.line,
// it does not really matter what edge we use here
// as the difference to the center from edges will be the same
area[destinationAxis[destinationEdge]],
area[destinationAxis.crossAxisStart]
);
// 1. Find the intersection corner point
// 2. add the difference between that point and the center of the dimension
const corner: Position = getCorner(destination);
// the difference between the center of the draggable and its corner
const centerDiff = absolute(subtract(
source.center,
getCorner(source)
));
const signed: Position = patch(
destinationAxis.line,
// if moving to the end edge - we need to pull the source backwards
(sourceEdge === 'end' ? -1 : 1) * centerDiff[destinationAxis.line],
centerDiff[destinationAxis.crossAxisLine],
);
return add(corner, signed);
};