@helpscout/hsds-react
Version:
React component library for Help Scout's Design System
345 lines (287 loc) • 14.5 kB
JavaScript
"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;