@homebound/beam 2.117.3 → 2.118.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/Css.d.ts +3 -0
- package/dist/Css.js +1 -0
- package/dist/components/Table/GridTable.d.ts +1 -0
- package/dist/components/Table/GridTable.js +51 -35
- package/dist/components/Table/RowState.d.ts +2 -0
- package/dist/components/Table/RowState.js +30 -9
- package/dist/components/Table/sortRows.d.ts +3 -3
- package/dist/components/Table/sortRows.js +3 -6
- package/dist/components/Table/useSortState.d.ts +2 -1
- package/dist/components/Table/useSortState.js +11 -5
- package/package.json +3 -3
package/dist/Css.d.ts
CHANGED
|
@@ -2527,6 +2527,9 @@ declare class CssBuilder<T extends Properties1> {
|
|
|
2527
2527
|
} & {
|
|
2528
2528
|
textOverflow: import("csstype").Property.TextOverflow | undefined;
|
|
2529
2529
|
}>;
|
|
2530
|
+
lh(value: Properties["lineHeight"]): CssBuilder<T & {
|
|
2531
|
+
lineHeight: import("csstype").Property.LineHeight<0 | (string & {})> | undefined;
|
|
2532
|
+
}>;
|
|
2530
2533
|
get selectNone(): CssBuilder<T & {
|
|
2531
2534
|
userSelect: import("csstype").Property.UserSelect | undefined;
|
|
2532
2535
|
}>;
|
package/dist/Css.js
CHANGED
|
@@ -754,6 +754,7 @@ class CssBuilder {
|
|
|
754
754
|
get indent() { return this.add("textIndent", "1em").add("marginTop", 0).add("marginBottom", 0); }
|
|
755
755
|
get smallCaps() { return this.add("fontVariant", "small-caps"); }
|
|
756
756
|
get truncate() { return this.add("whiteSpace", "nowrap").add("overflow", "hidden").add("textOverflow", "ellipsis"); }
|
|
757
|
+
lh(value) { return this.add("lineHeight", value); }
|
|
757
758
|
// userSelect
|
|
758
759
|
get selectNone() { return this.add("userSelect", "none"); }
|
|
759
760
|
get selectText() { return this.add("userSelect", "text"); }
|
|
@@ -149,6 +149,7 @@ export interface GridTableProps<R extends Kinded, S, X> {
|
|
|
149
149
|
/** Whether the header row should be sticky. */
|
|
150
150
|
stickyHeader?: boolean;
|
|
151
151
|
stickyOffset?: string;
|
|
152
|
+
/** Configures sorting via a hash, does not need to be stable. */
|
|
152
153
|
sorting?: GridSortConfig<S>;
|
|
153
154
|
/** Shown in the first row slot, if there are no rows to show, i.e. 'No rows found'. */
|
|
154
155
|
fallbackMessage?: string;
|
|
@@ -85,7 +85,7 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
85
85
|
*/
|
|
86
86
|
function GridTable(props) {
|
|
87
87
|
var _a, _b, _c, _d;
|
|
88
|
-
const { id = "gridTable", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss,
|
|
88
|
+
const { id = "gridTable", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, observeRows, persistCollapse, api: callerApi, resizeTarget, activeRowId, } = props;
|
|
89
89
|
// Create a ref that always contains the latest rows, for our effectively-singleton RowState to use
|
|
90
90
|
const rowsRef = (0, react_1.useRef)(rows);
|
|
91
91
|
rowsRef.current = rows;
|
|
@@ -127,25 +127,49 @@ function GridTable(props) {
|
|
|
127
127
|
// (or us) is resetting component state more than necessary, so we track render counts from
|
|
128
128
|
// here instead.
|
|
129
129
|
const { getCount } = (0, useRenderCount_1.useRenderCount)();
|
|
130
|
-
const
|
|
130
|
+
const columnSizes = (0, columnSizes_1.useSetupColumnSizes)(style, columns, tableRef, resizeTarget);
|
|
131
|
+
// Make a single copy of our current collapsed state, so we'll have a single observer.
|
|
132
|
+
const collapsedIds = (0, hooks_1.useComputed)(() => rowState.collapsedIds, [rowState]);
|
|
133
|
+
const [sortState, setSortKey, sortOn] = (0, useSortState_1.useSortState)(columns, props.sorting);
|
|
131
134
|
const maybeSorted = (0, react_1.useMemo)(() => {
|
|
132
|
-
if (
|
|
135
|
+
if (sortOn === "client" && sortState) {
|
|
133
136
|
// If using client-side sort, the sortState use S = number
|
|
134
137
|
return (0, sortRows_1.sortRows)(columns, rows, sortState);
|
|
135
138
|
}
|
|
136
139
|
return rows;
|
|
137
|
-
}, [columns, rows,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
// Filter + flatten + component-ize the sorted rows.
|
|
142
|
-
let [headerRows, filteredRows] = (0, react_1.useMemo)(() => {
|
|
140
|
+
}, [columns, rows, sortOn, sortState]);
|
|
141
|
+
// Filter rows - ensures parent rows remain in the list if any children match the filter.
|
|
142
|
+
const filterRows = (0, react_1.useCallback)((acc, row) => {
|
|
143
|
+
var _a, _b, _c;
|
|
143
144
|
// Break up "foo bar" into `[foo, bar]` and a row must match both `foo` and `bar`
|
|
144
145
|
const filters = (filter && filter.split(/ +/)) || [];
|
|
146
|
+
const matches = row.kind === "header" ||
|
|
147
|
+
filters.length === 0 ||
|
|
148
|
+
!!row.pin ||
|
|
149
|
+
filters.every((f) => columns.map((c) => applyRowFn(c, row, api)).some((maybeContent) => matchesFilter(maybeContent, f)));
|
|
150
|
+
// If the row matches, add it in
|
|
151
|
+
if (matches) {
|
|
152
|
+
return acc.concat([[row, (_b = (_a = row.children) === null || _a === void 0 ? void 0 : _a.reduce(filterRows, [])) !== null && _b !== void 0 ? _b : []]]);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Otherwise, maybe one of the children match.
|
|
156
|
+
const isCollapsed = collapsedIds.includes(row.id);
|
|
157
|
+
if (!isCollapsed && !!((_c = row.children) === null || _c === void 0 ? void 0 : _c.length)) {
|
|
158
|
+
const matchedChildren = row.children.reduce(filterRows, []);
|
|
159
|
+
// If some children did match, then add the parent row with its matched children.
|
|
160
|
+
if (matchedChildren.length > 0) {
|
|
161
|
+
return acc.concat([[row, matchedChildren]]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return acc;
|
|
166
|
+
}, [filter, collapsedIds, columns]);
|
|
167
|
+
// Flatten + component-ize the sorted rows.
|
|
168
|
+
let [headerRows, filteredRows] = (0, react_1.useMemo)(() => {
|
|
145
169
|
function makeRowComponent(row, level) {
|
|
146
170
|
// We only pass sortState to header rows, b/c non-headers rows shouldn't have to re-render on sorting
|
|
147
171
|
// changes, and so by not passing the sortProps, it means the data rows' React.memo will still cache them.
|
|
148
|
-
const sortProps = row.kind === "header" ? {
|
|
172
|
+
const sortProps = row.kind === "header" ? { sortOn, sortState, setSortKey } : { sortOn };
|
|
149
173
|
const RowComponent = observeRows ? ObservedGridRow : MemoizedGridRow;
|
|
150
174
|
return ((0, jsx_runtime_1.jsx)(RowComponent, Object.assign({}, {
|
|
151
175
|
as,
|
|
@@ -168,48 +192,40 @@ function GridTable(props) {
|
|
|
168
192
|
const filteredRows = [];
|
|
169
193
|
// Misc state to track our nested card-ification, i.e. interleaved actual rows + chrome rows
|
|
170
194
|
const nestedCards = !!style.nestedCards && new nestedCards_1.NestedCards(columns, filteredRows, style.nestedCards);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const matches = filters.length === 0 ||
|
|
175
|
-
row.pin ||
|
|
176
|
-
filters.every((filter) => columns.map((c) => applyRowFn(c, row, api)).some((maybeContent) => matchesFilter(maybeContent, filter)));
|
|
177
|
-
let isCard = false;
|
|
178
|
-
// Even if we don't pass the filter, one of our children might, so we continue on after this check
|
|
179
|
-
if (matches) {
|
|
180
|
-
isCard = nestedCards && nestedCards.maybeOpenCard(row);
|
|
181
|
-
filteredRows.push([row, makeRowComponent(row, level)]);
|
|
182
|
-
}
|
|
195
|
+
function visit([row, children], level) {
|
|
196
|
+
let isCard = nestedCards && nestedCards.maybeOpenCard(row);
|
|
197
|
+
filteredRows.push([row, makeRowComponent(row, level)]);
|
|
183
198
|
const isCollapsed = collapsedIds.includes(row.id);
|
|
184
|
-
if (!isCollapsed &&
|
|
185
|
-
nestedCards &&
|
|
186
|
-
visitRows(
|
|
199
|
+
if (!isCollapsed && children.length) {
|
|
200
|
+
nestedCards && nestedCards.addSpacer();
|
|
201
|
+
visitRows(children, isCard, level + 1);
|
|
187
202
|
}
|
|
188
203
|
!(0, nestedCards_1.isLeafRow)(row) && isCard && nestedCards && nestedCards.closeCard();
|
|
189
204
|
}
|
|
190
205
|
function visitRows(rows, addSpacer, level) {
|
|
191
206
|
const length = rows.length;
|
|
192
207
|
rows.forEach((row, i) => {
|
|
193
|
-
if (row.kind === "header") {
|
|
194
|
-
headerRows.push([row, makeRowComponent(row, level)]);
|
|
208
|
+
if (row[0].kind === "header") {
|
|
209
|
+
headerRows.push([row[0], makeRowComponent(row[0], level)]);
|
|
195
210
|
return;
|
|
196
211
|
}
|
|
197
212
|
visit(row, level);
|
|
198
213
|
addSpacer && nestedCards && i !== length - 1 && nestedCards.addSpacer();
|
|
199
214
|
});
|
|
200
215
|
}
|
|
216
|
+
// Call `visitRows` with our a pre-filtered set list
|
|
201
217
|
// If nestedCards is set, we assume the top-level kind is a card, and so should add spacers between them
|
|
202
|
-
visitRows(maybeSorted, !!nestedCards, 0);
|
|
218
|
+
visitRows(maybeSorted.reduce(filterRows, []), !!nestedCards, 0);
|
|
203
219
|
nestedCards && nestedCards.done();
|
|
204
220
|
return [headerRows, filteredRows];
|
|
205
221
|
}, [
|
|
206
222
|
as,
|
|
207
223
|
maybeSorted,
|
|
208
224
|
columns,
|
|
209
|
-
|
|
225
|
+
filterRows,
|
|
210
226
|
style,
|
|
211
227
|
rowStyles,
|
|
212
|
-
|
|
228
|
+
sortOn,
|
|
213
229
|
setSortKey,
|
|
214
230
|
sortState,
|
|
215
231
|
stickyHeader,
|
|
@@ -468,7 +484,7 @@ function getFirstOrLastCellCss(style, columnIndex, columns) {
|
|
|
468
484
|
// We extract GridRow to its own mini-component primarily so we can React.memo'ize it.
|
|
469
485
|
function GridRow(props) {
|
|
470
486
|
var _a;
|
|
471
|
-
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset,
|
|
487
|
+
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sortOn, sortState, setSortKey, openCards, columnSizes, level, getCount, api, ...others } = props;
|
|
472
488
|
const { rowState } = (0, react_1.useContext)(RowState_1.RowStateContext);
|
|
473
489
|
const isActive = (0, hooks_1.useComputed)(() => rowState.activeRowId === `${row.kind}_${row.id}`, [row, rowState]);
|
|
474
490
|
// We treat the "header" kind as special for "good defaults" styling
|
|
@@ -511,12 +527,12 @@ function GridRow(props) {
|
|
|
511
527
|
}
|
|
512
528
|
const maybeContent = applyRowFn(column, row, api);
|
|
513
529
|
currentColspan = isGridCellContent(maybeContent) ? (_a = maybeContent.colspan) !== null && _a !== void 0 ? _a : 1 : 1;
|
|
514
|
-
const canSortColumn = (
|
|
515
|
-
(
|
|
530
|
+
const canSortColumn = (sortOn === "client" && column.clientSideSort !== false) ||
|
|
531
|
+
(sortOn === "server" && !!column.serverSideSortKey);
|
|
516
532
|
const alignment = getAlignment(column, maybeContent);
|
|
517
533
|
const justificationCss = getJustification(column, maybeContent, as, alignment);
|
|
518
|
-
const content = toContent(maybeContent, isHeader, canSortColumn,
|
|
519
|
-
(0, sortRows_1.ensureClientSideSortValueIsSortable)(
|
|
534
|
+
const content = toContent(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment);
|
|
535
|
+
(0, sortRows_1.ensureClientSideSortValueIsSortable)(sortOn, isHeader, column, columnIndex, maybeContent);
|
|
520
536
|
const maybeNestedCardColumnIndex = columnIndex + (style.nestedCards ? 1 : 0);
|
|
521
537
|
const maybeSticky = (_b = ((isGridCellContent(maybeContent) && maybeContent.sticky) || column.sticky)) !== null && _b !== void 0 ? _b : undefined;
|
|
522
538
|
const maybeStickyColumnStyles = maybeSticky && columnSizes
|
|
@@ -34,6 +34,8 @@ export declare class RowState {
|
|
|
34
34
|
get collapsedIds(): string[];
|
|
35
35
|
isCollapsed(id: string): boolean;
|
|
36
36
|
toggleCollapsed(id: string): void;
|
|
37
|
+
private getVisibleChildrenStates;
|
|
38
|
+
private setNestedSelectedStates;
|
|
37
39
|
}
|
|
38
40
|
/** Provides a context for rows to access their table's `RowState`. */
|
|
39
41
|
export declare const RowStateContext: React.Context<{
|
|
@@ -37,6 +37,13 @@ class RowState {
|
|
|
37
37
|
// Make ourselves an observable so that mobx will do caching of .collapseIds so
|
|
38
38
|
// that it'll be a stable identity for GridTable to useMemo against.
|
|
39
39
|
(0, mobx_1.makeAutoObservable)(this, { rows: false }); // as any b/c rows is private, so the mapped type doesn't see it
|
|
40
|
+
// Whenever our `visibleRows` change (i.e. via filtering) then we need to re-derive header and parent rows' selected state.
|
|
41
|
+
(0, mobx_1.reaction)(() => [...this.visibleRows.values()].sort(), () => {
|
|
42
|
+
const map = new Map();
|
|
43
|
+
map.set("header", deriveParentSelected(this.rows.current.flatMap((row) => this.setNestedSelectedStates(row, map))));
|
|
44
|
+
// Merge the changes back into the selected rows state
|
|
45
|
+
this.selectedRows.merge(map);
|
|
46
|
+
}, { equals: mobx_1.comparer.shallow });
|
|
40
47
|
}
|
|
41
48
|
get selectedIds() {
|
|
42
49
|
// Return only ids that are fully checked, i.e. not partial
|
|
@@ -62,7 +69,7 @@ class RowState {
|
|
|
62
69
|
// Just mash the header + all rows + children as selected
|
|
63
70
|
const map = new Map();
|
|
64
71
|
map.set("header", "checked");
|
|
65
|
-
(0, visitor_1.visit)(this.rows.current, (row) => map.set(row.id, "checked"));
|
|
72
|
+
(0, visitor_1.visit)(this.rows.current, (row) => this.visibleRows.has(row.id) && map.set(row.id, "checked"));
|
|
66
73
|
this.selectedRows.replace(map);
|
|
67
74
|
}
|
|
68
75
|
else {
|
|
@@ -80,19 +87,15 @@ class RowState {
|
|
|
80
87
|
}
|
|
81
88
|
// Everything here & down is deterministically on/off
|
|
82
89
|
const map = new Map();
|
|
83
|
-
(0, visitor_1.visit)([curr.row], (row) => map.set(row.id, selected ? "checked" : "unchecked"));
|
|
90
|
+
(0, visitor_1.visit)([curr.row], (row) => this.visibleRows.has(row.id) && map.set(row.id, selected ? "checked" : "unchecked"));
|
|
84
91
|
// Now walk up the parents and see if they are now-all-checked/now-all-unchecked/some-of-each
|
|
85
92
|
for (const parent of [...curr.parents].reverse()) {
|
|
86
93
|
if (parent.children) {
|
|
87
|
-
|
|
88
|
-
map.set(parent.id, deriveParentSelected(children));
|
|
94
|
+
map.set(parent.id, deriveParentSelected(this.getVisibleChildrenStates(parent.children, map)));
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
// And do the header + top-level "children" as a final one-off
|
|
92
|
-
|
|
93
|
-
.filter((row) => row.id !== "header")
|
|
94
|
-
.map((row) => map.get(row.id) || this.getSelected(row.id));
|
|
95
|
-
map.set("header", deriveParentSelected(children));
|
|
98
|
+
map.set("header", deriveParentSelected(this.getVisibleChildrenStates(this.rows.current, map)));
|
|
96
99
|
this.selectedRows.merge(map);
|
|
97
100
|
}
|
|
98
101
|
}
|
|
@@ -145,6 +148,24 @@ class RowState {
|
|
|
145
148
|
localStorage.setItem(this.persistCollapse, JSON.stringify(collapsedIds));
|
|
146
149
|
}
|
|
147
150
|
}
|
|
151
|
+
getVisibleChildrenStates(children, map) {
|
|
152
|
+
return children
|
|
153
|
+
.filter((row) => row.id !== "header" && this.visibleRows.has(row.id))
|
|
154
|
+
.map((row) => map.get(row.id) || this.getSelected(row.id));
|
|
155
|
+
}
|
|
156
|
+
// Recursively traverse through rows to determine selected state of parent rows based on children
|
|
157
|
+
setNestedSelectedStates(row, map) {
|
|
158
|
+
if (this.visibleRows.has(row.id)) {
|
|
159
|
+
if (!row.children) {
|
|
160
|
+
return [this.getSelected(row.id)];
|
|
161
|
+
}
|
|
162
|
+
const childrenSelectedStates = row.children.flatMap((rc) => this.setNestedSelectedStates(rc, map));
|
|
163
|
+
const parentState = deriveParentSelected(childrenSelectedStates);
|
|
164
|
+
map.set(row.id, parentState);
|
|
165
|
+
return [parentState];
|
|
166
|
+
}
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
148
169
|
}
|
|
149
170
|
exports.RowState = RowState;
|
|
150
171
|
/** Provides a context for rows to access their table's `RowState`. */
|
|
@@ -177,5 +198,5 @@ function findRow(rows, id) {
|
|
|
177
198
|
function deriveParentSelected(children) {
|
|
178
199
|
const allChecked = children.every((child) => child === "checked");
|
|
179
200
|
const allUnchecked = children.every((child) => child === "unchecked");
|
|
180
|
-
return allChecked ? "checked" : allUnchecked ? "unchecked" : "partial";
|
|
201
|
+
return children.length === 0 ? "unchecked" : allChecked ? "checked" : allUnchecked ? "unchecked" : "partial";
|
|
181
202
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import { GridCellContent, GridColumn, GridDataRow,
|
|
3
|
-
import { SortState } from "./useSortState";
|
|
2
|
+
import { GridCellContent, GridColumn, GridDataRow, Kinded } from "./GridTable";
|
|
3
|
+
import { SortOn, SortState } from "./useSortState";
|
|
4
4
|
export declare function sortRows<R extends Kinded>(columns: GridColumn<R>[], rows: GridDataRow<R>[], sortState: SortState<number>): GridDataRow<R>[];
|
|
5
|
-
export declare function ensureClientSideSortValueIsSortable(
|
|
5
|
+
export declare function ensureClientSideSortValueIsSortable(sortOn: SortOn, isHeader: boolean, column: GridColumn<any>, idx: number, maybeContent: ReactNode | GridCellContent): void;
|
|
@@ -8,7 +8,7 @@ function sortRows(columns, rows, sortState) {
|
|
|
8
8
|
// Recursively sort child rows
|
|
9
9
|
sorted.forEach((row, i) => {
|
|
10
10
|
if (row.children) {
|
|
11
|
-
sorted[i] =
|
|
11
|
+
sorted[i].children = sortRows(columns, row.children, sortState);
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
return sorted;
|
|
@@ -64,11 +64,8 @@ function sortValue(value) {
|
|
|
64
64
|
}
|
|
65
65
|
return maybeFn;
|
|
66
66
|
}
|
|
67
|
-
function ensureClientSideSortValueIsSortable(
|
|
68
|
-
if (process.env.NODE_ENV !== "production" &&
|
|
69
|
-
!isHeader &&
|
|
70
|
-
(sorting === null || sorting === void 0 ? void 0 : sorting.on) === "client" &&
|
|
71
|
-
column.clientSideSort !== false) {
|
|
67
|
+
function ensureClientSideSortValueIsSortable(sortOn, isHeader, column, idx, maybeContent) {
|
|
68
|
+
if (process.env.NODE_ENV !== "production" && !isHeader && sortOn === "client" && column.clientSideSort !== false) {
|
|
72
69
|
const value = sortValue(maybeContent);
|
|
73
70
|
if (!canClientSideSort(value)) {
|
|
74
71
|
throw new Error(`Column ${idx} passed an unsortable value, use GridCellContent or clientSideSort=false`);
|
|
@@ -8,6 +8,7 @@ import { Direction, GridColumn, GridSortConfig, Kinded } from "./GridTable";
|
|
|
8
8
|
* b) it's index in the `columns` array, if client-side sorting
|
|
9
9
|
*/
|
|
10
10
|
export declare type SortState<S> = readonly [S, Direction];
|
|
11
|
+
export declare type SortOn = "client" | "server" | undefined;
|
|
11
12
|
/** Small custom hook that wraps the "setSortColumn inverts the current sort" logic. */
|
|
12
|
-
export declare function useSortState<R extends Kinded, S>(columns: GridColumn<R, S>[], sorting?: GridSortConfig<S>): [SortState<S> | undefined, (value: S) => void];
|
|
13
|
+
export declare function useSortState<R extends Kinded, S>(columns: GridColumn<R, S>[], sorting?: GridSortConfig<S>): [SortState<S> | undefined, (value: S) => void, SortOn];
|
|
13
14
|
export declare function deriveSortState<S>(currentSortState: SortState<S> | undefined, clickedKey: S, initialSortState: SortState<S> | undefined): SortState<S> | undefined;
|
|
@@ -28,20 +28,26 @@ function useSortState(columns, sorting) {
|
|
|
28
28
|
else {
|
|
29
29
|
return sorting === null || sorting === void 0 ? void 0 : sorting.value;
|
|
30
30
|
}
|
|
31
|
-
},
|
|
31
|
+
},
|
|
32
|
+
// We want to allow the user to not memoize `GridTableProps.sorting` b/c for the
|
|
33
|
+
// initialSortState calc, it's just a bunch of surely hard-coded primitives like
|
|
34
|
+
// sort on client/server, which column is initial.
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
[columns]);
|
|
32
37
|
const [sortState, setSortState] = (0, react_1.useState)(initialSortState);
|
|
33
38
|
// Make a custom setSortKey that is useState-like but contains the ASC->DESC->RESET logic.
|
|
39
|
+
const onSort = (sorting === null || sorting === void 0 ? void 0 : sorting.on) === "server" ? sorting.onSort : undefined;
|
|
34
40
|
const setSortKey = (0, react_1.useCallback)((clickedKey) => {
|
|
35
41
|
const newState = deriveSortState(sortState, clickedKey, initialSortState);
|
|
36
42
|
setSortState(newState);
|
|
37
|
-
if (
|
|
43
|
+
if (onSort) {
|
|
38
44
|
const [newKey, newDirection] = newState !== null && newState !== void 0 ? newState : [undefined, undefined];
|
|
39
|
-
|
|
45
|
+
onSort(newKey, newDirection);
|
|
40
46
|
}
|
|
41
47
|
},
|
|
42
48
|
// Note that sorting.onSort is not listed here, so we bind to whatever the 1st sorting.onSort was
|
|
43
|
-
[sortState,
|
|
44
|
-
return [sortState, setSortKey];
|
|
49
|
+
[initialSortState, sortState, onSort]);
|
|
50
|
+
return [sortState, setSortKey, sorting === null || sorting === void 0 ? void 0 : sorting.on];
|
|
45
51
|
}
|
|
46
52
|
exports.useSortState = useSortState;
|
|
47
53
|
// Exported for testing purposes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homebound/beam",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.118.1",
|
|
4
4
|
"author": "Homebound",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"start": "yarn storybook",
|
|
22
22
|
"build": "yarn copy && ttsc",
|
|
23
|
-
"build:truss": "
|
|
24
|
-
"watch:truss": "cd ./truss && watch 'npm run generate' ./",
|
|
23
|
+
"build:truss": "truss",
|
|
25
24
|
"build:storybook": "build-storybook -s ./testAssets",
|
|
26
25
|
"test": "jest --maxWorkers 4",
|
|
27
26
|
"test:watch": "jest --watch",
|
|
@@ -78,6 +77,7 @@
|
|
|
78
77
|
"@emotion/react": "^11.1.5",
|
|
79
78
|
"@homebound/rtl-react-router-utils": "^1.0.3",
|
|
80
79
|
"@homebound/rtl-utils": "^2.51.0",
|
|
80
|
+
"@homebound/truss": "^1.111.3",
|
|
81
81
|
"@homebound/tsconfig": "^1.0.3",
|
|
82
82
|
"@semantic-release/exec": "^6.0.3",
|
|
83
83
|
"@semantic-release/git": "^9.0.0",
|