UNPKG

@wix/design-system

Version:

@wix/design-system

325 lines (322 loc) 13.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _react = _interopRequireDefault(require("react")); var _utils = require("./utils"); var _DragLayer = _interopRequireDefault(require("./DragLayer")); var _Container = _interopRequireDefault(require("./Container")); var _VirtualContainer = _interopRequireDefault(require("./VirtualContainer")); var _AutoScroller = _interopRequireDefault(require("./AutoScroller")); var _NestableListBaseContext = require("./NestableListBaseContext"); var _withDNDContext = _interopRequireDefault(require("./withDNDContext")); var _ZIndex = require("../common/ZIndex"); var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/NestableListBase/NestableListBase.jsx"; function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function replaceNegativeIndex(items, nextPosition, childrenProperty) { var currItems = items; return nextPosition.map(function (nextIndex) { if (nextIndex !== -1) { currItems = currItems[nextIndex][childrenProperty] || []; return nextIndex; } return currItems.length; }); } // fixing a bug where the new path is increased in nesting // and the first position jumps too far by 2, and that's why it decreased by 1 // need to check if the jump can become more severe function getRealNextPosition(prev, next) { // moving up a level if (prev.length < next.length) { return next.map(function (nextIndex, i) { if (typeof prev[i] !== 'number') { return nextIndex; } return nextIndex > prev[i] ? nextIndex - 1 : nextIndex; }); } return next; } var NestableListBase = /*#__PURE__*/function (_React$PureComponent) { function NestableListBase() { var _this; (0, _classCallCheck2["default"])(this, NestableListBase); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, NestableListBase, [].concat(args)); _this.state = { items: _this.props.items, dragging: false }; _this.containerRef = /*#__PURE__*/_react["default"].createRef(); // drag and drop between multiple nestable lists is not supported // according to prevent it for now was created groupName - unique value for every nestable list // somethings similar exists in SortableListBase component. _this.groupName = (0, _utils.generateUniqueGroupId)(); // FIXME: reference to latest `state.items`. This is a workaround for issue // with `moveItem` where it updates `state.items` and if the update occurs // multiple times before the component re-renders, the `state.items` will be // be updated based on the previous state, not the latest one, which in some // cases leads to item duplication or removal. // This should be solved by not referring to current state by `this.state` and // instead providing callback to `setState` that receives the latest state. // However, due to architectural decisions this is not possible without // rewriting the whole component as `moveItem` must return new position of the // dragged item which is then used by the item itself to update its state. _this._items = _this.props.items; _this.moveItem = function (_ref) { var dragItem = _ref.dragItem, prevPosition = _ref.prevPosition, nextPosition = _ref.nextPosition; var _this$props = _this.props, childrenProperty = _this$props.childrenProperty, preventChangeDepth = _this$props.preventChangeDepth, preventChangeParent = _this$props.preventChangeParent, enforcePinnedOrder = _this$props.enforcePinnedOrder, items = _this$props.items; if (dragItem.preventItemChangeDepth && nextPosition.length !== prevPosition.length) { return prevPosition; } if (preventChangeDepth && nextPosition.length > 1) { var parent = (0, _utils.getDropParent)(items, nextPosition, childrenProperty); if (!parent) { return prevPosition; } } if (preventChangeParent) { var prevParentPath = prevPosition.slice(0, -1); var nextParentPath = nextPosition.slice(0, -1); var prevParent = (0, _utils.getDropParent)(items, prevParentPath, childrenProperty); var nextParent = (0, _utils.getDropParent)(items, nextParentPath, childrenProperty); if ((prevParent == null ? void 0 : prevParent.id) !== (nextParent == null ? void 0 : nextParent.id)) { return prevPosition; } } var newItems = _this._items; // the remove action might affect the next position, // so update next coordinates accordingly var realNextPosition = getRealNextPosition(prevPosition, nextPosition); if (enforcePinnedOrder) { var shouldProhibitPinMoveDown = !!dragItem.isPinned && !realNextPosition.isPinned; var shouldProhibitNonPinMoveUp = !dragItem.isPinned && !!realNextPosition.isPinned; if (shouldProhibitPinMoveDown && shouldProhibitNonPinMoveUp) { return prevPosition; } } if (realNextPosition[realNextPosition.length - 1] === -1) { realNextPosition = replaceNegativeIndex(newItems, realNextPosition, childrenProperty); } newItems = (0, _utils.removeFromTree)(newItems, prevPosition, childrenProperty); newItems = (0, _utils.addToTree)(newItems, dragItem, realNextPosition, childrenProperty); _this._items = newItems; _this.setState({ items: newItems }); return realNextPosition; }; _this.dropItem = function (item) { _this.props.onUpdate == null || _this.props.onUpdate({ items: _this.state.items, item: item }); }; _this.onDragStart = function (itemProps) { _this.setState({ dragging: true }); _this.props.onDragStart == null || _this.props.onDragStart(itemProps); }; _this.onDragEnd = function (itemProps) { _this.setState({ dragging: false }); _this.props.onDragEnd == null || _this.props.onDragEnd(itemProps); }; return _this; } (0, _inherits2["default"])(NestableListBase, _React$PureComponent); return (0, _createClass2["default"])(NestableListBase, [{ key: "UNSAFE_componentWillReceiveProps", value: // tried to use getDerivedStateFromProps but encounter an issue where the state was // updated internally but props items stayed the same and it caused the new state to be // overridden with the old state // can be done if component is controlled but requires refactor function UNSAFE_componentWillReceiveProps(newProps) { if (newProps.items !== this.state.items && !this.state.dragging) { this.setState({ items: newProps.items }); this._items = newProps.items; } } }, { key: "render", value: function render() { var items = this.state.items; var _this$props2 = this.props, renderItem = _this$props2.renderItem, readOnly = _this$props2.readOnly, childrenProperty = _this$props2.childrenProperty, childrenStyle = _this$props2.childrenStyle, renderAction = _this$props2.renderAction, isRenderDraggingChildren = _this$props2.isRenderDraggingChildren, useDragHandle = _this$props2.useDragHandle, maxDepth = _this$props2.maxDepth, preventChangeDepth = _this$props2.preventChangeDepth, preventChangeParent = _this$props2.preventChangeParent, enforcePinnedOrder = _this$props2.enforcePinnedOrder, canDrop = _this$props2.canDrop, threshold = _this$props2.threshold, theme = _this$props2.theme, renderPrefix = _this$props2.renderPrefix, dragLayerZIndex = _this$props2.dragLayerZIndex, zIndex = _this$props2.zIndex, virtualized = _this$props2.virtualized, itemHeight = _this$props2.itemHeight, viewportHeight = _this$props2.viewportHeight, offscreenRowCount = _this$props2.offscreenRowCount, pinnedItemId = _this$props2.pinnedItemId; var useVirtualized = virtualized && Number(itemHeight) > 0 && Number(viewportHeight) > 0; if (virtualized && !useVirtualized) { console.warn('NestableListBase: `virtualized` requires both `itemHeight` and ' + '`viewportHeight` to be positive numbers. Falling back to ' + 'non-virtualized rendering.'); } var dragOverlay = this.state.dragging && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 230, columnNumber: 7 } }, /*#__PURE__*/_react["default"].createElement(_DragLayer["default"], { siblings: items, isRenderDraggingChildren: isRenderDraggingChildren, renderItem: renderItem, childrenProperty: childrenProperty, childrenStyle: childrenStyle, theme: theme, dragLayerZIndex: zIndex !== null && zIndex !== void 0 ? zIndex : dragLayerZIndex, __self: this, __source: { fileName: _jsxFileName, lineNumber: 231, columnNumber: 9 } }), /*#__PURE__*/_react["default"].createElement(_AutoScroller["default"], { containerRef: this.containerRef, __self: this, __source: { fileName: _jsxFileName, lineNumber: 240, columnNumber: 9 } })); return /*#__PURE__*/_react["default"].createElement(_NestableListBaseContext.NestableListBaseContext.Provider, { value: { groupName: this.groupName, useDragHandle: useDragHandle, maxDepth: maxDepth, preventChangeDepth: preventChangeDepth, preventChangeParent: preventChangeParent, enforcePinnedOrder: enforcePinnedOrder, canDrop: canDrop, threshold: threshold, readOnly: readOnly, renderItem: renderItem, renderPrefix: renderPrefix, moveItem: this.moveItem, dropItem: this.dropItem, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 245, columnNumber: 7 } }, useVirtualized ? /*#__PURE__*/_react["default"].createElement("div", { __self: this, __source: { fileName: _jsxFileName, lineNumber: 265, columnNumber: 11 } }, /*#__PURE__*/_react["default"].createElement(_VirtualContainer["default"], { ref: this.containerRef, items: items, renderAction: renderAction, childrenProperty: childrenProperty, childrenStyle: childrenStyle, isRenderDraggingChildren: isRenderDraggingChildren, theme: theme, itemHeight: itemHeight, viewportHeight: viewportHeight, offscreenRowCount: offscreenRowCount, pinnedItemId: pinnedItemId, __self: this, __source: { fileName: _jsxFileName, lineNumber: 266, columnNumber: 13 } }), dragOverlay) : /*#__PURE__*/_react["default"].createElement("div", { ref: this.containerRef, __self: this, __source: { fileName: _jsxFileName, lineNumber: 282, columnNumber: 11 } }, /*#__PURE__*/_react["default"].createElement(_Container["default"], { treeDepth: 1, items: items, renderAction: renderAction, parentPosition: [], childrenProperty: childrenProperty, childrenStyle: childrenStyle, isRenderDraggingChildren: isRenderDraggingChildren, topLevel: true, theme: theme, __self: this, __source: { fileName: _jsxFileName, lineNumber: 283, columnNumber: 13 } }), dragOverlay)); } }]); }(_react["default"].PureComponent); NestableListBase.displayName = 'NestableListBase'; NestableListBase.defaultProps = { items: [], isRenderDraggingChildren: false, childrenProperty: 'children', childrenStyle: {}, renderPrefix: function renderPrefix() { return null; }, renderAction: function renderAction() { return null; }, onUpdate: function onUpdate() {}, useDragHandle: false, preventChangeDepth: false, preventChangeParent: false, enforcePinnedOrder: false, maxDepth: Infinity, threshold: 30, dragLayerZIndex: _ZIndex.ZIndex.nestableListDragLayer, virtualized: false, offscreenRowCount: 5 }; var _default = exports["default"] = (0, _withDNDContext["default"])(NestableListBase);