wix-style-react
Version:
424 lines (353 loc) • 17.5 kB
JavaScript
"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;