@hello-pangea/dnd
Version:
Beautiful and accessible drag and drop for lists with React
52 lines (47 loc) • 1.55 kB
text/typescript
import type { Position, Rect, Spacing } from 'css-box-model';
import { subtract } from '../../position';
import { offsetByPosition } from '../../spacing';
import {
isTotallyVisible,
isTotallyVisibleOnAxis,
} from '../../visibility/is-visible';
import type { Args as IsVisibleArgs } from '../../visibility/is-visible';
import type { DraggableDimension, DroppableDimension } from '../../../types';
interface Args {
draggable: DraggableDimension;
destination: DroppableDimension;
newPageBorderBoxCenter: Position;
viewport: Rect;
// only allowing a 'false' value. Being super clear
withDroppableDisplacement: false;
onlyOnMainAxis?: boolean;
}
export default ({
draggable,
destination,
newPageBorderBoxCenter,
viewport,
withDroppableDisplacement,
onlyOnMainAxis = false,
}: Args): boolean => {
// What would the location of the Draggable be once the move is completed?
// We are not considering margins for this calculation.
// This is because a move might move a Draggable slightly outside of the bounds
// of a Droppable (which is okay)
const changeNeeded: Position = subtract(
newPageBorderBoxCenter,
draggable.page.borderBox.center,
);
const shifted: Spacing = offsetByPosition(
draggable.page.borderBox,
changeNeeded,
);
// Must be totally visible, not just partially visible.
const args: IsVisibleArgs = {
target: shifted,
destination,
withDroppableDisplacement,
viewport,
};
return onlyOnMainAxis ? isTotallyVisibleOnAxis(args) : isTotallyVisible(args);
};