@gridkitjs/react 0.9.0 → 0.11.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/README.md +8 -3
- package/dist/index.d.ts +196 -281
- package/dist/index.js +2439 -1588
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
// src/DataGrid/DataGrid.tsx
|
|
2
4
|
import {
|
|
3
|
-
useEffect as
|
|
5
|
+
useEffect as useEffect5,
|
|
6
|
+
useId,
|
|
4
7
|
useImperativeHandle,
|
|
5
8
|
useMemo as useMemo4,
|
|
6
|
-
useRef as
|
|
7
|
-
useState as
|
|
9
|
+
useRef as useRef13,
|
|
10
|
+
useState as useState15
|
|
8
11
|
} from "react";
|
|
9
12
|
import {
|
|
10
|
-
applyColumnOrder,
|
|
11
|
-
computeAggregates,
|
|
12
|
-
defineColumnsFromRows,
|
|
13
|
-
fitColumnsToWidth,
|
|
14
|
-
groupRows,
|
|
15
13
|
moveColumnBefore,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
totalColumnWidth,
|
|
21
|
-
withGroupAggregates
|
|
14
|
+
resolveColumnHeaderText,
|
|
15
|
+
resolveMessages,
|
|
16
|
+
resolveRows,
|
|
17
|
+
totalColumnWidth
|
|
22
18
|
} from "@gridkitjs/core";
|
|
23
19
|
|
|
24
20
|
// src/DataGrid/components/GridColgroup.tsx
|
|
@@ -29,7 +25,13 @@ function GridColgroup({ columns }) {
|
|
|
29
25
|
|
|
30
26
|
// src/DataGrid/components/GridHeader.tsx
|
|
31
27
|
import { createPortal } from "react-dom";
|
|
32
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
buildKeyShortcuts,
|
|
30
|
+
intentOf,
|
|
31
|
+
KEYBOARD_STEP,
|
|
32
|
+
sortDirectionFor,
|
|
33
|
+
sortPriorityFor
|
|
34
|
+
} from "@gridkitjs/core";
|
|
33
35
|
|
|
34
36
|
// src/DataGrid/ariaAttr.ts
|
|
35
37
|
function ariaAttr(condition, key, value) {
|
|
@@ -41,30 +43,61 @@ function classNames(...values) {
|
|
|
41
43
|
return values.filter(Boolean).join(" ");
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
// src/DataGrid/icons.tsx
|
|
47
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
48
|
+
function Icon({ children }) {
|
|
49
|
+
return /* @__PURE__ */ jsx2(
|
|
50
|
+
"svg",
|
|
51
|
+
{
|
|
52
|
+
viewBox: "0 0 24 24",
|
|
53
|
+
fill: "none",
|
|
54
|
+
stroke: "currentColor",
|
|
55
|
+
strokeWidth: 2,
|
|
56
|
+
strokeLinecap: "round",
|
|
57
|
+
strokeLinejoin: "round",
|
|
58
|
+
"aria-hidden": "true",
|
|
59
|
+
children
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function ChevronsUpDownIcon() {
|
|
64
|
+
return /* @__PURE__ */ jsxs(Icon, { children: [
|
|
65
|
+
/* @__PURE__ */ jsx2("path", { d: "m7 15 5 5 5-5" }),
|
|
66
|
+
/* @__PURE__ */ jsx2("path", { d: "m7 9 5-5 5 5" })
|
|
67
|
+
] });
|
|
68
|
+
}
|
|
69
|
+
function ChevronUpIcon() {
|
|
70
|
+
return /* @__PURE__ */ jsx2(Icon, { children: /* @__PURE__ */ jsx2("path", { d: "m18 15-6-6-6 6" }) });
|
|
71
|
+
}
|
|
72
|
+
function GroupIcon() {
|
|
73
|
+
return /* @__PURE__ */ jsxs(Icon, { children: [
|
|
74
|
+
/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
75
|
+
/* @__PURE__ */ jsx2("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1" }),
|
|
76
|
+
/* @__PURE__ */ jsx2("rect", { x: "8.5", y: "14", width: "7", height: "7", rx: "1" })
|
|
77
|
+
] });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/DataGrid/isOwnEvent.ts
|
|
81
|
+
function isOwnEvent(event) {
|
|
82
|
+
return event.target instanceof Node && event.currentTarget.contains(event.target);
|
|
83
|
+
}
|
|
84
|
+
|
|
44
85
|
// src/DataGrid/useGridNavigation.ts
|
|
45
86
|
import {
|
|
46
87
|
useEffect,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
88
|
+
useLayoutEffect,
|
|
89
|
+
useState,
|
|
90
|
+
useSyncExternalStore
|
|
50
91
|
} from "react";
|
|
92
|
+
import { HEADER_ROW } from "@gridkitjs/core";
|
|
51
93
|
import {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
} from "@gridkitjs/
|
|
56
|
-
var FALLBACK_PAGE = 10;
|
|
94
|
+
createGridFocus,
|
|
95
|
+
findBodyRow,
|
|
96
|
+
measurePageSize
|
|
97
|
+
} from "@gridkitjs/dom";
|
|
57
98
|
function tabIndexFor(columnIndex, focusedColumnIndex) {
|
|
58
99
|
return columnIndex === focusedColumnIndex ? 0 : -1;
|
|
59
100
|
}
|
|
60
|
-
function cellAt(headerTable, bodyTable, focus) {
|
|
61
|
-
const row = focus.rowIndex === HEADER_ROW ? headerTable?.tHead?.rows[0] ?? null : bodyTable?.tBodies[0]?.rows[focus.rowIndex] ?? null;
|
|
62
|
-
if (row === null) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
const columnIndex = Math.min(focus.columnIndex, row.cells.length - 1);
|
|
66
|
-
return row.cells[columnIndex] ?? null;
|
|
67
|
-
}
|
|
68
101
|
function useGridNavigation({
|
|
69
102
|
headerTableRef,
|
|
70
103
|
bodyTableRef,
|
|
@@ -73,120 +106,52 @@ function useGridNavigation({
|
|
|
73
106
|
isSkippableRow,
|
|
74
107
|
virtualRange
|
|
75
108
|
}) {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const focus = useMemo(
|
|
81
|
-
() => clampFocus(stored, rowCount, columnCount),
|
|
82
|
-
[stored, rowCount, columnCount]
|
|
83
|
-
);
|
|
84
|
-
const pending = useRef(false);
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
if (!pending.current) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const cell = cellAt(headerTableRef.current, bodyTableRef.current, {
|
|
90
|
-
rowIndex: focus.rowIndex,
|
|
91
|
-
columnIndex: focus.columnIndex
|
|
92
|
-
});
|
|
93
|
-
if (cell !== null) {
|
|
94
|
-
pending.current = false;
|
|
95
|
-
cell.focus();
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
if (virtualRange != null && focus.rowIndex !== HEADER_ROW && (focus.rowIndex < virtualRange.startIndex || focus.rowIndex > virtualRange.endIndex)) {
|
|
99
|
-
virtualRange.scrollToIndex(focus.rowIndex);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
pending.current = false;
|
|
103
|
-
}, [
|
|
104
|
-
headerTableRef,
|
|
105
|
-
bodyTableRef,
|
|
106
|
-
focus.rowIndex,
|
|
107
|
-
focus.columnIndex,
|
|
109
|
+
const options = {
|
|
110
|
+
rowCount,
|
|
111
|
+
columnCount,
|
|
112
|
+
isSkippableRow,
|
|
108
113
|
virtualRange
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
function focusCell(rowIndex, columnIndex) {
|
|
123
|
-
const next = clampFocus({ rowIndex, columnIndex }, rowCount, columnCount);
|
|
124
|
-
if (next.rowIndex === focus.rowIndex && next.columnIndex === focus.columnIndex) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
pending.current = true;
|
|
128
|
-
setStored(next);
|
|
129
|
-
}
|
|
130
|
-
function onKeyDown(event) {
|
|
131
|
-
const next = nextFocusForKey(
|
|
132
|
-
event.key,
|
|
133
|
-
{
|
|
134
|
-
ctrlKey: event.ctrlKey,
|
|
135
|
-
metaKey: event.metaKey,
|
|
136
|
-
altKey: event.altKey,
|
|
137
|
-
shiftKey: event.shiftKey
|
|
138
|
-
},
|
|
139
|
-
focus,
|
|
140
|
-
rowCount,
|
|
141
|
-
columnCount,
|
|
142
|
-
pageSize(),
|
|
143
|
-
isSkippableRow
|
|
144
|
-
);
|
|
145
|
-
if (next === null) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
event.preventDefault();
|
|
149
|
-
focusCell(next.rowIndex, next.columnIndex);
|
|
150
|
-
}
|
|
114
|
+
};
|
|
115
|
+
const [gridFocus] = useState(() => createGridFocus(options));
|
|
116
|
+
gridFocus.setOptions(options);
|
|
117
|
+
const focus = useSyncExternalStore(gridFocus.subscribe, gridFocus.getFocus);
|
|
118
|
+
const [rows] = useState(() => ({
|
|
119
|
+
getHeaderRow: () => headerTableRef.current?.tHead?.rows[0] ?? null,
|
|
120
|
+
getBodyRow: (rowIndex) => findBodyRow(bodyTableRef.current, rowIndex)
|
|
121
|
+
}));
|
|
122
|
+
useLayoutEffect(() => gridFocus.attach(rows), [gridFocus, rows]);
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
gridFocus.focusDrawnCell(focus);
|
|
125
|
+
});
|
|
151
126
|
return {
|
|
152
127
|
focus,
|
|
153
128
|
tabIndexFor: (rowIndex, columnIndex) => tabIndexFor(
|
|
154
129
|
columnIndex,
|
|
155
130
|
rowIndex === focus.rowIndex ? focus.columnIndex : null
|
|
156
131
|
),
|
|
157
|
-
focusCell,
|
|
158
|
-
|
|
132
|
+
focusCell: gridFocus.focusCell,
|
|
133
|
+
focusCellNow: (rowIndex, columnIndex) => {
|
|
134
|
+
gridFocus.focusCell(rowIndex, columnIndex);
|
|
135
|
+
gridFocus.focusDrawnCell(gridFocus.getFocus());
|
|
136
|
+
},
|
|
137
|
+
focusTabStop: () => {
|
|
138
|
+
const cells = (focus.rowIndex === HEADER_ROW ? rows.getHeaderRow() : rows.getBodyRow(focus.rowIndex))?.cells;
|
|
139
|
+
cells?.[Math.min(focus.columnIndex, cells.length - 1)]?.focus();
|
|
140
|
+
},
|
|
141
|
+
onKeyDown: (event) => {
|
|
142
|
+
if (gridFocus.handleKey(
|
|
143
|
+
event.key,
|
|
144
|
+
event,
|
|
145
|
+
measurePageSize(bodyTableRef.current)
|
|
146
|
+
)) {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
159
150
|
};
|
|
160
151
|
}
|
|
161
152
|
|
|
162
153
|
// src/DataGrid/useGridSelection.ts
|
|
163
|
-
import {
|
|
164
|
-
useMemo as useMemo2,
|
|
165
|
-
useRef as useRef2
|
|
166
|
-
} from "react";
|
|
167
|
-
import {
|
|
168
|
-
applySelectionIntent,
|
|
169
|
-
clearSelection,
|
|
170
|
-
diffSelection,
|
|
171
|
-
resolveCell,
|
|
172
|
-
resolveColumns,
|
|
173
|
-
resolveRows,
|
|
174
|
-
selectAll,
|
|
175
|
-
selectCell,
|
|
176
|
-
toggleCellSelection
|
|
177
|
-
} from "@gridkitjs/core";
|
|
178
|
-
|
|
179
|
-
// src/DataGrid/commitIfChanged.ts
|
|
180
|
-
function commitIfChanged(current, next, setState, onCommit) {
|
|
181
|
-
if (next === current) {
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
setState(next);
|
|
185
|
-
onCommit?.(next);
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// src/DataGrid/useGridSelection.ts
|
|
154
|
+
import { useMemo } from "react";
|
|
190
155
|
function keyboardSelectIntent(event) {
|
|
191
156
|
return {
|
|
192
157
|
ctrlKey: event.key === " " || event.ctrlKey,
|
|
@@ -194,238 +159,55 @@ function keyboardSelectIntent(event) {
|
|
|
194
159
|
shiftKey: event.shiftKey
|
|
195
160
|
};
|
|
196
161
|
}
|
|
197
|
-
function countMessage(count, noun) {
|
|
198
|
-
if (count === 0) {
|
|
199
|
-
return `No ${noun}s selected`;
|
|
200
|
-
}
|
|
201
|
-
return count === 1 ? `1 ${noun} selected` : `${String(count)} ${noun}s selected`;
|
|
202
|
-
}
|
|
203
|
-
function useAsSet(values) {
|
|
204
|
-
return useMemo2(() => new Set(values), [values]);
|
|
205
|
-
}
|
|
206
|
-
function useIndexedBy(values, key) {
|
|
207
|
-
return useMemo2(
|
|
208
|
-
() => new Map(values.map((value) => [value[key], value])),
|
|
209
|
-
[values, key]
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
function useMappedArray(values, key) {
|
|
213
|
-
return useMemo2(() => values.map((value) => value[key]), [values, key]);
|
|
214
|
-
}
|
|
215
162
|
function useGridSelection({
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
selectable
|
|
219
|
-
rowSelection,
|
|
220
|
-
setRowSelection,
|
|
221
|
-
columnSelection,
|
|
222
|
-
setColumnSelection,
|
|
223
|
-
cellSelection,
|
|
224
|
-
setCellSelection,
|
|
225
|
-
callbacks,
|
|
226
|
-
announce,
|
|
227
|
-
columnName
|
|
163
|
+
controller,
|
|
164
|
+
state,
|
|
165
|
+
selectable
|
|
228
166
|
}) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const rowAnchor = useRef2(null);
|
|
238
|
-
const columnAnchor = useRef2(null);
|
|
239
|
-
function announceCount(changed, total, noun) {
|
|
240
|
-
if (changed > 1) {
|
|
241
|
-
announce(countMessage(total, noun));
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
function commitRows(next) {
|
|
245
|
-
commitIfChanged(rowSelection, next, setRowSelection, (committed) => {
|
|
246
|
-
const { added, removed } = diffSelection(rowSelection, committed);
|
|
247
|
-
const addedRows = resolveRows(rowsById, added);
|
|
248
|
-
const removedRows = resolveRows(rowsById, removed);
|
|
249
|
-
for (const row of addedRows) {
|
|
250
|
-
callbacks.onRowSelect?.({ row, selection: committed });
|
|
251
|
-
}
|
|
252
|
-
if (addedRows.length > 0) {
|
|
253
|
-
callbacks.onRowsSelect?.({ rows: addedRows, selection: committed });
|
|
254
|
-
}
|
|
255
|
-
for (const row of removedRows) {
|
|
256
|
-
callbacks.onRowDeselect?.({ row, selection: committed });
|
|
257
|
-
}
|
|
258
|
-
if (removedRows.length > 0) {
|
|
259
|
-
callbacks.onRowsDeselect?.({ rows: removedRows, selection: committed });
|
|
260
|
-
}
|
|
261
|
-
callbacks.onRowSelectionChange?.({
|
|
262
|
-
added: addedRows,
|
|
263
|
-
removed: removedRows,
|
|
264
|
-
selected: resolveRows(rowsById, committed),
|
|
265
|
-
selection: committed
|
|
266
|
-
});
|
|
267
|
-
announceCount(added.length + removed.length, committed.length, "row");
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
function commitColumns(next) {
|
|
271
|
-
commitIfChanged(columnSelection, next, setColumnSelection, (committed) => {
|
|
272
|
-
const { added, removed } = diffSelection(columnSelection, committed);
|
|
273
|
-
const addedColumns = resolveColumns(columns, added);
|
|
274
|
-
const removedColumns = resolveColumns(columns, removed);
|
|
275
|
-
for (const column of addedColumns) {
|
|
276
|
-
callbacks.onColumnSelect?.({ column, selection: committed });
|
|
277
|
-
}
|
|
278
|
-
if (addedColumns.length > 0) {
|
|
279
|
-
callbacks.onColumnsSelect?.({
|
|
280
|
-
columns: addedColumns,
|
|
281
|
-
selection: committed
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
for (const column of removedColumns) {
|
|
285
|
-
callbacks.onColumnDeselect?.({ column, selection: committed });
|
|
286
|
-
}
|
|
287
|
-
if (removedColumns.length > 0) {
|
|
288
|
-
callbacks.onColumnsDeselect?.({
|
|
289
|
-
columns: removedColumns,
|
|
290
|
-
selection: committed
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
callbacks.onColumnSelectionChange?.({
|
|
294
|
-
added: addedColumns,
|
|
295
|
-
removed: removedColumns,
|
|
296
|
-
selected: resolveColumns(columns, committed),
|
|
297
|
-
selection: committed
|
|
298
|
-
});
|
|
299
|
-
announceCount(added.length + removed.length, committed.length, "column");
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
function commitCell(next) {
|
|
303
|
-
commitIfChanged(cellSelection, next, setCellSelection, (committed) => {
|
|
304
|
-
const selected = resolveCell(rowsById, columns, committed);
|
|
305
|
-
const deselected = resolveCell(rowsById, columns, cellSelection);
|
|
306
|
-
if (deselected !== null) {
|
|
307
|
-
callbacks.onCellDeselect?.({ cell: deselected, selection: committed });
|
|
308
|
-
}
|
|
309
|
-
if (selected !== null) {
|
|
310
|
-
callbacks.onCellSelect?.({ cell: selected, selection: committed });
|
|
311
|
-
}
|
|
312
|
-
callbacks.onCellSelectionChange?.({
|
|
313
|
-
selected,
|
|
314
|
-
deselected,
|
|
315
|
-
selection: committed
|
|
316
|
-
});
|
|
317
|
-
if (selected !== null) {
|
|
318
|
-
announce(
|
|
319
|
-
`${columnName(selected.columnId)}, row ${String(selected.rowIndex + 1)}, selected`
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
function selectRow(rowId, intent) {
|
|
325
|
-
const next = applySelectionIntent(
|
|
326
|
-
rowSelection,
|
|
327
|
-
rowIds,
|
|
328
|
-
rowAnchor.current,
|
|
329
|
-
rowId,
|
|
330
|
-
intent,
|
|
331
|
-
rowMode
|
|
332
|
-
);
|
|
333
|
-
if (intent !== "range") {
|
|
334
|
-
rowAnchor.current = rowId;
|
|
335
|
-
}
|
|
336
|
-
commitRows(next);
|
|
337
|
-
}
|
|
338
|
-
function selectColumn(columnId, intent) {
|
|
339
|
-
const next = applySelectionIntent(
|
|
340
|
-
columnSelection,
|
|
341
|
-
columnIds,
|
|
342
|
-
columnAnchor.current,
|
|
343
|
-
columnId,
|
|
344
|
-
intent,
|
|
345
|
-
columnMode
|
|
346
|
-
);
|
|
347
|
-
if (intent !== "range") {
|
|
348
|
-
columnAnchor.current = columnId;
|
|
349
|
-
}
|
|
350
|
-
commitColumns(next);
|
|
351
|
-
}
|
|
352
|
-
function selectCellAt(cell, intent) {
|
|
353
|
-
commitCell(
|
|
354
|
-
intent === "toggle" ? toggleCellSelection(cellSelection, cell, cellMode) : selectCell(cellSelection, cell, cellMode)
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
function selectAllRows() {
|
|
358
|
-
commitRows(selectAll(rowSelection, rowIds, rowMode));
|
|
359
|
-
}
|
|
360
|
-
function clear() {
|
|
361
|
-
commitRows(clearSelection(rowSelection));
|
|
362
|
-
commitColumns(clearSelection(columnSelection));
|
|
363
|
-
commitCell(null);
|
|
364
|
-
}
|
|
167
|
+
const selectedRowIds = useMemo(
|
|
168
|
+
() => new Set(state.rowSelection),
|
|
169
|
+
[state.rowSelection]
|
|
170
|
+
);
|
|
171
|
+
const selectedColumnIds = useMemo(
|
|
172
|
+
() => new Set(state.columnSelection),
|
|
173
|
+
[state.columnSelection]
|
|
174
|
+
);
|
|
365
175
|
return {
|
|
366
|
-
rowMode,
|
|
367
|
-
columnMode,
|
|
368
|
-
cellMode,
|
|
176
|
+
rowMode: selectable?.rows ?? false,
|
|
177
|
+
columnMode: selectable?.columns ?? false,
|
|
178
|
+
cellMode: selectable?.cells ?? false,
|
|
179
|
+
toggleOnClick: selectable?.toggleOnClick ?? false,
|
|
369
180
|
selectedRowIds,
|
|
370
181
|
selectedColumnIds,
|
|
371
|
-
selectedCell: cellSelection,
|
|
372
|
-
selectRow,
|
|
373
|
-
selectColumn,
|
|
374
|
-
selectCell:
|
|
375
|
-
selectAllRows,
|
|
376
|
-
clear
|
|
182
|
+
selectedCell: state.cellSelection,
|
|
183
|
+
selectRow: controller.selectRow,
|
|
184
|
+
selectColumn: controller.selectColumn,
|
|
185
|
+
selectCell: controller.selectCell,
|
|
186
|
+
selectAllRows: controller.selectAllRows,
|
|
187
|
+
clear: controller.clearSelection
|
|
377
188
|
};
|
|
378
189
|
}
|
|
379
190
|
|
|
380
191
|
// src/DataGrid/components/GridHeader.tsx
|
|
381
|
-
import { jsx as
|
|
382
|
-
function Icon({ children }) {
|
|
383
|
-
return /* @__PURE__ */ jsx2(
|
|
384
|
-
"svg",
|
|
385
|
-
{
|
|
386
|
-
viewBox: "0 0 24 24",
|
|
387
|
-
fill: "none",
|
|
388
|
-
stroke: "currentColor",
|
|
389
|
-
strokeWidth: 2,
|
|
390
|
-
strokeLinecap: "round",
|
|
391
|
-
strokeLinejoin: "round",
|
|
392
|
-
"aria-hidden": "true",
|
|
393
|
-
children
|
|
394
|
-
}
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
function ChevronsUpDownIcon() {
|
|
398
|
-
return /* @__PURE__ */ jsxs(Icon, { children: [
|
|
399
|
-
/* @__PURE__ */ jsx2("path", { d: "m7 15 5 5 5-5" }),
|
|
400
|
-
/* @__PURE__ */ jsx2("path", { d: "m7 9 5-5 5 5" })
|
|
401
|
-
] });
|
|
402
|
-
}
|
|
403
|
-
function ChevronUpIcon() {
|
|
404
|
-
return /* @__PURE__ */ jsx2(Icon, { children: /* @__PURE__ */ jsx2("path", { d: "m18 15-6-6-6 6" }) });
|
|
405
|
-
}
|
|
406
|
-
function GroupIcon() {
|
|
407
|
-
return /* @__PURE__ */ jsxs(Icon, { children: [
|
|
408
|
-
/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
409
|
-
/* @__PURE__ */ jsx2("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1" }),
|
|
410
|
-
/* @__PURE__ */ jsx2("rect", { x: "8.5", y: "14", width: "7", height: "7", rx: "1" })
|
|
411
|
-
] });
|
|
412
|
-
}
|
|
192
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
413
193
|
function GridHeader({
|
|
414
194
|
columns,
|
|
415
195
|
resize,
|
|
416
196
|
drag,
|
|
417
|
-
|
|
197
|
+
controller,
|
|
198
|
+
columnSort,
|
|
418
199
|
sortableColumns,
|
|
419
|
-
|
|
200
|
+
groupBy,
|
|
420
201
|
groupableColumns,
|
|
421
202
|
groupToggleIconColumns,
|
|
203
|
+
headerMenu,
|
|
422
204
|
nav,
|
|
423
205
|
selection
|
|
424
206
|
}) {
|
|
425
207
|
const beforeId = drag.dropTarget?.kind === "column-order" ? drag.dropTarget.beforeId : void 0;
|
|
426
208
|
const draggedEntry = columns.find((entry) => entry.id === drag.draggedColumnId) ?? null;
|
|
427
|
-
return /* @__PURE__ */
|
|
428
|
-
/* @__PURE__ */
|
|
209
|
+
return /* @__PURE__ */ jsxs2("thead", { children: [
|
|
210
|
+
/* @__PURE__ */ jsx3("tr", { className: "grid-header", role: "row", "aria-rowindex": 1, children: columns.map((entry, index) => {
|
|
429
211
|
const { column } = entry;
|
|
430
212
|
const resizing = resize.activeColumnId === entry.id;
|
|
431
213
|
const dragging = drag.draggedColumnId === entry.id;
|
|
@@ -433,20 +215,21 @@ function GridHeader({
|
|
|
433
215
|
const dropAfter = beforeId === null && index === columns.length - 1;
|
|
434
216
|
const selected = selection.selectedColumnIds.has(entry.id);
|
|
435
217
|
const sortable = column.sortable ?? sortableColumns;
|
|
436
|
-
const sortDirection =
|
|
437
|
-
const sortPriority =
|
|
218
|
+
const sortDirection = sortDirectionFor(columnSort, entry.id);
|
|
219
|
+
const sortPriority = sortPriorityFor(columnSort, entry.id);
|
|
438
220
|
const groupable = column.groupable ?? groupableColumns;
|
|
439
221
|
const showGroupToggleIcon = column.groupToggleIcon ?? groupToggleIconColumns;
|
|
440
|
-
const isGrouped =
|
|
222
|
+
const isGrouped = groupBy.some(
|
|
441
223
|
(level) => level.columnId === entry.id
|
|
442
224
|
);
|
|
443
225
|
const shortcuts = buildKeyShortcuts({
|
|
444
226
|
reorderable: entry.reorderable,
|
|
445
227
|
resizable: entry.resizable,
|
|
446
228
|
sortable,
|
|
447
|
-
groupable
|
|
229
|
+
groupable,
|
|
230
|
+
contextMenu: headerMenu
|
|
448
231
|
});
|
|
449
|
-
return /* @__PURE__ */
|
|
232
|
+
return /* @__PURE__ */ jsxs2(
|
|
450
233
|
"th",
|
|
451
234
|
{
|
|
452
235
|
scope: "col",
|
|
@@ -472,6 +255,7 @@ function GridHeader({
|
|
|
472
255
|
selection.selectColumn(entry.id, intentOf(event));
|
|
473
256
|
},
|
|
474
257
|
onKeyDown: (event) => {
|
|
258
|
+
if (!isOwnEvent(event)) return;
|
|
475
259
|
const horizontal = event.key === "ArrowLeft" || event.key === "ArrowRight";
|
|
476
260
|
const direction = event.key === "ArrowLeft" ? -1 : 1;
|
|
477
261
|
if (horizontal && event.ctrlKey && entry.reorderable) {
|
|
@@ -491,12 +275,14 @@ function GridHeader({
|
|
|
491
275
|
}
|
|
492
276
|
if (event.key === "ArrowUp" && event.altKey && sortable) {
|
|
493
277
|
event.preventDefault();
|
|
494
|
-
|
|
278
|
+
controller.toggleColumnSort(entry.id, {
|
|
279
|
+
stack: event.shiftKey
|
|
280
|
+
});
|
|
495
281
|
return;
|
|
496
282
|
}
|
|
497
283
|
if (event.key === "ArrowDown" && event.altKey && groupable) {
|
|
498
284
|
event.preventDefault();
|
|
499
|
-
|
|
285
|
+
controller.toggleGroupBy(entry.id);
|
|
500
286
|
return;
|
|
501
287
|
}
|
|
502
288
|
if (event.key === " " || event.key === "Enter") {
|
|
@@ -545,7 +331,7 @@ function GridHeader({
|
|
|
545
331
|
* A pointer affordance only, same as the other two — the
|
|
546
332
|
* keyboard equivalent is Alt+ArrowDown on the header itself.
|
|
547
333
|
*/
|
|
548
|
-
/* @__PURE__ */
|
|
334
|
+
/* @__PURE__ */ jsx3(
|
|
549
335
|
"span",
|
|
550
336
|
{
|
|
551
337
|
className: classNames(
|
|
@@ -559,9 +345,9 @@ function GridHeader({
|
|
|
559
345
|
},
|
|
560
346
|
onClick: (event) => {
|
|
561
347
|
event.stopPropagation();
|
|
562
|
-
|
|
348
|
+
controller.toggleGroupBy(entry.id);
|
|
563
349
|
},
|
|
564
|
-
children: /* @__PURE__ */
|
|
350
|
+
children: /* @__PURE__ */ jsx3(GroupIcon, {})
|
|
565
351
|
}
|
|
566
352
|
),
|
|
567
353
|
entry.label,
|
|
@@ -571,7 +357,7 @@ function GridHeader({
|
|
|
571
357
|
* lives on the header itself, under Alt+ArrowUp (plain) /
|
|
572
358
|
* Alt+Shift+ArrowUp (stacking).
|
|
573
359
|
*/
|
|
574
|
-
/* @__PURE__ */
|
|
360
|
+
/* @__PURE__ */ jsxs2(
|
|
575
361
|
"span",
|
|
576
362
|
{
|
|
577
363
|
className: classNames(
|
|
@@ -584,11 +370,13 @@ function GridHeader({
|
|
|
584
370
|
event.stopPropagation();
|
|
585
371
|
},
|
|
586
372
|
onClick: (event) => {
|
|
587
|
-
|
|
373
|
+
controller.toggleColumnSort(entry.id, {
|
|
374
|
+
stack: event.shiftKey
|
|
375
|
+
});
|
|
588
376
|
},
|
|
589
377
|
children: [
|
|
590
|
-
sortDirection === null ? /* @__PURE__ */
|
|
591
|
-
sortPriority !== null && sortPriority > 1 && /* @__PURE__ */
|
|
378
|
+
sortDirection === null ? /* @__PURE__ */ jsx3(ChevronsUpDownIcon, {}) : /* @__PURE__ */ jsx3(ChevronUpIcon, {}),
|
|
379
|
+
sortPriority !== null && sortPriority > 1 && /* @__PURE__ */ jsx3("span", { className: "header-sort-priority", children: sortPriority })
|
|
592
380
|
]
|
|
593
381
|
}
|
|
594
382
|
),
|
|
@@ -598,7 +386,7 @@ function GridHeader({
|
|
|
598
386
|
* put N tab stops inside a widget that is meant to have one.
|
|
599
387
|
* The keyboard resizes from the header itself, under Alt.
|
|
600
388
|
*/
|
|
601
|
-
/* @__PURE__ */
|
|
389
|
+
/* @__PURE__ */ jsx3(
|
|
602
390
|
"span",
|
|
603
391
|
{
|
|
604
392
|
className: "header-resize-handle",
|
|
@@ -618,7 +406,7 @@ function GridHeader({
|
|
|
618
406
|
);
|
|
619
407
|
}) }),
|
|
620
408
|
draggedEntry !== null && drag.ghostTransform !== null && createPortal(
|
|
621
|
-
/* @__PURE__ */
|
|
409
|
+
/* @__PURE__ */ jsx3(
|
|
622
410
|
"div",
|
|
623
411
|
{
|
|
624
412
|
className: "gridkit-data-grid header-cell drag-ghost",
|
|
@@ -636,65 +424,82 @@ function GridHeader({
|
|
|
636
424
|
}
|
|
637
425
|
|
|
638
426
|
// src/DataGrid/components/GridBody.tsx
|
|
639
|
-
import {
|
|
427
|
+
import {
|
|
428
|
+
useMemo as useMemo2,
|
|
429
|
+
useState as useState2
|
|
430
|
+
} from "react";
|
|
640
431
|
import {
|
|
641
432
|
groupRowId,
|
|
642
433
|
intentOf as intentOf2
|
|
643
434
|
} from "@gridkitjs/core";
|
|
435
|
+
import {
|
|
436
|
+
bodyCellFrom,
|
|
437
|
+
bodyRowFrom,
|
|
438
|
+
groupRowFrom
|
|
439
|
+
} from "@gridkitjs/dom";
|
|
440
|
+
|
|
441
|
+
// src/DataGrid/rowProps.ts
|
|
442
|
+
var NO_ATTRIBUTES = {};
|
|
443
|
+
var NO_ROW_PROPS = {
|
|
444
|
+
className: "",
|
|
445
|
+
attributes: NO_ATTRIBUTES
|
|
446
|
+
};
|
|
447
|
+
function sameAttributes(a, b) {
|
|
448
|
+
const keys = Object.keys(a);
|
|
449
|
+
return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);
|
|
450
|
+
}
|
|
451
|
+
function createRowPropsResolver() {
|
|
452
|
+
let previous = /* @__PURE__ */ new Map();
|
|
453
|
+
return (rows, getRowProps) => {
|
|
454
|
+
if (getRowProps === void 0) {
|
|
455
|
+
previous = /* @__PURE__ */ new Map();
|
|
456
|
+
return () => NO_ROW_PROPS;
|
|
457
|
+
}
|
|
458
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
459
|
+
const attributesById = /* @__PURE__ */ new Map();
|
|
460
|
+
for (const entry of rows) {
|
|
461
|
+
const { className = "", attributes = NO_ATTRIBUTES } = getRowProps(entry);
|
|
462
|
+
const last = previous.get(entry.rowId);
|
|
463
|
+
const stable = last !== void 0 && sameAttributes(last, attributes) ? last : attributes;
|
|
464
|
+
attributesById.set(entry.rowId, stable);
|
|
465
|
+
resolved.set(entry.rowId, { className, attributes: stable });
|
|
466
|
+
}
|
|
467
|
+
previous = attributesById;
|
|
468
|
+
return (rowId) => resolved.get(rowId) ?? NO_ROW_PROPS;
|
|
469
|
+
};
|
|
470
|
+
}
|
|
644
471
|
|
|
645
472
|
// src/DataGrid/components/GridGroupRow.tsx
|
|
646
473
|
import { memo } from "react";
|
|
474
|
+
import {
|
|
475
|
+
formatCellValue,
|
|
476
|
+
resolveColumnLabel
|
|
477
|
+
} from "@gridkitjs/core";
|
|
647
478
|
|
|
648
|
-
// src/DataGrid/components/
|
|
649
|
-
|
|
479
|
+
// src/DataGrid/components/renderAggregate.ts
|
|
480
|
+
import {
|
|
481
|
+
formatAggregateValue
|
|
482
|
+
} from "@gridkitjs/core";
|
|
483
|
+
function renderAggregate(value, spec, column, rows, locale) {
|
|
484
|
+
if (column?.footerTemplate) {
|
|
485
|
+
return column.footerTemplate({ value, rows });
|
|
486
|
+
}
|
|
650
487
|
if (value === null || value === void 0) {
|
|
651
488
|
return "\u2014";
|
|
652
489
|
}
|
|
653
|
-
|
|
654
|
-
return value.toLocaleString();
|
|
655
|
-
}
|
|
656
|
-
switch (typeof value) {
|
|
657
|
-
case "string":
|
|
658
|
-
case "boolean":
|
|
659
|
-
case "bigint":
|
|
660
|
-
case "symbol":
|
|
661
|
-
return String(value);
|
|
662
|
-
case "number":
|
|
663
|
-
return value.toLocaleString();
|
|
664
|
-
case "function":
|
|
665
|
-
return "(function)";
|
|
666
|
-
default:
|
|
667
|
-
return JSON.stringify(value);
|
|
668
|
-
}
|
|
490
|
+
return formatAggregateValue(value, spec, column, locale);
|
|
669
491
|
}
|
|
670
492
|
|
|
671
493
|
// src/DataGrid/components/GridGroupRow.tsx
|
|
672
|
-
import { jsx as
|
|
673
|
-
function formatGroupValue(value) {
|
|
674
|
-
|
|
675
|
-
return "(blank)";
|
|
676
|
-
}
|
|
677
|
-
if (value instanceof Date) {
|
|
678
|
-
return value.toLocaleString();
|
|
679
|
-
}
|
|
680
|
-
switch (typeof value) {
|
|
681
|
-
case "string":
|
|
682
|
-
case "number":
|
|
683
|
-
case "boolean":
|
|
684
|
-
case "bigint":
|
|
685
|
-
case "symbol":
|
|
686
|
-
return String(value);
|
|
687
|
-
case "function":
|
|
688
|
-
return "(function)";
|
|
689
|
-
default:
|
|
690
|
-
return JSON.stringify(value);
|
|
691
|
-
}
|
|
494
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
495
|
+
function formatGroupValue(value, column, locale, messages) {
|
|
496
|
+
return value === null || value === void 0 ? messages.blankGroupValue : formatCellValue(value, column, locale, void 0, messages);
|
|
692
497
|
}
|
|
693
498
|
function GridGroupRowComponent({
|
|
694
499
|
columnCount,
|
|
695
500
|
groupId,
|
|
696
501
|
level,
|
|
697
|
-
|
|
502
|
+
groupColumn,
|
|
698
503
|
value,
|
|
699
504
|
expanded,
|
|
700
505
|
count,
|
|
@@ -703,13 +508,15 @@ function GridGroupRowComponent({
|
|
|
703
508
|
posinset,
|
|
704
509
|
setsize,
|
|
705
510
|
focused,
|
|
511
|
+
contextMenu,
|
|
706
512
|
aggregates,
|
|
707
513
|
results,
|
|
708
|
-
|
|
514
|
+
definitions,
|
|
515
|
+
locale,
|
|
516
|
+
cellMessages,
|
|
709
517
|
ref
|
|
710
518
|
}) {
|
|
711
|
-
|
|
712
|
-
return /* @__PURE__ */ jsx3(
|
|
519
|
+
return /* @__PURE__ */ jsx4(
|
|
713
520
|
"tr",
|
|
714
521
|
{
|
|
715
522
|
ref,
|
|
@@ -725,21 +532,21 @@ function GridGroupRowComponent({
|
|
|
725
532
|
"grid-group-row",
|
|
726
533
|
`is-group-level-${String(level)}`
|
|
727
534
|
),
|
|
728
|
-
children: /* @__PURE__ */
|
|
535
|
+
children: /* @__PURE__ */ jsx4(
|
|
729
536
|
"td",
|
|
730
537
|
{
|
|
731
538
|
role: "gridcell",
|
|
732
539
|
colSpan: columnCount,
|
|
733
540
|
tabIndex: focused ? 0 : -1,
|
|
734
|
-
"aria-keyshortcuts": "Space Enter",
|
|
541
|
+
"aria-keyshortcuts": contextMenu ? "Space Enter Shift+F10" : "Space Enter",
|
|
735
542
|
className: "grid-group-cell",
|
|
736
|
-
children: /* @__PURE__ */
|
|
543
|
+
children: /* @__PURE__ */ jsxs3(
|
|
737
544
|
"div",
|
|
738
545
|
{
|
|
739
546
|
className: "grid-group-cell-content",
|
|
740
547
|
style: { paddingInlineStart: `${String(level * 1.25 + 0.5)}rem` },
|
|
741
548
|
children: [
|
|
742
|
-
/* @__PURE__ */
|
|
549
|
+
/* @__PURE__ */ jsx4(
|
|
743
550
|
"span",
|
|
744
551
|
{
|
|
745
552
|
className: classNames(
|
|
@@ -749,26 +556,30 @@ function GridGroupRowComponent({
|
|
|
749
556
|
"aria-hidden": "true"
|
|
750
557
|
}
|
|
751
558
|
),
|
|
752
|
-
/* @__PURE__ */
|
|
753
|
-
|
|
754
|
-
":
|
|
755
|
-
|
|
559
|
+
/* @__PURE__ */ jsxs3("span", { className: "group-label", children: [
|
|
560
|
+
resolveColumnLabel(groupColumn),
|
|
561
|
+
":",
|
|
562
|
+
" ",
|
|
563
|
+
formatGroupValue(value, groupColumn, locale, cellMessages)
|
|
756
564
|
] }),
|
|
757
|
-
/* @__PURE__ */
|
|
565
|
+
/* @__PURE__ */ jsxs3("span", { className: "group-count", children: [
|
|
758
566
|
"(",
|
|
759
567
|
count,
|
|
760
568
|
")"
|
|
761
569
|
] }),
|
|
762
|
-
aggregates.length > 0 && /* @__PURE__ */
|
|
570
|
+
aggregates.length > 0 && /* @__PURE__ */ jsx4("span", { className: "group-aggregates", children: aggregates.map((spec) => {
|
|
763
571
|
const key = spec.id ?? spec.columnId;
|
|
764
572
|
const aggregateValue = results.get(key);
|
|
765
|
-
const column =
|
|
766
|
-
const rendered =
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
573
|
+
const column = definitions.get(spec.columnId);
|
|
574
|
+
const rendered = renderAggregate(
|
|
575
|
+
aggregateValue,
|
|
576
|
+
spec,
|
|
577
|
+
column,
|
|
578
|
+
[],
|
|
579
|
+
locale
|
|
580
|
+
);
|
|
581
|
+
const aggregateLabel = spec.id ?? (column === void 0 ? spec.columnId : resolveColumnLabel(column));
|
|
582
|
+
return /* @__PURE__ */ jsxs3("span", { className: "group-aggregate", children: [
|
|
772
583
|
aggregateLabel,
|
|
773
584
|
": ",
|
|
774
585
|
rendered
|
|
@@ -789,7 +600,7 @@ var GridGroupRow_default = GridGroupRow;
|
|
|
789
600
|
|
|
790
601
|
// src/DataGrid/components/GridGroupSummaryRow.tsx
|
|
791
602
|
import { memo as memo2 } from "react";
|
|
792
|
-
import { jsx as
|
|
603
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
793
604
|
function GridGroupSummaryRowComponent({
|
|
794
605
|
groupId,
|
|
795
606
|
level,
|
|
@@ -798,9 +609,10 @@ function GridGroupSummaryRowComponent({
|
|
|
798
609
|
results,
|
|
799
610
|
aggregates,
|
|
800
611
|
columns,
|
|
612
|
+
locale,
|
|
801
613
|
ref
|
|
802
614
|
}) {
|
|
803
|
-
return /* @__PURE__ */
|
|
615
|
+
return /* @__PURE__ */ jsx5(
|
|
804
616
|
"tr",
|
|
805
617
|
{
|
|
806
618
|
ref,
|
|
@@ -816,8 +628,7 @@ function GridGroupSummaryRowComponent({
|
|
|
816
628
|
const specs = aggregates.filter(
|
|
817
629
|
(candidate) => candidate.columnId === entry.id
|
|
818
630
|
);
|
|
819
|
-
|
|
820
|
-
return /* @__PURE__ */ jsxs3(
|
|
631
|
+
return /* @__PURE__ */ jsxs4(
|
|
821
632
|
"td",
|
|
822
633
|
{
|
|
823
634
|
role: "gridcell",
|
|
@@ -825,7 +636,7 @@ function GridGroupSummaryRowComponent({
|
|
|
825
636
|
className: "grid-group-summary-cell",
|
|
826
637
|
style: { textAlign: specs[0]?.alignment ?? entry.alignment },
|
|
827
638
|
children: [
|
|
828
|
-
entry.id === columns[0]?.id && /* @__PURE__ */
|
|
639
|
+
entry.id === columns[0]?.id && /* @__PURE__ */ jsx5(
|
|
829
640
|
"span",
|
|
830
641
|
{
|
|
831
642
|
className: "grid-group-summary-indent",
|
|
@@ -833,10 +644,15 @@ function GridGroupSummaryRowComponent({
|
|
|
833
644
|
"aria-hidden": "true"
|
|
834
645
|
}
|
|
835
646
|
),
|
|
836
|
-
specs.map(
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
647
|
+
specs.map(
|
|
648
|
+
(spec) => renderAggregate(
|
|
649
|
+
results.get(spec.id ?? spec.columnId),
|
|
650
|
+
spec,
|
|
651
|
+
entry.column,
|
|
652
|
+
[],
|
|
653
|
+
locale
|
|
654
|
+
)
|
|
655
|
+
).flatMap(
|
|
840
656
|
(rendered, index) => index === 0 ? [rendered] : [", ", rendered]
|
|
841
657
|
)
|
|
842
658
|
]
|
|
@@ -853,9 +669,12 @@ var GridGroupSummaryRow = memo2(
|
|
|
853
669
|
var GridGroupSummaryRow_default = GridGroupSummaryRow;
|
|
854
670
|
|
|
855
671
|
// src/DataGrid/components/GridRow.tsx
|
|
856
|
-
import {
|
|
672
|
+
import {
|
|
673
|
+
accessDotted,
|
|
674
|
+
formatCellValue as formatCellValue2
|
|
675
|
+
} from "@gridkitjs/core";
|
|
857
676
|
import { memo as memo3 } from "react";
|
|
858
|
-
import { jsx as
|
|
677
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
859
678
|
function GridRowComponent({
|
|
860
679
|
columns,
|
|
861
680
|
rowId,
|
|
@@ -869,21 +688,36 @@ function GridRowComponent({
|
|
|
869
688
|
focusedColumnIndex,
|
|
870
689
|
rowsSelectable,
|
|
871
690
|
cellsSelectable,
|
|
691
|
+
contextMenu,
|
|
692
|
+
locale,
|
|
693
|
+
cellMessages,
|
|
694
|
+
rowClassName,
|
|
695
|
+
rowAttributes,
|
|
872
696
|
ref
|
|
873
697
|
}) {
|
|
874
|
-
|
|
698
|
+
const shortcuts = [
|
|
699
|
+
cellsSelectable ? "Space Enter" : "",
|
|
700
|
+
contextMenu ? "Shift+F10" : ""
|
|
701
|
+
].filter(Boolean).join(" ");
|
|
702
|
+
return /* @__PURE__ */ jsx6(
|
|
875
703
|
"tr",
|
|
876
704
|
{
|
|
705
|
+
...rowAttributes,
|
|
877
706
|
ref,
|
|
878
707
|
role: "row",
|
|
879
708
|
"aria-rowindex": datasetIndex + 2,
|
|
880
709
|
"data-gridkit-row-index": rowIndex,
|
|
710
|
+
"data-gridkit-row-id": rowId,
|
|
881
711
|
...ariaAttr(rowsSelectable, "aria-selected", selected),
|
|
882
|
-
className: classNames(
|
|
712
|
+
className: classNames(
|
|
713
|
+
"grid-row",
|
|
714
|
+
selected ? "is-selected" : "",
|
|
715
|
+
rowClassName
|
|
716
|
+
),
|
|
883
717
|
children: columns.map(({ id, column, alignment }, columnIndex) => {
|
|
884
718
|
const value = accessDotted(row, column.field);
|
|
885
719
|
const cellSelected = id === selectedColumnId;
|
|
886
|
-
return /* @__PURE__ */
|
|
720
|
+
return /* @__PURE__ */ jsx6(
|
|
887
721
|
"td",
|
|
888
722
|
{
|
|
889
723
|
role: "gridcell",
|
|
@@ -891,7 +725,7 @@ function GridRowComponent({
|
|
|
891
725
|
"aria-colindex": columnIndex + 1,
|
|
892
726
|
tabIndex: tabIndexFor(columnIndex, focusedColumnIndex),
|
|
893
727
|
...ariaAttr(cellsSelectable, "aria-selected", cellSelected),
|
|
894
|
-
...ariaAttr(
|
|
728
|
+
...ariaAttr(shortcuts !== "", "aria-keyshortcuts", shortcuts),
|
|
895
729
|
className: classNames(
|
|
896
730
|
"grid-cell",
|
|
897
731
|
id === activeColumnId ? "is-resizing" : "",
|
|
@@ -907,7 +741,7 @@ function GridRowComponent({
|
|
|
907
741
|
datasetIndex,
|
|
908
742
|
rowId,
|
|
909
743
|
selected
|
|
910
|
-
}) : value
|
|
744
|
+
}) : formatCellValue2(value, column, locale, row, cellMessages)
|
|
911
745
|
},
|
|
912
746
|
id
|
|
913
747
|
);
|
|
@@ -919,40 +753,7 @@ var GridRow = memo3(GridRowComponent);
|
|
|
919
753
|
var GridRow_default = GridRow;
|
|
920
754
|
|
|
921
755
|
// src/DataGrid/components/GridBody.tsx
|
|
922
|
-
import { Fragment, jsx as
|
|
923
|
-
function rowIndexOf(row) {
|
|
924
|
-
const attribute = row.getAttribute("data-gridkit-row-index");
|
|
925
|
-
return attribute === null ? null : Number(attribute);
|
|
926
|
-
}
|
|
927
|
-
function cellFrom(target) {
|
|
928
|
-
if (!(target instanceof Element)) {
|
|
929
|
-
return null;
|
|
930
|
-
}
|
|
931
|
-
const cell = target.closest("td[data-gridkit-column]");
|
|
932
|
-
const row = cell?.parentElement;
|
|
933
|
-
const columnId = cell?.getAttribute("data-gridkit-column");
|
|
934
|
-
const rowIndex = row === null || row === void 0 ? null : rowIndexOf(row);
|
|
935
|
-
if (!(cell instanceof HTMLTableCellElement) || !(row instanceof HTMLTableRowElement) || columnId === null || columnId === void 0 || rowIndex === null) {
|
|
936
|
-
return null;
|
|
937
|
-
}
|
|
938
|
-
return {
|
|
939
|
-
rowIndex,
|
|
940
|
-
columnIndex: cell.cellIndex,
|
|
941
|
-
columnId
|
|
942
|
-
};
|
|
943
|
-
}
|
|
944
|
-
function groupRowFrom(target) {
|
|
945
|
-
if (!(target instanceof Element)) {
|
|
946
|
-
return null;
|
|
947
|
-
}
|
|
948
|
-
const row = target.closest("tr[data-gridkit-group]");
|
|
949
|
-
const groupId = row?.getAttribute("data-gridkit-group");
|
|
950
|
-
const rowIndex = row === null ? null : rowIndexOf(row);
|
|
951
|
-
if (!(row instanceof HTMLTableRowElement) || groupId === null || groupId === void 0 || rowIndex === null) {
|
|
952
|
-
return null;
|
|
953
|
-
}
|
|
954
|
-
return { rowIndex, groupId };
|
|
955
|
-
}
|
|
756
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
956
757
|
function groupAriaMeta(rows) {
|
|
957
758
|
const totals = /* @__PURE__ */ new Map();
|
|
958
759
|
for (const entry of rows) {
|
|
@@ -976,22 +777,42 @@ function groupAriaMeta(rows) {
|
|
|
976
777
|
}
|
|
977
778
|
function GridBody({
|
|
978
779
|
columns,
|
|
780
|
+
definitions,
|
|
979
781
|
rows,
|
|
980
782
|
activeColumnId,
|
|
981
783
|
nav,
|
|
982
784
|
selection,
|
|
983
|
-
|
|
785
|
+
controller,
|
|
984
786
|
aggregates,
|
|
985
787
|
groupAggregateDisplay,
|
|
986
788
|
virtualRange,
|
|
987
789
|
infiniteScroll,
|
|
988
|
-
sentinelRef
|
|
790
|
+
sentinelRef,
|
|
791
|
+
locale,
|
|
792
|
+
getRowProps,
|
|
793
|
+
onRowClick,
|
|
794
|
+
onRowDoubleClick,
|
|
795
|
+
messages,
|
|
796
|
+
cellMenu,
|
|
797
|
+
groupMenu
|
|
989
798
|
}) {
|
|
990
|
-
const { selectedCell, rowMode, cellMode } = selection;
|
|
991
|
-
const ariaMeta =
|
|
799
|
+
const { selectedCell, rowMode, cellMode, toggleOnClick } = selection;
|
|
800
|
+
const ariaMeta = useMemo2(() => groupAriaMeta(rows), [rows]);
|
|
992
801
|
const visibleRows = virtualRange === null ? rows : rows.slice(virtualRange.startIndex, virtualRange.endIndex + 1);
|
|
802
|
+
const { booleanTrue, booleanFalse, blankGroupValue } = messages;
|
|
803
|
+
const cellMessages = useMemo2(
|
|
804
|
+
() => ({ booleanTrue, booleanFalse, blankGroupValue }),
|
|
805
|
+
[booleanTrue, booleanFalse, blankGroupValue]
|
|
806
|
+
);
|
|
807
|
+
const [resolveRowProps] = useState2(() => createRowPropsResolver());
|
|
808
|
+
const rowPropsOf = resolveRowProps(
|
|
809
|
+
visibleRows.filter(
|
|
810
|
+
(entry) => !("kind" in entry)
|
|
811
|
+
),
|
|
812
|
+
getRowProps
|
|
813
|
+
);
|
|
993
814
|
function targetOf(target) {
|
|
994
|
-
const position =
|
|
815
|
+
const position = bodyCellFrom(target);
|
|
995
816
|
const entry = position === null ? void 0 : rows[position.rowIndex];
|
|
996
817
|
if (position === null || entry === void 0 || "kind" in entry) {
|
|
997
818
|
return null;
|
|
@@ -999,15 +820,39 @@ function GridBody({
|
|
|
999
820
|
return { position, rowId: entry.rowId };
|
|
1000
821
|
}
|
|
1001
822
|
function select(rowId, columnId, modifiers) {
|
|
1002
|
-
const intent = intentOf2(modifiers);
|
|
1003
823
|
if (rowMode !== false) {
|
|
1004
|
-
selection.selectRow(rowId,
|
|
824
|
+
selection.selectRow(rowId, intentOf2(modifiers, { toggleOnClick }));
|
|
1005
825
|
}
|
|
1006
826
|
if (cellMode !== false) {
|
|
1007
|
-
selection.selectCell({ rowId, columnId },
|
|
827
|
+
selection.selectCell({ rowId, columnId }, intentOf2(modifiers));
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
function rowPointerEventOf(event) {
|
|
831
|
+
const target = bodyRowFrom(event.target);
|
|
832
|
+
const entry = target === null ? void 0 : rows[target.rowIndex];
|
|
833
|
+
if (target === null || entry === void 0 || "kind" in entry) {
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
return {
|
|
837
|
+
row: entry,
|
|
838
|
+
columnId: target.columnId,
|
|
839
|
+
native: {
|
|
840
|
+
ctrlKey: event.ctrlKey,
|
|
841
|
+
metaKey: event.metaKey,
|
|
842
|
+
shiftKey: event.shiftKey,
|
|
843
|
+
altKey: event.altKey,
|
|
844
|
+
button: event.button
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
function reportRowPointer(event, callback) {
|
|
849
|
+
if (callback === void 0) return;
|
|
850
|
+
const pointer = rowPointerEventOf(event);
|
|
851
|
+
if (pointer !== null) {
|
|
852
|
+
callback(pointer);
|
|
1008
853
|
}
|
|
1009
854
|
}
|
|
1010
|
-
return /* @__PURE__ */
|
|
855
|
+
return /* @__PURE__ */ jsxs5(
|
|
1011
856
|
"tbody",
|
|
1012
857
|
{
|
|
1013
858
|
className: "grid-body",
|
|
@@ -1024,14 +869,20 @@ function GridBody({
|
|
|
1024
869
|
onClick: (event) => {
|
|
1025
870
|
const group = groupRowFrom(event.target);
|
|
1026
871
|
if (group !== null) {
|
|
1027
|
-
|
|
872
|
+
controller.toggleGroupExpansion(group.groupId);
|
|
1028
873
|
return;
|
|
1029
874
|
}
|
|
1030
875
|
const found = targetOf(event.target);
|
|
1031
|
-
if (found
|
|
1032
|
-
|
|
876
|
+
if (found !== null) {
|
|
877
|
+
select(found.rowId, found.position.columnId, event);
|
|
878
|
+
}
|
|
879
|
+
reportRowPointer(event, onRowClick);
|
|
880
|
+
},
|
|
881
|
+
onDoubleClick: (event) => {
|
|
882
|
+
reportRowPointer(event, onRowDoubleClick);
|
|
1033
883
|
},
|
|
1034
884
|
onKeyDown: (event) => {
|
|
885
|
+
if (!isOwnEvent(event)) return;
|
|
1035
886
|
const group = groupRowFrom(event.target);
|
|
1036
887
|
if (group !== null) {
|
|
1037
888
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
@@ -1040,7 +891,7 @@ function GridBody({
|
|
|
1040
891
|
}
|
|
1041
892
|
if (event.key === " " || event.key === "Enter") {
|
|
1042
893
|
event.preventDefault();
|
|
1043
|
-
|
|
894
|
+
controller.toggleGroupExpansion(group.groupId);
|
|
1044
895
|
return;
|
|
1045
896
|
}
|
|
1046
897
|
nav.onKeyDown(event);
|
|
@@ -1061,12 +912,12 @@ function GridBody({
|
|
|
1061
912
|
},
|
|
1062
913
|
children: [
|
|
1063
914
|
virtualRange !== null && virtualRange.offsetBefore > 0 && // `aria-hidden` and carrying neither `data-gridkit-column` nor
|
|
1064
|
-
// `data-gridkit-group`/`data-gridkit-row-index`, so `
|
|
915
|
+
// `data-gridkit-group`/`data-gridkit-row-index`, so `bodyCellFrom`/
|
|
1065
916
|
// `groupRowFrom` never mistake it for a real row — it exists purely
|
|
1066
917
|
// to give the browser's scrollbar the correct total height and thumb
|
|
1067
918
|
// position, the same way `GridFooter`'s `<tfoot>` isn't a "row" to
|
|
1068
919
|
// any of this grid's own row-counting logic.
|
|
1069
|
-
/* @__PURE__ */
|
|
920
|
+
/* @__PURE__ */ jsx7("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
|
|
1070
921
|
"td",
|
|
1071
922
|
{
|
|
1072
923
|
style: {
|
|
@@ -1078,7 +929,8 @@ function GridBody({
|
|
|
1078
929
|
) }),
|
|
1079
930
|
visibleRows.map((entry) => {
|
|
1080
931
|
if (!("kind" in entry)) {
|
|
1081
|
-
|
|
932
|
+
const rowProps = rowPropsOf(entry.rowId);
|
|
933
|
+
return /* @__PURE__ */ jsx7(
|
|
1082
934
|
GridRow_default,
|
|
1083
935
|
{
|
|
1084
936
|
ref: virtualRange?.measureRow(entry.rowIndex),
|
|
@@ -1093,13 +945,18 @@ function GridBody({
|
|
|
1093
945
|
selectedColumnId: selectedCell?.rowId === entry.rowId ? selectedCell.columnId : null,
|
|
1094
946
|
focusedColumnIndex: nav.focus.rowIndex === entry.rowIndex ? nav.focus.columnIndex : null,
|
|
1095
947
|
rowsSelectable: rowMode !== false,
|
|
1096
|
-
cellsSelectable: cellMode !== false
|
|
948
|
+
cellsSelectable: cellMode !== false,
|
|
949
|
+
contextMenu: cellMenu,
|
|
950
|
+
locale,
|
|
951
|
+
cellMessages,
|
|
952
|
+
rowClassName: rowProps.className,
|
|
953
|
+
rowAttributes: rowProps.attributes
|
|
1097
954
|
},
|
|
1098
955
|
entry.rowId
|
|
1099
956
|
);
|
|
1100
957
|
}
|
|
1101
958
|
if (entry.kind === "group-summary") {
|
|
1102
|
-
return /* @__PURE__ */
|
|
959
|
+
return /* @__PURE__ */ jsx7(
|
|
1103
960
|
GridGroupSummaryRow_default,
|
|
1104
961
|
{
|
|
1105
962
|
ref: virtualRange?.measureRow(entry.rowIndex),
|
|
@@ -1109,19 +966,20 @@ function GridBody({
|
|
|
1109
966
|
datasetIndex: entry.datasetIndex,
|
|
1110
967
|
results: entry.aggregates,
|
|
1111
968
|
aggregates,
|
|
1112
|
-
columns
|
|
969
|
+
columns,
|
|
970
|
+
locale
|
|
1113
971
|
},
|
|
1114
972
|
`${entry.groupId}-summary`
|
|
1115
973
|
);
|
|
1116
974
|
}
|
|
1117
|
-
return /* @__PURE__ */
|
|
975
|
+
return /* @__PURE__ */ jsx7(
|
|
1118
976
|
GridGroupRow_default,
|
|
1119
977
|
{
|
|
1120
978
|
ref: virtualRange?.measureRow(entry.rowIndex),
|
|
1121
979
|
columnCount: columns.length,
|
|
1122
980
|
groupId: entry.groupId,
|
|
1123
981
|
level: entry.level,
|
|
1124
|
-
|
|
982
|
+
groupColumn: definitions.get(entry.columnId) ?? { field: entry.columnId },
|
|
1125
983
|
value: entry.value,
|
|
1126
984
|
expanded: entry.expanded,
|
|
1127
985
|
count: entry.count,
|
|
@@ -1131,13 +989,16 @@ function GridBody({
|
|
|
1131
989
|
setsize: ariaMeta.get(entry.groupId)?.setsize ?? 1,
|
|
1132
990
|
aggregates: groupAggregateDisplay === "inline" ? aggregates : [],
|
|
1133
991
|
results: entry.aggregates,
|
|
1134
|
-
|
|
1135
|
-
|
|
992
|
+
definitions,
|
|
993
|
+
locale,
|
|
994
|
+
cellMessages,
|
|
995
|
+
focused: nav.focus.rowIndex === entry.rowIndex,
|
|
996
|
+
contextMenu: groupMenu
|
|
1136
997
|
},
|
|
1137
998
|
entry.groupId
|
|
1138
999
|
);
|
|
1139
1000
|
}),
|
|
1140
|
-
virtualRange !== null && virtualRange.offsetAfter > 0 && /* @__PURE__ */
|
|
1001
|
+
virtualRange !== null && virtualRange.offsetAfter > 0 && /* @__PURE__ */ jsx7("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
|
|
1141
1002
|
"td",
|
|
1142
1003
|
{
|
|
1143
1004
|
style: {
|
|
@@ -1147,15 +1008,15 @@ function GridBody({
|
|
|
1147
1008
|
}
|
|
1148
1009
|
}
|
|
1149
1010
|
) }),
|
|
1150
|
-
infiniteScroll?.hasMore && /* @__PURE__ */
|
|
1151
|
-
infiniteScroll.isLoadingMore === true && /* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1011
|
+
infiniteScroll?.hasMore && /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1012
|
+
infiniteScroll.isLoadingMore === true && /* @__PURE__ */ jsx7("tr", { "aria-hidden": "true", className: "grid-loading-row", children: /* @__PURE__ */ jsx7("td", { colSpan: columns.length, className: "grid-loading-cell", children: infiniteScroll.loadingTemplate ? infiniteScroll.loadingTemplate() : messages.loadingMore }) }),
|
|
1013
|
+
/* @__PURE__ */ jsx7(
|
|
1153
1014
|
"tr",
|
|
1154
1015
|
{
|
|
1155
1016
|
"aria-hidden": "true",
|
|
1156
1017
|
ref: sentinelRef,
|
|
1157
1018
|
className: "grid-sentinel-row",
|
|
1158
|
-
children: /* @__PURE__ */
|
|
1019
|
+
children: /* @__PURE__ */ jsx7(
|
|
1159
1020
|
"td",
|
|
1160
1021
|
{
|
|
1161
1022
|
colSpan: columns.length,
|
|
@@ -1171,29 +1032,34 @@ function GridBody({
|
|
|
1171
1032
|
}
|
|
1172
1033
|
|
|
1173
1034
|
// src/DataGrid/components/GridFooter.tsx
|
|
1174
|
-
import { jsx as
|
|
1035
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1175
1036
|
function GridFooter({
|
|
1176
1037
|
columns,
|
|
1177
1038
|
aggregates,
|
|
1178
1039
|
results,
|
|
1179
|
-
rows
|
|
1040
|
+
rows,
|
|
1041
|
+
locale
|
|
1180
1042
|
}) {
|
|
1181
|
-
return /* @__PURE__ */
|
|
1043
|
+
return /* @__PURE__ */ jsx8("tfoot", { children: /* @__PURE__ */ jsx8("tr", { className: "grid-footer", role: "row", children: columns.map((entry) => {
|
|
1182
1044
|
const specs = aggregates.filter(
|
|
1183
1045
|
(candidate) => candidate.columnId === entry.id
|
|
1184
1046
|
);
|
|
1185
|
-
|
|
1186
|
-
return /* @__PURE__ */ jsx7(
|
|
1047
|
+
return /* @__PURE__ */ jsx8(
|
|
1187
1048
|
"td",
|
|
1188
1049
|
{
|
|
1189
1050
|
role: "gridcell",
|
|
1190
1051
|
"data-gridkit-column": entry.id,
|
|
1191
1052
|
className: "grid-footer-cell",
|
|
1192
1053
|
style: { textAlign: specs[0]?.alignment ?? entry.alignment },
|
|
1193
|
-
children: specs.map(
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1054
|
+
children: specs.map(
|
|
1055
|
+
(spec) => renderAggregate(
|
|
1056
|
+
results.get(spec.id ?? spec.columnId),
|
|
1057
|
+
spec,
|
|
1058
|
+
entry.column,
|
|
1059
|
+
rows,
|
|
1060
|
+
locale
|
|
1061
|
+
)
|
|
1062
|
+
).flatMap(
|
|
1197
1063
|
(rendered, index) => index === 0 ? [rendered] : [", ", rendered]
|
|
1198
1064
|
)
|
|
1199
1065
|
},
|
|
@@ -1204,223 +1070,140 @@ function GridFooter({
|
|
|
1204
1070
|
|
|
1205
1071
|
// src/DataGrid/components/GridPager.tsx
|
|
1206
1072
|
import { paginationWindow } from "@gridkitjs/core";
|
|
1207
|
-
import { jsx as
|
|
1208
|
-
function GridPager({ pager, config }) {
|
|
1073
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1074
|
+
function GridPager({ pager, config, messages }) {
|
|
1209
1075
|
const { pagination, pageCount, currentPage } = pager;
|
|
1210
1076
|
const variant = config?.variant ?? "compact";
|
|
1211
1077
|
const sizeOptions = config?.sizeOptions;
|
|
1212
|
-
return /* @__PURE__ */
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
{
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1078
|
+
return /* @__PURE__ */ jsxs6(
|
|
1079
|
+
"div",
|
|
1080
|
+
{
|
|
1081
|
+
className: "gridkit-grid-pager",
|
|
1082
|
+
role: "group",
|
|
1083
|
+
"aria-label": messages.pagerLabel,
|
|
1084
|
+
children: [
|
|
1085
|
+
/* @__PURE__ */ jsx9(
|
|
1086
|
+
"button",
|
|
1087
|
+
{
|
|
1088
|
+
type: "button",
|
|
1089
|
+
className: "grid-pager-button",
|
|
1090
|
+
disabled: pagination.pageIndex <= 0,
|
|
1091
|
+
onClick: () => {
|
|
1092
|
+
pager.previousPage();
|
|
1093
|
+
},
|
|
1094
|
+
children: messages.previousPage
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
variant === "numbered" ? paginationWindow(currentPage, pageCount, {
|
|
1098
|
+
boundaryCount: config?.boundaryCount,
|
|
1099
|
+
siblingCount: config?.siblingCount
|
|
1100
|
+
}).map(
|
|
1101
|
+
(entry, index) => entry === "ellipsis" ? /* @__PURE__ */ jsx9(
|
|
1102
|
+
"span",
|
|
1103
|
+
{
|
|
1104
|
+
className: "grid-pager-ellipsis",
|
|
1105
|
+
"aria-hidden": "true",
|
|
1106
|
+
children: "\u2026"
|
|
1107
|
+
},
|
|
1108
|
+
`ellipsis-${String(index)}`
|
|
1109
|
+
) : /* @__PURE__ */ jsx9(
|
|
1110
|
+
"button",
|
|
1111
|
+
{
|
|
1112
|
+
type: "button",
|
|
1113
|
+
className: "grid-pager-button",
|
|
1114
|
+
"aria-label": messages.pageButtonLabel(entry),
|
|
1115
|
+
"aria-current": entry === currentPage ? "page" : void 0,
|
|
1116
|
+
onClick: () => {
|
|
1117
|
+
pager.goToPage(entry - 1);
|
|
1118
|
+
},
|
|
1119
|
+
children: entry
|
|
1120
|
+
},
|
|
1121
|
+
entry
|
|
1122
|
+
)
|
|
1123
|
+
) : /* @__PURE__ */ jsx9("span", { className: "grid-pager-status", children: messages.pageStatus(pageCount === 0 ? 0 : currentPage, pageCount) }),
|
|
1124
|
+
/* @__PURE__ */ jsx9(
|
|
1125
|
+
"button",
|
|
1126
|
+
{
|
|
1127
|
+
type: "button",
|
|
1128
|
+
className: "grid-pager-button",
|
|
1129
|
+
disabled: pagination.pageIndex >= pageCount - 1,
|
|
1130
|
+
onClick: () => {
|
|
1131
|
+
pager.nextPage();
|
|
1132
|
+
},
|
|
1133
|
+
children: messages.nextPage
|
|
1134
|
+
}
|
|
1135
|
+
),
|
|
1136
|
+
sizeOptions !== void 0 && sizeOptions.length > 0 && /* @__PURE__ */ jsxs6("label", { className: "grid-pager-page-size", children: [
|
|
1137
|
+
messages.pageSizeLabel,
|
|
1138
|
+
/* @__PURE__ */ jsx9(
|
|
1139
|
+
"select",
|
|
1140
|
+
{
|
|
1141
|
+
value: pagination.pageSize,
|
|
1142
|
+
onChange: (event) => {
|
|
1143
|
+
pager.setPageSize(Number(event.target.value));
|
|
1144
|
+
},
|
|
1145
|
+
children: sizeOptions.map((size) => /* @__PURE__ */ jsx9("option", { value: size, children: size }, size))
|
|
1146
|
+
}
|
|
1147
|
+
)
|
|
1148
|
+
] })
|
|
1149
|
+
]
|
|
1150
|
+
}
|
|
1151
|
+
);
|
|
1283
1152
|
}
|
|
1284
1153
|
|
|
1285
1154
|
// src/DataGrid/components/GroupByBar.tsx
|
|
1286
1155
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1287
|
-
import { resolveKeyboardDropTarget } from "@gridkitjs/core";
|
|
1288
|
-
|
|
1289
|
-
// src/DataGrid/groupByDropTarget.ts
|
|
1290
1156
|
import {
|
|
1291
|
-
|
|
1292
|
-
|
|
1157
|
+
resolveColumnLabel as resolveColumnLabel2,
|
|
1158
|
+
resolveKeyboardDropTarget
|
|
1293
1159
|
} from "@gridkitjs/core";
|
|
1294
1160
|
|
|
1295
|
-
// src/DataGrid/
|
|
1161
|
+
// src/DataGrid/useGroupByDrag.ts
|
|
1296
1162
|
import {
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
} from "react";
|
|
1300
|
-
|
|
1301
|
-
// src/DataGrid/pointerGesture.ts
|
|
1302
|
-
function startPointerGesture(element, pointerId, handlers) {
|
|
1303
|
-
element.setPointerCapture(pointerId);
|
|
1304
|
-
function stop() {
|
|
1305
|
-
element.removeEventListener("pointermove", move);
|
|
1306
|
-
element.removeEventListener("pointerup", end);
|
|
1307
|
-
element.removeEventListener("pointercancel", cancel);
|
|
1308
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1309
|
-
if (element.hasPointerCapture(pointerId)) {
|
|
1310
|
-
element.releasePointerCapture(pointerId);
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
function move(event) {
|
|
1314
|
-
handlers.onMove(event);
|
|
1315
|
-
}
|
|
1316
|
-
function end() {
|
|
1317
|
-
stop();
|
|
1318
|
-
handlers.onEnd();
|
|
1319
|
-
}
|
|
1320
|
-
function cancel() {
|
|
1321
|
-
stop();
|
|
1322
|
-
handlers.onCancel();
|
|
1323
|
-
}
|
|
1324
|
-
function onKeyDown(event) {
|
|
1325
|
-
if (event.key === "Escape") {
|
|
1326
|
-
cancel();
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
element.addEventListener("pointermove", move);
|
|
1330
|
-
element.addEventListener("pointerup", end);
|
|
1331
|
-
element.addEventListener("pointercancel", cancel);
|
|
1332
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1333
|
-
}
|
|
1163
|
+
resolveGroupByDropTarget
|
|
1164
|
+
} from "@gridkitjs/dom";
|
|
1334
1165
|
|
|
1335
1166
|
// src/DataGrid/useDragReorder.ts
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
}
|
|
1167
|
+
import {
|
|
1168
|
+
useRef,
|
|
1169
|
+
useState as useState3
|
|
1170
|
+
} from "react";
|
|
1171
|
+
import {
|
|
1172
|
+
NO_DRAG,
|
|
1173
|
+
startDragReorder
|
|
1174
|
+
} from "@gridkitjs/dom";
|
|
1344
1175
|
function useDragReorder({
|
|
1345
1176
|
resolveTarget,
|
|
1346
1177
|
onDrop
|
|
1347
1178
|
}) {
|
|
1348
|
-
const [
|
|
1349
|
-
const
|
|
1350
|
-
const [ghostTransform, setGhostTransform] = useState2(null);
|
|
1351
|
-
const dragged = useRef3(false);
|
|
1179
|
+
const [drag, setDrag] = useState3(NO_DRAG);
|
|
1180
|
+
const dragged = useRef(false);
|
|
1352
1181
|
function justDragged() {
|
|
1353
1182
|
const answer = dragged.current;
|
|
1354
1183
|
dragged.current = false;
|
|
1355
1184
|
return answer;
|
|
1356
1185
|
}
|
|
1357
1186
|
function startDrag(id, grabElement, event) {
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
function placeGhost(x, y) {
|
|
1363
|
-
setGhostTransform(`translate(${String(x - grabX)}px, ${String(y)}px)`);
|
|
1364
|
-
}
|
|
1365
|
-
function reset() {
|
|
1366
|
-
setGhostTransform(null);
|
|
1367
|
-
setDraggedId(null);
|
|
1368
|
-
setDropTarget(null);
|
|
1369
|
-
}
|
|
1370
|
-
startPointerGesture(grabElement, pointerId, {
|
|
1371
|
-
onMove(moveEvent) {
|
|
1372
|
-
const { clientX, clientY } = moveEvent;
|
|
1373
|
-
if (!dragging) {
|
|
1374
|
-
if (Math.abs(clientX - startX) < DRAG_THRESHOLD) {
|
|
1375
|
-
return;
|
|
1376
|
-
}
|
|
1377
|
-
dragging = true;
|
|
1187
|
+
startDragReorder(id, grabElement, event, {
|
|
1188
|
+
resolveTarget,
|
|
1189
|
+
onState(state) {
|
|
1190
|
+
if (state.draggedId !== null) {
|
|
1378
1191
|
dragged.current = true;
|
|
1379
|
-
setDraggedId(id);
|
|
1380
|
-
}
|
|
1381
|
-
placeGhost(clientX, clientY);
|
|
1382
|
-
target = resolveTarget(clientX, clientY, id);
|
|
1383
|
-
setDropTarget(target);
|
|
1384
|
-
},
|
|
1385
|
-
onEnd() {
|
|
1386
|
-
const dropped = target;
|
|
1387
|
-
reset();
|
|
1388
|
-
if (dragging && dropped !== null) {
|
|
1389
|
-
onDrop(dropped, id);
|
|
1390
1192
|
}
|
|
1193
|
+
setDrag(state);
|
|
1391
1194
|
},
|
|
1392
|
-
|
|
1393
|
-
onCancel() {
|
|
1394
|
-
target = null;
|
|
1395
|
-
reset();
|
|
1396
|
-
}
|
|
1195
|
+
onDrop
|
|
1397
1196
|
});
|
|
1398
1197
|
}
|
|
1399
1198
|
return {
|
|
1400
|
-
draggedId,
|
|
1401
|
-
dropTarget,
|
|
1402
|
-
ghostTransform,
|
|
1199
|
+
draggedId: drag.draggedId,
|
|
1200
|
+
dropTarget: drag.dropTarget,
|
|
1201
|
+
ghostTransform: drag.ghostTransform,
|
|
1403
1202
|
startDrag,
|
|
1404
1203
|
justDragged
|
|
1405
1204
|
};
|
|
1406
1205
|
}
|
|
1407
1206
|
|
|
1408
|
-
// src/DataGrid/groupByDropTarget.ts
|
|
1409
|
-
function resolveGroupByDropTarget(clientX, clientY, movedId, groupBy) {
|
|
1410
|
-
const overBar = elementAt(clientX, clientY, "[data-gridkit-group-by-bar]");
|
|
1411
|
-
if (overBar === null) {
|
|
1412
|
-
return null;
|
|
1413
|
-
}
|
|
1414
|
-
const overChip = elementAt(clientX, clientY, "[data-gridkit-group-chip]");
|
|
1415
|
-
const chipId = overChip?.getAttribute("data-gridkit-group-chip");
|
|
1416
|
-
const beforeColumnId = overChip && chipId ? resolveDropBefore(
|
|
1417
|
-
groupBy.map((entry) => entry.columnId),
|
|
1418
|
-
chipId,
|
|
1419
|
-
sideOf(overChip, clientX)
|
|
1420
|
-
) : null;
|
|
1421
|
-
return movesGroupBy(groupBy, movedId, beforeColumnId) ? { kind: "group-by", beforeColumnId } : null;
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
1207
|
// src/DataGrid/useGroupByDrag.ts
|
|
1425
1208
|
function useGroupByDrag({
|
|
1426
1209
|
groupBy,
|
|
@@ -1444,28 +1227,31 @@ function useGroupByDrag({
|
|
|
1444
1227
|
}
|
|
1445
1228
|
|
|
1446
1229
|
// src/DataGrid/components/GroupByBar.tsx
|
|
1447
|
-
import { jsx as
|
|
1230
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1448
1231
|
function GroupByBar({
|
|
1449
1232
|
columns,
|
|
1450
|
-
|
|
1233
|
+
definitions,
|
|
1234
|
+
groupBy,
|
|
1235
|
+
controller,
|
|
1451
1236
|
columnName,
|
|
1452
1237
|
headerDragEligible,
|
|
1453
1238
|
headerDragBlocked,
|
|
1454
|
-
headerDropTarget
|
|
1239
|
+
headerDropTarget,
|
|
1240
|
+
messages
|
|
1455
1241
|
}) {
|
|
1456
|
-
const { groupBy } = grouping;
|
|
1457
1242
|
const groupByIds = groupBy.map((entry) => entry.columnId);
|
|
1458
1243
|
const chipDrag = useGroupByDrag({
|
|
1459
1244
|
groupBy,
|
|
1460
1245
|
onDrop: (movedId, beforeColumnId) => {
|
|
1461
|
-
|
|
1246
|
+
controller.moveGroupBy(movedId, beforeColumnId);
|
|
1462
1247
|
}
|
|
1463
1248
|
});
|
|
1464
1249
|
const activeDropTarget = chipDrag.dropTarget ?? headerDropTarget;
|
|
1465
1250
|
const isDragTarget = chipDrag.draggedColumnId !== null || headerDragEligible;
|
|
1466
1251
|
const showPlaceholder = groupBy.length === 0 && columns.some((entry) => entry.groupByDraggable);
|
|
1467
1252
|
function labelFor(columnId) {
|
|
1468
|
-
|
|
1253
|
+
const definition = definitions.get(columnId);
|
|
1254
|
+
return definition === void 0 ? columnId : resolveColumnLabel2(definition);
|
|
1469
1255
|
}
|
|
1470
1256
|
function moveByKeyboard(columnId, direction) {
|
|
1471
1257
|
const beforeColumnId = resolveKeyboardDropTarget(
|
|
@@ -1476,9 +1262,9 @@ function GroupByBar({
|
|
|
1476
1262
|
if (beforeColumnId === void 0) {
|
|
1477
1263
|
return;
|
|
1478
1264
|
}
|
|
1479
|
-
|
|
1265
|
+
controller.moveGroupBy(columnId, beforeColumnId);
|
|
1480
1266
|
}
|
|
1481
|
-
return /* @__PURE__ */
|
|
1267
|
+
return /* @__PURE__ */ jsxs7(
|
|
1482
1268
|
"div",
|
|
1483
1269
|
{
|
|
1484
1270
|
className: classNames(
|
|
@@ -1488,14 +1274,14 @@ function GroupByBar({
|
|
|
1488
1274
|
),
|
|
1489
1275
|
"data-gridkit-group-by-bar": "",
|
|
1490
1276
|
role: "group",
|
|
1491
|
-
"aria-label":
|
|
1277
|
+
"aria-label": messages.groupByBarLabel,
|
|
1492
1278
|
children: [
|
|
1493
|
-
showPlaceholder && /* @__PURE__ */
|
|
1279
|
+
showPlaceholder && /* @__PURE__ */ jsx10("span", { className: "group-by-bar-placeholder", children: messages.groupByBarPlaceholder }),
|
|
1494
1280
|
groupBy.map((entry, index) => {
|
|
1495
1281
|
const dropBefore = activeDropTarget?.beforeColumnId === entry.columnId;
|
|
1496
1282
|
const dropAfter = activeDropTarget?.beforeColumnId === null && index === groupBy.length - 1;
|
|
1497
1283
|
const dragging = chipDrag.draggedColumnId === entry.columnId;
|
|
1498
|
-
return /* @__PURE__ */
|
|
1284
|
+
return /* @__PURE__ */ jsxs7(
|
|
1499
1285
|
"span",
|
|
1500
1286
|
{
|
|
1501
1287
|
className: classNames(
|
|
@@ -1506,7 +1292,11 @@ function GroupByBar({
|
|
|
1506
1292
|
),
|
|
1507
1293
|
"data-gridkit-group-chip": entry.columnId,
|
|
1508
1294
|
tabIndex: 0,
|
|
1509
|
-
"aria-label":
|
|
1295
|
+
"aria-label": messages.groupByChipLabel(
|
|
1296
|
+
columnName(entry.columnId),
|
|
1297
|
+
index + 1,
|
|
1298
|
+
groupBy.length
|
|
1299
|
+
),
|
|
1510
1300
|
"aria-keyshortcuts": "Control+ArrowLeft Control+ArrowRight",
|
|
1511
1301
|
onPointerDown: (event) => {
|
|
1512
1302
|
chipDrag.startDrag(entry.columnId, event);
|
|
@@ -1522,18 +1312,18 @@ function GroupByBar({
|
|
|
1522
1312
|
}
|
|
1523
1313
|
},
|
|
1524
1314
|
children: [
|
|
1525
|
-
/* @__PURE__ */
|
|
1526
|
-
/* @__PURE__ */
|
|
1315
|
+
/* @__PURE__ */ jsx10("span", { className: "group-by-chip-label", children: labelFor(entry.columnId) }),
|
|
1316
|
+
/* @__PURE__ */ jsx10(
|
|
1527
1317
|
"button",
|
|
1528
1318
|
{
|
|
1529
1319
|
type: "button",
|
|
1530
1320
|
className: "group-by-chip-remove",
|
|
1531
|
-
"aria-label":
|
|
1321
|
+
"aria-label": messages.removeGroupBy(columnName(entry.columnId)),
|
|
1532
1322
|
onPointerDown: (event) => {
|
|
1533
1323
|
event.stopPropagation();
|
|
1534
1324
|
},
|
|
1535
1325
|
onClick: () => {
|
|
1536
|
-
|
|
1326
|
+
controller.toggleGroupBy(entry.columnId);
|
|
1537
1327
|
},
|
|
1538
1328
|
children: "\xD7"
|
|
1539
1329
|
}
|
|
@@ -1544,7 +1334,7 @@ function GroupByBar({
|
|
|
1544
1334
|
);
|
|
1545
1335
|
}),
|
|
1546
1336
|
chipDrag.draggedColumnId !== null && chipDrag.ghostTransform !== null && createPortal2(
|
|
1547
|
-
/* @__PURE__ */
|
|
1337
|
+
/* @__PURE__ */ jsx10(
|
|
1548
1338
|
"span",
|
|
1549
1339
|
{
|
|
1550
1340
|
className: "group-by-chip drag-ghost",
|
|
@@ -1560,167 +1350,1553 @@ function GroupByBar({
|
|
|
1560
1350
|
);
|
|
1561
1351
|
}
|
|
1562
1352
|
|
|
1563
|
-
// src/DataGrid/
|
|
1353
|
+
// src/DataGrid/announcedCallbacks.ts
|
|
1564
1354
|
import {
|
|
1565
|
-
|
|
1566
|
-
resolveDropBefore as resolveDropBefore2,
|
|
1567
|
-
resolveKeyboardDropTarget as resolveKeyboardDropTarget2
|
|
1355
|
+
isColumnVisible
|
|
1568
1356
|
} from "@gridkitjs/core";
|
|
1569
|
-
function
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1357
|
+
function announcedCallbacks({
|
|
1358
|
+
callbacks,
|
|
1359
|
+
announce,
|
|
1360
|
+
messages,
|
|
1361
|
+
columnName,
|
|
1362
|
+
columnOf
|
|
1574
1363
|
}) {
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1364
|
+
return {
|
|
1365
|
+
/**
|
|
1366
|
+
* Announced only once the drag ends: the controller reports the
|
|
1367
|
+
* continuous `"move"` phase as well, and a live region given every frame
|
|
1368
|
+
* of a drag says nothing an assistive technology can keep up with.
|
|
1369
|
+
*/
|
|
1370
|
+
onColumnResize: (event) => {
|
|
1371
|
+
callbacks.onColumnResize?.(event);
|
|
1372
|
+
if (event.phase === "end") {
|
|
1373
|
+
announce(
|
|
1374
|
+
messages.columnResized(
|
|
1375
|
+
columnName(event.columnId),
|
|
1376
|
+
Math.round(event.width)
|
|
1377
|
+
)
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
},
|
|
1381
|
+
/**
|
|
1382
|
+
* Naming a column shown or hidden alone, and counting several — "Show
|
|
1383
|
+
* all" in the column chooser, or `hideColumns` given a list. A change
|
|
1384
|
+
* that shows some and hides others, as restoring a layout can, has no
|
|
1385
|
+
* one thing to say, and says nothing.
|
|
1386
|
+
*/
|
|
1387
|
+
onColumnVisibilityChange: (event) => {
|
|
1388
|
+
callbacks.onColumnVisibilityChange?.(event);
|
|
1389
|
+
const { columnIds, visibility } = event;
|
|
1390
|
+
const [columnId] = columnIds;
|
|
1391
|
+
const shownCount = columnIds.filter((id) => {
|
|
1392
|
+
const column = columnOf(id);
|
|
1393
|
+
return column !== void 0 && isColumnVisible(column, visibility);
|
|
1394
|
+
}).length;
|
|
1395
|
+
if (columnId === void 0 || shownCount !== 0 && shownCount !== columnIds.length) {
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
const shown = shownCount > 0;
|
|
1399
|
+
if (columnIds.length > 1) {
|
|
1400
|
+
announce(
|
|
1401
|
+
shown ? messages.columnsShown(columnIds.length) : messages.columnsHidden(columnIds.length)
|
|
1402
|
+
);
|
|
1403
|
+
return;
|
|
1582
1404
|
}
|
|
1583
|
-
|
|
1584
|
-
(
|
|
1405
|
+
announce(
|
|
1406
|
+
shown ? messages.columnShown(columnName(columnId)) : messages.columnHidden(columnName(columnId))
|
|
1585
1407
|
);
|
|
1586
|
-
return groupByDraggableIds.has(movedId) && !alreadyGrouped ? resolveGroupByDropTarget(clientX, clientY, movedId, groupBy) : null;
|
|
1587
1408
|
},
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1409
|
+
/** A toggle, a stack, or a clear back to "none" each get their own. */
|
|
1410
|
+
onColumnSortChange: (event) => {
|
|
1411
|
+
callbacks.onColumnSortChange?.(event);
|
|
1412
|
+
const entry = event.sort.find(
|
|
1413
|
+
(candidate) => candidate.columnId === event.columnId
|
|
1414
|
+
);
|
|
1415
|
+
if (entry === void 0) {
|
|
1416
|
+
announce(messages.sortCleared(columnName(event.columnId)));
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
announce(
|
|
1420
|
+
messages.columnSorted(
|
|
1421
|
+
columnName(event.columnId),
|
|
1422
|
+
entry.direction,
|
|
1423
|
+
event.sort.indexOf(entry) + 1,
|
|
1424
|
+
event.sort.length
|
|
1425
|
+
)
|
|
1426
|
+
);
|
|
1427
|
+
},
|
|
1428
|
+
onGroupByChange: (event) => {
|
|
1429
|
+
callbacks.onGroupByChange?.(event);
|
|
1430
|
+
const entry = event.groupBy.find(
|
|
1431
|
+
(candidate) => candidate.columnId === event.columnId
|
|
1432
|
+
);
|
|
1433
|
+
if (entry === void 0) {
|
|
1434
|
+
announce(messages.groupingRemoved(columnName(event.columnId)));
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
announce(
|
|
1438
|
+
messages.groupedBy(
|
|
1439
|
+
columnName(event.columnId),
|
|
1440
|
+
event.groupBy.indexOf(entry) + 1,
|
|
1441
|
+
event.groupBy.length
|
|
1442
|
+
)
|
|
1443
|
+
);
|
|
1444
|
+
},
|
|
1445
|
+
/**
|
|
1446
|
+
* `groupId: null` marks `expandAll`/`collapseAll`, which touch every
|
|
1447
|
+
* group in one call rather than one at a time — announced as a single
|
|
1448
|
+
* summary instead of naming a group that doesn't apply.
|
|
1449
|
+
*/
|
|
1450
|
+
onGroupExpansionChange: (event) => {
|
|
1451
|
+
callbacks.onGroupExpansionChange?.(event);
|
|
1452
|
+
if (event.groupId === null) {
|
|
1453
|
+
announce(
|
|
1454
|
+
event.expansion.length === 0 ? messages.allGroupsExpanded : messages.allGroupsCollapsed
|
|
1455
|
+
);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
announce(
|
|
1459
|
+
event.expansion.includes(event.groupId) ? messages.groupCollapsed : messages.groupExpanded
|
|
1460
|
+
);
|
|
1461
|
+
},
|
|
1462
|
+
onPaginationChange: (event) => {
|
|
1463
|
+
callbacks.onPaginationChange?.(event);
|
|
1464
|
+
announce(
|
|
1465
|
+
messages.pageStatus(event.pagination.pageIndex + 1, event.pageCount)
|
|
1466
|
+
);
|
|
1467
|
+
},
|
|
1468
|
+
/**
|
|
1469
|
+
* Unlike rows and columns, a cell selection is always exactly one cell —
|
|
1470
|
+
* there is no multi-cell range — so it never crosses the count's >1
|
|
1471
|
+
* threshold and the focused cell's own `aria-selected` is the only
|
|
1472
|
+
* feedback a screen-reader user would otherwise get. Announced on every
|
|
1473
|
+
* change that lands on a cell instead.
|
|
1474
|
+
*/
|
|
1475
|
+
onCellSelectionChange: (event) => {
|
|
1476
|
+
callbacks.onCellSelectionChange?.(event);
|
|
1477
|
+
if (event.selected !== null) {
|
|
1478
|
+
announce(
|
|
1479
|
+
messages.cellSelected(
|
|
1480
|
+
columnName(event.selected.columnId),
|
|
1481
|
+
event.selected.rowIndex + 1
|
|
1482
|
+
)
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
},
|
|
1486
|
+
/**
|
|
1487
|
+
* Announced only for a change touching more than one row or column. A
|
|
1488
|
+
* single selection is already carried by the focused member's own
|
|
1489
|
+
* `aria-selected`, and repeating it here would talk over that. Counted
|
|
1490
|
+
* by id, so rows the change touched off screen — on another page, in a
|
|
1491
|
+
* collapsed group — count too.
|
|
1492
|
+
*/
|
|
1493
|
+
onSelectionDiff: (event) => {
|
|
1494
|
+
if (event.added.length + event.removed.length > 1) {
|
|
1495
|
+
announce(messages.selectedCount(event.selection.length, event.target));
|
|
1496
|
+
}
|
|
1597
1497
|
}
|
|
1598
|
-
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// src/DataGrid/commands/useGridCommands.ts
|
|
1502
|
+
import { useMemo as useMemo3 } from "react";
|
|
1503
|
+
import {
|
|
1504
|
+
createCommandContext,
|
|
1505
|
+
resolveCommands,
|
|
1506
|
+
runCommand
|
|
1507
|
+
} from "@gridkitjs/core";
|
|
1508
|
+
function useGridCommands({
|
|
1509
|
+
controller,
|
|
1510
|
+
commands: appCommands,
|
|
1511
|
+
onCommand,
|
|
1512
|
+
messages,
|
|
1513
|
+
announce,
|
|
1514
|
+
resize,
|
|
1515
|
+
openPanel
|
|
1516
|
+
}) {
|
|
1517
|
+
const commands = useMemo3(() => resolveCommands(appCommands), [appCommands]);
|
|
1518
|
+
const host = {
|
|
1519
|
+
autoFitColumns: (columnIds) => {
|
|
1520
|
+
const { columns } = controller.getView();
|
|
1521
|
+
let fitted = 0;
|
|
1522
|
+
for (const columnId of columnIds) {
|
|
1523
|
+
const entry = columns.find((candidate) => candidate.id === columnId);
|
|
1524
|
+
if (entry !== void 0 && resize.sizeToContent(entry)) {
|
|
1525
|
+
fitted += 1;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
if (fitted > 1) {
|
|
1529
|
+
announce(messages.columnsAutoFitted(fitted));
|
|
1530
|
+
}
|
|
1531
|
+
},
|
|
1532
|
+
openPanel,
|
|
1533
|
+
announce
|
|
1534
|
+
};
|
|
1535
|
+
function contextFor(target) {
|
|
1536
|
+
return createCommandContext({ controller, target, messages, host });
|
|
1537
|
+
}
|
|
1538
|
+
function report(commandId, target, source) {
|
|
1539
|
+
onCommand?.({ commandId, target, source });
|
|
1599
1540
|
}
|
|
1600
1541
|
return {
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1542
|
+
commands,
|
|
1543
|
+
host,
|
|
1544
|
+
contextFor,
|
|
1545
|
+
report,
|
|
1546
|
+
run: (commandId, target, source) => {
|
|
1547
|
+
const command = commands.get(commandId);
|
|
1548
|
+
if (command === void 0) {
|
|
1549
|
+
console.error(`DataGrid: there is no command \`${commandId}\` to run.`);
|
|
1550
|
+
return false;
|
|
1551
|
+
}
|
|
1552
|
+
if (!runCommand(command, contextFor(target))) {
|
|
1553
|
+
return false;
|
|
1554
|
+
}
|
|
1555
|
+
report(commandId, target, source);
|
|
1556
|
+
return true;
|
|
1557
|
+
}
|
|
1607
1558
|
};
|
|
1608
1559
|
}
|
|
1609
1560
|
|
|
1610
|
-
// src/DataGrid/
|
|
1561
|
+
// src/DataGrid/menu/GridMenu.tsx
|
|
1562
|
+
import { useLayoutEffect as useLayoutEffect3, useRef as useRef3, useState as useState4 } from "react";
|
|
1611
1563
|
import {
|
|
1612
|
-
|
|
1613
|
-
} from "
|
|
1614
|
-
import {
|
|
1615
|
-
applyColumnResize,
|
|
1616
|
-
beginColumnResize,
|
|
1617
|
-
clampColumnWidth,
|
|
1618
|
-
resolveColumnConstraints,
|
|
1619
|
-
revertColumnSize,
|
|
1620
|
-
sizeColumnToContent
|
|
1621
|
-
} from "@gridkitjs/core";
|
|
1564
|
+
attachMenu
|
|
1565
|
+
} from "@gridkitjs/dom";
|
|
1622
1566
|
|
|
1623
|
-
// src/DataGrid/
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1567
|
+
// src/DataGrid/overlay/Overlay.tsx
|
|
1568
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef2 } from "react";
|
|
1569
|
+
import { createPortal as createPortal3 } from "react-dom";
|
|
1570
|
+
import {
|
|
1571
|
+
attachOverlay
|
|
1572
|
+
} from "@gridkitjs/dom";
|
|
1573
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1574
|
+
var ANCHOR_GAP = 4;
|
|
1575
|
+
function overlayThemeClassName(element) {
|
|
1576
|
+
const scope = element?.closest(".gridkit-light, .gridkit-dark");
|
|
1577
|
+
if (scope === null || scope === void 0) {
|
|
1578
|
+
return "";
|
|
1579
|
+
}
|
|
1580
|
+
return scope.classList.contains("gridkit-dark") ? "gridkit-dark" : "gridkit-light";
|
|
1581
|
+
}
|
|
1582
|
+
function Overlay({
|
|
1583
|
+
anchor,
|
|
1584
|
+
placement,
|
|
1585
|
+
gap,
|
|
1586
|
+
offset,
|
|
1587
|
+
initialFocus,
|
|
1588
|
+
returnFocusTo,
|
|
1589
|
+
ignoreScrollAfterInput,
|
|
1590
|
+
themeClassName,
|
|
1591
|
+
onDismiss,
|
|
1592
|
+
children
|
|
1593
|
+
}) {
|
|
1594
|
+
const panelRef = useRef2(null);
|
|
1595
|
+
const onDismissRef = useRef2(onDismiss);
|
|
1596
|
+
useLayoutEffect2(() => {
|
|
1597
|
+
onDismissRef.current = onDismiss;
|
|
1598
|
+
});
|
|
1599
|
+
useLayoutEffect2(() => {
|
|
1600
|
+
const panel = panelRef.current;
|
|
1601
|
+
if (panel === null) {
|
|
1602
|
+
return void 0;
|
|
1636
1603
|
}
|
|
1637
|
-
|
|
1638
|
-
|
|
1604
|
+
return attachOverlay(anchor, panel, {
|
|
1605
|
+
placement,
|
|
1606
|
+
gap,
|
|
1607
|
+
offset,
|
|
1608
|
+
initialFocus,
|
|
1609
|
+
returnFocusTo,
|
|
1610
|
+
ignoreScrollAfterInput,
|
|
1611
|
+
onDismiss: (reason) => {
|
|
1612
|
+
onDismissRef.current(reason);
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
}, [
|
|
1616
|
+
anchor,
|
|
1617
|
+
placement,
|
|
1618
|
+
gap,
|
|
1619
|
+
offset,
|
|
1620
|
+
initialFocus,
|
|
1621
|
+
returnFocusTo,
|
|
1622
|
+
ignoreScrollAfterInput
|
|
1623
|
+
]);
|
|
1624
|
+
return createPortal3(
|
|
1625
|
+
/* @__PURE__ */ jsx11(
|
|
1626
|
+
"div",
|
|
1627
|
+
{
|
|
1628
|
+
ref: panelRef,
|
|
1629
|
+
className: classNames("gridkit-overlay", themeClassName),
|
|
1630
|
+
children
|
|
1631
|
+
}
|
|
1632
|
+
),
|
|
1633
|
+
document.body
|
|
1634
|
+
);
|
|
1639
1635
|
}
|
|
1640
1636
|
|
|
1641
|
-
// src/DataGrid/
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1637
|
+
// src/DataGrid/menu/menuIcons.tsx
|
|
1638
|
+
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1639
|
+
var BUILT_IN_ICONS = {
|
|
1640
|
+
sortAscending: () => /* @__PURE__ */ jsxs8(Icon, { children: [
|
|
1641
|
+
/* @__PURE__ */ jsx12("path", { d: "m3 8 4-4 4 4" }),
|
|
1642
|
+
/* @__PURE__ */ jsx12("path", { d: "M7 4v16" }),
|
|
1643
|
+
/* @__PURE__ */ jsx12("path", { d: "M11 12h4" }),
|
|
1644
|
+
/* @__PURE__ */ jsx12("path", { d: "M11 16h7" }),
|
|
1645
|
+
/* @__PURE__ */ jsx12("path", { d: "M11 20h10" })
|
|
1646
|
+
] }),
|
|
1647
|
+
sortDescending: () => /* @__PURE__ */ jsxs8(Icon, { children: [
|
|
1648
|
+
/* @__PURE__ */ jsx12("path", { d: "m3 16 4 4 4-4" }),
|
|
1649
|
+
/* @__PURE__ */ jsx12("path", { d: "M7 20V4" }),
|
|
1650
|
+
/* @__PURE__ */ jsx12("path", { d: "M11 4h10" }),
|
|
1651
|
+
/* @__PURE__ */ jsx12("path", { d: "M11 8h7" }),
|
|
1652
|
+
/* @__PURE__ */ jsx12("path", { d: "M11 12h4" })
|
|
1653
|
+
] }),
|
|
1654
|
+
group: () => /* @__PURE__ */ jsx12(GroupIcon, {}),
|
|
1655
|
+
hide: () => /* @__PURE__ */ jsxs8(Icon, { children: [
|
|
1656
|
+
/* @__PURE__ */ jsx12("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }),
|
|
1657
|
+
/* @__PURE__ */ jsx12("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }),
|
|
1658
|
+
/* @__PURE__ */ jsx12("path", { d: "M6.61 6.61A13.53 13.53 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }),
|
|
1659
|
+
/* @__PURE__ */ jsx12("path", { d: "m2 2 20 20" })
|
|
1660
|
+
] }),
|
|
1661
|
+
autoFit: () => /* @__PURE__ */ jsxs8(Icon, { children: [
|
|
1662
|
+
/* @__PURE__ */ jsx12("path", { d: "m18 8 4 4-4 4" }),
|
|
1663
|
+
/* @__PURE__ */ jsx12("path", { d: "M2 12h20" }),
|
|
1664
|
+
/* @__PURE__ */ jsx12("path", { d: "m6 8-4 4 4 4" })
|
|
1665
|
+
] })
|
|
1666
|
+
};
|
|
1667
|
+
var ICONS = new Map(Object.entries(BUILT_IN_ICONS));
|
|
1668
|
+
function MenuIcon({ name }) {
|
|
1669
|
+
const draw = name === void 0 ? void 0 : ICONS.get(name);
|
|
1670
|
+
return draw === void 0 ? null : draw();
|
|
1671
|
+
}
|
|
1672
|
+
function CheckIcon() {
|
|
1673
|
+
return /* @__PURE__ */ jsx12(Icon, { children: /* @__PURE__ */ jsx12("path", { d: "M20 6 9 17l-5-5" }) });
|
|
1674
|
+
}
|
|
1675
|
+
function ChevronDownIcon() {
|
|
1676
|
+
return /* @__PURE__ */ jsx12(Icon, { children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) });
|
|
1677
|
+
}
|
|
1678
|
+
function ChevronRightIcon() {
|
|
1679
|
+
return /* @__PURE__ */ jsx12(Icon, { children: /* @__PURE__ */ jsx12("path", { d: "m9 18 6-6-6-6" }) });
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
// src/DataGrid/menu/GridMenu.tsx
|
|
1683
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1684
|
+
function itemElement(menu, id) {
|
|
1685
|
+
return Array.from(
|
|
1686
|
+
menu.querySelectorAll("[data-gridkit-menu-item]")
|
|
1687
|
+
).find((item) => item.getAttribute("data-gridkit-menu-item") === id) ?? null;
|
|
1688
|
+
}
|
|
1689
|
+
function topInset(menu) {
|
|
1690
|
+
const style = getComputedStyle(menu);
|
|
1691
|
+
return parseFloat(style.borderTopWidth) + parseFloat(style.paddingTop);
|
|
1692
|
+
}
|
|
1693
|
+
function MenuItem({
|
|
1694
|
+
entry,
|
|
1695
|
+
expanded
|
|
1648
1696
|
}) {
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1697
|
+
const isItem = entry.type === "item";
|
|
1698
|
+
const checked = isItem ? entry.checked : void 0;
|
|
1699
|
+
const shortcut = isItem ? entry.shortcut : void 0;
|
|
1700
|
+
return /* @__PURE__ */ jsxs9(
|
|
1701
|
+
"div",
|
|
1702
|
+
{
|
|
1703
|
+
role: checked === void 0 ? "menuitem" : "menuitemcheckbox",
|
|
1704
|
+
"data-gridkit-menu-item": entry.id,
|
|
1705
|
+
className: "menu-item",
|
|
1706
|
+
...ariaAttr(isItem && entry.disabled, "aria-disabled", true),
|
|
1707
|
+
...ariaAttr(checked !== void 0, "aria-checked", checked),
|
|
1708
|
+
...ariaAttr(shortcut !== void 0, "aria-keyshortcuts", shortcut),
|
|
1709
|
+
...ariaAttr(!isItem, "aria-haspopup", "menu"),
|
|
1710
|
+
...ariaAttr(!isItem, "aria-expanded", expanded),
|
|
1711
|
+
children: [
|
|
1712
|
+
/* @__PURE__ */ jsx13("span", { className: "menu-item-icon", "aria-hidden": "true", children: checked === true ? /* @__PURE__ */ jsx13(CheckIcon, {}) : /* @__PURE__ */ jsx13(MenuIcon, { name: entry.icon }) }),
|
|
1713
|
+
/* @__PURE__ */ jsx13("span", { className: "menu-item-label", children: entry.label }),
|
|
1714
|
+
shortcut !== void 0 && /* @__PURE__ */ jsx13("span", { className: "menu-item-shortcut", "aria-hidden": "true", children: shortcut }),
|
|
1715
|
+
!isItem && /* @__PURE__ */ jsx13("span", { className: "menu-submenu-indicator", "aria-hidden": "true", children: /* @__PURE__ */ jsx13(ChevronRightIcon, {}) })
|
|
1716
|
+
]
|
|
1717
|
+
}
|
|
1718
|
+
);
|
|
1719
|
+
}
|
|
1720
|
+
function GridMenu({
|
|
1721
|
+
entries,
|
|
1722
|
+
label,
|
|
1723
|
+
themeClassName,
|
|
1724
|
+
onRun,
|
|
1725
|
+
onClose,
|
|
1726
|
+
onCloseSubmenu,
|
|
1727
|
+
behaviourRef
|
|
1728
|
+
}) {
|
|
1729
|
+
const menuRef = useRef3(null);
|
|
1730
|
+
const submenuBehaviourRef = useRef3(null);
|
|
1731
|
+
const [submenu, setSubmenu] = useState4(null);
|
|
1732
|
+
const isSubmenu = onCloseSubmenu !== void 0;
|
|
1733
|
+
const latest = useRef3({ entries, submenu, onRun, onClose, onCloseSubmenu });
|
|
1734
|
+
useLayoutEffect3(() => {
|
|
1735
|
+
latest.current = { entries, submenu, onRun, onClose, onCloseSubmenu };
|
|
1736
|
+
});
|
|
1737
|
+
useLayoutEffect3(() => {
|
|
1738
|
+
const menu = menuRef.current;
|
|
1739
|
+
if (menu === null) {
|
|
1740
|
+
return void 0;
|
|
1741
|
+
}
|
|
1742
|
+
const behaviour = attachMenu(menu, {
|
|
1743
|
+
onActivate: (id) => {
|
|
1744
|
+
const item = latest.current.entries.find(
|
|
1745
|
+
(entry) => entry.type === "item" && entry.id === id
|
|
1746
|
+
);
|
|
1747
|
+
if (item !== void 0) {
|
|
1748
|
+
latest.current.onRun(item);
|
|
1749
|
+
}
|
|
1673
1750
|
},
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1751
|
+
onOpenSubmenu: (id, { focus }) => {
|
|
1752
|
+
if (latest.current.submenu?.id === id) {
|
|
1753
|
+
if (focus === "first") {
|
|
1754
|
+
submenuBehaviourRef.current?.focusItem(0);
|
|
1755
|
+
}
|
|
1756
|
+
return;
|
|
1678
1757
|
}
|
|
1758
|
+
const anchor = itemElement(menu, id);
|
|
1759
|
+
if (anchor !== null) {
|
|
1760
|
+
setSubmenu({ id, anchor, focus, offset: -topInset(menu) });
|
|
1761
|
+
}
|
|
1762
|
+
},
|
|
1763
|
+
onCollapseSubmenu: () => {
|
|
1764
|
+
setSubmenu(null);
|
|
1679
1765
|
},
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
* clobbered by a stale restore.
|
|
1686
|
-
*/
|
|
1687
|
-
onCancel() {
|
|
1688
|
-
setActiveColumnId(null);
|
|
1689
|
-
setSizing((current) => {
|
|
1690
|
-
const next = revertColumnSize(current, base, session.columnId);
|
|
1691
|
-
onColumnResize?.({
|
|
1692
|
-
columnId: session.columnId,
|
|
1693
|
-
width: session.startWidth,
|
|
1694
|
-
sizing: next,
|
|
1695
|
-
phase: "end"
|
|
1696
|
-
});
|
|
1697
|
-
return next;
|
|
1698
|
-
});
|
|
1766
|
+
onCloseSubmenu: isSubmenu ? () => {
|
|
1767
|
+
latest.current.onCloseSubmenu?.();
|
|
1768
|
+
} : void 0,
|
|
1769
|
+
onClose: () => {
|
|
1770
|
+
latest.current.onClose();
|
|
1699
1771
|
}
|
|
1700
1772
|
});
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
const table = tableRef.current;
|
|
1704
|
-
if (table === null) {
|
|
1705
|
-
return;
|
|
1706
|
-
}
|
|
1707
|
-
const measured = measureColumnContent(table, entry.id);
|
|
1708
|
-
if (measured === null) {
|
|
1709
|
-
return;
|
|
1773
|
+
if (behaviourRef !== void 0) {
|
|
1774
|
+
behaviourRef.current = behaviour;
|
|
1710
1775
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
);
|
|
1776
|
+
return () => {
|
|
1777
|
+
if (behaviourRef !== void 0) {
|
|
1778
|
+
behaviourRef.current = null;
|
|
1779
|
+
}
|
|
1780
|
+
behaviour.detach();
|
|
1781
|
+
};
|
|
1782
|
+
}, [isSubmenu, behaviourRef]);
|
|
1783
|
+
function closeSubmenu() {
|
|
1784
|
+
setSubmenu(null);
|
|
1785
|
+
}
|
|
1786
|
+
const openEntry = submenu === null ? void 0 : entries.find(
|
|
1787
|
+
(entry) => entry.type === "submenu" && entry.id === submenu.id
|
|
1788
|
+
);
|
|
1789
|
+
return /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
1790
|
+
/* @__PURE__ */ jsx13(
|
|
1791
|
+
"div",
|
|
1792
|
+
{
|
|
1793
|
+
ref: menuRef,
|
|
1794
|
+
role: "menu",
|
|
1795
|
+
"aria-label": label,
|
|
1796
|
+
className: "gridkit-menu",
|
|
1797
|
+
children: entries.map(
|
|
1798
|
+
(entry) => entry.type === "separator" ? /* @__PURE__ */ jsx13("div", { role: "separator", className: "menu-separator" }, entry.key) : /* @__PURE__ */ jsx13(
|
|
1799
|
+
MenuItem,
|
|
1800
|
+
{
|
|
1801
|
+
entry,
|
|
1802
|
+
expanded: entry.id === submenu?.id
|
|
1803
|
+
},
|
|
1804
|
+
entry.id
|
|
1805
|
+
)
|
|
1806
|
+
)
|
|
1807
|
+
}
|
|
1808
|
+
),
|
|
1809
|
+
submenu !== null && openEntry !== void 0 && /* @__PURE__ */ jsx13(
|
|
1810
|
+
Overlay,
|
|
1811
|
+
{
|
|
1812
|
+
anchor: submenu.anchor,
|
|
1813
|
+
placement: "right-start",
|
|
1814
|
+
offset: submenu.offset,
|
|
1815
|
+
initialFocus: submenu.focus,
|
|
1816
|
+
themeClassName,
|
|
1817
|
+
onDismiss: closeSubmenu,
|
|
1818
|
+
children: /* @__PURE__ */ jsx13(
|
|
1819
|
+
GridMenu,
|
|
1820
|
+
{
|
|
1821
|
+
entries: openEntry.items,
|
|
1822
|
+
label: openEntry.label,
|
|
1823
|
+
themeClassName,
|
|
1824
|
+
onRun,
|
|
1825
|
+
onClose,
|
|
1826
|
+
onCloseSubmenu: closeSubmenu,
|
|
1827
|
+
behaviourRef: submenuBehaviourRef
|
|
1828
|
+
}
|
|
1829
|
+
)
|
|
1830
|
+
},
|
|
1831
|
+
submenu.id
|
|
1832
|
+
)
|
|
1833
|
+
] });
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
// src/DataGrid/contextMenu/GridContextMenu.tsx
|
|
1837
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1838
|
+
function GridContextMenu({
|
|
1839
|
+
contextMenu
|
|
1840
|
+
}) {
|
|
1841
|
+
const { menu, run, close } = contextMenu;
|
|
1842
|
+
if (menu === null) {
|
|
1843
|
+
return null;
|
|
1844
|
+
}
|
|
1845
|
+
return /* @__PURE__ */ jsx14(
|
|
1846
|
+
Overlay,
|
|
1847
|
+
{
|
|
1848
|
+
anchor: menu.anchor,
|
|
1849
|
+
gap: menu.anchor instanceof Element ? ANCHOR_GAP : 0,
|
|
1850
|
+
returnFocusTo: menu.cell ?? void 0,
|
|
1851
|
+
themeClassName: menu.themeClassName,
|
|
1852
|
+
onDismiss: close,
|
|
1853
|
+
children: /* @__PURE__ */ jsx14(
|
|
1854
|
+
GridMenu,
|
|
1855
|
+
{
|
|
1856
|
+
entries: menu.entries,
|
|
1857
|
+
label: menu.label,
|
|
1858
|
+
themeClassName: menu.themeClassName,
|
|
1859
|
+
onRun: run,
|
|
1860
|
+
onClose: close
|
|
1861
|
+
}
|
|
1862
|
+
)
|
|
1863
|
+
},
|
|
1864
|
+
menu.key
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
// src/DataGrid/contextMenu/useContextMenu.ts
|
|
1869
|
+
import {
|
|
1870
|
+
useEffect as useEffect2,
|
|
1871
|
+
useLayoutEffect as useLayoutEffect4,
|
|
1872
|
+
useRef as useRef4,
|
|
1873
|
+
useState as useState5
|
|
1874
|
+
} from "react";
|
|
1875
|
+
import {
|
|
1876
|
+
contextMenuEntries,
|
|
1877
|
+
hasContextMenu,
|
|
1878
|
+
isSameCell,
|
|
1879
|
+
resolveMenu
|
|
1880
|
+
} from "@gridkitjs/core";
|
|
1881
|
+
import {
|
|
1882
|
+
attachContextMenuTrigger
|
|
1883
|
+
} from "@gridkitjs/dom";
|
|
1884
|
+
|
|
1885
|
+
// src/DataGrid/contextMenu/contextMenuPlaces.ts
|
|
1886
|
+
import {
|
|
1887
|
+
HEADER_ROW as HEADER_ROW2
|
|
1888
|
+
} from "@gridkitjs/core";
|
|
1889
|
+
import {
|
|
1890
|
+
bodyCellFrom as bodyCellFrom2,
|
|
1891
|
+
bodyRowFrom as bodyRowFrom2,
|
|
1892
|
+
findBodyRow as findBodyRow2,
|
|
1893
|
+
groupRowFrom as groupRowFrom2
|
|
1894
|
+
} from "@gridkitjs/dom";
|
|
1895
|
+
function headerCell(parts, columnIndex) {
|
|
1896
|
+
const element = parts.headerTable?.tHead?.rows[0]?.cells[columnIndex];
|
|
1897
|
+
return element === void 0 ? null : { element, rowIndex: HEADER_ROW2, columnIndex };
|
|
1898
|
+
}
|
|
1899
|
+
function bodyCell(parts, rowIndex, columnIndex) {
|
|
1900
|
+
const element = findBodyRow2(parts.bodyTable, rowIndex)?.cells[columnIndex];
|
|
1901
|
+
return element === void 0 ? null : { element, rowIndex, columnIndex };
|
|
1902
|
+
}
|
|
1903
|
+
function viewOf(element, parts) {
|
|
1904
|
+
const root = parts.root?.getBoundingClientRect();
|
|
1905
|
+
if (root === void 0) {
|
|
1906
|
+
return null;
|
|
1907
|
+
}
|
|
1908
|
+
const body = parts.body?.contains(element) === true ? parts.body.getBoundingClientRect() : root;
|
|
1909
|
+
const left = Math.max(root.left, body.left);
|
|
1910
|
+
const top = Math.max(root.top, body.top);
|
|
1911
|
+
return new DOMRect(
|
|
1912
|
+
left,
|
|
1913
|
+
top,
|
|
1914
|
+
Math.max(0, Math.min(root.right, body.right) - left),
|
|
1915
|
+
Math.max(0, Math.min(root.bottom, body.bottom) - top)
|
|
1916
|
+
);
|
|
1917
|
+
}
|
|
1918
|
+
function clamp(value, min, max) {
|
|
1919
|
+
return Math.min(Math.max(value, min), max);
|
|
1920
|
+
}
|
|
1921
|
+
function onCell(target, cell, parts) {
|
|
1922
|
+
if (cell === null) {
|
|
1923
|
+
return null;
|
|
1924
|
+
}
|
|
1925
|
+
const box = cell.element.getBoundingClientRect();
|
|
1926
|
+
const view = viewOf(cell.element, parts);
|
|
1927
|
+
if (view === null || box.right > view.left && box.left < view.right && box.bottom > view.top && box.top < view.bottom) {
|
|
1928
|
+
return { target, cell, anchor: cell.element };
|
|
1929
|
+
}
|
|
1930
|
+
return {
|
|
1931
|
+
target,
|
|
1932
|
+
cell,
|
|
1933
|
+
anchor: {
|
|
1934
|
+
x: clamp(box.left, view.left, view.right),
|
|
1935
|
+
y: clamp(box.bottom, view.top, view.bottom)
|
|
1936
|
+
}
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1939
|
+
function onBody(body) {
|
|
1940
|
+
const { left, top } = body.getBoundingClientRect();
|
|
1941
|
+
return { target: { area: "body" }, cell: null, anchor: { x: left, y: top } };
|
|
1942
|
+
}
|
|
1943
|
+
function headerPlaceAt(element, parts) {
|
|
1944
|
+
const cell = element.closest("th[data-gridkit-column]");
|
|
1945
|
+
const columnId = cell?.getAttribute("data-gridkit-column");
|
|
1946
|
+
if (cell === null || cell.parentElement !== parts.headerTable?.tHead?.rows[0] || columnId === null || columnId === void 0) {
|
|
1947
|
+
return null;
|
|
1948
|
+
}
|
|
1949
|
+
return onCell(
|
|
1950
|
+
{ area: "header", columnId },
|
|
1951
|
+
headerCell(parts, cell.cellIndex),
|
|
1952
|
+
parts
|
|
1953
|
+
);
|
|
1954
|
+
}
|
|
1955
|
+
function bodyPlaceAt(element, parts) {
|
|
1956
|
+
const { body, pageRows } = parts;
|
|
1957
|
+
if (body === null || !body.contains(element)) {
|
|
1958
|
+
return null;
|
|
1959
|
+
}
|
|
1960
|
+
const group = groupRowFrom2(element);
|
|
1961
|
+
if (group !== null) {
|
|
1962
|
+
const entry = pageRows[group.rowIndex];
|
|
1963
|
+
const cell = bodyCell(parts, group.rowIndex, 0);
|
|
1964
|
+
return entry !== void 0 && "kind" in entry && entry.kind === "group" && cell?.element.contains(element) === true ? onCell(
|
|
1965
|
+
{ area: "group", groupId: entry.groupId, columnId: entry.columnId },
|
|
1966
|
+
cell,
|
|
1967
|
+
parts
|
|
1968
|
+
) : null;
|
|
1969
|
+
}
|
|
1970
|
+
const position = bodyCellFrom2(element);
|
|
1971
|
+
if (position !== null) {
|
|
1972
|
+
const entry = pageRows[position.rowIndex];
|
|
1973
|
+
const cell = bodyCell(parts, position.rowIndex, position.columnIndex);
|
|
1974
|
+
return entry !== void 0 && !("kind" in entry) && cell?.element.contains(element) === true ? onCell(
|
|
1975
|
+
{ area: "cell", rowId: entry.rowId, columnId: position.columnId },
|
|
1976
|
+
cell,
|
|
1977
|
+
parts
|
|
1978
|
+
) : null;
|
|
1979
|
+
}
|
|
1980
|
+
return bodyRowFrom2(element) === null ? onBody(body) : null;
|
|
1981
|
+
}
|
|
1982
|
+
function placeAt(element, parts) {
|
|
1983
|
+
return headerPlaceAt(element, parts) ?? bodyPlaceAt(element, parts);
|
|
1984
|
+
}
|
|
1985
|
+
function placeOf(target, parts) {
|
|
1986
|
+
const columnIndexOf = (columnId) => parts.columns.findIndex((column) => column.id === columnId);
|
|
1987
|
+
switch (target.area) {
|
|
1988
|
+
case "header":
|
|
1989
|
+
return onCell(
|
|
1990
|
+
target,
|
|
1991
|
+
headerCell(parts, columnIndexOf(target.columnId)),
|
|
1992
|
+
parts
|
|
1993
|
+
);
|
|
1994
|
+
case "cell": {
|
|
1995
|
+
const rowIndex = parts.pageRows.findIndex(
|
|
1996
|
+
(entry) => !("kind" in entry) && entry.rowId === target.rowId
|
|
1997
|
+
);
|
|
1998
|
+
return onCell(
|
|
1999
|
+
target,
|
|
2000
|
+
bodyCell(parts, rowIndex, columnIndexOf(target.columnId)),
|
|
2001
|
+
parts
|
|
2002
|
+
);
|
|
2003
|
+
}
|
|
2004
|
+
case "group": {
|
|
2005
|
+
const rowIndex = parts.pageRows.findIndex(
|
|
2006
|
+
(entry) => "kind" in entry && entry.kind === "group" && entry.groupId === target.groupId
|
|
2007
|
+
);
|
|
2008
|
+
return onCell(target, bodyCell(parts, rowIndex, 0), parts);
|
|
2009
|
+
}
|
|
2010
|
+
case "body":
|
|
2011
|
+
return parts.body === null ? null : onBody(parts.body);
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
// src/DataGrid/contextMenu/useContextMenu.ts
|
|
2016
|
+
function useContextMenu({
|
|
2017
|
+
rootRef,
|
|
2018
|
+
headerTableRef,
|
|
2019
|
+
bodyTableRef,
|
|
2020
|
+
bodyScrollRef,
|
|
2021
|
+
contextMenu,
|
|
2022
|
+
onContextMenuOpenChange,
|
|
2023
|
+
controller,
|
|
2024
|
+
commands,
|
|
2025
|
+
nav,
|
|
2026
|
+
selection,
|
|
2027
|
+
messages,
|
|
2028
|
+
columnName
|
|
2029
|
+
}) {
|
|
2030
|
+
const [menu, setMenu] = useState5(null);
|
|
2031
|
+
const current = useRef4(null);
|
|
2032
|
+
const openings = useRef4(0);
|
|
2033
|
+
const enabled = contextMenu !== void 0 && contextMenu !== false;
|
|
2034
|
+
function parts() {
|
|
2035
|
+
const { columns, pageRows } = controller.getView();
|
|
2036
|
+
return {
|
|
2037
|
+
root: rootRef.current,
|
|
2038
|
+
headerTable: headerTableRef.current,
|
|
2039
|
+
bodyTable: bodyTableRef.current,
|
|
2040
|
+
body: bodyScrollRef.current,
|
|
2041
|
+
columns,
|
|
2042
|
+
pageRows
|
|
2043
|
+
};
|
|
2044
|
+
}
|
|
2045
|
+
function labelOf(target) {
|
|
2046
|
+
switch (target.area) {
|
|
2047
|
+
case "header":
|
|
2048
|
+
return messages.headerMenuLabel(columnName(target.columnId));
|
|
2049
|
+
case "cell":
|
|
2050
|
+
return messages.cellMenuLabel;
|
|
2051
|
+
case "group":
|
|
2052
|
+
return messages.groupMenuLabel;
|
|
2053
|
+
case "body":
|
|
2054
|
+
return messages.bodyMenuLabel;
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
function selectTarget(target) {
|
|
2058
|
+
const state = controller.getState();
|
|
2059
|
+
if (target.area === "header") {
|
|
2060
|
+
if (selection.columnMode === false || state.columnSelection.includes(target.columnId)) {
|
|
2061
|
+
return false;
|
|
2062
|
+
}
|
|
2063
|
+
controller.selectColumn(target.columnId, "replace");
|
|
2064
|
+
return true;
|
|
2065
|
+
}
|
|
2066
|
+
if (target.area !== "cell") {
|
|
2067
|
+
return false;
|
|
2068
|
+
}
|
|
2069
|
+
const cell = { rowId: target.rowId, columnId: target.columnId };
|
|
2070
|
+
const selectRow = selection.rowMode !== false && !state.rowSelection.includes(target.rowId);
|
|
2071
|
+
const selectCell = selection.cellMode !== false && !isSameCell(state.cellSelection, cell);
|
|
2072
|
+
if (selectRow) {
|
|
2073
|
+
controller.selectRow(target.rowId, "replace");
|
|
2074
|
+
}
|
|
2075
|
+
if (selectCell) {
|
|
2076
|
+
controller.selectCell(cell, "replace");
|
|
2077
|
+
}
|
|
2078
|
+
return selectRow || selectCell;
|
|
2079
|
+
}
|
|
2080
|
+
function resolveFor(target) {
|
|
2081
|
+
const context = commands.contextFor(target);
|
|
2082
|
+
return resolveMenu(contextMenuEntries(contextMenu, context), {
|
|
2083
|
+
commands: commands.commands,
|
|
2084
|
+
context
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
function show(next) {
|
|
2088
|
+
const previous = current.current;
|
|
2089
|
+
if (previous === next) {
|
|
2090
|
+
return;
|
|
2091
|
+
}
|
|
2092
|
+
current.current = next;
|
|
2093
|
+
setMenu(next);
|
|
2094
|
+
if (previous !== null) {
|
|
2095
|
+
onContextMenuOpenChange?.({ open: false, target: previous.target });
|
|
2096
|
+
}
|
|
2097
|
+
if (next !== null) {
|
|
2098
|
+
onContextMenuOpenChange?.({ open: true, target: next.target });
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
function openAt({ target, cell, anchor }, point) {
|
|
2102
|
+
let resolved = resolveFor(target);
|
|
2103
|
+
if (resolved.length === 0) {
|
|
2104
|
+
return false;
|
|
2105
|
+
}
|
|
2106
|
+
if (selectTarget(target)) {
|
|
2107
|
+
resolved = resolveFor(target);
|
|
2108
|
+
}
|
|
2109
|
+
if (cell !== null && document.activeElement !== cell.element) {
|
|
2110
|
+
cell.element.focus({ preventScroll: true });
|
|
2111
|
+
nav.focusCellNow(cell.rowIndex, cell.columnIndex);
|
|
2112
|
+
}
|
|
2113
|
+
openings.current += 1;
|
|
2114
|
+
show({
|
|
2115
|
+
key: openings.current,
|
|
2116
|
+
target,
|
|
2117
|
+
entries: resolved,
|
|
2118
|
+
label: labelOf(target),
|
|
2119
|
+
anchor: point ?? anchor,
|
|
2120
|
+
cell: cell?.element ?? null,
|
|
2121
|
+
themeClassName: overlayThemeClassName(rootRef.current)
|
|
2122
|
+
});
|
|
2123
|
+
return true;
|
|
2124
|
+
}
|
|
2125
|
+
function handleRequest({ target, point }) {
|
|
2126
|
+
const place = placeAt(target, parts());
|
|
2127
|
+
return place !== null && openAt(place, point);
|
|
2128
|
+
}
|
|
2129
|
+
const latestRequest = useRef4(handleRequest);
|
|
2130
|
+
useLayoutEffect4(() => {
|
|
2131
|
+
latestRequest.current = handleRequest;
|
|
2132
|
+
});
|
|
2133
|
+
useEffect2(() => {
|
|
2134
|
+
const root = rootRef.current;
|
|
2135
|
+
if (!enabled || root === null) {
|
|
2136
|
+
return void 0;
|
|
2137
|
+
}
|
|
2138
|
+
return attachContextMenuTrigger(root, {
|
|
2139
|
+
onRequest: (request) => latestRequest.current(request)
|
|
2140
|
+
});
|
|
2141
|
+
}, [rootRef, enabled]);
|
|
2142
|
+
const shown = useRef4(null);
|
|
2143
|
+
useLayoutEffect4(() => {
|
|
2144
|
+
const closed = shown.current;
|
|
2145
|
+
shown.current = menu;
|
|
2146
|
+
if (menu === null && closed !== null && closed.cell !== null && !closed.cell.isConnected && document.activeElement === document.body) {
|
|
2147
|
+
nav.focusTabStop();
|
|
2148
|
+
}
|
|
2149
|
+
});
|
|
2150
|
+
function close() {
|
|
2151
|
+
show(null);
|
|
2152
|
+
}
|
|
2153
|
+
return {
|
|
2154
|
+
menu,
|
|
2155
|
+
opens: (area) => hasContextMenu(contextMenu, area),
|
|
2156
|
+
open: (target, anchor) => {
|
|
2157
|
+
const place = placeOf(target, parts());
|
|
2158
|
+
return place !== null && openAt(place, anchor ?? null);
|
|
2159
|
+
},
|
|
2160
|
+
run: (item) => {
|
|
2161
|
+
const open = current.current;
|
|
2162
|
+
if (item.run() && open !== null) {
|
|
2163
|
+
commands.report(item.id, open.target, "contextMenu");
|
|
2164
|
+
}
|
|
2165
|
+
close();
|
|
2166
|
+
},
|
|
2167
|
+
close
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
// src/DataGrid/columnChooser/ColumnChooser.tsx
|
|
2172
|
+
import { useLayoutEffect as useLayoutEffect5, useRef as useRef5, useState as useState6 } from "react";
|
|
2173
|
+
import { resolveColumnChooser } from "@gridkitjs/core";
|
|
2174
|
+
import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2175
|
+
function ColumnChooser({
|
|
2176
|
+
controller,
|
|
2177
|
+
messages
|
|
2178
|
+
}) {
|
|
2179
|
+
const [search, setSearch] = useState6("");
|
|
2180
|
+
const showAllRef = useRef5(null);
|
|
2181
|
+
const { entries, selectAll, toggleAll } = resolveColumnChooser({
|
|
2182
|
+
columns: controller.getView().dataColumns,
|
|
2183
|
+
visibility: controller.getState().columnVisibility,
|
|
2184
|
+
search
|
|
2185
|
+
});
|
|
2186
|
+
useLayoutEffect5(() => {
|
|
2187
|
+
if (showAllRef.current !== null) {
|
|
2188
|
+
showAllRef.current.indeterminate = selectAll === "mixed";
|
|
2189
|
+
}
|
|
2190
|
+
});
|
|
2191
|
+
function setVisible(columnIds, visible) {
|
|
2192
|
+
if (visible) {
|
|
2193
|
+
controller.showColumns(columnIds);
|
|
2194
|
+
} else {
|
|
2195
|
+
controller.hideColumns(columnIds);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
return /* @__PURE__ */ jsxs10(
|
|
2199
|
+
"div",
|
|
2200
|
+
{
|
|
2201
|
+
role: "dialog",
|
|
2202
|
+
"aria-label": messages.columnChooserLabel,
|
|
2203
|
+
className: "gridkit-column-chooser",
|
|
2204
|
+
children: [
|
|
2205
|
+
/* @__PURE__ */ jsx15(
|
|
2206
|
+
"input",
|
|
2207
|
+
{
|
|
2208
|
+
type: "search",
|
|
2209
|
+
className: "column-chooser-search",
|
|
2210
|
+
"aria-label": messages.columnChooserSearchLabel,
|
|
2211
|
+
placeholder: messages.searchPlaceholder,
|
|
2212
|
+
value: search,
|
|
2213
|
+
onChange: (event) => {
|
|
2214
|
+
setSearch(event.currentTarget.value);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
),
|
|
2218
|
+
entries.length === 0 ? /* @__PURE__ */ jsx15("p", { role: "status", className: "column-chooser-empty", children: messages.noMatchingColumns }) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2219
|
+
/* @__PURE__ */ jsxs10("label", { className: "column-chooser-option column-chooser-all", children: [
|
|
2220
|
+
/* @__PURE__ */ jsx15(
|
|
2221
|
+
"input",
|
|
2222
|
+
{
|
|
2223
|
+
ref: showAllRef,
|
|
2224
|
+
type: "checkbox",
|
|
2225
|
+
checked: selectAll === "checked",
|
|
2226
|
+
disabled: toggleAll === null,
|
|
2227
|
+
onChange: () => {
|
|
2228
|
+
if (toggleAll !== null) {
|
|
2229
|
+
setVisible(toggleAll.columnIds, toggleAll.visible);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
),
|
|
2234
|
+
messages.showAllColumns
|
|
2235
|
+
] }),
|
|
2236
|
+
/* @__PURE__ */ jsx15("ul", { className: "column-chooser-list", children: entries.map((entry) => /* @__PURE__ */ jsx15("li", { children: /* @__PURE__ */ jsxs10("label", { className: "column-chooser-option", children: [
|
|
2237
|
+
/* @__PURE__ */ jsx15(
|
|
2238
|
+
"input",
|
|
2239
|
+
{
|
|
2240
|
+
type: "checkbox",
|
|
2241
|
+
checked: entry.visible,
|
|
2242
|
+
disabled: entry.disabled,
|
|
2243
|
+
onChange: () => {
|
|
2244
|
+
setVisible([entry.columnId], !entry.visible);
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
),
|
|
2248
|
+
entry.label
|
|
2249
|
+
] }) }, entry.columnId)) })
|
|
2250
|
+
] })
|
|
2251
|
+
]
|
|
2252
|
+
}
|
|
2253
|
+
);
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// src/DataGrid/panels/GridPanels.tsx
|
|
2257
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
2258
|
+
var panelComponents = {
|
|
2259
|
+
columnChooser: ColumnChooser
|
|
2260
|
+
};
|
|
2261
|
+
function GridPanels({
|
|
2262
|
+
panels,
|
|
2263
|
+
controller,
|
|
2264
|
+
messages
|
|
2265
|
+
}) {
|
|
2266
|
+
const { panel, close } = panels;
|
|
2267
|
+
if (panel === null) {
|
|
2268
|
+
return null;
|
|
2269
|
+
}
|
|
2270
|
+
const Panel = panelComponents[panel.kind];
|
|
2271
|
+
return /* @__PURE__ */ jsx16(
|
|
2272
|
+
Overlay,
|
|
2273
|
+
{
|
|
2274
|
+
anchor: panel.anchor,
|
|
2275
|
+
placement: panel.placement,
|
|
2276
|
+
gap: panel.anchor instanceof Element ? ANCHOR_GAP : 0,
|
|
2277
|
+
returnFocusTo: panel.returnFocusTo,
|
|
2278
|
+
ignoreScrollAfterInput: true,
|
|
2279
|
+
themeClassName: panel.themeClassName,
|
|
2280
|
+
onDismiss: close,
|
|
2281
|
+
children: /* @__PURE__ */ jsx16(
|
|
2282
|
+
Panel,
|
|
2283
|
+
{
|
|
2284
|
+
target: panel.target,
|
|
2285
|
+
controller,
|
|
2286
|
+
messages
|
|
2287
|
+
}
|
|
2288
|
+
)
|
|
2289
|
+
},
|
|
2290
|
+
panel.key
|
|
2291
|
+
);
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
// src/DataGrid/panels/useGridPanels.ts
|
|
2295
|
+
import { useLayoutEffect as useLayoutEffect6, useRef as useRef6, useState as useState7 } from "react";
|
|
2296
|
+
function toolbarItem(root, itemId) {
|
|
2297
|
+
const items = root.querySelectorAll(
|
|
2298
|
+
":scope > .gridkit-toolbar > [data-gridkit-toolbar-item]"
|
|
2299
|
+
);
|
|
2300
|
+
return Array.from(items).find(
|
|
2301
|
+
(item) => item.getAttribute("data-gridkit-toolbar-item") === itemId
|
|
2302
|
+
) ?? // In "More" while the toolbar is narrow: the button it is chosen from.
|
|
2303
|
+
Array.from(items).find(
|
|
2304
|
+
(item) => item.hasAttribute("data-gridkit-toolbar-more")
|
|
2305
|
+
) ?? null;
|
|
2306
|
+
}
|
|
2307
|
+
function headerCell2(headerTable, columnId) {
|
|
2308
|
+
const cells = headerTable?.tHead?.rows[0]?.cells;
|
|
2309
|
+
return cells === void 0 ? null : Array.from(cells).find(
|
|
2310
|
+
(cell) => cell.getAttribute("data-gridkit-column") === columnId
|
|
2311
|
+
) ?? null;
|
|
2312
|
+
}
|
|
2313
|
+
function useGridPanels({
|
|
2314
|
+
rootRef,
|
|
2315
|
+
headerTableRef,
|
|
2316
|
+
nav
|
|
2317
|
+
}) {
|
|
2318
|
+
const [panel, setPanel] = useState7(null);
|
|
2319
|
+
const openings = useRef6(0);
|
|
2320
|
+
function placeFor(root, target) {
|
|
2321
|
+
const element = target.area === "toolbar" ? toolbarItem(root, target.itemId) : target.area === "header" ? headerCell2(headerTableRef.current, target.columnId) : null;
|
|
2322
|
+
if (element !== null) {
|
|
2323
|
+
return {
|
|
2324
|
+
anchor: element,
|
|
2325
|
+
// The toolbar's own button sits at its far end.
|
|
2326
|
+
placement: target.area === "toolbar" ? "bottom-end" : "bottom-start",
|
|
2327
|
+
returnFocusTo: element
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
const { right, top } = root.getBoundingClientRect();
|
|
2331
|
+
return {
|
|
2332
|
+
anchor: { x: right, y: top },
|
|
2333
|
+
placement: "bottom-end",
|
|
2334
|
+
returnFocusTo: void 0
|
|
2335
|
+
};
|
|
2336
|
+
}
|
|
2337
|
+
const shown = useRef6(null);
|
|
2338
|
+
useLayoutEffect6(() => {
|
|
2339
|
+
const closed = shown.current;
|
|
2340
|
+
shown.current = panel;
|
|
2341
|
+
if (panel === null && closed?.returnFocusTo?.isConnected === false && document.activeElement === document.body) {
|
|
2342
|
+
nav.focusTabStop();
|
|
2343
|
+
}
|
|
2344
|
+
});
|
|
2345
|
+
return {
|
|
2346
|
+
panel,
|
|
2347
|
+
open: (kind, target) => {
|
|
2348
|
+
const root = rootRef.current;
|
|
2349
|
+
if (root === null) {
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
openings.current += 1;
|
|
2353
|
+
setPanel({
|
|
2354
|
+
key: openings.current,
|
|
2355
|
+
kind,
|
|
2356
|
+
target,
|
|
2357
|
+
...placeFor(root, target),
|
|
2358
|
+
themeClassName: overlayThemeClassName(root)
|
|
2359
|
+
});
|
|
2360
|
+
},
|
|
2361
|
+
close: () => {
|
|
2362
|
+
setPanel(null);
|
|
2363
|
+
}
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
// src/DataGrid/toolbar/GridToolbar.tsx
|
|
2368
|
+
import { useLayoutEffect as useLayoutEffect9, useRef as useRef10 } from "react";
|
|
2369
|
+
import {
|
|
2370
|
+
resolveToolbar,
|
|
2371
|
+
splitToolbarItems,
|
|
2372
|
+
toolbarEntries
|
|
2373
|
+
} from "@gridkitjs/core";
|
|
2374
|
+
import { attachToolbar } from "@gridkitjs/dom";
|
|
2375
|
+
|
|
2376
|
+
// src/DataGrid/toolbar/ToolbarMenuButton.tsx
|
|
2377
|
+
import { useLayoutEffect as useLayoutEffect7, useRef as useRef7, useState as useState8 } from "react";
|
|
2378
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2379
|
+
function ToolbarMenuButton({
|
|
2380
|
+
itemKey,
|
|
2381
|
+
label,
|
|
2382
|
+
icon,
|
|
2383
|
+
entries,
|
|
2384
|
+
more = false,
|
|
2385
|
+
onMenuClose
|
|
2386
|
+
}) {
|
|
2387
|
+
const [menu, setMenu] = useState8(null);
|
|
2388
|
+
const menuBehaviourRef = useRef7(null);
|
|
2389
|
+
useLayoutEffect7(() => {
|
|
2390
|
+
if (menu !== null && menu.focusItem > 0) {
|
|
2391
|
+
menuBehaviourRef.current?.focusItem(menu.focusItem);
|
|
2392
|
+
}
|
|
2393
|
+
}, [menu]);
|
|
2394
|
+
function open(button, onLast = false) {
|
|
2395
|
+
setMenu({
|
|
2396
|
+
anchor: button,
|
|
2397
|
+
themeClassName: overlayThemeClassName(button),
|
|
2398
|
+
focusItem: onLast ? entries.filter((entry) => entry.type !== "separator").length - 1 : 0
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
function close() {
|
|
2402
|
+
setMenu(null);
|
|
2403
|
+
onMenuClose();
|
|
2404
|
+
}
|
|
2405
|
+
return /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
2406
|
+
/* @__PURE__ */ jsxs11(
|
|
2407
|
+
"button",
|
|
2408
|
+
{
|
|
2409
|
+
type: "button",
|
|
2410
|
+
className: classNames("toolbar-button", more && "toolbar-more"),
|
|
2411
|
+
"data-gridkit-toolbar-item": itemKey,
|
|
2412
|
+
...ariaAttr(more, "data-gridkit-toolbar-more", ""),
|
|
2413
|
+
"aria-haspopup": "menu",
|
|
2414
|
+
"aria-expanded": menu !== null,
|
|
2415
|
+
onClick: (event) => {
|
|
2416
|
+
if (menu === null) {
|
|
2417
|
+
open(event.currentTarget);
|
|
2418
|
+
} else {
|
|
2419
|
+
close();
|
|
2420
|
+
}
|
|
2421
|
+
},
|
|
2422
|
+
onKeyDown: (event) => {
|
|
2423
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && menu === null) {
|
|
2424
|
+
event.preventDefault();
|
|
2425
|
+
open(event.currentTarget, event.key === "ArrowUp");
|
|
2426
|
+
}
|
|
2427
|
+
},
|
|
2428
|
+
children: [
|
|
2429
|
+
icon !== void 0 && /* @__PURE__ */ jsx17("span", { className: "toolbar-button-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(MenuIcon, { name: icon }) }),
|
|
2430
|
+
label,
|
|
2431
|
+
/* @__PURE__ */ jsx17("span", { className: "toolbar-button-indicator", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(ChevronDownIcon, {}) })
|
|
2432
|
+
]
|
|
2433
|
+
}
|
|
2434
|
+
),
|
|
2435
|
+
menu !== null && /* @__PURE__ */ jsx17(
|
|
2436
|
+
Overlay,
|
|
2437
|
+
{
|
|
2438
|
+
anchor: menu.anchor,
|
|
2439
|
+
placement: "bottom-start",
|
|
2440
|
+
gap: ANCHOR_GAP,
|
|
2441
|
+
returnFocusTo: menu.anchor,
|
|
2442
|
+
themeClassName: menu.themeClassName,
|
|
2443
|
+
onDismiss: close,
|
|
2444
|
+
children: /* @__PURE__ */ jsx17(
|
|
2445
|
+
GridMenu,
|
|
2446
|
+
{
|
|
2447
|
+
entries,
|
|
2448
|
+
label,
|
|
2449
|
+
themeClassName: menu.themeClassName,
|
|
2450
|
+
behaviourRef: menuBehaviourRef,
|
|
2451
|
+
onRun: (item) => {
|
|
2452
|
+
item.run();
|
|
2453
|
+
close();
|
|
2454
|
+
},
|
|
2455
|
+
onClose: close
|
|
2456
|
+
}
|
|
2457
|
+
)
|
|
2458
|
+
}
|
|
2459
|
+
)
|
|
2460
|
+
] });
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
// src/DataGrid/toolbar/ToolbarSearch.tsx
|
|
2464
|
+
import { useEffect as useEffect3, useRef as useRef8, useState as useState9 } from "react";
|
|
2465
|
+
import {
|
|
2466
|
+
searchTextOf,
|
|
2467
|
+
setSearchText
|
|
2468
|
+
} from "@gridkitjs/core";
|
|
2469
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2470
|
+
var SEARCH_DELAY_MS = 250;
|
|
2471
|
+
function ToolbarSearch({
|
|
2472
|
+
itemKey,
|
|
2473
|
+
controller,
|
|
2474
|
+
messages,
|
|
2475
|
+
announce
|
|
2476
|
+
}) {
|
|
2477
|
+
const applied = searchTextOf(controller.getState().filter);
|
|
2478
|
+
const [draft, setDraft] = useState9(null);
|
|
2479
|
+
const timer = useRef8(void 0);
|
|
2480
|
+
const unannounced = useRef8(null);
|
|
2481
|
+
const text = draft !== null && draft.over === applied ? draft.text : applied;
|
|
2482
|
+
function apply(next, over) {
|
|
2483
|
+
clearTimeout(timer.current);
|
|
2484
|
+
setDraft(null);
|
|
2485
|
+
const filter = controller.getState().filter;
|
|
2486
|
+
if (searchTextOf(filter) !== over) {
|
|
2487
|
+
return;
|
|
2488
|
+
}
|
|
2489
|
+
const searched = setSearchText(filter, next);
|
|
2490
|
+
if (searched !== filter) {
|
|
2491
|
+
unannounced.current = next;
|
|
2492
|
+
controller.setFilter(searched);
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
useEffect3(() => {
|
|
2496
|
+
if (unannounced.current === applied) {
|
|
2497
|
+
unannounced.current = null;
|
|
2498
|
+
announce(messages.searchResults(controller.getView().rows.length));
|
|
2499
|
+
}
|
|
2500
|
+
});
|
|
2501
|
+
useEffect3(
|
|
2502
|
+
() => () => {
|
|
2503
|
+
clearTimeout(timer.current);
|
|
2504
|
+
},
|
|
2505
|
+
[]
|
|
2506
|
+
);
|
|
2507
|
+
return /* @__PURE__ */ jsx18(
|
|
2508
|
+
"input",
|
|
2509
|
+
{
|
|
2510
|
+
type: "search",
|
|
2511
|
+
className: "toolbar-search",
|
|
2512
|
+
"data-gridkit-toolbar-item": itemKey,
|
|
2513
|
+
"aria-label": messages.searchLabel,
|
|
2514
|
+
placeholder: messages.searchPlaceholder,
|
|
2515
|
+
value: text,
|
|
2516
|
+
onChange: (event) => {
|
|
2517
|
+
const typed = event.target.value;
|
|
2518
|
+
setDraft({ text: typed, over: applied });
|
|
2519
|
+
clearTimeout(timer.current);
|
|
2520
|
+
timer.current = setTimeout(() => {
|
|
2521
|
+
apply(typed, applied);
|
|
2522
|
+
}, SEARCH_DELAY_MS);
|
|
2523
|
+
},
|
|
2524
|
+
onKeyDown: (event) => {
|
|
2525
|
+
if (event.key === "Enter") {
|
|
2526
|
+
apply(text, applied);
|
|
2527
|
+
} else if (event.key === "Escape" && text !== "") {
|
|
2528
|
+
event.preventDefault();
|
|
2529
|
+
apply("", applied);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// src/DataGrid/toolbar/useToolbarOverflow.ts
|
|
2537
|
+
import { useLayoutEffect as useLayoutEffect8, useRef as useRef9, useState as useState10 } from "react";
|
|
2538
|
+
import { observeToolbarOverflow } from "@gridkitjs/dom";
|
|
2539
|
+
function useToolbarOverflow(toolbarRef, items) {
|
|
2540
|
+
const [fit, setFit] = useState10(items.length);
|
|
2541
|
+
const overflow = useRef9(null);
|
|
2542
|
+
const measuredLayout = useRef9("");
|
|
2543
|
+
const layout = JSON.stringify(
|
|
2544
|
+
items.map((item) => [
|
|
2545
|
+
item.type,
|
|
2546
|
+
item.key,
|
|
2547
|
+
"label" in item ? item.label : null
|
|
2548
|
+
])
|
|
2549
|
+
);
|
|
2550
|
+
useLayoutEffect8(() => {
|
|
2551
|
+
const toolbar = toolbarRef.current;
|
|
2552
|
+
if (toolbar === null || layout === measuredLayout.current) {
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
measuredLayout.current = layout;
|
|
2556
|
+
const options = { items, onChange: setFit };
|
|
2557
|
+
if (overflow.current === null) {
|
|
2558
|
+
overflow.current = observeToolbarOverflow(toolbar, options);
|
|
2559
|
+
} else {
|
|
2560
|
+
overflow.current.update(options);
|
|
2561
|
+
}
|
|
2562
|
+
}, [toolbarRef, layout, items]);
|
|
2563
|
+
useLayoutEffect8(
|
|
2564
|
+
() => () => {
|
|
2565
|
+
overflow.current?.detach();
|
|
2566
|
+
overflow.current = null;
|
|
2567
|
+
measuredLayout.current = "";
|
|
2568
|
+
},
|
|
2569
|
+
[]
|
|
2570
|
+
);
|
|
2571
|
+
return fit;
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2574
|
+
// src/DataGrid/toolbar/GridToolbar.tsx
|
|
2575
|
+
import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2576
|
+
function reporting(run, report) {
|
|
2577
|
+
return () => {
|
|
2578
|
+
const ran = run();
|
|
2579
|
+
if (ran) {
|
|
2580
|
+
report();
|
|
2581
|
+
}
|
|
2582
|
+
return ran;
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
function reportingEntries(entries, report) {
|
|
2586
|
+
return entries.map((entry) => {
|
|
2587
|
+
switch (entry.type) {
|
|
2588
|
+
case "item":
|
|
2589
|
+
return {
|
|
2590
|
+
...entry,
|
|
2591
|
+
run: reporting(entry.run, () => {
|
|
2592
|
+
report(entry.id);
|
|
2593
|
+
})
|
|
2594
|
+
};
|
|
2595
|
+
case "submenu":
|
|
2596
|
+
return { ...entry, items: reportingEntries(entry.items, report) };
|
|
2597
|
+
default:
|
|
2598
|
+
return entry;
|
|
2599
|
+
}
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
function reportingItem(item, report) {
|
|
2603
|
+
switch (item.type) {
|
|
2604
|
+
case "button":
|
|
2605
|
+
return {
|
|
2606
|
+
...item,
|
|
2607
|
+
run: reporting(item.run, () => {
|
|
2608
|
+
report(item.id, item.id);
|
|
2609
|
+
})
|
|
2610
|
+
};
|
|
2611
|
+
case "menu":
|
|
2612
|
+
return {
|
|
2613
|
+
...item,
|
|
2614
|
+
items: reportingEntries(item.items, (commandId) => {
|
|
2615
|
+
report(commandId, item.id);
|
|
2616
|
+
})
|
|
2617
|
+
};
|
|
2618
|
+
default:
|
|
2619
|
+
return item;
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
function GridToolbar(props) {
|
|
2623
|
+
const entries = toolbarEntries(props.toolbar);
|
|
2624
|
+
if (entries.length === 0) {
|
|
2625
|
+
return null;
|
|
2626
|
+
}
|
|
2627
|
+
const label = (typeof props.toolbar === "object" ? props.toolbar.label : void 0) ?? props.messages.toolbarLabel;
|
|
2628
|
+
return /* @__PURE__ */ jsx19(Toolbar, { ...props, entries, label });
|
|
2629
|
+
}
|
|
2630
|
+
function Toolbar({
|
|
2631
|
+
entries,
|
|
2632
|
+
label,
|
|
2633
|
+
renderItem,
|
|
2634
|
+
gridId,
|
|
2635
|
+
controller,
|
|
2636
|
+
commands,
|
|
2637
|
+
messages,
|
|
2638
|
+
announce
|
|
2639
|
+
}) {
|
|
2640
|
+
const toolbarRef = useRef10(null);
|
|
2641
|
+
const menuClosed = useRef10(false);
|
|
2642
|
+
const items = resolveToolbar(entries, {
|
|
2643
|
+
commands: commands.commands,
|
|
2644
|
+
contextFor: commands.contextFor
|
|
2645
|
+
}).map(
|
|
2646
|
+
(item) => reportingItem(item, (commandId, itemId) => {
|
|
2647
|
+
commands.report(commandId, { area: "toolbar", itemId }, "toolbar");
|
|
2648
|
+
})
|
|
2649
|
+
);
|
|
2650
|
+
const fit = useToolbarOverflow(toolbarRef, items);
|
|
2651
|
+
const { shown, overflow } = splitToolbarItems(items, fit);
|
|
2652
|
+
useLayoutEffect9(() => {
|
|
2653
|
+
const toolbar = toolbarRef.current;
|
|
2654
|
+
return toolbar === null ? void 0 : attachToolbar(toolbar);
|
|
2655
|
+
}, []);
|
|
2656
|
+
useLayoutEffect9(() => {
|
|
2657
|
+
if (!menuClosed.current) {
|
|
2658
|
+
return;
|
|
2659
|
+
}
|
|
2660
|
+
menuClosed.current = false;
|
|
2661
|
+
const toolbar = toolbarRef.current;
|
|
2662
|
+
if (toolbar !== null && document.activeElement === document.body) {
|
|
2663
|
+
(toolbar.querySelector('[tabindex="0"]') ?? toolbar.querySelector("button, input"))?.focus();
|
|
2664
|
+
}
|
|
2665
|
+
});
|
|
2666
|
+
function onMenuClose() {
|
|
2667
|
+
menuClosed.current = true;
|
|
2668
|
+
}
|
|
2669
|
+
function draw(item) {
|
|
2670
|
+
switch (item.type) {
|
|
2671
|
+
case "button":
|
|
2672
|
+
return /* @__PURE__ */ jsxs12(
|
|
2673
|
+
"button",
|
|
2674
|
+
{
|
|
2675
|
+
type: "button",
|
|
2676
|
+
className: "toolbar-button",
|
|
2677
|
+
"data-gridkit-toolbar-item": item.key,
|
|
2678
|
+
...ariaAttr(item.disabled, "aria-disabled", true),
|
|
2679
|
+
...ariaAttr(
|
|
2680
|
+
item.pressed !== void 0,
|
|
2681
|
+
"aria-pressed",
|
|
2682
|
+
item.pressed
|
|
2683
|
+
),
|
|
2684
|
+
...ariaAttr(
|
|
2685
|
+
item.shortcut !== void 0,
|
|
2686
|
+
"aria-keyshortcuts",
|
|
2687
|
+
item.shortcut
|
|
2688
|
+
),
|
|
2689
|
+
onClick: () => {
|
|
2690
|
+
item.run();
|
|
2691
|
+
},
|
|
2692
|
+
children: [
|
|
2693
|
+
item.icon !== void 0 && /* @__PURE__ */ jsx19("span", { className: "toolbar-button-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(MenuIcon, { name: item.icon }) }),
|
|
2694
|
+
item.label
|
|
2695
|
+
]
|
|
2696
|
+
},
|
|
2697
|
+
item.key
|
|
2698
|
+
);
|
|
2699
|
+
case "menu":
|
|
2700
|
+
return /* @__PURE__ */ jsx19(
|
|
2701
|
+
ToolbarMenuButton,
|
|
2702
|
+
{
|
|
2703
|
+
itemKey: item.key,
|
|
2704
|
+
label: item.label,
|
|
2705
|
+
icon: item.icon,
|
|
2706
|
+
entries: item.items,
|
|
2707
|
+
onMenuClose
|
|
2708
|
+
},
|
|
2709
|
+
item.key
|
|
2710
|
+
);
|
|
2711
|
+
case "search":
|
|
2712
|
+
return /* @__PURE__ */ jsx19(
|
|
2713
|
+
ToolbarSearch,
|
|
2714
|
+
{
|
|
2715
|
+
itemKey: item.key,
|
|
2716
|
+
controller,
|
|
2717
|
+
messages,
|
|
2718
|
+
announce
|
|
2719
|
+
},
|
|
2720
|
+
item.key
|
|
2721
|
+
);
|
|
2722
|
+
case "separator":
|
|
2723
|
+
return /* @__PURE__ */ jsx19(
|
|
2724
|
+
"div",
|
|
2725
|
+
{
|
|
2726
|
+
role: "separator",
|
|
2727
|
+
"aria-orientation": "vertical",
|
|
2728
|
+
className: "toolbar-separator",
|
|
2729
|
+
"data-gridkit-toolbar-item": item.key
|
|
2730
|
+
},
|
|
2731
|
+
item.key
|
|
2732
|
+
);
|
|
2733
|
+
case "spacer":
|
|
2734
|
+
return /* @__PURE__ */ jsx19(
|
|
2735
|
+
"div",
|
|
2736
|
+
{
|
|
2737
|
+
className: "toolbar-spacer",
|
|
2738
|
+
"data-gridkit-toolbar-item": item.key
|
|
2739
|
+
},
|
|
2740
|
+
item.key
|
|
2741
|
+
);
|
|
2742
|
+
case "custom":
|
|
2743
|
+
return /* @__PURE__ */ jsx19(
|
|
2744
|
+
"div",
|
|
2745
|
+
{
|
|
2746
|
+
className: "toolbar-custom",
|
|
2747
|
+
"data-gridkit-toolbar-item": item.key,
|
|
2748
|
+
children: renderItem?.(item.id)
|
|
2749
|
+
},
|
|
2750
|
+
item.key
|
|
2751
|
+
);
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
return /* @__PURE__ */ jsxs12(
|
|
2755
|
+
"div",
|
|
2756
|
+
{
|
|
2757
|
+
ref: toolbarRef,
|
|
2758
|
+
role: "toolbar",
|
|
2759
|
+
"aria-label": label,
|
|
2760
|
+
"aria-controls": gridId,
|
|
2761
|
+
className: "gridkit-toolbar",
|
|
2762
|
+
children: [
|
|
2763
|
+
shown.map(draw),
|
|
2764
|
+
overflow.length > 0 && /* @__PURE__ */ jsx19(
|
|
2765
|
+
ToolbarMenuButton,
|
|
2766
|
+
{
|
|
2767
|
+
itemKey: "more",
|
|
2768
|
+
label: messages.moreToolbarItems,
|
|
2769
|
+
entries: overflow,
|
|
2770
|
+
more: true,
|
|
2771
|
+
onMenuClose
|
|
2772
|
+
}
|
|
2773
|
+
)
|
|
2774
|
+
]
|
|
2775
|
+
}
|
|
2776
|
+
);
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2779
|
+
// src/DataGrid/useColumnDrag.ts
|
|
2780
|
+
import {
|
|
2781
|
+
resolveKeyboardDropTarget as resolveKeyboardDropTarget2
|
|
2782
|
+
} from "@gridkitjs/core";
|
|
2783
|
+
import { resolveColumnDropTarget } from "@gridkitjs/dom";
|
|
2784
|
+
function useColumnDrag({
|
|
2785
|
+
order,
|
|
2786
|
+
groupBy,
|
|
2787
|
+
groupByDraggableIds,
|
|
2788
|
+
onDrop
|
|
2789
|
+
}) {
|
|
2790
|
+
const drag = useDragReorder({
|
|
2791
|
+
resolveTarget: (clientX, clientY, movedId) => resolveColumnDropTarget(clientX, clientY, movedId, {
|
|
2792
|
+
order,
|
|
2793
|
+
groupBy,
|
|
2794
|
+
groupByDraggableIds
|
|
2795
|
+
}),
|
|
2796
|
+
onDrop
|
|
2797
|
+
});
|
|
2798
|
+
function startDrag(entry, event) {
|
|
2799
|
+
drag.startDrag(entry.id, event.currentTarget, event);
|
|
2800
|
+
}
|
|
2801
|
+
function moveByKeyboard(entry, direction) {
|
|
2802
|
+
const beforeId = resolveKeyboardDropTarget2(order, entry.id, direction);
|
|
2803
|
+
if (beforeId === void 0) {
|
|
2804
|
+
return;
|
|
2805
|
+
}
|
|
2806
|
+
onDrop({ kind: "column-order", beforeId }, entry.id);
|
|
2807
|
+
}
|
|
2808
|
+
return {
|
|
2809
|
+
draggedColumnId: drag.draggedId,
|
|
2810
|
+
dropTarget: drag.dropTarget,
|
|
2811
|
+
ghostTransform: drag.ghostTransform,
|
|
2812
|
+
startDrag,
|
|
2813
|
+
moveByKeyboard,
|
|
2814
|
+
justDragged: drag.justDragged
|
|
2815
|
+
};
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
// src/DataGrid/useColumnResize.ts
|
|
2819
|
+
import {
|
|
2820
|
+
useState as useState11
|
|
2821
|
+
} from "react";
|
|
2822
|
+
import {
|
|
2823
|
+
beginColumnResize,
|
|
2824
|
+
clampColumnWidth,
|
|
2825
|
+
resolveColumnConstraints,
|
|
2826
|
+
sizeColumnToContent
|
|
2827
|
+
} from "@gridkitjs/core";
|
|
2828
|
+
import { measureColumnContent, startColumnResizeGesture } from "@gridkitjs/dom";
|
|
2829
|
+
function useColumnResize({
|
|
2830
|
+
tableRef,
|
|
2831
|
+
controller,
|
|
2832
|
+
columnSizeDefaults
|
|
2833
|
+
}) {
|
|
2834
|
+
const [activeColumnId, setActiveColumnId] = useState11(null);
|
|
2835
|
+
function startResize(entry, event) {
|
|
2836
|
+
event.stopPropagation();
|
|
2837
|
+
const session = beginColumnResize(
|
|
2838
|
+
entry.column,
|
|
2839
|
+
entry.width,
|
|
2840
|
+
event.clientX,
|
|
2841
|
+
columnSizeDefaults
|
|
2842
|
+
);
|
|
2843
|
+
const base = controller.getState().columnSizing;
|
|
2844
|
+
const started = startColumnResizeGesture(
|
|
2845
|
+
event.currentTarget,
|
|
2846
|
+
event,
|
|
2847
|
+
session,
|
|
2848
|
+
{
|
|
2849
|
+
onMove(width) {
|
|
2850
|
+
controller.resizeColumn(session.columnId, width, "move");
|
|
2851
|
+
},
|
|
2852
|
+
onEnd(width) {
|
|
2853
|
+
setActiveColumnId(null);
|
|
2854
|
+
if (width !== null) {
|
|
2855
|
+
controller.resizeColumn(session.columnId, width, "end");
|
|
2856
|
+
}
|
|
2857
|
+
},
|
|
2858
|
+
/**
|
|
2859
|
+
* Escape puts back only the dragged column's pre-drag width, merged
|
|
2860
|
+
* into whatever the sizing state is *now* — not the `base` snapshot
|
|
2861
|
+
* taken at drag-start — so a different column resized via keyboard
|
|
2862
|
+
* while this drag was still open keeps its change instead of being
|
|
2863
|
+
* clobbered by a stale restore.
|
|
2864
|
+
*/
|
|
2865
|
+
onCancel() {
|
|
2866
|
+
setActiveColumnId(null);
|
|
2867
|
+
controller.cancelColumnResize(
|
|
2868
|
+
session.columnId,
|
|
2869
|
+
base,
|
|
2870
|
+
session.startWidth
|
|
2871
|
+
);
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
);
|
|
2875
|
+
if (started) {
|
|
2876
|
+
setActiveColumnId(session.columnId);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
function sizeToContent(entry) {
|
|
2880
|
+
const table = tableRef.current;
|
|
2881
|
+
if (table === null) {
|
|
2882
|
+
return false;
|
|
2883
|
+
}
|
|
2884
|
+
const measured = measureColumnContent(table, entry.id);
|
|
2885
|
+
if (measured === null) {
|
|
2886
|
+
return false;
|
|
2887
|
+
}
|
|
2888
|
+
controller.resizeColumn(
|
|
2889
|
+
entry.id,
|
|
2890
|
+
sizeColumnToContent(
|
|
2891
|
+
measured,
|
|
2892
|
+
resolveColumnConstraints(entry.column, columnSizeDefaults)
|
|
2893
|
+
),
|
|
2894
|
+
"end"
|
|
2895
|
+
);
|
|
2896
|
+
return true;
|
|
1720
2897
|
}
|
|
1721
2898
|
function nudge(entry, delta) {
|
|
1722
|
-
|
|
1723
|
-
sizing,
|
|
2899
|
+
controller.resizeColumn(
|
|
1724
2900
|
entry.id,
|
|
1725
2901
|
clampColumnWidth(
|
|
1726
2902
|
entry.width + delta,
|
|
@@ -1729,238 +2905,107 @@ function useColumnResize({
|
|
|
1729
2905
|
"end"
|
|
1730
2906
|
);
|
|
1731
2907
|
}
|
|
1732
|
-
return { activeColumnId, startResize, sizeToContent, nudge };
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
// src/DataGrid/useColumnSort.ts
|
|
1736
|
-
import {
|
|
1737
|
-
sortDirectionFor,
|
|
1738
|
-
sortPriorityFor,
|
|
1739
|
-
toggleColumnSort
|
|
1740
|
-
} from "@gridkitjs/core";
|
|
1741
|
-
function useColumnSort({
|
|
1742
|
-
sort,
|
|
1743
|
-
setSort,
|
|
1744
|
-
onColumnSortChange
|
|
1745
|
-
}) {
|
|
1746
|
-
function toggle(entry, event) {
|
|
1747
|
-
const next = toggleColumnSort(sort, entry.id, { stack: event.shiftKey });
|
|
1748
|
-
commitIfChanged(sort, next, setSort, (committed) => {
|
|
1749
|
-
onColumnSortChange?.({ columnId: entry.id, sort: committed });
|
|
1750
|
-
});
|
|
1751
|
-
}
|
|
1752
|
-
return {
|
|
1753
|
-
sort,
|
|
1754
|
-
directionFor: (columnId) => sortDirectionFor(sort, columnId),
|
|
1755
|
-
priorityFor: (columnId) => sortPriorityFor(sort, columnId),
|
|
1756
|
-
toggle
|
|
1757
|
-
};
|
|
2908
|
+
return { activeColumnId, startResize, sizeToContent, nudge };
|
|
1758
2909
|
}
|
|
1759
2910
|
|
|
1760
2911
|
// src/DataGrid/useElementWidth.ts
|
|
1761
|
-
import { useLayoutEffect, useState as
|
|
2912
|
+
import { useLayoutEffect as useLayoutEffect10, useState as useState12 } from "react";
|
|
2913
|
+
import { observeElementWidth } from "@gridkitjs/dom";
|
|
1762
2914
|
function useElementWidth(ref, enabled) {
|
|
1763
|
-
const [width, setWidth] =
|
|
1764
|
-
|
|
2915
|
+
const [width, setWidth] = useState12(null);
|
|
2916
|
+
useLayoutEffect10(() => {
|
|
1765
2917
|
const element = ref.current;
|
|
1766
2918
|
if (element === null || !enabled) {
|
|
1767
2919
|
return void 0;
|
|
1768
2920
|
}
|
|
1769
|
-
|
|
1770
|
-
const observer = new ResizeObserver(() => {
|
|
1771
|
-
setWidth(element.clientWidth);
|
|
1772
|
-
});
|
|
1773
|
-
observer.observe(element);
|
|
1774
|
-
return () => {
|
|
1775
|
-
observer.disconnect();
|
|
1776
|
-
};
|
|
2921
|
+
return observeElementWidth(element, setWidth);
|
|
1777
2922
|
}, [ref, enabled]);
|
|
1778
2923
|
return width;
|
|
1779
2924
|
}
|
|
1780
2925
|
|
|
2926
|
+
// src/DataGrid/useGridController.ts
|
|
2927
|
+
import { useState as useState13, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2928
|
+
import {
|
|
2929
|
+
createGridController
|
|
2930
|
+
} from "@gridkitjs/core";
|
|
2931
|
+
function useGridController(options) {
|
|
2932
|
+
const [controller] = useState13(
|
|
2933
|
+
() => createGridController(options)
|
|
2934
|
+
);
|
|
2935
|
+
controller.setOptions(options);
|
|
2936
|
+
const state = useSyncExternalStore2(controller.subscribe, controller.getState);
|
|
2937
|
+
return { controller, state, view: controller.getView() };
|
|
2938
|
+
}
|
|
2939
|
+
|
|
1781
2940
|
// src/DataGrid/useInfiniteScroll.ts
|
|
1782
|
-
import {
|
|
2941
|
+
import { useEffect as useEffect4, useRef as useRef11 } from "react";
|
|
2942
|
+
import { attachInfiniteScroll } from "@gridkitjs/dom";
|
|
1783
2943
|
function useInfiniteScroll({
|
|
1784
2944
|
rootRef,
|
|
1785
2945
|
sentinelRef,
|
|
1786
2946
|
config
|
|
1787
2947
|
}) {
|
|
1788
|
-
const
|
|
1789
|
-
|
|
1790
|
-
const rootMargin = config?.rootMargin ?? "200px";
|
|
1791
|
-
const latestRef = useRef4({
|
|
1792
|
-
hasMore,
|
|
1793
|
-
isLoadingMore,
|
|
1794
|
-
onLoadMore: config?.onLoadMore
|
|
1795
|
-
});
|
|
1796
|
-
useEffect2(() => {
|
|
1797
|
-
latestRef.current = {
|
|
1798
|
-
hasMore,
|
|
1799
|
-
isLoadingMore,
|
|
1800
|
-
onLoadMore: config?.onLoadMore
|
|
1801
|
-
};
|
|
1802
|
-
});
|
|
1803
|
-
const firedRef = useRef4(false);
|
|
1804
|
-
const intersectingRef = useRef4(false);
|
|
1805
|
-
const maybeLoadMore = useCallback(() => {
|
|
1806
|
-
const current = latestRef.current;
|
|
1807
|
-
if (!intersectingRef.current || !current.hasMore || current.isLoadingMore || firedRef.current) {
|
|
1808
|
-
return;
|
|
1809
|
-
}
|
|
1810
|
-
firedRef.current = true;
|
|
1811
|
-
current.onLoadMore?.();
|
|
1812
|
-
}, []);
|
|
1813
|
-
const wasLoadingRef = useRef4(isLoadingMore);
|
|
1814
|
-
useEffect2(() => {
|
|
1815
|
-
if (wasLoadingRef.current && !isLoadingMore) {
|
|
1816
|
-
firedRef.current = false;
|
|
1817
|
-
maybeLoadMore();
|
|
1818
|
-
}
|
|
1819
|
-
wasLoadingRef.current = isLoadingMore;
|
|
1820
|
-
}, [isLoadingMore, maybeLoadMore]);
|
|
1821
|
-
useEffect2(() => {
|
|
1822
|
-
if (!hasMore) {
|
|
1823
|
-
return void 0;
|
|
1824
|
-
}
|
|
2948
|
+
const scroll = useRef11(null);
|
|
2949
|
+
useEffect4(() => {
|
|
1825
2950
|
const root = rootRef.current;
|
|
1826
|
-
|
|
1827
|
-
if (root === null || sentinel === null) {
|
|
2951
|
+
if (root === null) {
|
|
1828
2952
|
return void 0;
|
|
1829
2953
|
}
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
}
|
|
1836
|
-
intersectingRef.current = entry.isIntersecting;
|
|
1837
|
-
maybeLoadMore();
|
|
1838
|
-
},
|
|
1839
|
-
{ root, rootMargin }
|
|
1840
|
-
);
|
|
1841
|
-
observer.observe(sentinel);
|
|
2954
|
+
const attached = attachInfiniteScroll(root, {
|
|
2955
|
+
sentinel: null,
|
|
2956
|
+
hasMore: false
|
|
2957
|
+
});
|
|
2958
|
+
scroll.current = attached;
|
|
1842
2959
|
return () => {
|
|
1843
|
-
|
|
1844
|
-
|
|
2960
|
+
attached.detach();
|
|
2961
|
+
scroll.current = null;
|
|
1845
2962
|
};
|
|
1846
|
-
}, [
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
pagination,
|
|
1855
|
-
setPagination,
|
|
1856
|
-
rows,
|
|
1857
|
-
onPaginationChange
|
|
1858
|
-
}) {
|
|
1859
|
-
const { pageCount, pageIndex } = paginateRows(rows, pagination);
|
|
1860
|
-
function commit(next) {
|
|
1861
|
-
commitIfChanged(pagination, next, setPagination, (committed) => {
|
|
1862
|
-
const { pageCount: committedPageCount } = paginateRows(rows, committed);
|
|
1863
|
-
onPaginationChange?.({
|
|
1864
|
-
pagination: committed,
|
|
1865
|
-
pageCount: committedPageCount
|
|
1866
|
-
});
|
|
1867
|
-
});
|
|
1868
|
-
}
|
|
1869
|
-
function goToPage(nextPageIndex) {
|
|
1870
|
-
const { pageIndex: clamped } = paginateRows(rows, {
|
|
1871
|
-
...pagination,
|
|
1872
|
-
pageIndex: nextPageIndex
|
|
2963
|
+
}, [rootRef]);
|
|
2964
|
+
useEffect4(() => {
|
|
2965
|
+
scroll.current?.update({
|
|
2966
|
+
sentinel: sentinelRef.current,
|
|
2967
|
+
hasMore: config?.hasMore ?? false,
|
|
2968
|
+
onLoadMore: config?.onLoadMore,
|
|
2969
|
+
isLoadingMore: config?.isLoadingMore,
|
|
2970
|
+
rootMargin: config?.rootMargin
|
|
1873
2971
|
});
|
|
1874
|
-
|
|
1875
|
-
}
|
|
1876
|
-
return {
|
|
1877
|
-
pagination,
|
|
1878
|
-
pageCount,
|
|
1879
|
-
currentPage: Math.min(pagination.pageIndex + 1, pageCount),
|
|
1880
|
-
goToPage,
|
|
1881
|
-
nextPage: () => {
|
|
1882
|
-
goToPage(pageIndex + 1);
|
|
1883
|
-
},
|
|
1884
|
-
previousPage: () => {
|
|
1885
|
-
goToPage(pageIndex - 1);
|
|
1886
|
-
},
|
|
1887
|
-
setPageSize: (pageSize) => {
|
|
1888
|
-
const next = { pageIndex: 0, pageSize };
|
|
1889
|
-
const { pageIndex: clamped } = paginateRows(rows, next);
|
|
1890
|
-
commit({ ...next, pageIndex: clamped });
|
|
1891
|
-
}
|
|
1892
|
-
};
|
|
2972
|
+
});
|
|
1893
2973
|
}
|
|
1894
2974
|
|
|
1895
|
-
// src/DataGrid/
|
|
1896
|
-
import {
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
}
|
|
1915
|
-
function commitGroupBy(next, columnId) {
|
|
1916
|
-
commitIfChanged(groupBy, next, setGroupBy, (committed) => {
|
|
1917
|
-
onGroupByChange?.({ columnId, groupBy: committed });
|
|
1918
|
-
});
|
|
1919
|
-
}
|
|
1920
|
-
function toggleGroupBy(columnId) {
|
|
1921
|
-
const isGrouped = groupBy.some((entry) => entry.columnId === columnId);
|
|
1922
|
-
const next = isGrouped ? groupBy.filter((entry) => entry.columnId !== columnId) : [...groupBy, { columnId }];
|
|
1923
|
-
commitGroupBy(next, columnId);
|
|
1924
|
-
}
|
|
1925
|
-
function moveGroupBy(columnId, beforeColumnId) {
|
|
1926
|
-
commitGroupBy(
|
|
1927
|
-
moveGroupByBefore(groupBy, columnId, beforeColumnId),
|
|
1928
|
-
columnId
|
|
1929
|
-
);
|
|
1930
|
-
}
|
|
1931
|
-
return {
|
|
1932
|
-
groupBy,
|
|
1933
|
-
expansion,
|
|
1934
|
-
isExpanded: (groupId) => !expansion.includes(groupId),
|
|
1935
|
-
toggleExpansion: (groupId) => {
|
|
1936
|
-
commitExpansion(toggleGroupExpansion(expansion, groupId), groupId);
|
|
1937
|
-
},
|
|
1938
|
-
expandAll: () => {
|
|
1939
|
-
commitExpansion(expandAllGroups(expansion), null);
|
|
1940
|
-
},
|
|
1941
|
-
collapseAll: (rows) => {
|
|
1942
|
-
commitExpansion(collapseAllGroups(rows), null);
|
|
1943
|
-
},
|
|
1944
|
-
toggleGroupBy,
|
|
1945
|
-
moveGroupBy
|
|
1946
|
-
};
|
|
2975
|
+
// src/DataGrid/useLiveAnnouncer.ts
|
|
2976
|
+
import { useCallback, useLayoutEffect as useLayoutEffect11, useRef as useRef12 } from "react";
|
|
2977
|
+
import { createLiveAnnouncer } from "@gridkitjs/dom";
|
|
2978
|
+
function useLiveAnnouncer(containerRef) {
|
|
2979
|
+
const announcer = useRef12(null);
|
|
2980
|
+
useLayoutEffect11(() => {
|
|
2981
|
+
const container = containerRef.current;
|
|
2982
|
+
if (container === null) {
|
|
2983
|
+
return void 0;
|
|
2984
|
+
}
|
|
2985
|
+
const created = createLiveAnnouncer(container);
|
|
2986
|
+
announcer.current = created;
|
|
2987
|
+
return () => {
|
|
2988
|
+
created.destroy();
|
|
2989
|
+
announcer.current = null;
|
|
2990
|
+
};
|
|
2991
|
+
}, [containerRef]);
|
|
2992
|
+
return useCallback((text) => {
|
|
2993
|
+
announcer.current?.announce(text);
|
|
2994
|
+
}, []);
|
|
1947
2995
|
}
|
|
1948
2996
|
|
|
1949
2997
|
// src/DataGrid/useRowVirtualizer.ts
|
|
1950
|
-
import {
|
|
1951
|
-
|
|
1952
|
-
useEffect as useEffect3,
|
|
1953
|
-
useLayoutEffect as useLayoutEffect2,
|
|
1954
|
-
useRef as useRef5,
|
|
1955
|
-
useState as useState5
|
|
1956
|
-
} from "react";
|
|
1957
|
-
import { visibleRange } from "@gridkitjs/core";
|
|
2998
|
+
import { useLayoutEffect as useLayoutEffect12, useState as useState14 } from "react";
|
|
2999
|
+
import { createRowVirtualizer } from "@gridkitjs/dom";
|
|
1958
3000
|
var EMPTY_RANGE = {
|
|
1959
3001
|
startIndex: 0,
|
|
1960
3002
|
endIndex: -1,
|
|
1961
3003
|
offsetBefore: 0,
|
|
1962
3004
|
offsetAfter: 0
|
|
1963
3005
|
};
|
|
3006
|
+
function ignoreRow() {
|
|
3007
|
+
return () => void 0;
|
|
3008
|
+
}
|
|
1964
3009
|
function useRowVirtualizer({
|
|
1965
3010
|
enabled,
|
|
1966
3011
|
rows,
|
|
@@ -1968,339 +3013,142 @@ function useRowVirtualizer({
|
|
|
1968
3013
|
estimatedRowHeight,
|
|
1969
3014
|
overscan
|
|
1970
3015
|
}) {
|
|
1971
|
-
const
|
|
1972
|
-
const
|
|
1973
|
-
|
|
1974
|
-
const viewportHeightRef = useRef5(0);
|
|
1975
|
-
const elementsRef = useRef5(/* @__PURE__ */ new Map());
|
|
1976
|
-
const indexByElementRef = useRef5(/* @__PURE__ */ new Map());
|
|
1977
|
-
const refCallbacksRef = useRef5(
|
|
1978
|
-
/* @__PURE__ */ new Map()
|
|
1979
|
-
);
|
|
1980
|
-
const observerRef = useRef5(null);
|
|
1981
|
-
const pendingScrollRef = useRef5(void 0);
|
|
1982
|
-
const [range, setRange] = useState5(EMPTY_RANGE);
|
|
1983
|
-
const recompute = useCallback2(() => {
|
|
1984
|
-
setRange(
|
|
1985
|
-
enabled ? visibleRange(
|
|
1986
|
-
heightsRef.current,
|
|
1987
|
-
estimatedRowHeight,
|
|
1988
|
-
scrollTopRef.current,
|
|
1989
|
-
viewportHeightRef.current,
|
|
1990
|
-
overscan
|
|
1991
|
-
) : rowCount === 0 ? EMPTY_RANGE : {
|
|
1992
|
-
startIndex: 0,
|
|
1993
|
-
endIndex: rowCount - 1,
|
|
1994
|
-
offsetBefore: 0,
|
|
1995
|
-
offsetAfter: 0
|
|
1996
|
-
}
|
|
1997
|
-
);
|
|
1998
|
-
}, [enabled, rowCount, estimatedRowHeight, overscan]);
|
|
1999
|
-
useLayoutEffect2(() => {
|
|
2000
|
-
heightsRef.current = new Array(rowCount).fill(
|
|
2001
|
-
void 0
|
|
2002
|
-
);
|
|
2003
|
-
recompute();
|
|
2004
|
-
}, [rows, rowCount, recompute]);
|
|
2005
|
-
useLayoutEffect2(() => {
|
|
2006
|
-
if (!enabled) {
|
|
2007
|
-
return void 0;
|
|
2008
|
-
}
|
|
3016
|
+
const [virtualizer, setVirtualizer] = useState14(null);
|
|
3017
|
+
const [range, setRange] = useState14(EMPTY_RANGE);
|
|
3018
|
+
useLayoutEffect12(() => {
|
|
2009
3019
|
const element = bodyScrollRef.current;
|
|
2010
|
-
if (element === null) {
|
|
2011
|
-
return void 0;
|
|
2012
|
-
}
|
|
2013
|
-
scrollTopRef.current = element.scrollTop;
|
|
2014
|
-
viewportHeightRef.current = element.clientHeight;
|
|
2015
|
-
recompute();
|
|
2016
|
-
const handleScroll = () => {
|
|
2017
|
-
scrollTopRef.current = element.scrollTop;
|
|
2018
|
-
recompute();
|
|
2019
|
-
};
|
|
2020
|
-
element.addEventListener("scroll", handleScroll, { passive: true });
|
|
2021
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
2022
|
-
viewportHeightRef.current = element.clientHeight;
|
|
2023
|
-
recompute();
|
|
2024
|
-
});
|
|
2025
|
-
resizeObserver.observe(element);
|
|
2026
|
-
return () => {
|
|
2027
|
-
element.removeEventListener("scroll", handleScroll);
|
|
2028
|
-
resizeObserver.disconnect();
|
|
2029
|
-
};
|
|
2030
|
-
}, [enabled, bodyScrollRef, recompute]);
|
|
2031
|
-
useEffect3(() => {
|
|
2032
|
-
if (!enabled) {
|
|
3020
|
+
if (!enabled || element === null) {
|
|
2033
3021
|
return void 0;
|
|
2034
3022
|
}
|
|
2035
|
-
const
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
if (index === void 0) continue;
|
|
2040
|
-
const height = entry.target.getBoundingClientRect().height;
|
|
2041
|
-
if (heightsRef.current[index] !== height) {
|
|
2042
|
-
heightsRef.current[index] = height;
|
|
2043
|
-
changed = true;
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
if (changed) {
|
|
2047
|
-
recompute();
|
|
2048
|
-
}
|
|
3023
|
+
const created = createRowVirtualizer(element, {
|
|
3024
|
+
estimatedRowHeight,
|
|
3025
|
+
overscan,
|
|
3026
|
+
onRange: setRange
|
|
2049
3027
|
});
|
|
2050
|
-
|
|
2051
|
-
for (const element of elementsRef.current.values()) {
|
|
2052
|
-
observer.observe(element);
|
|
2053
|
-
}
|
|
3028
|
+
setVirtualizer(created);
|
|
2054
3029
|
return () => {
|
|
2055
|
-
|
|
2056
|
-
observerRef.current = null;
|
|
3030
|
+
created.destroy();
|
|
2057
3031
|
};
|
|
2058
|
-
}, [enabled,
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
const observer = observerRef.current;
|
|
2064
|
-
const previous = elementsRef.current.get(index);
|
|
2065
|
-
if (previous !== void 0) {
|
|
2066
|
-
observer?.unobserve(previous);
|
|
2067
|
-
indexByElementRef.current.delete(previous);
|
|
2068
|
-
elementsRef.current.delete(index);
|
|
2069
|
-
}
|
|
2070
|
-
if (element === null) {
|
|
2071
|
-
return;
|
|
2072
|
-
}
|
|
2073
|
-
elementsRef.current.set(index, element);
|
|
2074
|
-
indexByElementRef.current.set(element, index);
|
|
2075
|
-
observer?.observe(element);
|
|
2076
|
-
};
|
|
2077
|
-
refCallbacksRef.current.set(index, callback);
|
|
2078
|
-
}
|
|
2079
|
-
return callback;
|
|
2080
|
-
}
|
|
2081
|
-
useEffect3(() => {
|
|
2082
|
-
const pending = pendingScrollRef.current;
|
|
2083
|
-
if (pending === void 0) {
|
|
2084
|
-
return;
|
|
2085
|
-
}
|
|
2086
|
-
const element = elementsRef.current.get(pending.index);
|
|
2087
|
-
if (element === void 0) {
|
|
2088
|
-
return;
|
|
2089
|
-
}
|
|
2090
|
-
element.scrollIntoView(pending.options);
|
|
2091
|
-
pendingScrollRef.current = void 0;
|
|
2092
|
-
}, [range]);
|
|
2093
|
-
function estimateOffsetBefore(index) {
|
|
2094
|
-
let total = 0;
|
|
2095
|
-
for (let current = 0; current < index; current++) {
|
|
2096
|
-
total += heightsRef.current[current] ?? estimatedRowHeight;
|
|
2097
|
-
}
|
|
2098
|
-
return total;
|
|
2099
|
-
}
|
|
2100
|
-
function scrollToIndex(index, options) {
|
|
2101
|
-
const element = bodyScrollRef.current;
|
|
2102
|
-
if (element === null || rowCount === 0) {
|
|
2103
|
-
return;
|
|
2104
|
-
}
|
|
2105
|
-
const clamped = Math.max(0, Math.min(index, rowCount - 1));
|
|
2106
|
-
const mounted = elementsRef.current.get(clamped);
|
|
2107
|
-
if (mounted !== void 0) {
|
|
2108
|
-
mounted.scrollIntoView(options);
|
|
2109
|
-
return;
|
|
2110
|
-
}
|
|
2111
|
-
pendingScrollRef.current = { index: clamped, options };
|
|
2112
|
-
element.scrollTop = estimateOffsetBefore(clamped);
|
|
2113
|
-
}
|
|
3032
|
+
}, [enabled, bodyScrollRef, estimatedRowHeight, overscan]);
|
|
3033
|
+
useLayoutEffect12(() => {
|
|
3034
|
+
virtualizer?.setRowCount(rows.length);
|
|
3035
|
+
virtualizer?.resetHeights();
|
|
3036
|
+
}, [virtualizer, rows]);
|
|
2114
3037
|
return {
|
|
2115
3038
|
startIndex: range.startIndex,
|
|
2116
3039
|
endIndex: range.endIndex,
|
|
2117
3040
|
offsetBefore: range.offsetBefore,
|
|
2118
3041
|
offsetAfter: range.offsetAfter,
|
|
2119
|
-
measureRow,
|
|
2120
|
-
scrollToIndex
|
|
3042
|
+
measureRow: virtualizer?.measureRow ?? ignoreRow,
|
|
3043
|
+
scrollToIndex: (index, options) => {
|
|
3044
|
+
virtualizer?.scrollToIndex(index, options);
|
|
3045
|
+
}
|
|
2121
3046
|
};
|
|
2122
3047
|
}
|
|
2123
3048
|
|
|
2124
3049
|
// src/DataGrid/DataGrid.tsx
|
|
2125
|
-
import { jsx as
|
|
2126
|
-
var DEFAULT_PAGE_SIZE = 25;
|
|
3050
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2127
3051
|
var NO_AGGREGATES = [];
|
|
2128
|
-
function
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
3052
|
+
function paginationReader(controller) {
|
|
3053
|
+
let last;
|
|
3054
|
+
return () => {
|
|
3055
|
+
const { pageIndex } = controller.getView();
|
|
3056
|
+
const { pageSize } = controller.getState().pagination;
|
|
3057
|
+
if (last?.pageIndex !== pageIndex || last.pageSize !== pageSize) {
|
|
3058
|
+
last = { pageIndex, pageSize };
|
|
3059
|
+
}
|
|
3060
|
+
return last;
|
|
3061
|
+
};
|
|
3062
|
+
}
|
|
3063
|
+
function selectedRowsReader(controller) {
|
|
3064
|
+
let last;
|
|
3065
|
+
return () => {
|
|
3066
|
+
const { rows } = controller.getView();
|
|
3067
|
+
const selection = controller.getState().rowSelection;
|
|
3068
|
+
if (last?.rows !== rows || last.selection !== selection) {
|
|
3069
|
+
const rowsById = new Map(rows.map((entry) => [entry.rowId, entry]));
|
|
3070
|
+
last = { rows, selection, selected: resolveRows(rowsById, selection) };
|
|
3071
|
+
}
|
|
3072
|
+
return last.selected;
|
|
3073
|
+
};
|
|
3074
|
+
}
|
|
3075
|
+
function DataGrid(props) {
|
|
3076
|
+
const {
|
|
3077
|
+
borders,
|
|
3078
|
+
hoverable,
|
|
3079
|
+
selectable,
|
|
3080
|
+
resizeMode = "fit",
|
|
3081
|
+
columnSizeDefaults,
|
|
3082
|
+
sortableColumns = false,
|
|
3083
|
+
groupableColumns = false,
|
|
3084
|
+
groupToggleIconColumns = true,
|
|
3085
|
+
groupByBarVisibility = "auto",
|
|
3086
|
+
paginated = false,
|
|
3087
|
+
pager,
|
|
3088
|
+
infiniteScroll,
|
|
3089
|
+
aggregates = NO_AGGREGATES,
|
|
3090
|
+
groupAggregateDisplay = "inline",
|
|
3091
|
+
height,
|
|
3092
|
+
virtualized = false,
|
|
3093
|
+
overscan = 4,
|
|
3094
|
+
estimatedRowHeight = 40,
|
|
3095
|
+
label,
|
|
3096
|
+
labelledBy,
|
|
3097
|
+
locale,
|
|
3098
|
+
getRowProps,
|
|
3099
|
+
onRowClick,
|
|
3100
|
+
onRowDoubleClick,
|
|
3101
|
+
messages: messageOverrides,
|
|
3102
|
+
ref
|
|
3103
|
+
} = props;
|
|
2174
3104
|
const hoverRows = hoverable?.rows ?? true;
|
|
2175
3105
|
const hoverColumns = hoverable?.columns ?? true;
|
|
2176
3106
|
const hoverCells = hoverable?.cells ?? true;
|
|
2177
|
-
const viewportRef =
|
|
2178
|
-
const headerTableRef =
|
|
2179
|
-
const bodyTableRef =
|
|
2180
|
-
const bodyScrollRef =
|
|
2181
|
-
const sentinelRef =
|
|
3107
|
+
const viewportRef = useRef13(null);
|
|
3108
|
+
const headerTableRef = useRef13(null);
|
|
3109
|
+
const bodyTableRef = useRef13(null);
|
|
3110
|
+
const bodyScrollRef = useRef13(null);
|
|
3111
|
+
const sentinelRef = useRef13(null);
|
|
2182
3112
|
const viewportWidth = useElementWidth(viewportRef, resizeMode === "fit");
|
|
2183
|
-
const subscribersRef =
|
|
2184
|
-
const
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
);
|
|
2190
|
-
const [sort, setSort] = useState6(defaultColumnSort ?? []);
|
|
2191
|
-
const [groupBy, setGroupBy] = useState6(defaultGroupBy ?? []);
|
|
2192
|
-
const [expansion, setExpansion] = useState6(
|
|
2193
|
-
defaultGroupExpansion ?? []
|
|
2194
|
-
);
|
|
2195
|
-
const [filter] = useState6(defaultFilter ?? []);
|
|
2196
|
-
const [pagination, setPagination] = useState6(
|
|
2197
|
-
defaultPagination ?? { pageIndex: 0, pageSize: DEFAULT_PAGE_SIZE }
|
|
2198
|
-
);
|
|
2199
|
-
const [announcement, setAnnouncement] = useState6("");
|
|
2200
|
-
const [rowSelection, setRowSelection] = useState6(
|
|
2201
|
-
defaultRowSelection ?? []
|
|
2202
|
-
);
|
|
2203
|
-
const [columnSelection, setColumnSelection] = useState6(
|
|
2204
|
-
defaultColumnSelection ?? []
|
|
2205
|
-
);
|
|
2206
|
-
const [cellSelection, setCellSelection] = useState6(
|
|
2207
|
-
defaultCellSelection ?? null
|
|
3113
|
+
const subscribersRef = useRef13(/* @__PURE__ */ new Set());
|
|
3114
|
+
const gridId = useId();
|
|
3115
|
+
const announce = useLiveAnnouncer(viewportRef);
|
|
3116
|
+
const messages = useMemo4(
|
|
3117
|
+
() => resolveMessages(messageOverrides),
|
|
3118
|
+
[messageOverrides]
|
|
2208
3119
|
);
|
|
2209
|
-
const
|
|
2210
|
-
|
|
2211
|
-
rowId: resolveRowId(row, rowIndex, getRowId),
|
|
2212
|
-
row,
|
|
2213
|
-
rowIndex,
|
|
2214
|
-
datasetIndex: rowIndex
|
|
2215
|
-
})) ?? [],
|
|
2216
|
-
[dataSource, getRowId]
|
|
2217
|
-
);
|
|
2218
|
-
const definedColumns = useMemo4(() => {
|
|
2219
|
-
if (columns && columns.length !== 0) return columns;
|
|
2220
|
-
if (dataSource && dataSource.length > 0)
|
|
2221
|
-
return defineColumnsFromRows(dataSource);
|
|
2222
|
-
return [];
|
|
2223
|
-
}, [columns, dataSource]);
|
|
2224
|
-
const orderedColumns = useMemo4(
|
|
2225
|
-
() => applyColumnOrder(definedColumns, order),
|
|
2226
|
-
[definedColumns, order]
|
|
2227
|
-
);
|
|
2228
|
-
const resolved = useMemo4(() => {
|
|
2229
|
-
const widths = resolveColumnWidths(orderedColumns, sizing, {
|
|
2230
|
-
sizes: columnSizeDefaults,
|
|
2231
|
-
resizable: resizableColumns,
|
|
2232
|
-
reorderable: reorderableColumns,
|
|
2233
|
-
groupByDraggable: groupByDraggableColumns
|
|
2234
|
-
});
|
|
2235
|
-
return resizeMode === "fit" && viewportWidth !== null ? fitColumnsToWidth(widths, viewportWidth, columnSizeDefaults) : widths;
|
|
2236
|
-
}, [
|
|
2237
|
-
orderedColumns,
|
|
2238
|
-
sizing,
|
|
2239
|
-
resizeMode,
|
|
3120
|
+
const { controller, state, view } = useGridController({
|
|
3121
|
+
...props,
|
|
2240
3122
|
viewportWidth,
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
);
|
|
2250
|
-
const
|
|
2251
|
-
() => groupRows(shownRows, groupBy, expansion, resolved),
|
|
2252
|
-
[shownRows, groupBy, expansion, resolved]
|
|
2253
|
-
);
|
|
2254
|
-
const activeAggregates = aggregates ?? NO_AGGREGATES;
|
|
2255
|
-
const aggregatedRows = useMemo4(
|
|
2256
|
-
() => withGroupAggregates(
|
|
2257
|
-
displayRows,
|
|
2258
|
-
shownRows,
|
|
2259
|
-
groupBy,
|
|
2260
|
-
activeAggregates,
|
|
2261
|
-
resolved,
|
|
2262
|
-
groupAggregateDisplay
|
|
2263
|
-
),
|
|
2264
|
-
[
|
|
2265
|
-
displayRows,
|
|
2266
|
-
shownRows,
|
|
2267
|
-
groupBy,
|
|
2268
|
-
activeAggregates,
|
|
2269
|
-
resolved,
|
|
2270
|
-
groupAggregateDisplay
|
|
2271
|
-
]
|
|
2272
|
-
);
|
|
2273
|
-
const grandTotal = useMemo4(
|
|
2274
|
-
() => computeAggregates(
|
|
2275
|
-
shownRows.map((entry) => entry.row),
|
|
2276
|
-
activeAggregates,
|
|
2277
|
-
resolved
|
|
2278
|
-
),
|
|
2279
|
-
[shownRows, activeAggregates, resolved]
|
|
2280
|
-
);
|
|
2281
|
-
const paginatedRows = useMemo4(
|
|
2282
|
-
() => paginated ? paginateRows2(aggregatedRows, pagination) : { rows: aggregatedRows, pageCount: 1, pageIndex: 0 },
|
|
2283
|
-
[paginated, aggregatedRows, pagination]
|
|
2284
|
-
);
|
|
3123
|
+
...announcedCallbacks({
|
|
3124
|
+
callbacks: props,
|
|
3125
|
+
announce,
|
|
3126
|
+
messages,
|
|
3127
|
+
columnName,
|
|
3128
|
+
columnOf
|
|
3129
|
+
})
|
|
3130
|
+
});
|
|
3131
|
+
const [readPagination] = useState15(() => paginationReader(controller));
|
|
3132
|
+
const [readSelectedRows] = useState15(() => selectedRowsReader(controller));
|
|
2285
3133
|
const virtualizer = useRowVirtualizer({
|
|
2286
3134
|
enabled: virtualized,
|
|
2287
|
-
rows:
|
|
3135
|
+
rows: view.pageRows,
|
|
2288
3136
|
bodyScrollRef,
|
|
2289
3137
|
estimatedRowHeight,
|
|
2290
3138
|
overscan
|
|
2291
3139
|
});
|
|
2292
|
-
|
|
3140
|
+
useEffect5(() => {
|
|
2293
3141
|
if (virtualized && height === void 0) {
|
|
2294
3142
|
console.error(
|
|
2295
|
-
"
|
|
3143
|
+
"DataGrid: `virtualized` has no effect without `height` \u2014 a body with no bounded height has no viewport to window rows against."
|
|
2296
3144
|
);
|
|
2297
3145
|
}
|
|
2298
3146
|
}, [virtualized, height]);
|
|
2299
3147
|
const hasInfiniteScroll = infiniteScroll !== void 0;
|
|
2300
|
-
|
|
3148
|
+
useEffect5(() => {
|
|
2301
3149
|
if (paginated && hasInfiniteScroll) {
|
|
2302
3150
|
console.error(
|
|
2303
|
-
"
|
|
3151
|
+
"DataGrid: `paginated` and `infiniteScroll` are mutually exclusive \u2014 only `paginated` takes effect while both are set."
|
|
2304
3152
|
);
|
|
2305
3153
|
}
|
|
2306
3154
|
}, [paginated, hasInfiniteScroll]);
|
|
@@ -2309,79 +3157,21 @@ function DataGridComponent({
|
|
|
2309
3157
|
sentinelRef,
|
|
2310
3158
|
config: infiniteScroll
|
|
2311
3159
|
});
|
|
2312
|
-
|
|
2313
|
-
() =>
|
|
2314
|
-
pageIndex: paginatedRows.pageIndex,
|
|
2315
|
-
pageSize: pagination.pageSize
|
|
2316
|
-
}),
|
|
2317
|
-
[paginatedRows.pageIndex, pagination.pageSize]
|
|
2318
|
-
);
|
|
2319
|
-
const displayDataRows = useMemo4(
|
|
2320
|
-
() => groupBy.length === 0 && !paginated ? shownRows : paginatedRows.rows.filter(
|
|
2321
|
-
(entry) => !("kind" in entry)
|
|
2322
|
-
),
|
|
2323
|
-
[paginatedRows, groupBy.length, paginated, shownRows]
|
|
2324
|
-
);
|
|
2325
|
-
function columnName(columnId) {
|
|
2326
|
-
const entry = resolved.find((candidate) => candidate.id === columnId);
|
|
2327
|
-
if (entry === void 0) {
|
|
2328
|
-
return columnId;
|
|
2329
|
-
}
|
|
2330
|
-
return typeof entry.label === "string" ? entry.label : entry.column.field;
|
|
2331
|
-
}
|
|
2332
|
-
function announce(message) {
|
|
2333
|
-
setAnnouncement(message);
|
|
3160
|
+
function columnOf(columnId) {
|
|
3161
|
+
return view.dataColumns.find((candidate) => candidate.id === columnId)?.column;
|
|
2334
3162
|
}
|
|
2335
|
-
function
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
announce(
|
|
2339
|
-
`${columnName(event.columnId)}, ${String(Math.round(event.width))} pixels wide`
|
|
2340
|
-
);
|
|
2341
|
-
}
|
|
3163
|
+
function columnName(columnId) {
|
|
3164
|
+
const column = columnOf(columnId);
|
|
3165
|
+
return column === void 0 ? columnId : resolveColumnHeaderText(column);
|
|
2342
3166
|
}
|
|
2343
3167
|
const resize = useColumnResize({
|
|
2344
|
-
// `measureColumnContent` only ever matches
|
|
2345
|
-
// (never `th`), so the header table has nothing
|
|
2346
|
-
// body table alone was already the effective scope
|
|
3168
|
+
// `@gridkitjs/dom`'s `measureColumnContent` only ever matches
|
|
3169
|
+
// `td[data-gridkit-column]` (never `th`), so the header table has nothing
|
|
3170
|
+
// for it to find — the body table alone was already the effective scope
|
|
3171
|
+
// before this split.
|
|
2347
3172
|
tableRef: bodyTableRef,
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
columnSizeDefaults,
|
|
2351
|
-
onColumnResize: handleColumnResize
|
|
2352
|
-
});
|
|
2353
|
-
function handleGroupByChange(event) {
|
|
2354
|
-
onGroupByChange?.(event);
|
|
2355
|
-
const entry = event.groupBy.find(
|
|
2356
|
-
(candidate) => candidate.columnId === event.columnId
|
|
2357
|
-
);
|
|
2358
|
-
if (entry === void 0) {
|
|
2359
|
-
announce(`${columnName(event.columnId)}, grouping removed`);
|
|
2360
|
-
return;
|
|
2361
|
-
}
|
|
2362
|
-
announce(
|
|
2363
|
-
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)}`
|
|
2364
|
-
);
|
|
2365
|
-
}
|
|
2366
|
-
function handleGroupExpansionChange(event) {
|
|
2367
|
-
onGroupExpansionChange?.(event);
|
|
2368
|
-
if (event.groupId === null) {
|
|
2369
|
-
announce(
|
|
2370
|
-
event.expansion.length === 0 ? "All groups expanded" : "All groups collapsed"
|
|
2371
|
-
);
|
|
2372
|
-
return;
|
|
2373
|
-
}
|
|
2374
|
-
announce(
|
|
2375
|
-
event.expansion.includes(event.groupId) ? "Group collapsed" : "Group expanded"
|
|
2376
|
-
);
|
|
2377
|
-
}
|
|
2378
|
-
const grouping = useRowGrouping({
|
|
2379
|
-
groupBy,
|
|
2380
|
-
setGroupBy,
|
|
2381
|
-
expansion,
|
|
2382
|
-
setExpansion,
|
|
2383
|
-
onGroupByChange: handleGroupByChange,
|
|
2384
|
-
onGroupExpansionChange: handleGroupExpansionChange
|
|
3173
|
+
controller,
|
|
3174
|
+
columnSizeDefaults
|
|
2385
3175
|
});
|
|
2386
3176
|
const nav = useGridNavigation({
|
|
2387
3177
|
headerTableRef,
|
|
@@ -2392,131 +3182,106 @@ function DataGridComponent({
|
|
|
2392
3182
|
// Group headers are addressable rows too — the whole point of the flat
|
|
2393
3183
|
// `DisplayRow[]` shape is that they share one position space with data
|
|
2394
3184
|
// rows, so navigation counts them the same way. Page-relative
|
|
2395
|
-
// (`
|
|
3185
|
+
// (`view.pageRows`, not `view.displayRows`): arrow keys operate on what's
|
|
2396
3186
|
// actually in the DOM, which is the current page — a different "page"
|
|
2397
3187
|
// concept than `useGridNavigation`'s own Page Up/Down viewport scrolling.
|
|
2398
|
-
rowCount:
|
|
2399
|
-
columnCount:
|
|
3188
|
+
rowCount: view.pageRows.length,
|
|
3189
|
+
columnCount: view.columns.length,
|
|
2400
3190
|
// A group's own summary row (`groupAggregateDisplay: "row"`) occupies a
|
|
2401
3191
|
// real slot in `rowCount` above — its DOM position has to line up with
|
|
2402
3192
|
// everything else — but is presentational, never a tab stop: arrow-key
|
|
2403
3193
|
// vertical movement steps over it rather than landing there.
|
|
2404
3194
|
isSkippableRow: (rowIndex) => {
|
|
2405
|
-
const entry =
|
|
3195
|
+
const entry = view.pageRows[rowIndex];
|
|
2406
3196
|
return entry !== void 0 && "kind" in entry && entry.kind === "group-summary";
|
|
2407
3197
|
}
|
|
2408
3198
|
});
|
|
3199
|
+
const panels = useGridPanels({ rootRef: viewportRef, headerTableRef, nav });
|
|
3200
|
+
const commands = useGridCommands({
|
|
3201
|
+
controller,
|
|
3202
|
+
commands: props.commands,
|
|
3203
|
+
onCommand: props.onCommand,
|
|
3204
|
+
messages,
|
|
3205
|
+
announce,
|
|
3206
|
+
resize,
|
|
3207
|
+
openPanel: panels.open
|
|
3208
|
+
});
|
|
3209
|
+
const orderedIds = useMemo4(
|
|
3210
|
+
() => view.dataColumns.map((entry) => entry.id),
|
|
3211
|
+
[view.dataColumns]
|
|
3212
|
+
);
|
|
2409
3213
|
const displayedIds = useMemo4(
|
|
2410
|
-
() =>
|
|
2411
|
-
[
|
|
3214
|
+
() => view.columns.map((entry) => entry.id),
|
|
3215
|
+
[view.columns]
|
|
3216
|
+
);
|
|
3217
|
+
const definitions = useMemo4(
|
|
3218
|
+
() => new Map(view.dataColumns.map((entry) => [entry.id, entry.column])),
|
|
3219
|
+
[view.dataColumns]
|
|
2412
3220
|
);
|
|
2413
3221
|
const groupByDraggableIds = useMemo4(
|
|
2414
3222
|
() => new Set(
|
|
2415
|
-
|
|
3223
|
+
view.columns.filter((entry) => entry.groupByDraggable).map((entry) => entry.id)
|
|
2416
3224
|
),
|
|
2417
|
-
[
|
|
3225
|
+
[view.columns]
|
|
2418
3226
|
);
|
|
2419
3227
|
function handleDrop(target, movedId) {
|
|
2420
3228
|
if (target.kind === "group-by") {
|
|
2421
|
-
|
|
3229
|
+
controller.moveGroupBy(movedId, target.beforeColumnId);
|
|
2422
3230
|
return;
|
|
2423
3231
|
}
|
|
2424
|
-
const next = moveColumnBefore(
|
|
2425
|
-
if (next ===
|
|
3232
|
+
const next = moveColumnBefore(orderedIds, movedId, target.beforeId);
|
|
3233
|
+
if (next === orderedIds) {
|
|
2426
3234
|
return;
|
|
2427
3235
|
}
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
3236
|
+
controller.moveColumn(movedId, target.beforeId);
|
|
3237
|
+
const shown = next.filter((id) => displayedIds.includes(id));
|
|
3238
|
+
const position = shown.indexOf(movedId);
|
|
2431
3239
|
announce(
|
|
2432
|
-
|
|
3240
|
+
messages.columnMoved(columnName(movedId), position + 1, shown.length)
|
|
2433
3241
|
);
|
|
2434
3242
|
nav.focusCell(HEADER_ROW, position);
|
|
2435
3243
|
}
|
|
2436
3244
|
const drag = useColumnDrag({
|
|
2437
3245
|
order: displayedIds,
|
|
2438
|
-
groupBy,
|
|
3246
|
+
groupBy: state.groupBy,
|
|
2439
3247
|
groupByDraggableIds,
|
|
2440
3248
|
onDrop: handleDrop
|
|
2441
3249
|
});
|
|
2442
|
-
const draggedColumnAlreadyGrouped = drag.draggedColumnId !== null && groupBy.some((entry) => entry.columnId === drag.draggedColumnId);
|
|
3250
|
+
const draggedColumnAlreadyGrouped = drag.draggedColumnId !== null && state.groupBy.some((entry) => entry.columnId === drag.draggedColumnId);
|
|
2443
3251
|
const dragEligibleForGroupBy = drag.draggedColumnId !== null && groupByDraggableIds.has(drag.draggedColumnId) && !draggedColumnAlreadyGrouped;
|
|
2444
|
-
const showGroupByBar = groupByBarVisibility === "always" || groupByBarVisibility === "auto" && (groupBy.length > 0 || dragEligibleForGroupBy);
|
|
3252
|
+
const showGroupByBar = groupByBarVisibility === "always" || groupByBarVisibility === "auto" && (state.groupBy.length > 0 || dragEligibleForGroupBy);
|
|
2445
3253
|
const headerGroupByDropTarget = drag.dropTarget?.kind === "group-by" ? drag.dropTarget : null;
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
}
|
|
2471
|
-
const paginationApi = usePagination({
|
|
2472
|
-
pagination,
|
|
2473
|
-
setPagination,
|
|
2474
|
-
rows: displayRows,
|
|
2475
|
-
onPaginationChange: handlePaginationChange
|
|
2476
|
-
});
|
|
2477
|
-
const [previous, setPrevious] = useState6({ filter, sort, groupBy });
|
|
2478
|
-
if (previous.filter !== filter || previous.sort !== sort || previous.groupBy !== groupBy) {
|
|
2479
|
-
setPrevious({ filter, sort, groupBy });
|
|
2480
|
-
if (pagination.pageIndex !== 0) {
|
|
2481
|
-
setPagination({ ...pagination, pageIndex: 0 });
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
const selection = useGridSelection({
|
|
2485
|
-
rows: displayDataRows,
|
|
2486
|
-
columns: resolved,
|
|
2487
|
-
selectable,
|
|
2488
|
-
rowSelection,
|
|
2489
|
-
setRowSelection,
|
|
2490
|
-
columnSelection,
|
|
2491
|
-
setColumnSelection,
|
|
2492
|
-
cellSelection,
|
|
2493
|
-
setCellSelection,
|
|
2494
|
-
callbacks,
|
|
2495
|
-
announce,
|
|
3254
|
+
const pagerContext = {
|
|
3255
|
+
pagination: state.pagination,
|
|
3256
|
+
currentPage: Math.min(state.pagination.pageIndex + 1, view.pageCount),
|
|
3257
|
+
pageCount: view.pageCount,
|
|
3258
|
+
pageSizeOptions: pager?.sizeOptions,
|
|
3259
|
+
goToPage: controller.goToPage,
|
|
3260
|
+
nextPage: controller.nextPage,
|
|
3261
|
+
previousPage: controller.previousPage,
|
|
3262
|
+
setPageSize: controller.setPageSize
|
|
3263
|
+
};
|
|
3264
|
+
const selection = useGridSelection({ controller, state, selectable });
|
|
3265
|
+
const multiselectable = selection.rowMode === "multiple" || selection.columnMode === "multiple";
|
|
3266
|
+
const contextMenu = useContextMenu({
|
|
3267
|
+
rootRef: viewportRef,
|
|
3268
|
+
headerTableRef,
|
|
3269
|
+
bodyTableRef,
|
|
3270
|
+
bodyScrollRef,
|
|
3271
|
+
contextMenu: props.contextMenu,
|
|
3272
|
+
onContextMenuOpenChange: props.onContextMenuOpenChange,
|
|
3273
|
+
controller,
|
|
3274
|
+
commands,
|
|
3275
|
+
nav,
|
|
3276
|
+
selection,
|
|
3277
|
+
messages,
|
|
2496
3278
|
columnName
|
|
2497
3279
|
});
|
|
2498
|
-
|
|
2499
|
-
useEffect4(() => {
|
|
3280
|
+
useEffect5(() => {
|
|
2500
3281
|
for (const listener of subscribersRef.current) {
|
|
2501
3282
|
listener();
|
|
2502
3283
|
}
|
|
2503
|
-
}, [
|
|
2504
|
-
shownRows,
|
|
2505
|
-
aggregatedRows,
|
|
2506
|
-
resolved,
|
|
2507
|
-
sizing,
|
|
2508
|
-
order,
|
|
2509
|
-
sort,
|
|
2510
|
-
groupBy,
|
|
2511
|
-
expansion,
|
|
2512
|
-
paginationSnapshot,
|
|
2513
|
-
paginatedRows.pageCount,
|
|
2514
|
-
grandTotal,
|
|
2515
|
-
rowSelection,
|
|
2516
|
-
columnSelection,
|
|
2517
|
-
cellSelection,
|
|
2518
|
-
nav.focus
|
|
2519
|
-
]);
|
|
3284
|
+
}, [view, state, nav.focus]);
|
|
2520
3285
|
useImperativeHandle(ref, () => ({
|
|
2521
3286
|
get element() {
|
|
2522
3287
|
return viewportRef.current;
|
|
@@ -2524,38 +3289,70 @@ function DataGridComponent({
|
|
|
2524
3289
|
get table() {
|
|
2525
3290
|
return bodyTableRef.current;
|
|
2526
3291
|
},
|
|
2527
|
-
getRows: () =>
|
|
2528
|
-
//
|
|
2529
|
-
//
|
|
2530
|
-
//
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
getColumns: () =>
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
3292
|
+
getRows: () => controller.getView().rows,
|
|
3293
|
+
// Every group header's own `aggregates` field is populated here — the
|
|
3294
|
+
// whole reason `getDisplayRows()` is where a consumer reads a specific
|
|
3295
|
+
// group's computed results from.
|
|
3296
|
+
getDisplayRows: () => controller.getView().displayRows,
|
|
3297
|
+
getPageRows: () => controller.getView().pageRows,
|
|
3298
|
+
getColumns: () => controller.getView().columns,
|
|
3299
|
+
getDataColumns: () => controller.getView().dataColumns,
|
|
3300
|
+
getColumnSizing: () => controller.getState().columnSizing,
|
|
3301
|
+
getColumnOrder: () => controller.getState().columnOrder,
|
|
3302
|
+
getColumnVisibility: () => controller.getState().columnVisibility,
|
|
3303
|
+
getColumnSort: () => controller.getState().columnSort,
|
|
3304
|
+
getFilter: () => controller.getState().filter,
|
|
3305
|
+
getGroupBy: () => controller.getState().groupBy,
|
|
3306
|
+
getGroupExpansion: () => controller.getState().groupExpansion,
|
|
3307
|
+
getPagination: readPagination,
|
|
3308
|
+
getPageCount: () => controller.getView().pageCount,
|
|
3309
|
+
getAggregates: () => controller.getView().grandTotal,
|
|
3310
|
+
getRowSelection: () => controller.getState().rowSelection,
|
|
3311
|
+
getSelectedRows: readSelectedRows,
|
|
3312
|
+
getColumnSelection: () => controller.getState().columnSelection,
|
|
3313
|
+
getCellSelection: () => controller.getState().cellSelection,
|
|
2545
3314
|
getFocusedCell: () => nav.focus,
|
|
3315
|
+
getState: controller.getState,
|
|
3316
|
+
restoreState: controller.restoreState,
|
|
2546
3317
|
focusCell: nav.focusCell,
|
|
2547
|
-
clearSelection:
|
|
2548
|
-
selectAllRows:
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
3318
|
+
clearSelection: controller.clearSelection,
|
|
3319
|
+
selectAllRows: controller.selectAllRows,
|
|
3320
|
+
selectRows: controller.selectRows,
|
|
3321
|
+
expandAllGroups: controller.expandAllGroups,
|
|
3322
|
+
collapseAllGroups: controller.collapseAllGroups,
|
|
3323
|
+
goToPage: controller.goToPage,
|
|
3324
|
+
nextPage: controller.nextPage,
|
|
3325
|
+
previousPage: controller.previousPage,
|
|
3326
|
+
setPageSize: controller.setPageSize,
|
|
3327
|
+
showColumns: controller.showColumns,
|
|
3328
|
+
hideColumns: controller.hideColumns,
|
|
3329
|
+
setFilter: controller.setFilter,
|
|
3330
|
+
setColumnSort: controller.setColumnSort,
|
|
3331
|
+
setGroupBy: controller.setGroupBy,
|
|
3332
|
+
setGroupExpansion: controller.setGroupExpansion,
|
|
3333
|
+
setPagination: controller.setPagination,
|
|
3334
|
+
setColumnSizing: controller.setColumnSizing,
|
|
3335
|
+
setColumnOrder: controller.setColumnOrder,
|
|
3336
|
+
setColumnVisibility: controller.setColumnVisibility,
|
|
3337
|
+
setRowSelection: controller.setRowSelection,
|
|
3338
|
+
setColumnSelection: controller.setColumnSelection,
|
|
3339
|
+
setCellSelection: controller.setCellSelection,
|
|
3340
|
+
autoFitColumn: (columnId) => {
|
|
3341
|
+
commands.host.autoFitColumns([columnId]);
|
|
2552
3342
|
},
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
3343
|
+
autoFitColumns: (columnIds) => {
|
|
3344
|
+
commands.host.autoFitColumns(
|
|
3345
|
+
columnIds ?? controller.getView().columns.map((entry) => entry.id)
|
|
3346
|
+
);
|
|
3347
|
+
},
|
|
3348
|
+
openContextMenu: contextMenu.open,
|
|
3349
|
+
closeContextMenu: contextMenu.close,
|
|
3350
|
+
openColumnChooser: () => {
|
|
3351
|
+
panels.open("columnChooser", { area: "grid" });
|
|
3352
|
+
},
|
|
3353
|
+
runCommand: (commandId, target = { area: "grid" }) => commands.run(commandId, target, "api"),
|
|
2557
3354
|
scrollToRow: (rowId, options) => {
|
|
2558
|
-
const index =
|
|
3355
|
+
const index = controller.getView().pageRows.findIndex(
|
|
2559
3356
|
(entry) => !("kind" in entry) && entry.rowId === rowId
|
|
2560
3357
|
);
|
|
2561
3358
|
if (index === -1) return;
|
|
@@ -2594,25 +3391,41 @@ function DataGridComponent({
|
|
|
2594
3391
|
selection.columnMode === false ? "" : "selectable-columns",
|
|
2595
3392
|
selection.cellMode === false ? "" : "selectable-cells"
|
|
2596
3393
|
);
|
|
2597
|
-
return /* @__PURE__ */
|
|
2598
|
-
|
|
3394
|
+
return /* @__PURE__ */ jsxs13("div", { className: "gridkit-data-grid-viewport", ref: viewportRef, children: [
|
|
3395
|
+
/* @__PURE__ */ jsx20(
|
|
3396
|
+
GridToolbar,
|
|
3397
|
+
{
|
|
3398
|
+
toolbar: props.toolbar,
|
|
3399
|
+
renderItem: props.renderToolbarItem,
|
|
3400
|
+
gridId,
|
|
3401
|
+
controller,
|
|
3402
|
+
commands,
|
|
3403
|
+
messages,
|
|
3404
|
+
announce
|
|
3405
|
+
}
|
|
3406
|
+
),
|
|
3407
|
+
showGroupByBar && /* @__PURE__ */ jsx20(
|
|
2599
3408
|
GroupByBar,
|
|
2600
3409
|
{
|
|
2601
|
-
columns:
|
|
2602
|
-
|
|
3410
|
+
columns: view.columns,
|
|
3411
|
+
definitions,
|
|
3412
|
+
groupBy: state.groupBy,
|
|
3413
|
+
controller,
|
|
2603
3414
|
columnName,
|
|
2604
3415
|
headerDragEligible: dragEligibleForGroupBy,
|
|
2605
3416
|
headerDragBlocked: draggedColumnAlreadyGrouped,
|
|
2606
|
-
headerDropTarget: headerGroupByDropTarget
|
|
3417
|
+
headerDropTarget: headerGroupByDropTarget,
|
|
3418
|
+
messages
|
|
2607
3419
|
}
|
|
2608
3420
|
),
|
|
2609
|
-
/* @__PURE__ */
|
|
3421
|
+
/* @__PURE__ */ jsxs13(
|
|
2610
3422
|
"div",
|
|
2611
3423
|
{
|
|
3424
|
+
id: gridId,
|
|
2612
3425
|
className: "gridkit-data-grid-tables",
|
|
2613
|
-
role: groupBy.length > 0 ? "treegrid" : "grid",
|
|
2614
|
-
"aria-rowcount":
|
|
2615
|
-
"aria-colcount":
|
|
3426
|
+
role: state.groupBy.length > 0 ? "treegrid" : "grid",
|
|
3427
|
+
"aria-rowcount": view.displayRows.length + 1,
|
|
3428
|
+
"aria-colcount": view.columns.length,
|
|
2616
3429
|
...ariaAttr(multiselectable, "aria-multiselectable", true),
|
|
2617
3430
|
...ariaAttr(labelledBy !== void 0, "aria-labelledby", labelledBy),
|
|
2618
3431
|
...ariaAttr(
|
|
@@ -2621,6 +3434,7 @@ function DataGridComponent({
|
|
|
2621
3434
|
label
|
|
2622
3435
|
),
|
|
2623
3436
|
onKeyDown: (event) => {
|
|
3437
|
+
if (!isOwnEvent(event)) return;
|
|
2624
3438
|
if (event.key === "Escape") {
|
|
2625
3439
|
if (drag.draggedColumnId !== null || resize.activeColumnId !== null)
|
|
2626
3440
|
return;
|
|
@@ -2634,25 +3448,27 @@ function DataGridComponent({
|
|
|
2634
3448
|
}
|
|
2635
3449
|
},
|
|
2636
3450
|
children: [
|
|
2637
|
-
/* @__PURE__ */
|
|
3451
|
+
/* @__PURE__ */ jsxs13(
|
|
2638
3452
|
"table",
|
|
2639
3453
|
{
|
|
2640
3454
|
ref: headerTableRef,
|
|
2641
|
-
style: { width: totalColumnWidth(
|
|
3455
|
+
style: { width: totalColumnWidth(view.columns) },
|
|
2642
3456
|
className: classNames(gridTableClassName, "gridkit-data-grid-header"),
|
|
2643
3457
|
children: [
|
|
2644
|
-
/* @__PURE__ */
|
|
2645
|
-
/* @__PURE__ */
|
|
3458
|
+
/* @__PURE__ */ jsx20(GridColgroup, { columns: view.columns }),
|
|
3459
|
+
/* @__PURE__ */ jsx20(
|
|
2646
3460
|
GridHeader,
|
|
2647
3461
|
{
|
|
2648
|
-
columns:
|
|
3462
|
+
columns: view.columns,
|
|
2649
3463
|
resize,
|
|
2650
3464
|
drag,
|
|
2651
|
-
|
|
3465
|
+
controller,
|
|
3466
|
+
columnSort: state.columnSort,
|
|
2652
3467
|
sortableColumns,
|
|
2653
|
-
|
|
3468
|
+
groupBy: state.groupBy,
|
|
2654
3469
|
groupableColumns,
|
|
2655
3470
|
groupToggleIconColumns,
|
|
3471
|
+
headerMenu: contextMenu.opens("header"),
|
|
2656
3472
|
nav,
|
|
2657
3473
|
selection
|
|
2658
3474
|
}
|
|
@@ -2660,7 +3476,7 @@ function DataGridComponent({
|
|
|
2660
3476
|
]
|
|
2661
3477
|
}
|
|
2662
3478
|
),
|
|
2663
|
-
/* @__PURE__ */
|
|
3479
|
+
/* @__PURE__ */ jsx20(
|
|
2664
3480
|
"div",
|
|
2665
3481
|
{
|
|
2666
3482
|
className: "gridkit-data-grid-body",
|
|
@@ -2668,28 +3484,36 @@ function DataGridComponent({
|
|
|
2668
3484
|
style: height === void 0 ? void 0 : {
|
|
2669
3485
|
"--gridkit-body-height": typeof height === "number" ? `${String(height)}px` : height
|
|
2670
3486
|
},
|
|
2671
|
-
children: /* @__PURE__ */
|
|
3487
|
+
children: /* @__PURE__ */ jsxs13(
|
|
2672
3488
|
"table",
|
|
2673
3489
|
{
|
|
2674
3490
|
ref: bodyTableRef,
|
|
2675
|
-
style: { width: totalColumnWidth(
|
|
3491
|
+
style: { width: totalColumnWidth(view.columns) },
|
|
2676
3492
|
className: gridTableClassName,
|
|
2677
3493
|
children: [
|
|
2678
|
-
/* @__PURE__ */
|
|
2679
|
-
/* @__PURE__ */
|
|
3494
|
+
/* @__PURE__ */ jsx20(GridColgroup, { columns: view.columns }),
|
|
3495
|
+
/* @__PURE__ */ jsx20(
|
|
2680
3496
|
GridBody,
|
|
2681
3497
|
{
|
|
2682
|
-
columns:
|
|
2683
|
-
|
|
3498
|
+
columns: view.columns,
|
|
3499
|
+
definitions,
|
|
3500
|
+
rows: view.pageRows,
|
|
2684
3501
|
activeColumnId: resize.activeColumnId,
|
|
2685
3502
|
nav,
|
|
2686
3503
|
selection,
|
|
2687
|
-
|
|
2688
|
-
aggregates
|
|
3504
|
+
controller,
|
|
3505
|
+
aggregates,
|
|
2689
3506
|
groupAggregateDisplay,
|
|
2690
3507
|
virtualRange: virtualized ? virtualizer : null,
|
|
2691
3508
|
infiniteScroll,
|
|
2692
|
-
sentinelRef
|
|
3509
|
+
sentinelRef,
|
|
3510
|
+
locale,
|
|
3511
|
+
getRowProps,
|
|
3512
|
+
onRowClick,
|
|
3513
|
+
onRowDoubleClick,
|
|
3514
|
+
messages,
|
|
3515
|
+
cellMenu: contextMenu.opens("cell"),
|
|
3516
|
+
groupMenu: contextMenu.opens("group")
|
|
2693
3517
|
}
|
|
2694
3518
|
)
|
|
2695
3519
|
]
|
|
@@ -2697,23 +3521,24 @@ function DataGridComponent({
|
|
|
2697
3521
|
)
|
|
2698
3522
|
}
|
|
2699
3523
|
),
|
|
2700
|
-
|
|
3524
|
+
aggregates.length > 0 && /* @__PURE__ */ jsxs13(
|
|
2701
3525
|
"table",
|
|
2702
3526
|
{
|
|
2703
|
-
style: { width: totalColumnWidth(
|
|
3527
|
+
style: { width: totalColumnWidth(view.columns) },
|
|
2704
3528
|
className: classNames(
|
|
2705
3529
|
gridTableClassName,
|
|
2706
3530
|
"gridkit-data-grid-footer"
|
|
2707
3531
|
),
|
|
2708
3532
|
children: [
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
3533
|
+
/* @__PURE__ */ jsx20(GridColgroup, { columns: view.columns }),
|
|
3534
|
+
/* @__PURE__ */ jsx20(
|
|
2711
3535
|
GridFooter,
|
|
2712
3536
|
{
|
|
2713
|
-
columns:
|
|
2714
|
-
aggregates
|
|
2715
|
-
results: grandTotal,
|
|
2716
|
-
rows:
|
|
3537
|
+
columns: view.columns,
|
|
3538
|
+
aggregates,
|
|
3539
|
+
results: view.grandTotal,
|
|
3540
|
+
rows: view.rows.map((entry) => entry.row),
|
|
3541
|
+
locale
|
|
2717
3542
|
}
|
|
2718
3543
|
)
|
|
2719
3544
|
]
|
|
@@ -2722,27 +3547,22 @@ function DataGridComponent({
|
|
|
2722
3547
|
]
|
|
2723
3548
|
}
|
|
2724
3549
|
),
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
pageCount: paginationApi.pageCount,
|
|
2729
|
-
pageSizeOptions: pager.sizeOptions,
|
|
2730
|
-
goToPage: paginationApi.goToPage,
|
|
2731
|
-
nextPage: paginationApi.nextPage,
|
|
2732
|
-
previousPage: paginationApi.previousPage,
|
|
2733
|
-
setPageSize: paginationApi.setPageSize
|
|
2734
|
-
}) : /* @__PURE__ */ jsx10(GridPager, { pager: paginationApi, config: pager })),
|
|
2735
|
-
/* @__PURE__ */ jsx10("div", { className: "gridkit-sr-only", role: "status", "aria-live": "polite", children: announcement })
|
|
3550
|
+
/* @__PURE__ */ jsx20(GridContextMenu, { contextMenu }),
|
|
3551
|
+
/* @__PURE__ */ jsx20(GridPanels, { panels, controller, messages }),
|
|
3552
|
+
paginated && (pager?.template ? pager.template(pagerContext) : /* @__PURE__ */ jsx20(GridPager, { pager: pagerContext, config: pager, messages }))
|
|
2736
3553
|
] });
|
|
2737
3554
|
}
|
|
2738
3555
|
|
|
3556
|
+
// src/index.ts
|
|
3557
|
+
import { serializeGridState } from "@gridkitjs/core";
|
|
3558
|
+
|
|
2739
3559
|
// src/DataGrid/hooks/usePaginationState.ts
|
|
2740
|
-
import { useCallback as
|
|
3560
|
+
import { useCallback as useCallback3 } from "react";
|
|
2741
3561
|
|
|
2742
3562
|
// src/DataGrid/hooks/useGridSnapshot.ts
|
|
2743
|
-
import { useCallback as
|
|
3563
|
+
import { useCallback as useCallback2, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
2744
3564
|
function useGridSnapshot(gridRef, getSnapshot, fallback) {
|
|
2745
|
-
const subscribe =
|
|
3565
|
+
const subscribe = useCallback2(
|
|
2746
3566
|
(listener) => {
|
|
2747
3567
|
const api = gridRef.current;
|
|
2748
3568
|
if (api === null) {
|
|
@@ -2753,7 +3573,7 @@ function useGridSnapshot(gridRef, getSnapshot, fallback) {
|
|
|
2753
3573
|
},
|
|
2754
3574
|
[gridRef]
|
|
2755
3575
|
);
|
|
2756
|
-
return
|
|
3576
|
+
return useSyncExternalStore3(subscribe, () => {
|
|
2757
3577
|
const api = gridRef.current;
|
|
2758
3578
|
return api === null ? fallback : getSnapshot(api);
|
|
2759
3579
|
});
|
|
@@ -2764,12 +3584,12 @@ var FALLBACK_PAGINATION = { pageIndex: 0, pageSize: 0 };
|
|
|
2764
3584
|
function usePaginationState(gridRef) {
|
|
2765
3585
|
const pagination = useGridSnapshot(
|
|
2766
3586
|
gridRef,
|
|
2767
|
-
|
|
3587
|
+
useCallback3((api) => api.getPagination(), []),
|
|
2768
3588
|
FALLBACK_PAGINATION
|
|
2769
3589
|
);
|
|
2770
3590
|
const pageCount = useGridSnapshot(
|
|
2771
3591
|
gridRef,
|
|
2772
|
-
|
|
3592
|
+
useCallback3((api) => api.getPageCount(), []),
|
|
2773
3593
|
0
|
|
2774
3594
|
);
|
|
2775
3595
|
return {
|
|
@@ -2791,18 +3611,18 @@ function usePaginationState(gridRef) {
|
|
|
2791
3611
|
}
|
|
2792
3612
|
|
|
2793
3613
|
// src/DataGrid/hooks/useGroupByState.ts
|
|
2794
|
-
import { useCallback as
|
|
3614
|
+
import { useCallback as useCallback4 } from "react";
|
|
2795
3615
|
var FALLBACK_GROUP_BY = [];
|
|
2796
3616
|
var FALLBACK_EXPANSION = [];
|
|
2797
3617
|
function useGroupByState(gridRef) {
|
|
2798
3618
|
const groupBy = useGridSnapshot(
|
|
2799
3619
|
gridRef,
|
|
2800
|
-
|
|
3620
|
+
useCallback4((api) => api.getGroupBy(), []),
|
|
2801
3621
|
FALLBACK_GROUP_BY
|
|
2802
3622
|
);
|
|
2803
3623
|
const groupExpansion = useGridSnapshot(
|
|
2804
3624
|
gridRef,
|
|
2805
|
-
|
|
3625
|
+
useCallback4((api) => api.getGroupExpansion(), []),
|
|
2806
3626
|
FALLBACK_EXPANSION
|
|
2807
3627
|
);
|
|
2808
3628
|
return {
|
|
@@ -2818,34 +3638,34 @@ function useGroupByState(gridRef) {
|
|
|
2818
3638
|
}
|
|
2819
3639
|
|
|
2820
3640
|
// src/DataGrid/hooks/useColumnSortState.ts
|
|
2821
|
-
import { useCallback as
|
|
3641
|
+
import { useCallback as useCallback5 } from "react";
|
|
2822
3642
|
var FALLBACK_SORT = [];
|
|
2823
3643
|
function useColumnSortState(gridRef) {
|
|
2824
3644
|
return useGridSnapshot(
|
|
2825
3645
|
gridRef,
|
|
2826
|
-
|
|
3646
|
+
useCallback5((api) => api.getColumnSort(), []),
|
|
2827
3647
|
FALLBACK_SORT
|
|
2828
3648
|
);
|
|
2829
3649
|
}
|
|
2830
3650
|
|
|
2831
3651
|
// src/DataGrid/hooks/useSelectionState.ts
|
|
2832
|
-
import { useCallback as
|
|
3652
|
+
import { useCallback as useCallback6 } from "react";
|
|
2833
3653
|
var FALLBACK_SELECTION = [];
|
|
2834
3654
|
var FALLBACK_CELL_SELECTION = null;
|
|
2835
3655
|
function useSelectionState(gridRef) {
|
|
2836
3656
|
const rowSelection = useGridSnapshot(
|
|
2837
3657
|
gridRef,
|
|
2838
|
-
|
|
3658
|
+
useCallback6((api) => api.getRowSelection(), []),
|
|
2839
3659
|
FALLBACK_SELECTION
|
|
2840
3660
|
);
|
|
2841
3661
|
const columnSelection = useGridSnapshot(
|
|
2842
3662
|
gridRef,
|
|
2843
|
-
|
|
3663
|
+
useCallback6((api) => api.getColumnSelection(), []),
|
|
2844
3664
|
FALLBACK_SELECTION
|
|
2845
3665
|
);
|
|
2846
3666
|
const cellSelection = useGridSnapshot(
|
|
2847
3667
|
gridRef,
|
|
2848
|
-
|
|
3668
|
+
useCallback6((api) => api.getCellSelection(), []),
|
|
2849
3669
|
FALLBACK_CELL_SELECTION
|
|
2850
3670
|
);
|
|
2851
3671
|
return {
|
|
@@ -2862,43 +3682,74 @@ function useSelectionState(gridRef) {
|
|
|
2862
3682
|
}
|
|
2863
3683
|
|
|
2864
3684
|
// src/DataGrid/hooks/useAggregateState.ts
|
|
2865
|
-
import { useCallback as
|
|
3685
|
+
import { useCallback as useCallback7 } from "react";
|
|
2866
3686
|
var FALLBACK_AGGREGATES = /* @__PURE__ */ new Map();
|
|
2867
3687
|
function useAggregateState(gridRef) {
|
|
2868
3688
|
return useGridSnapshot(
|
|
2869
3689
|
gridRef,
|
|
2870
|
-
|
|
3690
|
+
useCallback7((api) => api.getAggregates(), []),
|
|
2871
3691
|
FALLBACK_AGGREGATES
|
|
2872
3692
|
);
|
|
2873
3693
|
}
|
|
2874
3694
|
|
|
2875
3695
|
// src/DataGrid/hooks/useColumnSizingState.ts
|
|
2876
|
-
import { useCallback as
|
|
3696
|
+
import { useCallback as useCallback8 } from "react";
|
|
2877
3697
|
var FALLBACK_SIZING = {};
|
|
2878
3698
|
function useColumnSizingState(gridRef) {
|
|
2879
3699
|
return useGridSnapshot(
|
|
2880
3700
|
gridRef,
|
|
2881
|
-
|
|
3701
|
+
useCallback8((api) => api.getColumnSizing(), []),
|
|
2882
3702
|
FALLBACK_SIZING
|
|
2883
3703
|
);
|
|
2884
3704
|
}
|
|
2885
3705
|
|
|
2886
3706
|
// src/DataGrid/hooks/useColumnOrderState.ts
|
|
2887
|
-
import { useCallback as
|
|
3707
|
+
import { useCallback as useCallback9 } from "react";
|
|
2888
3708
|
var FALLBACK_ORDER = [];
|
|
2889
3709
|
function useColumnOrderState(gridRef) {
|
|
2890
3710
|
return useGridSnapshot(
|
|
2891
3711
|
gridRef,
|
|
2892
|
-
|
|
3712
|
+
useCallback9((api) => api.getColumnOrder(), []),
|
|
2893
3713
|
FALLBACK_ORDER
|
|
2894
3714
|
);
|
|
2895
3715
|
}
|
|
3716
|
+
|
|
3717
|
+
// src/DataGrid/hooks/useColumnVisibilityState.ts
|
|
3718
|
+
import { useCallback as useCallback10 } from "react";
|
|
3719
|
+
var FALLBACK_VISIBILITY = {};
|
|
3720
|
+
function useColumnVisibilityState(gridRef) {
|
|
3721
|
+
return useGridSnapshot(
|
|
3722
|
+
gridRef,
|
|
3723
|
+
useCallback10((api) => api.getColumnVisibility(), []),
|
|
3724
|
+
FALLBACK_VISIBILITY
|
|
3725
|
+
);
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
// src/DataGrid/hooks/useFilterState.ts
|
|
3729
|
+
import { useCallback as useCallback11, useState as useState16 } from "react";
|
|
3730
|
+
function useFilterState(gridRef) {
|
|
3731
|
+
const [fallback] = useState16(() => []);
|
|
3732
|
+
const filter = useGridSnapshot(
|
|
3733
|
+
gridRef,
|
|
3734
|
+
useCallback11((api) => api.getFilter(), []),
|
|
3735
|
+
fallback
|
|
3736
|
+
);
|
|
3737
|
+
return {
|
|
3738
|
+
filter,
|
|
3739
|
+
setFilter: (next) => {
|
|
3740
|
+
gridRef.current?.setFilter(next);
|
|
3741
|
+
}
|
|
3742
|
+
};
|
|
3743
|
+
}
|
|
2896
3744
|
export {
|
|
2897
|
-
|
|
3745
|
+
DataGrid,
|
|
3746
|
+
serializeGridState,
|
|
2898
3747
|
useAggregateState,
|
|
2899
3748
|
useColumnOrderState,
|
|
2900
3749
|
useColumnSizingState,
|
|
2901
3750
|
useColumnSortState,
|
|
3751
|
+
useColumnVisibilityState,
|
|
3752
|
+
useFilterState,
|
|
2902
3753
|
useGroupByState,
|
|
2903
3754
|
usePaginationState,
|
|
2904
3755
|
useSelectionState
|