@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-migration
Version:
An optional Pragmatic drag and drop package that enables rapid migration from react-beautiful-dnd to Pragmatic drag and drop
222 lines (211 loc) • 6.95 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getIndicatorSizeAndOffset = getIndicatorSizeAndOffset;
var _attributes = require("../../utils/attributes");
var _findClosestScrollContainer = require("../../utils/find-closest-scroll-container");
var _findElement = require("../../utils/find-element");
var _findPlaceholder = require("../../utils/find-placeholder");
var _getClosestPositionedElement = require("../../utils/get-closest-positioned-element");
var _getElementByDraggableLocation = require("../../utils/get-element-by-draggable-location");
var _gap = require("../gap");
var _constants = require("./constants");
// eslint-disable-next-line import/no-extraneous-dependencies
/**
* Returns the dimensions for a drop indicator either before or after a
* draggable.
*
* `isForwardEdge` determines whether it is before or after.
*/
function measureDraggable(_ref) {
var element = _ref.element,
isForwardEdge = _ref.isForwardEdge,
mode = _ref.mode,
direction = _ref.direction,
contextId = _ref.contextId;
var _directionMapping$dir = _constants.directionMapping[direction],
mainAxis = _directionMapping$dir.mainAxis,
crossAxis = _directionMapping$dir.crossAxis;
var offsetElement = (0, _getClosestPositionedElement.getClosestPositionedElement)({
element: element,
mode: mode
});
var gapOffset = (0, _gap.getGapOffset)({
element: element,
where: isForwardEdge ? 'after' : 'before',
direction: direction,
contextId: contextId
});
var baseOffset = offsetElement[mainAxis.offset] - _constants.lineOffset;
var mainAxisOffset = isForwardEdge ? baseOffset + element[mainAxis.length] : baseOffset;
return {
mainAxis: {
offset: mainAxisOffset + gapOffset
},
crossAxis: {
offset: offsetElement[crossAxis.offset],
length: offsetElement[crossAxis.length]
}
};
}
/**
* This will return an indicator size and offset corresponding to a line
* through the middle of the placeholder.
*
* The reason this is a special case, instead of just falling back to the
* standard positioning logic, is to avoid measuring the drag preview.
*/
function measurePlaceholder(_ref2) {
var element = _ref2.element,
direction = _ref2.direction;
var _directionMapping$dir2 = _constants.directionMapping[direction],
mainAxis = _directionMapping$dir2.mainAxis,
crossAxis = _directionMapping$dir2.crossAxis;
/**
* This function measures against the `element` directly instead of an
* `offsetElement` because:
* - For standard lists, that is already the behavior.
* - For virtual lists, we know that the `element` is being absolutely
* positioned (and not an ancestor).
*/
var baseOffset = element[mainAxis.offset] - _constants.lineOffset;
var mainAxisOffset = baseOffset + element[mainAxis.length] / 2;
return {
mainAxis: {
offset: mainAxisOffset
},
crossAxis: {
offset: element[crossAxis.offset],
length: element[crossAxis.length]
}
};
}
function getDroppableOffset(_ref3) {
var element = _ref3.element,
direction = _ref3.direction;
var mainAxis = _constants.directionMapping[direction].mainAxis;
var scrollContainer = (0, _findClosestScrollContainer.findClosestScrollContainer)(element);
if (!scrollContainer) {
return 0;
}
/**
* If the scroll container has static positioning,
* then we need to add the scroll container's offset as well.
*/
var _getComputedStyle = getComputedStyle(scrollContainer),
position = _getComputedStyle.position;
if (position !== 'static') {
return 0;
}
return scrollContainer[mainAxis.offset];
}
/**
* Returns the dimensions for a drop indicator in an empty list.
*/
function measureDroppable(_ref4) {
var droppableId = _ref4.droppableId,
direction = _ref4.direction;
var element = (0, _findElement.getElement)({
attribute: _attributes.attributes.droppable.id,
value: droppableId
});
var mainAxisOffset = getDroppableOffset({
element: element,
direction: direction
});
return {
mainAxis: {
offset: mainAxisOffset
},
crossAxis: {
offset: 0,
length: '100%'
}
};
}
function getIndicatorSizeAndOffset(_ref5) {
var targetLocation = _ref5.targetLocation,
isInHomeLocation = _ref5.isInHomeLocation,
direction = _ref5.direction,
mode = _ref5.mode,
contextId = _ref5.contextId;
if (isInHomeLocation) {
/**
* If we are in the home location (source === destination) then the
* indicator is centered in the placeholder.
*
* It isn't visible, but is used to scroll to.
*
* This is a special case, because the standard logic will not work
* correctly when measuring the drag preview,
* which occurs when in the home location.
*
* This is because the drag preview:
*
* 1. Has `position: fixed; top: 0; left: 0;` so its `offsetTop` and `offsetLeft`
* will always be `0`, which result in the indicator being at the start of the list.
* 2. Is in the wrong location anyway.
*
* `measurePlaceholder()` is specifically designed for this case.
*/
var _element = (0, _findPlaceholder.findPlaceholder)(contextId);
if (!_element) {
return null;
}
return measurePlaceholder({
element: _element,
direction: direction
});
}
if (targetLocation.index === 0) {
/**
* If the target is the 0th index, there are two situations:
*
* 1. Targeting an empty list
* 2. Targeting before the first item in the list
*/
var _element2 = (0, _getElementByDraggableLocation.getElementByDraggableLocation)(contextId, targetLocation);
if (!_element2) {
/**
* If there's no element in the location, it is because the list is empty.
* In this case, we measure the droppable itself to draw the indicator.
*/
return measureDroppable({
droppableId: targetLocation.droppableId,
direction: direction
});
}
/**
* Otherwise, there is a reference element we can use to measure.
*/
return measureDraggable({
element: _element2,
// `false` because the line is before the item
isForwardEdge: false,
mode: mode,
direction: direction,
contextId: contextId
});
}
/**
* Otherwise, for any other index, we can measure the draggable above where
* we would be dropping.
*/
var element = (0, _getElementByDraggableLocation.getElementByDraggableLocation)(contextId, {
droppableId: targetLocation.droppableId,
// subtracting one because it is the draggable above
index: targetLocation.index - 1
});
if (!element) {
return null;
}
return measureDraggable({
element: element,
// `true` because the line is after the item
isForwardEdge: true,
mode: mode,
direction: direction,
contextId: contextId
});
}