react-beautiful-dnd
Version:
Beautiful, accessible drag and drop for lists with React.js
1,651 lines (1,450 loc) • 183 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var _extends = _interopDefault(require('@babel/runtime-corejs2/helpers/extends'));
var invariant = _interopDefault(require('tiny-invariant'));
var cssBoxModel = require('css-box-model');
var _Object$keys = _interopDefault(require('@babel/runtime-corejs2/core-js/object/keys'));
var memoizeOne = _interopDefault(require('memoize-one'));
var redux = require('redux');
var _Object$assign = _interopDefault(require('@babel/runtime-corejs2/core-js/object/assign'));
var rafSchd = _interopDefault(require('raf-schd'));
var _inheritsLoose = _interopDefault(require('@babel/runtime-corejs2/helpers/inheritsLoose'));
var React = require('react');
var React__default = _interopDefault(React);
var PropTypes = _interopDefault(require('prop-types'));
var reactRedux = require('react-redux');
var reactMotion = require('react-motion');
var vertical = {
direction: 'vertical',
line: 'y',
crossAxisLine: 'x',
start: 'top',
end: 'bottom',
size: 'height',
crossAxisStart: 'left',
crossAxisEnd: 'right',
crossAxisSize: 'width'
};
var horizontal = {
direction: 'horizontal',
line: 'x',
crossAxisLine: 'y',
start: 'left',
end: 'right',
size: 'width',
crossAxisStart: 'top',
crossAxisEnd: 'bottom',
crossAxisSize: 'height'
};
var origin = {
x: 0,
y: 0
};
var add = function add(point1, point2) {
return {
x: point1.x + point2.x,
y: point1.y + point2.y
};
};
var subtract = function subtract(point1, point2) {
return {
x: point1.x - point2.x,
y: point1.y - point2.y
};
};
var isEqual = function isEqual(point1, point2) {
return point1.x === point2.x && point1.y === point2.y;
};
var negate = function negate(point) {
return {
x: point.x !== 0 ? -point.x : 0,
y: point.y !== 0 ? -point.y : 0
};
};
var absolute = function absolute(point) {
return {
x: Math.abs(point.x),
y: Math.abs(point.y)
};
};
var patch = function patch(line, value, otherValue) {
var _ref;
if (otherValue === void 0) {
otherValue = 0;
}
return _ref = {}, _ref[line] = value, _ref[line === 'x' ? 'y' : 'x'] = otherValue, _ref;
};
var distance = function distance(point1, point2) {
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
};
var closest = function closest(target, points) {
return Math.min.apply(Math, points.map(function (point) {
return distance(target, point);
}));
};
var apply = function apply(fn) {
return function (point) {
return {
x: fn(point.x),
y: fn(point.y)
};
};
};
var offsetByPosition = function offsetByPosition(spacing, point) {
return {
top: spacing.top + point.y,
left: spacing.left + point.x,
bottom: spacing.bottom + point.y,
right: spacing.right + point.x
};
};
var expandByPosition = function expandByPosition(spacing, position) {
return {
top: spacing.top - position.y,
left: spacing.left - position.x,
right: spacing.right + position.x,
bottom: spacing.bottom + position.y
};
};
var getCorners = function getCorners(spacing) {
return [{
x: spacing.left,
y: spacing.top
}, {
x: spacing.right,
y: spacing.top
}, {
x: spacing.left,
y: spacing.bottom
}, {
x: spacing.right,
y: spacing.bottom
}];
};
var getMaxScroll = (function (_ref) {
var scrollHeight = _ref.scrollHeight,
scrollWidth = _ref.scrollWidth,
height = _ref.height,
width = _ref.width;
var maxScroll = subtract({
x: scrollWidth,
y: scrollHeight
}, {
x: width,
y: height
});
var adjustedMaxScroll = {
x: Math.max(0, maxScroll.x),
y: Math.max(0, maxScroll.y)
};
return adjustedMaxScroll;
});
var clip = function clip(frame, subject) {
var result = cssBoxModel.getRect({
top: Math.max(subject.top, frame.top),
right: Math.min(subject.right, frame.right),
bottom: Math.min(subject.bottom, frame.bottom),
left: Math.max(subject.left, frame.left)
});
if (result.width <= 0 || result.height <= 0) {
return null;
}
return result;
};
var getDroppableDimension = function getDroppableDimension(_ref) {
var descriptor = _ref.descriptor,
isEnabled = _ref.isEnabled,
direction = _ref.direction,
client = _ref.client,
page = _ref.page,
closest$$1 = _ref.closest;
var scrollable = function () {
if (!closest$$1) {
return null;
}
var maxScroll = getMaxScroll({
scrollHeight: closest$$1.scrollHeight,
scrollWidth: closest$$1.scrollWidth,
height: closest$$1.client.paddingBox.height,
width: closest$$1.client.paddingBox.width
});
return {
framePageMarginBox: closest$$1.page.marginBox,
shouldClipSubject: closest$$1.shouldClipSubject,
scroll: {
initial: closest$$1.scroll,
current: closest$$1.scroll,
max: maxScroll,
diff: {
value: origin,
displacement: origin
}
}
};
}();
var subjectPageMarginBox = page.marginBox;
var clippedPageMarginBox = scrollable && scrollable.shouldClipSubject ? clip(scrollable.framePageMarginBox, subjectPageMarginBox) : subjectPageMarginBox;
var viewport = {
closestScrollable: scrollable,
subjectPageMarginBox: subjectPageMarginBox,
clippedPageMarginBox: clippedPageMarginBox
};
var dimension = {
descriptor: descriptor,
axis: direction === 'vertical' ? vertical : horizontal,
isEnabled: isEnabled,
client: client,
page: page,
viewport: viewport
};
return dimension;
};
var scrollDroppable = function scrollDroppable(droppable, newScroll) {
!droppable.viewport.closestScrollable ? process.env.NODE_ENV !== "production" ? invariant(false) : invariant(false) : void 0;
var scrollable = droppable.viewport.closestScrollable;
var framePageMarginBox = scrollable.framePageMarginBox;
var scrollDiff = subtract(newScroll, scrollable.scroll.initial);
var scrollDisplacement = negate(scrollDiff);
var closestScrollable = {
framePageMarginBox: scrollable.framePageMarginBox,
shouldClipSubject: scrollable.shouldClipSubject,
scroll: {
initial: scrollable.scroll.initial,
current: newScroll,
diff: {
value: scrollDiff,
displacement: scrollDisplacement
},
max: scrollable.scroll.max
}
};
var displacedSubject = offsetByPosition(droppable.viewport.subjectPageMarginBox, scrollDisplacement);
var clippedPageMarginBox = closestScrollable.shouldClipSubject ? clip(framePageMarginBox, displacedSubject) : cssBoxModel.getRect(displacedSubject);
var viewport = {
closestScrollable: closestScrollable,
subjectPageMarginBox: droppable.viewport.subjectPageMarginBox,
clippedPageMarginBox: clippedPageMarginBox
};
var result = _extends({}, droppable, {
viewport: viewport
});
return result;
};
var toDroppableMap = memoizeOne(function (droppables) {
return droppables.reduce(function (previous, current) {
previous[current.descriptor.id] = current;
return previous;
}, {});
});
var toDraggableMap = memoizeOne(function (draggables) {
return draggables.reduce(function (previous, current) {
previous[current.descriptor.id] = current;
return previous;
}, {});
});
var toDroppableList = memoizeOne(function (droppables) {
return _Object$keys(droppables).map(function (id) {
return droppables[id];
});
});
var toDraggableList = memoizeOne(function (draggables) {
return _Object$keys(draggables).map(function (id) {
return draggables[id];
});
});
var getDraggablesInsideDroppable = memoizeOne(function (droppable, draggables) {
return toDraggableList(draggables).filter(function (draggable) {
return droppable.descriptor.id === draggable.descriptor.droppableId;
}).sort(function (a, b) {
return a.descriptor.index - b.descriptor.index;
});
});
var isWithin = (function (lowerBound, upperBound) {
return function (value) {
return value <= upperBound && value >= lowerBound;
};
});
var isPositionInFrame = (function (frame) {
var isWithinVertical = isWithin(frame.top, frame.bottom);
var isWithinHorizontal = isWithin(frame.left, frame.right);
return function (point) {
return isWithinVertical(point.y) && isWithinVertical(point.y) && isWithinHorizontal(point.x) && isWithinHorizontal(point.x);
};
});
var getRequiredGrowth = memoizeOne(function (draggable, draggables, droppable) {
var getResult = function getResult(existingSpace) {
var requiredSpace = draggable.page.marginBox[droppable.axis.size];
if (requiredSpace <= existingSpace) {
return null;
}
var requiredGrowth = patch(droppable.axis.line, requiredSpace - existingSpace);
return requiredGrowth;
};
var dimensions = getDraggablesInsideDroppable(droppable, draggables);
if (!dimensions.length) {
var _existingSpace = droppable.page.marginBox[droppable.axis.size];
return getResult(_existingSpace);
}
var endOfDraggables = dimensions[dimensions.length - 1].page.marginBox[droppable.axis.end];
var endOfDroppable = droppable.page.marginBox[droppable.axis.end];
var existingSpace = endOfDroppable - endOfDraggables;
return getResult(existingSpace);
});
var getWithGrowth = memoizeOne(function (area, growth) {
return cssBoxModel.getRect(expandByPosition(area, growth));
});
var getClippedRectWithPlaceholder = function getClippedRectWithPlaceholder(_ref) {
var draggable = _ref.draggable,
draggables = _ref.draggables,
droppable = _ref.droppable,
previousDroppableOverId = _ref.previousDroppableOverId;
var isHome = draggable.descriptor.droppableId === droppable.descriptor.id;
var wasOver = Boolean(previousDroppableOverId && previousDroppableOverId === droppable.descriptor.id);
var clippedPageMarginBox = droppable.viewport.clippedPageMarginBox;
if (!clippedPageMarginBox) {
return clippedPageMarginBox;
}
if (isHome || !wasOver) {
return clippedPageMarginBox;
}
var requiredGrowth = getRequiredGrowth(draggable, draggables, droppable);
if (!requiredGrowth) {
return clippedPageMarginBox;
}
var subjectWithGrowth = getWithGrowth(clippedPageMarginBox, requiredGrowth);
var closestScrollable = droppable.viewport.closestScrollable;
if (!closestScrollable) {
return subjectWithGrowth;
}
if (!closestScrollable.shouldClipSubject) {
return subjectWithGrowth;
}
return clip(closestScrollable.framePageMarginBox, subjectWithGrowth);
};
var getDroppableOver = (function (_ref2) {
var target = _ref2.target,
draggable = _ref2.draggable,
draggables = _ref2.draggables,
droppables = _ref2.droppables,
previousDroppableOverId = _ref2.previousDroppableOverId;
var maybe = toDroppableList(droppables).filter(function (droppable) {
return droppable.isEnabled;
}).find(function (droppable) {
var withPlaceholder = getClippedRectWithPlaceholder({
draggable: draggable,
draggables: draggables,
droppable: droppable,
previousDroppableOverId: previousDroppableOverId
});
if (!withPlaceholder) {
return false;
}
return isPositionInFrame(withPlaceholder)(target);
});
return maybe ? maybe.descriptor.id : null;
});
var noMovement = {
displaced: [],
amount: origin,
isBeyondStartPosition: false
};
var noImpact = {
movement: noMovement,
direction: null,
destination: null
};
var getDisplacementMap = memoizeOne(function (displaced) {
return displaced.reduce(function (map, displacement) {
map[displacement.draggableId] = displacement;
return map;
}, {});
});
var isPartiallyVisibleThroughFrame = (function (frame) {
var isWithinVertical = isWithin(frame.top, frame.bottom);
var isWithinHorizontal = isWithin(frame.left, frame.right);
return function (subject) {
var isContained = isWithinVertical(subject.top) && isWithinVertical(subject.bottom) && isWithinHorizontal(subject.left) && isWithinHorizontal(subject.right);
if (isContained) {
return true;
}
var isPartiallyVisibleVertically = isWithinVertical(subject.top) || isWithinVertical(subject.bottom);
var isPartiallyVisibleHorizontally = isWithinHorizontal(subject.left) || isWithinHorizontal(subject.right);
var isPartiallyContained = isPartiallyVisibleVertically && isPartiallyVisibleHorizontally;
if (isPartiallyContained) {
return true;
}
var isBiggerVertically = subject.top < frame.top && subject.bottom > frame.bottom;
var isBiggerHorizontally = subject.left < frame.left && subject.right > frame.right;
var isTargetBiggerThanFrame = isBiggerVertically && isBiggerHorizontally;
if (isTargetBiggerThanFrame) {
return true;
}
var isTargetBiggerOnOneAxis = isBiggerVertically && isPartiallyVisibleHorizontally || isBiggerHorizontally && isPartiallyVisibleVertically;
return isTargetBiggerOnOneAxis;
};
});
var isTotallyVisibleThroughFrame = (function (frame) {
var isWithinVertical = isWithin(frame.top, frame.bottom);
var isWithinHorizontal = isWithin(frame.left, frame.right);
return function (subject) {
var isContained = isWithinVertical(subject.top) && isWithinVertical(subject.bottom) && isWithinHorizontal(subject.left) && isWithinHorizontal(subject.right);
return isContained;
};
});
var isVisible = function isVisible(_ref) {
var target = _ref.target,
destination = _ref.destination,
viewport = _ref.viewport,
isVisibleThroughFrameFn = _ref.isVisibleThroughFrameFn;
var displacement = destination.viewport.closestScrollable ? destination.viewport.closestScrollable.scroll.diff.displacement : origin;
var withDisplacement = offsetByPosition(target, displacement);
if (!destination.viewport.clippedPageMarginBox) {
return false;
}
var isVisibleInDroppable = isVisibleThroughFrameFn(destination.viewport.clippedPageMarginBox)(withDisplacement);
var isVisibleInViewport = isVisibleThroughFrameFn(viewport)(withDisplacement);
return isVisibleInDroppable && isVisibleInViewport;
};
var isPartiallyVisible = function isPartiallyVisible(_ref2) {
var target = _ref2.target,
destination = _ref2.destination,
viewport = _ref2.viewport;
return isVisible({
target: target,
destination: destination,
viewport: viewport,
isVisibleThroughFrameFn: isPartiallyVisibleThroughFrame
});
};
var isTotallyVisible = function isTotallyVisible(_ref3) {
var target = _ref3.target,
destination = _ref3.destination,
viewport = _ref3.viewport;
return isVisible({
target: target,
destination: destination,
viewport: viewport,
isVisibleThroughFrameFn: isTotallyVisibleThroughFrame
});
};
var getDisplacement = (function (_ref) {
var draggable = _ref.draggable,
destination = _ref.destination,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var id = draggable.descriptor.id;
var map = getDisplacementMap(previousImpact.movement.displaced);
var isVisible = isPartiallyVisible({
target: draggable.page.marginBox,
destination: destination,
viewport: viewport
});
var shouldAnimate = function () {
if (!isVisible) {
return false;
}
var previous = map[id];
if (!previous) {
return true;
}
return previous.shouldAnimate;
}();
var displacement = {
draggableId: id,
isVisible: isVisible,
shouldAnimate: shouldAnimate
};
return displacement;
});
var withDroppableScroll = (function (droppable, point) {
var closestScrollable = droppable.viewport.closestScrollable;
if (!closestScrollable) {
return point;
}
return add(point, closestScrollable.scroll.diff.value);
});
var inHomeList = (function (_ref) {
var pageBorderBoxCenter = _ref.pageBorderBoxCenter,
draggable = _ref.draggable,
home = _ref.home,
insideHome = _ref.insideHome,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var axis = home.axis;
var originalCenter = draggable.page.borderBox.center;
var currentCenter = withDroppableScroll(home, pageBorderBoxCenter);
var isBeyondStartPosition = currentCenter[axis.line] - originalCenter[axis.line] > 0;
var amount = patch(axis.line, draggable.client.marginBox[axis.size]);
var displaced = insideHome.filter(function (child) {
if (child === draggable) {
return false;
}
var borderBox = child.page.borderBox;
if (isBeyondStartPosition) {
if (borderBox.center[axis.line] < originalCenter[axis.line]) {
return false;
}
return currentCenter[axis.line] > borderBox[axis.start];
}
if (originalCenter[axis.line] < borderBox.center[axis.line]) {
return false;
}
return currentCenter[axis.line] < borderBox[axis.end];
}).map(function (dimension) {
return getDisplacement({
draggable: dimension,
destination: home,
previousImpact: previousImpact,
viewport: viewport.frame
});
});
var ordered = isBeyondStartPosition ? displaced.reverse() : displaced;
var index = function () {
var startIndex = draggable.descriptor.index;
var length = ordered.length;
if (!length) {
return startIndex;
}
if (isBeyondStartPosition) {
return startIndex + length;
}
return startIndex - length;
}();
var movement = {
amount: amount,
displaced: ordered,
isBeyondStartPosition: isBeyondStartPosition
};
var impact = {
movement: movement,
direction: axis.direction,
destination: {
droppableId: home.descriptor.id,
index: index
}
};
return impact;
});
var inForeignList = (function (_ref) {
var pageBorderBoxCenter = _ref.pageBorderBoxCenter,
draggable = _ref.draggable,
destination = _ref.destination,
insideDestination = _ref.insideDestination,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var axis = destination.axis;
var currentCenter = withDroppableScroll(destination, pageBorderBoxCenter);
var displaced = insideDestination.filter(function (child) {
var threshold = child.page.borderBox[axis.end];
return threshold > currentCenter[axis.line];
}).map(function (dimension) {
return getDisplacement({
draggable: dimension,
destination: destination,
previousImpact: previousImpact,
viewport: viewport.frame
});
});
var newIndex = insideDestination.length - displaced.length;
var movement = {
amount: patch(axis.line, draggable.page.marginBox[axis.size]),
displaced: displaced,
isBeyondStartPosition: false
};
var impact = {
movement: movement,
direction: axis.direction,
destination: {
droppableId: destination.descriptor.id,
index: newIndex
}
};
return impact;
});
var getDragImpact = (function (_ref) {
var pageBorderBoxCenter = _ref.pageBorderBoxCenter,
draggable = _ref.draggable,
draggables = _ref.draggables,
droppables = _ref.droppables,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var previousDroppableOverId = previousImpact.destination && previousImpact.destination.droppableId;
var destinationId = getDroppableOver({
target: pageBorderBoxCenter,
draggable: draggable,
draggables: draggables,
droppables: droppables,
previousDroppableOverId: previousDroppableOverId
});
if (!destinationId) {
return noImpact;
}
var destination = droppables[destinationId];
if (!destination.isEnabled) {
return noImpact;
}
var home = droppables[draggable.descriptor.droppableId];
var isWithinHomeDroppable = home.descriptor.id === destinationId;
var insideDestination = getDraggablesInsideDroppable(destination, draggables);
if (isWithinHomeDroppable) {
return inHomeList({
pageBorderBoxCenter: pageBorderBoxCenter,
draggable: draggable,
home: home,
insideHome: insideDestination,
previousImpact: previousImpact || noImpact,
viewport: viewport
});
}
return inForeignList({
pageBorderBoxCenter: pageBorderBoxCenter,
draggable: draggable,
destination: destination,
insideDestination: insideDestination,
previousImpact: previousImpact || noImpact,
viewport: viewport
});
});
var getHomeLocation = (function (critical) {
return {
index: critical.draggable.index,
droppableId: critical.droppable.id
};
});
var getSafeClipped = function getSafeClipped(droppable) {
var rect = droppable.viewport.clippedPageMarginBox;
!rect ? process.env.NODE_ENV !== "production" ? invariant(false, 'Cannot get clipped area from droppable') : invariant(false) : void 0;
return rect;
};
var getBestCrossAxisDroppable = (function (_ref) {
var isMovingForward = _ref.isMovingForward,
pageBorderBoxCenter = _ref.pageBorderBoxCenter,
source = _ref.source,
droppables = _ref.droppables,
viewport = _ref.viewport;
var sourceClipped = source.viewport.clippedPageMarginBox;
if (!sourceClipped) {
return null;
}
var axis = source.axis;
var isBetweenSourceClipped = isWithin(sourceClipped[axis.start], sourceClipped[axis.end]);
var candidates = toDroppableList(droppables).filter(function (droppable) {
return droppable !== source;
}).filter(function (droppable) {
return droppable.isEnabled;
}).filter(function (droppable) {
var clippedPageMarginBox = droppable.viewport.clippedPageMarginBox;
if (!clippedPageMarginBox) {
return false;
}
return isPartiallyVisibleThroughFrame(viewport.frame)(clippedPageMarginBox);
}).filter(function (droppable) {
var targetClipped = getSafeClipped(droppable);
if (isMovingForward) {
return sourceClipped[axis.crossAxisEnd] < targetClipped[axis.crossAxisEnd];
}
return targetClipped[axis.crossAxisStart] < sourceClipped[axis.crossAxisStart];
}).filter(function (droppable) {
var targetClipped = getSafeClipped(droppable);
var isBetweenDestinationClipped = isWithin(targetClipped[axis.start], targetClipped[axis.end]);
return isBetweenSourceClipped(targetClipped[axis.start]) || isBetweenSourceClipped(targetClipped[axis.end]) || isBetweenDestinationClipped(sourceClipped[axis.start]) || isBetweenDestinationClipped(sourceClipped[axis.end]);
}).sort(function (a, b) {
var first = getSafeClipped(a)[axis.crossAxisStart];
var second = getSafeClipped(b)[axis.crossAxisStart];
if (isMovingForward) {
return first - second;
}
return second - first;
}).filter(function (droppable, index, array) {
return getSafeClipped(droppable)[axis.crossAxisStart] === getSafeClipped(array[0])[axis.crossAxisStart];
});
if (!candidates.length) {
return null;
}
if (candidates.length === 1) {
return candidates[0];
}
var contains = candidates.filter(function (droppable) {
var isWithinDroppable = isWithin(getSafeClipped(droppable)[axis.start], getSafeClipped(droppable)[axis.end]);
return isWithinDroppable(pageBorderBoxCenter[axis.line]);
});
if (contains.length === 1) {
return contains[0];
}
if (contains.length > 1) {
return contains.sort(function (a, b) {
return getSafeClipped(a)[axis.start] - getSafeClipped(b)[axis.start];
})[0];
}
return candidates.sort(function (a, b) {
var first = closest(pageBorderBoxCenter, getCorners(getSafeClipped(a)));
var second = closest(pageBorderBoxCenter, getCorners(getSafeClipped(b)));
if (first !== second) {
return first - second;
}
return getSafeClipped(a)[axis.start] - getSafeClipped(b)[axis.start];
})[0];
});
var withDroppableDisplacement = (function (droppable, point) {
var closestScrollable = droppable.viewport.closestScrollable;
if (!closestScrollable) {
return point;
}
return add(point, closestScrollable.scroll.diff.displacement);
});
var getClosestDraggable = (function (_ref) {
var axis = _ref.axis,
viewport = _ref.viewport,
pageBorderBoxCenter = _ref.pageBorderBoxCenter,
destination = _ref.destination,
insideDestination = _ref.insideDestination;
if (!insideDestination.length) {
return null;
}
var result = insideDestination.filter(function (draggable) {
return isTotallyVisible({
target: draggable.page.borderBox,
destination: destination,
viewport: viewport.frame
});
}).sort(function (a, b) {
var distanceToA = distance(pageBorderBoxCenter, withDroppableDisplacement(destination, a.page.borderBox.center));
var distanceToB = distance(pageBorderBoxCenter, withDroppableDisplacement(destination, b.page.borderBox.center));
if (distanceToA < distanceToB) {
return -1;
}
if (distanceToB < distanceToA) {
return 1;
}
return a.page.borderBox[axis.start] - b.page.borderBox[axis.start];
});
return result.length ? result[0] : null;
});
var moveToEdge = (function (_ref) {
var source = _ref.source,
sourceEdge = _ref.sourceEdge,
destination = _ref.destination,
destinationEdge = _ref.destinationEdge,
destinationAxis = _ref.destinationAxis;
var getCorner = function getCorner(area) {
return patch(destinationAxis.line, area[destinationAxis[destinationEdge]], area[destinationAxis.crossAxisStart]);
};
var corner = getCorner(destination);
var centerDiff = absolute(subtract(source.center, getCorner(source)));
var signed = patch(destinationAxis.line, (sourceEdge === 'end' ? -1 : 1) * centerDiff[destinationAxis.line], centerDiff[destinationAxis.crossAxisLine]);
return add(corner, signed);
});
var toHomeList = (function (_ref) {
var amount = _ref.amount,
homeIndex = _ref.homeIndex,
movingRelativeTo = _ref.movingRelativeTo,
insideDestination = _ref.insideDestination,
draggable = _ref.draggable,
destination = _ref.destination,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var axis = destination.axis;
var targetIndex = insideDestination.indexOf(movingRelativeTo);
!(targetIndex !== -1) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unable to find target in destination droppable') : invariant(false) : void 0;
if (targetIndex === homeIndex) {
var _newCenter = draggable.page.borderBox.center;
var _newImpact = {
movement: {
displaced: [],
amount: amount,
isBeyondStartPosition: false
},
direction: destination.axis.direction,
destination: {
droppableId: destination.descriptor.id,
index: homeIndex
}
};
return {
pageBorderBoxCenter: withDroppableDisplacement(destination, _newCenter),
impact: _newImpact
};
}
var isMovingPastOriginalIndex = targetIndex > homeIndex;
var edge = isMovingPastOriginalIndex ? 'end' : 'start';
var newCenter = moveToEdge({
source: draggable.page.borderBox,
sourceEdge: edge,
destination: isMovingPastOriginalIndex ? movingRelativeTo.page.borderBox : movingRelativeTo.page.marginBox,
destinationEdge: edge,
destinationAxis: axis
});
var modified = function () {
if (!isMovingPastOriginalIndex) {
return insideDestination.slice(targetIndex, homeIndex);
}
var from = homeIndex + 1;
var to = targetIndex + 1;
return insideDestination.slice(from, to).reverse();
}();
var displaced = modified.map(function (dimension) {
return getDisplacement({
draggable: dimension,
destination: destination,
previousImpact: previousImpact,
viewport: viewport.frame
});
});
var newImpact = {
movement: {
displaced: displaced,
amount: amount,
isBeyondStartPosition: isMovingPastOriginalIndex
},
direction: axis.direction,
destination: {
droppableId: destination.descriptor.id,
index: targetIndex
}
};
return {
pageBorderBoxCenter: withDroppableDisplacement(destination, newCenter),
impact: newImpact
};
});
var toForeignList = (function (_ref) {
var amount = _ref.amount,
pageBorderBoxCenter = _ref.pageBorderBoxCenter,
movingRelativeTo = _ref.movingRelativeTo,
insideDestination = _ref.insideDestination,
draggable = _ref.draggable,
destination = _ref.destination,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var axis = destination.axis;
var isGoingBeforeTarget = Boolean(movingRelativeTo && pageBorderBoxCenter[destination.axis.line] < movingRelativeTo.page.borderBox.center[destination.axis.line]);
if (!movingRelativeTo) {
var _newCenter = moveToEdge({
source: draggable.page.borderBox,
sourceEdge: 'start',
destination: destination.page.contentBox,
destinationEdge: 'start',
destinationAxis: axis
});
var _newImpact = {
movement: {
displaced: [],
amount: amount,
isBeyondStartPosition: false
},
direction: axis.direction,
destination: {
droppableId: destination.descriptor.id,
index: 0
}
};
return {
pageBorderBoxCenter: withDroppableDisplacement(destination, _newCenter),
impact: _newImpact
};
}
var targetIndex = insideDestination.indexOf(movingRelativeTo);
!(targetIndex !== -1) ? process.env.NODE_ENV !== "production" ? invariant(false, 'The target was not found within its droppable') : invariant(false) : void 0;
var proposedIndex = isGoingBeforeTarget ? targetIndex : targetIndex + 1;
var newCenter = moveToEdge({
source: draggable.page.borderBox,
sourceEdge: 'start',
destination: movingRelativeTo.page.marginBox,
destinationEdge: isGoingBeforeTarget ? 'start' : 'end',
destinationAxis: axis
});
var displaced = insideDestination.slice(proposedIndex, insideDestination.length).map(function (dimension) {
return getDisplacement({
draggable: dimension,
destination: destination,
viewport: viewport.frame,
previousImpact: previousImpact
});
});
var newImpact = {
movement: {
displaced: displaced,
amount: amount,
isBeyondStartPosition: false
},
direction: axis.direction,
destination: {
droppableId: destination.descriptor.id,
index: proposedIndex
}
};
return {
pageBorderBoxCenter: withDroppableDisplacement(destination, newCenter),
impact: newImpact
};
});
var moveToNewDroppable = (function (_ref) {
var pageBorderBoxCenter = _ref.pageBorderBoxCenter,
destination = _ref.destination,
insideDestination = _ref.insideDestination,
draggable = _ref.draggable,
movingRelativeTo = _ref.movingRelativeTo,
home = _ref.home,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var amount = patch(destination.axis.line, draggable.client.marginBox[destination.axis.size]);
if (destination.descriptor.id === draggable.descriptor.droppableId) {
!movingRelativeTo ? process.env.NODE_ENV !== "production" ? invariant(false, 'There will always be a target in the original list') : invariant(false) : void 0;
return toHomeList({
amount: amount,
homeIndex: home.index,
movingRelativeTo: movingRelativeTo,
insideDestination: insideDestination,
draggable: draggable,
destination: destination,
previousImpact: previousImpact,
viewport: viewport
});
}
return toForeignList({
amount: amount,
pageBorderBoxCenter: pageBorderBoxCenter,
movingRelativeTo: movingRelativeTo,
insideDestination: insideDestination,
draggable: draggable,
destination: destination,
previousImpact: previousImpact,
viewport: viewport
});
});
var moveCrossAxis = (function (_ref) {
var isMovingForward = _ref.isMovingForward,
pageBorderBoxCenter = _ref.pageBorderBoxCenter,
draggableId = _ref.draggableId,
droppableId = _ref.droppableId,
home = _ref.home,
draggables = _ref.draggables,
droppables = _ref.droppables,
previousImpact = _ref.previousImpact,
viewport = _ref.viewport;
var draggable = draggables[draggableId];
var source = droppables[droppableId];
var destination = getBestCrossAxisDroppable({
isMovingForward: isMovingForward,
pageBorderBoxCenter: pageBorderBoxCenter,
source: source,
droppables: droppables,
viewport: viewport
});
if (!destination) {
return null;
}
var insideDestination = getDraggablesInsideDroppable(destination, draggables);
var movingRelativeTo = getClosestDraggable({
axis: destination.axis,
pageBorderBoxCenter: pageBorderBoxCenter,
destination: destination,
insideDestination: insideDestination,
viewport: viewport
});
if (insideDestination.length && !movingRelativeTo) {
return null;
}
return moveToNewDroppable({
pageBorderBoxCenter: pageBorderBoxCenter,
destination: destination,
draggable: draggable,
movingRelativeTo: movingRelativeTo,
insideDestination: insideDestination,
home: home,
previousImpact: previousImpact || noImpact,
viewport: viewport
});
});
var isTotallyVisibleInNewLocation = (function (_ref) {
var draggable = _ref.draggable,
destination = _ref.destination,
newPageBorderBoxCenter = _ref.newPageBorderBoxCenter,
viewport = _ref.viewport;
var diff = subtract(newPageBorderBoxCenter, draggable.page.borderBox.center);
var shifted = offsetByPosition(draggable.page.borderBox, diff);
return isTotallyVisible({
target: shifted,
destination: destination,
viewport: viewport
});
});
var withFirstAdded = function withFirstAdded(_ref) {
var add = _ref.add,
previousImpact = _ref.previousImpact,
droppable = _ref.droppable,
draggables = _ref.draggables,
viewport = _ref.viewport;
var newDisplacement = {
draggableId: add,
isVisible: true,
shouldAnimate: true
};
var added = [newDisplacement].concat(previousImpact.movement.displaced);
var withUpdatedVisibility = added.map(function (current) {
if (current === newDisplacement) {
return current;
}
var updated = getDisplacement({
draggable: draggables[current.draggableId],
destination: droppable,
previousImpact: previousImpact,
viewport: viewport.frame
});
return updated;
});
return withUpdatedVisibility;
};
var forceVisibleDisplacement = function forceVisibleDisplacement(current) {
if (current.isVisible) {
return current;
}
return {
draggableId: current.draggableId,
isVisible: true,
shouldAnimate: false
};
};
var withFirstRemoved = function withFirstRemoved(_ref2) {
var dragging = _ref2.dragging,
isVisibleInNewLocation = _ref2.isVisibleInNewLocation,
previousImpact = _ref2.previousImpact,
droppable = _ref2.droppable,
draggables = _ref2.draggables;
var last = previousImpact.movement.displaced;
!last.length ? process.env.NODE_ENV !== "production" ? invariant(false, 'Cannot remove displacement from empty list') : invariant(false) : void 0;
var withFirstRestored = last.slice(1, last.length);
if (!withFirstRestored.length) {
return withFirstRestored;
}
if (isVisibleInNewLocation) {
return withFirstRestored;
}
var axis = droppable.axis;
var sizeOfRestored = draggables[last[0].draggableId].page.marginBox[axis.size];
var sizeOfDragging = draggables[dragging].page.marginBox[axis.size];
var buffer = sizeOfRestored + sizeOfDragging;
var withUpdatedVisibility = withFirstRestored.map(function (displacement, index) {
if (index === 0) {
return forceVisibleDisplacement(displacement);
}
if (buffer > 0) {
var current = draggables[displacement.draggableId];
var size = current.page.marginBox[axis.size];
buffer -= size;
return forceVisibleDisplacement(displacement);
}
return {
draggableId: displacement.draggableId,
isVisible: false,
shouldAnimate: false
};
});
return withUpdatedVisibility;
};
var inHomeList$1 = (function (_ref) {
var isMovingForward = _ref.isMovingForward,
draggableId = _ref.draggableId,
previousPageBorderBoxCenter = _ref.previousPageBorderBoxCenter,
previousImpact = _ref.previousImpact,
droppable = _ref.droppable,
draggables = _ref.draggables,
viewport = _ref.viewport;
var location = previousImpact.destination;
!location ? process.env.NODE_ENV !== "production" ? invariant(false, 'Cannot move to next index in home list when there is no previous destination') : invariant(false) : void 0;
var draggable = draggables[draggableId];
var axis = droppable.axis;
var insideDroppable = getDraggablesInsideDroppable(droppable, draggables);
var startIndex = draggable.descriptor.index;
var currentIndex = location.index;
var proposedIndex = isMovingForward ? currentIndex + 1 : currentIndex - 1;
if (proposedIndex > insideDroppable.length - 1) {
return null;
}
if (proposedIndex < 0) {
return null;
}
var destination = insideDroppable[proposedIndex];
var isMovingTowardStart = isMovingForward && proposedIndex <= startIndex || !isMovingForward && proposedIndex >= startIndex;
var edge = function () {
if (!isMovingTowardStart) {
return isMovingForward ? 'end' : 'start';
}
return isMovingForward ? 'start' : 'end';
}();
var newPageBorderBoxCenter = moveToEdge({
source: draggable.page.borderBox,
sourceEdge: edge,
destination: destination.page.borderBox,
destinationEdge: edge,
destinationAxis: droppable.axis
});
var isVisibleInNewLocation = isTotallyVisibleInNewLocation({
draggable: draggable,
destination: droppable,
newPageBorderBoxCenter: newPageBorderBoxCenter,
viewport: viewport.frame
});
var displaced = isMovingTowardStart ? withFirstRemoved({
dragging: draggableId,
isVisibleInNewLocation: isVisibleInNewLocation,
previousImpact: previousImpact,
droppable: droppable,
draggables: draggables
}) : withFirstAdded({
add: destination.descriptor.id,
previousImpact: previousImpact,
droppable: droppable,
draggables: draggables,
viewport: viewport
});
var newImpact = {
movement: {
displaced: displaced,
amount: patch(axis.line, draggable.page.marginBox[axis.size]),
isBeyondStartPosition: proposedIndex > startIndex
},
destination: {
droppableId: droppable.descriptor.id,
index: proposedIndex
},
direction: droppable.axis.direction
};
if (isVisibleInNewLocation) {
return {
pageBorderBoxCenter: withDroppableDisplacement(droppable, newPageBorderBoxCenter),
impact: newImpact,
scrollJumpRequest: null
};
}
var distance$$1 = subtract(newPageBorderBoxCenter, previousPageBorderBoxCenter);
var distanceWithScroll = withDroppableDisplacement(droppable, distance$$1);
return {
pageBorderBoxCenter: previousPageBorderBoxCenter,
impact: newImpact,
scrollJumpRequest: distanceWithScroll
};
});
var inForeignList$1 = (function (_ref) {
var isMovingForward = _ref.isMovingForward,
draggableId = _ref.draggableId,
previousImpact = _ref.previousImpact,
previousPageBorderBoxCenter = _ref.previousPageBorderBoxCenter,
droppable = _ref.droppable,
draggables = _ref.draggables,
viewport = _ref.viewport;
!previousImpact.destination ? process.env.NODE_ENV !== "production" ? invariant(false, 'Cannot move to next index where there is no previous destination') : invariant(false) : void 0;
var location = previousImpact.destination;
var draggable = draggables[draggableId];
var axis = droppable.axis;
var insideForeignDroppable = getDraggablesInsideDroppable(droppable, draggables);
var currentIndex = location.index;
var proposedIndex = isMovingForward ? currentIndex + 1 : currentIndex - 1;
var lastIndex = insideForeignDroppable.length - 1;
if (proposedIndex > insideForeignDroppable.length) {
return null;
}
if (proposedIndex < 0) {
return null;
}
var movingRelativeTo = insideForeignDroppable[Math.min(proposedIndex, lastIndex)];
var isMovingPastLastIndex = proposedIndex > lastIndex;
var sourceEdge = 'start';
var destinationEdge = function () {
if (isMovingPastLastIndex) {
return 'end';
}
return 'start';
}();
var newPageBorderBoxCenter = moveToEdge({
source: draggable.page.borderBox,
sourceEdge: sourceEdge,
destination: movingRelativeTo.page.marginBox,
destinationEdge: destinationEdge,
destinationAxis: droppable.axis
});
var isVisibleInNewLocation = isTotallyVisibleInNewLocation({
draggable: draggable,
destination: droppable,
newPageBorderBoxCenter: newPageBorderBoxCenter,
viewport: viewport.frame
});
var displaced = function () {
if (isMovingForward) {
return withFirstRemoved({
dragging: draggableId,
isVisibleInNewLocation: isVisibleInNewLocation,
previousImpact: previousImpact,
droppable: droppable,
draggables: draggables
});
}
return withFirstAdded({
add: movingRelativeTo.descriptor.id,
previousImpact: previousImpact,
droppable: droppable,
draggables: draggables,
viewport: viewport
});
}();
var newImpact = {
movement: {
displaced: displaced,
amount: patch(axis.line, draggable.page.marginBox[axis.size]),
isBeyondStartPosition: false
},
destination: {
droppableId: droppable.descriptor.id,
index: proposedIndex
},
direction: droppable.axis.direction
};
if (isVisibleInNewLocation) {
return {
pageBorderBoxCenter: withDroppableDisplacement(droppable, newPageBorderBoxCenter),
impact: newImpact,
scrollJumpRequest: null
};
}
var distanceMoving = subtract(newPageBorderBoxCenter, previousPageBorderBoxCenter);
var distanceWithScroll = withDroppableDisplacement(droppable, distanceMoving);
return {
pageBorderBoxCenter: previousPageBorderBoxCenter,
impact: newImpact,
scrollJumpRequest: distanceWithScroll
};
});
var moveToNextIndex = (function (args) {
var draggableId = args.draggableId,
draggables = args.draggables,
droppable = args.droppable;
var draggable = draggables[draggableId];
var isInHomeList = draggable.descriptor.droppableId === droppable.descriptor.id;
if (!droppable.isEnabled) {
return null;
}
if (isInHomeList) {
return inHomeList$1(args);
}
return inForeignList$1(args);
});
var getClientSelection = function getClientSelection(pageBorderBoxCenter, currentScroll) {
return subtract(pageBorderBoxCenter, currentScroll);
};
var moveInDirection = (function (_ref) {
var state = _ref.state,
type = _ref.type;
var _ref2 = function () {
if (state.impact.destination) {
return {
droppable: state.dimensions.droppables[state.impact.destination.droppableId],
isMainAxisMovementAllowed: true
};
}
return {
droppable: state.dimensions.droppables[state.critical.droppable.id],
isMainAxisMovementAllowed: false
};
}(),
droppable = _ref2.droppable,
isMainAxisMovementAllowed = _ref2.isMainAxisMovementAllowed;
var direction = droppable.axis.direction;
var isMovingOnMainAxis = direction === 'vertical' && (type === 'MOVE_UP' || type === 'MOVE_DOWN') || direction === 'horizontal' && (type === 'MOVE_LEFT' || type === 'MOVE_RIGHT');
if (isMovingOnMainAxis && !isMainAxisMovementAllowed) {
return null;
}
var isMovingForward = type === 'MOVE_DOWN' || type === 'MOVE_RIGHT';
if (isMovingOnMainAxis) {
var _result = moveToNextIndex({
isMovingForward: isMovingForward,
draggableId: state.critical.draggable.id,
droppable: droppable,
draggables: state.dimensions.draggables,
previousPageBorderBoxCenter: state.current.page.borderBoxCenter,
previousImpact: state.impact,
viewport: state.viewport
});
if (!_result) {
return null;
}
return {
impact: _result.impact,
clientSelection: getClientSelection(_result.pageBorderBoxCenter, state.viewport.scroll.current),
scrollJumpRequest: _result.scrollJumpRequest
};
}
var home = getHomeLocation(state.critical);
var result = moveCrossAxis({
isMovingForward: isMovingForward,
pageBorderBoxCenter: state.current.page.borderBoxCenter,
draggableId: state.critical.draggable.id,
droppableId: droppable.descriptor.id,
home: home,
draggables: state.dimensions.draggables,
droppables: state.dimensions.droppables,
previousImpact: state.impact,
viewport: state.viewport
});
if (!result) {
return null;
}
return {
clientSelection: getClientSelection(result.pageBorderBoxCenter, state.viewport.scroll.current),
impact: result.impact,
scrollJumpRequest: null
};
});
var scrollViewport = (function (viewport, newScroll) {
var diff = subtract(newScroll, viewport.scroll.initial);
var displacement = negate(diff);
var frame = cssBoxModel.getRect({
top: newScroll.y,
bottom: newScroll.y + viewport.frame.height,
left: newScroll.x,
right: newScroll.x + viewport.frame.width
});
var updated = {
frame: frame,
scroll: {
initial: viewport.scroll.initial,
max: viewport.scroll.max,
current: newScroll,
diff: {
value: diff,
displacement: displacement
}
}
};
return updated;
});
var getHomeImpact = (function (critical, dimensions) {
var home = dimensions.droppables[critical.droppable.id];
var axis = home.axis;
var draggable = dimensions.draggables[critical.draggable.id];
return {
movement: {
displaced: [],
isBeyondStartPosition: false,
amount: patch(axis.line, draggable.client.marginBox[axis.size])
},
direction: axis.direction,
destination: getHomeLocation(critical)
};
});
var getPageItemPositions = (function (client, windowScroll) {
return {
selection: add(client.selection, windowScroll),
borderBoxCenter: add(client.borderBoxCenter, windowScroll),
offset: add(client.offset, windowScroll)
};
});
function isMovementAllowed(state) {
return state.phase === 'DRAGGING' || state.phase === 'COLLECTING';
}
var idle = {
phase: 'IDLE'
};
var preparing = {
phase: 'PREPARING'
};
var moveWithPositionUpdates = function moveWithPositionUpdates(_ref) {
var state = _ref.state,
clientSelection = _ref.clientSelection,
shouldAnimate = _ref.shouldAnimate,
viewport = _ref.viewport,
impact = _ref.impact,
scrollJumpRequest = _ref.scrollJumpRequest;
var newViewport = viewport || state.viewport;
var currentWindowScroll = newViewport.scroll.current;
var client = function () {
var offset = subtract(clientSelection, state.initial.client.selection);
return {
offset: offset,
selection: clientSelection,
borderBoxCenter: add(state.initial.client.borderBoxCenter, offset)
};
}();
var page = getPageItemPositions(client, currentWindowScroll);
var current = {
client: client,
page: page
};
if (state.phase === 'COLLECTING') {
return _extends({
phase: 'COLLECTING'
}, state, {
current: current
});
}
var newImpact = impact || getDragImpact({
pageBorderBoxCenter: page.borderBoxCenter,
draggable: state.dimensions.draggables[state.critical.draggable.id],
draggables: state.dimensions.draggables,
droppables: state.dimensions.droppables,
previousImpact: state.impact,
viewport: newViewport
});
var result = _extends({}, state, {
current: current,
shouldAnimate: shouldAnimate,
impact: newImpact,
scrollJumpRequest: scrollJumpRequest || null,
viewport: newViewport
});
return result;
};
var reducer = (function (state, action) {
if (state === void 0) {
state = idle;
}
if (action.type === 'CLEAN') {
return idle;
}
if (action.type === 'PREPARE') {
return preparing;
}
if (action.type === 'INITIAL_PUBLISH') {
!(state.phase === 'PREPARING') ? process.env.NODE_ENV !== "production" ? invariant(false, 'INITIAL_PUBLISH must come after a PREPARING phase') : invariant(false) : void 0;
var _action$payload = action.payload,
critical = _action$payload.critical,
client = _action$payload.client,
viewport = _action$payload.viewport,
dimensions = _action$payload.dimensions,
autoScrollMode = _action$payload.autoScrollMode;
var initial = {
client: client,
page: {
selection: add(client.selection, viewport.scroll.initial),
borderBoxCenter: add(client.selection, viewport.scroll.initial),
offset: origin
}
};
var result = {
phase: 'DRAGGING',
isDragging: true,
critical: critical,
autoScrollMode: autoScrollMode,
dimensions: dimensions,
initial: initial,
current: initial,
impact: getHomeImpact(critical, dimensions),
viewport: viewport,
scrollJumpRequest: null,
shouldAnimate: false
};
return result;
}
if (action.type === 'COLLECTION_STARTING') {
var _extends2;
if (state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING') {
return state;
}
!(state.phase === 'DRAGGING') ? process.env.NODE_ENV !== "production" ? invariant(false, "Collection cannot start from phase " + state.phase) : invariant(false) : void 0;
var _result = _extends({
phase: 'COLLECTING'
}, state, (_extends2 = {}, _extends2["phase"] = 'COLLECTING', _extends2));
return _result;
}
if (action.type === 'PUBLISH') {
!(state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING') ? process.env.NODE_ENV !== "production" ? invariant(false, "Unexpected " + action.type + " received in phase " + state.