@hello-pangea/dnd
Version:
Beautiful and accessible drag and drop for lists with React
60 lines (47 loc) • 1.98 kB
text/typescript
import type { Spacing } from 'css-box-model';
import isWithin from '../is-within';
export default (frame: Spacing) => {
const isWithinVertical = isWithin(frame.top, frame.bottom);
const isWithinHorizontal = isWithin(frame.left, frame.right);
return (subject: Spacing) => {
// situations where target is visible:
// 1. is completely contained within frame
// 2. is partially visible on both axis within frame
// 3. is bigger than frame on both axis
// 4. is bigger than frame on one axis and is partially visible on the other
// completely contained
const isContained: boolean =
isWithinVertical(subject.top) &&
isWithinVertical(subject.bottom) &&
isWithinHorizontal(subject.left) &&
isWithinHorizontal(subject.right);
if (isContained) {
return true;
}
const isPartiallyVisibleVertically: boolean =
isWithinVertical(subject.top) || isWithinVertical(subject.bottom);
const isPartiallyVisibleHorizontally: boolean =
isWithinHorizontal(subject.left) || isWithinHorizontal(subject.right);
// partially visible on both axis
const isPartiallyContained: boolean =
isPartiallyVisibleVertically && isPartiallyVisibleHorizontally;
if (isPartiallyContained) {
return true;
}
const isBiggerVertically: boolean =
subject.top < frame.top && subject.bottom > frame.bottom;
const isBiggerHorizontally: boolean =
subject.left < frame.left && subject.right > frame.right;
// is bigger than frame on both axis
const isTargetBiggerThanFrame: boolean =
isBiggerVertically && isBiggerHorizontally;
if (isTargetBiggerThanFrame) {
return true;
}
// is bigger on one axis, and partially visible on another
const isTargetBiggerOnOneAxis: boolean =
(isBiggerVertically && isPartiallyVisibleHorizontally) ||
(isBiggerHorizontally && isPartiallyVisibleVertically);
return isTargetBiggerOnOneAxis;
};
};