UNPKG

@vtex/styleguide

Version:

> VTEX Styleguide React components ([Docs](https://vtex.github.io/styleguide))

470 lines (414 loc) 17.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _propTypes = require("prop-types"); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactVirtualized = require("react-virtualized"); var _ArrowDown = require("../icon/ArrowDown"); var _ArrowDown2 = _interopRequireDefault(_ArrowDown); var _ArrowUp = require("../icon/ArrowUp"); var _ArrowUp2 = _interopRequireDefault(_ArrowUp); var _OptionsDots = require("../icon/OptionsDots"); var _OptionsDots2 = _interopRequireDefault(_OptionsDots); var _EmptyState = require("../EmptyState"); var _EmptyState2 = _interopRequireDefault(_EmptyState); var _Spinner = require("../Spinner"); var _Spinner2 = _interopRequireDefault(_Spinner); var _ActionMenu = require("../ActionMenu"); var _ActionMenu2 = _interopRequireDefault(_ActionMenu); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } var ARROW_SIZE = 11; var HEADER_HEIGHT = 36; var DEFAULT_COLUMN_WIDTH = 200; var LINE_ACTIONS_COLUMN_WIDTH = 70; var NO_TITLE_COLUMN = ' '; var SELECTED_ROW_BACKGROUND = '#dbe9fd'; var EMPTY_STATE_SIZE_IN_ROWS = 5; var SimpleTable = /*#__PURE__*/ function (_Component) { _inheritsLoose(SimpleTable, _Component); function SimpleTable(props) { var _this; _this = _Component.call(this, props) || this; _this.toggleSortType = function (key) { var _this$props$sort = _this.props.sort, _this$props$sort$pref = _this$props$sort.preferentialSortOrder, preferentialSortOrder = _this$props$sort$pref === void 0 ? 'ASC' : _this$props$sort$pref, sortOrder = _this$props$sort.sortOrder, sortedBy = _this$props$sort.sortedBy; if (sortedBy !== key) { return { sortOrder: preferentialSortOrder, sortedBy: key }; } return { sortOrder: sortOrder === 'ASC' ? 'DESC' : 'ASC', sortedBy: key }; }; _this.handleRowHover = function (rowIndex) { var _this$props = _this.props, onRowClick = _this$props.onRowClick, onRowHover = _this$props.onRowHover; var isLineActionsHovered = _this.state.isLineActionsHovered; if (onRowClick && !isLineActionsHovered) { _this.setState({ hoverRowIndex: rowIndex }); } else { _this.setState({ hoverRowIndex: -1 }); } onRowHover(rowIndex); }; _this.calculateColWidth = function (schema, properties, index, fullWidth, fullWidthColWidth) { var col = schema.properties[properties[index]]; return col.width ? col.width : fullWidth ? Math.max(col.minWidth || 100, fullWidthColWidth) : DEFAULT_COLUMN_WIDTH; }; _this.calculateRowHeight = function (index) { var _this$props2 = _this.props, disableHeader = _this$props2.disableHeader, dynamicRowHeight = _this$props2.dynamicRowHeight, rowHeight = _this$props2.rowHeight; var isHeader = !disableHeader && index === 0; if (isHeader) { return HEADER_HEIGHT; } if (dynamicRowHeight) { return _this._cache.rowHeight({ index: index }); } return rowHeight; }; _this.addLineActionsToSchema = function (schema, lineActions) { return _extends({}, schema.properties, { // eslint-disable-next-line camelcase _VTEX_Table_Internal_lineActions: { title: NO_TITLE_COLUMN, width: LINE_ACTIONS_COLUMN_WIDTH, cellRenderer: function cellRenderer(_ref) { var rowData = _ref.rowData; return _react2.default.createElement(_ActionMenu2.default, { buttonProps: { variation: 'tertiary', icon: _react2.default.createElement(_OptionsDots2.default, null), onMouseEnter: function onMouseEnter() { return _this.setState({ isLineActionsHovered: true }); }, onMouseLeave: function onMouseLeave() { return _this.setState({ isLineActionsHovered: false }); } }, options: lineActions.map(function (action) { return _extends({}, action, { label: action.label({ rowData: rowData }), onClick: function onClick() { return action.onClick({ rowData: rowData }); } }); }) }); } } }); }; _this.handleScrollbarPresenceChange = function (_ref2) { var horizontal = _ref2.horizontal, size = _ref2.size; if (horizontal) { _this.setState({ scrollbarWidth: size || 0 }); } }; _this.calculateContainerHeight = function () { var _this$props3 = _this.props, rowHeight = _this$props3.rowHeight, items = _this$props3.items, disableHeader = _this$props3.disableHeader; var scrollbarWidth = _this.state.scrollbarWidth; if (items.length === 0) { return HEADER_HEIGHT + rowHeight * EMPTY_STATE_SIZE_IN_ROWS + scrollbarWidth; } var rowCount = disableHeader ? items.length : items.length + 1; var rawTableHeight = 0; for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) { rawTableHeight += _this.calculateRowHeight(rowIndex); } return rawTableHeight + scrollbarWidth; }; _this.state = { hoverRowIndex: -1, tableHeight: 0, scrollbarWidth: 0 }; _this._cache = new _reactVirtualized.CellMeasurerCache({ defaultHeight: props.rowHeight, minHeight: props.rowHeight, fixedWidth: true }); return _this; } var _proto = SimpleTable.prototype; _proto.componentDidMount = function componentDidMount() { this.setState({ tableHeight: this.props.containerHeight || this.calculateContainerHeight() }); }; _proto.componentDidUpdate = function componentDidUpdate() { if (!this.props.containerHeight) { this.updateTableHeight(); } }; _proto.updateTableHeight = function updateTableHeight() { var calculatedContainerHeight = this.calculateContainerHeight(); if (this.state.tableHeight !== calculatedContainerHeight) { this.setState({ tableHeight: calculatedContainerHeight }); } }; _proto.render = function render() { var _this2 = this; var _this$props4 = this.props, schema = _this$props4.schema, items = _this$props4.items, fixFirstColumn = _this$props4.fixFirstColumn, disableHeader = _this$props4.disableHeader, density = _this$props4.density, emptyStateLabel = _this$props4.emptyStateLabel, emptyStateChildren = _this$props4.emptyStateChildren, onRowClick = _this$props4.onRowClick, _this$props4$sort = _this$props4.sort, sortOrder = _this$props4$sort.sortOrder, sortedBy = _this$props4$sort.sortedBy, onSort = _this$props4.onSort, updateTableKey = _this$props4.updateTableKey, fullWidth = _this$props4.fullWidth, lineActions = _this$props4.lineActions, loading = _this$props4.loading, selectedRowsIndexes = _this$props4.selectedRowsIndexes; var _this$state = this.state, hoverRowIndex = _this$state.hoverRowIndex, tableHeight = _this$state.tableHeight; if (lineActions) schema.properties = this.addLineActionsToSchema(schema, lineActions); var properties = Object.keys(schema.properties); var tableKey = "vtex-table--" + updateTableKey + "--" + density; return _react2.default.createElement("div", { className: "vh-100 w-100 dt", style: { height: tableHeight } }, loading ? _react2.default.createElement("div", { className: "dtc v-mid tc", style: { height: tableHeight - HEADER_HEIGHT } }, _react2.default.createElement(_Spinner2.default, null)) : _react2.default.createElement("div", { className: "h-100" }, _react2.default.createElement(_reactVirtualized.AutoSizer, { key: tableKey }, function (_ref3) { var width = _ref3.width; var colsWidth = Object.keys(schema.properties).reduce(function (acc, curr) { var col = schema.properties[curr]; return acc + (col.width ? col.width : 0); }, 0); var colsWithoutWidth = Object.keys(schema.properties).filter(function (curr) { var col = schema.properties[curr]; return !col.width; }); var fullWidthColWidth = (width - colsWidth) / colsWithoutWidth.length; return _react2.default.createElement(_reactVirtualized.MultiGrid, { onScrollbarPresenceChange: _this2.handleScrollbarPresenceChange, height: tableHeight, width: width, key: width, deferredMeasurementCache: _this2._cache, tabIndex: null, fixedRowCount: disableHeader ? 0 : 1, rowCount: disableHeader ? items.length : items.length + 1, rowHeight: function rowHeight(_ref4) { var index = _ref4.index; return _this2.calculateRowHeight(index); }, enableFixedRowScroll: !disableHeader, hideTopRightGridScrollbar: !disableHeader, overscanRowCount: 0, styleTopRightGrid: fixFirstColumn ? { overflow: 'hidden' } : {}, styleTopLeftGrid: fixFirstColumn ? { overflow: 'hidden' } : {}, fixedColumnCount: fixFirstColumn ? 1 : 0, columnCount: properties.length, columnWidth: function columnWidth(_ref5) { var index = _ref5.index; return _this2.calculateColWidth(schema, properties, index, fullWidth, fullWidthColWidth); }, enableFixedColumnScroll: true, overscanColumnCount: 0, cellRenderer: function cellRenderer(_ref6) { var columnIndex = _ref6.columnIndex, key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style, parent = _ref6.parent; var property = properties[columnIndex]; if (!disableHeader && rowIndex === 0) { // Header row var title = schema.properties[property].title || property; var headerRight = schema.properties[property].headerRight || false; var headerRenderer = schema.properties[property].headerRenderer; var arrowIsDown = sortOrder === 'ASC' && sortedBy === property; var arrowIsUp = sortOrder === 'DESC' && sortedBy === property; return _react2.default.createElement(_reactVirtualized.CellMeasurer, { cache: _this2._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, _react2.default.createElement("div", { key: key, style: _extends({}, style, { height: HEADER_HEIGHT }), className: "flex items-center w-100 h-100 c-muted-2 f6 truncate ph4 " + (columnIndex === 0 && fixFirstColumn ? 'br' : '') + " bt bb b--muted-4 overflow-x-hidden " + (headerRight ? 'tr' : 'tl') }, schema.properties[property].sortable ? _react2.default.createElement("div", { className: "w-100 pointer c-muted-1 b t-small", onClick: function onClick() { onSort(_this2.toggleSortType(property)); } }, !headerRight && title, _react2.default.createElement("div", { className: "inline-flex " + (headerRight ? 'pr2' : 'pl3') }, arrowIsDown ? _react2.default.createElement(_ArrowDown2.default, { size: ARROW_SIZE }) : arrowIsUp ? _react2.default.createElement(_ArrowUp2.default, { size: ARROW_SIZE }) : null), headerRight && title) : columnIndex === 0 && fixFirstColumn ? _react2.default.createElement("div", { className: "w-100" }, title) : headerRenderer ? headerRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style, title: title }) : _react2.default.createElement("span", { className: "w-100" }, title))); } var cellRenderer = schema.properties[property].cellRenderer; var rowData = items[disableHeader ? rowIndex : rowIndex - 1]; var cellData = rowData[property]; var cellClassNames = "flex items-center w-100 h-100 ph4 bb\n b--muted-4 truncate " + (disableHeader && rowIndex === 0 ? 'bt' : '') + " " + (onRowClick && rowIndex === hoverRowIndex ? 'pointer bg-near-white c-link' : '') + " " + (columnIndex === 0 && fixFirstColumn ? 'br' : ''); return _react2.default.createElement(_reactVirtualized.CellMeasurer, { cache: _this2._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, function (_ref7) { var updateCellMeasurements = _ref7.measure; return _react2.default.createElement("div", { key: key, style: _extends({}, style, { height: _this2.calculateRowHeight(rowIndex), width: _this2.calculateColWidth(schema, properties, columnIndex, fullWidth, fullWidthColWidth), backgroundColor: selectedRowsIndexes.includes(rowIndex - 1) ? SELECTED_ROW_BACKGROUND : '' }), className: cellClassNames, onClick: onRowClick && property !== '_VTEX_Table_Internal_lineActions' ? function (event) { return onRowClick({ event: event, index: rowIndex, rowData: rowData }); } : null, onMouseEnter: onRowClick ? function () { return _this2.handleRowHover(rowIndex); } : null, onMouseLeave: onRowClick ? function () { return _this2.handleRowHover(-1); } : null }, cellRenderer ? cellRenderer({ cellData: cellData, rowData: rowData, updateCellMeasurements: updateCellMeasurements }) : cellData); }); } }); }), items.length === 0 && _react2.default.createElement("div", { className: "h-100", style: { paddingTop: HEADER_HEIGHT } }, _react2.default.createElement(_EmptyState2.default, { title: emptyStateLabel }, emptyStateChildren)))); }; return SimpleTable; }(_react.Component); SimpleTable.defaultProps = { indexColumnLabel: null, fixFirstColumn: false, items: [], disableHeader: false, sort: { sortOrder: null, sortedBy: null }, fullWidth: false, dynamicRowHeight: false, selectedRowsIndexes: [], onRowHover: function onRowHover() {} }; SimpleTable.propTypes = { items: _propTypes2.default.array.isRequired, schema: _propTypes2.default.object.isRequired, indexColumnLabel: _propTypes2.default.string, fixFirstColumn: _propTypes2.default.bool, density: _propTypes2.default.string, disableHeader: _propTypes2.default.bool, onRowClick: _propTypes2.default.func, onRowHover: _propTypes2.default.func, emptyStateLabel: _propTypes2.default.string, emptyStateChildren: _propTypes2.default.node, sort: _propTypes2.default.shape({ sortOrder: _propTypes2.default.oneOf(['ASC', 'DESC']), sortedBy: _propTypes2.default.string, preferentialSortOrder: _propTypes2.default.oneOf(['ASC', 'DESC']) }), onSort: _propTypes2.default.func, updateTableKey: _propTypes2.default.string, containerHeight: _propTypes2.default.number, rowHeight: _propTypes2.default.number.isRequired, dynamicRowHeight: _propTypes2.default.bool, fullWidth: _propTypes2.default.bool, lineActions: _propTypes2.default.arrayOf(_propTypes2.default.shape({ label: _propTypes2.default.func, isDangerous: _propTypes2.default.bool, onClick: _propTypes2.default.func })), loading: _propTypes2.default.bool, selectedRowsIndexes: _propTypes2.default.array }; exports.default = SimpleTable;