zubin-grid 0.4.13 → 0.41.13
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/README.md +100 -19
- package/dist/core/cell.d.ts +6 -6
- package/dist/core/cell.d.ts.map +1 -1
- package/dist/core/cell.js +125 -38
- package/dist/core/cell.js.map +1 -1
- package/dist/core/grid-id.d.ts +7 -0
- package/dist/core/grid-id.d.ts.map +1 -0
- package/dist/core/grid-id.js +51 -0
- package/dist/core/grid-id.js.map +1 -0
- package/dist/core/grid.d.ts +10 -9
- package/dist/core/grid.d.ts.map +1 -1
- package/dist/core/grid.js +388 -144
- package/dist/core/grid.js.map +1 -1
- package/dist/core/head.d.ts +9 -11
- package/dist/core/head.d.ts.map +1 -1
- package/dist/core/head.js +38 -33
- package/dist/core/head.js.map +1 -1
- package/dist/core/helpers.d.ts +3 -3
- package/dist/core/helpers.d.ts.map +1 -1
- package/dist/core/helpers.js +5 -2
- package/dist/core/helpers.js.map +1 -1
- package/dist/core/persist.d.ts.map +1 -1
- package/dist/core/persist.js +42 -41
- package/dist/core/persist.js.map +1 -1
- package/dist/core/tail.d.ts +7 -9
- package/dist/core/tail.d.ts.map +1 -1
- package/dist/core/tail.js +17 -19
- package/dist/core/tail.js.map +1 -1
- package/dist/core/types/grid.types.d.ts +69 -27
- package/dist/core/types/grid.types.d.ts.map +1 -1
- package/dist/core/types/head.types.d.ts +7 -6
- package/dist/core/types/head.types.d.ts.map +1 -1
- package/dist/core/types/tail.types.d.ts +3 -2
- package/dist/core/types/tail.types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/core/gridPersist.d.ts +0 -3
- package/dist/core/gridPersist.d.ts.map +0 -1
- package/dist/core/gridPersist.js +0 -2
- package/dist/core/gridPersist.js.map +0 -1
- package/dist/core/types/gridPersist.types.d.ts +0 -2
- package/dist/core/types/gridPersist.types.d.ts.map +0 -1
- package/dist/core/types/gridPersist.types.js +0 -2
- package/dist/core/types/gridPersist.types.js.map +0 -1
package/dist/core/grid.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useSyncExternalStore } from "react";
|
|
2
2
|
import { cell } from "./cell.js";
|
|
3
|
-
import {
|
|
3
|
+
import { assertGridId, createGridIdKey, formatGridId } from "./grid-id.js";
|
|
4
|
+
import { createGridPersistController, defaultGridPersistAdapter } from "./persist.js";
|
|
4
5
|
import { assertHeadId, createHeadCellMap, createHeadOrderIndex, getHeadCell, getOrderedHeads, } from "./head.js";
|
|
5
6
|
import { createTailCellMap, getTailCell, setTailCellResult } from "./tail.js";
|
|
6
7
|
export function grid(input, options) {
|
|
@@ -13,12 +14,212 @@ export function grid(input, options) {
|
|
|
13
14
|
const stateAdapter = createSchemaStateAdapter(rowCellKey, columnCellKey);
|
|
14
15
|
return createGridStore(normalizedRowHeads, normalizedColumnHeads, createGridInitialCellsFromState(initialState.cells, stateAdapter), stateAdapter, schemaOptions.persist);
|
|
15
16
|
}
|
|
16
|
-
export function
|
|
17
|
-
const
|
|
17
|
+
export function createDimensionGrid(parentGrid, initialCells, dimension, options) {
|
|
18
|
+
const readBoundIds = () => (dimension === "rows"
|
|
19
|
+
? parentGrid.rowHeaders
|
|
20
|
+
: parentGrid.colHeaders);
|
|
21
|
+
const emptyRowHeaders = [];
|
|
22
|
+
const emptyColumnHeaders = [];
|
|
23
|
+
const dimensionSubscribers = new Set();
|
|
24
|
+
const resolvedPersistOption = createDimensionGridPersistOption(parentGrid, dimension, options?.persist);
|
|
25
|
+
let isApplyingState = false;
|
|
26
|
+
let boundIds = [...readBoundIds()];
|
|
27
|
+
const cellsById = new Map(boundIds.map((boundId, index) => [
|
|
28
|
+
createGridIdKey(boundId),
|
|
29
|
+
cell(initialCells[index]),
|
|
30
|
+
]));
|
|
31
|
+
let dimensionGridApi;
|
|
32
|
+
const getCellAtIndex = (index) => {
|
|
33
|
+
if (!Number.isInteger(index) || index < 0 || index >= boundIds.length) {
|
|
34
|
+
throw new Error(`Dimension grid ${dimension} index ${index} is out of bounds.`);
|
|
35
|
+
}
|
|
36
|
+
const boundId = boundIds[index];
|
|
37
|
+
const currentCell = cellsById.get(createGridIdKey(boundId));
|
|
38
|
+
if (!currentCell) {
|
|
39
|
+
throw new Error(`Missing dimension cell for ${dimension} index ${index}.`);
|
|
40
|
+
}
|
|
41
|
+
return currentCell;
|
|
42
|
+
};
|
|
43
|
+
const getState = () => ({
|
|
44
|
+
dimension,
|
|
45
|
+
cells: boundIds.map((boundId) => {
|
|
46
|
+
const currentCell = cellsById.get(createGridIdKey(boundId));
|
|
47
|
+
if (!currentCell) {
|
|
48
|
+
throw new Error(`Missing dimension cell for ${dimension} id "${formatGridId(boundId)}".`);
|
|
49
|
+
}
|
|
50
|
+
return currentCell.get();
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
const applyDimensionCells = (nextCells, mode) => {
|
|
54
|
+
const changedIndices = [];
|
|
55
|
+
const limit = mode === "update" ? Math.min(nextCells.length, boundIds.length) : boundIds.length;
|
|
56
|
+
isApplyingState = true;
|
|
57
|
+
try {
|
|
58
|
+
for (let index = 0; index < limit; index += 1) {
|
|
59
|
+
const currentCell = getCellAtIndex(index);
|
|
60
|
+
const nextValue = nextCells[index];
|
|
61
|
+
if (Object.is(currentCell.get(), nextValue)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
currentCell.set(nextValue);
|
|
65
|
+
changedIndices.push(index);
|
|
66
|
+
}
|
|
67
|
+
if (mode === "replace") {
|
|
68
|
+
for (let index = nextCells.length; index < boundIds.length; index += 1) {
|
|
69
|
+
const currentCell = getCellAtIndex(index);
|
|
70
|
+
if (Object.is(currentCell.get(), undefined)) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
currentCell.set(undefined);
|
|
74
|
+
changedIndices.push(index);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
isApplyingState = false;
|
|
80
|
+
}
|
|
81
|
+
return changedIndices;
|
|
82
|
+
};
|
|
83
|
+
const { hydrate, markStateChanged } = createGridPersistController(resolvedPersistOption, {
|
|
84
|
+
getState,
|
|
85
|
+
replaceState: (nextState) => {
|
|
86
|
+
applyDimensionCells(normalizeDimensionGridStateInput(nextState, dimension).cells, "replace");
|
|
87
|
+
},
|
|
88
|
+
isApplyingState: () => isApplyingState,
|
|
89
|
+
});
|
|
90
|
+
const emitDimensionGridUpdate = (diff, persistStateChanged = false) => {
|
|
91
|
+
if (persistStateChanged) {
|
|
92
|
+
markStateChanged();
|
|
93
|
+
}
|
|
94
|
+
[...dimensionSubscribers].forEach((callback) => {
|
|
95
|
+
callback(dimensionGridApi, diff);
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
const syncDimensionFromParent = () => {
|
|
99
|
+
const nextBoundIds = [...readBoundIds()];
|
|
100
|
+
if (haveSameItems(boundIds, nextBoundIds)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const nextCellsById = new Map(nextBoundIds.map((boundId) => [
|
|
104
|
+
createGridIdKey(boundId),
|
|
105
|
+
cellsById.get(createGridIdKey(boundId)) ?? cell(undefined),
|
|
106
|
+
]));
|
|
107
|
+
const previousSize = boundIds.length;
|
|
108
|
+
boundIds = nextBoundIds;
|
|
109
|
+
cellsById.clear();
|
|
110
|
+
nextCellsById.forEach((currentCell, boundIdKey) => {
|
|
111
|
+
cellsById.set(boundIdKey, currentCell);
|
|
112
|
+
});
|
|
113
|
+
emitDimensionGridUpdate({
|
|
114
|
+
type: "dimension",
|
|
115
|
+
action: previousSize === nextBoundIds.length ? "update" : "resize",
|
|
116
|
+
source: "parent",
|
|
117
|
+
dimension,
|
|
118
|
+
size: nextBoundIds.length,
|
|
119
|
+
previousSize,
|
|
120
|
+
}, true);
|
|
121
|
+
};
|
|
122
|
+
const setGrid = (nextState, mode = "replace") => {
|
|
123
|
+
const changedIndices = applyDimensionCells(normalizeDimensionGridStateInput(nextState, dimension).cells, mode);
|
|
124
|
+
if (changedIndices.length === 0) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
emitDimensionGridUpdate({
|
|
128
|
+
type: "cells",
|
|
129
|
+
action: mode === "update" ? "update" : "replace",
|
|
130
|
+
source: "setGrid",
|
|
131
|
+
dimension,
|
|
132
|
+
size: boundIds.length,
|
|
133
|
+
indices: changedIndices,
|
|
134
|
+
}, true);
|
|
135
|
+
};
|
|
136
|
+
const clearGrid = () => {
|
|
137
|
+
const changedIndices = applyDimensionCells([], "replace");
|
|
138
|
+
if (changedIndices.length === 0) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
emitDimensionGridUpdate({
|
|
142
|
+
type: "cells",
|
|
143
|
+
action: "clear",
|
|
144
|
+
source: "clearGrid",
|
|
145
|
+
dimension,
|
|
146
|
+
size: boundIds.length,
|
|
147
|
+
indices: changedIndices,
|
|
148
|
+
}, true);
|
|
149
|
+
};
|
|
150
|
+
dimensionGridApi = {
|
|
151
|
+
dimension,
|
|
152
|
+
get size() {
|
|
153
|
+
return boundIds.length;
|
|
154
|
+
},
|
|
155
|
+
get rowHeaders() {
|
|
156
|
+
return dimension === "rows" ? parentGrid.rowHeaders : emptyRowHeaders;
|
|
157
|
+
},
|
|
158
|
+
get colHeaders() {
|
|
159
|
+
return dimension === "columns" ? parentGrid.colHeaders : emptyColumnHeaders;
|
|
160
|
+
},
|
|
161
|
+
getState,
|
|
162
|
+
setGrid,
|
|
163
|
+
getCell: getCellAtIndex,
|
|
164
|
+
getValue: (index) => getCellAtIndex(index).get(),
|
|
165
|
+
hasCell: (index) => Number.isInteger(index) && index >= 0 && index < boundIds.length,
|
|
166
|
+
clearGrid,
|
|
167
|
+
subscribeGrid: (callback) => {
|
|
168
|
+
dimensionSubscribers.add(callback);
|
|
169
|
+
return () => {
|
|
170
|
+
dimensionSubscribers.delete(callback);
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
__setCellValue: (index, newValue) => {
|
|
174
|
+
const currentCell = getCellAtIndex(index);
|
|
175
|
+
if (Object.is(currentCell.get(), newValue)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
isApplyingState = true;
|
|
179
|
+
try {
|
|
180
|
+
currentCell.set(newValue);
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
isApplyingState = false;
|
|
184
|
+
}
|
|
185
|
+
emitDimensionGridUpdate({
|
|
186
|
+
type: "cells",
|
|
187
|
+
action: "update",
|
|
188
|
+
source: "cell.set",
|
|
189
|
+
dimension,
|
|
190
|
+
size: boundIds.length,
|
|
191
|
+
indices: [index],
|
|
192
|
+
}, true);
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
Object.defineProperty(dimensionGridApi, "__persistOption", {
|
|
196
|
+
value: resolvedPersistOption,
|
|
197
|
+
enumerable: false,
|
|
198
|
+
configurable: true,
|
|
199
|
+
});
|
|
200
|
+
hydrate();
|
|
201
|
+
void parentGrid.subscribeGrid((_currentParentGrid, diff) => {
|
|
202
|
+
if (dimension === "rows") {
|
|
203
|
+
if (diff.type === "rows" ||
|
|
204
|
+
diff.type === "row-head" ||
|
|
205
|
+
(diff.type === "grid" && didGridDiffAffectAxes(diff))) {
|
|
206
|
+
syncDimensionFromParent();
|
|
207
|
+
}
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (diff.type === "columns" ||
|
|
211
|
+
diff.type === "column-head" ||
|
|
212
|
+
(diff.type === "grid" && didGridDiffAffectAxes(diff))) {
|
|
213
|
+
syncDimensionFromParent();
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
return dimensionGridApi;
|
|
217
|
+
}
|
|
218
|
+
export function createSubGrid(parentGrid, initialCells = [], options) {
|
|
18
219
|
const parentState = parentGrid.getState();
|
|
19
220
|
const stateAdapter = createGridStateCellAdapter();
|
|
20
221
|
const resolvedInitialCells = assertGridStateCellsWithinAxes(initialCells, parentState.rows, parentState.columns, "Sub grid cells");
|
|
21
|
-
const subGridStore = createGridStore(parentState.rows, parentState.columns, createGridInitialCellsFromState(resolvedInitialCells, stateAdapter), stateAdapter, createSubGridPersistOption(parentGrid,
|
|
222
|
+
const subGridStore = createGridStore(parentState.rows, parentState.columns, createGridInitialCellsFromState(resolvedInitialCells, stateAdapter), stateAdapter, createSubGridPersistOption(parentGrid, options?.persist));
|
|
22
223
|
const getSubGridState = () => {
|
|
23
224
|
const nextParentState = parentGrid.getState();
|
|
24
225
|
return createSubGridState(nextParentState.rows, nextParentState.columns, subGridStore.getState().cells);
|
|
@@ -174,13 +375,13 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
174
375
|
return stateAdapter.deserializeCell(stateAdapter.serializeCell(rowId, columnId, value)).value;
|
|
175
376
|
};
|
|
176
377
|
const recomputeRowTailInternal = (rowId) => {
|
|
177
|
-
const onRowUpdate = rowTailUpdaters.get(rowId);
|
|
378
|
+
const onRowUpdate = rowTailUpdaters.get(createGridIdKey(rowId));
|
|
178
379
|
if (!onRowUpdate)
|
|
179
380
|
return false;
|
|
180
381
|
return setTailCellResult(getTailCell(rowTailCells, rowId, "row"), onRowUpdate(getRowCells(rowId)));
|
|
181
382
|
};
|
|
182
383
|
const recomputeColumnTailInternal = (columnId) => {
|
|
183
|
-
const onColumnUpdate = columnTailUpdaters.get(columnId);
|
|
384
|
+
const onColumnUpdate = columnTailUpdaters.get(createGridIdKey(columnId));
|
|
184
385
|
if (!onColumnUpdate)
|
|
185
386
|
return false;
|
|
186
387
|
return setTailCellResult(getTailCell(columnTailCells, columnId, "column"), onColumnUpdate(getColumnCells(columnId)));
|
|
@@ -209,13 +410,16 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
209
410
|
cellsMap.delete(gridKey);
|
|
210
411
|
};
|
|
211
412
|
const attachCell = (rowId, columnId, currentCell) => {
|
|
212
|
-
if (!rowHeadCells.has(rowId))
|
|
213
|
-
throw new Error(`Missing row header "${rowId}".`);
|
|
214
|
-
|
|
215
|
-
|
|
413
|
+
if (!rowHeadCells.has(createGridIdKey(rowId))) {
|
|
414
|
+
throw new Error(`Missing row header "${formatGridId(rowId)}".`);
|
|
415
|
+
}
|
|
416
|
+
if (!columnHeadCells.has(createGridIdKey(columnId))) {
|
|
417
|
+
throw new Error(`Missing column header "${formatGridId(columnId)}".`);
|
|
418
|
+
}
|
|
216
419
|
const gridKey = createGridKey(rowId, columnId);
|
|
217
|
-
if (cellsMap.has(gridKey))
|
|
218
|
-
throw new Error(`Duplicate cell for row "${rowId}" and column "${columnId}".`);
|
|
420
|
+
if (cellsMap.has(gridKey)) {
|
|
421
|
+
throw new Error(`Duplicate cell for row "${formatGridId(rowId)}" and column "${formatGridId(columnId)}".`);
|
|
422
|
+
}
|
|
219
423
|
cellsMap.set(gridKey, currentCell);
|
|
220
424
|
let previousValue = currentCell.get();
|
|
221
425
|
const unsubscribe = currentCell.subscribe(() => {
|
|
@@ -244,8 +448,9 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
244
448
|
};
|
|
245
449
|
const getCell = (rowId, columnId) => {
|
|
246
450
|
const currentCell = cellsMap.get(createGridKey(rowId, columnId));
|
|
247
|
-
if (!currentCell)
|
|
248
|
-
throw new Error(`Missing cell for row "${rowId}" and column "${columnId}".`);
|
|
451
|
+
if (!currentCell) {
|
|
452
|
+
throw new Error(`Missing cell for row "${formatGridId(rowId)}" and column "${formatGridId(columnId)}".`);
|
|
453
|
+
}
|
|
249
454
|
return currentCell;
|
|
250
455
|
};
|
|
251
456
|
const createAxisCellSnapshot = (rowId, columnId) => {
|
|
@@ -272,15 +477,16 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
272
477
|
assertUniqueHeadIds(nextHeads, axis);
|
|
273
478
|
const nextIds = new Set();
|
|
274
479
|
nextHeads.forEach((nextHead, index) => {
|
|
275
|
-
|
|
276
|
-
|
|
480
|
+
const idKey = createGridIdKey(nextHead.id);
|
|
481
|
+
nextIds.add(idKey);
|
|
482
|
+
const currentHeadCell = headCells.get(idKey);
|
|
277
483
|
if (currentHeadCell)
|
|
278
484
|
currentHeadCell.set(nextHead);
|
|
279
485
|
else
|
|
280
|
-
headCells.set(
|
|
281
|
-
if (!tailCells.has(
|
|
282
|
-
tailCells.set(
|
|
283
|
-
headOrder.set(
|
|
486
|
+
headCells.set(idKey, cell(nextHead));
|
|
487
|
+
if (!tailCells.has(idKey))
|
|
488
|
+
tailCells.set(idKey, cell(createEmptyTailState()));
|
|
489
|
+
headOrder.set(idKey, index);
|
|
284
490
|
});
|
|
285
491
|
[...headCells.keys()].forEach((id) => {
|
|
286
492
|
if (nextIds.has(id))
|
|
@@ -294,24 +500,24 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
294
500
|
const replaceState = (nextState) => {
|
|
295
501
|
isApplyingState = true;
|
|
296
502
|
try {
|
|
297
|
-
syncAxisHeads(nextState.rows, "row", rowHeadCells, rowTailCells, rowHeadOrder, (
|
|
298
|
-
rowTailUpdaters.delete(
|
|
503
|
+
syncAxisHeads(nextState.rows, "row", rowHeadCells, rowTailCells, rowHeadOrder, (idKey) => {
|
|
504
|
+
rowTailUpdaters.delete(idKey);
|
|
299
505
|
});
|
|
300
|
-
syncAxisHeads(nextState.columns, "column", columnHeadCells, columnTailCells, columnHeadOrder, (
|
|
301
|
-
columnTailUpdaters.delete(
|
|
506
|
+
syncAxisHeads(nextState.columns, "column", columnHeadCells, columnTailCells, columnHeadOrder, (idKey) => {
|
|
507
|
+
columnTailUpdaters.delete(idKey);
|
|
302
508
|
});
|
|
303
509
|
const nextCells = new Map();
|
|
304
510
|
nextState.cells.forEach((nextStateCell) => {
|
|
305
511
|
const { rowId, columnId, value } = stateAdapter.deserializeCell(nextStateCell);
|
|
306
|
-
if (!rowHeadCells.has(rowId)) {
|
|
307
|
-
throw new Error(`Missing row header "${rowId}".`);
|
|
512
|
+
if (!rowHeadCells.has(createGridIdKey(rowId))) {
|
|
513
|
+
throw new Error(`Missing row header "${formatGridId(rowId)}".`);
|
|
308
514
|
}
|
|
309
|
-
if (!columnHeadCells.has(columnId)) {
|
|
310
|
-
throw new Error(`Missing column header "${columnId}".`);
|
|
515
|
+
if (!columnHeadCells.has(createGridIdKey(columnId))) {
|
|
516
|
+
throw new Error(`Missing column header "${formatGridId(columnId)}".`);
|
|
311
517
|
}
|
|
312
518
|
const gridKey = createGridKey(rowId, columnId);
|
|
313
519
|
if (nextCells.has(gridKey)) {
|
|
314
|
-
throw new Error(`Duplicate cell for row "${rowId}" and column "${columnId}".`);
|
|
520
|
+
throw new Error(`Duplicate cell for row "${formatGridId(rowId)}" and column "${formatGridId(columnId)}".`);
|
|
315
521
|
}
|
|
316
522
|
nextCells.set(gridKey, {
|
|
317
523
|
rowId,
|
|
@@ -365,8 +571,8 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
365
571
|
if (nextCells.length === 0) {
|
|
366
572
|
return null;
|
|
367
573
|
}
|
|
368
|
-
const touchedRowIds = new
|
|
369
|
-
const touchedColumnIds = new
|
|
574
|
+
const touchedRowIds = new Map();
|
|
575
|
+
const touchedColumnIds = new Map();
|
|
370
576
|
const normalizedCells = [];
|
|
371
577
|
const previousCells = [];
|
|
372
578
|
const cellKeys = [];
|
|
@@ -374,10 +580,12 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
374
580
|
try {
|
|
375
581
|
nextCells.forEach((nextStateCell) => {
|
|
376
582
|
const { rowId, columnId, value } = stateAdapter.deserializeCell(nextStateCell);
|
|
377
|
-
if (!rowHeadCells.has(rowId))
|
|
378
|
-
throw new Error(`Missing row header "${rowId}".`);
|
|
379
|
-
|
|
380
|
-
|
|
583
|
+
if (!rowHeadCells.has(createGridIdKey(rowId))) {
|
|
584
|
+
throw new Error(`Missing row header "${formatGridId(rowId)}".`);
|
|
585
|
+
}
|
|
586
|
+
if (!columnHeadCells.has(createGridIdKey(columnId))) {
|
|
587
|
+
throw new Error(`Missing column header "${formatGridId(columnId)}".`);
|
|
588
|
+
}
|
|
381
589
|
const normalizedValue = normalizeCellValue(rowId, columnId, value);
|
|
382
590
|
const gridKey = createGridKey(rowId, columnId);
|
|
383
591
|
const currentCell = cellsMap.get(gridKey);
|
|
@@ -389,16 +597,16 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
389
597
|
attachCell(rowId, columnId, cell(normalizedValue));
|
|
390
598
|
}
|
|
391
599
|
normalizedCells.push(stateAdapter.serializeCell(rowId, columnId, normalizedValue));
|
|
392
|
-
touchedRowIds.
|
|
393
|
-
touchedColumnIds.
|
|
600
|
+
touchedRowIds.set(createGridIdKey(rowId), rowId);
|
|
601
|
+
touchedColumnIds.set(createGridIdKey(columnId), columnId);
|
|
394
602
|
cellKeys.push(gridKey);
|
|
395
603
|
});
|
|
396
604
|
}
|
|
397
605
|
finally {
|
|
398
606
|
isApplyingState = false;
|
|
399
607
|
}
|
|
400
|
-
const rowIds = [...touchedRowIds];
|
|
401
|
-
const columnIds = [...touchedColumnIds];
|
|
608
|
+
const rowIds = [...touchedRowIds.values()];
|
|
609
|
+
const columnIds = [...touchedColumnIds.values()];
|
|
402
610
|
return {
|
|
403
611
|
rowIds,
|
|
404
612
|
columnIds,
|
|
@@ -431,35 +639,34 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
431
639
|
if (nextRowHeads.length === 0) {
|
|
432
640
|
return null;
|
|
433
641
|
}
|
|
434
|
-
const rowIds = new
|
|
642
|
+
const rowIds = new Map();
|
|
435
643
|
const rows = [];
|
|
436
644
|
const previousRows = [];
|
|
437
645
|
let shouldRecomputeColumns = false;
|
|
438
646
|
nextRowHeads.forEach((nextRowHead) => {
|
|
439
647
|
const rowHeadLike = nextRowHead;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const currentHeadCell = rowHeadCells.get(rowHeadLike.id);
|
|
648
|
+
const rowIdKey = createGridIdKey(rowHeadLike.id);
|
|
649
|
+
assertGridId(rowHeadLike.id, "Row header upserts");
|
|
650
|
+
const currentHeadCell = rowHeadCells.get(rowIdKey);
|
|
444
651
|
const currentHead = currentHeadCell?.get();
|
|
445
652
|
const resolvedHead = normalizeUpsertHead(rowHeadLike, currentHead, nextRowFallbackOrder);
|
|
446
653
|
if (currentHeadCell) {
|
|
447
654
|
currentHeadCell.set(resolvedHead);
|
|
448
655
|
}
|
|
449
656
|
else {
|
|
450
|
-
rowHeadCells.set(
|
|
451
|
-
rowTailCells.set(
|
|
452
|
-
rowHeadOrder.set(
|
|
657
|
+
rowHeadCells.set(rowIdKey, cell(resolvedHead));
|
|
658
|
+
rowTailCells.set(rowIdKey, cell(createEmptyTailState()));
|
|
659
|
+
rowHeadOrder.set(rowIdKey, nextRowFallbackOrder);
|
|
453
660
|
nextRowFallbackOrder += 1;
|
|
454
661
|
}
|
|
455
662
|
rows.push(resolvedHead);
|
|
456
663
|
if (currentHead) {
|
|
457
664
|
previousRows.push(currentHead);
|
|
458
665
|
}
|
|
459
|
-
rowIds.
|
|
666
|
+
rowIds.set(rowIdKey, resolvedHead.id);
|
|
460
667
|
shouldRecomputeColumns ||= !currentHead || currentHead.order !== resolvedHead.order;
|
|
461
668
|
});
|
|
462
|
-
const resolvedRowIds = [...rowIds];
|
|
669
|
+
const resolvedRowIds = [...rowIds.values()];
|
|
463
670
|
return {
|
|
464
671
|
rows,
|
|
465
672
|
previousRows,
|
|
@@ -488,35 +695,34 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
488
695
|
if (nextColumnHeads.length === 0) {
|
|
489
696
|
return null;
|
|
490
697
|
}
|
|
491
|
-
const columnIds = new
|
|
698
|
+
const columnIds = new Map();
|
|
492
699
|
const columns = [];
|
|
493
700
|
const previousColumns = [];
|
|
494
701
|
let shouldRecomputeRows = false;
|
|
495
702
|
nextColumnHeads.forEach((nextColumnHead) => {
|
|
496
703
|
const columnHeadLike = nextColumnHead;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
const currentHeadCell = columnHeadCells.get(columnHeadLike.id);
|
|
704
|
+
const columnIdKey = createGridIdKey(columnHeadLike.id);
|
|
705
|
+
assertGridId(columnHeadLike.id, "Column header upserts");
|
|
706
|
+
const currentHeadCell = columnHeadCells.get(columnIdKey);
|
|
501
707
|
const currentHead = currentHeadCell?.get();
|
|
502
708
|
const resolvedHead = normalizeUpsertHead(columnHeadLike, currentHead, nextColumnFallbackOrder);
|
|
503
709
|
if (currentHeadCell) {
|
|
504
710
|
currentHeadCell.set(resolvedHead);
|
|
505
711
|
}
|
|
506
712
|
else {
|
|
507
|
-
columnHeadCells.set(
|
|
508
|
-
columnTailCells.set(
|
|
509
|
-
columnHeadOrder.set(
|
|
713
|
+
columnHeadCells.set(columnIdKey, cell(resolvedHead));
|
|
714
|
+
columnTailCells.set(columnIdKey, cell(createEmptyTailState()));
|
|
715
|
+
columnHeadOrder.set(columnIdKey, nextColumnFallbackOrder);
|
|
510
716
|
nextColumnFallbackOrder += 1;
|
|
511
717
|
}
|
|
512
718
|
columns.push(resolvedHead);
|
|
513
719
|
if (currentHead) {
|
|
514
720
|
previousColumns.push(currentHead);
|
|
515
721
|
}
|
|
516
|
-
columnIds.
|
|
722
|
+
columnIds.set(columnIdKey, resolvedHead.id);
|
|
517
723
|
shouldRecomputeRows ||= !currentHead || currentHead.order !== resolvedHead.order;
|
|
518
724
|
});
|
|
519
|
-
const resolvedColumnIds = [...columnIds];
|
|
725
|
+
const resolvedColumnIds = [...columnIds.values()];
|
|
520
726
|
return {
|
|
521
727
|
columns,
|
|
522
728
|
previousColumns,
|
|
@@ -644,23 +850,25 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
644
850
|
});
|
|
645
851
|
};
|
|
646
852
|
function registerRowTail(rowId, onRowUpdate) {
|
|
647
|
-
|
|
853
|
+
const rowIdKey = createGridIdKey(rowId);
|
|
854
|
+
rowTailUpdaters.set(rowIdKey, onRowUpdate);
|
|
648
855
|
recomputeRowTailInternal(rowId);
|
|
649
856
|
return () => {
|
|
650
|
-
if (rowTailUpdaters.get(
|
|
857
|
+
if (rowTailUpdaters.get(rowIdKey) !== onRowUpdate) {
|
|
651
858
|
return;
|
|
652
859
|
}
|
|
653
|
-
rowTailUpdaters.delete(
|
|
860
|
+
rowTailUpdaters.delete(rowIdKey);
|
|
654
861
|
};
|
|
655
862
|
}
|
|
656
863
|
function registerColumnTail(columnId, onColumnUpdate) {
|
|
657
|
-
|
|
864
|
+
const columnIdKey = createGridIdKey(columnId);
|
|
865
|
+
columnTailUpdaters.set(columnIdKey, onColumnUpdate);
|
|
658
866
|
recomputeColumnTailInternal(columnId);
|
|
659
867
|
return () => {
|
|
660
|
-
if (columnTailUpdaters.get(
|
|
868
|
+
if (columnTailUpdaters.get(columnIdKey) !== onColumnUpdate) {
|
|
661
869
|
return;
|
|
662
870
|
}
|
|
663
|
-
columnTailUpdaters.delete(
|
|
871
|
+
columnTailUpdaters.delete(columnIdKey);
|
|
664
872
|
};
|
|
665
873
|
}
|
|
666
874
|
const setGrid = (nextState, mode = "replace") => {
|
|
@@ -871,6 +1079,11 @@ function createGridStore(initialRows, initialColumns, initialCells, stateAdapter
|
|
|
871
1079
|
recomputeRowTail,
|
|
872
1080
|
recomputeColumnTail,
|
|
873
1081
|
};
|
|
1082
|
+
Object.defineProperty(gridApi, "__persistOption", {
|
|
1083
|
+
value: persist,
|
|
1084
|
+
enumerable: false,
|
|
1085
|
+
configurable: true,
|
|
1086
|
+
});
|
|
874
1087
|
return gridApi;
|
|
875
1088
|
}
|
|
876
1089
|
function resolveUpdater(nextValue, currentValue) {
|
|
@@ -879,7 +1092,7 @@ function resolveUpdater(nextValue, currentValue) {
|
|
|
879
1092
|
: nextValue;
|
|
880
1093
|
}
|
|
881
1094
|
export function createGridKey(rowId, columnId) {
|
|
882
|
-
return
|
|
1095
|
+
return `row=${createGridIdKey(rowId)}|col=${createGridIdKey(columnId)}`;
|
|
883
1096
|
}
|
|
884
1097
|
export function useGrid(currentGrid, options) {
|
|
885
1098
|
const snapshotRef = useRef({
|
|
@@ -917,7 +1130,7 @@ function toOptionalArray(values) {
|
|
|
917
1130
|
}
|
|
918
1131
|
function haveSameItems(left, right) {
|
|
919
1132
|
return (left.length === right.length &&
|
|
920
|
-
left.every((currentValue, index) =>
|
|
1133
|
+
left.every((currentValue, index) => createGridIdKey(currentValue) === createGridIdKey(right[index])));
|
|
921
1134
|
}
|
|
922
1135
|
function normalizeGridStateInput(value) {
|
|
923
1136
|
if (!value || typeof value !== "object") {
|
|
@@ -969,16 +1182,16 @@ function mergeHeadStates(currentHeads, nextHeads) {
|
|
|
969
1182
|
const currentIds = new Set();
|
|
970
1183
|
const nextHeadsById = new Map();
|
|
971
1184
|
currentHeads.forEach((currentHead) => {
|
|
972
|
-
currentIds.add(currentHead.id);
|
|
1185
|
+
currentIds.add(createGridIdKey(currentHead.id));
|
|
973
1186
|
});
|
|
974
1187
|
nextHeads.forEach((nextHead) => {
|
|
975
|
-
nextHeadsById.set(nextHead.id, nextHead);
|
|
1188
|
+
nextHeadsById.set(createGridIdKey(nextHead.id), nextHead);
|
|
976
1189
|
});
|
|
977
1190
|
const resolvedHeads = currentHeads.map((currentHead) => {
|
|
978
|
-
return nextHeadsById.get(currentHead.id) ?? currentHead;
|
|
1191
|
+
return nextHeadsById.get(createGridIdKey(currentHead.id)) ?? currentHead;
|
|
979
1192
|
});
|
|
980
1193
|
nextHeads.forEach((nextHead) => {
|
|
981
|
-
if (currentIds.has(nextHead.id)) {
|
|
1194
|
+
if (currentIds.has(createGridIdKey(nextHead.id))) {
|
|
982
1195
|
return;
|
|
983
1196
|
}
|
|
984
1197
|
resolvedHeads.push(nextHead);
|
|
@@ -1013,7 +1226,7 @@ function normalizeGridState(value) {
|
|
|
1013
1226
|
throw new Error("Grid state initializer must return an object.");
|
|
1014
1227
|
}
|
|
1015
1228
|
if (Array.isArray(value)) {
|
|
1016
|
-
throw new Error("
|
|
1229
|
+
throw new Error("Grid state initializer must be a schema object with rows, columns, and cells.");
|
|
1017
1230
|
}
|
|
1018
1231
|
const partialState = value;
|
|
1019
1232
|
const { cells = [], rows = [], columns = [] } = partialState;
|
|
@@ -1029,9 +1242,7 @@ function normalizeGridState(value) {
|
|
|
1029
1242
|
function normalizeRecordHeads(heads, idKey) {
|
|
1030
1243
|
return heads.map((head, index) => {
|
|
1031
1244
|
const id = head[idKey];
|
|
1032
|
-
|
|
1033
|
-
throw new Error(`Grid header key "${String(idKey)}" must resolve to a string id.`);
|
|
1034
|
-
}
|
|
1245
|
+
assertGridId(id, `Grid header key "${String(idKey)}"`);
|
|
1035
1246
|
return {
|
|
1036
1247
|
...head,
|
|
1037
1248
|
id,
|
|
@@ -1047,7 +1258,7 @@ function createGridInitialCellsFromState(stateCells, stateAdapter) {
|
|
|
1047
1258
|
const { rowId, columnId, value } = stateAdapter.deserializeCell(stateCell);
|
|
1048
1259
|
const gridKey = createGridKey(rowId, columnId);
|
|
1049
1260
|
if (seenKeys.has(gridKey)) {
|
|
1050
|
-
throw new Error(`Duplicate cell for row "${rowId}" and column "${columnId}".`);
|
|
1261
|
+
throw new Error(`Duplicate cell for row "${formatGridId(rowId)}" and column "${formatGridId(columnId)}".`);
|
|
1051
1262
|
}
|
|
1052
1263
|
seenKeys.add(gridKey);
|
|
1053
1264
|
initialCells.push({
|
|
@@ -1063,9 +1274,8 @@ function createSchemaStateAdapter(rowCellKey, columnCellKey) {
|
|
|
1063
1274
|
deserializeCell: (stateCell) => {
|
|
1064
1275
|
const rowId = stateCell[rowCellKey];
|
|
1065
1276
|
const columnId = stateCell[columnCellKey];
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
}
|
|
1277
|
+
assertGridId(rowId, `Grid cell key "${String(rowCellKey)}"`);
|
|
1278
|
+
assertGridId(columnId, `Grid cell key "${String(columnCellKey)}"`);
|
|
1069
1279
|
return {
|
|
1070
1280
|
rowId: rowId,
|
|
1071
1281
|
columnId: columnId,
|
|
@@ -1104,10 +1314,11 @@ function normalizeUpsertHead(nextHead, currentHead, fallbackOrder) {
|
|
|
1104
1314
|
function assertUniqueHeadIds(heads, axis) {
|
|
1105
1315
|
const seenIds = new Set();
|
|
1106
1316
|
heads.forEach((head) => {
|
|
1107
|
-
|
|
1108
|
-
|
|
1317
|
+
const idKey = createGridIdKey(head.id);
|
|
1318
|
+
if (seenIds.has(idKey)) {
|
|
1319
|
+
throw new Error(`Duplicate ${axis} header "${formatGridId(head.id)}".`);
|
|
1109
1320
|
}
|
|
1110
|
-
seenIds.add(
|
|
1321
|
+
seenIds.add(idKey);
|
|
1111
1322
|
});
|
|
1112
1323
|
}
|
|
1113
1324
|
function createEmptyTailState() {
|
|
@@ -1125,54 +1336,7 @@ function readGridHeadLabel(head, id) {
|
|
|
1125
1336
|
if (typeof name === "string") {
|
|
1126
1337
|
return name;
|
|
1127
1338
|
}
|
|
1128
|
-
return id;
|
|
1129
|
-
}
|
|
1130
|
-
function resolveCreateSubGridArgs(cellsOrOptionsOrPersist, persist) {
|
|
1131
|
-
if (persist) {
|
|
1132
|
-
return {
|
|
1133
|
-
initialCells: readCreateSubGridCells(cellsOrOptionsOrPersist),
|
|
1134
|
-
persistOption: persist,
|
|
1135
|
-
};
|
|
1136
|
-
}
|
|
1137
|
-
if (!cellsOrOptionsOrPersist) {
|
|
1138
|
-
return {
|
|
1139
|
-
initialCells: [],
|
|
1140
|
-
persistOption: undefined,
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
if (isCreateSubGridOptions(cellsOrOptionsOrPersist)) {
|
|
1144
|
-
const subGridOptions = cellsOrOptionsOrPersist;
|
|
1145
|
-
return {
|
|
1146
|
-
initialCells: subGridOptions.cells ?? [],
|
|
1147
|
-
persistOption: subGridOptions.persist,
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
if (isGridPersistOption(cellsOrOptionsOrPersist)) {
|
|
1151
|
-
return {
|
|
1152
|
-
initialCells: [],
|
|
1153
|
-
persistOption: cellsOrOptionsOrPersist,
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
return {
|
|
1157
|
-
initialCells: cellsOrOptionsOrPersist,
|
|
1158
|
-
persistOption: undefined,
|
|
1159
|
-
};
|
|
1160
|
-
}
|
|
1161
|
-
function readCreateSubGridCells(value) {
|
|
1162
|
-
if (!value || isGridPersistOption(value)) {
|
|
1163
|
-
return [];
|
|
1164
|
-
}
|
|
1165
|
-
if (isCreateSubGridOptions(value)) {
|
|
1166
|
-
return (value
|
|
1167
|
-
.cells ?? []);
|
|
1168
|
-
}
|
|
1169
|
-
return value;
|
|
1170
|
-
}
|
|
1171
|
-
function isCreateSubGridOptions(value) {
|
|
1172
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1173
|
-
}
|
|
1174
|
-
function isGridPersistOption(value) {
|
|
1175
|
-
return Array.isArray(value) && value.length > 0 && typeof value[0] === "string";
|
|
1339
|
+
return formatGridId(id);
|
|
1176
1340
|
}
|
|
1177
1341
|
function createGridStateCellAdapter() {
|
|
1178
1342
|
return {
|
|
@@ -1189,12 +1353,13 @@ function createGridStateCellAdapter() {
|
|
|
1189
1353
|
};
|
|
1190
1354
|
}
|
|
1191
1355
|
function createSubGridPersistOption(parentGrid, persist) {
|
|
1192
|
-
|
|
1356
|
+
const resolvedPersist = resolveDependentGridPersistOption(parentGrid, persist, "sub-grid");
|
|
1357
|
+
if (!resolvedPersist) {
|
|
1193
1358
|
return undefined;
|
|
1194
1359
|
}
|
|
1195
|
-
const [storageKey, adapter] =
|
|
1196
|
-
const resolvedAdapter = adapter ??
|
|
1197
|
-
defaultGridPersistAdapter;
|
|
1360
|
+
const [storageKey, adapter] = resolvedPersist;
|
|
1361
|
+
const resolvedAdapter = (adapter ??
|
|
1362
|
+
defaultGridPersistAdapter);
|
|
1198
1363
|
return [
|
|
1199
1364
|
storageKey,
|
|
1200
1365
|
{
|
|
@@ -1220,6 +1385,73 @@ function createSubGridPersistOption(parentGrid, persist) {
|
|
|
1220
1385
|
},
|
|
1221
1386
|
];
|
|
1222
1387
|
}
|
|
1388
|
+
function createDimensionGridPersistOption(parentGrid, dimension, persist) {
|
|
1389
|
+
const resolvedPersist = resolveDependentGridPersistOption(parentGrid, persist, `dimension-grid:${dimension}`);
|
|
1390
|
+
if (!resolvedPersist) {
|
|
1391
|
+
return undefined;
|
|
1392
|
+
}
|
|
1393
|
+
const [storageKey, adapter] = resolvedPersist;
|
|
1394
|
+
const resolvedAdapter = (adapter ?? defaultGridPersistAdapter);
|
|
1395
|
+
return [
|
|
1396
|
+
storageKey,
|
|
1397
|
+
{
|
|
1398
|
+
get: async (nextStorageKey) => {
|
|
1399
|
+
const persistedState = await Promise.resolve(resolvedAdapter.get(nextStorageKey));
|
|
1400
|
+
if (persistedState === null) {
|
|
1401
|
+
return null;
|
|
1402
|
+
}
|
|
1403
|
+
try {
|
|
1404
|
+
return normalizeDimensionGridStateInput(persistedState, dimension);
|
|
1405
|
+
}
|
|
1406
|
+
catch {
|
|
1407
|
+
return null;
|
|
1408
|
+
}
|
|
1409
|
+
},
|
|
1410
|
+
set: (nextStorageKey, nextState) => {
|
|
1411
|
+
return resolvedAdapter.set(nextStorageKey, normalizeDimensionGridStateInput(nextState, dimension));
|
|
1412
|
+
},
|
|
1413
|
+
remove: (nextStorageKey) => resolvedAdapter.remove(nextStorageKey),
|
|
1414
|
+
},
|
|
1415
|
+
];
|
|
1416
|
+
}
|
|
1417
|
+
function normalizeDimensionGridStateInput(value, dimension) {
|
|
1418
|
+
if (Array.isArray(value)) {
|
|
1419
|
+
return {
|
|
1420
|
+
dimension,
|
|
1421
|
+
cells: value,
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
if (!value || typeof value !== "object") {
|
|
1425
|
+
throw new Error("Dimension grid state updates must be arrays or objects.");
|
|
1426
|
+
}
|
|
1427
|
+
const nextState = value;
|
|
1428
|
+
if (nextState.dimension !== undefined && nextState.dimension !== dimension) {
|
|
1429
|
+
throw new Error(`Dimension grid state must use the "${dimension}" dimension when updating this grid.`);
|
|
1430
|
+
}
|
|
1431
|
+
if (!Array.isArray(nextState.cells)) {
|
|
1432
|
+
throw new Error("Dimension grid state updates must provide a cells array.");
|
|
1433
|
+
}
|
|
1434
|
+
return {
|
|
1435
|
+
dimension,
|
|
1436
|
+
cells: nextState.cells,
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
function resolveDependentGridPersistOption(parentGrid, persist, suffix) {
|
|
1440
|
+
if (persist === false) {
|
|
1441
|
+
return undefined;
|
|
1442
|
+
}
|
|
1443
|
+
if (persist) {
|
|
1444
|
+
return persist;
|
|
1445
|
+
}
|
|
1446
|
+
const inheritedPersist = parentGrid.__persistOption;
|
|
1447
|
+
if (!inheritedPersist) {
|
|
1448
|
+
return undefined;
|
|
1449
|
+
}
|
|
1450
|
+
return [
|
|
1451
|
+
`${inheritedPersist[0]}:${suffix}`,
|
|
1452
|
+
inheritedPersist[1],
|
|
1453
|
+
];
|
|
1454
|
+
}
|
|
1223
1455
|
function createSubGridState(rows, columns, cells) {
|
|
1224
1456
|
return {
|
|
1225
1457
|
rows,
|
|
@@ -1228,22 +1460,23 @@ function createSubGridState(rows, columns, cells) {
|
|
|
1228
1460
|
};
|
|
1229
1461
|
}
|
|
1230
1462
|
function assertGridStateCellsWithinAxes(cells, rows, columns, contextLabel) {
|
|
1231
|
-
const rowIds = new Set(rows.map((rowHead) => rowHead.id));
|
|
1232
|
-
const columnIds = new Set(columns.map((columnHead) => columnHead.id));
|
|
1463
|
+
const rowIds = new Set(rows.map((rowHead) => createGridIdKey(rowHead.id)));
|
|
1464
|
+
const columnIds = new Set(columns.map((columnHead) => createGridIdKey(columnHead.id)));
|
|
1233
1465
|
cells.forEach((currentCell) => {
|
|
1234
|
-
if (!rowIds.has(currentCell.rowId)) {
|
|
1235
|
-
throw new Error(`${contextLabel} must reference an existing parent row header. Missing row "${currentCell.rowId}".`);
|
|
1466
|
+
if (!rowIds.has(createGridIdKey(currentCell.rowId))) {
|
|
1467
|
+
throw new Error(`${contextLabel} must reference an existing parent row header. Missing row "${formatGridId(currentCell.rowId)}".`);
|
|
1236
1468
|
}
|
|
1237
|
-
if (!columnIds.has(currentCell.columnId)) {
|
|
1238
|
-
throw new Error(`${contextLabel} must reference an existing parent column header. Missing column "${currentCell.columnId}".`);
|
|
1469
|
+
if (!columnIds.has(createGridIdKey(currentCell.columnId))) {
|
|
1470
|
+
throw new Error(`${contextLabel} must reference an existing parent column header. Missing column "${formatGridId(currentCell.columnId)}".`);
|
|
1239
1471
|
}
|
|
1240
1472
|
});
|
|
1241
1473
|
return cells;
|
|
1242
1474
|
}
|
|
1243
1475
|
function filterGridStateCellsToAxes(cells, rows, columns) {
|
|
1244
|
-
const rowIds = new Set(rows.map((rowHead) => rowHead.id));
|
|
1245
|
-
const columnIds = new Set(columns.map((columnHead) => columnHead.id));
|
|
1246
|
-
return cells.filter((currentCell) => rowIds.has(currentCell.rowId) &&
|
|
1476
|
+
const rowIds = new Set(rows.map((rowHead) => createGridIdKey(rowHead.id)));
|
|
1477
|
+
const columnIds = new Set(columns.map((columnHead) => createGridIdKey(columnHead.id)));
|
|
1478
|
+
return cells.filter((currentCell) => rowIds.has(createGridIdKey(currentCell.rowId)) &&
|
|
1479
|
+
columnIds.has(createGridIdKey(currentCell.columnId)));
|
|
1247
1480
|
}
|
|
1248
1481
|
function didGridDiffAffectAxes(diff) {
|
|
1249
1482
|
return (!haveSameHeadSnapshots(diff.rows, diff.previousRows) ||
|
|
@@ -1277,7 +1510,18 @@ function haveSameShallowRecord(leftRecord, rightRecord) {
|
|
|
1277
1510
|
if (!(key in rightRecord)) {
|
|
1278
1511
|
return false;
|
|
1279
1512
|
}
|
|
1280
|
-
|
|
1513
|
+
const leftValue = leftRecord[key];
|
|
1514
|
+
const rightValue = rightRecord[key];
|
|
1515
|
+
if (isGridIdValue(leftValue) && isGridIdValue(rightValue)) {
|
|
1516
|
+
return createGridIdKey(leftValue) === createGridIdKey(rightValue);
|
|
1517
|
+
}
|
|
1518
|
+
return Object.is(leftValue, rightValue);
|
|
1281
1519
|
});
|
|
1282
1520
|
}
|
|
1521
|
+
function isGridIdValue(value) {
|
|
1522
|
+
return (typeof value === "string" ||
|
|
1523
|
+
typeof value === "number" ||
|
|
1524
|
+
typeof value === "boolean" ||
|
|
1525
|
+
value instanceof Date);
|
|
1526
|
+
}
|
|
1283
1527
|
//# sourceMappingURL=grid.js.map
|