@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
234 lines (223 loc) • 9.04 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DropIndicator = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = require("react");
var _react2 = require("@emotion/react");
var _draggableLocation = require("../../drag-drop-context/draggable-location");
var _getDestination = require("../../drag-drop-context/get-destination");
var _internalContext = require("../../drag-drop-context/internal-context");
var _lifecycleContext = require("../../drag-drop-context/lifecycle-context");
var _rbdInvariant = require("../../drag-drop-context/rbd-invariant");
var _attributes = require("../../utils/attributes");
var _constants = require("./constants");
var _getDimensions = require("./get-dimensions");
/**
* @jsxRuntime classic
* @jsx jsx
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
// eslint-disable-next-line import/no-extraneous-dependencies
var scrollMarginTop = _constants.lineThickness + 2 * _constants.lineOffset;
var baseStyles = (0, _react2.css)({
background: "var(--ds-border-brand, #0C66E4)",
/**
* Ensures that when the indicator is scrolled into view there is visual
* space around it.
*
* Otherwise it will hug the edge of the container and be hard to see.
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
scrollMarginTop: scrollMarginTop,
/**
* The bottom margin needs to be slightly bigger for the gap to look
* the same visually.
*
* It's unclear why, this was found through testing.
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
scrollMarginBottom: scrollMarginTop + _constants.lineOffset
});
/**
* For virtual lists, the indicator might not be a sibling of the contents.
* This can lead to issues like wrapping.
*
* This style 'resets' it so that there is a consistent initial position.
*/
var virtualStyles = (0, _react2.css)({
position: 'absolute',
top: 0,
left: 0
});
/**
* When targeting the source location, we hide the drop indicator.
* But it should still be scrolled to, so we only want to hide it visually,
* instead of not rendering it.
*/
var visuallyHiddenStyles = (0, _react2.css)({
opacity: 0
});
var directionStyles = {
horizontal: (0, _react2.css)({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
width: _constants.lineThickness,
height: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
marginLeft: -_constants.lineThickness
}),
vertical: (0, _react2.css)({
width: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
height: _constants.lineThickness,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
marginTop: -_constants.lineThickness
})
};
function getDynamicStyles(_ref) {
var direction = _ref.direction,
dimensions = _ref.dimensions,
indicatorOffset = _ref.indicatorOffset;
if (dimensions === null) {
/**
* We hide the indicator initially until dimensions can be taken.
*/
return {
opacity: 0
};
}
var _directionMapping$dir = _constants.directionMapping[direction],
mainAxis = _directionMapping$dir.mainAxis,
crossAxis = _directionMapping$dir.crossAxis;
return (0, _defineProperty2.default)((0, _defineProperty2.default)({
transform: "".concat(mainAxis.style.transform, "(").concat(dimensions.mainAxis.offset - indicatorOffset, "px)")
}, crossAxis.style.length, dimensions.crossAxis.length), crossAxis.style.offset, dimensions.crossAxis.offset);
}
var dropIndicatorData = (0, _defineProperty2.default)({}, _attributes.customAttributes.dropIndicator, '');
var DropIndicator = exports.DropIndicator = function DropIndicator(_ref3) {
var direction = _ref3.direction,
mode = _ref3.mode;
var _useDragDropContext = (0, _internalContext.useDragDropContext)(),
contextId = _useDragDropContext.contextId,
getDragState = _useDragDropContext.getDragState;
var ref = (0, _react.useRef)(null);
var _useState = (0, _react.useState)(null),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
dimensions = _useState2[0],
setDimensions = _useState2[1];
var _useState3 = (0, _react.useState)(false),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
isHidden = _useState4[0],
setIsHidden = _useState4[1];
var monitorForLifecycle = (0, _lifecycleContext.useMonitorForLifecycle)();
var updateIndicator = (0, _react.useCallback)(function (_ref4) {
var targetLocation = _ref4.targetLocation,
source = _ref4.source,
destination = _ref4.destination;
if (!targetLocation) {
return setDimensions(null);
}
var isInHomeLocation = (0, _draggableLocation.isSameLocation)(source, destination);
/**
* Determines if the drop indicator should be hidden.
*
* This is desired when the current drop target would not change the position
* of the draggable.
*/
setIsHidden(isInHomeLocation);
return setDimensions((0, _getDimensions.getIndicatorSizeAndOffset)({
targetLocation: targetLocation,
isInHomeLocation: isInHomeLocation,
direction: direction,
mode: mode,
contextId: contextId
}));
}, [contextId, direction, mode]);
/**
* This is in a `useLayoutEffect` for immediacy.
*
* When mounting (cross-axis movement) the indicator should update into
* its correct position right away, so that the drag preview can be placed
* correctly.
*/
(0, _react.useLayoutEffect)(function () {
var dragState = getDragState();
if (!dragState.isDragging) {
return;
}
/**
* If the indicator is only just mounting then it needs an immediate
* update to have it appear in the correct position.
*/
var targetLocation = dragState.targetLocation,
sourceLocation = dragState.sourceLocation;
var destination = (0, _getDestination.getActualDestination)({
start: sourceLocation,
target: targetLocation
});
updateIndicator({
targetLocation: targetLocation,
destination: destination,
source: sourceLocation
});
return monitorForLifecycle({
onPrePendingDragUpdate: function onPrePendingDragUpdate(_ref5) {
var update = _ref5.update,
targetLocation = _ref5.targetLocation;
var _update$destination = update.destination,
destination = _update$destination === void 0 ? null : _update$destination,
source = update.source;
updateIndicator({
targetLocation: targetLocation,
source: source,
destination: destination
});
}
});
}, [contextId, direction, getDragState, mode, monitorForLifecycle, updateIndicator]);
/**
* Scroll the indicator into view.
*
* This is in a `useLayoutEffect` for immediacy.
* Otherwise the keyboard drag preview can appear in the wrong (old) location.
*/
(0, _react.useLayoutEffect)(function () {
if (dimensions === null) {
return;
}
/**
* If we are doing a mouse drag,
* then we don't want to scroll to the indicator.
*
* Otherwise, it will conflict with the auto-scroll addon.
*/
var dragState = getDragState();
if (!dragState.isDragging || dragState.mode !== 'SNAP') {
return;
}
var element = ref.current;
(0, _rbdInvariant.rbdInvariant)(element instanceof HTMLElement);
element.scrollIntoView({
block: 'nearest'
});
}, [dimensions, getDragState]);
var mainAxis = _constants.directionMapping[direction].mainAxis;
var indicatorOffset = ref.current ? ref.current[mainAxis.offset] : 0;
var dynamicStyles = getDynamicStyles({
direction: direction,
dimensions: dimensions,
indicatorOffset: indicatorOffset
});
var isVirtual = mode === 'virtual';
return (0, _react2.jsx)("div", (0, _extends2.default)({
ref: ref,
css: [baseStyles, directionStyles[direction], isVirtual && virtualStyles, isHidden && visuallyHiddenStyles]
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
,
style: dynamicStyles
}, dropIndicatorData));
};