@gridkitjs/react 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +101 -4
- package/dist/index.js +1019 -421
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
// src/DataGrid/DataGrid.tsx
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
useImperativeHandle,
|
|
4
|
+
useMemo as useMemo3,
|
|
5
|
+
useRef as useRef4,
|
|
6
|
+
useState as useState5
|
|
7
|
+
} from "react";
|
|
3
8
|
import {
|
|
4
9
|
applyColumnOrder,
|
|
5
10
|
defineColumnsFromRows,
|
|
6
11
|
fitColumnsToWidth,
|
|
12
|
+
groupRows,
|
|
7
13
|
moveColumnBefore,
|
|
8
14
|
resolveColumnWidths,
|
|
9
15
|
resolveRowId,
|
|
@@ -13,7 +19,17 @@ import {
|
|
|
13
19
|
|
|
14
20
|
// src/DataGrid/components/GridHeader.tsx
|
|
15
21
|
import { createPortal } from "react-dom";
|
|
16
|
-
import { KEYBOARD_STEP } from "@gridkitjs/core";
|
|
22
|
+
import { buildKeyShortcuts, intentOf, KEYBOARD_STEP } from "@gridkitjs/core";
|
|
23
|
+
|
|
24
|
+
// src/DataGrid/ariaAttr.ts
|
|
25
|
+
function ariaAttr(condition, key, value) {
|
|
26
|
+
return condition ? { [key]: value } : {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// src/DataGrid/classNames.ts
|
|
30
|
+
function classNames(...values) {
|
|
31
|
+
return values.filter(Boolean).join(" ");
|
|
32
|
+
}
|
|
17
33
|
|
|
18
34
|
// src/DataGrid/useGridNavigation.ts
|
|
19
35
|
import {
|
|
@@ -21,20 +37,22 @@ import {
|
|
|
21
37
|
useRef,
|
|
22
38
|
useState
|
|
23
39
|
} from "react";
|
|
24
|
-
|
|
40
|
+
import {
|
|
41
|
+
clampFocus,
|
|
42
|
+
nextFocusForKey,
|
|
43
|
+
HEADER_ROW
|
|
44
|
+
} from "@gridkitjs/core";
|
|
25
45
|
var FALLBACK_PAGE = 10;
|
|
26
|
-
function
|
|
27
|
-
return
|
|
28
|
-
rowIndex: Math.min(Math.max(focus.rowIndex, HEADER_ROW), rowCount - 1),
|
|
29
|
-
columnIndex: Math.min(
|
|
30
|
-
Math.max(focus.columnIndex, 0),
|
|
31
|
-
Math.max(columnCount - 1, 0)
|
|
32
|
-
)
|
|
33
|
-
};
|
|
46
|
+
function tabIndexFor(columnIndex, focusedColumnIndex) {
|
|
47
|
+
return columnIndex === focusedColumnIndex ? 0 : -1;
|
|
34
48
|
}
|
|
35
49
|
function cellAt(table, focus) {
|
|
36
50
|
const row = focus.rowIndex === HEADER_ROW ? table.tHead?.rows[0] ?? null : table.tBodies[0]?.rows[focus.rowIndex] ?? null;
|
|
37
|
-
|
|
51
|
+
if (row === null) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const columnIndex = Math.min(focus.columnIndex, row.cells.length - 1);
|
|
55
|
+
return row.cells[columnIndex] ?? null;
|
|
38
56
|
}
|
|
39
57
|
function useGridNavigation({
|
|
40
58
|
tableRef,
|
|
@@ -78,83 +96,71 @@ function useGridNavigation({
|
|
|
78
96
|
pending.current = true;
|
|
79
97
|
setStored(next);
|
|
80
98
|
}
|
|
81
|
-
function tabIndexFor(rowIndex, columnIndex) {
|
|
82
|
-
return rowIndex === focus.rowIndex && columnIndex === focus.columnIndex ? 0 : -1;
|
|
83
|
-
}
|
|
84
99
|
function onKeyDown(event) {
|
|
85
|
-
|
|
100
|
+
const next = nextFocusForKey(
|
|
101
|
+
event.key,
|
|
102
|
+
{
|
|
103
|
+
ctrlKey: event.ctrlKey,
|
|
104
|
+
metaKey: event.metaKey,
|
|
105
|
+
altKey: event.altKey,
|
|
106
|
+
shiftKey: event.shiftKey
|
|
107
|
+
},
|
|
108
|
+
focus,
|
|
109
|
+
rowCount,
|
|
110
|
+
columnCount,
|
|
111
|
+
pageSize()
|
|
112
|
+
);
|
|
113
|
+
if (next === null) {
|
|
86
114
|
return;
|
|
87
115
|
}
|
|
88
|
-
const { rowIndex, columnIndex } = focus;
|
|
89
|
-
let next;
|
|
90
|
-
switch (event.key) {
|
|
91
|
-
case "ArrowLeft":
|
|
92
|
-
if (event.ctrlKey) return;
|
|
93
|
-
next = { rowIndex, columnIndex: columnIndex - 1 };
|
|
94
|
-
break;
|
|
95
|
-
case "ArrowRight":
|
|
96
|
-
if (event.ctrlKey) return;
|
|
97
|
-
next = { rowIndex, columnIndex: columnIndex + 1 };
|
|
98
|
-
break;
|
|
99
|
-
case "ArrowUp":
|
|
100
|
-
next = { rowIndex: rowIndex - 1, columnIndex };
|
|
101
|
-
break;
|
|
102
|
-
case "ArrowDown":
|
|
103
|
-
next = { rowIndex: rowIndex + 1, columnIndex };
|
|
104
|
-
break;
|
|
105
|
-
// Ctrl takes Home and End to the grid's ends rather than the row's, which
|
|
106
|
-
// is the one place Ctrl is navigation rather than reorder.
|
|
107
|
-
case "Home":
|
|
108
|
-
next = event.ctrlKey ? { rowIndex: HEADER_ROW, columnIndex: 0 } : { rowIndex, columnIndex: 0 };
|
|
109
|
-
break;
|
|
110
|
-
case "End":
|
|
111
|
-
next = event.ctrlKey ? { rowIndex: rowCount - 1, columnIndex: columnCount - 1 } : { rowIndex, columnIndex: columnCount - 1 };
|
|
112
|
-
break;
|
|
113
|
-
case "PageUp":
|
|
114
|
-
next = { rowIndex: rowIndex - pageSize(), columnIndex };
|
|
115
|
-
break;
|
|
116
|
-
case "PageDown":
|
|
117
|
-
next = { rowIndex: rowIndex + pageSize(), columnIndex };
|
|
118
|
-
break;
|
|
119
|
-
default:
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
116
|
event.preventDefault();
|
|
123
117
|
focusCell(next.rowIndex, next.columnIndex);
|
|
124
118
|
}
|
|
125
|
-
return {
|
|
119
|
+
return {
|
|
120
|
+
focus,
|
|
121
|
+
tabIndexFor: (rowIndex, columnIndex) => tabIndexFor(
|
|
122
|
+
columnIndex,
|
|
123
|
+
rowIndex === focus.rowIndex ? focus.columnIndex : null
|
|
124
|
+
),
|
|
125
|
+
focusCell,
|
|
126
|
+
onKeyDown
|
|
127
|
+
};
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
// src/DataGrid/useGridSelection.ts
|
|
129
|
-
import { useMemo, useRef as useRef2 } from "react";
|
|
130
131
|
import {
|
|
131
|
-
|
|
132
|
+
useMemo,
|
|
133
|
+
useRef as useRef2
|
|
134
|
+
} from "react";
|
|
135
|
+
import {
|
|
136
|
+
applySelectionIntent,
|
|
132
137
|
clearSelection,
|
|
133
138
|
diffSelection,
|
|
139
|
+
resolveCell,
|
|
140
|
+
resolveColumns,
|
|
141
|
+
resolveRows,
|
|
134
142
|
selectAll,
|
|
135
143
|
selectCell,
|
|
136
|
-
|
|
137
|
-
selectRange,
|
|
138
|
-
toggleCellSelection,
|
|
139
|
-
toggleSelection
|
|
144
|
+
toggleCellSelection
|
|
140
145
|
} from "@gridkitjs/core";
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
|
|
147
|
+
// src/DataGrid/commitIfChanged.ts
|
|
148
|
+
function commitIfChanged(current, next, setState, onCommit) {
|
|
149
|
+
if (next === current) {
|
|
150
|
+
return false;
|
|
144
151
|
}
|
|
145
|
-
|
|
152
|
+
setState(next);
|
|
153
|
+
onCommit?.(next);
|
|
154
|
+
return true;
|
|
146
155
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
default:
|
|
156
|
-
return selectOnly(selection, id, mode);
|
|
157
|
-
}
|
|
156
|
+
|
|
157
|
+
// src/DataGrid/useGridSelection.ts
|
|
158
|
+
function keyboardSelectIntent(event) {
|
|
159
|
+
return {
|
|
160
|
+
ctrlKey: event.key === " " || event.ctrlKey,
|
|
161
|
+
metaKey: event.metaKey,
|
|
162
|
+
shiftKey: event.shiftKey
|
|
163
|
+
};
|
|
158
164
|
}
|
|
159
165
|
function countMessage(count, noun) {
|
|
160
166
|
if (count === 0) {
|
|
@@ -162,6 +168,18 @@ function countMessage(count, noun) {
|
|
|
162
168
|
}
|
|
163
169
|
return count === 1 ? `1 ${noun} selected` : `${String(count)} ${noun}s selected`;
|
|
164
170
|
}
|
|
171
|
+
function useAsSet(values) {
|
|
172
|
+
return useMemo(() => new Set(values), [values]);
|
|
173
|
+
}
|
|
174
|
+
function useIndexedBy(values, key) {
|
|
175
|
+
return useMemo(
|
|
176
|
+
() => new Map(values.map((value) => [value[key], value])),
|
|
177
|
+
[values, key]
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
function useMappedArray(values, key) {
|
|
181
|
+
return useMemo(() => values.map((value) => value[key]), [values, key]);
|
|
182
|
+
}
|
|
165
183
|
function useGridSelection({
|
|
166
184
|
rows,
|
|
167
185
|
columns,
|
|
@@ -173,141 +191,106 @@ function useGridSelection({
|
|
|
173
191
|
cellSelection,
|
|
174
192
|
setCellSelection,
|
|
175
193
|
callbacks,
|
|
176
|
-
announce
|
|
194
|
+
announce,
|
|
195
|
+
columnName
|
|
177
196
|
}) {
|
|
178
197
|
const rowMode = selectable?.rows ?? false;
|
|
179
198
|
const columnMode = selectable?.columns ?? false;
|
|
180
199
|
const cellMode = selectable?.cells ?? false;
|
|
181
|
-
const rowsById =
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
);
|
|
185
|
-
const
|
|
186
|
-
const columnIds = useMemo(() => columns.map((entry) => entry.id), [columns]);
|
|
187
|
-
const selectedRowIds = useMemo(() => new Set(rowSelection), [rowSelection]);
|
|
188
|
-
const selectedColumnIds = useMemo(
|
|
189
|
-
() => new Set(columnSelection),
|
|
190
|
-
[columnSelection]
|
|
191
|
-
);
|
|
200
|
+
const rowsById = useIndexedBy(rows, "rowId");
|
|
201
|
+
const rowIds = useMappedArray(rows, "rowId");
|
|
202
|
+
const columnIds = useMappedArray(columns, "id");
|
|
203
|
+
const selectedRowIds = useAsSet(rowSelection);
|
|
204
|
+
const selectedColumnIds = useAsSet(columnSelection);
|
|
192
205
|
const rowAnchor = useRef2(null);
|
|
193
206
|
const columnAnchor = useRef2(null);
|
|
194
|
-
function resolveRows(ids) {
|
|
195
|
-
return ids.map((id) => rowsById.get(id)).filter((row) => row !== void 0);
|
|
196
|
-
}
|
|
197
|
-
function resolveColumns(ids) {
|
|
198
|
-
return ids.map((id) => {
|
|
199
|
-
const columnIndex = columns.findIndex((entry) => entry.id === id);
|
|
200
|
-
const column = columns[columnIndex];
|
|
201
|
-
return column === void 0 ? void 0 : { columnId: id, column, columnIndex };
|
|
202
|
-
}).filter((column) => column !== void 0);
|
|
203
|
-
}
|
|
204
|
-
function resolveCell(ref) {
|
|
205
|
-
if (ref === null) {
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
const entry = rowsById.get(ref.rowId);
|
|
209
|
-
const columnIndex = columns.findIndex(
|
|
210
|
-
(candidate) => candidate.id === ref.columnId
|
|
211
|
-
);
|
|
212
|
-
const column = columns[columnIndex];
|
|
213
|
-
if (entry === void 0 || column === void 0) {
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
rowId: ref.rowId,
|
|
218
|
-
columnId: ref.columnId,
|
|
219
|
-
row: entry.row,
|
|
220
|
-
column,
|
|
221
|
-
rowIndex: entry.rowIndex,
|
|
222
|
-
columnIndex,
|
|
223
|
-
value: accessDotted(entry.row, column.column.field)
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
207
|
function announceCount(changed, total, noun) {
|
|
227
208
|
if (changed > 1) {
|
|
228
209
|
announce(countMessage(total, noun));
|
|
229
210
|
}
|
|
230
211
|
}
|
|
231
212
|
function commitRows(next) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
selection: next
|
|
213
|
+
commitIfChanged(rowSelection, next, setRowSelection, (committed) => {
|
|
214
|
+
const { added, removed } = diffSelection(rowSelection, committed);
|
|
215
|
+
const addedRows = resolveRows(rowsById, added);
|
|
216
|
+
const removedRows = resolveRows(rowsById, removed);
|
|
217
|
+
for (const row of addedRows) {
|
|
218
|
+
callbacks.onRowSelect?.({ row, selection: committed });
|
|
219
|
+
}
|
|
220
|
+
if (addedRows.length > 0) {
|
|
221
|
+
callbacks.onRowsSelect?.({ rows: addedRows, selection: committed });
|
|
222
|
+
}
|
|
223
|
+
for (const row of removedRows) {
|
|
224
|
+
callbacks.onRowDeselect?.({ row, selection: committed });
|
|
225
|
+
}
|
|
226
|
+
if (removedRows.length > 0) {
|
|
227
|
+
callbacks.onRowsDeselect?.({ rows: removedRows, selection: committed });
|
|
228
|
+
}
|
|
229
|
+
callbacks.onRowSelectionChange?.({
|
|
230
|
+
added: addedRows,
|
|
231
|
+
removed: removedRows,
|
|
232
|
+
selected: resolveRows(rowsById, committed),
|
|
233
|
+
selection: committed
|
|
234
|
+
});
|
|
235
|
+
announceCount(added.length + removed.length, committed.length, "row");
|
|
256
236
|
});
|
|
257
|
-
announceCount(added.length + removed.length, next.length, "row");
|
|
258
237
|
}
|
|
259
238
|
function commitColumns(next) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
239
|
+
commitIfChanged(columnSelection, next, setColumnSelection, (committed) => {
|
|
240
|
+
const { added, removed } = diffSelection(columnSelection, committed);
|
|
241
|
+
const addedColumns = resolveColumns(columns, added);
|
|
242
|
+
const removedColumns = resolveColumns(columns, removed);
|
|
243
|
+
for (const column of addedColumns) {
|
|
244
|
+
callbacks.onColumnSelect?.({ column, selection: committed });
|
|
245
|
+
}
|
|
246
|
+
if (addedColumns.length > 0) {
|
|
247
|
+
callbacks.onColumnsSelect?.({
|
|
248
|
+
columns: addedColumns,
|
|
249
|
+
selection: committed
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
for (const column of removedColumns) {
|
|
253
|
+
callbacks.onColumnDeselect?.({ column, selection: committed });
|
|
254
|
+
}
|
|
255
|
+
if (removedColumns.length > 0) {
|
|
256
|
+
callbacks.onColumnsDeselect?.({
|
|
257
|
+
columns: removedColumns,
|
|
258
|
+
selection: committed
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
callbacks.onColumnSelectionChange?.({
|
|
262
|
+
added: addedColumns,
|
|
263
|
+
removed: removedColumns,
|
|
264
|
+
selected: resolveColumns(columns, committed),
|
|
265
|
+
selection: committed
|
|
280
266
|
});
|
|
281
|
-
|
|
282
|
-
callbacks.onColumnSelectionChange?.({
|
|
283
|
-
added: addedColumns,
|
|
284
|
-
removed: removedColumns,
|
|
285
|
-
selected: resolveColumns(next),
|
|
286
|
-
selection: next
|
|
267
|
+
announceCount(added.length + removed.length, committed.length, "column");
|
|
287
268
|
});
|
|
288
|
-
announceCount(added.length + removed.length, next.length, "column");
|
|
289
269
|
}
|
|
290
270
|
function commitCell(next) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
271
|
+
commitIfChanged(cellSelection, next, setCellSelection, (committed) => {
|
|
272
|
+
const selected = resolveCell(rowsById, columns, committed);
|
|
273
|
+
const deselected = resolveCell(rowsById, columns, cellSelection);
|
|
274
|
+
if (deselected !== null) {
|
|
275
|
+
callbacks.onCellDeselect?.({ cell: deselected, selection: committed });
|
|
276
|
+
}
|
|
277
|
+
if (selected !== null) {
|
|
278
|
+
callbacks.onCellSelect?.({ cell: selected, selection: committed });
|
|
279
|
+
}
|
|
280
|
+
callbacks.onCellSelectionChange?.({
|
|
281
|
+
selected,
|
|
282
|
+
deselected,
|
|
283
|
+
selection: committed
|
|
284
|
+
});
|
|
285
|
+
if (selected !== null) {
|
|
286
|
+
announce(
|
|
287
|
+
`${columnName(selected.columnId)}, row ${String(selected.rowIndex + 1)}, selected`
|
|
288
|
+
);
|
|
289
|
+
}
|
|
307
290
|
});
|
|
308
291
|
}
|
|
309
292
|
function selectRow(rowId, intent) {
|
|
310
|
-
const next =
|
|
293
|
+
const next = applySelectionIntent(
|
|
311
294
|
rowSelection,
|
|
312
295
|
rowIds,
|
|
313
296
|
rowAnchor.current,
|
|
@@ -321,7 +304,7 @@ function useGridSelection({
|
|
|
321
304
|
commitRows(next);
|
|
322
305
|
}
|
|
323
306
|
function selectColumn(columnId, intent) {
|
|
324
|
-
const next =
|
|
307
|
+
const next = applySelectionIntent(
|
|
325
308
|
columnSelection,
|
|
326
309
|
columnIds,
|
|
327
310
|
columnAnchor.current,
|
|
@@ -364,8 +347,8 @@ function useGridSelection({
|
|
|
364
347
|
|
|
365
348
|
// src/DataGrid/components/GridHeader.tsx
|
|
366
349
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
367
|
-
function
|
|
368
|
-
return /* @__PURE__ */
|
|
350
|
+
function Icon({ children }) {
|
|
351
|
+
return /* @__PURE__ */ jsx(
|
|
369
352
|
"svg",
|
|
370
353
|
{
|
|
371
354
|
viewBox: "0 0 24 24",
|
|
@@ -375,27 +358,25 @@ function ChevronsUpDownIcon() {
|
|
|
375
358
|
strokeLinecap: "round",
|
|
376
359
|
strokeLinejoin: "round",
|
|
377
360
|
"aria-hidden": "true",
|
|
378
|
-
children
|
|
379
|
-
/* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5" }),
|
|
380
|
-
/* @__PURE__ */ jsx("path", { d: "m7 9 5-5 5 5" })
|
|
381
|
-
]
|
|
361
|
+
children
|
|
382
362
|
}
|
|
383
363
|
);
|
|
384
364
|
}
|
|
365
|
+
function ChevronsUpDownIcon() {
|
|
366
|
+
return /* @__PURE__ */ jsxs(Icon, { children: [
|
|
367
|
+
/* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5" }),
|
|
368
|
+
/* @__PURE__ */ jsx("path", { d: "m7 9 5-5 5 5" })
|
|
369
|
+
] });
|
|
370
|
+
}
|
|
385
371
|
function ChevronUpIcon() {
|
|
386
|
-
return /* @__PURE__ */ jsx(
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
strokeLinejoin: "round",
|
|
395
|
-
"aria-hidden": "true",
|
|
396
|
-
children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" })
|
|
397
|
-
}
|
|
398
|
-
);
|
|
372
|
+
return /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" }) });
|
|
373
|
+
}
|
|
374
|
+
function GroupIcon() {
|
|
375
|
+
return /* @__PURE__ */ jsxs(Icon, { children: [
|
|
376
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
377
|
+
/* @__PURE__ */ jsx("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1" }),
|
|
378
|
+
/* @__PURE__ */ jsx("rect", { x: "8.5", y: "14", width: "7", height: "7", rx: "1" })
|
|
379
|
+
] });
|
|
399
380
|
}
|
|
400
381
|
function GridHeader({
|
|
401
382
|
columns,
|
|
@@ -403,10 +384,13 @@ function GridHeader({
|
|
|
403
384
|
drag,
|
|
404
385
|
sort,
|
|
405
386
|
sortableColumns,
|
|
387
|
+
grouping,
|
|
388
|
+
groupableColumns,
|
|
389
|
+
groupToggleIconColumns,
|
|
406
390
|
nav,
|
|
407
391
|
selection
|
|
408
392
|
}) {
|
|
409
|
-
const
|
|
393
|
+
const beforeId = drag.dropTarget?.kind === "column-order" ? drag.dropTarget.beforeId : void 0;
|
|
410
394
|
const draggedEntry = columns.find((entry) => entry.id === drag.draggedColumnId) ?? null;
|
|
411
395
|
return /* @__PURE__ */ jsxs("thead", { children: [
|
|
412
396
|
/* @__PURE__ */ jsx("tr", { className: "grid-header", role: "row", "aria-rowindex": 1, children: columns.map((entry, index) => {
|
|
@@ -419,21 +403,30 @@ function GridHeader({
|
|
|
419
403
|
const sortable = column.sortable ?? sortableColumns;
|
|
420
404
|
const sortDirection = sort.directionFor(entry.id);
|
|
421
405
|
const sortPriority = sort.priorityFor(entry.id);
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
406
|
+
const groupable = column.groupable ?? groupableColumns;
|
|
407
|
+
const showGroupToggleIcon = column.groupToggleIcon ?? groupToggleIconColumns;
|
|
408
|
+
const isGrouped = grouping.groupBy.some(
|
|
409
|
+
(level) => level.columnId === entry.id
|
|
410
|
+
);
|
|
411
|
+
const shortcuts = buildKeyShortcuts({
|
|
412
|
+
reorderable: entry.reorderable,
|
|
413
|
+
resizable: entry.resizable,
|
|
414
|
+
sortable,
|
|
415
|
+
groupable
|
|
416
|
+
});
|
|
427
417
|
return /* @__PURE__ */ jsxs(
|
|
428
418
|
"th",
|
|
429
419
|
{
|
|
430
420
|
scope: "col",
|
|
421
|
+
role: "columnheader",
|
|
431
422
|
"data-gridkit-column": entry.id,
|
|
432
423
|
"aria-colindex": index + 1,
|
|
433
424
|
tabIndex: nav.tabIndexFor(HEADER_ROW, index),
|
|
434
|
-
...
|
|
435
|
-
|
|
436
|
-
|
|
425
|
+
...ariaAttr(
|
|
426
|
+
selection.columnMode !== false,
|
|
427
|
+
"aria-selected",
|
|
428
|
+
selected
|
|
429
|
+
),
|
|
437
430
|
onFocus: () => {
|
|
438
431
|
nav.focusCell(HEADER_ROW, index);
|
|
439
432
|
},
|
|
@@ -441,7 +434,7 @@ function GridHeader({
|
|
|
441
434
|
if (drag.justDragged()) {
|
|
442
435
|
return;
|
|
443
436
|
}
|
|
444
|
-
if (event.target instanceof Element && (event.target.closest(".header-resize-handle") !== null || event.target.closest(".header-sort-toggle") !== null)) {
|
|
437
|
+
if (event.target instanceof Element && (event.target.closest(".header-resize-handle") !== null || event.target.closest(".header-sort-toggle") !== null || event.target.closest(".header-group-toggle") !== null)) {
|
|
445
438
|
return;
|
|
446
439
|
}
|
|
447
440
|
selection.selectColumn(entry.id, intentOf(event));
|
|
@@ -459,28 +452,38 @@ function GridHeader({
|
|
|
459
452
|
resize.nudge(entry, direction * KEYBOARD_STEP);
|
|
460
453
|
return;
|
|
461
454
|
}
|
|
455
|
+
if (event.key === "Enter" && event.altKey && entry.resizable) {
|
|
456
|
+
event.preventDefault();
|
|
457
|
+
resize.sizeToContent(entry);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
462
460
|
if (event.key === "ArrowUp" && event.altKey && sortable) {
|
|
463
461
|
event.preventDefault();
|
|
464
462
|
sort.toggle(entry, { shiftKey: event.shiftKey });
|
|
465
463
|
return;
|
|
466
464
|
}
|
|
465
|
+
if (event.key === "ArrowDown" && event.altKey && groupable) {
|
|
466
|
+
event.preventDefault();
|
|
467
|
+
grouping.toggleGroupBy(entry.id);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
467
470
|
if (event.key === " " || event.key === "Enter") {
|
|
468
471
|
event.preventDefault();
|
|
469
472
|
selection.selectColumn(
|
|
470
473
|
entry.id,
|
|
471
|
-
intentOf(
|
|
472
|
-
ctrlKey: event.key === " " || event.ctrlKey,
|
|
473
|
-
metaKey: event.metaKey,
|
|
474
|
-
shiftKey: event.shiftKey
|
|
475
|
-
})
|
|
474
|
+
intentOf(keyboardSelectIntent(event))
|
|
476
475
|
);
|
|
477
476
|
return;
|
|
478
477
|
}
|
|
479
478
|
nav.onKeyDown(event);
|
|
480
479
|
},
|
|
481
|
-
className:
|
|
480
|
+
className: classNames(
|
|
482
481
|
"header-cell",
|
|
483
|
-
|
|
482
|
+
// The grab affordance a header showing either drag
|
|
483
|
+
// destination shares — a column dragged only for grouping
|
|
484
|
+
// (`groupByDraggable` without `reorderable`) grabs the same
|
|
485
|
+
// way one dragged only for reordering does.
|
|
486
|
+
entry.reorderable || entry.groupByDraggable ? "is-reorderable" : "",
|
|
484
487
|
selected ? "is-selected" : "",
|
|
485
488
|
resizing ? "is-resizing" : "",
|
|
486
489
|
dragging ? "is-dragging" : "",
|
|
@@ -488,17 +491,47 @@ function GridHeader({
|
|
|
488
491
|
dropAfter ? "is-drop-after" : "",
|
|
489
492
|
column.wrap?.header ? "is-wrapped" : "",
|
|
490
493
|
column.headerClassName ?? ""
|
|
491
|
-
|
|
492
|
-
...shortcuts !== ""
|
|
493
|
-
...
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
494
|
+
),
|
|
495
|
+
...ariaAttr(shortcuts !== "", "aria-keyshortcuts", shortcuts),
|
|
496
|
+
...ariaAttr(
|
|
497
|
+
sortable && sortDirection !== null,
|
|
498
|
+
"aria-sort",
|
|
499
|
+
sortDirection === "asc" ? "ascending" : "descending"
|
|
500
|
+
),
|
|
501
|
+
...(entry.reorderable || entry.groupByDraggable) && {
|
|
497
502
|
onPointerDown: (event) => {
|
|
498
503
|
drag.startDrag(entry, event);
|
|
499
504
|
}
|
|
500
505
|
},
|
|
501
506
|
children: [
|
|
507
|
+
groupable && showGroupToggleIcon && /*
|
|
508
|
+
* Inline, before the label, rather than absolutely
|
|
509
|
+
* positioned like the sort toggle and resize handle: those
|
|
510
|
+
* two already share the header's right edge, and a third
|
|
511
|
+
* overlay there would need its own carve-out. Sitting in
|
|
512
|
+
* normal flow costs nothing but a few pixels of label width.
|
|
513
|
+
* A pointer affordance only, same as the other two — the
|
|
514
|
+
* keyboard equivalent is Alt+ArrowDown on the header itself.
|
|
515
|
+
*/
|
|
516
|
+
/* @__PURE__ */ jsx(
|
|
517
|
+
"span",
|
|
518
|
+
{
|
|
519
|
+
className: classNames(
|
|
520
|
+
"header-group-toggle",
|
|
521
|
+
isGrouped ? "is-grouped" : ""
|
|
522
|
+
),
|
|
523
|
+
"aria-hidden": "true",
|
|
524
|
+
tabIndex: -1,
|
|
525
|
+
onPointerDown: (event) => {
|
|
526
|
+
event.stopPropagation();
|
|
527
|
+
},
|
|
528
|
+
onClick: (event) => {
|
|
529
|
+
event.stopPropagation();
|
|
530
|
+
grouping.toggleGroupBy(entry.id);
|
|
531
|
+
},
|
|
532
|
+
children: /* @__PURE__ */ jsx(GroupIcon, {})
|
|
533
|
+
}
|
|
534
|
+
),
|
|
502
535
|
entry.label,
|
|
503
536
|
sortable && /*
|
|
504
537
|
* A pointer affordance only, and hidden from assistive
|
|
@@ -509,10 +542,10 @@ function GridHeader({
|
|
|
509
542
|
/* @__PURE__ */ jsxs(
|
|
510
543
|
"span",
|
|
511
544
|
{
|
|
512
|
-
className:
|
|
545
|
+
className: classNames(
|
|
513
546
|
"header-sort-toggle",
|
|
514
547
|
sortDirection !== null ? `is-sorted-${sortDirection}` : ""
|
|
515
|
-
|
|
548
|
+
),
|
|
516
549
|
"aria-hidden": "true",
|
|
517
550
|
tabIndex: -1,
|
|
518
551
|
onPointerDown: (event) => {
|
|
@@ -570,10 +603,109 @@ function GridHeader({
|
|
|
570
603
|
] });
|
|
571
604
|
}
|
|
572
605
|
|
|
573
|
-
// src/DataGrid/components/
|
|
574
|
-
import {
|
|
606
|
+
// src/DataGrid/components/GridBody.tsx
|
|
607
|
+
import { useMemo as useMemo2 } from "react";
|
|
608
|
+
import { groupRowId, intentOf as intentOf2 } from "@gridkitjs/core";
|
|
609
|
+
|
|
610
|
+
// src/DataGrid/components/GridGroupRow.tsx
|
|
575
611
|
import { memo } from "react";
|
|
576
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
612
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
613
|
+
function formatGroupValue(value) {
|
|
614
|
+
if (value === null || value === void 0) {
|
|
615
|
+
return "(blank)";
|
|
616
|
+
}
|
|
617
|
+
if (value instanceof Date) {
|
|
618
|
+
return value.toLocaleString();
|
|
619
|
+
}
|
|
620
|
+
switch (typeof value) {
|
|
621
|
+
case "string":
|
|
622
|
+
case "number":
|
|
623
|
+
case "boolean":
|
|
624
|
+
case "bigint":
|
|
625
|
+
case "symbol":
|
|
626
|
+
return String(value);
|
|
627
|
+
case "function":
|
|
628
|
+
return "(function)";
|
|
629
|
+
default:
|
|
630
|
+
return JSON.stringify(value);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
function GridGroupRowComponent({
|
|
634
|
+
columnCount,
|
|
635
|
+
groupId,
|
|
636
|
+
level,
|
|
637
|
+
columnLabel,
|
|
638
|
+
value,
|
|
639
|
+
expanded,
|
|
640
|
+
count,
|
|
641
|
+
rowIndex,
|
|
642
|
+
posinset,
|
|
643
|
+
setsize,
|
|
644
|
+
focused
|
|
645
|
+
}) {
|
|
646
|
+
return /* @__PURE__ */ jsx2(
|
|
647
|
+
"tr",
|
|
648
|
+
{
|
|
649
|
+
role: "row",
|
|
650
|
+
"aria-rowindex": rowIndex + 2,
|
|
651
|
+
"aria-level": level + 1,
|
|
652
|
+
"aria-expanded": expanded,
|
|
653
|
+
"aria-setsize": setsize,
|
|
654
|
+
"aria-posinset": posinset,
|
|
655
|
+
"data-gridkit-group": groupId,
|
|
656
|
+
className: classNames(
|
|
657
|
+
"grid-group-row",
|
|
658
|
+
`is-group-level-${String(level)}`
|
|
659
|
+
),
|
|
660
|
+
children: /* @__PURE__ */ jsx2(
|
|
661
|
+
"td",
|
|
662
|
+
{
|
|
663
|
+
role: "gridcell",
|
|
664
|
+
colSpan: columnCount,
|
|
665
|
+
tabIndex: focused ? 0 : -1,
|
|
666
|
+
"aria-keyshortcuts": "Space Enter",
|
|
667
|
+
className: "grid-group-cell",
|
|
668
|
+
children: /* @__PURE__ */ jsxs2(
|
|
669
|
+
"div",
|
|
670
|
+
{
|
|
671
|
+
className: "grid-group-cell-content",
|
|
672
|
+
style: { paddingInlineStart: `${String(level * 1.25 + 0.5)}rem` },
|
|
673
|
+
children: [
|
|
674
|
+
/* @__PURE__ */ jsx2(
|
|
675
|
+
"span",
|
|
676
|
+
{
|
|
677
|
+
className: classNames(
|
|
678
|
+
"group-toggle",
|
|
679
|
+
expanded ? "is-expanded" : "is-collapsed"
|
|
680
|
+
),
|
|
681
|
+
"aria-hidden": "true"
|
|
682
|
+
}
|
|
683
|
+
),
|
|
684
|
+
/* @__PURE__ */ jsxs2("span", { className: "group-label", children: [
|
|
685
|
+
columnLabel,
|
|
686
|
+
": ",
|
|
687
|
+
formatGroupValue(value)
|
|
688
|
+
] }),
|
|
689
|
+
/* @__PURE__ */ jsxs2("span", { className: "group-count", children: [
|
|
690
|
+
"(",
|
|
691
|
+
count,
|
|
692
|
+
")"
|
|
693
|
+
] })
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
)
|
|
697
|
+
}
|
|
698
|
+
)
|
|
699
|
+
}
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
var GridGroupRow = memo(GridGroupRowComponent);
|
|
703
|
+
var GridGroupRow_default = GridGroupRow;
|
|
704
|
+
|
|
705
|
+
// src/DataGrid/components/GridRow.tsx
|
|
706
|
+
import { accessDotted } from "@gridkitjs/core";
|
|
707
|
+
import { memo as memo2 } from "react";
|
|
708
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
577
709
|
function GridRowComponent({
|
|
578
710
|
columns,
|
|
579
711
|
rowId,
|
|
@@ -587,31 +719,32 @@ function GridRowComponent({
|
|
|
587
719
|
rowsSelectable,
|
|
588
720
|
cellsSelectable
|
|
589
721
|
}) {
|
|
590
|
-
return /* @__PURE__ */
|
|
722
|
+
return /* @__PURE__ */ jsx3(
|
|
591
723
|
"tr",
|
|
592
724
|
{
|
|
593
725
|
role: "row",
|
|
594
726
|
"aria-rowindex": rowIndex + 2,
|
|
595
|
-
...rowsSelectable
|
|
596
|
-
className:
|
|
727
|
+
...ariaAttr(rowsSelectable, "aria-selected", selected),
|
|
728
|
+
className: classNames("grid-row", selected ? "is-selected" : ""),
|
|
597
729
|
children: columns.map(({ id, column, alignment }, columnIndex) => {
|
|
598
|
-
const value =
|
|
730
|
+
const value = accessDotted(row, column.field);
|
|
599
731
|
const cellSelected = id === selectedColumnId;
|
|
600
|
-
return /* @__PURE__ */
|
|
732
|
+
return /* @__PURE__ */ jsx3(
|
|
601
733
|
"td",
|
|
602
734
|
{
|
|
603
735
|
role: "gridcell",
|
|
604
736
|
"data-gridkit-column": id,
|
|
605
737
|
"aria-colindex": columnIndex + 1,
|
|
606
|
-
tabIndex: columnIndex
|
|
607
|
-
...cellsSelectable
|
|
608
|
-
|
|
738
|
+
tabIndex: tabIndexFor(columnIndex, focusedColumnIndex),
|
|
739
|
+
...ariaAttr(cellsSelectable, "aria-selected", cellSelected),
|
|
740
|
+
...ariaAttr(cellsSelectable, "aria-keyshortcuts", "Space Enter"),
|
|
741
|
+
className: classNames(
|
|
609
742
|
"grid-cell",
|
|
610
743
|
id === activeColumnId ? "is-resizing" : "",
|
|
611
744
|
cellSelected || selectedColumnIds.has(id) ? "is-selected" : "",
|
|
612
745
|
column.wrap?.cells ? "is-wrapped" : "",
|
|
613
746
|
column.cellClassName ?? ""
|
|
614
|
-
|
|
747
|
+
),
|
|
615
748
|
style: { textAlign: alignment },
|
|
616
749
|
children: column.cellTemplate ? column.cellTemplate({ value, row, rowIndex, rowId, selected }) : value
|
|
617
750
|
},
|
|
@@ -621,11 +754,11 @@ function GridRowComponent({
|
|
|
621
754
|
}
|
|
622
755
|
);
|
|
623
756
|
}
|
|
624
|
-
var GridRow =
|
|
757
|
+
var GridRow = memo2(GridRowComponent);
|
|
625
758
|
var GridRow_default = GridRow;
|
|
626
759
|
|
|
627
760
|
// src/DataGrid/components/GridBody.tsx
|
|
628
|
-
import { jsx as
|
|
761
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
629
762
|
function cellFrom(target) {
|
|
630
763
|
if (!(target instanceof Element)) {
|
|
631
764
|
return null;
|
|
@@ -642,21 +775,58 @@ function cellFrom(target) {
|
|
|
642
775
|
columnId
|
|
643
776
|
};
|
|
644
777
|
}
|
|
778
|
+
function groupRowFrom(target) {
|
|
779
|
+
if (!(target instanceof Element)) {
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
const row = target.closest("tr[data-gridkit-group]");
|
|
783
|
+
const groupId = row?.getAttribute("data-gridkit-group");
|
|
784
|
+
if (!(row instanceof HTMLTableRowElement) || groupId === null || groupId === void 0) {
|
|
785
|
+
return null;
|
|
786
|
+
}
|
|
787
|
+
return { rowIndex: row.sectionRowIndex, groupId };
|
|
788
|
+
}
|
|
789
|
+
function groupAriaMeta(rows) {
|
|
790
|
+
const totals = /* @__PURE__ */ new Map();
|
|
791
|
+
for (const entry of rows) {
|
|
792
|
+
if (!("kind" in entry)) continue;
|
|
793
|
+
const parentKey = groupRowId(entry.path.slice(0, -1));
|
|
794
|
+
totals.set(parentKey, (totals.get(parentKey) ?? 0) + 1);
|
|
795
|
+
}
|
|
796
|
+
const seen = /* @__PURE__ */ new Map();
|
|
797
|
+
const meta = /* @__PURE__ */ new Map();
|
|
798
|
+
for (const entry of rows) {
|
|
799
|
+
if (!("kind" in entry)) continue;
|
|
800
|
+
const parentKey = groupRowId(entry.path.slice(0, -1));
|
|
801
|
+
const posinset = (seen.get(parentKey) ?? 0) + 1;
|
|
802
|
+
seen.set(parentKey, posinset);
|
|
803
|
+
meta.set(entry.groupId, {
|
|
804
|
+
posinset,
|
|
805
|
+
setsize: totals.get(parentKey) ?? posinset
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
return meta;
|
|
809
|
+
}
|
|
645
810
|
function GridBody({
|
|
646
811
|
columns,
|
|
647
812
|
rows,
|
|
648
813
|
activeColumnId,
|
|
649
814
|
nav,
|
|
650
|
-
selection
|
|
815
|
+
selection,
|
|
816
|
+
grouping
|
|
651
817
|
}) {
|
|
652
818
|
const { selectedCell, rowMode, cellMode } = selection;
|
|
819
|
+
const ariaMeta = useMemo2(() => groupAriaMeta(rows), [rows]);
|
|
653
820
|
function targetOf(target) {
|
|
654
821
|
const position = cellFrom(target);
|
|
655
822
|
const entry = position === null ? void 0 : rows[position.rowIndex];
|
|
656
|
-
|
|
823
|
+
if (position === null || entry === void 0 || "kind" in entry) {
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
return { position, rowId: entry.rowId };
|
|
657
827
|
}
|
|
658
828
|
function select(rowId, columnId, modifiers) {
|
|
659
|
-
const intent =
|
|
829
|
+
const intent = intentOf2(modifiers);
|
|
660
830
|
if (rowMode !== false) {
|
|
661
831
|
selection.selectRow(rowId, intent);
|
|
662
832
|
}
|
|
@@ -664,78 +834,161 @@ function GridBody({
|
|
|
664
834
|
selection.selectCell({ rowId, columnId }, intent);
|
|
665
835
|
}
|
|
666
836
|
}
|
|
667
|
-
return /* @__PURE__ */
|
|
837
|
+
return /* @__PURE__ */ jsx4(
|
|
668
838
|
"tbody",
|
|
669
839
|
{
|
|
670
840
|
className: "grid-body",
|
|
671
841
|
onFocus: (event) => {
|
|
842
|
+
const group = groupRowFrom(event.target);
|
|
843
|
+
if (group !== null) {
|
|
844
|
+
nav.focusCell(group.rowIndex, 0);
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
672
847
|
const found = targetOf(event.target);
|
|
673
848
|
if (found === null) return;
|
|
674
849
|
nav.focusCell(found.position.rowIndex, found.position.columnIndex);
|
|
675
850
|
},
|
|
676
851
|
onClick: (event) => {
|
|
852
|
+
const group = groupRowFrom(event.target);
|
|
853
|
+
if (group !== null) {
|
|
854
|
+
grouping.toggleExpansion(group.groupId);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
677
857
|
const found = targetOf(event.target);
|
|
678
858
|
if (found === null) return;
|
|
679
859
|
select(found.rowId, found.position.columnId, event);
|
|
680
860
|
},
|
|
681
861
|
onKeyDown: (event) => {
|
|
862
|
+
const group = groupRowFrom(event.target);
|
|
863
|
+
if (group !== null) {
|
|
864
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
865
|
+
event.preventDefault();
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
if (event.key === " " || event.key === "Enter") {
|
|
869
|
+
event.preventDefault();
|
|
870
|
+
grouping.toggleExpansion(group.groupId);
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
nav.onKeyDown(event);
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
682
876
|
if (event.key === " " || event.key === "Enter") {
|
|
683
877
|
const found = targetOf(event.target);
|
|
684
878
|
if (found === null) return;
|
|
685
879
|
event.preventDefault();
|
|
686
|
-
select(
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
880
|
+
select(
|
|
881
|
+
found.rowId,
|
|
882
|
+
found.position.columnId,
|
|
883
|
+
keyboardSelectIntent(event)
|
|
884
|
+
);
|
|
691
885
|
return;
|
|
692
886
|
}
|
|
693
887
|
nav.onKeyDown(event);
|
|
694
888
|
},
|
|
695
|
-
children: rows.map(
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
889
|
+
children: rows.map(
|
|
890
|
+
(entry) => "kind" in entry ? /* @__PURE__ */ jsx4(
|
|
891
|
+
GridGroupRow_default,
|
|
892
|
+
{
|
|
893
|
+
columnCount: columns.length,
|
|
894
|
+
groupId: entry.groupId,
|
|
895
|
+
level: entry.level,
|
|
896
|
+
columnLabel: columns.find((column) => column.id === entry.columnId)?.label ?? entry.columnId,
|
|
897
|
+
value: entry.value,
|
|
898
|
+
expanded: entry.expanded,
|
|
899
|
+
count: entry.count,
|
|
900
|
+
rowIndex: entry.rowIndex,
|
|
901
|
+
posinset: ariaMeta.get(entry.groupId)?.posinset ?? 1,
|
|
902
|
+
setsize: ariaMeta.get(entry.groupId)?.setsize ?? 1,
|
|
903
|
+
focused: nav.focus.rowIndex === entry.rowIndex
|
|
904
|
+
},
|
|
905
|
+
entry.groupId
|
|
906
|
+
) : /* @__PURE__ */ jsx4(
|
|
907
|
+
GridRow_default,
|
|
908
|
+
{
|
|
909
|
+
columns,
|
|
910
|
+
rowId: entry.rowId,
|
|
911
|
+
row: entry.row,
|
|
912
|
+
rowIndex: entry.rowIndex,
|
|
913
|
+
activeColumnId,
|
|
914
|
+
selectedColumnIds: selection.selectedColumnIds,
|
|
915
|
+
selected: selection.selectedRowIds.has(entry.rowId),
|
|
916
|
+
selectedColumnId: selectedCell?.rowId === entry.rowId ? selectedCell.columnId : null,
|
|
917
|
+
focusedColumnIndex: nav.focus.rowIndex === entry.rowIndex ? nav.focus.columnIndex : null,
|
|
918
|
+
rowsSelectable: rowMode !== false,
|
|
919
|
+
cellsSelectable: cellMode !== false
|
|
920
|
+
},
|
|
921
|
+
entry.rowId
|
|
922
|
+
)
|
|
923
|
+
)
|
|
712
924
|
}
|
|
713
925
|
);
|
|
714
926
|
}
|
|
715
927
|
|
|
716
|
-
// src/DataGrid/
|
|
928
|
+
// src/DataGrid/components/GroupByBar.tsx
|
|
929
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
930
|
+
import { resolveKeyboardDropTarget } from "@gridkitjs/core";
|
|
931
|
+
|
|
932
|
+
// src/DataGrid/groupByDropTarget.ts
|
|
933
|
+
import {
|
|
934
|
+
movesGroupBy,
|
|
935
|
+
resolveDropBefore
|
|
936
|
+
} from "@gridkitjs/core";
|
|
937
|
+
|
|
938
|
+
// src/DataGrid/useDragReorder.ts
|
|
717
939
|
import {
|
|
718
940
|
useRef as useRef3,
|
|
719
941
|
useState as useState2
|
|
720
942
|
} from "react";
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
943
|
+
|
|
944
|
+
// src/DataGrid/pointerGesture.ts
|
|
945
|
+
function startPointerGesture(element, pointerId, handlers) {
|
|
946
|
+
element.setPointerCapture(pointerId);
|
|
947
|
+
function stop() {
|
|
948
|
+
element.removeEventListener("pointermove", move);
|
|
949
|
+
element.removeEventListener("pointerup", end);
|
|
950
|
+
element.removeEventListener("pointercancel", cancel);
|
|
951
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
952
|
+
if (element.hasPointerCapture(pointerId)) {
|
|
953
|
+
element.releasePointerCapture(pointerId);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function move(event) {
|
|
957
|
+
handlers.onMove(event);
|
|
958
|
+
}
|
|
959
|
+
function end() {
|
|
960
|
+
stop();
|
|
961
|
+
handlers.onEnd();
|
|
962
|
+
}
|
|
963
|
+
function cancel() {
|
|
964
|
+
stop();
|
|
965
|
+
handlers.onCancel();
|
|
966
|
+
}
|
|
967
|
+
function onKeyDown(event) {
|
|
968
|
+
if (event.key === "Escape") {
|
|
969
|
+
cancel();
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
element.addEventListener("pointermove", move);
|
|
973
|
+
element.addEventListener("pointerup", end);
|
|
974
|
+
element.addEventListener("pointercancel", cancel);
|
|
975
|
+
window.addEventListener("keydown", onKeyDown);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// src/DataGrid/useDragReorder.ts
|
|
725
979
|
var DRAG_THRESHOLD = 4;
|
|
726
|
-
function
|
|
727
|
-
|
|
728
|
-
return element?.closest("th[data-gridkit-column]") ?? null;
|
|
980
|
+
function elementAt(x, y, selector) {
|
|
981
|
+
return document.elementFromPoint(x, y)?.closest(selector) ?? null;
|
|
729
982
|
}
|
|
730
983
|
function sideOf(element, x) {
|
|
731
984
|
const rect = element.getBoundingClientRect();
|
|
732
985
|
return x < rect.left + rect.width / 2 ? "before" : "after";
|
|
733
986
|
}
|
|
734
|
-
function
|
|
735
|
-
|
|
987
|
+
function useDragReorder({
|
|
988
|
+
resolveTarget,
|
|
736
989
|
onDrop
|
|
737
990
|
}) {
|
|
738
|
-
const [
|
|
991
|
+
const [draggedId, setDraggedId] = useState2(null);
|
|
739
992
|
const [dropTarget, setDropTarget] = useState2(null);
|
|
740
993
|
const [ghostTransform, setGhostTransform] = useState2(null);
|
|
741
994
|
const dragged = useRef3(false);
|
|
@@ -744,87 +997,256 @@ function useColumnDrag({
|
|
|
744
997
|
dragged.current = false;
|
|
745
998
|
return answer;
|
|
746
999
|
}
|
|
747
|
-
function startDrag(
|
|
748
|
-
const header = event.currentTarget;
|
|
1000
|
+
function startDrag(id, grabElement, event) {
|
|
749
1001
|
const { pointerId, clientX: startX } = event;
|
|
750
|
-
const grabX = startX -
|
|
1002
|
+
const grabX = startX - grabElement.getBoundingClientRect().left;
|
|
751
1003
|
let dragging = false;
|
|
752
1004
|
let target = null;
|
|
753
1005
|
function placeGhost(x, y) {
|
|
754
1006
|
setGhostTransform(`translate(${String(x - grabX)}px, ${String(y)}px)`);
|
|
755
1007
|
}
|
|
756
|
-
|
|
757
|
-
function move(moveEvent) {
|
|
758
|
-
const { clientX, clientY } = moveEvent;
|
|
759
|
-
if (!dragging) {
|
|
760
|
-
if (Math.abs(clientX - startX) < DRAG_THRESHOLD) {
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
dragging = true;
|
|
764
|
-
dragged.current = true;
|
|
765
|
-
setDraggedColumnId(entry.id);
|
|
766
|
-
}
|
|
767
|
-
placeGhost(clientX, clientY);
|
|
768
|
-
const over = headerAt(clientX, clientY);
|
|
769
|
-
const overId = over?.getAttribute("data-gridkit-column");
|
|
770
|
-
const beforeId = over && overId ? resolveDropBefore(order, overId, sideOf(over, clientX)) : void 0;
|
|
771
|
-
target = beforeId !== void 0 && movesColumn(order, entry.id, beforeId) ? { kind: "column-order", beforeId } : null;
|
|
772
|
-
setDropTarget(target);
|
|
773
|
-
}
|
|
774
|
-
function stop() {
|
|
775
|
-
header.removeEventListener("pointermove", move);
|
|
776
|
-
header.removeEventListener("pointerup", end);
|
|
777
|
-
header.removeEventListener("pointercancel", cancel);
|
|
778
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
779
|
-
if (header.hasPointerCapture(pointerId)) {
|
|
780
|
-
header.releasePointerCapture(pointerId);
|
|
781
|
-
}
|
|
1008
|
+
function reset() {
|
|
782
1009
|
setGhostTransform(null);
|
|
783
|
-
|
|
1010
|
+
setDraggedId(null);
|
|
784
1011
|
setDropTarget(null);
|
|
785
1012
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
1013
|
+
startPointerGesture(grabElement, pointerId, {
|
|
1014
|
+
onMove(moveEvent) {
|
|
1015
|
+
const { clientX, clientY } = moveEvent;
|
|
1016
|
+
if (!dragging) {
|
|
1017
|
+
if (Math.abs(clientX - startX) < DRAG_THRESHOLD) {
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
dragging = true;
|
|
1021
|
+
dragged.current = true;
|
|
1022
|
+
setDraggedId(id);
|
|
1023
|
+
}
|
|
1024
|
+
placeGhost(clientX, clientY);
|
|
1025
|
+
target = resolveTarget(clientX, clientY, id);
|
|
1026
|
+
setDropTarget(target);
|
|
1027
|
+
},
|
|
1028
|
+
onEnd() {
|
|
1029
|
+
const dropped = target;
|
|
1030
|
+
reset();
|
|
1031
|
+
if (dragging && dropped !== null) {
|
|
1032
|
+
onDrop(dropped, id);
|
|
1033
|
+
}
|
|
1034
|
+
},
|
|
1035
|
+
// Escape and a cancelled pointer both leave the order as it was.
|
|
1036
|
+
onCancel() {
|
|
1037
|
+
target = null;
|
|
1038
|
+
reset();
|
|
791
1039
|
}
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
return {
|
|
1043
|
+
draggedId,
|
|
1044
|
+
dropTarget,
|
|
1045
|
+
ghostTransform,
|
|
1046
|
+
startDrag,
|
|
1047
|
+
justDragged
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// src/DataGrid/groupByDropTarget.ts
|
|
1052
|
+
function resolveGroupByDropTarget(clientX, clientY, movedId, groupBy) {
|
|
1053
|
+
const overBar = elementAt(clientX, clientY, "[data-gridkit-group-by-bar]");
|
|
1054
|
+
if (overBar === null) {
|
|
1055
|
+
return null;
|
|
1056
|
+
}
|
|
1057
|
+
const overChip = elementAt(clientX, clientY, "[data-gridkit-group-chip]");
|
|
1058
|
+
const chipId = overChip?.getAttribute("data-gridkit-group-chip");
|
|
1059
|
+
const beforeColumnId = overChip && chipId ? resolveDropBefore(
|
|
1060
|
+
groupBy.map((entry) => entry.columnId),
|
|
1061
|
+
chipId,
|
|
1062
|
+
sideOf(overChip, clientX)
|
|
1063
|
+
) : null;
|
|
1064
|
+
return movesGroupBy(groupBy, movedId, beforeColumnId) ? { kind: "group-by", beforeColumnId } : null;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/DataGrid/useGroupByDrag.ts
|
|
1068
|
+
function useGroupByDrag({
|
|
1069
|
+
groupBy,
|
|
1070
|
+
onDrop
|
|
1071
|
+
}) {
|
|
1072
|
+
const drag = useDragReorder({
|
|
1073
|
+
resolveTarget: (clientX, clientY, movedId) => resolveGroupByDropTarget(clientX, clientY, movedId, groupBy),
|
|
1074
|
+
onDrop: (target, movedId) => {
|
|
1075
|
+
onDrop(movedId, target.beforeColumnId);
|
|
792
1076
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1077
|
+
});
|
|
1078
|
+
return {
|
|
1079
|
+
draggedColumnId: drag.draggedId,
|
|
1080
|
+
dropTarget: drag.dropTarget,
|
|
1081
|
+
ghostTransform: drag.ghostTransform,
|
|
1082
|
+
startDrag: (columnId, event) => {
|
|
1083
|
+
drag.startDrag(columnId, event.currentTarget, event);
|
|
1084
|
+
},
|
|
1085
|
+
justDragged: drag.justDragged
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// src/DataGrid/components/GroupByBar.tsx
|
|
1090
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1091
|
+
function GroupByBar({
|
|
1092
|
+
columns,
|
|
1093
|
+
grouping,
|
|
1094
|
+
columnName,
|
|
1095
|
+
headerDragEligible,
|
|
1096
|
+
headerDragBlocked,
|
|
1097
|
+
headerDropTarget
|
|
1098
|
+
}) {
|
|
1099
|
+
const { groupBy } = grouping;
|
|
1100
|
+
const groupByIds = groupBy.map((entry) => entry.columnId);
|
|
1101
|
+
const chipDrag = useGroupByDrag({
|
|
1102
|
+
groupBy,
|
|
1103
|
+
onDrop: (movedId, beforeColumnId) => {
|
|
1104
|
+
grouping.moveGroupBy(movedId, beforeColumnId);
|
|
801
1105
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
1106
|
+
});
|
|
1107
|
+
const activeDropTarget = chipDrag.dropTarget ?? headerDropTarget;
|
|
1108
|
+
const isDragTarget = chipDrag.draggedColumnId !== null || headerDragEligible;
|
|
1109
|
+
const showPlaceholder = groupBy.length === 0 && columns.some((entry) => entry.groupByDraggable);
|
|
1110
|
+
function labelFor(columnId) {
|
|
1111
|
+
return columns.find((entry) => entry.id === columnId)?.label ?? columnId;
|
|
806
1112
|
}
|
|
807
|
-
function moveByKeyboard(
|
|
808
|
-
const
|
|
809
|
-
|
|
1113
|
+
function moveByKeyboard(columnId, direction) {
|
|
1114
|
+
const beforeColumnId = resolveKeyboardDropTarget(
|
|
1115
|
+
groupByIds,
|
|
1116
|
+
columnId,
|
|
1117
|
+
direction
|
|
1118
|
+
);
|
|
1119
|
+
if (beforeColumnId === void 0) {
|
|
810
1120
|
return;
|
|
811
1121
|
}
|
|
812
|
-
|
|
813
|
-
|
|
1122
|
+
grouping.moveGroupBy(columnId, beforeColumnId);
|
|
1123
|
+
}
|
|
1124
|
+
return /* @__PURE__ */ jsxs3(
|
|
1125
|
+
"div",
|
|
1126
|
+
{
|
|
1127
|
+
className: classNames(
|
|
1128
|
+
"gridkit-group-by-bar",
|
|
1129
|
+
isDragTarget ? "is-drag-target" : "",
|
|
1130
|
+
headerDragBlocked ? "is-drag-blocked" : ""
|
|
1131
|
+
),
|
|
1132
|
+
"data-gridkit-group-by-bar": "",
|
|
1133
|
+
role: "group",
|
|
1134
|
+
"aria-label": "Grouped by",
|
|
1135
|
+
children: [
|
|
1136
|
+
showPlaceholder && /* @__PURE__ */ jsx5("span", { className: "group-by-bar-placeholder", children: "Drag a column here to group by it" }),
|
|
1137
|
+
groupBy.map((entry, index) => {
|
|
1138
|
+
const dropBefore = activeDropTarget?.beforeColumnId === entry.columnId;
|
|
1139
|
+
const dropAfter = activeDropTarget?.beforeColumnId === null && index === groupBy.length - 1;
|
|
1140
|
+
const dragging = chipDrag.draggedColumnId === entry.columnId;
|
|
1141
|
+
return /* @__PURE__ */ jsxs3(
|
|
1142
|
+
"span",
|
|
1143
|
+
{
|
|
1144
|
+
className: classNames(
|
|
1145
|
+
"group-by-chip",
|
|
1146
|
+
dragging ? "is-dragging" : "",
|
|
1147
|
+
dropBefore ? "is-drop-before" : "",
|
|
1148
|
+
dropAfter ? "is-drop-after" : ""
|
|
1149
|
+
),
|
|
1150
|
+
"data-gridkit-group-chip": entry.columnId,
|
|
1151
|
+
tabIndex: 0,
|
|
1152
|
+
"aria-label": groupBy.length > 1 ? `${columnName(entry.columnId)}, level ${String(index + 1)} of ${String(groupBy.length)}` : columnName(entry.columnId),
|
|
1153
|
+
"aria-keyshortcuts": "Control+ArrowLeft Control+ArrowRight",
|
|
1154
|
+
onPointerDown: (event) => {
|
|
1155
|
+
chipDrag.startDrag(entry.columnId, event);
|
|
1156
|
+
},
|
|
1157
|
+
onKeyDown: (event) => {
|
|
1158
|
+
const horizontal = event.key === "ArrowLeft" || event.key === "ArrowRight";
|
|
1159
|
+
if (horizontal && event.ctrlKey) {
|
|
1160
|
+
event.preventDefault();
|
|
1161
|
+
moveByKeyboard(
|
|
1162
|
+
entry.columnId,
|
|
1163
|
+
event.key === "ArrowLeft" ? -1 : 1
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
},
|
|
1167
|
+
children: [
|
|
1168
|
+
/* @__PURE__ */ jsx5("span", { className: "group-by-chip-label", children: labelFor(entry.columnId) }),
|
|
1169
|
+
/* @__PURE__ */ jsx5(
|
|
1170
|
+
"button",
|
|
1171
|
+
{
|
|
1172
|
+
type: "button",
|
|
1173
|
+
className: "group-by-chip-remove",
|
|
1174
|
+
"aria-label": `Stop grouping by ${columnName(entry.columnId)}`,
|
|
1175
|
+
onPointerDown: (event) => {
|
|
1176
|
+
event.stopPropagation();
|
|
1177
|
+
},
|
|
1178
|
+
onClick: () => {
|
|
1179
|
+
grouping.toggleGroupBy(entry.columnId);
|
|
1180
|
+
},
|
|
1181
|
+
children: "\xD7"
|
|
1182
|
+
}
|
|
1183
|
+
)
|
|
1184
|
+
]
|
|
1185
|
+
},
|
|
1186
|
+
entry.columnId
|
|
1187
|
+
);
|
|
1188
|
+
}),
|
|
1189
|
+
chipDrag.draggedColumnId !== null && chipDrag.ghostTransform !== null && createPortal2(
|
|
1190
|
+
/* @__PURE__ */ jsx5(
|
|
1191
|
+
"span",
|
|
1192
|
+
{
|
|
1193
|
+
className: "group-by-chip drag-ghost",
|
|
1194
|
+
style: { transform: chipDrag.ghostTransform },
|
|
1195
|
+
"aria-hidden": "true",
|
|
1196
|
+
children: labelFor(chipDrag.draggedColumnId)
|
|
1197
|
+
}
|
|
1198
|
+
),
|
|
1199
|
+
document.body
|
|
1200
|
+
)
|
|
1201
|
+
]
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
// src/DataGrid/useColumnDrag.ts
|
|
1207
|
+
import {
|
|
1208
|
+
movesColumn,
|
|
1209
|
+
resolveDropBefore as resolveDropBefore2,
|
|
1210
|
+
resolveKeyboardDropTarget as resolveKeyboardDropTarget2
|
|
1211
|
+
} from "@gridkitjs/core";
|
|
1212
|
+
function useColumnDrag({
|
|
1213
|
+
order,
|
|
1214
|
+
groupBy,
|
|
1215
|
+
groupByDraggableIds,
|
|
1216
|
+
onDrop
|
|
1217
|
+
}) {
|
|
1218
|
+
const drag = useDragReorder({
|
|
1219
|
+
resolveTarget(clientX, clientY, movedId) {
|
|
1220
|
+
const over = elementAt(clientX, clientY, "th[data-gridkit-column]");
|
|
1221
|
+
const overId = over?.getAttribute("data-gridkit-column");
|
|
1222
|
+
const beforeId = over && overId ? resolveDropBefore2(order, overId, sideOf(over, clientX)) : void 0;
|
|
1223
|
+
if (beforeId !== void 0) {
|
|
1224
|
+
return movesColumn(order, movedId, beforeId) ? { kind: "column-order", beforeId } : null;
|
|
1225
|
+
}
|
|
1226
|
+
const alreadyGrouped = groupBy.some(
|
|
1227
|
+
(entry) => entry.columnId === movedId
|
|
1228
|
+
);
|
|
1229
|
+
return groupByDraggableIds.has(movedId) && !alreadyGrouped ? resolveGroupByDropTarget(clientX, clientY, movedId, groupBy) : null;
|
|
1230
|
+
},
|
|
1231
|
+
onDrop
|
|
1232
|
+
});
|
|
1233
|
+
function startDrag(entry, event) {
|
|
1234
|
+
drag.startDrag(entry.id, event.currentTarget, event);
|
|
1235
|
+
}
|
|
1236
|
+
function moveByKeyboard(entry, direction) {
|
|
1237
|
+
const beforeId = resolveKeyboardDropTarget2(order, entry.id, direction);
|
|
1238
|
+
if (beforeId === void 0) {
|
|
814
1239
|
return;
|
|
815
1240
|
}
|
|
816
|
-
onDrop(
|
|
817
|
-
{ kind: "column-order", beforeId: order[targetIndex] ?? null },
|
|
818
|
-
entry.id
|
|
819
|
-
);
|
|
1241
|
+
onDrop({ kind: "column-order", beforeId }, entry.id);
|
|
820
1242
|
}
|
|
821
1243
|
return {
|
|
822
|
-
draggedColumnId,
|
|
823
|
-
dropTarget,
|
|
824
|
-
ghostTransform,
|
|
1244
|
+
draggedColumnId: drag.draggedId,
|
|
1245
|
+
dropTarget: drag.dropTarget,
|
|
1246
|
+
ghostTransform: drag.ghostTransform,
|
|
825
1247
|
startDrag,
|
|
826
1248
|
moveByKeyboard,
|
|
827
|
-
justDragged
|
|
1249
|
+
justDragged: drag.justDragged
|
|
828
1250
|
};
|
|
829
1251
|
}
|
|
830
1252
|
|
|
@@ -837,6 +1259,7 @@ import {
|
|
|
837
1259
|
beginColumnResize,
|
|
838
1260
|
clampColumnWidth,
|
|
839
1261
|
resolveColumnConstraints,
|
|
1262
|
+
revertColumnSize,
|
|
840
1263
|
sizeColumnToContent
|
|
841
1264
|
} from "@gridkitjs/core";
|
|
842
1265
|
|
|
@@ -885,57 +1308,39 @@ function useColumnResize({
|
|
|
885
1308
|
let width = session.startWidth;
|
|
886
1309
|
event.preventDefault();
|
|
887
1310
|
event.stopPropagation();
|
|
888
|
-
handle.setPointerCapture(pointerId);
|
|
889
1311
|
setActiveColumnId(session.columnId);
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
if (handle.hasPointerCapture(pointerId)) {
|
|
900
|
-
handle.releasePointerCapture(pointerId);
|
|
901
|
-
}
|
|
902
|
-
setActiveColumnId(null);
|
|
903
|
-
}
|
|
904
|
-
function end() {
|
|
905
|
-
stop();
|
|
906
|
-
if (width !== session.startWidth) {
|
|
907
|
-
commit(base, session.columnId, width, "end");
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
function cancel() {
|
|
911
|
-
stop();
|
|
912
|
-
setSizing((current) => {
|
|
913
|
-
const next = Object.fromEntries(
|
|
914
|
-
Object.entries(current).filter(
|
|
915
|
-
([columnId]) => columnId !== session.columnId
|
|
916
|
-
)
|
|
917
|
-
);
|
|
918
|
-
if (session.columnId in base) {
|
|
919
|
-
next[session.columnId] = base[session.columnId];
|
|
1312
|
+
startPointerGesture(handle, pointerId, {
|
|
1313
|
+
onMove(moveEvent) {
|
|
1314
|
+
width = applyColumnResize(session, moveEvent.clientX);
|
|
1315
|
+
commit(base, session.columnId, width, "move");
|
|
1316
|
+
},
|
|
1317
|
+
onEnd() {
|
|
1318
|
+
setActiveColumnId(null);
|
|
1319
|
+
if (width !== session.startWidth) {
|
|
1320
|
+
commit(base, session.columnId, width, "end");
|
|
920
1321
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
1322
|
+
},
|
|
1323
|
+
/**
|
|
1324
|
+
* Escape puts back only the dragged column's pre-drag width, merged
|
|
1325
|
+
* into whatever the sizing state is *now* — not the `base` snapshot
|
|
1326
|
+
* taken at drag-start — so a different column resized via keyboard
|
|
1327
|
+
* while this drag was still open keeps its change instead of being
|
|
1328
|
+
* clobbered by a stale restore.
|
|
1329
|
+
*/
|
|
1330
|
+
onCancel() {
|
|
1331
|
+
setActiveColumnId(null);
|
|
1332
|
+
setSizing((current) => {
|
|
1333
|
+
const next = revertColumnSize(current, base, session.columnId);
|
|
1334
|
+
onColumnResize?.({
|
|
1335
|
+
columnId: session.columnId,
|
|
1336
|
+
width: session.startWidth,
|
|
1337
|
+
sizing: next,
|
|
1338
|
+
phase: "end"
|
|
1339
|
+
});
|
|
1340
|
+
return next;
|
|
926
1341
|
});
|
|
927
|
-
return next;
|
|
928
|
-
});
|
|
929
|
-
}
|
|
930
|
-
function onKeyDown(keyEvent) {
|
|
931
|
-
if (keyEvent.key === "Escape") {
|
|
932
|
-
cancel();
|
|
933
1342
|
}
|
|
934
|
-
}
|
|
935
|
-
handle.addEventListener("pointermove", move);
|
|
936
|
-
handle.addEventListener("pointerup", end);
|
|
937
|
-
handle.addEventListener("pointercancel", cancel);
|
|
938
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1343
|
+
});
|
|
939
1344
|
}
|
|
940
1345
|
function sizeToContent(entry) {
|
|
941
1346
|
const table = tableRef.current;
|
|
@@ -983,11 +1388,9 @@ function useColumnSort({
|
|
|
983
1388
|
}) {
|
|
984
1389
|
function toggle(entry, event) {
|
|
985
1390
|
const next = toggleColumnSort(sort, entry.id, { stack: event.shiftKey });
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
}
|
|
989
|
-
setSort(next);
|
|
990
|
-
onColumnSortChange?.({ columnId: entry.id, sort: next });
|
|
1391
|
+
commitIfChanged(sort, next, setSort, (committed) => {
|
|
1392
|
+
onColumnSortChange?.({ columnId: entry.id, sort: committed });
|
|
1393
|
+
});
|
|
991
1394
|
}
|
|
992
1395
|
return {
|
|
993
1396
|
sort,
|
|
@@ -1018,8 +1421,62 @@ function useElementWidth(ref, enabled) {
|
|
|
1018
1421
|
return width;
|
|
1019
1422
|
}
|
|
1020
1423
|
|
|
1424
|
+
// src/DataGrid/useRowGrouping.ts
|
|
1425
|
+
import {
|
|
1426
|
+
collapseAllGroups,
|
|
1427
|
+
expandAllGroups,
|
|
1428
|
+
moveGroupByBefore,
|
|
1429
|
+
toggleGroupExpansion
|
|
1430
|
+
} from "@gridkitjs/core";
|
|
1431
|
+
function useRowGrouping({
|
|
1432
|
+
groupBy,
|
|
1433
|
+
setGroupBy,
|
|
1434
|
+
expansion,
|
|
1435
|
+
setExpansion,
|
|
1436
|
+
onGroupByChange,
|
|
1437
|
+
onGroupExpansionChange
|
|
1438
|
+
}) {
|
|
1439
|
+
function commitExpansion(next, groupId) {
|
|
1440
|
+
commitIfChanged(expansion, next, setExpansion, (committed) => {
|
|
1441
|
+
onGroupExpansionChange?.({ groupId, expansion: committed });
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
function commitGroupBy(next, columnId) {
|
|
1445
|
+
commitIfChanged(groupBy, next, setGroupBy, (committed) => {
|
|
1446
|
+
onGroupByChange?.({ columnId, groupBy: committed });
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
function toggleGroupBy(columnId) {
|
|
1450
|
+
const isGrouped = groupBy.some((entry) => entry.columnId === columnId);
|
|
1451
|
+
const next = isGrouped ? groupBy.filter((entry) => entry.columnId !== columnId) : [...groupBy, { columnId }];
|
|
1452
|
+
commitGroupBy(next, columnId);
|
|
1453
|
+
}
|
|
1454
|
+
function moveGroupBy(columnId, beforeColumnId) {
|
|
1455
|
+
commitGroupBy(
|
|
1456
|
+
moveGroupByBefore(groupBy, columnId, beforeColumnId),
|
|
1457
|
+
columnId
|
|
1458
|
+
);
|
|
1459
|
+
}
|
|
1460
|
+
return {
|
|
1461
|
+
groupBy,
|
|
1462
|
+
expansion,
|
|
1463
|
+
isExpanded: (groupId) => !expansion.includes(groupId),
|
|
1464
|
+
toggleExpansion: (groupId) => {
|
|
1465
|
+
commitExpansion(toggleGroupExpansion(expansion, groupId), groupId);
|
|
1466
|
+
},
|
|
1467
|
+
expandAll: () => {
|
|
1468
|
+
commitExpansion(expandAllGroups(expansion), null);
|
|
1469
|
+
},
|
|
1470
|
+
collapseAll: (rows) => {
|
|
1471
|
+
commitExpansion(collapseAllGroups(rows), null);
|
|
1472
|
+
},
|
|
1473
|
+
toggleGroupBy,
|
|
1474
|
+
moveGroupBy
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1021
1478
|
// src/DataGrid/DataGrid.tsx
|
|
1022
|
-
import { jsx as
|
|
1479
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1023
1480
|
function DataGridComponent({
|
|
1024
1481
|
dataSource,
|
|
1025
1482
|
columns,
|
|
@@ -1041,9 +1498,18 @@ function DataGridComponent({
|
|
|
1041
1498
|
sortableColumns = false,
|
|
1042
1499
|
defaultColumnSort,
|
|
1043
1500
|
onColumnSortChange,
|
|
1501
|
+
groupableColumns = false,
|
|
1502
|
+
groupToggleIconColumns = true,
|
|
1503
|
+
groupByDraggableColumns = false,
|
|
1504
|
+
groupByBarVisibility = "auto",
|
|
1505
|
+
defaultGroupBy,
|
|
1506
|
+
onGroupByChange,
|
|
1507
|
+
defaultGroupExpansion,
|
|
1508
|
+
onGroupExpansionChange,
|
|
1044
1509
|
defaultFilter,
|
|
1045
1510
|
label,
|
|
1046
1511
|
labelledBy,
|
|
1512
|
+
ref,
|
|
1047
1513
|
...callbacks
|
|
1048
1514
|
}) {
|
|
1049
1515
|
const hoverRows = hoverable?.rows ?? true;
|
|
@@ -1059,6 +1525,10 @@ function DataGridComponent({
|
|
|
1059
1525
|
defaultColumnOrder ?? []
|
|
1060
1526
|
);
|
|
1061
1527
|
const [sort, setSort] = useState5(defaultColumnSort ?? []);
|
|
1528
|
+
const [groupBy, setGroupBy] = useState5(defaultGroupBy ?? []);
|
|
1529
|
+
const [expansion, setExpansion] = useState5(
|
|
1530
|
+
defaultGroupExpansion ?? []
|
|
1531
|
+
);
|
|
1062
1532
|
const [filter] = useState5(defaultFilter ?? []);
|
|
1063
1533
|
const [announcement, setAnnouncement] = useState5("");
|
|
1064
1534
|
const [rowSelection, setRowSelection] = useState5(
|
|
@@ -1070,7 +1540,7 @@ function DataGridComponent({
|
|
|
1070
1540
|
const [cellSelection, setCellSelection] = useState5(
|
|
1071
1541
|
defaultCellSelection ?? null
|
|
1072
1542
|
);
|
|
1073
|
-
const rows =
|
|
1543
|
+
const rows = useMemo3(
|
|
1074
1544
|
() => dataSource?.map((row, rowIndex) => ({
|
|
1075
1545
|
rowId: resolveRowId(row, rowIndex, getRowId),
|
|
1076
1546
|
row,
|
|
@@ -1078,21 +1548,22 @@ function DataGridComponent({
|
|
|
1078
1548
|
})) ?? [],
|
|
1079
1549
|
[dataSource, getRowId]
|
|
1080
1550
|
);
|
|
1081
|
-
const definedColumns =
|
|
1551
|
+
const definedColumns = useMemo3(() => {
|
|
1082
1552
|
if (columns && columns.length !== 0) return columns;
|
|
1083
1553
|
if (dataSource && dataSource.length > 0)
|
|
1084
1554
|
return defineColumnsFromRows(dataSource);
|
|
1085
1555
|
return [];
|
|
1086
1556
|
}, [columns, dataSource]);
|
|
1087
|
-
const orderedColumns =
|
|
1557
|
+
const orderedColumns = useMemo3(
|
|
1088
1558
|
() => applyColumnOrder(definedColumns, order),
|
|
1089
1559
|
[definedColumns, order]
|
|
1090
1560
|
);
|
|
1091
|
-
const resolved =
|
|
1561
|
+
const resolved = useMemo3(() => {
|
|
1092
1562
|
const widths = resolveColumnWidths(orderedColumns, sizing, {
|
|
1093
1563
|
sizes: columnSizeDefaults,
|
|
1094
1564
|
resizable: resizableColumns,
|
|
1095
|
-
reorderable: reorderableColumns
|
|
1565
|
+
reorderable: reorderableColumns,
|
|
1566
|
+
groupByDraggable: groupByDraggableColumns
|
|
1096
1567
|
});
|
|
1097
1568
|
return resizeMode === "fit" && viewportWidth !== null ? fitColumnsToWidth(widths, viewportWidth, columnSizeDefaults) : widths;
|
|
1098
1569
|
}, [
|
|
@@ -1102,12 +1573,23 @@ function DataGridComponent({
|
|
|
1102
1573
|
viewportWidth,
|
|
1103
1574
|
columnSizeDefaults,
|
|
1104
1575
|
resizableColumns,
|
|
1105
|
-
reorderableColumns
|
|
1576
|
+
reorderableColumns,
|
|
1577
|
+
groupByDraggableColumns
|
|
1106
1578
|
]);
|
|
1107
|
-
const shownRows =
|
|
1579
|
+
const shownRows = useMemo3(
|
|
1108
1580
|
() => resolveShownRows(rows, filter, sort, resolved),
|
|
1109
1581
|
[rows, filter, sort, resolved]
|
|
1110
1582
|
);
|
|
1583
|
+
const displayRows = useMemo3(
|
|
1584
|
+
() => groupRows(shownRows, groupBy, expansion, resolved),
|
|
1585
|
+
[shownRows, groupBy, expansion, resolved]
|
|
1586
|
+
);
|
|
1587
|
+
const displayDataRows = useMemo3(
|
|
1588
|
+
() => groupBy.length === 0 ? shownRows : displayRows.filter(
|
|
1589
|
+
(entry) => !("kind" in entry)
|
|
1590
|
+
),
|
|
1591
|
+
[displayRows, groupBy.length, shownRows]
|
|
1592
|
+
);
|
|
1111
1593
|
function columnName(columnId) {
|
|
1112
1594
|
const entry = resolved.find((candidate) => candidate.id === columnId);
|
|
1113
1595
|
if (entry === void 0) {
|
|
@@ -1133,16 +1615,62 @@ function DataGridComponent({
|
|
|
1133
1615
|
columnSizeDefaults,
|
|
1134
1616
|
onColumnResize: handleColumnResize
|
|
1135
1617
|
});
|
|
1618
|
+
function handleGroupByChange(event) {
|
|
1619
|
+
onGroupByChange?.(event);
|
|
1620
|
+
const entry = event.groupBy.find(
|
|
1621
|
+
(candidate) => candidate.columnId === event.columnId
|
|
1622
|
+
);
|
|
1623
|
+
if (entry === void 0) {
|
|
1624
|
+
announce(`${columnName(event.columnId)}, grouping removed`);
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1627
|
+
announce(
|
|
1628
|
+
event.groupBy.length > 1 ? `Grouped by ${columnName(event.columnId)}, level ${String(event.groupBy.indexOf(entry) + 1)} of ${String(event.groupBy.length)}` : `Grouped by ${columnName(event.columnId)}`
|
|
1629
|
+
);
|
|
1630
|
+
}
|
|
1631
|
+
function handleGroupExpansionChange(event) {
|
|
1632
|
+
onGroupExpansionChange?.(event);
|
|
1633
|
+
if (event.groupId === null) {
|
|
1634
|
+
announce(
|
|
1635
|
+
event.expansion.length === 0 ? "All groups expanded" : "All groups collapsed"
|
|
1636
|
+
);
|
|
1637
|
+
return;
|
|
1638
|
+
}
|
|
1639
|
+
announce(
|
|
1640
|
+
event.expansion.includes(event.groupId) ? "Group collapsed" : "Group expanded"
|
|
1641
|
+
);
|
|
1642
|
+
}
|
|
1643
|
+
const grouping = useRowGrouping({
|
|
1644
|
+
groupBy,
|
|
1645
|
+
setGroupBy,
|
|
1646
|
+
expansion,
|
|
1647
|
+
setExpansion,
|
|
1648
|
+
onGroupByChange: handleGroupByChange,
|
|
1649
|
+
onGroupExpansionChange: handleGroupExpansionChange
|
|
1650
|
+
});
|
|
1136
1651
|
const nav = useGridNavigation({
|
|
1137
1652
|
tableRef,
|
|
1138
|
-
|
|
1653
|
+
// Group headers are addressable rows too — the whole point of the flat
|
|
1654
|
+
// `DisplayRow[]` shape is that they share one position space with data
|
|
1655
|
+
// rows, so navigation counts them the same way.
|
|
1656
|
+
rowCount: displayRows.length,
|
|
1139
1657
|
columnCount: resolved.length
|
|
1140
1658
|
});
|
|
1141
|
-
const displayedIds =
|
|
1659
|
+
const displayedIds = useMemo3(
|
|
1142
1660
|
() => orderedColumns.map((column) => column.id ?? column.field),
|
|
1143
1661
|
[orderedColumns]
|
|
1144
1662
|
);
|
|
1663
|
+
const groupByDraggableIds = useMemo3(
|
|
1664
|
+
() => new Set(
|
|
1665
|
+
resolved.filter((entry) => entry.groupByDraggable).map((entry) => entry.id)
|
|
1666
|
+
),
|
|
1667
|
+
[resolved]
|
|
1668
|
+
);
|
|
1145
1669
|
function handleDrop(target, movedId) {
|
|
1670
|
+
if (target.kind === "group-by") {
|
|
1671
|
+
grouping.moveGroupBy(movedId, target.beforeColumnId);
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1146
1674
|
const next = moveColumnBefore(displayedIds, movedId, target.beforeId);
|
|
1147
1675
|
if (next === displayedIds) {
|
|
1148
1676
|
return;
|
|
@@ -1155,7 +1683,16 @@ function DataGridComponent({
|
|
|
1155
1683
|
);
|
|
1156
1684
|
nav.focusCell(HEADER_ROW, position);
|
|
1157
1685
|
}
|
|
1158
|
-
const drag = useColumnDrag({
|
|
1686
|
+
const drag = useColumnDrag({
|
|
1687
|
+
order: displayedIds,
|
|
1688
|
+
groupBy,
|
|
1689
|
+
groupByDraggableIds,
|
|
1690
|
+
onDrop: handleDrop
|
|
1691
|
+
});
|
|
1692
|
+
const draggedColumnAlreadyGrouped = drag.draggedColumnId !== null && groupBy.some((entry) => entry.columnId === drag.draggedColumnId);
|
|
1693
|
+
const dragEligibleForGroupBy = drag.draggedColumnId !== null && groupByDraggableIds.has(drag.draggedColumnId) && !draggedColumnAlreadyGrouped;
|
|
1694
|
+
const showGroupByBar = groupByBarVisibility === "always" || groupByBarVisibility === "auto" && (groupBy.length > 0 || dragEligibleForGroupBy);
|
|
1695
|
+
const headerGroupByDropTarget = drag.dropTarget?.kind === "group-by" ? drag.dropTarget : null;
|
|
1159
1696
|
function handleColumnSortChange(event) {
|
|
1160
1697
|
onColumnSortChange?.(event);
|
|
1161
1698
|
const entry = event.sort.find(
|
|
@@ -1176,7 +1713,7 @@ function DataGridComponent({
|
|
|
1176
1713
|
onColumnSortChange: handleColumnSortChange
|
|
1177
1714
|
});
|
|
1178
1715
|
const selection = useGridSelection({
|
|
1179
|
-
rows:
|
|
1716
|
+
rows: displayDataRows,
|
|
1180
1717
|
columns: resolved,
|
|
1181
1718
|
selectable,
|
|
1182
1719
|
rowSelection,
|
|
@@ -1186,20 +1723,77 @@ function DataGridComponent({
|
|
|
1186
1723
|
cellSelection,
|
|
1187
1724
|
setCellSelection,
|
|
1188
1725
|
callbacks,
|
|
1189
|
-
announce
|
|
1726
|
+
announce,
|
|
1727
|
+
columnName
|
|
1190
1728
|
});
|
|
1191
1729
|
const multiselectable = selection.rowMode === "multiple" || selection.columnMode === "multiple";
|
|
1192
|
-
|
|
1193
|
-
|
|
1730
|
+
useImperativeHandle(ref, () => ({
|
|
1731
|
+
get element() {
|
|
1732
|
+
return viewportRef.current;
|
|
1733
|
+
},
|
|
1734
|
+
get table() {
|
|
1735
|
+
return tableRef.current;
|
|
1736
|
+
},
|
|
1737
|
+
getRows: () => shownRows,
|
|
1738
|
+
getDisplayRows: () => displayRows,
|
|
1739
|
+
getColumns: () => resolved,
|
|
1740
|
+
getColumnSizing: () => sizing,
|
|
1741
|
+
getColumnOrder: () => order,
|
|
1742
|
+
getColumnSort: () => sort,
|
|
1743
|
+
getGroupBy: () => groupBy,
|
|
1744
|
+
getGroupExpansion: () => expansion,
|
|
1745
|
+
getRowSelection: () => rowSelection,
|
|
1746
|
+
getColumnSelection: () => columnSelection,
|
|
1747
|
+
getCellSelection: () => cellSelection,
|
|
1748
|
+
getFocusedCell: () => nav.focus,
|
|
1749
|
+
focusCell: nav.focusCell,
|
|
1750
|
+
clearSelection: selection.clear,
|
|
1751
|
+
selectAllRows: selection.selectAllRows,
|
|
1752
|
+
expandAllGroups: grouping.expandAll,
|
|
1753
|
+
collapseAllGroups: () => {
|
|
1754
|
+
grouping.collapseAll(displayRows);
|
|
1755
|
+
},
|
|
1756
|
+
scrollToRow: (rowId, options) => {
|
|
1757
|
+
const index = displayRows.findIndex(
|
|
1758
|
+
(entry) => !("kind" in entry) && entry.rowId === rowId
|
|
1759
|
+
);
|
|
1760
|
+
if (index === -1) return;
|
|
1761
|
+
tableRef.current?.tBodies[0]?.rows[index]?.scrollIntoView(options);
|
|
1762
|
+
},
|
|
1763
|
+
scrollToColumn: (columnId, options) => {
|
|
1764
|
+
const cells = tableRef.current?.querySelectorAll("[data-gridkit-column]");
|
|
1765
|
+
const cell = cells ? Array.from(cells).find(
|
|
1766
|
+
(entry) => entry.getAttribute("data-gridkit-column") === columnId
|
|
1767
|
+
) : void 0;
|
|
1768
|
+
cell?.scrollIntoView(options);
|
|
1769
|
+
}
|
|
1770
|
+
}));
|
|
1771
|
+
return /* @__PURE__ */ jsxs4("div", { className: "gridkit-data-grid-viewport", ref: viewportRef, children: [
|
|
1772
|
+
showGroupByBar && /* @__PURE__ */ jsx6(
|
|
1773
|
+
GroupByBar,
|
|
1774
|
+
{
|
|
1775
|
+
columns: resolved,
|
|
1776
|
+
grouping,
|
|
1777
|
+
columnName,
|
|
1778
|
+
headerDragEligible: dragEligibleForGroupBy,
|
|
1779
|
+
headerDragBlocked: draggedColumnAlreadyGrouped,
|
|
1780
|
+
headerDropTarget: headerGroupByDropTarget
|
|
1781
|
+
}
|
|
1782
|
+
),
|
|
1783
|
+
/* @__PURE__ */ jsxs4(
|
|
1194
1784
|
"table",
|
|
1195
1785
|
{
|
|
1196
1786
|
ref: tableRef,
|
|
1197
|
-
role: "grid",
|
|
1198
|
-
"aria-rowcount":
|
|
1787
|
+
role: groupBy.length > 0 ? "treegrid" : "grid",
|
|
1788
|
+
"aria-rowcount": displayRows.length + 1,
|
|
1199
1789
|
"aria-colcount": resolved.length,
|
|
1200
|
-
...multiselectable
|
|
1201
|
-
...labelledBy !== void 0
|
|
1202
|
-
...
|
|
1790
|
+
...ariaAttr(multiselectable, "aria-multiselectable", true),
|
|
1791
|
+
...ariaAttr(labelledBy !== void 0, "aria-labelledby", labelledBy),
|
|
1792
|
+
...ariaAttr(
|
|
1793
|
+
labelledBy === void 0 && label !== void 0,
|
|
1794
|
+
"aria-label",
|
|
1795
|
+
label
|
|
1796
|
+
),
|
|
1203
1797
|
onKeyDown: (event) => {
|
|
1204
1798
|
if (event.key === "Escape") {
|
|
1205
1799
|
if (drag.draggedColumnId !== null || resize.activeColumnId !== null)
|
|
@@ -1214,7 +1808,7 @@ function DataGridComponent({
|
|
|
1214
1808
|
}
|
|
1215
1809
|
},
|
|
1216
1810
|
style: { width: totalColumnWidth(resolved) },
|
|
1217
|
-
className:
|
|
1811
|
+
className: classNames(
|
|
1218
1812
|
"gridkit-data-grid",
|
|
1219
1813
|
borders ? `borders-${borders}` : "",
|
|
1220
1814
|
// Hover is on by default and selection off, so one set of classes
|
|
@@ -1226,10 +1820,10 @@ function DataGridComponent({
|
|
|
1226
1820
|
selection.rowMode === false ? "" : "selectable-rows",
|
|
1227
1821
|
selection.columnMode === false ? "" : "selectable-columns",
|
|
1228
1822
|
selection.cellMode === false ? "" : "selectable-cells"
|
|
1229
|
-
|
|
1823
|
+
),
|
|
1230
1824
|
children: [
|
|
1231
|
-
/* @__PURE__ */
|
|
1232
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsx6("colgroup", { children: resolved.map((entry) => /* @__PURE__ */ jsx6("col", { style: { width: entry.width } }, entry.id)) }),
|
|
1826
|
+
/* @__PURE__ */ jsx6(
|
|
1233
1827
|
GridHeader,
|
|
1234
1828
|
{
|
|
1235
1829
|
columns: resolved,
|
|
@@ -1237,24 +1831,28 @@ function DataGridComponent({
|
|
|
1237
1831
|
drag,
|
|
1238
1832
|
sort: columnSort,
|
|
1239
1833
|
sortableColumns,
|
|
1834
|
+
grouping,
|
|
1835
|
+
groupableColumns,
|
|
1836
|
+
groupToggleIconColumns,
|
|
1240
1837
|
nav,
|
|
1241
1838
|
selection
|
|
1242
1839
|
}
|
|
1243
1840
|
),
|
|
1244
|
-
/* @__PURE__ */
|
|
1841
|
+
/* @__PURE__ */ jsx6(
|
|
1245
1842
|
GridBody,
|
|
1246
1843
|
{
|
|
1247
1844
|
columns: resolved,
|
|
1248
|
-
rows:
|
|
1845
|
+
rows: displayRows,
|
|
1249
1846
|
activeColumnId: resize.activeColumnId,
|
|
1250
1847
|
nav,
|
|
1251
|
-
selection
|
|
1848
|
+
selection,
|
|
1849
|
+
grouping
|
|
1252
1850
|
}
|
|
1253
1851
|
)
|
|
1254
1852
|
]
|
|
1255
1853
|
}
|
|
1256
1854
|
),
|
|
1257
|
-
/* @__PURE__ */
|
|
1855
|
+
/* @__PURE__ */ jsx6("div", { className: "gridkit-sr-only", role: "status", "aria-live": "polite", children: announcement })
|
|
1258
1856
|
] });
|
|
1259
1857
|
}
|
|
1260
1858
|
export {
|