@atlaskit/dynamic-table
Version:
A dynamic table displays rows of data with built-in pagination, sorting, and re-ordering functionality.
170 lines (166 loc) • 7.31 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _typeof from "@babel/runtime/helpers/typeof";
var _excluded = ["rows", "head", "sortKey", "sortOrder", "rowsPerPage", "page", "forwardedRef"];
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) { _defineProperty(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; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
import React from 'react';
import { getPageRows } from '../internal/get-page-rows';
import { validateSortKey } from '../internal/validate-sort-key';
var getSortingCellValue = function getSortingCellValue(cells, head, sortKey) {
for (var i = 0; i < cells.length; i++) {
var _head$cells$i;
if (head.cells[i] && ((_head$cells$i = head.cells[i]) === null || _head$cells$i === void 0 ? void 0 : _head$cells$i.key) === sortKey) {
var _cells$i;
return (_cells$i = cells[i]) === null || _cells$i === void 0 ? void 0 : _cells$i.key;
}
}
return undefined;
};
// sort all rows based on sort key and order
var getSortedRows = function getSortedRows(head, rows, sortKey, sortOrder) {
if (!sortKey || !head) {
return rows;
}
if (!rows) {
return [];
}
var modifier = sortOrder === 'ASC' ? 1 : -1;
// Re-initialising an I18n Collator on every sort is performance intensive, thus constructed outside
var collator = new Intl.Collator(undefined, {
numeric: true,
sensitivity: 'accent'
});
// Get copy of rows to avoid sorting prop in place
var sortableRows = Array.from(rows);
// Reorder rows in table based on sorting cell value
// Algorithm will sort numerics or strings, but not both
return sortableRows.sort(function (a, b) {
var valA = getSortingCellValue(a.cells, head, sortKey);
var valB = getSortingCellValue(b.cells, head, sortKey);
if (valA === undefined || valB === undefined) {
return modifier;
}
if (_typeof(valA) !== _typeof(valB)) {
// numbers are always grouped higher in the sort
if (typeof valA === 'number') {
return -1;
}
if (typeof valB === 'number') {
return 1;
}
// strings are grouped next
if (typeof valA === 'string') {
return -1;
}
if (typeof valB === 'string') {
return 1;
}
}
if (typeof valA === 'string' && typeof valB === 'string') {
return modifier * collator.compare(valA, valB);
}
if (!valA && valA !== 0 || valA < valB) {
return -modifier;
}
if (!valB && valB !== 0 || valA > valB) {
return modifier;
}
if (valA === valB) {
return 0;
}
return 1;
});
};
// get one page of data in table, sorting all rows previously
export default function withSortedPageRows(WrappedComponent) {
// eslint-disable-next-line @repo/internal/react/no-class-components
var WithSortedPageRows = /*#__PURE__*/function (_React$Component) {
function WithSortedPageRows() {
var _this;
_classCallCheck(this, WithSortedPageRows);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _callSuper(this, WithSortedPageRows, [].concat(args));
_defineProperty(_this, "state", {
pageRows: []
});
return _this;
}
_inherits(WithSortedPageRows, _React$Component);
return _createClass(WithSortedPageRows, [{
key: "componentDidMount",
value: function componentDidMount() {
this.props.onPageRowsUpdate && this.props.onPageRowsUpdate(this.state.pageRows);
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(_prevProps, prevState) {
if (this.props.onPageRowsUpdate && this.state.pageRows !== prevState.pageRows) {
this.props.onPageRowsUpdate(this.state.pageRows);
}
}
}, {
key: "render",
value: function render() {
var _this$props = this.props,
rows = _this$props.rows,
head = _this$props.head,
sortKey = _this$props.sortKey,
sortOrder = _this$props.sortOrder,
rowsPerPage = _this$props.rowsPerPage,
page = _this$props.page,
forwardedRef = _this$props.forwardedRef,
restProps = _objectWithoutProperties(_this$props, _excluded);
return /*#__PURE__*/React.createElement(WrappedComponent
//@ts-expect-error TODO Fix legit TypeScript 3.9.6 improved inference error
, _extends({
pageRows: this.state.pageRows,
head: head
}, restProps, {
ref: forwardedRef
}));
}
}], [{
key: "getDerivedStateFromProps",
value: function getDerivedStateFromProps(props, state) {
var rows = props.rows,
head = props.head,
sortKey = props.sortKey,
sortOrder = props.sortOrder,
page = props.page,
rowsPerPage = props.rowsPerPage,
isTotalPagesControlledExternally = props.isTotalPagesControlledExternally;
validateSortKey(sortKey, head);
var sortedRows;
var pageRows;
if (isTotalPagesControlledExternally) {
sortedRows = rows;
pageRows = rows;
} else {
sortedRows = getSortedRows(head, rows, sortKey, sortOrder) || [];
pageRows = getPageRows(sortedRows, page, rowsPerPage);
}
return _objectSpread(_objectSpread({}, state), {}, {
pageRows: pageRows
});
}
}]);
}(React.Component);
return /*#__PURE__*/React.forwardRef(function (props, ref) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: to unblock React 18.2.0 -> 18.3.1 version bump in Jira
return /*#__PURE__*/React.createElement(WithSortedPageRows, _extends({}, props, {
forwardedRef: ref
}));
});
}