@homebound/beam 2.208.1 → 2.209.1
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 +5 -0
- package/dist/components/Table/GridTable.js +48 -21
- package/dist/components/Table/GridTableApi.d.ts +4 -0
- package/dist/components/Table/GridTableApi.js +6 -0
- package/dist/components/Table/TableStyles.d.ts +4 -0
- package/dist/components/Table/TableStyles.js +11 -7
- package/dist/components/Table/components/EditColumnsButton.d.ts +3 -4
- package/dist/components/Table/components/EditColumnsButton.js +10 -9
- package/dist/components/Table/components/ExpandableHeader.d.ts +9 -0
- package/dist/components/Table/components/ExpandableHeader.js +25 -0
- package/dist/components/Table/components/Row.d.ts +1 -0
- package/dist/components/Table/components/Row.js +54 -18
- package/dist/components/Table/components/cell.d.ts +5 -2
- package/dist/components/Table/components/cell.js +6 -3
- package/dist/components/Table/index.d.ts +0 -1
- package/dist/components/Table/index.js +0 -1
- package/dist/components/Table/types.d.ts +9 -0
- package/dist/components/Table/types.js +2 -0
- package/dist/components/Table/utils/TableState.d.ts +10 -0
- package/dist/components/Table/utils/TableState.js +55 -7
- package/dist/components/Table/utils/columns.js +29 -5
- package/dist/components/Table/utils/simpleHelpers.d.ts +5 -0
- package/dist/components/Table/utils/simpleHelpers.js +2 -1
- package/dist/components/Table/utils/sortRows.d.ts +2 -2
- package/dist/components/Table/utils/sortRows.js +5 -3
- package/dist/components/Table/utils/utils.d.ts +12 -2
- package/dist/components/Table/utils/utils.js +21 -4
- package/package.json +1 -1
- package/dist/components/Table/hooks/useColumns.d.ts +0 -3
- package/dist/components/Table/hooks/useColumns.js +0 -33
|
@@ -104,6 +104,11 @@ export interface GridTableProps<R extends Kinded, X> {
|
|
|
104
104
|
* Expected format is `${row.kind}_${row.id}_${column.id}`.
|
|
105
105
|
*/
|
|
106
106
|
activeCellId?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Defines the session storage key for which columns are visible. If not provided, a default storage key will be used based on column order and/or `GridColumn.id`
|
|
109
|
+
* This is beneficial when looking at the same table, but of a different subject (i.e. Project A's PreCon Schedule vs Project A's Construction schedule)
|
|
110
|
+
*/
|
|
111
|
+
visibleColumnsStorageKey?: string;
|
|
107
112
|
}
|
|
108
113
|
/**
|
|
109
114
|
* Renders data in our table layout.
|
|
@@ -79,8 +79,8 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
79
79
|
*/
|
|
80
80
|
function GridTable(props) {
|
|
81
81
|
var _a, _b, _c;
|
|
82
|
-
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, setRowCount, persistCollapse, resizeTarget, activeRowId, activeCellId, } = props;
|
|
83
|
-
const
|
|
82
|
+
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, setRowCount, persistCollapse, resizeTarget, activeRowId, activeCellId, visibleColumnsStorageKey, } = props;
|
|
83
|
+
const columnsWithIds = (0, react_1.useMemo)(() => (0, columns_1.assignDefaultColumnIds)(_columns), [_columns]);
|
|
84
84
|
// We only use this in as=virtual mode, but keep this here for rowLookup to use
|
|
85
85
|
const virtuosoRef = (0, react_1.useRef)(null);
|
|
86
86
|
// Use this ref to watch for changes in the GridTable's container and resize columns accordingly.
|
|
@@ -95,6 +95,11 @@ function GridTable(props) {
|
|
|
95
95
|
}, [props.api]);
|
|
96
96
|
const style = (0, TableStyles_1.resolveStyles)(maybeStyle);
|
|
97
97
|
const { tableState } = api;
|
|
98
|
+
tableState.setRows(rows);
|
|
99
|
+
tableState.setColumns(columnsWithIds, visibleColumnsStorageKey);
|
|
100
|
+
const columns = (0, hooks_1.useComputed)(() => tableState.columns
|
|
101
|
+
.filter((c) => tableState.visibleColumnIds.includes(c.id))
|
|
102
|
+
.flatMap((c) => c.expandColumns && tableState.expandedColumnIds.includes(c.id) ? [c, ...c.expandColumns] : [c]), [tableState]);
|
|
98
103
|
// Initialize the sort state. This will only happen on the first render.
|
|
99
104
|
// Once the `TableState.sort` is defined, it will not re-initialize.
|
|
100
105
|
tableState.initSortState(props.sorting, columns);
|
|
@@ -102,7 +107,6 @@ function GridTable(props) {
|
|
|
102
107
|
const { sortConfig } = tableState;
|
|
103
108
|
return [sortConfig === null || sortConfig === void 0 ? void 0 : sortConfig.on, (sortConfig === null || sortConfig === void 0 ? void 0 : sortConfig.on) === "client" ? !!sortConfig.caseSensitive : false];
|
|
104
109
|
}, [tableState]);
|
|
105
|
-
tableState.setRows(rows);
|
|
106
110
|
(0, react_1.useEffect)(() => {
|
|
107
111
|
tableState.activeRowId = activeRowId;
|
|
108
112
|
}, [tableState, activeRowId]);
|
|
@@ -125,10 +129,21 @@ function GridTable(props) {
|
|
|
125
129
|
}
|
|
126
130
|
return rows;
|
|
127
131
|
}, [columns, rows, sortOn, sortState, caseSensitive]);
|
|
128
|
-
const hasTotalsRow = rows.some((row) => row.id === "totals");
|
|
129
132
|
// Flatten + component-ize the sorted rows.
|
|
130
|
-
let [headerRows, visibleDataRows, totalsRows, filteredRowIds] = (0, react_1.useMemo)(() => {
|
|
133
|
+
let [headerRows, visibleDataRows, totalsRows, expandableHeaderRows, filteredRowIds] = (0, react_1.useMemo)(() => {
|
|
131
134
|
function makeRowComponent(row, level) {
|
|
135
|
+
// We may have multiple rows that need to be sticky, if that is the case, then we need properly define the stickyOffset for each row.
|
|
136
|
+
// *TOTALS* will always be on top, so that can remain 0.
|
|
137
|
+
// *EXPANDABLE_HEADER Header* may need to include the height of the totals row in the offset
|
|
138
|
+
// *HEADER* may need to include both TOTALS and EXPANDABLE_HEADER in its offset.
|
|
139
|
+
// TODO: Create a single "table header" container that can hold multiple rows and use a single `position: sticky`. And we can get rid of this nonsense.
|
|
140
|
+
const maybeTotalsRowHeight = hasTotalsRow ? TableStyles_1.totalsRowHeight : 0;
|
|
141
|
+
const maybeExpandableRowsHeight = hasExpandableHeader ? TableStyles_1.expandableHeaderRowHeight : 0;
|
|
142
|
+
const rowStickyOffset = row.kind === utils_1.HEADER
|
|
143
|
+
? maybeTotalsRowHeight + maybeExpandableRowsHeight
|
|
144
|
+
: row.kind === utils_1.EXPANDABLE_HEADER
|
|
145
|
+
? maybeTotalsRowHeight
|
|
146
|
+
: 0;
|
|
132
147
|
return ((0, jsx_runtime_1.jsx)(Row_1.Row, Object.assign({}, {
|
|
133
148
|
as,
|
|
134
149
|
columns,
|
|
@@ -136,8 +151,7 @@ function GridTable(props) {
|
|
|
136
151
|
style,
|
|
137
152
|
rowStyles,
|
|
138
153
|
stickyHeader,
|
|
139
|
-
|
|
140
|
-
stickyOffset: hasTotalsRow && row.kind === "header" ? 52 + stickyOffset : stickyOffset,
|
|
154
|
+
stickyOffset: rowStickyOffset + stickyOffset,
|
|
141
155
|
columnSizes,
|
|
142
156
|
level,
|
|
143
157
|
getCount,
|
|
@@ -145,13 +159,17 @@ function GridTable(props) {
|
|
|
145
159
|
cellHighlight: "cellHighlight" in maybeStyle && maybeStyle.cellHighlight === true,
|
|
146
160
|
omitRowHover: "rowHover" in maybeStyle && maybeStyle.rowHover === false,
|
|
147
161
|
sortOn,
|
|
162
|
+
hasExpandableHeader,
|
|
148
163
|
}), `${row.kind}-${row.id}`));
|
|
149
164
|
}
|
|
150
165
|
// Split out the header rows from the data rows so that we can put an `infoMessage` in between them (if needed).
|
|
151
166
|
const headerRows = [];
|
|
167
|
+
const expandableHeaderRows = [];
|
|
152
168
|
const totalsRows = [];
|
|
153
169
|
const visibleDataRows = [];
|
|
154
170
|
const filteredRowIds = [];
|
|
171
|
+
const hasTotalsRow = rows.some((row) => row.id === utils_1.TOTALS);
|
|
172
|
+
const hasExpandableHeader = rows.some((row) => row.id === utils_1.EXPANDABLE_HEADER);
|
|
155
173
|
function visit([row, children], level, visible) {
|
|
156
174
|
visible && visibleDataRows.push([row, makeRowComponent(row, level)]);
|
|
157
175
|
// This row may be invisible (because it's parent is collapsed), but we still want
|
|
@@ -173,13 +191,17 @@ function GridTable(props) {
|
|
|
173
191
|
totalsRows.push([row[0], makeRowComponent(row[0], level)]);
|
|
174
192
|
return;
|
|
175
193
|
}
|
|
194
|
+
if (row[0].kind === "expandableHeader") {
|
|
195
|
+
expandableHeaderRows.push([row[0], makeRowComponent(row[0], level)]);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
176
198
|
visit(row, level, visible);
|
|
177
199
|
});
|
|
178
200
|
}
|
|
179
201
|
// Call `visitRows` with our a pre-filtered set list
|
|
180
202
|
const filteredRows = filterRows(api, columns, maybeSorted, filter);
|
|
181
203
|
visitRows(filteredRows, 0, true);
|
|
182
|
-
return [headerRows, visibleDataRows, totalsRows, filteredRowIds];
|
|
204
|
+
return [headerRows, visibleDataRows, totalsRows, expandableHeaderRows, filteredRowIds];
|
|
183
205
|
}, [
|
|
184
206
|
as,
|
|
185
207
|
api,
|
|
@@ -194,7 +216,6 @@ function GridTable(props) {
|
|
|
194
216
|
columnSizes,
|
|
195
217
|
collapsedIds,
|
|
196
218
|
getCount,
|
|
197
|
-
hasTotalsRow,
|
|
198
219
|
]);
|
|
199
220
|
let tooManyClientSideRows = false;
|
|
200
221
|
if (filterMaxRows && visibleDataRows.length > filterMaxRows) {
|
|
@@ -230,7 +251,7 @@ function GridTable(props) {
|
|
|
230
251
|
// behave semantically the same as `as=div` did for its tests.
|
|
231
252
|
const _as = as === "virtual" && runningInJest ? "div" : as;
|
|
232
253
|
const rowStateContext = (0, react_1.useMemo)(() => ({ tableState: tableState }), [tableState]);
|
|
233
|
-
return ((0, jsx_runtime_1.jsx)(TableState_1.TableStateContext.Provider, Object.assign({ value: rowStateContext }, { children: (0, jsx_runtime_1.jsxs)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_c = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _c === void 0 ? void 0 : _c.wrap }, { children: [(0, jsx_runtime_1.jsx)("div", { ref: resizeRef, css: Css_1.Css.w100.if(as === "virtual").w("calc(100% - 20px)").$ }, void 0), renders[_as](style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, stickyHeader, xss, virtuosoRef)] }), void 0) }), void 0));
|
|
254
|
+
return ((0, jsx_runtime_1.jsx)(TableState_1.TableStateContext.Provider, Object.assign({ value: rowStateContext }, { children: (0, jsx_runtime_1.jsxs)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_c = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _c === void 0 ? void 0 : _c.wrap }, { children: [(0, jsx_runtime_1.jsx)("div", { ref: resizeRef, css: Css_1.Css.w100.if(as === "virtual").w("calc(100% - 20px)").$ }, void 0), renders[_as](style, id, columns, headerRows, totalsRows, expandableHeaderRows, visibleDataRows, firstRowMessage, stickyHeader, xss, virtuosoRef)] }), void 0) }), void 0));
|
|
234
255
|
}
|
|
235
256
|
exports.GridTable = GridTable;
|
|
236
257
|
// Determine which HTML element to use to build the GridTable
|
|
@@ -240,7 +261,7 @@ const renders = {
|
|
|
240
261
|
virtual: renderVirtual,
|
|
241
262
|
};
|
|
242
263
|
/** Renders table using divs with flexbox rows, which is the default render */
|
|
243
|
-
function renderDiv(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, _stickyHeader, xss, _virtuosoRef) {
|
|
264
|
+
function renderDiv(style, id, columns, headerRows, totalsRows, expandableHeaderRows, visibleDataRows, firstRowMessage, _stickyHeader, xss, _virtuosoRef) {
|
|
244
265
|
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
245
266
|
// Use `fit-content` to ensure the width of the table takes up the full width of its content.
|
|
246
267
|
// Otherwise, the table's width would be that of its container, which may not be as wide as the table itself.
|
|
@@ -261,10 +282,10 @@ function renderDiv(style, id, columns, headerRows, totalsRows, visibleDataRows,
|
|
|
261
282
|
...style.rootCss,
|
|
262
283
|
...(style.minWidthPx ? Css_1.Css.mwPx(style.minWidthPx).$ : {}),
|
|
263
284
|
...xss,
|
|
264
|
-
}, "data-testid": id }, { children: [totalsRows.map(([, node]) => node), headerRows.map(([, node]) => node), firstRowMessage && ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...style.firstRowMessageCss }, "data-gridrow": true }, { children: firstRowMessage }), void 0)), visibleDataRows.map(([, node]) => node)] }), void 0));
|
|
285
|
+
}, "data-testid": id }, { children: [totalsRows.map(([, node]) => node), expandableHeaderRows.map(([, node]) => node), headerRows.map(([, node]) => node), firstRowMessage && ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...style.firstRowMessageCss }, "data-gridrow": true }, { children: firstRowMessage }), void 0)), visibleDataRows.map(([, node]) => node)] }), void 0));
|
|
265
286
|
}
|
|
266
287
|
/** Renders as a table, primarily/solely for good print support. */
|
|
267
|
-
function renderTable(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, _stickyHeader, xss, _virtuosoRef) {
|
|
288
|
+
function renderTable(style, id, columns, headerRows, totalsRows, expandableHeaderRows, visibleDataRows, firstRowMessage, _stickyHeader, xss, _virtuosoRef) {
|
|
268
289
|
return ((0, jsx_runtime_1.jsxs)("table", Object.assign({ css: {
|
|
269
290
|
...Css_1.Css.w100.add("borderCollapse", "separate").add("borderSpacing", "0").$,
|
|
270
291
|
...Css_1.Css.addIn("& > tbody > tr > * ", style.betweenRowsCss || {})
|
|
@@ -275,7 +296,7 @@ function renderTable(style, id, columns, headerRows, totalsRows, visibleDataRows
|
|
|
275
296
|
...style.rootCss,
|
|
276
297
|
...(style.minWidthPx ? Css_1.Css.mwPx(style.minWidthPx).$ : {}),
|
|
277
298
|
...xss,
|
|
278
|
-
}, "data-testid": id }, { children: [(0, jsx_runtime_1.jsx)("thead", { children: [...totalsRows, ...headerRows].map(([, node]) => node) }, void 0), (0, jsx_runtime_1.jsxs)("tbody", { children: [firstRowMessage && ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", Object.assign({ colSpan: columns.length, css: { ...style.firstRowMessageCss } }, { children: firstRowMessage }), void 0) }, void 0)), visibleDataRows.map(([, node]) => node)] }, void 0)] }), void 0));
|
|
299
|
+
}, "data-testid": id }, { children: [(0, jsx_runtime_1.jsx)("thead", { children: [...totalsRows, ...expandableHeaderRows, ...headerRows].map(([, node]) => node) }, void 0), (0, jsx_runtime_1.jsxs)("tbody", { children: [firstRowMessage && ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", Object.assign({ colSpan: columns.length, css: { ...style.firstRowMessageCss } }, { children: firstRowMessage }), void 0) }, void 0)), visibleDataRows.map(([, node]) => node)] }, void 0)] }), void 0));
|
|
279
300
|
}
|
|
280
301
|
/**
|
|
281
302
|
* Uses react-virtuoso to render rows virtually.
|
|
@@ -297,7 +318,7 @@ function renderTable(style, id, columns, headerRows, totalsRows, visibleDataRows
|
|
|
297
318
|
* [2]: https://github.com/tannerlinsley/react-virtual/issues/85
|
|
298
319
|
* [3]: https://github.com/tannerlinsley/react-virtual/issues/108
|
|
299
320
|
*/
|
|
300
|
-
function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, stickyHeader, xss, virtuosoRef) {
|
|
321
|
+
function renderVirtual(style, id, columns, headerRows, totalsRows, expandableHeaderRows, visibleDataRows, firstRowMessage, stickyHeader, xss, virtuosoRef) {
|
|
301
322
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
302
323
|
const { footerStyle, listStyle } = (0, react_1.useMemo)(() => {
|
|
303
324
|
var _a;
|
|
@@ -306,13 +327,14 @@ function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRo
|
|
|
306
327
|
}, [style]);
|
|
307
328
|
return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { overscan: 5, ref: virtuosoRef, components: {
|
|
308
329
|
// Applying a zIndex: 2 to ensure it stays on top of sticky columns
|
|
309
|
-
TopItemList: react_1.default.forwardRef((props, ref) => ((0, jsx_runtime_1.jsx)("div", Object.assign({}, props, { ref: ref, style: { ...props.style, ...{ zIndex:
|
|
330
|
+
TopItemList: react_1.default.forwardRef((props, ref) => ((0, jsx_runtime_1.jsx)("div", Object.assign({}, props, { ref: ref, style: { ...props.style, ...{ zIndex: utils_1.zIndices.stickyHeader } } }), void 0))),
|
|
310
331
|
List: VirtualRoot(listStyle, columns, id, xss),
|
|
311
332
|
Footer: () => (0, jsx_runtime_1.jsx)("div", { css: footerStyle }, void 0),
|
|
312
333
|
},
|
|
313
334
|
// Pin/sticky both the header row(s) + firstRowMessage to the top
|
|
314
|
-
topItemCount: (stickyHeader ? headerRows.length + totalsRows.length
|
|
315
|
-
|
|
335
|
+
topItemCount: (stickyHeader ? headerRows.length + totalsRows.length + expandableHeaderRows.length : 0) +
|
|
336
|
+
(firstRowMessage ? 1 : 0), itemContent: (index) => {
|
|
337
|
+
// Since we have 4 arrays of rows: `headerRows`, `totalsRows`, `expandableHeaderRows`, and `filteredRow` we
|
|
316
338
|
// must determine which one to render.
|
|
317
339
|
// Determine if we need to render a totals row
|
|
318
340
|
if (index < totalsRows.length) {
|
|
@@ -320,6 +342,12 @@ function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRo
|
|
|
320
342
|
}
|
|
321
343
|
// Reset index
|
|
322
344
|
index -= totalsRows.length;
|
|
345
|
+
// Determine if we need to render an expandableHeaderRows row
|
|
346
|
+
if (index < expandableHeaderRows.length) {
|
|
347
|
+
return expandableHeaderRows[index][1];
|
|
348
|
+
}
|
|
349
|
+
// Reset index
|
|
350
|
+
index -= expandableHeaderRows.length;
|
|
323
351
|
// Determine if we need to render a header row
|
|
324
352
|
if (index < headerRows.length) {
|
|
325
353
|
return headerRows[index][1];
|
|
@@ -392,10 +420,9 @@ function filterRows(api, columns, rows, filter) {
|
|
|
392
420
|
var _a, _b, _c, _d;
|
|
393
421
|
// Break up "foo bar" into `[foo, bar]` and a row must match both `foo` and `bar`
|
|
394
422
|
const filters = (filter && filter.split(/ +/)) || [];
|
|
395
|
-
const matches = row.kind
|
|
396
|
-
row.kind === "totals" ||
|
|
423
|
+
const matches = utils_1.reservedRowKinds.includes(row.kind) ||
|
|
397
424
|
filters.length === 0 ||
|
|
398
|
-
filters.every((f) => columns.map((c) => (0, utils_1.applyRowFn)(c, row, api, 0)).some((maybeContent) => (0, utils_1.matchesFilter)(maybeContent, f)));
|
|
425
|
+
filters.every((f) => columns.map((c) => (0, utils_1.applyRowFn)(c, row, api, 0, false)).some((maybeContent) => (0, utils_1.matchesFilter)(maybeContent, f)));
|
|
399
426
|
if (matches) {
|
|
400
427
|
return acc.concat([[row, (_b = (_a = row.children) === null || _a === void 0 ? void 0 : _a.reduce(acceptAll, [])) !== null && _b !== void 0 ? _b : []]]);
|
|
401
428
|
}
|
|
@@ -39,6 +39,8 @@ export declare type GridTableApi<R extends Kinded> = {
|
|
|
39
39
|
selectRow: (id: string, selected?: boolean) => void;
|
|
40
40
|
/** Toggle collapse state of a row by id */
|
|
41
41
|
toggleCollapsedRow: (id: string) => void;
|
|
42
|
+
setVisibleColumns: (ids: string[]) => void;
|
|
43
|
+
getVisibleColumnIds: () => string[];
|
|
42
44
|
};
|
|
43
45
|
export declare class GridTableApiImpl<R extends Kinded> implements GridTableApi<R> {
|
|
44
46
|
readonly tableState: TableState;
|
|
@@ -53,4 +55,6 @@ export declare class GridTableApiImpl<R extends Kinded> implements GridTableApi<
|
|
|
53
55
|
setActiveCellId(id: string | undefined): void;
|
|
54
56
|
selectRow(id: string, selected?: boolean): void;
|
|
55
57
|
toggleCollapsedRow(id: string): void;
|
|
58
|
+
setVisibleColumns(ids: string[]): void;
|
|
59
|
+
getVisibleColumnIds(): string[];
|
|
56
60
|
}
|
|
@@ -68,5 +68,11 @@ class GridTableApiImpl {
|
|
|
68
68
|
toggleCollapsedRow(id) {
|
|
69
69
|
this.tableState.toggleCollapsed(id);
|
|
70
70
|
}
|
|
71
|
+
setVisibleColumns(ids) {
|
|
72
|
+
this.tableState.setVisibleColumns(ids);
|
|
73
|
+
}
|
|
74
|
+
getVisibleColumnIds() {
|
|
75
|
+
return this.tableState.visibleColumnIds;
|
|
76
|
+
}
|
|
71
77
|
}
|
|
72
78
|
exports.GridTableApiImpl = GridTableApiImpl;
|
|
@@ -28,6 +28,8 @@ export interface GridStyle {
|
|
|
28
28
|
headerCellCss?: Properties;
|
|
29
29
|
/** Applied to 'kind: "totals"' cells */
|
|
30
30
|
totalsCellCss?: Properties;
|
|
31
|
+
/** Applied to 'kind: "expandableHeader"' cells */
|
|
32
|
+
expandableHeaderCss?: Properties;
|
|
31
33
|
/** Applied to the first cell of all rows, i.e. for table-wide padding or left-side borders. */
|
|
32
34
|
firstCellCss?: Properties;
|
|
33
35
|
/** Applied to the last cell of all rows, i.e. for table-wide padding or right-side borders. */
|
|
@@ -64,6 +66,8 @@ export interface GridStyleDef {
|
|
|
64
66
|
rowHover?: boolean;
|
|
65
67
|
}
|
|
66
68
|
export declare const getTableStyles: (props?: GridStyleDef) => GridStyle;
|
|
69
|
+
export declare const totalsRowHeight = 52;
|
|
70
|
+
export declare const expandableHeaderRowHeight = 40;
|
|
67
71
|
/** Defines row-specific styling for each given row `kind` in `R` */
|
|
68
72
|
export declare type RowStyles<R extends Kinded> = {
|
|
69
73
|
[P in R["kind"]]?: RowStyle<DiscriminateUnion<R, "kind", P>>;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveStyles = exports.tableRowStyles = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = exports.getTableStyles = void 0;
|
|
3
|
+
exports.resolveStyles = exports.tableRowStyles = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = exports.expandableHeaderRowHeight = exports.totalsRowHeight = exports.getTableStyles = void 0;
|
|
4
4
|
const Css_1 = require("../../Css");
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
6
|
// Returns a "blessed" style of GridTable
|
|
7
7
|
function memoizedTableStyles() {
|
|
8
8
|
const cache = {};
|
|
9
9
|
return (props = {}) => {
|
|
10
|
-
const { inlineEditing = false, grouped = false, rowHeight = "flexible", cellHighlight = false, allWhite = false, bordered = false,
|
|
10
|
+
const { inlineEditing = false, grouped = false, rowHeight = "flexible", cellHighlight = false, allWhite = false, bordered = false, } = props;
|
|
11
11
|
const key = (0, utils_1.safeKeys)(props)
|
|
12
12
|
.sort()
|
|
13
13
|
.map((k) => `${k}_${props[k]}`)
|
|
@@ -30,9 +30,13 @@ function memoizedTableStyles() {
|
|
|
30
30
|
headerCellCss: {
|
|
31
31
|
...Css_1.Css.gray700.xsMd.bgGray200.aic.nowrap.pxPx(12).hPx(40).$,
|
|
32
32
|
...(allWhite && Css_1.Css.bgWhite.$),
|
|
33
|
-
...(bordered && Css_1.Css.bt.bGray200.$),
|
|
34
33
|
},
|
|
35
|
-
totalsCellCss: Css_1.Css.bgWhite.gray700.smMd.hPx(
|
|
34
|
+
totalsCellCss: Css_1.Css.bgWhite.gray700.smMd.hPx(exports.totalsRowHeight).pPx(12).boxShadow("none").$,
|
|
35
|
+
expandableHeaderCss: Css_1.Css.bgWhite.gray900.xsMd.wsNormal
|
|
36
|
+
.hPx(exports.expandableHeaderRowHeight)
|
|
37
|
+
.pxPx(12)
|
|
38
|
+
.py0.boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`)
|
|
39
|
+
.addIn("&:not(:last-of-type)", Css_1.Css.boxShadow(`inset -1px -1px 0 ${Css_1.Palette.Gray200}`).$).$,
|
|
36
40
|
cellCss: {
|
|
37
41
|
...Css_1.Css.gray900.xs.bgWhite.aic.pxPx(12).boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$,
|
|
38
42
|
...(rowHeight === "flexible" ? Css_1.Css.pyPx(12).$ : Css_1.Css.nowrap.hPx(inlineEditing ? 48 : 36).$),
|
|
@@ -40,9 +44,7 @@ function memoizedTableStyles() {
|
|
|
40
44
|
...(bordered && { "&:first-of-type": Css_1.Css.bl.bGray200.$, "&:last-of-type": Css_1.Css.br.bGray200.$ }),
|
|
41
45
|
},
|
|
42
46
|
firstRowCss: {
|
|
43
|
-
|
|
44
|
-
...(allWhite &&
|
|
45
|
-
Css_1.Css.addIn("& > *:first-of-type", Css_1.Css.borderRadius("8px 0 0 0 ").$).addIn("& > *:last-of-type", Css_1.Css.borderRadius("0 8px 0 0").$).$),
|
|
47
|
+
...Css_1.Css.addIn("& > *:first-of-type", Css_1.Css.borderRadius("8px 0 0 0 ").$).addIn("& > *:last-of-type", Css_1.Css.borderRadius("0 8px 0 0").$).$,
|
|
46
48
|
...(bordered && Css_1.Css.addIn("& > *", Css_1.Css.bt.bGray200.$).$),
|
|
47
49
|
},
|
|
48
50
|
...(allWhite && {
|
|
@@ -57,6 +59,8 @@ function memoizedTableStyles() {
|
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
61
|
exports.getTableStyles = memoizedTableStyles();
|
|
62
|
+
exports.totalsRowHeight = 52;
|
|
63
|
+
exports.expandableHeaderRowHeight = 40;
|
|
60
64
|
/** Our original table look & feel/style. */
|
|
61
65
|
exports.defaultStyle = {
|
|
62
66
|
rootCss: Css_1.Css.gray700.$,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction } from "react";
|
|
2
1
|
import { OverlayTriggerProps } from "../../internal/OverlayTrigger";
|
|
2
|
+
import { GridTableApi } from "../GridTableApi";
|
|
3
3
|
import { GridColumn, Kinded } from "../types";
|
|
4
4
|
interface EditColumnsButtonProps<R extends Kinded> extends Pick<OverlayTriggerProps, "trigger" | "placement" | "disabled" | "tooltip"> {
|
|
5
|
-
|
|
6
|
-
selectedColumns: GridColumn<R>[];
|
|
7
|
-
setSelectedColumns: Dispatch<SetStateAction<GridColumn<R>[]>>;
|
|
5
|
+
columns: GridColumn<R>[];
|
|
8
6
|
title?: string;
|
|
7
|
+
api: GridTableApi<R>;
|
|
9
8
|
defaultOpen?: boolean;
|
|
10
9
|
}
|
|
11
10
|
export declare function EditColumnsButton<R extends Kinded>(props: EditColumnsButtonProps<R>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -8,31 +8,32 @@ const react_stately_1 = require("react-stately");
|
|
|
8
8
|
const Button_1 = require("../../Button");
|
|
9
9
|
const OverlayTrigger_1 = require("../../internal/OverlayTrigger");
|
|
10
10
|
const Css_1 = require("../../../Css");
|
|
11
|
+
const hooks_1 = require("../../../hooks");
|
|
11
12
|
const inputs_1 = require("../../../inputs");
|
|
12
13
|
const utils_1 = require("../../../utils");
|
|
13
14
|
function EditColumnsButton(props) {
|
|
14
|
-
const { defaultOpen, disabled,
|
|
15
|
+
const { defaultOpen, disabled, columns, trigger, title, api } = props;
|
|
15
16
|
const state = (0, react_stately_1.useMenuTriggerState)({ isOpen: defaultOpen });
|
|
16
17
|
const buttonRef = (0, react_1.useRef)(null);
|
|
17
18
|
const { menuTriggerProps } = (0, react_aria_1.useMenuTrigger)({ isDisabled: !!disabled }, state, buttonRef);
|
|
18
19
|
const tid = (0, utils_1.useTestIds)(props, (0, OverlayTrigger_1.isTextButton)(trigger) ? trigger.label : (0, OverlayTrigger_1.isIconButton)(trigger) ? trigger.icon : trigger.name);
|
|
19
20
|
const { options } = (0, react_1.useMemo)(() => {
|
|
20
|
-
return
|
|
21
|
+
return columns.reduce((acc, column) => {
|
|
21
22
|
// Only include options that can be hidden and have the `name` property defined.
|
|
22
23
|
if (!column.canHide)
|
|
23
24
|
return acc;
|
|
24
|
-
if (!column.id || column.id.length === 0) {
|
|
25
|
-
console.warn("Column is missing 'name' property required by the Edit Columns button", column);
|
|
25
|
+
if (!column.name || column.name.length === 0 || !column.id || column.id.length === 0) {
|
|
26
|
+
console.warn("Column is missing 'name' and/or 'id' property required by the Edit Columns button", column);
|
|
26
27
|
return acc;
|
|
27
28
|
}
|
|
28
29
|
// Add current column as an option
|
|
29
|
-
return { ...acc, options: acc.options.concat({ label: column.
|
|
30
|
+
return { ...acc, options: acc.options.concat({ label: column.name, value: column.id }) };
|
|
30
31
|
}, { options: [] });
|
|
31
|
-
}, [
|
|
32
|
-
const selectedValues =
|
|
32
|
+
}, [columns]);
|
|
33
|
+
const selectedValues = (0, hooks_1.useComputed)(() => api.getVisibleColumnIds(), [api]);
|
|
33
34
|
const setSelectedValues = (0, react_1.useCallback)((values) => {
|
|
34
|
-
|
|
35
|
-
}, [
|
|
35
|
+
api.setVisibleColumns(columns.filter((column) => (column.canHide ? values.includes(column.id) : true)).map((c) => c.id));
|
|
36
|
+
}, [columns, api]);
|
|
36
37
|
return ((0, jsx_runtime_1.jsx)(OverlayTrigger_1.OverlayTrigger, Object.assign({}, props, { menuTriggerProps: menuTriggerProps, state: state, buttonRef: buttonRef }, tid, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
37
38
|
...Css_1.Css.bgWhite.py5.px3.maxwPx(380).bshBasic.$,
|
|
38
39
|
"&:hover": Css_1.Css.bshHover.$,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GridColumnWithId, Kinded, RenderAs } from "../types";
|
|
2
|
+
interface ExpandableHeaderProps<R extends Kinded> {
|
|
3
|
+
title: string;
|
|
4
|
+
column: GridColumnWithId<R>;
|
|
5
|
+
minStickyLeftOffset: number;
|
|
6
|
+
as: RenderAs;
|
|
7
|
+
}
|
|
8
|
+
export declare function ExpandableHeader<R extends Kinded>(props: ExpandableHeaderProps<R>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExpandableHeader = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const Icon_1 = require("../../Icon");
|
|
7
|
+
const TableState_1 = require("../utils/TableState");
|
|
8
|
+
const utils_1 = require("../utils/utils");
|
|
9
|
+
const Css_1 = require("../../../Css");
|
|
10
|
+
const hooks_1 = require("../../../hooks");
|
|
11
|
+
function ExpandableHeader(props) {
|
|
12
|
+
const { title, column, minStickyLeftOffset, as } = props;
|
|
13
|
+
const { tableState } = (0, react_1.useContext)(TableState_1.TableStateContext);
|
|
14
|
+
const expandedColumnIds = (0, hooks_1.useComputed)(() => tableState.expandedColumnIds, [tableState]);
|
|
15
|
+
const isExpanded = expandedColumnIds.includes(column.id);
|
|
16
|
+
// Do not apply sticky styles when rendering as table. Currently the table does not properly respect column widths, causing the sticky offsets to be incorrect
|
|
17
|
+
const applyStickyStyles = isExpanded && as !== "table";
|
|
18
|
+
const { hoverProps, isHovered } = (0, hooks_1.useHover)({});
|
|
19
|
+
return ((0, jsx_runtime_1.jsxs)("button", Object.assign({}, hoverProps, { css: Css_1.Css.df.xsMd.aic.jcsb.gap2.px1.hPx(32).mxPx(-8).w("calc(100% + 16px)").br4.lightBlue700.if(isHovered).bgGray100.$, onClick: () => tableState.toggleExpandedColumn(column.id), "data-testid": "expandableColumn" }, { children: [(0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.tl.lineClamp2
|
|
20
|
+
.if(applyStickyStyles)
|
|
21
|
+
.sticky.leftPx(minStickyLeftOffset + 12)
|
|
22
|
+
.pr2.mr2.bgWhite.z(utils_1.zIndices.expandableHeaderTitle)
|
|
23
|
+
.if(isHovered).bgGray100.$ }, { children: title }), void 0), (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.if(applyStickyStyles).sticky.rightPx(12).z(utils_1.zIndices.expandableHeaderIcon).$ }, { children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: isExpanded ? "chevronLeft" : "chevronRight", inc: 2 }, void 0) }), void 0)] }), void 0));
|
|
24
|
+
}
|
|
25
|
+
exports.ExpandableHeader = ExpandableHeader;
|
|
@@ -33,17 +33,18 @@ const shallowEqual_1 = require("../../../utils/shallowEqual");
|
|
|
33
33
|
// We extract Row to its own mini-component primarily so we can React.memo'ize it.
|
|
34
34
|
function RowImpl(props) {
|
|
35
35
|
var _a;
|
|
36
|
-
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sortOn, columnSizes, level, getCount, api, cellHighlight, omitRowHover, ...others } = props;
|
|
36
|
+
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sortOn, columnSizes, level, getCount, api, cellHighlight, omitRowHover, hasExpandableHeader, ...others } = props;
|
|
37
37
|
const { tableState } = (0, react_1.useContext)(TableState_1.TableStateContext);
|
|
38
38
|
const rowId = `${row.kind}_${row.id}`;
|
|
39
39
|
const isActive = (0, hooks_1.useComputed)(() => tableState.activeRowId === rowId, [rowId, tableState]);
|
|
40
40
|
// We treat the "header" and "totals" kind as special for "good defaults" styling
|
|
41
|
-
const isHeader = row.kind ===
|
|
42
|
-
const isTotals = row.kind ===
|
|
41
|
+
const isHeader = row.kind === utils_1.HEADER;
|
|
42
|
+
const isTotals = row.kind === utils_1.TOTALS;
|
|
43
|
+
const isExpandableHeader = row.kind === utils_1.EXPANDABLE_HEADER;
|
|
43
44
|
const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
|
|
44
45
|
const RowTag = as === "table" ? "tr" : "div";
|
|
45
46
|
const revealOnRowHoverClass = "revealOnRowHover";
|
|
46
|
-
const showRowHoverColor =
|
|
47
|
+
const showRowHoverColor = !utils_1.reservedRowKinds.includes(row.kind) && !omitRowHover;
|
|
47
48
|
const rowStyleCellCss = (0, utils_1.maybeApplyFunction)(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.cellCss);
|
|
48
49
|
const rowCss = {
|
|
49
50
|
// Optionally include the row hover styles, by default they should be turned on.
|
|
@@ -57,16 +58,23 @@ function RowImpl(props) {
|
|
|
57
58
|
...(((rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowLink) || (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.onClick)) && { "&:hover": Css_1.Css.cursorPointer.$ }),
|
|
58
59
|
...(0, utils_1.maybeApplyFunction)(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowCss),
|
|
59
60
|
// Maybe add the sticky header styles
|
|
60
|
-
...((
|
|
61
|
+
...(utils_1.reservedRowKinds.includes(row.kind) && stickyHeader
|
|
62
|
+
? Css_1.Css.sticky.topPx(stickyOffset).z(utils_1.zIndices.stickyHeader).$
|
|
63
|
+
: undefined),
|
|
61
64
|
...{
|
|
62
65
|
[` > .${revealOnRowHoverClass} > *`]: Css_1.Css.invisible.$,
|
|
63
66
|
[`:hover > .${revealOnRowHoverClass} > *`]: Css_1.Css.visible.$,
|
|
64
67
|
},
|
|
65
68
|
};
|
|
66
69
|
let currentColspan = 1;
|
|
70
|
+
// Keep a running count of how many expanded columns are being shown.
|
|
71
|
+
let currentExpandedColumnCount = 0;
|
|
67
72
|
let firstContentColumnStylesApplied = false;
|
|
73
|
+
let minStickyLeftOffset = 0;
|
|
68
74
|
return ((0, jsx_runtime_1.jsx)(RowTag, Object.assign({ css: rowCss }, others, { "data-gridrow": true }, getCount(row.id), { children: columns.map((column, columnIndex) => {
|
|
69
|
-
var _a, _b, _c, _d, _e;
|
|
75
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
76
|
+
// Need to keep track of the expanded columns so we can add borders as expected for the header rows
|
|
77
|
+
const isExpanded = tableState.expandedColumnIds.includes(column.id);
|
|
70
78
|
const { wrapAction = true, isAction = false } = column;
|
|
71
79
|
const applyFirstContentColumnStyles = !isHeader && !isAction && !firstContentColumnStylesApplied;
|
|
72
80
|
firstContentColumnStylesApplied || (firstContentColumnStylesApplied = applyFirstContentColumnStyles);
|
|
@@ -76,24 +84,40 @@ function RowImpl(props) {
|
|
|
76
84
|
throw new Error("Beam Table column min-width definition only supports px or percentage values");
|
|
77
85
|
}
|
|
78
86
|
}
|
|
87
|
+
// When using the variation of the table with an EXPANDABLE_HEADER, then our HEADER row required special border styling
|
|
88
|
+
if (hasExpandableHeader && (isHeader || isTotals)) {
|
|
89
|
+
// When the value of `currentExpandedColumnCount` is 0, then we have started over.
|
|
90
|
+
// If the current column `isExpanded`, then store the number of expandable columns.
|
|
91
|
+
if (currentExpandedColumnCount === 0 && isExpanded) {
|
|
92
|
+
currentExpandedColumnCount = (_b = (_a = column.expandColumns) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
93
|
+
}
|
|
94
|
+
else if (currentExpandedColumnCount > 0) {
|
|
95
|
+
// If value is great than 0, then decrement. Once the value equals 0, then the special styling will be applied below.
|
|
96
|
+
currentExpandedColumnCount -= 1;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
79
99
|
// Decrement colspan count and skip if greater than 1.
|
|
80
100
|
if (currentColspan > 1) {
|
|
81
101
|
currentColspan -= 1;
|
|
82
102
|
return null;
|
|
83
103
|
}
|
|
84
|
-
const maybeContent = (0, utils_1.applyRowFn)(column, row, api, level);
|
|
85
|
-
|
|
104
|
+
const maybeContent = (0, utils_1.applyRowFn)(column, row, api, level, isExpanded);
|
|
105
|
+
const numExpandedColumns = isExpandableHeader && isExpanded ? (_d = (_c = column.expandColumns) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0 : 0;
|
|
106
|
+
currentColspan = (0, utils_1.isGridCellContent)(maybeContent)
|
|
107
|
+
? (_e = maybeContent.colspan) !== null && _e !== void 0 ? _e : numExpandedColumns + 1
|
|
108
|
+
: numExpandedColumns + 1;
|
|
86
109
|
const revealOnRowHover = (0, utils_1.isGridCellContent)(maybeContent) ? maybeContent.revealOnRowHover : false;
|
|
87
110
|
const canSortColumn = (sortOn === "client" && column.clientSideSort !== false) ||
|
|
88
111
|
(sortOn === "server" && !!column.serverSideSortKey);
|
|
89
112
|
const alignment = (0, utils_1.getAlignment)(column, maybeContent);
|
|
90
113
|
const justificationCss = (0, utils_1.getJustification)(column, maybeContent, as, alignment);
|
|
91
|
-
const
|
|
92
|
-
(0,
|
|
93
|
-
|
|
114
|
+
const isExpandable = column.expandColumns !== undefined && column.expandColumns.length > 0;
|
|
115
|
+
const content = (0, utils_1.toContent)(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment, column, isExpandableHeader, isExpandable, minStickyLeftOffset);
|
|
116
|
+
(0, sortRows_1.ensureClientSideSortValueIsSortable)(sortOn, isHeader || isTotals || isExpandableHeader, column, columnIndex, maybeContent);
|
|
117
|
+
const maybeSticky = (_f = (((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.sticky) || column.sticky)) !== null && _f !== void 0 ? _f : undefined;
|
|
94
118
|
const maybeStickyColumnStyles = maybeSticky && columnSizes
|
|
95
119
|
? {
|
|
96
|
-
...Css_1.Css.sticky.
|
|
120
|
+
...Css_1.Css.sticky.z(utils_1.zIndices.stickyColumns).bgWhite.$,
|
|
97
121
|
...(maybeSticky === "left"
|
|
98
122
|
? Css_1.Css.left(columnIndex === 0 ? 0 : `calc(${columnSizes.slice(0, columnIndex).join(" + ")})`).$
|
|
99
123
|
: {}),
|
|
@@ -104,6 +128,8 @@ function RowImpl(props) {
|
|
|
104
128
|
: {}),
|
|
105
129
|
}
|
|
106
130
|
: {};
|
|
131
|
+
// This relies on our column sizes being defined in pixel values, which is currently true as we calculate to pixel values in the `useSetupColumnSizes` hook
|
|
132
|
+
minStickyLeftOffset += maybeSticky === "left" ? parseInt(columnSizes[columnIndex].replace("px", ""), 10) : 0;
|
|
107
133
|
const cellId = `${row.kind}_${row.id}_${column.id}`;
|
|
108
134
|
const applyCellHighlight = cellHighlight && !!column.id && !isHeader && !isTotals;
|
|
109
135
|
const isCellActive = tableState.activeCellId === cellId;
|
|
@@ -132,14 +158,22 @@ function RowImpl(props) {
|
|
|
132
158
|
...(isHeader && style.headerCellCss),
|
|
133
159
|
// Then apply any totals-specific override
|
|
134
160
|
...(isTotals && style.totalsCellCss),
|
|
161
|
+
...(isTotals && hasExpandableHeader && Css_1.Css.boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$),
|
|
162
|
+
// Then apply any expandable header specific override
|
|
163
|
+
...(isExpandableHeader && style.expandableHeaderCss),
|
|
164
|
+
// Apply the right border styling for the header row when using expandable tables and this column is the last expandable column, or not expanded.
|
|
165
|
+
...(hasExpandableHeader &&
|
|
166
|
+
(isHeader || isTotals) &&
|
|
167
|
+
currentExpandedColumnCount === 0 &&
|
|
168
|
+
Css_1.Css.boxShadow(`inset -1px -1px 0 ${Css_1.Palette.Gray200}`).$),
|
|
135
169
|
// Or level-specific styling
|
|
136
|
-
...(!isHeader && !isTotals && !!style.levels && ((
|
|
170
|
+
...(!isHeader && !isTotals && !isExpandableHeader && !!style.levels && ((_g = style.levels[level]) === null || _g === void 0 ? void 0 : _g.cellCss)),
|
|
137
171
|
// Level specific styling for the first content column
|
|
138
|
-
...(applyFirstContentColumnStyles && !!style.levels && ((
|
|
172
|
+
...(applyFirstContentColumnStyles && !!style.levels && ((_h = style.levels[level]) === null || _h === void 0 ? void 0 : _h.firstContentColumn)),
|
|
139
173
|
// The specific cell's css (if any from GridCellContent)
|
|
140
174
|
...rowStyleCellCss,
|
|
141
175
|
// Apply active row styling for non-nested card styles.
|
|
142
|
-
...(isActive ? Css_1.Css.bgColor((
|
|
176
|
+
...(isActive ? Css_1.Css.bgColor((_j = style.activeBgColor) !== null && _j !== void 0 ? _j : Css_1.Palette.LightBlue50).$ : {}),
|
|
143
177
|
// Add any cell specific style overrides
|
|
144
178
|
...((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.typeScale ? Css_1.Css[maybeContent.typeScale].$ : {}),
|
|
145
179
|
// And any cell specific css
|
|
@@ -148,14 +182,16 @@ function RowImpl(props) {
|
|
|
148
182
|
...Css_1.Css.if(applyCellHighlight && isCellActive).br4.boxShadow(`inset 0 0 0 1px ${Css_1.Palette.LightBlue700}`).$,
|
|
149
183
|
// Define the width of the column on each cell. Supports col spans.
|
|
150
184
|
width: `calc(${columnSizes.slice(columnIndex, columnIndex + currentColspan).join(" + ")})`,
|
|
151
|
-
...(column.mw ? Css_1.Css.mw(column.mw).$ : {}),
|
|
185
|
+
...(typeof column.mw === "string" ? Css_1.Css.mw(column.mw).$ : {}),
|
|
152
186
|
};
|
|
153
187
|
const cellClassNames = revealOnRowHover ? revealOnRowHoverClass : undefined;
|
|
154
188
|
const cellOnClick = applyCellHighlight ? () => api.setActiveCellId(cellId) : undefined;
|
|
189
|
+
// If the expandable header is expanded, then we need to set a colspan on it which includes all expanded columns + this column.
|
|
190
|
+
const expandableHeaderColSpan = (isExpandableHeader && isExpanded ? (_l = (_k = column.expandColumns) === null || _k === void 0 ? void 0 : _k.length) !== null && _l !== void 0 ? _l : 0 : 0) + 1;
|
|
155
191
|
const renderFn = ((rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.renderCell) || (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowLink)) && wrapAction
|
|
156
192
|
? (0, cell_1.rowLinkRenderFn)(as)
|
|
157
|
-
: isHeader
|
|
158
|
-
? (0, cell_1.headerRenderFn)(column, as)
|
|
193
|
+
: isHeader || isTotals || isExpandableHeader
|
|
194
|
+
? (0, cell_1.headerRenderFn)(column, as, expandableHeaderColSpan)
|
|
159
195
|
: (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.onClick) && wrapAction
|
|
160
196
|
? (0, cell_1.rowClickRenderFn)(as, api)
|
|
161
197
|
: (0, cell_1.defaultRenderFn)(as);
|
|
@@ -32,8 +32,11 @@ export declare type GridCellContent = {
|
|
|
32
32
|
export declare type RenderCellFn<R extends Kinded> = (idx: number, css: Properties, content: ReactNode, row: R, rowStyle: RowStyle<R> | undefined, classNames: string | undefined, onClick: (() => void) | undefined) => ReactNode;
|
|
33
33
|
/** Renders our default cell element, i.e. if no row links and no custom renderCell are used. */
|
|
34
34
|
export declare const defaultRenderFn: (as: RenderAs) => RenderCellFn<any>;
|
|
35
|
-
/**
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Sets up the `GridContext` so that header cells can access the current sort settings.
|
|
37
|
+
* Used for the Header, Totals, and Expanded Header row's cells.
|
|
38
|
+
* */
|
|
39
|
+
export declare const headerRenderFn: (column: GridColumnWithId<any>, as: RenderAs, colSpan: number) => RenderCellFn<any>;
|
|
37
40
|
/** Renders a cell element when a row link is in play. */
|
|
38
41
|
export declare const rowLinkRenderFn: (as: RenderAs) => RenderCellFn<any>;
|
|
39
42
|
/** Renders a cell that will fire the RowStyle.onClick. */
|
|
@@ -12,10 +12,13 @@ const defaultRenderFn = (as) => (key, css, content, row, rowStyle, classNames, o
|
|
|
12
12
|
return ((0, jsx_runtime_1.jsx)(Cell, Object.assign({ css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as) }, className: classNames, onClick: onClick }, { children: content }), key));
|
|
13
13
|
};
|
|
14
14
|
exports.defaultRenderFn = defaultRenderFn;
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Sets up the `GridContext` so that header cells can access the current sort settings.
|
|
17
|
+
* Used for the Header, Totals, and Expanded Header row's cells.
|
|
18
|
+
* */
|
|
19
|
+
const headerRenderFn = (column, as, colSpan) => (key, css, content, row, rowStyle, classNames) => {
|
|
17
20
|
const Cell = as === "table" ? "th" : "div";
|
|
18
|
-
return ((0, jsx_runtime_1.jsx)(Cell, Object.assign({ css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as, column) }, className: classNames }, { children: content }), key));
|
|
21
|
+
return ((0, jsx_runtime_1.jsx)(Cell, Object.assign({ css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as, column) }, className: classNames }, (as === "table" && { colSpan }), { children: content }), key));
|
|
19
22
|
};
|
|
20
23
|
exports.headerRenderFn = headerRenderFn;
|
|
21
24
|
/** Renders a cell element when a row link is in play. */
|
|
@@ -9,7 +9,6 @@ export * from "./components/SortHeader";
|
|
|
9
9
|
export { SortHeader } from "./components/SortHeader";
|
|
10
10
|
export { useGridTableApi } from "./GridTableApi";
|
|
11
11
|
export type { GridTableApi } from "./GridTableApi";
|
|
12
|
-
export * from "./hooks/useColumns";
|
|
13
12
|
export * from "./hooks/useSetupColumnSizes";
|
|
14
13
|
export { cardStyle, condensedStyle, defaultStyle, getTableStyles } from "./TableStyles";
|
|
15
14
|
export type { GridStyle, RowStyle, RowStyles } from "./TableStyles";
|
|
@@ -27,7 +27,6 @@ var SortHeader_1 = require("./components/SortHeader");
|
|
|
27
27
|
Object.defineProperty(exports, "SortHeader", { enumerable: true, get: function () { return SortHeader_1.SortHeader; } });
|
|
28
28
|
var GridTableApi_1 = require("./GridTableApi");
|
|
29
29
|
Object.defineProperty(exports, "useGridTableApi", { enumerable: true, get: function () { return GridTableApi_1.useGridTableApi; } });
|
|
30
|
-
__exportStar(require("./hooks/useColumns"), exports);
|
|
31
30
|
__exportStar(require("./hooks/useSetupColumnSizes"), exports);
|
|
32
31
|
var TableStyles_1 = require("./TableStyles");
|
|
33
32
|
Object.defineProperty(exports, "cardStyle", { enumerable: true, get: function () { return TableStyles_1.cardStyle; } });
|
|
@@ -37,10 +37,12 @@ export declare type GridColumn<R extends Kinded> = {
|
|
|
37
37
|
row: GridRowKind<R, K>;
|
|
38
38
|
api: GridTableApi<R>;
|
|
39
39
|
level: number;
|
|
40
|
+
expanded: boolean;
|
|
40
41
|
}) => ReactNode | GridCellContent : (data: undefined, opts: {
|
|
41
42
|
row: GridRowKind<R, K>;
|
|
42
43
|
api: GridTableApi<R>;
|
|
43
44
|
level: number;
|
|
45
|
+
expanded: boolean;
|
|
44
46
|
}) => ReactNode | GridCellContent);
|
|
45
47
|
} & {
|
|
46
48
|
/**
|
|
@@ -66,13 +68,20 @@ export declare type GridColumn<R extends Kinded> = {
|
|
|
66
68
|
isAction?: true;
|
|
67
69
|
/** Column id that will be used to generate an unique identifier for every row cell */
|
|
68
70
|
id?: string;
|
|
71
|
+
/** String identifier of the column. Typically the same text content as in column header. This is used to in things like the Edit Columns Button */
|
|
72
|
+
name?: string;
|
|
69
73
|
/** Flag that will allow to know which columns are hide-able */
|
|
70
74
|
canHide?: boolean;
|
|
71
75
|
/** Flag that will allow to know which hide-able columns are visible on initial load */
|
|
72
76
|
initVisible?: boolean;
|
|
77
|
+
/** A list of columns that should only be shown when this column is "expanded" */
|
|
78
|
+
expandColumns?: GridColumn<R>[];
|
|
79
|
+
/** Determines whether the group should initially be expanded on load of the table */
|
|
80
|
+
initExpanded?: boolean;
|
|
73
81
|
};
|
|
74
82
|
export declare type GridColumnWithId<R extends Kinded> = GridColumn<R> & {
|
|
75
83
|
id: string;
|
|
84
|
+
expandColumns?: GridColumnWithId<R>[];
|
|
76
85
|
};
|
|
77
86
|
export declare const nonKindGridColumnKeys: string[];
|
|
78
87
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ObservableSet } from "mobx";
|
|
1
2
|
import React from "react";
|
|
2
3
|
import { GridDataRow } from "../components/Row";
|
|
3
4
|
import { GridSortConfig } from "../GridTable";
|
|
@@ -30,6 +31,10 @@ export declare class TableState {
|
|
|
30
31
|
sort: SortState;
|
|
31
32
|
private initialSortState;
|
|
32
33
|
private onSort;
|
|
34
|
+
columns: GridColumnWithId<any>[];
|
|
35
|
+
private expandedColumns;
|
|
36
|
+
visibleColumns: ObservableSet<string>;
|
|
37
|
+
private visibleColumnsStorageKey;
|
|
33
38
|
/**
|
|
34
39
|
* Creates the `RowState` for a given `GridTable`.
|
|
35
40
|
*/
|
|
@@ -40,6 +45,11 @@ export declare class TableState {
|
|
|
40
45
|
setSortKey(clickedColumnId: string): void;
|
|
41
46
|
get sortState(): SortState | undefined;
|
|
42
47
|
setRows(rows: GridDataRow<any>[]): void;
|
|
48
|
+
setColumns(columns: GridColumnWithId<any>[], visibleColumnsStorageKey: string | undefined): void;
|
|
49
|
+
setVisibleColumns(ids: string[]): void;
|
|
50
|
+
get visibleColumnIds(): string[];
|
|
51
|
+
get expandedColumnIds(): string[];
|
|
52
|
+
toggleExpandedColumn(columnId: string): void;
|
|
43
53
|
setMatchedRows(rowIds: string[]): void;
|
|
44
54
|
get selectedIds(): string[];
|
|
45
55
|
getSelected(id: string): SelectedState;
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.deriveSortState = exports.TableStateContext = exports.TableState = void 0;
|
|
7
|
+
const change_case_1 = require("change-case");
|
|
7
8
|
const mobx_1 = require("mobx");
|
|
8
9
|
const react_1 = __importDefault(require("react"));
|
|
9
10
|
const utils_1 = require("./utils");
|
|
@@ -41,15 +42,25 @@ class TableState {
|
|
|
41
42
|
this.activeCellId = undefined;
|
|
42
43
|
// Provide some defaults to get the sort state to properly work.
|
|
43
44
|
this.sort = {};
|
|
45
|
+
// Non-reactive list of our columns
|
|
46
|
+
this.columns = [];
|
|
47
|
+
// An observable set of column ids to keep track of which columns are currently expanded
|
|
48
|
+
this.expandedColumns = new mobx_1.ObservableSet();
|
|
49
|
+
// An observable set of column ids to keep track of which columns are visible
|
|
50
|
+
this.visibleColumns = new mobx_1.ObservableSet();
|
|
51
|
+
this.visibleColumnsStorageKey = "";
|
|
44
52
|
// Make ourselves an observable so that mobx will do caching of .collapseIds so
|
|
45
53
|
// that it'll be a stable identity for GridTable to useMemo against.
|
|
46
|
-
(0, mobx_1.makeAutoObservable)(this,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
(0, mobx_1.makeAutoObservable)(this, {
|
|
55
|
+
// We only shallow observe rows so that:
|
|
56
|
+
// a) we don't deeply/needlessly proxy-ize a large Apollo fragment cache, but
|
|
57
|
+
// b) if rows changes, we re-run computeds like getSelectedRows that may need to see the
|
|
58
|
+
// updated _contents_ of a given row, even if our other selected/matched row states don't change.
|
|
59
|
+
// (as any b/c rows is private, so the mapped type doesn't see it)
|
|
60
|
+
rows: mobx_1.observable.shallow,
|
|
61
|
+
// Do not observe columns, expect this to be a non-reactive value for us to base our reactive values off of.
|
|
62
|
+
columns: false,
|
|
63
|
+
});
|
|
53
64
|
// Whenever our `matchedRows` change (i.e. via filtering) then we need to re-derive header and parent rows' selected state.
|
|
54
65
|
(0, mobx_1.reaction)(() => [...this.matchedRows.values()].sort(), () => {
|
|
55
66
|
const map = new Map();
|
|
@@ -165,6 +176,33 @@ class TableState {
|
|
|
165
176
|
// Finally replace our existing list of rows
|
|
166
177
|
this.rows = rows;
|
|
167
178
|
}
|
|
179
|
+
setColumns(columns, visibleColumnsStorageKey) {
|
|
180
|
+
if (columns !== this.columns) {
|
|
181
|
+
this.columns = columns;
|
|
182
|
+
this.visibleColumnsStorageKey = visibleColumnsStorageKey !== null && visibleColumnsStorageKey !== void 0 ? visibleColumnsStorageKey : (0, change_case_1.camelCase)(columns.map((c) => c.id).join());
|
|
183
|
+
this.visibleColumns.replace(readOrSetLocalVisibleColumnState(columns, this.visibleColumnsStorageKey));
|
|
184
|
+
const expandedColumnIds = columns.filter((c) => c.initExpanded).map((c) => c.id);
|
|
185
|
+
this.expandedColumns.replace(expandedColumnIds);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
setVisibleColumns(ids) {
|
|
189
|
+
sessionStorage.setItem(this.visibleColumnsStorageKey, JSON.stringify(ids));
|
|
190
|
+
this.visibleColumns.replace(ids);
|
|
191
|
+
}
|
|
192
|
+
get visibleColumnIds() {
|
|
193
|
+
return [...this.visibleColumns.values()];
|
|
194
|
+
}
|
|
195
|
+
get expandedColumnIds() {
|
|
196
|
+
return [...this.expandedColumns.values()];
|
|
197
|
+
}
|
|
198
|
+
toggleExpandedColumn(columnId) {
|
|
199
|
+
if (this.expandedColumns.has(columnId)) {
|
|
200
|
+
this.expandedColumns.delete(columnId);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
this.expandedColumns.add(columnId);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
168
206
|
setMatchedRows(rowIds) {
|
|
169
207
|
// ObservableSet doesn't seem to do a `diff` inside `replace` before firing
|
|
170
208
|
// observers/reactions that watch it, which can lead to render loops with the
|
|
@@ -319,6 +357,16 @@ function readLocalCollapseState(persistCollapse) {
|
|
|
319
357
|
const collapsedGridRowIds = sessionStorage.getItem(persistCollapse);
|
|
320
358
|
return collapsedGridRowIds ? JSON.parse(collapsedGridRowIds) : [];
|
|
321
359
|
}
|
|
360
|
+
// Get the columns that are already in the visible state so we keep them toggled.
|
|
361
|
+
function readOrSetLocalVisibleColumnState(columns, storageKey) {
|
|
362
|
+
const storageValue = sessionStorage.getItem(storageKey);
|
|
363
|
+
if (storageValue) {
|
|
364
|
+
return JSON.parse(storageValue);
|
|
365
|
+
}
|
|
366
|
+
const visibleColumnIds = columns.filter((c) => c.initVisible || !c.canHide).map((c) => c.id);
|
|
367
|
+
sessionStorage.setItem(storageKey, JSON.stringify(visibleColumnIds));
|
|
368
|
+
return visibleColumnIds;
|
|
369
|
+
}
|
|
322
370
|
/** Finds a row by id, and returns it + any parents. */
|
|
323
371
|
function findRow(rows, id) {
|
|
324
372
|
// This is technically an array of "maybe FoundRow"
|
|
@@ -5,7 +5,8 @@ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
|
5
5
|
const CollapseToggle_1 = require("../components/CollapseToggle");
|
|
6
6
|
const SelectToggle_1 = require("../components/SelectToggle");
|
|
7
7
|
const types_1 = require("../types");
|
|
8
|
-
const utils_1 = require("
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const utils_2 = require("../../../utils");
|
|
9
10
|
/** Provides default styling for a GridColumn representing a Date. */
|
|
10
11
|
function column(columnDef) {
|
|
11
12
|
return { ...columnDef };
|
|
@@ -44,10 +45,14 @@ function selectColumn(columnDef) {
|
|
|
44
45
|
w: "48px",
|
|
45
46
|
wrapAction: false,
|
|
46
47
|
isAction: true,
|
|
48
|
+
expandColumns: undefined,
|
|
49
|
+
// Select Column should not display the select toggle for `expandableHeader` or `totals` row kinds
|
|
50
|
+
expandableHeader: utils_1.emptyCell,
|
|
51
|
+
totals: utils_1.emptyCell,
|
|
47
52
|
// Use any of the user's per-row kind methods if they have them.
|
|
48
53
|
...columnDef,
|
|
49
54
|
};
|
|
50
|
-
return (0,
|
|
55
|
+
return (0, utils_2.newMethodMissingProxy)(base, (key) => {
|
|
51
56
|
return (data, { row }) => ({
|
|
52
57
|
content: (0, jsx_runtime_1.jsx)(SelectToggle_1.SelectToggle, { id: row.id, disabled: row.selectable === false }, void 0),
|
|
53
58
|
});
|
|
@@ -71,9 +76,13 @@ function collapseColumn(columnDef) {
|
|
|
71
76
|
w: "38px",
|
|
72
77
|
wrapAction: false,
|
|
73
78
|
isAction: true,
|
|
79
|
+
expandColumns: undefined,
|
|
80
|
+
// Collapse Column should not display the collapse toggle for `expandableHeader` or `totals` row kinds
|
|
81
|
+
expandableHeader: utils_1.emptyCell,
|
|
82
|
+
totals: utils_1.emptyCell,
|
|
74
83
|
...columnDef,
|
|
75
84
|
};
|
|
76
|
-
return (0,
|
|
85
|
+
return (0, utils_2.newMethodMissingProxy)(base, (key) => {
|
|
77
86
|
return (data, { row, level }) => ({
|
|
78
87
|
content: (0, jsx_runtime_1.jsx)(CollapseToggle_1.CollapseToggle, { row: row, compact: level > 0 }, void 0),
|
|
79
88
|
});
|
|
@@ -153,8 +162,23 @@ exports.calcColumnSizes = calcColumnSizes;
|
|
|
153
162
|
function assignDefaultColumnIds(columns) {
|
|
154
163
|
// Note: we are not _always_ spreading the `c` property as we need to be able to return the whole proxy object that
|
|
155
164
|
// exists as part of `selectColumn` and `collapseColumn`.
|
|
156
|
-
return columns.map((c, idx) => {
|
|
165
|
+
return columns.map((c, idx) => {
|
|
166
|
+
var _a;
|
|
167
|
+
const { expandColumns = [] } = c;
|
|
168
|
+
const expandColumnsWithId = expandColumns.map((ec, ecIdx) => {
|
|
169
|
+
var _a;
|
|
170
|
+
return ({
|
|
171
|
+
...ec,
|
|
172
|
+
id: (_a = ec.id) !== null && _a !== void 0 ? _a : `${(0, exports.generateColumnId)(idx)}_${ecIdx}`,
|
|
173
|
+
// Defining this as undefined to make TS happy for now.
|
|
174
|
+
// If we do not explicitly set to `undefined`, TS thinks `expandColumns` could still be of type GridColumn<T> (not WithId).
|
|
175
|
+
// We only support a single level of expanding columns, so this is safe to do.
|
|
176
|
+
expandColumns: undefined,
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
return Object.assign(c, { id: (_a = c.id) !== null && _a !== void 0 ? _a : (0, exports.generateColumnId)(idx), expandColumns: expandColumnsWithId });
|
|
180
|
+
});
|
|
157
181
|
}
|
|
158
182
|
exports.assignDefaultColumnIds = assignDefaultColumnIds;
|
|
159
|
-
const generateColumnId = (columnIndex) => `
|
|
183
|
+
const generateColumnId = (columnIndex) => `beamColumn_${columnIndex}`;
|
|
160
184
|
exports.generateColumnId = generateColumnId;
|
|
@@ -19,6 +19,11 @@ export declare const simpleHeader: {
|
|
|
19
19
|
id: string;
|
|
20
20
|
data: {};
|
|
21
21
|
};
|
|
22
|
+
export declare const simpleExpandableHeader: {
|
|
23
|
+
kind: "expandableHeader";
|
|
24
|
+
id: string;
|
|
25
|
+
data: {};
|
|
26
|
+
};
|
|
22
27
|
/** Like `simpleRows` but for `SimpleHeaderAndData`. */
|
|
23
28
|
export declare function simpleDataRows<R extends SimpleHeaderAndData<D>, D>(data?: Array<D & {
|
|
24
29
|
id: string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.simpleDataRows = exports.simpleHeader = void 0;
|
|
3
|
+
exports.simpleDataRows = exports.simpleExpandableHeader = exports.simpleHeader = void 0;
|
|
4
4
|
/** A const for a marker header row. */
|
|
5
5
|
exports.simpleHeader = { kind: "header", id: "header", data: {} };
|
|
6
|
+
exports.simpleExpandableHeader = { kind: "expandableHeader", id: "expandableHeader", data: {} };
|
|
6
7
|
/** Like `simpleRows` but for `SimpleHeaderAndData`. */
|
|
7
8
|
function simpleDataRows(data = []) {
|
|
8
9
|
// @ts-ignore Not sure why this doesn't type-check, something esoteric with the DiscriminateUnion type
|
|
@@ -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 { GridColumnWithId, Kinded } from "../types";
|
|
5
5
|
import { SortOn, SortState } from "./TableState";
|
|
6
6
|
export declare function sortRows<R extends Kinded>(columns: GridColumnWithId<R>[], rows: GridDataRow<R>[], sortState: SortState, caseSensitive: boolean): GridDataRow<R>[];
|
|
7
|
-
export declare function ensureClientSideSortValueIsSortable(sortOn: SortOn, isHeader: boolean, column:
|
|
7
|
+
export declare function ensureClientSideSortValueIsSortable(sortOn: SortOn, isHeader: boolean, column: GridColumnWithId<any>, idx: number, maybeContent: ReactNode | GridCellContent): void;
|
|
@@ -50,8 +50,8 @@ function getPin(pin) {
|
|
|
50
50
|
return typeof pin === "string" ? pin : pin === null || pin === void 0 ? void 0 : pin.at;
|
|
51
51
|
}
|
|
52
52
|
function compare(column, a, b, invert, caseSensitive) {
|
|
53
|
-
const v1 = sortValue((0, utils_1.applyRowFn)(column, a, {}, 0), caseSensitive);
|
|
54
|
-
const v2 = sortValue((0, utils_1.applyRowFn)(column, b, {}, 0), caseSensitive);
|
|
53
|
+
const v1 = sortValue((0, utils_1.applyRowFn)(column, a, {}, 0, false), caseSensitive);
|
|
54
|
+
const v2 = sortValue((0, utils_1.applyRowFn)(column, b, {}, 0, false), caseSensitive);
|
|
55
55
|
const v1e = v1 === null || v1 === undefined;
|
|
56
56
|
const v2e = v2 === null || v2 === undefined;
|
|
57
57
|
if ((v1e && v2e) || v1 === v2) {
|
|
@@ -91,10 +91,12 @@ function sortValue(value, caseSensitive) {
|
|
|
91
91
|
return typeof maybeFn === "string" && !caseSensitive ? maybeFn.toLowerCase() : maybeFn;
|
|
92
92
|
}
|
|
93
93
|
function ensureClientSideSortValueIsSortable(sortOn, isHeader, column, idx, maybeContent) {
|
|
94
|
+
var _a;
|
|
94
95
|
if (process.env.NODE_ENV !== "production" && !isHeader && sortOn === "client" && column.clientSideSort !== false) {
|
|
95
96
|
const value = sortValue(maybeContent, false);
|
|
96
97
|
if (!canClientSideSort(value)) {
|
|
97
|
-
|
|
98
|
+
const columnIdentifier = !column.id.startsWith("beamColumn_") ? column.id : (_a = column.name) !== null && _a !== void 0 ? _a : idx;
|
|
99
|
+
throw new Error(`Column ${columnIdentifier} passed an unsortable value, use GridCellContent or clientSideSort=false`);
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
}
|
|
@@ -6,10 +6,10 @@ import { GridStyle, RowStyle } from "../TableStyles";
|
|
|
6
6
|
import { GridCellAlignment, GridColumnWithId, Kinded, RenderAs } from "../types";
|
|
7
7
|
import { Properties } from "../../../Css";
|
|
8
8
|
/** If a column def return just string text for a given row, apply some default styling. */
|
|
9
|
-
export declare function toContent(maybeContent: ReactNode | GridCellContent, isHeader: boolean, canSortColumn: boolean, isClientSideSorting: boolean, style: GridStyle, as: RenderAs, alignment: GridCellAlignment, column: GridColumnWithId<any
|
|
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): 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: GridTableApi<R>, level: number): ReactNode | GridCellContent;
|
|
12
|
+
export declare function applyRowFn<R extends Kinded>(column: GridColumnWithId<R>, row: GridDataRow<R>, api: GridTableApi<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;
|
|
@@ -21,3 +21,13 @@ export declare function getJustification(column: GridColumnWithId<any>, maybeCon
|
|
|
21
21
|
};
|
|
22
22
|
export declare function maybeApplyFunction<T>(row: T, maybeFn: Properties | ((row: T) => Properties) | undefined): Properties | undefined;
|
|
23
23
|
export declare function matchesFilter(maybeContent: ReactNode | GridCellContent, filter: string): boolean;
|
|
24
|
+
export declare const HEADER = "header";
|
|
25
|
+
export declare const TOTALS = "totals";
|
|
26
|
+
export declare const EXPANDABLE_HEADER = "expandableHeader";
|
|
27
|
+
export declare const reservedRowKinds: string[];
|
|
28
|
+
export declare const zIndices: {
|
|
29
|
+
stickyHeader: number;
|
|
30
|
+
stickyColumns: number;
|
|
31
|
+
expandableHeaderTitle: number;
|
|
32
|
+
expandableHeaderIcon: number;
|
|
33
|
+
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.matchesFilter = exports.maybeApplyFunction = exports.getJustification = exports.getAlignment = exports.getFirstOrLastCellCss = exports.getIndentationCss = exports.emptyCell = exports.DESC = exports.ASC = exports.applyRowFn = exports.isGridCellContent = exports.toContent = void 0;
|
|
3
|
+
exports.zIndices = exports.reservedRowKinds = exports.EXPANDABLE_HEADER = exports.TOTALS = exports.HEADER = exports.matchesFilter = exports.maybeApplyFunction = exports.getJustification = exports.getAlignment = exports.getFirstOrLastCellCss = exports.getIndentationCss = exports.emptyCell = exports.DESC = exports.ASC = exports.applyRowFn = exports.isGridCellContent = exports.toContent = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const ExpandableHeader_1 = require("../components/ExpandableHeader");
|
|
5
6
|
const SortHeader_1 = require("../components/SortHeader");
|
|
6
7
|
const Css_1 = require("../../../Css");
|
|
7
8
|
const getInteractiveElement_1 = require("../../../utils/getInteractiveElement");
|
|
8
9
|
/** If a column def return just string text for a given row, apply some default styling. */
|
|
9
|
-
function toContent(maybeContent, isHeader, canSortColumn, isClientSideSorting, style, as, alignment, column) {
|
|
10
|
+
function toContent(maybeContent, isHeader, canSortColumn, isClientSideSorting, style, as, alignment, column, isExpandableHeader, isExpandable, minStickyLeftOffset) {
|
|
10
11
|
var _a, _b, _c;
|
|
11
12
|
let content = isGridCellContent(maybeContent) ? maybeContent.content : maybeContent;
|
|
12
13
|
if (typeof content === "function") {
|
|
@@ -34,6 +35,12 @@ function toContent(maybeContent, isHeader, canSortColumn, isClientSideSorting, s
|
|
|
34
35
|
if (content && typeof content === "string" && isHeader && canSortColumn) {
|
|
35
36
|
return ((0, jsx_runtime_1.jsx)(SortHeader_1.SortHeader, { content: content, iconOnLeft: alignment === "right", sortKey: (_b = column.serverSideSortKey) !== null && _b !== void 0 ? _b : column.id }, void 0));
|
|
36
37
|
}
|
|
38
|
+
else if (content && typeof content === "string" && isExpandableHeader && isExpandable) {
|
|
39
|
+
return (0, jsx_runtime_1.jsx)(ExpandableHeader_1.ExpandableHeader, { title: content, column: column, minStickyLeftOffset: minStickyLeftOffset, as: as }, void 0);
|
|
40
|
+
}
|
|
41
|
+
else if (content && typeof content === "string" && isExpandableHeader) {
|
|
42
|
+
return (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.lineClamp2.$ }, { children: content }), void 0);
|
|
43
|
+
}
|
|
37
44
|
else if (content && ((_c = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _c === void 0 ? void 0 : _c.wrap) === false && typeof content === "string") {
|
|
38
45
|
// In order to truncate the text properly, then we need to wrap it in another element
|
|
39
46
|
// as our cell element is a flex container, which don't allow for applying truncation styles directly on it.
|
|
@@ -55,12 +62,12 @@ function isContentEmpty(content) {
|
|
|
55
62
|
return emptyValues.includes(content);
|
|
56
63
|
}
|
|
57
64
|
/** Return the content for a given column def applied to a given row. */
|
|
58
|
-
function applyRowFn(column, row, api, level) {
|
|
65
|
+
function applyRowFn(column, row, api, level, expanded) {
|
|
59
66
|
// Usually this is a function to apply against the row, but sometimes it's a hard-coded value, i.e. for headers
|
|
60
67
|
const maybeContent = column[row.kind];
|
|
61
68
|
if (typeof maybeContent === "function") {
|
|
62
69
|
// Auto-destructure data
|
|
63
|
-
return maybeContent(row["data"], { row: row, api, level });
|
|
70
|
+
return maybeContent(row["data"], { row: row, api, level, expanded });
|
|
64
71
|
}
|
|
65
72
|
else {
|
|
66
73
|
return maybeContent;
|
|
@@ -146,3 +153,13 @@ function matchesFilter(maybeContent, filter) {
|
|
|
146
153
|
return false;
|
|
147
154
|
}
|
|
148
155
|
exports.matchesFilter = matchesFilter;
|
|
156
|
+
exports.HEADER = "header";
|
|
157
|
+
exports.TOTALS = "totals";
|
|
158
|
+
exports.EXPANDABLE_HEADER = "expandableHeader";
|
|
159
|
+
exports.reservedRowKinds = [exports.HEADER, exports.TOTALS, exports.EXPANDABLE_HEADER];
|
|
160
|
+
exports.zIndices = {
|
|
161
|
+
stickyHeader: 4,
|
|
162
|
+
stickyColumns: 3,
|
|
163
|
+
expandableHeaderTitle: 2,
|
|
164
|
+
expandableHeaderIcon: 1,
|
|
165
|
+
};
|
package/package.json
CHANGED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useColumns = void 0;
|
|
4
|
-
const change_case_1 = require("change-case");
|
|
5
|
-
const react_1 = require("react");
|
|
6
|
-
const useSessionStorage_1 = require("../../../hooks/useSessionStorage");
|
|
7
|
-
function useColumns(tableColumns, maybeStorageKey) {
|
|
8
|
-
const { selectedColumns, hideColumns } = tableColumns.reduce((acc, column) => {
|
|
9
|
-
// Only include options that can be hidden and have the `id` property defined.
|
|
10
|
-
if (!column.id || column.id.length === 0) {
|
|
11
|
-
console.warn("Column is missing 'id' property required by the Edit Columns button", column);
|
|
12
|
-
return acc;
|
|
13
|
-
}
|
|
14
|
-
// Add hide-able columns
|
|
15
|
-
if (column.canHide) {
|
|
16
|
-
acc.hideColumns.push(column.id);
|
|
17
|
-
}
|
|
18
|
-
// Add selected columns
|
|
19
|
-
if (!column.canHide || (column.canHide && column.initVisible)) {
|
|
20
|
-
acc.selectedColumns.push(column.id);
|
|
21
|
-
}
|
|
22
|
-
return { ...acc };
|
|
23
|
-
}, { selectedColumns: [], hideColumns: [] });
|
|
24
|
-
const storageKey = maybeStorageKey !== null && maybeStorageKey !== void 0 ? maybeStorageKey : (0, change_case_1.camelCase)(hideColumns.map((c) => c).join(""));
|
|
25
|
-
const [storageNames, setStorageNames] = (0, useSessionStorage_1.useSessionStorage)(storageKey, selectedColumns);
|
|
26
|
-
const storageColumns = storageNames && storageNames.map((sc) => tableColumns.find((column) => column.id === sc));
|
|
27
|
-
const [columns, setColumns] = (0, react_1.useState)(storageColumns);
|
|
28
|
-
(0, react_1.useEffect)(() => {
|
|
29
|
-
setStorageNames(columns.map((column) => column.id));
|
|
30
|
-
}, [columns]);
|
|
31
|
-
return [columns, setColumns];
|
|
32
|
-
}
|
|
33
|
-
exports.useColumns = useColumns;
|