UNPKG

@vtex/styleguide

Version:

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

610 lines (492 loc) 20.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _reactSticky = require("react-sticky"); var _propTypes = require("prop-types"); var _propTypes2 = _interopRequireDefault(_propTypes); var _reduce = require("lodash/reduce"); var _reduce2 = _interopRequireDefault(_reduce); var _map = require("lodash/map"); var _map2 = _interopRequireDefault(_map); var _isEmpty = require("lodash/isEmpty"); var _isEmpty2 = _interopRequireDefault(_isEmpty); var _difference = require("lodash/difference"); var _difference2 = _interopRequireDefault(_difference); var _Box = require("../Box"); var _Box2 = _interopRequireDefault(_Box); var _EmptyState = require("../EmptyState"); var _EmptyState2 = _interopRequireDefault(_EmptyState); var _FilterBar = require("../FilterBar"); var _FilterBar2 = _interopRequireDefault(_FilterBar); var _SimpleTable = require("./SimpleTable"); var _SimpleTable2 = _interopRequireDefault(_SimpleTable); var _Toolbar = require("./Toolbar"); var _Toolbar2 = _interopRequireDefault(_Toolbar); var _CheckboxContainer = require("./CheckboxContainer"); var _CheckboxContainer2 = _interopRequireDefault(_CheckboxContainer); var _Totalizer = require("../Totalizer"); var _Totalizer2 = _interopRequireDefault(_Totalizer); var _BulkActions = require("./BulkActions"); var _BulkActions2 = _interopRequireDefault(_BulkActions); var _SwitchablePagination = require("./SwitchablePagination"); var _SwitchablePagination2 = _interopRequireDefault(_SwitchablePagination); 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 Table = /*#__PURE__*/ function (_PureComponent) { _inheritsLoose(Table, _PureComponent); function Table(props) { var _this; _this = _PureComponent.call(this, props) || this; _this.getInitialHiddenFieldsFromSchema = function (schema) { var hiddenFields = []; Object.keys(schema.properties).forEach(function (key) { if (schema.properties[key].hidden) { hiddenFields.push(key); } }); return hiddenFields; }; _this.getRowHeight = function (density) { switch (density) { case 'low': return 76; case 'medium': return 48; case 'high': return 32; default: return 45; } }; _this.handleTableRowHeight = function (density) { var tableRowHeight = _this.state.tableRowHeight; var newHeight = _this.getRowHeight(density); if (tableRowHeight !== newHeight) { _this.setState({ tableRowHeight: newHeight, selectedDensity: density }); } }; _this.handleToggleColumn = function (key) { var _toolbar$fields; var hiddenFields = _this.state.hiddenFields; var newFieldsArray = hiddenFields.slice(); var index = hiddenFields.indexOf(key); index === -1 ? newFieldsArray.push(key) : newFieldsArray.splice(index, 1); _this.setState({ hiddenFields: newFieldsArray }); var toolbar = _this.props.toolbar; var activeFields = (0, _difference2.default)(Object.keys(_this.props.schema.properties), newFieldsArray); if (toolbar == null ? void 0 : (_toolbar$fields = toolbar.fields) == null ? void 0 : _toolbar$fields.onToggleColumn) { toolbar.fields.onToggleColumn({ toggledField: key, activeFields: activeFields }); } }; _this.handleShowAllColumns = function () { var _toolbar$fields2; _this.setState({ hiddenFields: [] }); var toolbar = _this.props.toolbar; if (toolbar == null ? void 0 : (_toolbar$fields2 = toolbar.fields) == null ? void 0 : _toolbar$fields2.onShowAllColumns) { toolbar.fields.onShowAllColumns(Object.keys(_this.props.schema.properties)); } }; _this.handleHideAllColumns = function () { var _toolbar$fields3; var newFieldsArray = Object.keys(_this.props.schema.properties); _this.setState({ hiddenFields: newFieldsArray }); var toolbar = _this.props.toolbar; if (toolbar == null ? void 0 : (_toolbar$fields3 = toolbar.fields) == null ? void 0 : _toolbar$fields3.onHideAllColumns) { toolbar.fields.onHideAllColumns([]); } }; _this.handleSelectionChange = function () { if (_this.props.bulkActions && _this.props.bulkActions.onChange) { var selectedParameters = _this.state.allLinesSelected ? { allLinesSelected: true } : { selectedRows: _this.state.selectedRows }; _this.props.bulkActions.onChange(selectedParameters); } }; _this.handleSelectAllLines = function () { var selectedRows = _this.props.items; _this.setState({ selectedRows: selectedRows, allLinesSelected: true }, _this.handleSelectionChange); }; _this.handleSelectAllVisibleLines = function () { var selectedRows = _this.state.selectedRows.slice(0); var items = _this.props.items; var itemsLength = items.length; if (selectedRows.length <= itemsLength && selectedRows.length !== 0) { _this.handleDeselectAllLines(); } else { _this.setState({ selectedRows: items }, _this.handleSelectionChange); } }; _this.handleSelectLine = function (rowData) { var selectedRows = _this.state.selectedRows.slice(0); var id = rowData.id; if (selectedRows.some(function (el) { return el.id === id; })) { var filteredRows = selectedRows.filter(function (row) { return row.id !== id; }); _this.setState({ selectedRows: filteredRows }, _this.handleSelectionChange); } else { selectedRows.push(_extends({}, rowData)); _this.setState({ selectedRows: selectedRows }, _this.handleSelectionChange); } }; _this.handleDeselectAllLines = function () { _this.setState({ selectedRows: [], allLinesSelected: false }, _this.handleSelectionChange); }; _this.handleInputSearchClearWithBulkAction = function (event) { var _this$props$toolbar$i = _this.props.toolbar.inputSearch.onClear, onClear = _this$props$toolbar$i === void 0 ? function () {} : _this$props$toolbar$i; _this.handleDeselectAllLines(); onClear(event); }; _this.state = { hiddenFields: _this.getInitialHiddenFieldsFromSchema(props.schema), tableRowHeight: _this.getRowHeight(props.density), selectedDensity: props.density, allChecked: false, selectedRows: _this.props.bulkActions.selectedRows || [], allLinesSelected: false }; return _this; } var _proto = Table.prototype; _proto.componentDidUpdate = function componentDidUpdate() { var bulkActions = this.props.bulkActions; var selectedRows = this.state.selectedRows; if (bulkActions && bulkActions.selectedRows && bulkActions.selectedRows !== selectedRows) { this.setState({ selectedRows: bulkActions.selectedRows }); } }; _proto.render = function render() { var _this2 = this; var _this$props = this.props, items = _this$props.items, schema = _this$props.schema, disableHeader = _this$props.disableHeader, emptyStateLabel = _this$props.emptyStateLabel, emptyStateChildren = _this$props.emptyStateChildren, fixFirstColumn = _this$props.fixFirstColumn, onRowClick = _this$props.onRowClick, onRowHover = _this$props.onRowHover, sort = _this$props.sort, onSort = _this$props.onSort, updateTableKey = _this$props.updateTableKey, containerHeight = _this$props.containerHeight, toolbar = _this$props.toolbar, pagination = _this$props.pagination, fullWidth = _this$props.fullWidth, dynamicRowHeight = _this$props.dynamicRowHeight, lineActions = _this$props.lineActions, loading = _this$props.loading, bulkActions = _this$props.bulkActions, totalizers = _this$props.totalizers, filters = _this$props.filters; var _this$state = this.state, hiddenFields = _this$state.hiddenFields, tableRowHeight = _this$state.tableRowHeight, selectedDensity = _this$state.selectedDensity, selectedRows = _this$state.selectedRows, allLinesSelected = _this$state.allLinesSelected; var hasPrimaryBulkAction = bulkActions && bulkActions.main && typeof bulkActions.main.handleCallback === 'function'; var hasSecondaryBulkActions = bulkActions.others && bulkActions.others.length > 0; var hasBulkActions = hasPrimaryBulkAction || hasSecondaryBulkActions; if (hasBulkActions) { schema.properties = _extends({ bulk: { width: 40, headerRenderer: function headerRenderer() { var selectedRows = _this2.state.selectedRows; var selectedRowsLength = selectedRows.length; var itemsLength = _this2.props.items.length; var isChecked = selectedRowsLength === itemsLength; var isPartial = selectedRowsLength > 0 && selectedRowsLength < itemsLength; return _react2.default.createElement(_CheckboxContainer2.default, { checked: isChecked, onClick: _this2.handleSelectAllVisibleLines, id: "all", partial: isPartial }); }, cellRenderer: function cellRenderer(_ref) { var rowData = _ref.rowData; return _react2.default.createElement(_CheckboxContainer2.default, { checked: _this2.state.selectedRows.some(function (row) { return row.id === rowData.id; }), onClick: function onClick() { return _this2.handleSelectLine(rowData); }, id: rowData.id, disabled: _this2.state.allLinesSelected }); } } }, schema.properties); items.map(function (item, i) { return item.id = i; }); } var properties = Object.keys(schema.properties); var emptyState = !!(properties.length === 0 || properties.length === hiddenFields.length); var displayProperties = (0, _reduce2.default)(schema.properties, function (acc, value, key) { var _extends2; if (hiddenFields.includes && hiddenFields.includes(key)) { return acc; } return _extends({}, acc, (_extends2 = {}, _extends2[key] = value, _extends2)); }, {}); var displaySchema = _extends({}, schema, { properties: displayProperties }); // if pagination and bulk actions features are active at the same time // when paginating, bulk actions active lines should be deselected var paginationClone = pagination ? Object.assign({}, pagination) : null; if (paginationClone && hasBulkActions) { paginationClone.onNextClick = function () { _this2.handleDeselectAllLines(); pagination.onNextClick(); }; paginationClone.onPrevClick = function () { _this2.handleDeselectAllLines(); pagination.onPrevClick(); }; } // extend toolbar's input search onClear when bulk action is turned on to // deselect all lines when clearing to avoid weird unwanted behaviors // until a permanent solution for https://github.com/vtex/styleguide/issues/873 // is found var extendedToolbar = toolbar ? _extends({}, toolbar, { inputSearch: toolbar.inputSearch ? _extends({}, toolbar.inputSearch, { onClear: hasBulkActions ? this.handleInputSearchClearWithBulkAction : toolbar.inputSearch.onClear }) : null }) : null; return _react2.default.createElement("div", { className: "vtex-table__container" }, extendedToolbar && _react2.default.createElement(_Toolbar2.default, { loading: loading, hiddenFields: hiddenFields, onToggleColumn: this.handleToggleColumn, onDeselectAllLines: this.handleDeselectAllLines, onHideAllColumns: this.handleHideAllColumns, onShowAllColumns: this.handleShowAllColumns, onToggleDensity: this.handleTableRowHeight, selectedDensity: selectedDensity, schema: schema, actions: extendedToolbar }), filters && _react2.default.createElement("div", { className: "mb5" }, _react2.default.createElement(_FilterBar2.default, filters)), totalizers && _react2.default.createElement("div", { className: "mb5" }, Array.isArray(totalizers) ? _react2.default.createElement(_Totalizer2.default, { items: totalizers }) : _react2.default.createElement(_Totalizer2.default, totalizers)), _react2.default.createElement(_SwitchablePagination2.default, _extends({ enabled: !loading && !(0, _isEmpty2.default)(paginationClone) }, paginationClone), _react2.default.createElement(_reactSticky.StickyContainer, null, _react2.default.createElement(_BulkActions2.default, { hasPrimaryBulkAction: hasPrimaryBulkAction, hasSecondaryBulkActions: hasSecondaryBulkActions, selectedRows: selectedRows, bulkActions: bulkActions, allLinesSelected: allLinesSelected, onSelectAllLines: this.handleSelectAllLines, onDeselectAllLines: this.handleDeselectAllLines }), emptyState ? _react2.default.createElement(_Box2.default, null, _react2.default.createElement(_EmptyState2.default, { title: emptyStateLabel }, emptyStateChildren)) : _react2.default.createElement(_SimpleTable2.default, { fullWidth: fullWidth, items: items, schema: displaySchema, fixFirstColumn: fixFirstColumn, rowHeight: tableRowHeight, disableHeader: disableHeader, emptyStateLabel: emptyStateLabel, emptyStateChildren: emptyStateChildren, dynamicRowHeight: dynamicRowHeight, onRowClick: onRowClick, onRowHover: onRowHover, sort: sort, onSort: onSort, key: hiddenFields.toString(), updateTableKey: updateTableKey, lineActions: lineActions, loading: loading, containerHeight: containerHeight, selectedRowsIndexes: (0, _map2.default)(selectedRows, 'id'), density: selectedDensity })))); }; return Table; }(_react.PureComponent); Table.defaultProps = { loading: false, density: 'medium', fixFirstColumn: false, toolbar: null, emptyStateLabel: 'Nothing to show.', fullWidth: false, bulkActions: {}, totalizers: [] }; Table.propTypes = { /** Array of objects with data */ items: _propTypes2.default.array.isRequired, /** JSON defining the data model schema for the items (More info about it after the examples) */ schema: _propTypes2.default.object.isRequired, /** Do not render the table header (only the rows) */ disableHeader: _propTypes2.default.bool, /** Fix first column so only the following ones scroll horizontaly */ fixFirstColumn: _propTypes2.default.bool, /** Callback invoked when a user clicks on a table row. ({ event: Event, index: number, rowData: any }): void */ onRowClick: _propTypes2.default.func, /** Callback invoked when a user hovers a table row. (rowIndex): void */ onRowHover: _propTypes2.default.func, /** Sort order and which property (key in schema) is table data sorted by. */ sort: _propTypes2.default.shape({ sortOrder: _propTypes2.default.oneOf(['ASC', 'DESC']), sortedBy: _propTypes2.default.string }), /** Callback to handle sort ({ sortOrder, sortedBy }) : object */ onSort: _propTypes2.default.func, /** Forces table re-render when changed */ updateTableKey: _propTypes2.default.string, /** In case you need precise control of table container height (number in pixels) */ containerHeight: _propTypes2.default.number, /** Row info visual density */ density: _propTypes2.default.oneOf(['low', 'medium', 'high']), /** Label for emptystate */ emptyStateLabel: _propTypes2.default.string, /** Children for emptystate */ emptyStateChildren: _propTypes2.default.node, /** Full width property */ fullWidth: _propTypes2.default.bool, /** Allows rows to show the full height of their content */ dynamicRowHeight: _propTypes2.default.bool, /** Line actions column */ lineActions: _propTypes2.default.arrayOf(_propTypes2.default.shape({ /** Function that returns a string for the action label */ label: _propTypes2.default.func, /** Mark whether the action performs a dangerous option or not */ isDangerous: _propTypes2.default.bool, /** Handles the callback function of the action */ onClick: _propTypes2.default.func })), /** Controls the table loading state */ loading: _propTypes2.default.bool, /** Toolbar (search and actions) */ toolbar: _propTypes2.default.shape({ inputSearch: _propTypes2.default.shape({ onSubmit: _propTypes2.default.func, onClear: _propTypes2.default.func }), density: _propTypes2.default.shape({ buttonLabel: _propTypes2.default.string, lowOptionLabel: _propTypes2.default.string, mediumOptionLabel: _propTypes2.default.string, highOptionLabel: _propTypes2.default.string, alignMenu: _propTypes2.default.oneOf(['right', 'left']), handleCallback: _propTypes2.default.func }), fields: _propTypes2.default.shape({ label: _propTypes2.default.string, showAllLabel: _propTypes2.default.string, hideAllLabel: _propTypes2.default.string, alignMenu: _propTypes2.default.oneOf(['right', 'left']), onToggleColumn: _propTypes2.default.func, onHideAllColumns: _propTypes2.default.func, onShowAllColumns: _propTypes2.default.func }), download: _propTypes2.default.shape({ label: _propTypes2.default.string, handleCallback: _propTypes2.default.func, disabled: _propTypes2.default.bool }), upload: _propTypes2.default.shape({ label: _propTypes2.default.string, handleCallback: _propTypes2.default.func, disabled: _propTypes2.default.bool }), extraActions: _propTypes2.default.shape({ label: _propTypes2.default.string, actions: _propTypes2.default.arrayOf(_propTypes2.default.shape({ label: _propTypes2.default.string, handleCallback: _propTypes2.default.func })), alignMenu: _propTypes2.default.oneOf(['right', 'left']) }), newLine: _propTypes2.default.shape({ label: _propTypes2.default.string.isRequired, handleCallback: _propTypes2.default.func.isRequired, disabled: _propTypes2.default.bool }) }), pagination: _propTypes2.default.shape({ onNextClick: _propTypes2.default.func, onPrevClick: _propTypes2.default.func, currentItemFrom: _propTypes2.default.number, currentItemTo: _propTypes2.default.number, textOf: _propTypes2.default.node, totalItems: _propTypes2.default.number }), bulkActions: _propTypes2.default.shape({ texts: _propTypes2.default.shape({ secondaryActionsLabel: _propTypes2.default.string.isRequired, rowsSelected: _propTypes2.default.func.isRequired, selectAll: _propTypes2.default.string, allRowsSelected: _propTypes2.default.func }), totalItems: _propTypes2.default.number, onChange: _propTypes2.default.func, selectedRows: _propTypes2.default.array, main: _propTypes2.default.shape({ label: _propTypes2.default.string.isRequired, handleCallback: _propTypes2.default.func.isRequired }), others: _propTypes2.default.arrayOf(_propTypes2.default.shape({ label: _propTypes2.default.string.isRequired, handleCallback: _propTypes2.default.func.isRequired })), fixed: _propTypes2.default.bool }), /** Totalizers property */ totalizers: _propTypes2.default.oneOfType([_propTypes2.default.array, _propTypes2.default.shape({ mobileScroll: _propTypes2.default.bool, horizontalLayout: _propTypes2.default.bool, items: _propTypes2.default.array })]), /** Filters property */ filters: _propTypes2.default.shape(_extends({}, _FilterBar2.default.propTypes)) }; exports.default = Table;