UNPKG

@helpscout/hsds-react

Version:

React component library for Help Scout's Design System

345 lines (287 loc) 14.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.Table = Table; exports.default = exports.TABLE_CLASSNAME = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _useDeepCompareEffect = _interopRequireDefault(require("use-deep-compare-effect")); var _styledComponents = require("styled-components"); var _classnames = _interopRequireDefault(require("classnames")); var _lodash = _interopRequireDefault(require("lodash.isnil")); var _Scrollable = _interopRequireDefault(require("../Scrollable")); var _Table = require("./Table.css"); var _Table2 = require("./Table.skins"); var _Table3 = require("./Table.utils"); var _Table4 = require("./Table.hooks"); var _Table5 = _interopRequireDefault(require("./Table.Body")); var _Table6 = _interopRequireDefault(require("./Table.Head")); var _Table7 = _interopRequireDefault(require("./Table.ColumnChooser")); var _jsxRuntime = require("react/jsx-runtime"); function noop() {} var TABLE_CLASSNAME = 'c-Table'; exports.TABLE_CLASSNAME = TABLE_CLASSNAME; function Table(_ref) { var animateRows = _ref.animateRows, className = _ref.className, _ref$columns = _ref.columns, columns = _ref$columns === void 0 ? [] : _ref$columns, columnChooserResetLabel = _ref.columnChooserResetLabel, _ref$containerWidth = _ref.containerWidth, containerWidth = _ref$containerWidth === void 0 ? '100%' : _ref$containerWidth, _ref$data = _ref.data, data = _ref$data === void 0 ? [] : _ref$data, _ref$dataCy = _ref['data-cy'], dataCy = _ref$dataCy === void 0 ? 'Table' : _ref$dataCy, expanderText = _ref.expanderText, headerContent = _ref.headerContent, _ref$isLoading = _ref.isLoading, isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading, _ref$isScrollLocked = _ref.isScrollLocked, isScrollLocked = _ref$isScrollLocked === void 0 ? true : _ref$isScrollLocked, maxRowsToDisplay = _ref.maxRowsToDisplay, _ref$onColumnChoose = _ref.onColumnChoose, onColumnChoose = _ref$onColumnChoose === void 0 ? noop : _ref$onColumnChoose, _ref$onExpand = _ref.onExpand, onExpand = _ref$onExpand === void 0 ? noop : _ref$onExpand, _ref$onRowClick = _ref.onRowClick, onRowClick = _ref$onRowClick === void 0 ? null : _ref$onRowClick, _ref$onSelectRow = _ref.onSelectRow, onSelectRow = _ref$onSelectRow === void 0 ? noop : _ref$onSelectRow, _ref$rowClassName = _ref.rowClassName, rowClassName = _ref$rowClassName === void 0 ? noop : _ref$rowClassName, _ref$rowWrapper = _ref.rowWrapper, rowWrapper = _ref$rowWrapper === void 0 ? null : _ref$rowWrapper, _ref$selectionKey = _ref.selectionKey, selectionKey = _ref$selectionKey === void 0 ? 'id' : _ref$selectionKey, _ref$skin = _ref.skin, skin = _ref$skin === void 0 ? _Table2.defaultSkin : _ref$skin, _ref$sortedInfo = _ref.sortedInfo, sortedInfo = _ref$sortedInfo === void 0 ? { columnKey: null, order: null } : _ref$sortedInfo, tableClassName = _ref.tableClassName, tableDescription = _ref.tableDescription, _ref$tableRole = _ref.tableRole, tableRole = _ref$tableRole === void 0 ? 'table' : _ref$tableRole, _ref$tableWidth = _ref.tableWidth, tableWidth = _ref$tableWidth === void 0 ? { min: '700px' } : _ref$tableWidth, _ref$withColumnChoose = _ref.withColumnChooser, withColumnChooser = _ref$withColumnChoose === void 0 ? false : _ref$withColumnChoose, _ref$withFocusableRow = _ref.withFocusableRows, withFocusableRows = _ref$withFocusableRow === void 0 ? false : _ref$withFocusableRow, _ref$withSelectableRo = _ref.withSelectableRows, withSelectableRows = _ref$withSelectableRo === void 0 ? false : _ref$withSelectableRo, _ref$withTallRows = _ref.withTallRows, withTallRows = _ref$withTallRows === void 0 ? false : _ref$withTallRows, rest = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["animateRows", "className", "columns", "columnChooserResetLabel", "containerWidth", "data", "data-cy", "expanderText", "headerContent", "isLoading", "isScrollLocked", "maxRowsToDisplay", "onColumnChoose", "onExpand", "onRowClick", "onSelectRow", "rowClassName", "rowWrapper", "selectionKey", "skin", "sortedInfo", "tableClassName", "tableDescription", "tableRole", "tableWidth", "withColumnChooser", "withFocusableRows", "withSelectableRows", "withTallRows"]); var defaultColumns = columns.map(function (col) { if ((0, _lodash.default)(col.show)) { col.show = true; } return col; }); var _useTable = (0, _Table4.useTable)(data, maxRowsToDisplay, defaultColumns), state = _useTable[0], actions = _useTable[1]; var updateTableData = actions.updateTableData, expandTable = actions.expandTable, collapseTable = actions.collapseTable, selectAllRows = actions.selectAllRows, deselectAllRows = actions.deselectAllRows, selectRow = actions.selectRow, deselectRow = actions.deselectRow, updateColumns = actions.updateColumns, resetColumns = actions.resetColumns; var isTableCollapsable = !(0, _lodash.default)(maxRowsToDisplay); var isCollapsed = data.length !== state.currentTableData.length; (0, _useDeepCompareEffect.default)(function () { updateTableData(data, maxRowsToDisplay); }, [data, maxRowsToDisplay, sortedInfo]); (0, _useDeepCompareEffect.default)(function () { resetColumns(columns); }, [columns]); function renderHeader() { if (!headerContent && !withColumnChooser) { return null; } var withHeaderContent = /*#__PURE__*/_react.default.isValidElement(headerContent); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Table.HeaderUI, { className: (0, _classnames.default)('c-Table__Header', withHeaderContent && 'with-header-content', withColumnChooser && 'with-column-chooser'), children: [withHeaderContent ? headerContent : null, withColumnChooser ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Table7.default, { columns: state.columns, columnChooserResetLabel: columnChooserResetLabel, defaultColumns: defaultColumns, onColumnChoose: onColumnChoose, resetColumns: resetColumns, updateColumns: updateColumns }) : null] }); } return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledComponents.ThemeProvider, { theme: (0, _Table2.chooseSkin)(skin), children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Table.TableWrapperUI, (0, _extends2.default)({ className: (0, _classnames.default)(TABLE_CLASSNAME + "__Wrapper", isCollapsed && 'is-collapsed', (0, _Table3.isTableSortable)(columns) && 'is-sortable', className), containerWidth: containerWidth, dataCy: dataCy }, rest, { children: [renderHeader(), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Scrollable.default, { fadeLeft: true, fadeRight: true, isScrollLocked: isScrollLocked, scrollLockDirection: "x", children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Table.TableUI, { ariaLabel: tableDescription, className: (0, _classnames.default)(TABLE_CLASSNAME, Boolean(onRowClick) && 'with-clickable-rows', withSelectableRows && 'selection-enabled', tableClassName), role: tableRole, tableWidth: tableWidth, withTallRows: withTallRows, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Table6.default, { columns: state.columns, deselectAllRows: deselectAllRows, isLoading: isLoading, rows: state.currentTableData, onSelectRow: onSelectRow, selectAllRows: selectAllRows, selectionKey: selectionKey, selected: state.selectedRows.length === state.currentTableData.length, sortedInfo: sortedInfo, tableRole: tableRole, withSelectableRows: withSelectableRows }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Table5.default, { animateRows: animateRows, columns: state.columns, deselectRow: deselectRow, maxRowsToDisplay: maxRowsToDisplay, onRowClick: onRowClick, onSelectRow: onSelectRow, rows: state.currentTableData, rowClassName: rowClassName, rowWrapper: rowWrapper, selectionKey: selectionKey, selectedRows: state.selectedRows, selectRow: selectRow, withSelectableRows: withSelectableRows, withFocusableRows: withFocusableRows })] }) }), isLoading && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Table.LoadingUI, { className: TABLE_CLASSNAME + "__Loading" }), isTableCollapsable && isCollapsed ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Table.ButtonExpanderUI, { size: "sm", theme: "blue", linked: true, className: TABLE_CLASSNAME + "__Expander", onClick: function onClick() { expandTable(data); onExpand({ collapsed: false }); }, children: expanderText ? expanderText.collapsed : 'View All' }) : null, isTableCollapsable && !isCollapsed ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Table.ButtonExpanderUI, { size: "sm", theme: "blue", linked: true, className: TABLE_CLASSNAME + "__Expander", onClick: function onClick() { collapseTable(data, maxRowsToDisplay); onExpand({ collapsed: true }); }, children: expanderText ? expanderText.expanded : 'Collapse' }) : null] })) }); } Table.propTypes = { /** Enable animation for row addition / removal. */ animateRows: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.object]), /** Custom class names to be added to the component top level element. */ className: _propTypes.default.string, /** List of columns */ columns: _propTypes.default.arrayOf(_propTypes.default.shape(_Table3.columnShape)), /** If the column chooser is enabled, customize the text of the reset option */ columnChooserResetLabel: _propTypes.default.string, /** The table wrapper width (if `tableWidth` is larger, the component scrolls horizontally) */ containerWidth: _propTypes.default.string, /** List of Rows, which are objects */ data: _propTypes.default.arrayOf(_propTypes.default.shape(_Table3.dataShape)), /** Data attr for Cypress tests. */ 'data-cy': _propTypes.default.string, /** The text for the "expander" button when table is either collapsed or expanded */ expanderText: _propTypes.default.any, /** Content to render inside the header tag just above the table (together with the column chooser if enabled) */ headerContent: _propTypes.default.element, /** Adds the 'is-loading' class to the component */ isLoading: _propTypes.default.bool, /** Whether to use `ScrollLock` with `direction="x"` on the Table. */ isScrollLocked: _propTypes.default.bool, /** When provided the Table will only show this number of rows and and expander to see the rest */ maxRowsToDisplay: _propTypes.default.number, /** Callback when choosing a column to show/hide if `withColumnChooser` is enabled*/ onColumnChoose: _propTypes.default.func, /** Callback when expending/collapsing the table */ onExpand: _propTypes.default.func, /** Callback function when a row is clicked. Arguments are the event and the row clicked. */ onRowClick: _propTypes.default.func, /** Callback when selecting a row if enabled */ onSelectRow: _propTypes.default.func, /** Custom class names to be added to the each row based on a condition. */ rowClassName: _propTypes.default.func, /** Gives you the ability to wrap rows based on conditions */ rowWrapper: _propTypes.default.func, /** Custom class names to be added to the `<table>` element. */ tableClassName: _propTypes.default.string, /** Description of the table contents for accessibility */ tableDescription: _propTypes.default.string.isRequired, /** Change the default role of the table */ tableRole: _propTypes.default.string, /** The `<table>` width */ tableWidth: _propTypes.default.shape({ min: _propTypes.default.string, max: _propTypes.default.string }), /** An object to customize the visual appearance of the table. See [Skins.md](/src/components/Table/docs/Skins.md) */ skin: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({ fontColorHeader: _propTypes.default.string, fontColorBody: _propTypes.default.string, fontColorAlternate: _propTypes.default.string, bgColor: _propTypes.default.string, bgAlternate: _propTypes.default.string, bgHeader: _propTypes.default.string, bgColorHover: _propTypes.default.string, borderTableBody: _propTypes.default.string, borderTableHeader: _propTypes.default.string, borderRows: _propTypes.default.string, borderColumns: _propTypes.default.string, bgFocus: _propTypes.default.string, bgFocusIndicator: _propTypes.default.string, bgSelected: _propTypes.default.string, bgSelectedHover: _propTypes.default.string, headerRowHeight: _propTypes.default.string })]), /** Customize which key from your data should be used for selection */ selectionKey: _propTypes.default.string, /** When sortable, indicates which column the table is sorted by, and in which order (ascending or descending) */ sortedInfo: _propTypes.default.shape({ columnKey: _propTypes.default.string, order: _propTypes.default.string }), /** If passed the column chooser will be enabled, contains an array of all the possible columns and whether they are checked and enabled */ withColumnChooser: _propTypes.default.bool, /** Adds tabindex=0 to each row*/ withFocusableRows: _propTypes.default.bool, /** Adds a column with a checkbox for row selection */ withSelectableRows: _propTypes.default.bool, /** Makes the rows 60px tall */ withTallRows: _propTypes.default.bool }; var _default = Table; exports.default = _default;