@homebound/beam 2.310.0 → 2.312.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/dist/components/Table/GridTable.d.ts +15 -0
- package/dist/components/Table/GridTable.js +52 -58
- package/dist/components/Table/GridTableApi.d.ts +12 -2
- package/dist/components/Table/GridTableApi.js +11 -1
- package/dist/components/Table/components/Row.d.ts +9 -15
- package/dist/components/Table/components/Row.js +16 -45
- package/dist/components/Table/hooks/useSetupColumnSizes.d.ts +2 -2
- package/dist/components/Table/types.d.ts +5 -7
- package/dist/components/Table/utils/ColumnState.d.ts +6 -6
- package/dist/components/Table/utils/ColumnStates.d.ts +7 -7
- package/dist/components/Table/utils/ColumnStorage.d.ts +3 -2
- package/dist/components/Table/utils/GridRowLookup.d.ts +3 -2
- package/dist/components/Table/utils/GridRowLookup.js +5 -4
- package/dist/components/Table/utils/RowState.d.ts +22 -7
- package/dist/components/Table/utils/RowState.js +110 -16
- package/dist/components/Table/utils/RowStates.d.ts +11 -10
- package/dist/components/Table/utils/RowStates.js +3 -6
- package/dist/components/Table/utils/RowStorage.d.ts +3 -2
- package/dist/components/Table/utils/TableState.d.ts +19 -14
- package/dist/components/Table/utils/TableState.js +7 -5
- package/dist/components/Table/utils/columns.d.ts +1 -1
- package/dist/components/Table/utils/utils.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MutableRefObject } from "react";
|
|
2
|
+
import { DiscriminateUnion, GridRowKind } from "../index";
|
|
2
3
|
import { GridTableApi } from "./GridTableApi";
|
|
3
4
|
import { GridStyle, GridStyleDef, RowStyles } from "./TableStyles";
|
|
4
5
|
import { Direction, GridColumn, GridTableXss, InfiniteScroll, Kinded, RenderAs } from "./types";
|
|
@@ -41,6 +42,18 @@ export type GridSortConfig = {
|
|
|
41
42
|
/** Callback for when the column is sorted (if server-side sorting). Parameters set to `undefined` is a signal to return to the initial sort state */
|
|
42
43
|
onSort: (orderBy: string | undefined, direction: Direction | undefined) => void;
|
|
43
44
|
};
|
|
45
|
+
/** Allows listening to per-kind row selection changes. */
|
|
46
|
+
export type OnRowSelect<R extends Kinded> = {
|
|
47
|
+
[K in R["kind"]]?: DiscriminateUnion<R, "kind", K> extends {
|
|
48
|
+
data: infer D;
|
|
49
|
+
} ? (data: D, isSelected: boolean, opts: {
|
|
50
|
+
row: GridRowKind<R, K>;
|
|
51
|
+
api: GridTableApi<R>;
|
|
52
|
+
}) => void : (data: undefined, isSelected: boolean, opts: {
|
|
53
|
+
row: GridRowKind<R, K>;
|
|
54
|
+
api: GridTableApi<R>;
|
|
55
|
+
}) => void;
|
|
56
|
+
};
|
|
44
57
|
export interface GridTableProps<R extends Kinded, X> {
|
|
45
58
|
id?: string;
|
|
46
59
|
/**
|
|
@@ -114,6 +127,8 @@ export interface GridTableProps<R extends Kinded, X> {
|
|
|
114
127
|
** `endOffsetPx` is the number of pixels from the bottom of the list to eagerly trigger `onEndReached`. The default is is 500px.
|
|
115
128
|
*/
|
|
116
129
|
infiniteScroll?: InfiniteScroll;
|
|
130
|
+
/** Callback for when a row is selected or unselected. */
|
|
131
|
+
onRowSelect?: OnRowSelect<R>;
|
|
117
132
|
}
|
|
118
133
|
/**
|
|
119
134
|
* Renders data in our table layout.
|
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.GridTable = exports.setGridTableDefaults = exports.setDefaultStyle = exports.setRunningInJest = void 0;
|
|
30
30
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
31
31
|
const memoize_one_1 = __importDefault(require("memoize-one"));
|
|
32
|
+
const mobx_1 = require("mobx");
|
|
32
33
|
const react_1 = __importStar(require("react"));
|
|
33
34
|
const react_virtuoso_1 = require("react-virtuoso");
|
|
34
35
|
const PresentationContext_1 = require("../PresentationContext");
|
|
@@ -36,7 +37,6 @@ const GridTableApi_1 = require("./GridTableApi");
|
|
|
36
37
|
const useSetupColumnSizes_1 = require("./hooks/useSetupColumnSizes");
|
|
37
38
|
const TableStyles_1 = require("./TableStyles");
|
|
38
39
|
const columns_1 = require("./utils/columns");
|
|
39
|
-
const GridRowLookup_1 = require("./utils/GridRowLookup");
|
|
40
40
|
const TableState_1 = require("./utils/TableState");
|
|
41
41
|
const utils_1 = require("./utils/utils");
|
|
42
42
|
const Css_1 = require("../../Css");
|
|
@@ -85,7 +85,7 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
85
85
|
*/
|
|
86
86
|
function GridTable(props) {
|
|
87
87
|
var _a, _b, _c;
|
|
88
|
-
const { id = "gridTable", as = "div", columns: _columns, rows, style: maybeStyle = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = 0, xss, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, persistCollapse, resizeTarget, activeRowId, activeCellId, visibleColumnsStorageKey, infiniteScroll, } = props;
|
|
88
|
+
const { id = "gridTable", as = "div", columns: _columns, rows, style: maybeStyle = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = 0, xss, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, persistCollapse, resizeTarget, activeRowId, activeCellId, visibleColumnsStorageKey, infiniteScroll, onRowSelect, } = props;
|
|
89
89
|
const columnsWithIds = (0, react_1.useMemo)(() => (0, columns_1.assignDefaultColumnIds)(_columns), [_columns]);
|
|
90
90
|
// We only use this in as=virtual mode, but keep this here for rowLookup to use
|
|
91
91
|
const virtuosoRef = (0, react_1.useRef)(null);
|
|
@@ -93,8 +93,9 @@ function GridTable(props) {
|
|
|
93
93
|
const resizeRef = (0, react_1.useRef)(null);
|
|
94
94
|
const api = (0, react_1.useMemo)(() => {
|
|
95
95
|
var _a;
|
|
96
|
+
// Let the user pass in their own api handle, otherwise make our own
|
|
96
97
|
const api = (_a = props.api) !== null && _a !== void 0 ? _a : new GridTableApi_1.GridTableApiImpl();
|
|
97
|
-
api.init(persistCollapse, virtuosoRef
|
|
98
|
+
api.init(persistCollapse, virtuosoRef);
|
|
98
99
|
api.setActiveRowId(activeRowId);
|
|
99
100
|
api.setActiveCellId(activeCellId);
|
|
100
101
|
// Push the initial columns directly into tableState, b/c that is what
|
|
@@ -105,25 +106,27 @@ function GridTable(props) {
|
|
|
105
106
|
}, [props.api]);
|
|
106
107
|
const style = (0, TableStyles_1.resolveStyles)(maybeStyle);
|
|
107
108
|
const { tableState } = api;
|
|
108
|
-
tableState.
|
|
109
|
+
tableState.onRowSelect = onRowSelect;
|
|
110
|
+
// Use a single useEffect to push props into the TableState observable, that
|
|
111
|
+
// way we avoid React warnings when the observable mutations cause downstream
|
|
112
|
+
// components to be marked for re-render. Mobx will ignore setter calls that
|
|
113
|
+
// don't actually change the value, so we can do this in a single useEffect.
|
|
109
114
|
(0, react_1.useEffect)(() => {
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
// Use runInAction so mobx delays any reactions until all the mutations happen
|
|
116
|
+
(0, mobx_1.runInAction)(() => {
|
|
117
|
+
tableState.setRows(rows);
|
|
118
|
+
tableState.setColumns(columnsWithIds, visibleColumnsStorageKey);
|
|
119
|
+
tableState.setSearch(filter);
|
|
120
|
+
tableState.activeRowId = activeRowId;
|
|
121
|
+
tableState.activeCellId = activeCellId;
|
|
122
|
+
});
|
|
123
|
+
}, [tableState, rows, columnsWithIds, visibleColumnsStorageKey, activeRowId, activeCellId, filter]);
|
|
112
124
|
const columns = (0, hooks_1.useComputed)(() => {
|
|
113
125
|
return tableState.visibleColumns;
|
|
114
126
|
}, [tableState]);
|
|
115
127
|
// Initialize the sort state. This will only happen on the first render.
|
|
116
128
|
// Once the `TableState.sort` is defined, it will not re-initialize.
|
|
117
129
|
tableState.initSortState(props.sorting, columns);
|
|
118
|
-
(0, react_1.useEffect)(() => {
|
|
119
|
-
tableState.activeRowId = activeRowId;
|
|
120
|
-
}, [tableState, activeRowId]);
|
|
121
|
-
(0, react_1.useEffect)(() => {
|
|
122
|
-
tableState.activeCellId = activeCellId;
|
|
123
|
-
}, [tableState, activeCellId]);
|
|
124
|
-
(0, react_1.useEffect)(() => {
|
|
125
|
-
tableState.setSearch(filter);
|
|
126
|
-
}, [tableState, filter]);
|
|
127
130
|
// We track render count at the table level, which seems odd (we should be able to track this
|
|
128
131
|
// internally within each GridRow using a useRef), but we have suspicions that react-virtuoso
|
|
129
132
|
// (or us) is resetting component state more than necessary, so we track render counts from
|
|
@@ -134,51 +137,41 @@ function GridTable(props) {
|
|
|
134
137
|
const columnSizes = (0, useSetupColumnSizes_1.useSetupColumnSizes)(style, columns, resizeTarget !== null && resizeTarget !== void 0 ? resizeTarget : resizeRef, expandedColumnIds);
|
|
135
138
|
// Flatten, hide-if-filtered, hide-if-collapsed, and component-ize the sorted rows.
|
|
136
139
|
const [tableHeadRows, visibleDataRows, keptSelectedRows, tooManyClientSideRows] = (0, hooks_1.useComputed)(() => {
|
|
137
|
-
const columns = tableState.visibleColumns;
|
|
138
140
|
// Split out the header rows from the data rows so that we can put an `infoMessage` in between them (if needed).
|
|
139
141
|
const headerRows = [];
|
|
140
142
|
const expandableHeaderRows = [];
|
|
141
143
|
const totalsRows = [];
|
|
142
144
|
const keptSelectedRows = [];
|
|
143
145
|
let visibleDataRows = [];
|
|
144
|
-
const { visibleRows
|
|
146
|
+
const { visibleRows } = tableState;
|
|
145
147
|
const hasExpandableHeader = visibleRows.some((rs) => rs.row.id === utils_1.EXPANDABLE_HEADER);
|
|
146
148
|
// Get the flat list or rows from the header down...
|
|
147
149
|
visibleRows.forEach((rs) => {
|
|
148
|
-
const row =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
cellHighlight: "cellHighlight" in maybeStyle && maybeStyle.cellHighlight === true,
|
|
162
|
-
omitRowHover: "rowHover" in maybeStyle && maybeStyle.rowHover === false,
|
|
163
|
-
hasExpandableHeader,
|
|
164
|
-
isKeptSelectedRow: rs.isKept,
|
|
165
|
-
isLastKeptSelectionRow: keptRows[keptRows.length - 1] === rs.row,
|
|
166
|
-
} }, `${row.kind}-${row.id}`),
|
|
167
|
-
];
|
|
168
|
-
if (row.kind === "header") {
|
|
169
|
-
headerRows.push(tuple);
|
|
150
|
+
const row = ((0, jsx_runtime_1.jsx)(Row_1.Row, { ...{
|
|
151
|
+
as,
|
|
152
|
+
rs,
|
|
153
|
+
style,
|
|
154
|
+
rowStyles,
|
|
155
|
+
columnSizes,
|
|
156
|
+
getCount,
|
|
157
|
+
cellHighlight: "cellHighlight" in maybeStyle && maybeStyle.cellHighlight === true,
|
|
158
|
+
omitRowHover: "rowHover" in maybeStyle && maybeStyle.rowHover === false,
|
|
159
|
+
hasExpandableHeader,
|
|
160
|
+
} }, rs.key));
|
|
161
|
+
if (rs.kind === "header") {
|
|
162
|
+
headerRows.push(row);
|
|
170
163
|
}
|
|
171
|
-
else if (
|
|
172
|
-
expandableHeaderRows.push(
|
|
164
|
+
else if (rs.kind === "expandableHeader") {
|
|
165
|
+
expandableHeaderRows.push(row);
|
|
173
166
|
}
|
|
174
|
-
else if (
|
|
175
|
-
totalsRows.push(
|
|
167
|
+
else if (rs.kind === "totals") {
|
|
168
|
+
totalsRows.push(row);
|
|
176
169
|
}
|
|
177
|
-
else if (rs.isKept ||
|
|
178
|
-
keptSelectedRows.push(
|
|
170
|
+
else if (rs.isKept || rs.kind === utils_1.KEPT_GROUP) {
|
|
171
|
+
keptSelectedRows.push(row);
|
|
179
172
|
}
|
|
180
173
|
else {
|
|
181
|
-
visibleDataRows.push(
|
|
174
|
+
visibleDataRows.push(row);
|
|
182
175
|
}
|
|
183
176
|
});
|
|
184
177
|
// Once our header rows are created we can organize them in expected order.
|
|
@@ -190,11 +183,9 @@ function GridTable(props) {
|
|
|
190
183
|
return [tableHeadRows, visibleDataRows, keptSelectedRows, tooManyClientSideRows];
|
|
191
184
|
}, [as, api, style, rowStyles, maybeStyle, columnSizes, getCount, filterMaxRows]);
|
|
192
185
|
// Push back to the caller a way to ask us where a row is.
|
|
193
|
-
|
|
194
|
-
if (rowLookup)
|
|
195
|
-
|
|
196
|
-
rowLookup.current = (0, GridRowLookup_1.createRowLookup)(columns, visibleDataRows, virtuosoRef);
|
|
197
|
-
}
|
|
186
|
+
// Refs are cheap to assign to, so we don't bother doing this in a useEffect
|
|
187
|
+
if (props.rowLookup)
|
|
188
|
+
props.rowLookup.current = api.lookup;
|
|
198
189
|
const noData = visibleDataRows.length === 0;
|
|
199
190
|
const firstRowMessage = (noData && fallbackMessage) || (tooManyClientSideRows && "Hiding some rows, use filter...") || infoMessage;
|
|
200
191
|
const borderless = (_a = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _a === void 0 ? void 0 : _a.borderless;
|
|
@@ -237,11 +228,11 @@ function renderDiv(style, id, columns, visibleDataRows, keptSelectedRows, firstR
|
|
|
237
228
|
}, "data-testid": id, children: [(0, jsx_runtime_1.jsx)("div", { css: {
|
|
238
229
|
...(style.firstRowCss && Css_1.Css.addIn("& > div:first-of-type", style.firstRowCss).$),
|
|
239
230
|
...Css_1.Css.if(stickyHeader).sticky.topPx(stickyOffset).z(utils_1.zIndices.stickyHeader).$,
|
|
240
|
-
}, children: tableHeadRows
|
|
231
|
+
}, children: tableHeadRows }), (0, jsx_runtime_1.jsxs)("div", { css: {
|
|
241
232
|
...(style.betweenRowsCss ? Css_1.Css.addIn(`& > div > *`, style.betweenRowsCss).$ : {}),
|
|
242
233
|
...(style.firstNonHeaderRowCss ? Css_1.Css.addIn(`& > div:first-of-type > *`, style.firstNonHeaderRowCss).$ : {}),
|
|
243
234
|
...(style.lastRowCss && Css_1.Css.addIn("& > div:last-of-type", style.lastRowCss).$),
|
|
244
|
-
}, children: [keptSelectedRows
|
|
235
|
+
}, children: [keptSelectedRows, firstRowMessage && ((0, jsx_runtime_1.jsx)("div", { css: { ...style.firstRowMessageCss }, "data-gridrow": true, children: firstRowMessage })), visibleDataRows] })] }));
|
|
245
236
|
}
|
|
246
237
|
/** Renders as a table, primarily/solely for good print support. */
|
|
247
238
|
function renderTable(style, id, columns, visibleDataRows, keptSelectedRows, firstRowMessage, stickyHeader, xss, _virtuosoRef, tableHeadRows, stickyOffset, _infiniteScroll) {
|
|
@@ -255,7 +246,7 @@ function renderTable(style, id, columns, visibleDataRows, keptSelectedRows, firs
|
|
|
255
246
|
...style.rootCss,
|
|
256
247
|
...(style.minWidthPx ? Css_1.Css.mwPx(style.minWidthPx).$ : {}),
|
|
257
248
|
...xss,
|
|
258
|
-
}, "data-testid": id, children: [(0, jsx_runtime_1.jsx)("thead", { css: Css_1.Css.if(stickyHeader).sticky.topPx(stickyOffset).z(utils_1.zIndices.stickyHeader).$, children: tableHeadRows
|
|
249
|
+
}, "data-testid": id, children: [(0, jsx_runtime_1.jsx)("thead", { css: Css_1.Css.if(stickyHeader).sticky.topPx(stickyOffset).z(utils_1.zIndices.stickyHeader).$, children: tableHeadRows }), (0, jsx_runtime_1.jsxs)("tbody", { children: [keptSelectedRows, firstRowMessage && ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { colSpan: columns.length, css: { ...style.firstRowMessageCss }, children: firstRowMessage }) })), visibleDataRows] })] }));
|
|
259
250
|
}
|
|
260
251
|
/**
|
|
261
252
|
* Uses react-virtuoso to render rows virtually.
|
|
@@ -295,13 +286,13 @@ function renderVirtual(style, id, columns, visibleDataRows, keptSelectedRows, fi
|
|
|
295
286
|
topItemCount: stickyHeader ? tableHeadRows.length : 0, itemContent: (index) => {
|
|
296
287
|
// Since we have 3 arrays of rows: `tableHeadRows` and `visibleDataRows` and `keptSelectedRows` we must determine which one to render.
|
|
297
288
|
if (index < tableHeadRows.length) {
|
|
298
|
-
return tableHeadRows[index]
|
|
289
|
+
return tableHeadRows[index];
|
|
299
290
|
}
|
|
300
291
|
// Reset index
|
|
301
292
|
index -= tableHeadRows.length;
|
|
302
293
|
// Show keptSelectedRows if there are any
|
|
303
294
|
if (index < keptSelectedRows.length) {
|
|
304
|
-
return keptSelectedRows[index]
|
|
295
|
+
return keptSelectedRows[index];
|
|
305
296
|
}
|
|
306
297
|
// Reset index
|
|
307
298
|
index -= keptSelectedRows.length;
|
|
@@ -315,14 +306,17 @@ function renderVirtual(style, id, columns, visibleDataRows, keptSelectedRows, fi
|
|
|
315
306
|
index--;
|
|
316
307
|
}
|
|
317
308
|
// Lastly render the table body rows
|
|
318
|
-
return visibleDataRows[index]
|
|
309
|
+
return visibleDataRows[index];
|
|
319
310
|
}, totalCount: tableHeadRows.length + (firstRowMessage ? 1 : 0) + visibleDataRows.length + keptSelectedRows.length, ...(infiniteScroll
|
|
320
311
|
? {
|
|
321
312
|
increaseViewportBy: {
|
|
322
313
|
bottom: (_a = infiniteScroll.endOffsetPx) !== null && _a !== void 0 ? _a : 500,
|
|
323
314
|
top: 0,
|
|
324
315
|
},
|
|
325
|
-
|
|
316
|
+
// Add a `index > 0` check b/c Virtuoso is calling this in storybook
|
|
317
|
+
// with `endReached(0)` at odd times, like on page unload/story load,
|
|
318
|
+
// which then causes our test data to have duplicate ids in it.
|
|
319
|
+
endReached: (index) => (index > 0 ? infiniteScroll.onEndReached(index) : 0),
|
|
326
320
|
}
|
|
327
321
|
: {}) }));
|
|
328
322
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MutableRefObject } from "react";
|
|
2
2
|
import { VirtuosoHandle } from "react-virtuoso";
|
|
3
|
+
import { GridRowLookup } from "../index";
|
|
3
4
|
import { GridDataRow } from "./components/Row";
|
|
4
5
|
import { DiscriminateUnion, Kinded } from "./types";
|
|
5
6
|
import { TableState } from "./utils/TableState";
|
|
@@ -47,11 +48,20 @@ export type GridTableApi<R extends Kinded> = {
|
|
|
47
48
|
getVisibleColumnIds(): string[];
|
|
48
49
|
setVisibleColumns(ids: string[]): void;
|
|
49
50
|
};
|
|
51
|
+
/** Adds per-row methods to the `api`, i.e. for getting currently-visible children. */
|
|
52
|
+
export type GridRowApi<R extends Kinded> = GridTableApi<R> & {
|
|
53
|
+
getVisibleChildren(): GridDataRow<R>[];
|
|
54
|
+
getVisibleChildren<K extends R["kind"]>(kind: K): GridDataRow<DiscriminateUnion<R, "kind", K>>[];
|
|
55
|
+
getSelectedChildren(): GridDataRow<R>[];
|
|
56
|
+
getSelectedChildren<K extends R["kind"]>(kind: K): GridDataRow<DiscriminateUnion<R, "kind", K>>[];
|
|
57
|
+
};
|
|
50
58
|
export declare class GridTableApiImpl<R extends Kinded> implements GridTableApi<R> {
|
|
51
|
-
readonly tableState: TableState
|
|
59
|
+
readonly tableState: TableState<R>;
|
|
52
60
|
virtuosoRef: MutableRefObject<VirtuosoHandle | null>;
|
|
61
|
+
lookup: GridRowLookup<R>;
|
|
62
|
+
constructor();
|
|
53
63
|
/** Called once by the GridTable when it takes ownership of this api instance. */
|
|
54
|
-
init(persistCollapse: string | undefined, virtuosoRef: MutableRefObject<VirtuosoHandle | null
|
|
64
|
+
init(persistCollapse: string | undefined, virtuosoRef: MutableRefObject<VirtuosoHandle | null>): void;
|
|
55
65
|
scrollToIndex(index: number): void;
|
|
56
66
|
getSelectedRowIds(kind?: string): string[];
|
|
57
67
|
getSelectedRows(kind?: string): any;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GridTableApiImpl = exports.useGridTableApi = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
+
const index_1 = require("../index");
|
|
5
6
|
const TableState_1 = require("./utils/TableState");
|
|
6
7
|
/**
|
|
7
8
|
* Creates an `api` handle to drive a `GridTable`.
|
|
@@ -28,13 +29,16 @@ class GridTableApiImpl {
|
|
|
28
29
|
// This is public to GridTable but not exported outside of Beam
|
|
29
30
|
this.tableState = new TableState_1.TableState(this);
|
|
30
31
|
this.virtuosoRef = { current: null };
|
|
32
|
+
// This instance gets spread into each row's GridRowApi, so bind the methods up-front
|
|
33
|
+
bindMethods(this);
|
|
31
34
|
}
|
|
32
35
|
/** Called once by the GridTable when it takes ownership of this api instance. */
|
|
33
|
-
init(persistCollapse, virtuosoRef
|
|
36
|
+
init(persistCollapse, virtuosoRef) {
|
|
34
37
|
// Technically this drives both row-collapse and column-expanded
|
|
35
38
|
if (persistCollapse)
|
|
36
39
|
this.tableState.loadCollapse(persistCollapse);
|
|
37
40
|
this.virtuosoRef = virtuosoRef;
|
|
41
|
+
this.lookup = (0, index_1.createRowLookup)(this, virtuosoRef);
|
|
38
42
|
}
|
|
39
43
|
scrollToIndex(index) {
|
|
40
44
|
this.virtuosoRef.current && this.virtuosoRef.current.scrollToIndex(index);
|
|
@@ -75,3 +79,9 @@ class GridTableApiImpl {
|
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
exports.GridTableApiImpl = GridTableApiImpl;
|
|
82
|
+
function bindMethods(instance) {
|
|
83
|
+
Object.getOwnPropertyNames(Object.getPrototypeOf(instance)).forEach((key) => {
|
|
84
|
+
if (instance[key] instanceof Function && key !== "constructor")
|
|
85
|
+
instance[key] = instance[key].bind(instance);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -1,35 +1,29 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
-
import { GridTableApi } from "../GridTableApi";
|
|
3
2
|
import { GridStyle, RowStyles } from "../TableStyles";
|
|
4
|
-
import { DiscriminateUnion,
|
|
3
|
+
import { DiscriminateUnion, IfAny, Kinded, Pin, RenderAs } from "../types";
|
|
4
|
+
import { RowState } from "../utils/RowState";
|
|
5
5
|
import { AnyObject } from "../../../types";
|
|
6
6
|
interface RowProps<R extends Kinded> {
|
|
7
7
|
as: RenderAs;
|
|
8
|
-
|
|
9
|
-
row: GridDataRow<R>;
|
|
8
|
+
rs: RowState<R>;
|
|
10
9
|
style: GridStyle;
|
|
11
10
|
rowStyles: RowStyles<R> | undefined;
|
|
12
11
|
columnSizes: string[];
|
|
13
|
-
level: number;
|
|
14
12
|
getCount: (id: string) => object;
|
|
15
|
-
api: GridTableApi<R>;
|
|
16
13
|
cellHighlight: boolean;
|
|
17
14
|
omitRowHover: boolean;
|
|
18
15
|
hasExpandableHeader: boolean;
|
|
19
|
-
isKeptSelectedRow: boolean;
|
|
20
|
-
isLastKeptSelectionRow: boolean;
|
|
21
16
|
}
|
|
22
17
|
declare function RowImpl<R extends Kinded, S>(props: RowProps<R>): ReactElement;
|
|
23
18
|
/**
|
|
24
|
-
* Memoizes
|
|
19
|
+
* Memoizes rows so that re-rendering the table doesn't re-render every single row.
|
|
25
20
|
*
|
|
26
|
-
* We
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* same/unchanged Apollo cache fragment, then we won't re-render that row.
|
|
21
|
+
* We used to have a custom `propsAreEqual` method that would only compare `props.rows`
|
|
22
|
+
* on the `data` attribute, b/c our `createRows` methods do not create stable row identities;
|
|
23
|
+
* i.e. if one row changes, they all change.
|
|
30
24
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
25
|
+
* However, now RowState.row synthesizes a `row` that only reactively changes when
|
|
26
|
+
* that row's `data` explicitly changes, so we no longer need a custom `propsAreEqual` here.
|
|
33
27
|
*/
|
|
34
28
|
export declare const Row: typeof RowImpl;
|
|
35
29
|
/** A specific kind of row, including the GridDataRow props. */
|
|
@@ -1,49 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
3
|
exports.Row = void 0;
|
|
27
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
28
5
|
const mobx_react_1 = require("mobx-react");
|
|
29
|
-
const react_1 =
|
|
6
|
+
const react_1 = require("react");
|
|
30
7
|
const cell_1 = require("./cell");
|
|
31
8
|
const KeptGroupRow_1 = require("./KeptGroupRow");
|
|
32
9
|
const sortRows_1 = require("../utils/sortRows");
|
|
33
10
|
const TableState_1 = require("../utils/TableState");
|
|
34
11
|
const utils_1 = require("../utils/utils");
|
|
35
12
|
const Css_1 = require("../../../Css");
|
|
36
|
-
const hooks_1 = require("../../../hooks");
|
|
37
13
|
const utils_2 = require("../../../utils");
|
|
38
|
-
const shallowEqual_1 = require("../../../utils/shallowEqual");
|
|
39
14
|
// We extract Row to its own mini-component primarily so we can React.memo'ize it.
|
|
40
15
|
function RowImpl(props) {
|
|
41
16
|
var _a, _b;
|
|
42
|
-
const { as,
|
|
17
|
+
const { as, rs, style, rowStyles, columnSizes, getCount, cellHighlight, omitRowHover, hasExpandableHeader, ...others } = props;
|
|
43
18
|
const { tableState } = (0, react_1.useContext)(TableState_1.TableStateContext);
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const
|
|
19
|
+
// We're wrapped in observer, so can access these without useComputeds
|
|
20
|
+
const { api, visibleColumns: columns } = tableState;
|
|
21
|
+
const { row, api: rowApi, isActive, isKept: isKeptRow, isLastKeptRow, level } = rs;
|
|
47
22
|
// We treat the "header" and "totals" kind as special for "good defaults" styling
|
|
48
23
|
const isHeader = row.kind === utils_1.HEADER;
|
|
49
24
|
const isTotals = row.kind === utils_1.TOTALS;
|
|
@@ -51,6 +26,7 @@ function RowImpl(props) {
|
|
|
51
26
|
const isKeptGroupRow = row.kind === utils_1.KEPT_GROUP;
|
|
52
27
|
const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
|
|
53
28
|
const RowTag = as === "table" ? "tr" : "div";
|
|
29
|
+
const sortOn = (_a = tableState.sortConfig) === null || _a === void 0 ? void 0 : _a.on;
|
|
54
30
|
const revealOnRowHoverClass = "revealOnRowHover";
|
|
55
31
|
const showRowHoverColor = !utils_1.reservedRowKinds.includes(row.kind) && !omitRowHover;
|
|
56
32
|
const rowStyleCellCss = (0, utils_1.maybeApplyFunction)(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.cellCss);
|
|
@@ -69,7 +45,7 @@ function RowImpl(props) {
|
|
|
69
45
|
[` > .${revealOnRowHoverClass} > *`]: Css_1.Css.invisible.$,
|
|
70
46
|
[`:hover > .${revealOnRowHoverClass} > *`]: Css_1.Css.visible.$,
|
|
71
47
|
},
|
|
72
|
-
...(
|
|
48
|
+
...(isLastKeptRow && Css_1.Css.addIn("&>*", style.keptLastRowCss).$),
|
|
73
49
|
};
|
|
74
50
|
let currentColspan = 1;
|
|
75
51
|
// Keep a running count of how many expanded columns are being shown.
|
|
@@ -127,7 +103,7 @@ function RowImpl(props) {
|
|
|
127
103
|
currentColspan -= 1;
|
|
128
104
|
return null;
|
|
129
105
|
}
|
|
130
|
-
const maybeContent = (0, utils_1.applyRowFn)(column, row,
|
|
106
|
+
const maybeContent = (0, utils_1.applyRowFn)(column, row, rowApi, level, isExpanded);
|
|
131
107
|
// Only use the `numExpandedColumns` as the `colspan` when rendering the "Expandable Header"
|
|
132
108
|
currentColspan =
|
|
133
109
|
(0, utils_1.isGridCellContent)(maybeContent) && typeof maybeContent.colspan === "number"
|
|
@@ -143,7 +119,7 @@ function RowImpl(props) {
|
|
|
143
119
|
const isExpandable = (0, utils_2.isFunction)(column.expandColumns) ||
|
|
144
120
|
(column.expandColumns && column.expandColumns.length > 0) ||
|
|
145
121
|
column.expandedWidth !== undefined;
|
|
146
|
-
const content = (0, utils_1.toContent)(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment, column, isExpandableHeader, isExpandable, minStickyLeftOffset,
|
|
122
|
+
const content = (0, utils_1.toContent)(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment, column, isExpandableHeader, isExpandable, minStickyLeftOffset, isKeptRow);
|
|
147
123
|
(0, sortRows_1.ensureClientSideSortValueIsSortable)(sortOn, isHeader || isTotals || isExpandableHeader, column, columnIndex, maybeContent);
|
|
148
124
|
const maybeSticky = (_a = (((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.sticky) || column.sticky)) !== null && _a !== void 0 ? _a : undefined;
|
|
149
125
|
const maybeStickyColumnStyles = maybeSticky && columnSizes
|
|
@@ -230,19 +206,14 @@ function RowImpl(props) {
|
|
|
230
206
|
})) }));
|
|
231
207
|
}
|
|
232
208
|
/**
|
|
233
|
-
* Memoizes
|
|
209
|
+
* Memoizes rows so that re-rendering the table doesn't re-render every single row.
|
|
234
210
|
*
|
|
235
|
-
* We
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* same/unchanged Apollo cache fragment, then we won't re-render that row.
|
|
211
|
+
* We used to have a custom `propsAreEqual` method that would only compare `props.rows`
|
|
212
|
+
* on the `data` attribute, b/c our `createRows` methods do not create stable row identities;
|
|
213
|
+
* i.e. if one row changes, they all change.
|
|
239
214
|
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
215
|
+
* However, now RowState.row synthesizes a `row` that only reactively changes when
|
|
216
|
+
* that row's `data` explicitly changes, so we no longer need a custom `propsAreEqual` here.
|
|
242
217
|
*/
|
|
243
218
|
// Declared as a const + `as typeof RowImpl` to work with generics, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37087#issuecomment-656596623
|
|
244
|
-
exports.Row =
|
|
245
|
-
const { row: row1, ...others1 } = one;
|
|
246
|
-
const { row: row2, ...others2 } = two;
|
|
247
|
-
return (0, shallowEqual_1.shallowEqual)(row1, row2) && (0, shallowEqual_1.shallowEqual)(others1, others2);
|
|
248
|
-
});
|
|
219
|
+
exports.Row = (0, mobx_react_1.observer)(RowImpl);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MutableRefObject } from "react";
|
|
2
2
|
import { GridStyle } from "../TableStyles";
|
|
3
|
-
import { GridColumnWithId } from "../types";
|
|
3
|
+
import { GridColumnWithId, Kinded } from "../types";
|
|
4
4
|
/**
|
|
5
5
|
* Calculates an array of sizes for each of our columns.
|
|
6
6
|
*
|
|
@@ -20,4 +20,4 @@ import { GridColumnWithId } from "../types";
|
|
|
20
20
|
*
|
|
21
21
|
* Disclaimer that we roll our own `fr` b/c we're not in CSS grid anymore.
|
|
22
22
|
*/
|
|
23
|
-
export declare function useSetupColumnSizes(style: GridStyle, columns: GridColumnWithId<
|
|
23
|
+
export declare function useSetupColumnSizes<R extends Kinded>(style: GridStyle, columns: GridColumnWithId<R>[], resizeRef: MutableRefObject<HTMLElement | null>, expandedColumnIds: string[]): string[];
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
2
|
import { GridCellContent } from "./components/cell";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { GridRowKind } from "./components/Row";
|
|
4
|
+
import { GridRowApi } from "./GridTableApi";
|
|
5
5
|
import { Margin, Xss } from "../../Css";
|
|
6
6
|
export type Kinded = {
|
|
7
7
|
kind: string;
|
|
8
8
|
};
|
|
9
9
|
export type GridTableXss = Xss<Margin>;
|
|
10
10
|
export type RenderAs = "div" | "table" | "virtual";
|
|
11
|
-
export type RowTuple<R extends Kinded> = [GridDataRow<R>, ReactElement];
|
|
12
|
-
export type ParentChildrenTuple<R extends Kinded> = [GridDataRow<R>, ParentChildrenTuple<R>[]];
|
|
13
11
|
export type Direction = "ASC" | "DESC";
|
|
14
12
|
export type MaybeFn<T> = T | (() => T);
|
|
15
13
|
export type GridCellAlignment = "left" | "right" | "center";
|
|
@@ -35,12 +33,12 @@ export type GridColumn<R extends Kinded> = {
|
|
|
35
33
|
data: infer D;
|
|
36
34
|
} ? (data: D, opts: {
|
|
37
35
|
row: GridRowKind<R, K>;
|
|
38
|
-
api:
|
|
36
|
+
api: GridRowApi<R>;
|
|
39
37
|
level: number;
|
|
40
38
|
expanded: boolean;
|
|
41
39
|
}) => ReactNode | GridCellContent : (data: undefined, opts: {
|
|
42
40
|
row: GridRowKind<R, K>;
|
|
43
|
-
api:
|
|
41
|
+
api: GridRowApi<R>;
|
|
44
42
|
level: number;
|
|
45
43
|
expanded: boolean;
|
|
46
44
|
}) => ReactNode | GridCellContent);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GridColumnWithId } from "../types";
|
|
1
|
+
import { GridColumnWithId, Kinded } from "../types";
|
|
2
2
|
import { ColumnStates } from "./ColumnStates";
|
|
3
3
|
import { ColumnStorage } from "./ColumnStorage";
|
|
4
4
|
/**
|
|
@@ -7,18 +7,18 @@ import { ColumnStorage } from "./ColumnStorage";
|
|
|
7
7
|
* This is primarily for tracking visible/expanded columns for tables
|
|
8
8
|
* that use the expandable columns feature.
|
|
9
9
|
*/
|
|
10
|
-
export declare class ColumnState {
|
|
10
|
+
export declare class ColumnState<R extends Kinded> {
|
|
11
11
|
private states;
|
|
12
|
-
column: GridColumnWithId<
|
|
13
|
-
children: ColumnState[] | undefined;
|
|
12
|
+
column: GridColumnWithId<R>;
|
|
13
|
+
children: ColumnState<R>[] | undefined;
|
|
14
14
|
private visible;
|
|
15
15
|
private expanded;
|
|
16
|
-
constructor(states: ColumnStates
|
|
16
|
+
constructor(states: ColumnStates<R>, storage: ColumnStorage<R>, column: GridColumnWithId<R>);
|
|
17
17
|
setVisible(visible: boolean): void;
|
|
18
18
|
get isExpanded(): boolean;
|
|
19
19
|
toggleExpanded(): void;
|
|
20
20
|
/** Calls the `column.expandColumns` function, if set, and adds the resulting columns. */
|
|
21
21
|
doExpand(force?: boolean): Promise<void>;
|
|
22
22
|
/** Returns this column, if visible, and its children, if expanded. */
|
|
23
|
-
get maybeSelfAndChildren(): ColumnState[];
|
|
23
|
+
get maybeSelfAndChildren(): ColumnState<R>[];
|
|
24
24
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { GridColumnWithId } from "../../..";
|
|
1
|
+
import { GridColumnWithId, Kinded } from "../../..";
|
|
2
2
|
import { ColumnState } from "./ColumnState";
|
|
3
3
|
/** A reactive/observable wrapper around our columns. */
|
|
4
|
-
export declare class ColumnStates {
|
|
4
|
+
export declare class ColumnStates<R extends Kinded> {
|
|
5
5
|
private columns;
|
|
6
6
|
private map;
|
|
7
7
|
private storage;
|
|
@@ -14,15 +14,15 @@ export declare class ColumnStates {
|
|
|
14
14
|
* So like you expand a column, and new columns show up, but we'll remember they
|
|
15
15
|
* were hidden last time you looked at this specific expansion of columns.
|
|
16
16
|
*/
|
|
17
|
-
setColumns(columns: GridColumnWithId<
|
|
17
|
+
setColumns(columns: GridColumnWithId<R>[], visibleColumnsStorageKey: string | undefined): void;
|
|
18
18
|
/** Adds a column to our state, i.e. maybe a dynamically loaded column. */
|
|
19
|
-
addColumn(column: GridColumnWithId<
|
|
19
|
+
addColumn(column: GridColumnWithId<R>): ColumnState<R>;
|
|
20
20
|
/** Returns the `ColumnState` for the given `id`. */
|
|
21
|
-
get(id: string): ColumnState
|
|
21
|
+
get(id: string): ColumnState<R>;
|
|
22
22
|
/** Returns all currently-expanded columns. */
|
|
23
|
-
get expandedColumns(): ColumnState[];
|
|
23
|
+
get expandedColumns(): ColumnState<R>[];
|
|
24
24
|
/** Returns a flat list of all visible columns. */
|
|
25
|
-
get allVisibleColumns(): ColumnState[];
|
|
25
|
+
get allVisibleColumns(): ColumnState<R>[];
|
|
26
26
|
setVisibleColumns(ids: string[]): void;
|
|
27
27
|
loadExpanded(storageKey: string): void;
|
|
28
28
|
loadVisible(storageKey: string): void;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { Kinded } from "../types";
|
|
1
2
|
import { ColumnStates } from "./ColumnStates";
|
|
2
3
|
/** Loads/saves the column state from sessionStorage. */
|
|
3
|
-
export declare class ColumnStorage {
|
|
4
|
+
export declare class ColumnStorage<R extends Kinded> {
|
|
4
5
|
private states;
|
|
5
6
|
private expandedIds;
|
|
6
7
|
private visibleIds;
|
|
7
|
-
constructor(states: ColumnStates);
|
|
8
|
+
constructor(states: ColumnStates<R>);
|
|
8
9
|
loadExpanded(persistCollapse: string): void;
|
|
9
10
|
loadVisible(storageKey: string): void;
|
|
10
11
|
wasExpanded(id: string): boolean | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { MutableRefObject } from "react";
|
|
2
2
|
import { VirtuosoHandle } from "react-virtuoso";
|
|
3
3
|
import { GridDataRow } from "../components/Row";
|
|
4
|
-
import {
|
|
4
|
+
import { GridTableApiImpl } from "../GridTableApi";
|
|
5
|
+
import { DiscriminateUnion, GridColumnWithId, Kinded } from "../types";
|
|
5
6
|
/**
|
|
6
7
|
* Allows a caller to ask for the currently shown rows, given the current sorting/filtering.
|
|
7
8
|
*
|
|
@@ -22,6 +23,6 @@ interface NextPrev<R extends Kinded> {
|
|
|
22
23
|
next: GridDataRow<R> | undefined;
|
|
23
24
|
prev: GridDataRow<R> | undefined;
|
|
24
25
|
}
|
|
25
|
-
export declare function createRowLookup<R extends Kinded>(
|
|
26
|
+
export declare function createRowLookup<R extends Kinded>(api: GridTableApiImpl<R>, virtuosoRef: MutableRefObject<VirtuosoHandle | null>): GridRowLookup<R>;
|
|
26
27
|
export declare function getKinds<R extends Kinded>(columns: GridColumnWithId<R>[]): R[];
|
|
27
28
|
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getKinds = exports.createRowLookup = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
|
-
function createRowLookup(
|
|
5
|
+
function createRowLookup(api, virtuosoRef) {
|
|
6
6
|
return {
|
|
7
7
|
scrollTo(kind, id) {
|
|
8
8
|
if (virtuosoRef.current === null) {
|
|
@@ -10,16 +10,17 @@ function createRowLookup(columns, filteredRows, virtuosoRef) {
|
|
|
10
10
|
// element and calling .scrollIntoView, just not doing that yet.
|
|
11
11
|
throw new Error("scrollTo is only supported for as=virtual");
|
|
12
12
|
}
|
|
13
|
-
const index =
|
|
13
|
+
const index = api.tableState.visibleRows.findIndex((r) => r && r.kind === kind && r.row.id === id);
|
|
14
14
|
virtuosoRef.current.scrollToIndex({ index, behavior: "smooth" });
|
|
15
15
|
},
|
|
16
16
|
currentList() {
|
|
17
|
-
return
|
|
17
|
+
return api.tableState.visibleRows.map((rs) => rs.row);
|
|
18
18
|
},
|
|
19
19
|
lookup(row, additionalFilter = () => true) {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
var _c;
|
|
22
|
-
const rows =
|
|
22
|
+
const rows = this.currentList().filter(additionalFilter);
|
|
23
|
+
const columns = api.tableState.visibleColumns;
|
|
23
24
|
// Ensure we have `result.kind = {}` for each kind
|
|
24
25
|
const result = Object.fromEntries(getKinds(columns).map((kind) => [kind, {}]));
|
|
25
26
|
// This is an admittedly cute/fancy scan, instead of just `rows.findIndex`, but
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { Kinded } from "../../..";
|
|
1
2
|
import { GridDataRow } from "../components/Row";
|
|
3
|
+
import { GridRowApi } from "../GridTableApi";
|
|
2
4
|
import { RowStates } from "./RowStates";
|
|
3
5
|
import { SelectedState } from "./TableState";
|
|
4
6
|
/**
|
|
@@ -7,13 +9,15 @@ import { SelectedState } from "./TableState";
|
|
|
7
9
|
* We set up the RowStates in a tree, just like GridDataRow, to make business logic
|
|
8
10
|
* that uses parent/children easier to write, i.e. selected-ness and collapsed-ness.
|
|
9
11
|
*/
|
|
10
|
-
export declare class RowState {
|
|
12
|
+
export declare class RowState<R extends Kinded> {
|
|
11
13
|
private states;
|
|
12
|
-
parent: RowState | undefined;
|
|
13
|
-
/** Our row,
|
|
14
|
-
|
|
14
|
+
parent: RowState<R> | undefined;
|
|
15
|
+
/** Our row, not actually observed, b/c each `createRows` calc creates unstable rows. */
|
|
16
|
+
private _row;
|
|
17
|
+
/** Our data, only ref observed, so we don't crawl into GraphQL fragments. */
|
|
18
|
+
private _data;
|
|
15
19
|
/** Our children row states, as of the latest `props.rows`, without any filtering applied. */
|
|
16
|
-
children: RowState[] | undefined;
|
|
20
|
+
children: RowState<R>[] | undefined;
|
|
17
21
|
/** Whether we are *directly* selected. */
|
|
18
22
|
selected: boolean;
|
|
19
23
|
/** Whether we are collapsed. */
|
|
@@ -37,7 +41,12 @@ export declare class RowState {
|
|
|
37
41
|
* actively removed.
|
|
38
42
|
*/
|
|
39
43
|
removed: false | "soft" | "hard";
|
|
40
|
-
|
|
44
|
+
private isCalculatingDirectMatch;
|
|
45
|
+
constructor(states: RowStates<R>, parent: RowState<R> | undefined, row: GridDataRow<R>);
|
|
46
|
+
/** Returns a stable-ish row identity that will only change if our `data` changes. */
|
|
47
|
+
get row(): GridDataRow<R>;
|
|
48
|
+
/** Accepts a new unstable row, i.e. each `createRows` creates a new row literal. */
|
|
49
|
+
set row(row: GridDataRow<R>);
|
|
41
50
|
/**
|
|
42
51
|
* Whether we match a client-side filter; true if no filter is in place.
|
|
43
52
|
*
|
|
@@ -75,11 +84,16 @@ export declare class RowState {
|
|
|
75
84
|
toggleCollapsed(): void;
|
|
76
85
|
/** Whether this is a selected-but-filtered-out row that we should hoist to the top. */
|
|
77
86
|
get isKept(): boolean;
|
|
87
|
+
get isLastKeptRow(): boolean;
|
|
88
|
+
get key(): string;
|
|
89
|
+
get kind(): string;
|
|
90
|
+
get isActive(): boolean;
|
|
78
91
|
get level(): number;
|
|
79
92
|
private get inferSelectedState();
|
|
80
93
|
/** Returns this row and, if we're not collapsed, our children. */
|
|
81
|
-
get selfAndMaybeChildren(): RowState[];
|
|
94
|
+
get selfAndMaybeChildren(): RowState<R>[];
|
|
82
95
|
private get visibleChildren();
|
|
96
|
+
private get visibleDirectlyMatchedChildren();
|
|
83
97
|
/** The `visibleChildren`, but with the current sort config applied. */
|
|
84
98
|
private get visibleSortedChildren();
|
|
85
99
|
/**
|
|
@@ -95,6 +109,7 @@ export declare class RowState {
|
|
|
95
109
|
*/
|
|
96
110
|
private get isParent();
|
|
97
111
|
private get isPinned();
|
|
112
|
+
get api(): GridRowApi<R>;
|
|
98
113
|
get isReservedKind(): boolean;
|
|
99
114
|
/** A dedicated method to "looking down" recursively, to avoid loops in `isMatched`. */
|
|
100
115
|
private get hasDirectlyMatchedChildren();
|
|
@@ -39,10 +39,39 @@ class RowState {
|
|
|
39
39
|
* actively removed.
|
|
40
40
|
*/
|
|
41
41
|
this.removed = false;
|
|
42
|
+
this.isCalculatingDirectMatch = false;
|
|
42
43
|
this.row = row;
|
|
43
44
|
this.selected = !!row.initSelected;
|
|
44
45
|
this.collapsed = (_a = states.storage.wasCollapsed(row.id)) !== null && _a !== void 0 ? _a : !!row.initCollapsed;
|
|
45
|
-
(0, mobx_1.makeAutoObservable)(this,
|
|
46
|
+
(0, mobx_1.makeAutoObservable)(this,
|
|
47
|
+
// 'as any' because the fields are private so don't show up in the type
|
|
48
|
+
{
|
|
49
|
+
_row: false,
|
|
50
|
+
_data: mobx_1.observable.ref,
|
|
51
|
+
isCalculatingDirectMatch: false,
|
|
52
|
+
}, { name: `RowState@${row.id}` });
|
|
53
|
+
// Ideally we could hook up this reaction conditionally, but for the header RowState,
|
|
54
|
+
// we're initialized by GridTableApiImpl, before TableState.onRowSelect has a chance
|
|
55
|
+
// to be set to GridTableProps.onRowSelect, so for now just always hook up this reaction.
|
|
56
|
+
(0, mobx_1.reaction)(() => this.selectedState, (state) => {
|
|
57
|
+
var _a;
|
|
58
|
+
const isSelected = state === "checked";
|
|
59
|
+
const tableFn = (_a = states.table.onRowSelect) === null || _a === void 0 ? void 0 : _a[this.row.kind];
|
|
60
|
+
tableFn && tableFn(this.row.data, isSelected, { row, api: states.table.api });
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/** Returns a stable-ish row identity that will only change if our `data` changes. */
|
|
64
|
+
get row() {
|
|
65
|
+
// This is a noop, but makes mobx see `_data` as a dependency
|
|
66
|
+
return Object.assign(this._row, { data: this._data });
|
|
67
|
+
}
|
|
68
|
+
/** Accepts a new unstable row, i.e. each `createRows` creates a new row literal. */
|
|
69
|
+
set row(row) {
|
|
70
|
+
// If `_data` is a stable GraphQL fragment, but row is just a new literal around
|
|
71
|
+
// it, this won't actually cause any reactivity changes. But once _data does change,
|
|
72
|
+
// then anyone watching `.row` will see the new row instance + new data.
|
|
73
|
+
this._row = row;
|
|
74
|
+
this._data = row.data;
|
|
46
75
|
}
|
|
47
76
|
/**
|
|
48
77
|
* Whether we match a client-side filter; true if no filter is in place.
|
|
@@ -148,6 +177,21 @@ class RowState {
|
|
|
148
177
|
!this.isParent &&
|
|
149
178
|
(!this.isMatched || this.removed === "soft"));
|
|
150
179
|
}
|
|
180
|
+
get isLastKeptRow() {
|
|
181
|
+
if (!this.isKept)
|
|
182
|
+
return false;
|
|
183
|
+
const { keptRows } = this.states.table;
|
|
184
|
+
return keptRows[keptRows.length - 1] === this;
|
|
185
|
+
}
|
|
186
|
+
get key() {
|
|
187
|
+
return `${this.row.kind}-${this.row.id}`;
|
|
188
|
+
}
|
|
189
|
+
get kind() {
|
|
190
|
+
return this.row.kind;
|
|
191
|
+
}
|
|
192
|
+
get isActive() {
|
|
193
|
+
return this.states.table.activeRowId === `${this.row.kind}_${this.row.id}`;
|
|
194
|
+
}
|
|
151
195
|
get level() {
|
|
152
196
|
// Make the header level -1, so the top-level rows are level 0
|
|
153
197
|
return !this.parent ? -1 : this.parent.level + 1;
|
|
@@ -176,6 +220,28 @@ class RowState {
|
|
|
176
220
|
// any kept row children, as they will cause its hasDirectlyMatchedChildren to be true.
|
|
177
221
|
(rs.isReservedKind && rs.row.kind !== utils_1.KEPT_GROUP) || rs.isMatched || rs.isPinned)) !== null && _b !== void 0 ? _b : []);
|
|
178
222
|
}
|
|
223
|
+
// This is a copy/paste of visibleChildren, but using isDirectlyMatched instead of isMatched
|
|
224
|
+
// to avoid a cycle, i.e.:
|
|
225
|
+
//
|
|
226
|
+
// 1. A parent row evals its own isDirectlyMatched
|
|
227
|
+
// 2. The parent row has a cell that calculates "sum of visible children"
|
|
228
|
+
// 3. To know whether the sum cell matches the filter, "1234", we need to render the cell
|
|
229
|
+
// 4. If rendering the parent cell called `visibleChildren` directly, that method checks
|
|
230
|
+
// "is the parent directly matched?" (so that child of matched parents are always shown),
|
|
231
|
+
// but now we've looped--deciding the content of the parent cell itself requires knowing
|
|
232
|
+
// if the parent cell matched (b/c that controls which children are visible).
|
|
233
|
+
//
|
|
234
|
+
// We side-step this by assuming that the `GridRowApi.getVisibleChildren` can use the
|
|
235
|
+
// slightly-less accurate "my children are visible if they're directly matched".
|
|
236
|
+
get visibleDirectlyMatchedChildren() {
|
|
237
|
+
var _a, _b;
|
|
238
|
+
if (this.row.kind === utils_1.KEPT_GROUP)
|
|
239
|
+
return this.states.keptRows;
|
|
240
|
+
return ((_b = (_a = this.children) === null || _a === void 0 ? void 0 : _a.filter((rs) => (rs.isReservedKind && rs.row.kind !== utils_1.KEPT_GROUP) ||
|
|
241
|
+
rs.isDirectlyMatched ||
|
|
242
|
+
rs.hasDirectlyMatchedChildren ||
|
|
243
|
+
rs.isPinned)) !== null && _b !== void 0 ? _b : []);
|
|
244
|
+
}
|
|
179
245
|
/** The `visibleChildren`, but with the current sort config applied. */
|
|
180
246
|
get visibleSortedChildren() {
|
|
181
247
|
let rows = this.visibleChildren;
|
|
@@ -203,6 +269,28 @@ class RowState {
|
|
|
203
269
|
get isPinned() {
|
|
204
270
|
return typeof this.row.pin === "string" || (!!this.row.pin && this.row.pin.filter !== true);
|
|
205
271
|
}
|
|
272
|
+
// mobx will cache this getter for us
|
|
273
|
+
get api() {
|
|
274
|
+
const rs = this;
|
|
275
|
+
// Copy the GridTableApi + the getVisibleChildren GridRowApi method
|
|
276
|
+
return {
|
|
277
|
+
...this.states.table.api,
|
|
278
|
+
// The caller can invoke this observable without their own useComputed,
|
|
279
|
+
// b/c we wrap all rows in an observer
|
|
280
|
+
getVisibleChildren(kind) {
|
|
281
|
+
// Avoid infinite loop if a cell asks for getVisibleChildren while calculating isMatched
|
|
282
|
+
const children = rs.isCalculatingDirectMatch
|
|
283
|
+
? rs.visibleDirectlyMatchedChildren.map((cs) => cs.row)
|
|
284
|
+
: rs.visibleChildren.map((cs) => cs.row);
|
|
285
|
+
return !kind ? children : children.filter((r) => r.kind === kind);
|
|
286
|
+
},
|
|
287
|
+
getSelectedChildren(kind) {
|
|
288
|
+
var _a;
|
|
289
|
+
const children = ((_a = rs.children) !== null && _a !== void 0 ? _a : []).filter((cs) => cs.isSelected).map((cs) => cs.row);
|
|
290
|
+
return !kind ? children : children.filter((r) => r.kind === kind);
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
}
|
|
206
294
|
get isReservedKind() {
|
|
207
295
|
return utils_1.reservedRowKinds.includes(this.row.kind);
|
|
208
296
|
}
|
|
@@ -218,21 +306,27 @@ class RowState {
|
|
|
218
306
|
return !!this.parent && (this.parent.isDirectlyMatched || this.parent.hasDirectlyMatchedParent);
|
|
219
307
|
}
|
|
220
308
|
get isDirectlyMatched() {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
.
|
|
309
|
+
this.isCalculatingDirectMatch = true;
|
|
310
|
+
try {
|
|
311
|
+
// Reserved rows like the header can never be directly matched, and treating them
|
|
312
|
+
// as matched currently throws off the header's select all/etc. behavior
|
|
313
|
+
if (this.isReservedKind)
|
|
314
|
+
return false;
|
|
315
|
+
// Ignore hard-deleted rows, i.e. from `api.deleteRows`; in theory any hard-deleted
|
|
316
|
+
// rows should be removed from `this.children` anyway, by a change to `props.rows`,
|
|
317
|
+
// but just in case the user calls _only_ `api.deleteRows`, and expects the row to
|
|
318
|
+
// go away, go ahead and filter them out here.
|
|
319
|
+
if (this.removed === "hard")
|
|
320
|
+
return false;
|
|
321
|
+
// Reacts to either search state or visibleColumns state changing
|
|
322
|
+
const { visibleColumns, search } = this.states.table;
|
|
323
|
+
return search.every((term) => visibleColumns
|
|
324
|
+
.map((c) => (0, utils_1.applyRowFn)(c, this.row, this.api, 0, false))
|
|
325
|
+
.some((maybeContent) => (0, utils_1.matchesFilter)(maybeContent, term)));
|
|
326
|
+
}
|
|
327
|
+
finally {
|
|
328
|
+
this.isCalculatingDirectMatch = false;
|
|
329
|
+
}
|
|
236
330
|
}
|
|
237
331
|
/** Used by node when doing `console.log(rs)`. */
|
|
238
332
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Kinded } from "../../..";
|
|
1
2
|
import { GridDataRow } from "../components/Row";
|
|
2
3
|
import { RowState } from "./RowState";
|
|
3
4
|
import { RowStorage } from "./RowStorage";
|
|
@@ -5,33 +6,33 @@ import { TableState } from "./TableState";
|
|
|
5
6
|
/**
|
|
6
7
|
* Manages our tree of observable RowStates that manage each GridDataRow's behavior.
|
|
7
8
|
*/
|
|
8
|
-
export declare class RowStates {
|
|
9
|
+
export declare class RowStates<R extends Kinded> {
|
|
9
10
|
private map;
|
|
10
|
-
readonly table: TableState
|
|
11
|
-
readonly storage: RowStorage
|
|
11
|
+
readonly table: TableState<R>;
|
|
12
|
+
readonly storage: RowStorage<R>;
|
|
12
13
|
private readonly header;
|
|
13
14
|
private keptGroupRow;
|
|
14
15
|
/** The first level of rows, i.e. not the header (or kept group), but the totals + top-level children. */
|
|
15
16
|
private topRows;
|
|
16
|
-
constructor(table: TableState);
|
|
17
|
+
constructor(table: TableState<R>);
|
|
17
18
|
/** Returns a flat list of all of our RowStates. */
|
|
18
|
-
get allStates(): RowState[];
|
|
19
|
+
get allStates(): RowState<R>[];
|
|
19
20
|
/** Returns the `RowState` for the given `id`. We should probably require `kind`. */
|
|
20
|
-
get(id: string): RowState
|
|
21
|
+
get(id: string): RowState<R>;
|
|
21
22
|
/**
|
|
22
23
|
* Merge a new set of `rows` prop into our state.
|
|
23
24
|
*
|
|
24
25
|
* Any missing rows are marked as `wasRemoved` so we can consider them "kept" if they're also selected.
|
|
25
26
|
*/
|
|
26
|
-
setRows(rows: GridDataRow<
|
|
27
|
+
setRows(rows: GridDataRow<R>[]): void;
|
|
27
28
|
/** Fully delete `ids`, so they don't show up in kept rows anymore. */
|
|
28
29
|
delete(ids: string[]): void;
|
|
29
30
|
/** Implements special collapse behavior, which is just the header's collapse/uncollapse. */
|
|
30
31
|
toggleCollapsed(id: string): void;
|
|
31
|
-
get visibleRows(): RowState[];
|
|
32
|
+
get visibleRows(): RowState<R>[];
|
|
32
33
|
/** Returns kept rows, i.e. those that were user-selected but then client-side or server-side filtered. */
|
|
33
|
-
get keptRows(): RowState[];
|
|
34
|
-
get collapsedRows(): RowState[];
|
|
34
|
+
get keptRows(): RowState<R>[];
|
|
35
|
+
get collapsedRows(): RowState<R>[];
|
|
35
36
|
private createHeaderRow;
|
|
36
37
|
/** Create our synthetic "group row" for kept rows, that users never pass in, but we self-inject as needed. */
|
|
37
38
|
private createKeptGroupRow;
|
|
@@ -13,14 +13,11 @@ class RowStates {
|
|
|
13
13
|
// A flat map of all row id -> RowState
|
|
14
14
|
this.map = new mobx_1.ObservableMap();
|
|
15
15
|
this.storage = new RowStorage_1.RowStorage(this);
|
|
16
|
-
// Pre-create the header to drive select-all/etc. behavior, even if the user
|
|
17
|
-
// doesn't pass an explicit `header` GridDataRow in `rows.props`
|
|
18
|
-
this.header = this.createHeaderRow();
|
|
19
|
-
// Pre-create our keptGroupRow for if/when we need it.
|
|
20
|
-
this.keptGroupRow = this.createKeptGroupRow(this.header);
|
|
21
16
|
/** The first level of rows, i.e. not the header (or kept group), but the totals + top-level children. */
|
|
22
17
|
this.topRows = [];
|
|
23
18
|
this.table = table;
|
|
19
|
+
this.header = this.createHeaderRow();
|
|
20
|
+
this.keptGroupRow = this.createKeptGroupRow(this.header);
|
|
24
21
|
this.map.set(this.header.row.id, this.header);
|
|
25
22
|
this.map.set(this.keptGroupRow.row.id, this.keptGroupRow);
|
|
26
23
|
}
|
|
@@ -170,4 +167,4 @@ class RowStates {
|
|
|
170
167
|
}
|
|
171
168
|
}
|
|
172
169
|
exports.RowStates = RowStates;
|
|
173
|
-
const missingHeader = { kind: "header", id: "header", data:
|
|
170
|
+
const missingHeader = { kind: "header", id: "header", data: "MISSING" };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Kinded } from "../../..";
|
|
1
2
|
import { RowStates } from "./RowStates";
|
|
2
3
|
/**
|
|
3
4
|
* Manages loading/saving our currently-collapsed rows to session storage.
|
|
@@ -10,10 +11,10 @@ import { RowStates } from "./RowStates";
|
|
|
10
11
|
* Unlike most of our other states, this is not directly reactive/an observable,
|
|
11
12
|
* although we do reactive to collapsedRows changing to persist the new state.
|
|
12
13
|
*/
|
|
13
|
-
export declare class RowStorage {
|
|
14
|
+
export declare class RowStorage<R extends Kinded> {
|
|
14
15
|
private states;
|
|
15
16
|
private historicalIds;
|
|
16
|
-
constructor(states: RowStates);
|
|
17
|
+
constructor(states: RowStates<R>);
|
|
17
18
|
load(persistCollapse: string): void;
|
|
18
19
|
/** Once the first real-data load is done, we ignore historical ids so that we prefer any new data's `initCollapsed`. */
|
|
19
20
|
done(): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { Kinded, OnRowSelect } from "../..";
|
|
2
3
|
import { GridDataRow } from "../components/Row";
|
|
3
4
|
import { GridSortConfig } from "../GridTable";
|
|
4
5
|
import { GridTableApi } from "../GridTableApi";
|
|
@@ -20,11 +21,11 @@ export type SelectedState = "checked" | "unchecked" | "partial";
|
|
|
20
21
|
* that need to change their toggle/select on/off in response to parent/child
|
|
21
22
|
* changes.
|
|
22
23
|
*/
|
|
23
|
-
export declare class TableState {
|
|
24
|
+
export declare class TableState<R extends Kinded> {
|
|
24
25
|
private persistCollapse;
|
|
25
26
|
private rows;
|
|
26
|
-
columns: GridColumnWithId<
|
|
27
|
-
readonly api: GridTableApi<
|
|
27
|
+
columns: GridColumnWithId<R>[];
|
|
28
|
+
readonly api: GridTableApi<R>;
|
|
28
29
|
private readonly rowStates;
|
|
29
30
|
private readonly columnStates;
|
|
30
31
|
activeRowId: string | undefined;
|
|
@@ -35,22 +36,23 @@ export declare class TableState {
|
|
|
35
36
|
sort: SortState;
|
|
36
37
|
private initialSortState;
|
|
37
38
|
private onSort;
|
|
39
|
+
onRowSelect: OnRowSelect<any> | undefined;
|
|
38
40
|
/**
|
|
39
41
|
* Creates the `RowState` for a given `GridTable`.
|
|
40
42
|
*/
|
|
41
43
|
constructor(api: GridTableApi<any>);
|
|
42
44
|
loadCollapse(persistCollapse: string): void;
|
|
43
|
-
initSortState(sortConfig: GridSortConfig | undefined, columns: GridColumnWithId<
|
|
45
|
+
initSortState(sortConfig: GridSortConfig | undefined, columns: GridColumnWithId<R>[]): void;
|
|
44
46
|
setSortKey(clickedColumnId: string): void;
|
|
45
47
|
get sortState(): SortState | undefined;
|
|
46
48
|
/** Returns a client-side sort function, if applicable. */
|
|
47
|
-
get sortFn(): ((a: RowState
|
|
48
|
-
setRows(rows: GridDataRow<
|
|
49
|
-
setColumns(columns: GridColumnWithId<
|
|
49
|
+
get sortFn(): ((a: RowState<R>, b: RowState<R>) => number) | undefined;
|
|
50
|
+
setRows(rows: GridDataRow<R>[]): void;
|
|
51
|
+
setColumns(columns: GridColumnWithId<R>[], visibleColumnsStorageKey: string | undefined): void;
|
|
50
52
|
setSearch(search: string | undefined): void;
|
|
51
|
-
get visibleRows(): RowState[];
|
|
53
|
+
get visibleRows(): RowState<R>[];
|
|
52
54
|
/** Returns visible columns, i.e. those that are visible + any expanded children. */
|
|
53
|
-
get visibleColumns(): GridColumnWithId<
|
|
55
|
+
get visibleColumns(): GridColumnWithId<R>[];
|
|
54
56
|
/** Implements GridTableApi.visibleColumnIds. */
|
|
55
57
|
get visibleColumnIds(): string[];
|
|
56
58
|
setVisibleColumns(ids: string[]): void;
|
|
@@ -59,12 +61,15 @@ export declare class TableState {
|
|
|
59
61
|
toggleExpandedColumn(columnId: string): void;
|
|
60
62
|
numberOfExpandedChildren(columnId: string): number;
|
|
61
63
|
loadExpandedColumns(columnId: string): Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Returns selected data rows (non-header, non-totals, etc.), ignoring rows that
|
|
66
|
+
* have `row.selectable !== false`.
|
|
67
|
+
*/
|
|
68
|
+
get selectedRows(): GridDataRow<R>[];
|
|
64
69
|
/** Returns kept group row, with the latest kept children, if any. */
|
|
65
|
-
get keptRowGroup(): GridDataRow<
|
|
70
|
+
get keptRowGroup(): GridDataRow<R>;
|
|
66
71
|
/** Returns kept rows, i.e. those that were user-selected but then client-side or server-side filtered. */
|
|
67
|
-
get keptRows(): GridDataRow<
|
|
72
|
+
get keptRows(): GridDataRow<R>[];
|
|
68
73
|
getSelected(id: string): SelectedState;
|
|
69
74
|
selectRow(id: string, selected: boolean): void;
|
|
70
75
|
get collapsedIds(): string[];
|
|
@@ -74,7 +79,7 @@ export declare class TableState {
|
|
|
74
79
|
}
|
|
75
80
|
/** Provides a context for rows to access their table's `TableState`. */
|
|
76
81
|
export declare const TableStateContext: React.Context<{
|
|
77
|
-
tableState: TableState
|
|
82
|
+
tableState: TableState<any>;
|
|
78
83
|
}>;
|
|
79
84
|
export declare function deriveSortState(currentSortState: SortState, clickedKey: string, initialSortState: SortState | undefined): SortState | undefined;
|
|
80
85
|
type ColumnSort = {
|
|
@@ -45,6 +45,7 @@ class TableState {
|
|
|
45
45
|
// Tracks the active sort column(s), so GridTable or SortHeaders can reactively
|
|
46
46
|
// re-render (for GridTable, only if client-side sorting)
|
|
47
47
|
this.sort = {};
|
|
48
|
+
this.onRowSelect = undefined;
|
|
48
49
|
this.api = api;
|
|
49
50
|
// Make ourselves an observable so that mobx will do caching of .collapseIds so
|
|
50
51
|
// that it'll be a stable identity for GridTable to useMemo against.
|
|
@@ -129,10 +130,8 @@ class TableState {
|
|
|
129
130
|
}
|
|
130
131
|
// Updates the list of rows and regenerates the collapsedRows property if needed.
|
|
131
132
|
setRows(rows) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.rows = rows;
|
|
135
|
-
}
|
|
133
|
+
this.rowStates.setRows(rows);
|
|
134
|
+
this.rows = rows;
|
|
136
135
|
}
|
|
137
136
|
setColumns(columns, visibleColumnsStorageKey) {
|
|
138
137
|
if (columns !== this.columns) {
|
|
@@ -175,7 +174,10 @@ class TableState {
|
|
|
175
174
|
loadExpandedColumns(columnId) {
|
|
176
175
|
return this.columnStates.get(columnId).doExpand();
|
|
177
176
|
}
|
|
178
|
-
/**
|
|
177
|
+
/**
|
|
178
|
+
* Returns selected data rows (non-header, non-totals, etc.), ignoring rows that
|
|
179
|
+
* have `row.selectable !== false`.
|
|
180
|
+
*/
|
|
179
181
|
get selectedRows() {
|
|
180
182
|
return this.rowStates.allStates
|
|
181
183
|
.filter((rs) => rs.isSelected && !utils_1.reservedRowKinds.includes(rs.row.kind))
|
|
@@ -28,7 +28,7 @@ export declare function collapseColumn<T extends Kinded>(columnDef?: Partial<Gri
|
|
|
28
28
|
* Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
|
|
29
29
|
* Enforces only fixed-sized units (% and px)
|
|
30
30
|
*/
|
|
31
|
-
export declare function calcColumnSizes(columns: GridColumnWithId<
|
|
31
|
+
export declare function calcColumnSizes<R extends Kinded>(columns: GridColumnWithId<R>[], tableWidth: number | undefined, tableMinWidthPx: number | undefined, expandedColumnIds: string[]): string[];
|
|
32
32
|
/** Assign column ids if missing. */
|
|
33
33
|
export declare function assignDefaultColumnIds<T extends Kinded>(columns: GridColumn<T>[]): GridColumnWithId<T>[];
|
|
34
34
|
export declare const generateColumnId: (columnIndex: number) => string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { GridCellContent } from "../components/cell";
|
|
3
3
|
import { GridDataRow } from "../components/Row";
|
|
4
|
-
import {
|
|
4
|
+
import { GridRowApi } from "../GridTableApi";
|
|
5
5
|
import { GridStyle } from "../TableStyles";
|
|
6
6
|
import { GridCellAlignment, GridColumnWithId, Kinded, RenderAs } from "../types";
|
|
7
7
|
import { Properties } from "../../../Css";
|
|
@@ -9,7 +9,7 @@ import { Properties } from "../../../Css";
|
|
|
9
9
|
export declare function toContent(maybeContent: ReactNode | GridCellContent, isHeader: boolean, canSortColumn: boolean, isClientSideSorting: boolean, style: GridStyle, as: RenderAs, alignment: GridCellAlignment, column: GridColumnWithId<any>, isExpandableHeader: boolean, isExpandable: boolean, minStickyLeftOffset: number, isKeptSelectedRow: boolean): ReactNode;
|
|
10
10
|
export declare function isGridCellContent(content: ReactNode | GridCellContent): content is GridCellContent;
|
|
11
11
|
/** Return the content for a given column def applied to a given row. */
|
|
12
|
-
export declare function applyRowFn<R extends Kinded>(column: GridColumnWithId<R>, row: GridDataRow<R>, api:
|
|
12
|
+
export declare function applyRowFn<R extends Kinded>(column: GridColumnWithId<R>, row: GridDataRow<R>, api: GridRowApi<R>, level: number, expanded: boolean): ReactNode | GridCellContent;
|
|
13
13
|
export declare const ASC: "ASC";
|
|
14
14
|
export declare const DESC: "DESC";
|
|
15
15
|
export declare const emptyCell: GridCellContent;
|