UNPKG

wix-style-react

Version:
424 lines (353 loc) 17.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _NestableListThemeSt = require("./NestableListTheme.st.css"); var _StyledNestableListSt = require("./StyledNestableList.st.css"); var _NestableList = _interopRequireDefault(require("../NestableList")); var _TableListItem = _interopRequireDefault(require("../TableListItem")); var _Box = _interopRequireDefault(require("../Box")); var _Arrow = require("./Arrow"); var _TextButton = _interopRequireDefault(require("../TextButton")); var _Add = _interopRequireDefault(require("wix-ui-icons-common/Add")); var _utils = require("../NestableList/utils"); var _constants = require("./constants"); var _excluded = ["id", "children", "isCollapsed", "draggable"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /** A styled list with drag and drop and nesting capabilities. */ var StyledNestableList = /*#__PURE__*/function (_React$PureComponent) { (0, _inherits2["default"])(StyledNestableList, _React$PureComponent); var _super = _createSuper(StyledNestableList); function StyledNestableList() { var _this; (0, _classCallCheck2["default"])(this, StyledNestableList); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { movedItem: null, backup: null, isDragging: false, isInternalStateUpdate: false, items: _this.props.items }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setStateDecorator", function (state) { _this.setState(_objectSpread(_objectSpread({}, state), {}, { isInternalStateUpdate: true })); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderArrow", function () { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$isLastChild = _ref.isLastChild, isLastChild = _ref$isLastChild === void 0 ? false : _ref$isLastChild, _ref$isPreview = _ref.isPreview, isPreview = _ref$isPreview === void 0 ? false : _ref$isPreview, isPlaceholder = _ref.isPlaceholder; return /*#__PURE__*/_react["default"].createElement(_Box["default"], { className: _StyledNestableListSt.classes.arrowContainer, backgroundColor: isPlaceholder ? 'D60' : undefined, direction: 'vertical' }, /*#__PURE__*/_react["default"].createElement("div", { className: (0, _StyledNestableListSt.st)(_StyledNestableListSt.classes.arrow, { lastChild: isLastChild, preview: isPreview, placeholder: isPlaceholder }) }, /*#__PURE__*/_react["default"].createElement(_Arrow.Arrow, { className: _StyledNestableListSt.classes.horizontalArrow }))); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderAction", function (data) { var label = data.isRootAction ? _this.props.addItemLabel : data.item.addItemLabel; if (!label || _this.props.maxDepth <= data.depth) { return; } return /*#__PURE__*/_react["default"].createElement(_Box["default"], { direction: 'vertical', className: (0, _StyledNestableListSt.st)(_StyledNestableListSt.classes.item, { rootAction: data.isRootAction, dragging: _this.state.isDragging, withoutBottomBorder: !_this.props.withBottomBorder && (data.veryLastItem && !data.addItemLabel || data.isRootAction) }, _StyledNestableListSt.classes.actionItem) }, /*#__PURE__*/_react["default"].createElement(_TableListItem["default"], { onClick: function onClick() { return _this.props.onAddItem(data.item); }, options: [{ value: /*#__PURE__*/_react["default"].createElement(_Box["default"], null, /*#__PURE__*/_react["default"].createElement(_TextButton["default"], { size: 'small', prefixIcon: /*#__PURE__*/_react["default"].createElement(_Add["default"], null) }, label)) }] })); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderPrefix", function (data) { if (data.isPreview || (0, _utils.isLastItem)(data.siblings, data.item) || (0, _utils.isRootItem)(data.depth)) { return null; } return /*#__PURE__*/_react["default"].createElement("div", { className: _StyledNestableListSt.classes.childArrow }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderItem", function (options) { var isPlaceholder = options.isPlaceholder, depth = options.depth, isPreview = options.isPreview, isVeryLastItem = options.isVeryLastItem, siblings = options.siblings, item = options.item; var id = item.id, children = item.children, isCollapsed = item.isCollapsed, _item$draggable = item.draggable, draggable = _item$draggable === void 0 ? true : _item$draggable, rest = (0, _objectWithoutProperties2["default"])(item, _excluded); var isLastChild = (0, _utils.isLastItem)(siblings, item); var focused = _this.state.movedItem && id === _this.state.movedItem.id; return /*#__PURE__*/_react["default"].createElement("div", { className: (0, _StyledNestableListSt.st)(_StyledNestableListSt.classes.itemWrapper, { dragEnabled: draggable && !_this.props.readOnly }), "data-hook": "styled-nestable-list-item-".concat(item.id) }, !(0, _utils.isRootItem)(depth) && _this._renderArrow({ isLastChild: isLastChild, isPreview: isPreview, isPlaceholder: isPlaceholder }), /*#__PURE__*/_react["default"].createElement("div", { className: (0, _StyledNestableListSt.st)(_StyledNestableListSt.classes.item, { root: (0, _utils.isRootItem)(depth), firstSibling: (0, _utils.isFistItem)(siblings, item), placeholder: isPlaceholder, preview: isPreview, focused: focused, dragging: _this.state.isDragging || focused, withoutBottomBorder: isVeryLastItem && !_this.props.withBottomBorder && !_this.props.addItemLabel }) }, /*#__PURE__*/_react["default"].createElement(_TableListItem["default"], (0, _extends2["default"])({}, rest, { focused: focused, onBlur: _this._onBlur, onKeyUp: function onKeyUp(e) { return _this._moveItemViaKeyboard(e, options); }, showDivider: false, dragging: isPreview || focused, dragDisabled: !draggable && !_this.props.readOnly, draggable: !_this.props.readOnly, options: rest.options ? rest.options : [] })))); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onBlur", function () { _this._releaseItems(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_moveItemViaKeyboard", function (e, itemOptions) { var left = 'ArrowLeft'; var top = 'ArrowUp'; var right = 'ArrowRight'; var bottom = 'ArrowDown'; var enter = 'Enter'; var esc = 'Escape'; // start dragend-drop if (e.key === enter && !_this.state.movedItem) { _this._setStateDecorator({ backup: _this.state.items, movedItem: itemOptions.item, items: (0, _utils.setCollapse)(_this.state.items, itemOptions.item.id, true) }); } if (!_this.state.movedItem) { return; } switch (e.key) { case esc: _this._setStateDecorator({ items: _this.state.backup, backup: null, movedItem: null }); break; case left: if (!_this.props.preventChangeDepth) { _this._setStateDecorator({ items: (0, _utils.moveItemOutsideOfTheParent)(_this.state.items, itemOptions.item) }); } break; case right: if (!_this.props.preventChangeDepth) { _this._setStateDecorator({ items: (0, _utils.moveItemToTheChildOfPrevSibling)(_this.state.items, itemOptions.item) }); } break; case top: _this._setStateDecorator({ items: (0, _utils.moveItemVertically)(_this.state.items, itemOptions.item, _utils.VerticalMovementDirection.top) }); break; case bottom: _this._setStateDecorator({ items: (0, _utils.moveItemVertically)(_this.state.items, itemOptions.item, _utils.VerticalMovementDirection.bottom) }); break; default: case enter: _this._releaseItems(); break; } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onDragEnd", function () { _this._setStateDecorator({ isDragging: false }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onDragStart", function () { _this._setStateDecorator({ isDragging: true }); }); return _this; } (0, _createClass2["default"])(StyledNestableList, [{ key: "_releaseItems", value: function _releaseItems() { if (this.state.movedItem) { var releaseItems = (0, _utils.setCollapse)(this.state.items, this.state.movedItem.id, this.state.movedItem.isCollapsed); this.props.onChange({ items: releaseItems, item: this.state.movedItem }); this._setStateDecorator({ movedItem: null, backup: null, items: releaseItems }); } } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, dataHook = _this$props.dataHook, className = _this$props.className, maxDepth = _this$props.maxDepth, onChange = _this$props.onChange, preventChangeDepth = _this$props.preventChangeDepth, readOnly = _this$props.readOnly; return /*#__PURE__*/_react["default"].createElement("div", { "data-hook": dataHook, className: (0, _StyledNestableListSt.st)(_StyledNestableListSt.classes.root, { dragEnabled: !readOnly }, className) }, /*#__PURE__*/_react["default"].createElement(_NestableList["default"], { items: this.state.items, renderItem: this._renderItem, renderPrefix: this._renderPrefix, renderAction: this._renderAction, onDragEnd: this._onDragEnd, onDragStart: this._onDragStart, onUpdate: function onUpdate(_ref2) { var items = _ref2.items, item = _ref2.item; _this2._setStateDecorator({ items: items }); onChange({ items: items, item: item.data }); }, maxDepth: maxDepth, threshold: _constants.DEPTH_THRESHOLD, theme: _NestableListThemeSt.classes, readOnly: readOnly, preventChangeDepth: preventChangeDepth, childrenStyle: { position: 'relative', marginLeft: "".concat(_constants.DEPTH_THRESHOLD, "px") }, childrenProperty: 'children', isRenderDraggingChildren: false }), this.props.addItemLabel && this._renderAction({ depth: 0, isRootAction: true })); } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(props, state) { if (state.isInternalStateUpdate) { return _objectSpread(_objectSpread({}, state), {}, { isInternalStateUpdate: false }); } return { items: props.items }; } }]); return StyledNestableList; }(_react["default"].PureComponent); StyledNestableList.displayName = 'StyledNestableList'; var Node = _objectSpread({ id: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]).isRequired, isCollapsed: _propTypes["default"].bool, addItemLabel: _propTypes["default"].string }, _TableListItem["default"].propTypes); var NodeShape = _propTypes["default"].shape(Node); Node.children = _propTypes["default"].arrayOf(NodeShape); StyledNestableList.propTypes = { /** Adds a bottom border (divider) to the last item. */ withBottomBorder: _propTypes["default"].bool, /** Prevents the list from being reordered by removing the dragging grip icons. */ readOnly: _propTypes["default"].bool, /** Adds a button to create a new item (to the Root or a child to the existing item). */ addItemLabel: _propTypes["default"].string, /** Triggers function when the "Add new ..." button is clicked. */ onAddItem: _propTypes["default"].func, /** Triggers function when the item’s order or nesting position is changed. */ onChange: _propTypes["default"].func, /** Defines a maximum depth (number of levels) for the list. */ maxDepth: _propTypes["default"].number, /** Allows dragging and dropping an item only on its own depth (inside the same level). */ preventChangeDepth: _propTypes["default"].bool, /** * Defines each Nestable List item individually, using the following props: * * __id__ - specifies an item’s ID. * * __addItemLabel__ - creates the “Add new ...” button with a given label at the bottom of the item. * * __isCollapsed__ - bool prop, defines whether to render the item’s children. * * __children__ - defines an item’s children. * * __draggable__ - bool prop, turns on / off dragging ability for an item. * * All <a href="https://www.wix-style-react.com/?path=/story/components-lists-table--tablelistitem" target="_blank">`<TableListItem/>`</a> props can be used to format item’s style and content. */ items: _propTypes["default"].arrayOf(NodeShape), /** Can be applied in the tests as a data-hook HTML attribute. */ dataHook: _propTypes["default"].string, /** Defines a CSS class to be applied to the component's Root element. */ className: _propTypes["default"].string }; StyledNestableList.defaultProps = { maxDepth: 10, withBottomBorder: false, preventChangeDepth: false, items: [], onAddItem: function onAddItem() {} }; var _default = StyledNestableList; exports["default"] = _default;