@absreim/react-bootstrap-data-grid 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Grid.js CHANGED
@@ -17,18 +17,20 @@ import inputStrsToRowData from "./editing/inputStrsToRowData";
17
17
  import { unwrapAdditionalComponentsStyleModel, unwrapTableStyleModel, } from "./styling/styleModelUnwrappers";
18
18
  import useCurrentPageRows from "./pipeline/useCurrentPageRows";
19
19
  import isSubset from "./util/isSubset";
20
+ import useFilterStateStore from "./pipeline/useFilterStateStore";
20
21
  var Grid = function (_a) {
21
22
  var _b;
22
23
  var rows = _a.rows, cols = _a.cols, pagination = _a.pagination, sortModel = _a.sortModel, filterModel = _a.filterModel, selectModel = _a.selectModel, editModel = _a.editModel, caption = _a.caption, styleModel = _a.styleModel;
23
- var editableFilterState = (filterModel === null || filterModel === void 0 ? void 0 : filterModel.tableFilterState) || null;
24
- var filterState = useFilterStateFromEditable(cols, editableFilterState);
24
+ var normalizedTableFilterModel = useFilterStateStore(filterModel, cols);
25
+ var editableFilterState = (normalizedTableFilterModel === null || normalizedTableFilterModel === void 0 ? void 0 : normalizedTableFilterModel.tableFilterState) || null;
25
26
  var filteredRows = useFilter(rows, editableFilterState);
26
- var sortedRows = useSortedRows(filteredRows, cols, sortModel);
27
- var currentPageRows = useCurrentPageRows(sortedRows, pagination);
27
+ var filterState = useFilterStateFromEditable(cols, editableFilterState);
28
+ var _c = useSortedRows(filteredRows, cols, sortModel), sortedRows = _c.sortedRows, sortingEnabled = _c.sortingEnabled, sortColDef = _c.sortColDef, setSortColDef = _c.setSortColDef;
29
+ var _d = useCurrentPageRows(sortedRows, pagination), paginatedRows = _d.paginatedRows, normalizedModel = _d.normalizedModel;
28
30
  var showSelectCol = selectModel && selectModel.mode !== "row";
29
31
  var ariaColIndexOffset = showSelectCol ? 1 : 0;
30
- var displayRows = useDisplayRows(currentPageRows, cols, ariaColIndexOffset);
31
- var _c = useState(false), filterOptionsVisible = _c[0], setFilterOptionsVisible = _c[1];
32
+ var displayRows = useDisplayRows(paginatedRows, cols, ariaColIndexOffset);
33
+ var _e = useState(false), filterOptionsVisible = _e[0], setFilterOptionsVisible = _e[1];
32
34
  var handleToggleFilterOptions = function () {
33
35
  setFilterOptionsVisible(!filterOptionsVisible);
34
36
  };
@@ -113,9 +115,9 @@ var Grid = function (_a) {
113
115
  }
114
116
  var getMultiExistingSelection = function (selectionExists, rows) {
115
117
  var rowIndices = rows.map(function (_, index) { return index; });
116
- var isFullSelection = isSubset(rowIndices, selectModel.selected);
117
- // Note that isFullSelection is true if there are no rows at all. In that case, the existing selection value
118
+ // Note that isFullSelection is true if there are no rows at all. In that case, the return value of this function
118
119
  // should be "none", not "full".
120
+ var isFullSelection = isSubset(rowIndices, selectModel.selected);
119
121
  if (!selectionExists) {
120
122
  return "none";
121
123
  }
@@ -157,18 +159,16 @@ var Grid = function (_a) {
157
159
  var unwrappedAdditionalStyleModel = useMemo(function () {
158
160
  return unwrapAdditionalComponentsStyleModel(styleModel === null || styleModel === void 0 ? void 0 : styleModel.additionalComponentsStyleModel);
159
161
  }, [styleModel === null || styleModel === void 0 ? void 0 : styleModel.additionalComponentsStyleModel]);
160
- return (_jsxs("div", { "data-testid": "rbdg-top-level-div", className: classNames(unwrappedAdditionalStyleModel.topLevelDiv), children: [filterState && filterModel && (_jsxs("div", { "data-testid": "rbdg-filter-inputs-div", className: classNames(unwrappedAdditionalStyleModel.filterInputsDiv), children: [_jsx(ToggleButton, { isActive: filterOptionsVisible, label: "".concat(filterOptionsVisible ? "Hide" : "Show ", " Filter Options"), onClick: handleToggleFilterOptions, classes: (_b = styleModel === null || styleModel === void 0 ? void 0 : styleModel.additionalComponentsStyleModel) === null || _b === void 0 ? void 0 : _b.filterUiToggleButton }), filterOptionsVisible && (_jsx(FilterOptionsTable, { caption: filterModel.filterTableCaption, filterState: filterState, setFilterState: filterModel.setTableFilterState, styleModel: styleModel === null || styleModel === void 0 ? void 0 : styleModel.filterInputTableStyleModel }))] })), _jsxs("div", { "data-testid": "rbdg-table-and-pagination-div", className: classNames(unwrappedAdditionalStyleModel.tableAndPaginationDiv), children: [_jsxs("table", { className: classNames("table", {
162
+ return (_jsxs("div", { "data-testid": "rbdg-top-level-div", className: classNames(unwrappedAdditionalStyleModel.topLevelDiv), children: [normalizedTableFilterModel && (_jsxs("div", { "data-testid": "rbdg-filter-inputs-div", className: classNames(unwrappedAdditionalStyleModel.filterInputsDiv), children: [_jsx(ToggleButton, { isActive: filterOptionsVisible, label: "".concat(filterOptionsVisible ? "Hide" : "Show ", " Filter Options"), onClick: handleToggleFilterOptions, classes: (_b = styleModel === null || styleModel === void 0 ? void 0 : styleModel.additionalComponentsStyleModel) === null || _b === void 0 ? void 0 : _b.filterUiToggleButton }), filterOptionsVisible && (_jsx(FilterOptionsTable, { caption: filterModel.filterTableCaption, filterState: filterState, setFilterState: normalizedTableFilterModel.setTableFilterState, styleModel: styleModel === null || styleModel === void 0 ? void 0 : styleModel.filterInputTableStyleModel }))] })), _jsxs("div", { "data-testid": "rbdg-table-and-pagination-div", className: classNames(unwrappedAdditionalStyleModel.tableAndPaginationDiv), children: [_jsxs("table", { className: classNames("table", {
161
163
  "table-hover": rowsAreSelectable,
162
164
  }, unwrappedTableModel.table), "aria-rowcount": filteredRows.length + 1, children: [caption !== undefined && (_jsx("caption", { className: classNames(unwrappedTableModel.caption), children: caption })), _jsx("thead", { className: classNames(unwrappedTableModel.thead), children: _jsxs("tr", { "aria-rowindex": 1, className: classNames(unwrappedTableModel.theadTr), children: [showSelectCol && (_jsx(SelectAllHeaderCell, { selectionInfo: selectionInfo, onClick: selectAllOnClick, totalRows: rows.length, additionalClasses: unwrappedTableModel.rowSelectColTh })), cols.map(function (_a, index) {
163
- var _b;
164
165
  var name = _a.name, label = _a.label, sortable = _a.sortable;
165
- var colSortModel = sortModel && sortable
166
+ var colSortModel = sortingEnabled && sortable
166
167
  ? {
167
- sortOrder: ((_b = sortModel.sortColDef) === null || _b === void 0 ? void 0 : _b.name) === name
168
- ? sortModel.sortColDef.order
169
- : null,
168
+ sortOrder: (sortColDef === null || sortColDef === void 0 ? void 0 : sortColDef.name) === name ? sortColDef.order : null,
170
169
  setSortOrder: function (order) {
171
- sortModel.setSortColDef(order && { name: name, order: order });
170
+ setSortColDef &&
171
+ setSortColDef(order && { name: name, order: order });
172
172
  },
173
173
  }
174
174
  : undefined;
@@ -183,6 +183,6 @@ var Grid = function (_a) {
183
183
  }, dataCellInputClasses: function (colIndex) {
184
184
  return unwrappedTableModel.tbodyTdInput(row.id, index, colIndex);
185
185
  }, editCellClasses: unwrappedTableModel.editColTd(row.id, index), saveButtonClasses: unwrappedTableModel.editSaveButton(row.id, index), deleteButtonClasses: unwrappedTableModel.editDeleteButton(row.id, index), startButtonClasses: unwrappedTableModel.editStartButton(row.id, index), cancelButtonClasses: unwrappedTableModel.editCancelButton(row.id, index), children: showSelectCol && (_jsx("td", { className: classNames(unwrappedTableModel.rowSelectColTd(row.id, index)), "aria-colindex": 1, children: _jsx(SelectionInput, { selected: selectedSet.has(row.id), selectionInputModel: getSelectInputModel(row.id, selectModel), selectCallback: getSelectHandler(row.id), additionalClasses: unwrappedTableModel.rowSelectInput(row.id, index) }) })) }, row.id));
186
- }) })] }), pagination && (_jsx(Pagination, { componentSize: pagination.componentSize || "medium", pageSizeOptions: pagination.pageSizeOptions, pageSizeIndex: pagination.pageSizeIndex, handleSetPageSizeIndex: pagination.setPageSizeIndex, handleSetPageNum: pagination.setCurrentPage, prePagingNumRows: sortedRows.length, maxPageButtons: pagination.maxPageButtons, currentPage: pagination.currentPage, pageSelectorJustifyContent: pagination.pageSelectorJustifyContent, pageSelectorAriaLabel: pagination.pageSelectorAriaLabel }))] })] }));
186
+ }) })] }), normalizedModel && (_jsx(Pagination, { normalizedModel: normalizedModel, prePagingNumRows: sortedRows.length }))] })] }));
187
187
  };
188
188
  export default Grid;
@@ -45,16 +45,22 @@ export interface BetweenDatesFilterState extends AbstractDateFilterState {
45
45
  }
46
46
  export type DateFilterState = StartDateFilterState | EndDateFilterState | BetweenDatesFilterState;
47
47
  export type FilterState = StringFilterState | NumberFilterState | DateFilterState;
48
- export interface FilterModel {
48
+ export interface ControlledFilterModel {
49
+ type?: "controlled";
49
50
  tableFilterState: EditableTableFilterState;
50
51
  setTableFilterState: (state: EditableTableFilterState) => void;
51
52
  filterTableCaption?: string;
52
53
  }
54
+ export type UncontrolledFilterModel = Partial<Pick<ControlledFilterModel, "tableFilterState" | "filterTableCaption">> & {
55
+ type: "uncontrolled";
56
+ };
57
+ export type NormalizedTableFilterModel = Pick<ControlledFilterModel, "tableFilterState" | "setTableFilterState">;
53
58
  export interface NumberFormFilterState extends AbstractFilterState {
54
59
  type: "number";
55
60
  scheme: NumberFilterScheme;
56
61
  inputValue: string;
57
62
  }
63
+ export type FilterModel = ControlledFilterModel | UncontrolledFilterModel;
58
64
  export interface DateFormFilterState extends AbstractDateFilterState {
59
65
  scheme: DateFilterScheme;
60
66
  startDate: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@absreim/react-bootstrap-data-grid",
3
3
  "description": "Data grid UI component for use with web apps using React and Bootstrap",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "license": "MIT",
6
6
  "author": "Brook Li",
7
7
  "homepage": "https://react-bootstrap-data-grid.vercel.app/",
@@ -1,14 +1,9 @@
1
1
  import { FC } from "react";
2
- import { JustifyContentSetting, Size } from "../types";
2
+ import { JustifyContentSetting } from "../types";
3
+ import { NormalizedPaginationModel } from "./types";
3
4
  export interface PaginationProps {
4
- componentSize: Size;
5
- pageSizeOptions: number[];
6
- pageSizeIndex: number;
7
- handleSetPageSizeIndex: (index: number) => void;
8
- handleSetPageNum: (index: number) => void;
5
+ normalizedModel: NormalizedPaginationModel;
9
6
  prePagingNumRows: number;
10
- maxPageButtons: number;
11
- currentPage: number;
12
7
  pageSelectorAriaLabel?: string;
13
8
  pageSelectorJustifyContent?: JustifyContentSetting;
14
9
  }
@@ -2,19 +2,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import PageSizeSelector from "./PageSizeSelector";
3
3
  import PageSelector from "./PageSelector";
4
4
  var Pagination = function (_a) {
5
- var componentSize = _a.componentSize, pageSizeOptions = _a.pageSizeOptions, pageSizeIndex = _a.pageSizeIndex, handleSetPageSizeIndex = _a.handleSetPageSizeIndex, handleSetPageNum = _a.handleSetPageNum, prePagingNumRows = _a.prePagingNumRows, maxPageButtons = _a.maxPageButtons, currentPage = _a.currentPage, pageSelectorAriaLabel = _a.pageSelectorAriaLabel, pageSelectorJustifyContent = _a.pageSelectorJustifyContent;
5
+ var normalizedModel = _a.normalizedModel, prePagingNumRows = _a.prePagingNumRows;
6
+ var pageSizeOptions = normalizedModel.pageSizeOptions, pageSizeIndex = normalizedModel.pageSizeIndex, currentPage = normalizedModel.currentPage, setCurrentPage = normalizedModel.setCurrentPage, setPageSizeIndex = normalizedModel.setPageSizeIndex, componentSize = normalizedModel.componentSize, maxPageButtons = normalizedModel.maxPageButtons, pageSelectorAriaLabel = normalizedModel.pageSelectorAriaLabel, pageSelectorJustifyContent = normalizedModel.pageSelectorJustifyContent;
6
7
  var numPages = Math.ceil(prePagingNumRows / pageSizeOptions[pageSizeIndex]);
7
8
  var pageIndexAwarePageSizeSetter = function (newPageSizeIndex) {
8
9
  var newPageSize = pageSizeOptions[newPageSizeIndex];
9
10
  var maxPages = Math.ceil(prePagingNumRows / newPageSize);
10
- handleSetPageSizeIndex(newPageSizeIndex);
11
+ setPageSizeIndex(newPageSizeIndex);
11
12
  // The new page size can cause the current page number to be out of bounds.
12
13
  // In that case, set the page num to the maximum possible with new page
13
14
  // size.
14
15
  if (currentPage > maxPages) {
15
- handleSetPageNum(maxPages);
16
+ setCurrentPage(maxPages);
16
17
  }
17
18
  };
18
- return (_jsxs("div", { className: "d-flex justify-content-end gap-2", children: [_jsx(PageSizeSelector, { componentSize: componentSize, pageSizeOptions: pageSizeOptions, pageSizeIndex: pageSizeIndex, handleSetPageSize: pageIndexAwarePageSizeSetter }), _jsx(PageSelector, { numPages: numPages, pageNum: currentPage, numButtons: maxPageButtons, setPageNum: handleSetPageNum, size: componentSize, ariaLabel: pageSelectorAriaLabel, alignment: pageSelectorJustifyContent })] }));
19
+ return (_jsxs("div", { className: "d-flex justify-content-end gap-2", children: [_jsx(PageSizeSelector, { componentSize: componentSize, pageSizeOptions: pageSizeOptions, pageSizeIndex: pageSizeIndex, handleSetPageSize: pageIndexAwarePageSizeSetter }), _jsx(PageSelector, { numPages: numPages, pageNum: currentPage, numButtons: maxPageButtons, setPageNum: setCurrentPage, size: componentSize, ariaLabel: pageSelectorAriaLabel, alignment: pageSelectorJustifyContent })] }));
19
20
  };
20
21
  export default Pagination;
@@ -1,12 +1,22 @@
1
1
  import { JustifyContentSetting, Size } from "../types";
2
- export interface GridPaginationState {
3
- pageSizeOptions: number[];
4
- pageSizeIndex: number;
5
- setPageSizeIndex: (pageSizeIndex: number) => void;
6
- currentPage: number;
7
- setCurrentPage: (pageNum: number) => void;
8
- maxPageButtons: number;
2
+ export interface PaginationOptions {
3
+ pageSizeOptions?: number[];
4
+ maxPageButtons?: number;
9
5
  componentSize?: Size;
10
6
  pageSelectorAriaLabel?: string;
11
7
  pageSelectorJustifyContent?: JustifyContentSetting;
12
8
  }
9
+ export type ControlledPaginationModel = PaginationOptions & {
10
+ type?: "controlled";
11
+ pageSizeIndex: number;
12
+ setPageSizeIndex: (pageSizeIndex: number) => void;
13
+ currentPage: number;
14
+ setCurrentPage: (pageNum: number) => void;
15
+ };
16
+ export type UncontrolledPaginationModel = PaginationOptions & {
17
+ type: "uncontrolled";
18
+ startingPageSizeIndex?: number;
19
+ startingCurrentPage?: number;
20
+ };
21
+ export type GridPaginationState = ControlledPaginationModel | UncontrolledPaginationModel;
22
+ export type NormalizedPaginationModel = Required<Omit<ControlledPaginationModel, "type" | "pageSelectorAriaLabel" | "pageSelectorJustifyContent">> & Pick<ControlledPaginationModel, "pageSelectorAriaLabel" | "pageSelectorJustifyContent">;
@@ -1,4 +1,7 @@
1
1
  import { RowDef } from "../types";
2
- import { GridPaginationState } from "../pagination/types";
3
- declare const useCurrentPageRows: (sortedRows: RowDef[], pagination: GridPaginationState | undefined) => RowDef[];
2
+ import { NormalizedPaginationModel, GridPaginationState } from "../pagination/types";
3
+ declare const useCurrentPageRows: (sortedRows: RowDef[], paginationModel: GridPaginationState | undefined) => {
4
+ paginatedRows: RowDef[];
5
+ normalizedModel: NormalizedPaginationModel | null;
6
+ };
4
7
  export default useCurrentPageRows;
@@ -1,14 +1,52 @@
1
- import { useMemo } from "react";
2
- var useCurrentPageRows = function (sortedRows, pagination) {
1
+ import { useMemo, useState } from "react";
2
+ var useCurrentPageRows = function (sortedRows, paginationModel) {
3
+ var componentSize = (paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.componentSize) || "medium";
4
+ var isControlled = (paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.type) !== "uncontrolled";
5
+ var _a = useState(isControlled ? 0 : paginationModel.startingPageSizeIndex || 0), internalPageSizeIndex = _a[0], setInternalPageSizeIndex = _a[1];
6
+ var pageSizeIndex = isControlled
7
+ ? (paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.pageSizeIndex) || 0
8
+ : internalPageSizeIndex;
9
+ var setPageSizeIndex = isControlled
10
+ ? paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.setPageSizeIndex
11
+ : setInternalPageSizeIndex;
12
+ var _b = useState(isControlled ? 1 : paginationModel.startingCurrentPage || 1), internalPageNum = _b[0], setInternalPageNum = _b[1];
13
+ var currentPage = isControlled
14
+ ? (paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.currentPage) || 1
15
+ : internalPageNum;
16
+ var setCurrentPage = isControlled
17
+ ? paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.setCurrentPage
18
+ : setInternalPageNum;
19
+ var maxPageButtons = (paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.maxPageButtons) || 5;
3
20
  return useMemo(function () {
4
- if (pagination === undefined) {
5
- return sortedRows;
21
+ if (paginationModel === undefined) {
22
+ return { paginatedRows: sortedRows, normalizedModel: null };
6
23
  }
7
- var pageSizeOptions = pagination.pageSizeOptions, pageSizeIndex = pagination.pageSizeIndex, currentPage = pagination.currentPage;
24
+ var pageSizeOptions = (paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.pageSizeOptions) || [10, 25, 100];
25
+ var normalizedModel = {
26
+ pageSizeIndex: pageSizeIndex,
27
+ setPageSizeIndex: setPageSizeIndex,
28
+ currentPage: currentPage,
29
+ setCurrentPage: setCurrentPage,
30
+ pageSizeOptions: pageSizeOptions,
31
+ maxPageButtons: maxPageButtons,
32
+ componentSize: componentSize,
33
+ pageSelectorAriaLabel: paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.pageSelectorAriaLabel,
34
+ pageSelectorJustifyContent: paginationModel === null || paginationModel === void 0 ? void 0 : paginationModel.pageSelectorJustifyContent,
35
+ };
8
36
  var pageSize = pageSizeOptions[pageSizeIndex];
9
37
  var lowerIndex = pageSize * (currentPage - 1);
10
38
  var upperIndex = lowerIndex + pageSize;
11
- return sortedRows.slice(lowerIndex, upperIndex);
12
- }, [sortedRows, pagination]);
39
+ var paginatedRows = sortedRows.slice(lowerIndex, upperIndex);
40
+ return { paginatedRows: paginatedRows, normalizedModel: normalizedModel };
41
+ }, [
42
+ paginationModel,
43
+ pageSizeIndex,
44
+ setPageSizeIndex,
45
+ currentPage,
46
+ setCurrentPage,
47
+ maxPageButtons,
48
+ componentSize,
49
+ sortedRows,
50
+ ]);
13
51
  };
14
52
  export default useCurrentPageRows;
@@ -0,0 +1,4 @@
1
+ import { FilterModel, NormalizedTableFilterModel } from "../filtering/types";
2
+ import { ColDef } from "../types";
3
+ declare const useFilterStateStore: (filterModel: FilterModel | undefined, cols: ColDef[]) => NormalizedTableFilterModel | null;
4
+ export default useFilterStateStore;
@@ -0,0 +1,57 @@
1
+ import { useState } from "react";
2
+ var generateEmptyFilterState = function (cols) {
3
+ var filterState = {};
4
+ cols.forEach(function (_a) {
5
+ var type = _a.type, name = _a.name;
6
+ switch (type) {
7
+ case "string": {
8
+ filterState[name] = {
9
+ type: "string",
10
+ enabled: false,
11
+ scheme: "contains",
12
+ searchString: "",
13
+ };
14
+ break;
15
+ }
16
+ case "number": {
17
+ filterState[name] = {
18
+ type: "number",
19
+ enabled: false,
20
+ scheme: "greaterOrEqual",
21
+ numValue: null,
22
+ };
23
+ break;
24
+ }
25
+ default: {
26
+ filterState[name] = {
27
+ type: type,
28
+ enabled: false,
29
+ scheme: "startFrom",
30
+ startDate: null,
31
+ };
32
+ }
33
+ }
34
+ });
35
+ return filterState;
36
+ };
37
+ var useFilterStateStore = function (filterModel, cols) {
38
+ // Initial states being from prop values means that should uncontrolled
39
+ // FilterModel starting values change, the changes will not take effect
40
+ // unless the Grid is remounted. The documentation for this and other
41
+ // uncontrolled features should indicate this fact and recommend using
42
+ // controlled modes if this behavior is unacceptable.
43
+ var _a = useState((filterModel === null || filterModel === void 0 ? void 0 : filterModel.tableFilterState) || generateEmptyFilterState(cols)), internalFilterState = _a[0], setInternalFilterState = _a[1];
44
+ if (!filterModel) {
45
+ return null;
46
+ }
47
+ return filterModel.type === "uncontrolled"
48
+ ? {
49
+ tableFilterState: internalFilterState,
50
+ setTableFilterState: setInternalFilterState,
51
+ }
52
+ : {
53
+ tableFilterState: filterModel.tableFilterState,
54
+ setTableFilterState: filterModel.setTableFilterState,
55
+ };
56
+ };
57
+ export default useFilterStateStore;
@@ -1,4 +1,9 @@
1
1
  import { ColDef, RowDef } from "../types";
2
- import { TableSortModel } from "../sorting/types";
3
- declare const useSortedRows: (rows: RowDef[], cols: ColDef[], sortModel: TableSortModel | undefined) => RowDef[];
2
+ import { SortColDef, TableSortModel } from "../sorting/types";
3
+ declare const useSortedRows: (rows: RowDef[], cols: ColDef[], sortModel: TableSortModel | undefined) => {
4
+ sortedRows: RowDef[];
5
+ sortingEnabled: boolean;
6
+ sortColDef: SortColDef | null | undefined;
7
+ setSortColDef: ((sortColDef: SortColDef | null) => void) | undefined;
8
+ };
4
9
  export default useSortedRows;
@@ -1,4 +1,4 @@
1
- import { useMemo } from "react";
1
+ import { useMemo, useState } from "react";
2
2
  var getTypeComparator = function (typeStr) {
3
3
  if (typeStr === "date" || typeStr === "datetime") {
4
4
  return function (a, b) { return a.valueOf() - b.valueOf(); };
@@ -20,12 +20,21 @@ var getRowComparator = function (comparator, fieldName) {
20
20
  return function (rowA, rowB) { return comparator(rowA.data[fieldName], rowB.data[fieldName]); };
21
21
  };
22
22
  var useSortedRows = function (rows, cols, sortModel) {
23
- return useMemo(function () {
24
- if (!sortModel || !sortModel.sortColDef) {
23
+ var _a = useState(((sortModel === null || sortModel === void 0 ? void 0 : sortModel.type) === "uncontrolled" && sortModel.initialSortColDef) ||
24
+ null), internalSortColDef = _a[0], setInternalSortColDef = _a[1];
25
+ var sortColDef = (sortModel === null || sortModel === void 0 ? void 0 : sortModel.type) === "uncontrolled"
26
+ ? internalSortColDef
27
+ : (sortModel === null || sortModel === void 0 ? void 0 : sortModel.sortColDef) || undefined;
28
+ var setSortColDef = (sortModel === null || sortModel === void 0 ? void 0 : sortModel.type) === "uncontrolled"
29
+ ? setInternalSortColDef
30
+ : (sortModel === null || sortModel === void 0 ? void 0 : sortModel.setSortColDef) || undefined;
31
+ var sortingEnabled = !!sortModel;
32
+ var sortedRows = useMemo(function () {
33
+ if (!sortColDef) {
25
34
  return rows;
26
35
  }
27
- var sortFieldName = sortModel.sortColDef.name;
28
- var sortOrder = sortModel.sortColDef.order;
36
+ var sortFieldName = sortColDef.name;
37
+ var sortOrder = sortColDef.order;
29
38
  var sortColIndex = cols.findIndex(function (_a) {
30
39
  var name = _a.name;
31
40
  return name === sortFieldName;
@@ -43,6 +52,7 @@ var useSortedRows = function (rows, cols, sortModel) {
43
52
  rowComparator = getRowComparator(descComparator, sortFieldName);
44
53
  }
45
54
  return rows.slice().sort(rowComparator);
46
- }, [rows, cols, sortModel]);
55
+ }, [sortColDef, cols, rows]);
56
+ return { sortedRows: sortedRows, sortingEnabled: sortingEnabled, sortColDef: sortColDef, setSortColDef: setSortColDef };
47
57
  };
48
58
  export default useSortedRows;
@@ -7,7 +7,13 @@ export interface ColSortModel {
7
7
  sortOrder: SortOrder | null;
8
8
  setSortOrder: (order: SortOrder | null) => void;
9
9
  }
10
- export interface TableSortModel {
10
+ export interface ControlledTableSortModel {
11
+ type?: "controlled";
11
12
  sortColDef: SortColDef | null;
12
13
  setSortColDef: (sortColDef: SortColDef | null) => void;
13
14
  }
15
+ export interface UncontrolledTableSortModel {
16
+ type: "uncontrolled";
17
+ initialSortColDef: SortColDef | null;
18
+ }
19
+ export type TableSortModel = ControlledTableSortModel | UncontrolledTableSortModel;