wix-style-react
Version:
wix-style-react
502 lines (501 loc) • 18.4 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
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 _NestableListSt = require("./NestableList.st.css");
var _NestableListBase = _interopRequireDefault(require("../NestableListBase"));
var _TableListItem = _interopRequireDefault(require("../TableListItem"));
var _Box = _interopRequireDefault(require("../Box"));
var _Arrow = require("./Arrow");
var _TextButton = _interopRequireDefault(require("../TextButton"));
var _wixUiIconsCommon = require("@wix/wix-ui-icons-common");
var _utils = require("../NestableListBase/utils");
var _constants = require("./constants");
var _excluded = ["id", "children", "isCollapsed", "draggable"];
var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/NestableList/NestableList.js";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/** A styled list with drag and drop and nesting capabilities. */
class NestableList extends _react.default.PureComponent {
constructor() {
var _this;
super(...arguments);
_this = this;
this.state = {
movedItem: null,
backup: null,
isDragging: false,
isInternalStateUpdate: false,
items: this.props.items
};
// according to make possible use setState along with getDerivedStateFromProps
// https://stackoverflow.com/questions/51019936/why-getderivedstatefromprops-is-called-after-setstate
this._setStateDecorator = state => {
this.setState(_objectSpread(_objectSpread({}, state), {}, {
isInternalStateUpdate: true
}));
};
this._renderArrow = function () {
var {
isLastChild = false,
isPreview = false,
isPlaceholder
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return /*#__PURE__*/_react.default.createElement(_Box.default, {
className: _NestableListSt.classes.arrowContainer,
backgroundColor: isPlaceholder ? 'D60' : undefined,
direction: "vertical",
__self: _this,
__source: {
fileName: _jsxFileName,
lineNumber: 61,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement("div", {
className: (0, _NestableListSt.st)(_NestableListSt.classes.arrow, {
lastChild: isLastChild,
preview: isPreview,
placeholder: isPlaceholder
}),
__self: _this,
__source: {
fileName: _jsxFileName,
lineNumber: 66,
columnNumber: 9
}
}, /*#__PURE__*/_react.default.createElement(_Arrow.Arrow, {
className: _NestableListSt.classes.horizontalArrow,
__self: _this,
__source: {
fileName: _jsxFileName,
lineNumber: 73,
columnNumber: 11
}
})));
};
this._renderActions = data => {
var {
isRootAction,
veryLastItem,
item
} = data;
var actions = isRootAction ? this.props.actions : item.actions;
if (!actions) {
return null;
}
var dataHook = isRootAction ? 'nestable-list-root-actions' : item.actionsDataHook;
return /*#__PURE__*/_react.default.createElement("div", {
"data-hook": dataHook,
className: (0, _NestableListSt.st)(_NestableListSt.classes.item, {
rootAction: isRootAction,
dragging: this.state.isDragging,
withoutBottomBorder: !this.props.withBottomBorder && (veryLastItem && !actions || isRootAction)
}, _NestableListSt.classes.actionItem),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 90,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement(_TableListItem.default, {
onClick: e => {
if (actions.length === 1) {
actions[0].onClick(e, item);
}
},
options: actions.map((action, index, arr) => {
return {
width: "fit-content(".concat(100 / arr.length, "%)"),
value: /*#__PURE__*/_react.default.createElement(_TextButton.default, {
dataHook: "nestable-list-action",
ellipsis: true,
size: "small",
onClick: e => {
// if one element event handler is fired on table list item
if (arr.length !== 1) {
action.onClick(e, item);
}
},
prefixIcon: action.prefixIcon,
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 114,
columnNumber: 17
}
}, action.label)
};
}),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 104,
columnNumber: 9
}
}));
};
this._renderAction = 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, _NestableListSt.st)(_NestableListSt.classes.item, {
rootAction: data.isRootAction,
dragging: this.state.isDragging,
withoutBottomBorder: !this.props.withBottomBorder && (data.veryLastItem && !data.addItemLabel || data.isRootAction)
}, _NestableListSt.classes.actionItem),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 145,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement(_TableListItem.default, {
onClick: () => this.props.onAddItem(data.item),
options: [{
value: /*#__PURE__*/_react.default.createElement(_Box.default, {
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 164,
columnNumber: 17
}
}, /*#__PURE__*/_react.default.createElement(_TextButton.default, {
size: "small",
prefixIcon: /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Add, {
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 165,
columnNumber: 56
}
}),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 165,
columnNumber: 19
}
}, label))
}],
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 159,
columnNumber: 9
}
}));
};
this._renderPrefix = 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: _NestableListSt.classes.childArrow,
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 185,
columnNumber: 12
}
});
};
this._renderItem = options => {
var {
isPlaceholder,
depth,
isPreview,
isVeryLastItem,
siblings,
item
} = options;
var {
id,
children,
isCollapsed,
draggable = true
} = item,
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, _NestableListSt.st)(_NestableListSt.classes.itemWrapper, {
dragEnabled: draggable && !this.props.readOnly
}),
"data-hook": item.dataHook ? "".concat(item.dataHook, "-item") : "styled-nestable-list-item-".concat(item.id),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 196,
columnNumber: 7
}
}, !(0, _utils.isRootItem)(depth) && this._renderArrow({
isLastChild,
isPreview,
isPlaceholder
}), /*#__PURE__*/_react.default.createElement("div", {
className: (0, _NestableListSt.st)(_NestableListSt.classes.item, {
root: (0, _utils.isRootItem)(depth),
firstSibling: (0, _utils.isFistItem)(siblings, item),
placeholder: isPlaceholder,
preview: isPreview,
focused,
dragging: this.state.isDragging || focused,
withoutBottomBorder: isVeryLastItem && !this.props.withBottomBorder && !this.props.addItemLabel
}),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 212,
columnNumber: 9
}
}, /*#__PURE__*/_react.default.createElement(_TableListItem.default, (0, _extends2.default)({}, rest, {
focused: focused,
onBlur: this._onBlur,
onKeyUp: e => this._moveItemViaKeyboard(e, options),
showDivider: false,
dragging: isPreview || focused,
dragDisabled: !draggable && !this.props.readOnly,
draggable: !this.props.readOnly,
options: rest.options ? rest.options : [],
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 226,
columnNumber: 11
}
}))));
};
this._onBlur = () => {
this._releaseItems();
};
this._moveItemViaKeyboard = (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;
}
};
this._onDragEnd = () => {
this._setStateDecorator({
isDragging: false
});
};
this._onDragStart = () => {
this._setStateDecorator({
isDragging: true
});
};
this._renderActionsFactory = function () {
var data = arguments.length <= 0 ? undefined : arguments[0];
var actions = data.isRootAction ? _this.props.actions : data.item.actions;
if (actions) {
return _this._renderActions(...arguments);
}
return _this._renderAction(...arguments);
};
}
static getDerivedStateFromProps(props, state) {
if (state.isInternalStateUpdate) {
return _objectSpread(_objectSpread({}, state), {}, {
isInternalStateUpdate: false
});
}
return {
items: props.items
};
}
_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
});
}
}
render() {
var {
dataHook,
className,
maxDepth,
onChange,
preventChangeDepth,
readOnly,
zIndex
} = this.props;
return /*#__PURE__*/_react.default.createElement("div", {
"data-hook": dataHook,
className: (0, _NestableListSt.st)(_NestableListSt.classes.root, {
dragEnabled: !readOnly
}, className),
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 371,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement(_NestableListBase.default, {
items: this.state.items,
renderItem: this._renderItem,
renderPrefix: this._renderPrefix,
renderAction: this._renderActionsFactory,
onDragEnd: this._onDragEnd,
onDragStart: this._onDragStart,
onUpdate: _ref => {
var {
items,
item
} = _ref;
this._setStateDecorator({
items
});
onChange({
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,
zIndex: zIndex,
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 375,
columnNumber: 9
}
}), this._renderActionsFactory({
depth: 0,
isRootAction: true
}));
}
}
NestableList.displayName = 'NestableList';
var actions = _propTypes.default.arrayOf(_propTypes.default.shape({
onClick: _propTypes.default.func,
prefixIcon: _propTypes.default.node,
label: _propTypes.default.string
}));
var Node = _objectSpread({
id: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]).isRequired,
actions,
dataHook: _propTypes.default.string,
isCollapsed: _propTypes.default.bool,
addItemLabel: _propTypes.default.string
}, _TableListItem.default.propTypes);
var NodeShape = _propTypes.default.shape(Node);
Node.children = _propTypes.default.arrayOf(NodeShape);
NestableList.propTypes = {
/** Actions that will be rendered for on the root depth level */
actions,
/** 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/storybook/?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,
/** Defines the zIndex of the draggable layer */
zIndex: _propTypes.default.number
};
NestableList.defaultProps = {
maxDepth: 10,
withBottomBorder: false,
preventChangeDepth: false,
items: [],
onAddItem: () => {}
};
var _default = exports.default = NestableList;
//# sourceMappingURL=NestableList.js.map