UNPKG

react-beautiful-dnd-next

Version:

Beautiful and accessible drag and drop for lists with React

78 lines (67 loc) 1.98 kB
// @flow import memoizeOne from 'memoize-one'; import invariant from 'tiny-invariant'; import { type Position } from 'css-box-model'; import type { DroppableDimension, DroppableDimensionMap, DroppableId, } from '../../../types'; import isPositionInFrame from '../../visibility/is-position-in-frame'; import { toDroppableList } from '../../dimension-structures'; import { find } from '../../../native-with-fallback'; const getScrollableDroppables = memoizeOne( (droppables: DroppableDimensionMap): DroppableDimension[] => toDroppableList(droppables).filter( (droppable: DroppableDimension): boolean => { // exclude disabled droppables if (!droppable.isEnabled) { return false; } // only want droppables that are scrollable if (!droppable.frame) { return false; } return true; }, ), ); const getScrollableDroppableOver = ( target: Position, droppables: DroppableDimensionMap, ): ?DroppableDimension => { const maybe: ?DroppableDimension = find( getScrollableDroppables(droppables), (droppable: DroppableDimension): boolean => { invariant(droppable.frame, 'Invalid result'); return isPositionInFrame(droppable.frame.pageMarginBox)(target); }, ); return maybe; }; type Api = {| center: Position, destination: ?DroppableId, droppables: DroppableDimensionMap, |}; export default ({ center, destination, droppables, }: Api): ?DroppableDimension => { // We need to scroll the best droppable frame we can so that the // placeholder buffer logic works correctly if (destination) { const dimension: DroppableDimension = droppables[destination]; if (!dimension.frame) { return null; } return dimension; } // 2. If we are not over a droppable - are we over a droppable frame? const dimension: ?DroppableDimension = getScrollableDroppableOver( center, droppables, ); return dimension; };