UNPKG

@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

255 lines (250 loc) 11.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.Droppable = Droppable; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _tinyInvariant = _interopRequireDefault(require("tiny-invariant")); var _closestEdge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge"); var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine"); var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter"); var _internalContext = require("../drag-drop-context/internal-context"); var _lifecycleContext = require("../drag-drop-context/lifecycle-context"); var _data = require("../draggable/data"); var _useIsomorphicLayoutEffect = require("../hooks/use-isomorphic-layout-effect"); var _attributes = require("../utils/attributes"); var _useStable = require("../utils/use-stable"); var _data2 = require("./data"); var _draggableClone = require("./draggable-clone"); var _dropIndicator = require("./drop-indicator"); var _droppableContext = require("./droppable-context"); var _state = require("./state"); var _virtualPlaceholder = require("./virtual-placeholder"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } // eslint-disable-next-line import/no-extraneous-dependencies function Droppable(_ref) { var children = _ref.children, droppableId = _ref.droppableId, _ref$type = _ref.type, type = _ref$type === void 0 ? 'DEFAULT' : _ref$type, _ref$direction = _ref.direction, direction = _ref$direction === void 0 ? 'vertical' : _ref$direction, _ref$mode = _ref.mode, mode = _ref$mode === void 0 ? 'standard' : _ref$mode, renderClone = _ref.renderClone, getContainerForClone = _ref.getContainerForClone, _ref$isDropDisabled = _ref.isDropDisabled, isDropDisabled = _ref$isDropDisabled === void 0 ? false : _ref$isDropDisabled; var getIsDropDisabled = (0, _useStable.useStable)(isDropDisabled); var _useDragDropContext = (0, _internalContext.useDragDropContext)(), contextId = _useDragDropContext.contextId, droppableRegistry = _useDragDropContext.droppableRegistry; var data = (0, _data2.useDroppableData)({ contextId: contextId, droppableId: droppableId, getIsDropDisabled: getIsDropDisabled }); var elementRef = (0, _react.useRef)(null); var setElement = (0, _react.useCallback)(function (element) { if (element) { (0, _attributes.setAttributes)(element, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _attributes.customAttributes.droppable.type, type), _attributes.customAttributes.droppable.direction, direction), _attributes.attributes.droppable.id, droppableId), _attributes.attributes.droppable.contextId, contextId)); } elementRef.current = element; }, [contextId, direction, droppableId, type]); var _useReducer = (0, _react.useReducer)(_state.reducer, _state.idleState), _useReducer2 = (0, _slicedToArray2.default)(_useReducer, 2), state = _useReducer2[0], dispatch = _useReducer2[1]; var draggingFromThisWith = state.draggingFromThisWith, draggingOverWith = state.draggingOverWith, isDraggingOver = state.isDraggingOver; var parentDroppableId = (0, _droppableContext.useParentDroppableId)(); (0, _react.useEffect)(function () { var element = elementRef.current; (0, _tinyInvariant.default)(element instanceof HTMLElement, 'innerRef must provide an `HTMLElement`'); return (0, _combine.combine)(droppableRegistry.register({ droppableId: droppableId, type: type, isDropDisabled: isDropDisabled, parentDroppableId: parentDroppableId, element: element, direction: direction, mode: mode }), (0, _adapter.dropTargetForElements)({ element: element, getData: function getData(_ref2) { var input = _ref2.input; return (0, _closestEdge.attachClosestEdge)(data, { element: element, input: input, allowedEdges: direction === 'vertical' ? ['top', 'bottom'] : ['left', 'right'] }); }, canDrop: function canDrop(_ref3) { var source = _ref3.source; if (!(0, _data.isDraggableData)(source.data)) { // not dragging something from the migration layer // we should not allow dropping return false; } if (isDropDisabled) { return false; } return source.data.contextId === contextId && source.data.type === type; }, onDragLeave: function onDragLeave() { dispatch({ type: 'DRAG_CLEAR' }); } })); }, [data, droppableId, contextId, isDropDisabled, type, droppableRegistry, parentDroppableId, direction, mode]); var monitorForLifecycle = (0, _lifecycleContext.useMonitorForLifecycle)(); (0, _react.useEffect)(function () { function isEventRelevant(data) { var _data$destination; /** * If the draggable is of a different type to this droppable, * then we can ignore it. */ var isSameType = data.type === type; var isOverAfterUpdate = ((_data$destination = data.destination) === null || _data$destination === void 0 ? void 0 : _data$destination.droppableId) === droppableId; var isDragEnter = !isDraggingOver && isOverAfterUpdate; var isDragLeave = isDraggingOver && !isOverAfterUpdate; /** * A droppable will only have a meaningful state update if the user is entering or exiting it. */ var isDragEnterOrLeave = isDragEnter || isDragLeave; return isSameType && isDragEnterOrLeave; } return monitorForLifecycle({ onPendingDragStart: function onPendingDragStart(_ref4) { var start = _ref4.start; if (!isEventRelevant({ destination: start.source, type: start.type })) { return; } dispatch({ type: 'DRAG_START', payload: { droppableId: droppableId, start: start } }); }, onPendingDragUpdate: function onPendingDragUpdate(_ref5) { var update = _ref5.update; if (!isEventRelevant(update)) { return; } dispatch({ type: 'DRAG_UPDATE', payload: { droppableId: droppableId, update: update } }); }, onBeforeDragEnd: function onBeforeDragEnd() { /** * This is safe to call optimistically as it uses a stable idle state. * * If the droppable is already idle, it will not rerender. */ dispatch({ type: 'DRAG_CLEAR' }); } }); }, [droppableId, isDraggingOver, monitorForLifecycle, type]); var dropIndicator = (0, _react.useMemo)(function () { if (!isDraggingOver) { return null; } return /*#__PURE__*/_react.default.createElement(_dropIndicator.DropIndicator, { direction: direction, mode: mode }); }, [direction, isDraggingOver, mode]); var provided = (0, _react.useMemo)(function () { return { innerRef: setElement, droppableProps: (0, _defineProperty2.default)((0, _defineProperty2.default)({}, _attributes.attributes.droppable.contextId, contextId), _attributes.attributes.droppable.id, droppableId), /** * We only provide a drop indicator as the placeholder for * non-virtual lists. Otherwise it is portalled in. */ placeholder: mode === 'standard' ? dropIndicator : null }; }, [contextId, dropIndicator, droppableId, mode, setElement]); var snapshot = (0, _react.useMemo)(function () { return { draggingFromThisWith: draggingFromThisWith, draggingOverWith: draggingOverWith, isDraggingOver: isDraggingOver, isUsingPlaceholder: isDraggingOver }; }, [draggingFromThisWith, draggingOverWith, isDraggingOver]); var element = elementRef.current; var shouldPortalDropIndicator = isDraggingOver && mode === 'virtual' && element; /** * Assumes that the ref points to the scroll container. */ (0, _useIsomorphicLayoutEffect.useLayoutEffect)(function () { if (!shouldPortalDropIndicator) { return; } var _window$getComputedSt = window.getComputedStyle(element), position = _window$getComputedSt.position; if (position !== 'static') { return; } var prevStyle = element.style.position; element.style.position = 'relative'; return function () { element.style.position = prevStyle; }; }, [element, shouldPortalDropIndicator]); /** * Used to disable the dragging style for the real draggable. */ var shouldRenderCloneWhileDragging = Boolean(renderClone); var contextValue = (0, _react.useMemo)(function () { return { direction: direction, droppableId: droppableId, shouldRenderCloneWhileDragging: shouldRenderCloneWhileDragging, isDropDisabled: isDropDisabled, type: type, mode: mode }; }, [direction, droppableId, shouldRenderCloneWhileDragging, isDropDisabled, type, mode]); /** * For virtual lists we portal a placeholder in when dragging from the list. * * This is because `<Draggable />`'s can be unmounted at any time, so we * cannot rely on rendering the placeholder as a sibling. */ var shouldPortalPlaceholder = draggingFromThisWith && mode === 'virtual' && element; return /*#__PURE__*/_react.default.createElement(_droppableContext.DroppableContextProvider, { value: contextValue }, children(provided, snapshot), shouldPortalDropIndicator && /*#__PURE__*/(0, _reactDom.createPortal)(dropIndicator, element), shouldPortalPlaceholder && /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/_react.default.createElement(_virtualPlaceholder.VirtualPlaceholder, { droppableId: droppableId, draggableId: draggingFromThisWith, type: type, direction: direction, isDropDisabled: isDropDisabled }), element), renderClone && /*#__PURE__*/_react.default.createElement(_draggableClone.DraggableClone, { droppableId: droppableId, type: type, getContainerForClone: getContainerForClone }, renderClone)); }