@nexgrid/react 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -65
- package/dist/index.cjs +1045 -318
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -37
- package/dist/index.d.ts +112 -37
- package/dist/index.js +1070 -330
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- package/styles.css +1724 -445
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
// src/
|
|
3
|
+
// src/table-x.tsx
|
|
4
4
|
import * as React4 from "react";
|
|
5
5
|
import {
|
|
6
6
|
DENSITIES,
|
|
@@ -16,8 +16,11 @@ import {
|
|
|
16
16
|
getPageNumbers,
|
|
17
17
|
getRecordRange,
|
|
18
18
|
initialHiddenColumns,
|
|
19
|
+
isEditable,
|
|
20
|
+
isFilterable,
|
|
19
21
|
isHideable,
|
|
20
22
|
isPageSize,
|
|
23
|
+
isPinned,
|
|
21
24
|
isSortable,
|
|
22
25
|
primarySort,
|
|
23
26
|
resolveLocale,
|
|
@@ -26,10 +29,22 @@ import {
|
|
|
26
29
|
toExportColumns,
|
|
27
30
|
totalPagesFor,
|
|
28
31
|
visibleColumns,
|
|
32
|
+
withFilter,
|
|
29
33
|
withPage,
|
|
30
34
|
withPageSize,
|
|
31
35
|
withSearch,
|
|
32
|
-
withToggledSort
|
|
36
|
+
withToggledSort,
|
|
37
|
+
withToggledMultiSort,
|
|
38
|
+
copyToClipboard,
|
|
39
|
+
clearGridState,
|
|
40
|
+
loadGridState,
|
|
41
|
+
saveGridState,
|
|
42
|
+
getCellValue as getCellValue2,
|
|
43
|
+
getCellText as getCellText2,
|
|
44
|
+
queryClientData,
|
|
45
|
+
defaultQuery,
|
|
46
|
+
flattenColumns,
|
|
47
|
+
buildHeaderRows
|
|
33
48
|
} from "@nexgrid/core";
|
|
34
49
|
|
|
35
50
|
// src/icons.tsx
|
|
@@ -70,29 +85,22 @@ function XIcon(props) {
|
|
|
70
85
|
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
71
86
|
] });
|
|
72
87
|
}
|
|
73
|
-
function
|
|
88
|
+
function ColumnsIcon(props) {
|
|
74
89
|
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
75
|
-
/* @__PURE__ */ jsx("
|
|
76
|
-
/* @__PURE__ */ jsx("
|
|
77
|
-
/* @__PURE__ */ jsx("
|
|
78
|
-
/* @__PURE__ */ jsx("line", { x1: "8", x2: "3", y1: "12", y2: "12" }),
|
|
79
|
-
/* @__PURE__ */ jsx("line", { x1: "21", x2: "16", y1: "20", y2: "20" }),
|
|
80
|
-
/* @__PURE__ */ jsx("line", { x1: "12", x2: "3", y1: "20", y2: "20" }),
|
|
81
|
-
/* @__PURE__ */ jsx("line", { x1: "14", x2: "14", y1: "2", y2: "6" }),
|
|
82
|
-
/* @__PURE__ */ jsx("line", { x1: "8", x2: "8", y1: "10", y2: "14" }),
|
|
83
|
-
/* @__PURE__ */ jsx("line", { x1: "16", x2: "16", y1: "18", y2: "22" })
|
|
90
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
91
|
+
/* @__PURE__ */ jsx("path", { d: "M9 3v18" }),
|
|
92
|
+
/* @__PURE__ */ jsx("path", { d: "M15 3v18" })
|
|
84
93
|
] });
|
|
85
94
|
}
|
|
86
|
-
function
|
|
87
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("polygon", { points: "22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" }) });
|
|
88
|
-
}
|
|
89
|
-
function DownloadIcon(props) {
|
|
95
|
+
function DensityIcon(props) {
|
|
90
96
|
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
91
|
-
/* @__PURE__ */ jsx("
|
|
92
|
-
/* @__PURE__ */ jsx("
|
|
93
|
-
/* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
|
|
97
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "4.5", width: "18", height: "6", rx: "1.5" }),
|
|
98
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "13.5", width: "18", height: "6", rx: "1.5" })
|
|
94
99
|
] });
|
|
95
100
|
}
|
|
101
|
+
function ChevronDownIcon(props) {
|
|
102
|
+
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
|
|
103
|
+
}
|
|
96
104
|
function FileSpreadsheetIcon(props) {
|
|
97
105
|
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
98
106
|
/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
@@ -141,6 +149,26 @@ function ArrowUpDownIcon(props) {
|
|
|
141
149
|
function CheckIcon(props) {
|
|
142
150
|
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
|
|
143
151
|
}
|
|
152
|
+
function RotateCcwIcon(props) {
|
|
153
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
154
|
+
/* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
155
|
+
/* @__PURE__ */ jsx("path", { d: "M3 3v5h5" })
|
|
156
|
+
] });
|
|
157
|
+
}
|
|
158
|
+
function DownloadTrayIcon(props) {
|
|
159
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
160
|
+
/* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
161
|
+
/* @__PURE__ */ jsx("polyline", { points: "7 10 12 15 17 10" }),
|
|
162
|
+
/* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
|
|
163
|
+
] });
|
|
164
|
+
}
|
|
165
|
+
function DotsVerticalIcon(props) {
|
|
166
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
167
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "5", r: "1.5" }),
|
|
168
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
169
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "19", r: "1.5" })
|
|
170
|
+
] });
|
|
171
|
+
}
|
|
144
172
|
|
|
145
173
|
// src/render.tsx
|
|
146
174
|
import * as React from "react";
|
|
@@ -176,9 +204,9 @@ function bodyCellStyle(col) {
|
|
|
176
204
|
}
|
|
177
205
|
function headerInnerClass(col) {
|
|
178
206
|
const align = col.meta?.align;
|
|
179
|
-
if (align === "center") return "
|
|
180
|
-
if (align === "right") return "
|
|
181
|
-
return "
|
|
207
|
+
if (align === "center") return "tbx-th-inner tbx-th-inner--center";
|
|
208
|
+
if (align === "right") return "tbx-th-inner tbx-th-inner--right";
|
|
209
|
+
return "tbx-th-inner";
|
|
182
210
|
}
|
|
183
211
|
function renderTemplate(template, values) {
|
|
184
212
|
const parts = [];
|
|
@@ -250,8 +278,8 @@ function useDropdown() {
|
|
|
250
278
|
return { isOpen, toggle, close, containerRef, triggerRef };
|
|
251
279
|
}
|
|
252
280
|
|
|
253
|
-
// src/
|
|
254
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
281
|
+
// src/table-x.tsx
|
|
282
|
+
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
255
283
|
function defaultRowId(row) {
|
|
256
284
|
const record = row;
|
|
257
285
|
const id = record === null || record === void 0 ? void 0 : record["id"];
|
|
@@ -262,53 +290,189 @@ var DENSITY_LABEL_KEY = {
|
|
|
262
290
|
default: "densityDefault",
|
|
263
291
|
comfortable: "densityComfortable"
|
|
264
292
|
};
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
293
|
+
function TableX(props) {
|
|
294
|
+
const {
|
|
295
|
+
columns,
|
|
296
|
+
data,
|
|
297
|
+
total: totalProp,
|
|
298
|
+
query: queryProp,
|
|
299
|
+
onQueryChange: onQueryChangeProp,
|
|
300
|
+
clientSidePagination,
|
|
301
|
+
paginationMode,
|
|
302
|
+
caption,
|
|
303
|
+
density: initialDensity = "default",
|
|
304
|
+
isLoading = false,
|
|
305
|
+
error = false,
|
|
306
|
+
onRetry,
|
|
307
|
+
enableSelection = false,
|
|
308
|
+
selectionMode = "multi",
|
|
309
|
+
enableColumnFilters = true,
|
|
310
|
+
enableColumnResize = true,
|
|
311
|
+
onSelectionChange,
|
|
312
|
+
enableSearch = true,
|
|
313
|
+
searchPlaceholder,
|
|
314
|
+
enableColumns = true,
|
|
315
|
+
showColumnsButton,
|
|
316
|
+
enableDensity = true,
|
|
317
|
+
showDensityButton,
|
|
318
|
+
enableExport = true,
|
|
319
|
+
showExportButton,
|
|
320
|
+
enableSorting = true,
|
|
321
|
+
enablePagination = true,
|
|
322
|
+
showPagination,
|
|
323
|
+
enableRowsPerPage = true,
|
|
324
|
+
showRowsPerPage,
|
|
325
|
+
enableJumpToPage = true,
|
|
326
|
+
showJumpToPage,
|
|
327
|
+
showToolbar = true,
|
|
328
|
+
showFooter = true,
|
|
329
|
+
renderExpandedRow,
|
|
330
|
+
enableBulkActions = true,
|
|
331
|
+
bulkActions,
|
|
332
|
+
enableSummaryRow,
|
|
333
|
+
enableColumnReorder = false,
|
|
334
|
+
onColumnOrderChange,
|
|
335
|
+
onCellEdit,
|
|
336
|
+
storageKey,
|
|
337
|
+
showFilterPills = true,
|
|
338
|
+
toolbarActions,
|
|
339
|
+
onRowClick,
|
|
340
|
+
getRowId = defaultRowId,
|
|
341
|
+
className,
|
|
342
|
+
showSerialNumber = true,
|
|
343
|
+
exportFileName,
|
|
344
|
+
onExportAll,
|
|
345
|
+
fetchEndpoint,
|
|
346
|
+
badgeRules,
|
|
347
|
+
locale: localeOverrides,
|
|
348
|
+
onNotify,
|
|
349
|
+
theme = "light"
|
|
350
|
+
} = props;
|
|
351
|
+
const isClientSide = clientSidePagination === true || paginationMode === "client" || onQueryChangeProp === void 0 && queryProp === void 0;
|
|
352
|
+
const [internalQuery, setInternalQuery] = React4.useState(() => queryProp ?? defaultQuery());
|
|
353
|
+
const query = queryProp ?? internalQuery;
|
|
354
|
+
const onQueryChange = React4.useCallback(
|
|
355
|
+
(next) => {
|
|
356
|
+
setInternalQuery(next);
|
|
357
|
+
onQueryChangeProp?.(next);
|
|
358
|
+
},
|
|
359
|
+
[onQueryChangeProp]
|
|
360
|
+
);
|
|
361
|
+
const clientPaged = React4.useMemo(() => {
|
|
362
|
+
if (!isClientSide) return null;
|
|
363
|
+
return queryClientData(data, query);
|
|
364
|
+
}, [isClientSide, data, query]);
|
|
365
|
+
const rows = isClientSide ? clientPaged?.items ?? data : data;
|
|
366
|
+
const total = isClientSide ? clientPaged?.total ?? data.length : totalProp ?? data.length;
|
|
294
367
|
const locale = resolveLocale(localeOverrides);
|
|
295
368
|
const boolLabels = { yes: locale.booleanYes, no: locale.booleanNo };
|
|
369
|
+
const isColumnsVisible = enableColumns && showColumnsButton !== false;
|
|
370
|
+
const isDensityVisible = enableDensity && showDensityButton !== false;
|
|
371
|
+
const isExportVisible = enableExport && showExportButton !== false;
|
|
372
|
+
const isPaginationVisible = enablePagination && showPagination !== false;
|
|
373
|
+
const isRowsPerPageVisible = enableRowsPerPage && showRowsPerPage !== false;
|
|
374
|
+
const isJumpToPageVisible = enableJumpToPage && showJumpToPage !== false;
|
|
375
|
+
const [colList, setColList] = React4.useState(columns);
|
|
376
|
+
React4.useEffect(() => {
|
|
377
|
+
setColList(columns);
|
|
378
|
+
}, [columns]);
|
|
296
379
|
const [density, setDensity] = React4.useState(initialDensity);
|
|
297
380
|
const [hiddenCols, setHiddenCols] = React4.useState(
|
|
298
|
-
() => initialHiddenColumns(columns)
|
|
381
|
+
() => initialHiddenColumns(flattenColumns(columns))
|
|
299
382
|
);
|
|
300
383
|
const [selectedIds, setSelectedIds] = React4.useState(
|
|
301
384
|
() => /* @__PURE__ */ new Set()
|
|
302
385
|
);
|
|
386
|
+
const [expandedRows, setExpandedRows] = React4.useState(
|
|
387
|
+
() => /* @__PURE__ */ new Set()
|
|
388
|
+
);
|
|
389
|
+
const [editingCell, setEditingCell] = React4.useState(null);
|
|
390
|
+
const [draggedColId, setDraggedColId] = React4.useState(null);
|
|
303
391
|
const [isExporting, setIsExporting] = React4.useState(false);
|
|
392
|
+
const [openFilterCol, setOpenFilterCol] = React4.useState(null);
|
|
393
|
+
const [colWidths, setColWidths] = React4.useState({});
|
|
394
|
+
React4.useEffect(() => {
|
|
395
|
+
if (!storageKey) return;
|
|
396
|
+
const persisted = loadGridState(storageKey);
|
|
397
|
+
if (persisted) {
|
|
398
|
+
if (persisted.density) setDensity(persisted.density);
|
|
399
|
+
if (persisted.columnWidths) setColWidths(persisted.columnWidths);
|
|
400
|
+
if (persisted.hiddenColumns && Array.isArray(persisted.hiddenColumns)) {
|
|
401
|
+
const hiddenMap = {};
|
|
402
|
+
for (const col of columns) {
|
|
403
|
+
const id = getColumnId2(col);
|
|
404
|
+
if (id) hiddenMap[id] = persisted.hiddenColumns.includes(id);
|
|
405
|
+
}
|
|
406
|
+
setHiddenCols(hiddenMap);
|
|
407
|
+
}
|
|
408
|
+
if (persisted.columnOrder && Array.isArray(persisted.columnOrder)) {
|
|
409
|
+
const colMap = new Map(columns.map((c) => [getColumnId2(c), c]));
|
|
410
|
+
const reordered = [];
|
|
411
|
+
for (const id of persisted.columnOrder) {
|
|
412
|
+
const col = colMap.get(id);
|
|
413
|
+
if (col) {
|
|
414
|
+
reordered.push(col);
|
|
415
|
+
colMap.delete(id);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
for (const remaining of colMap.values()) {
|
|
419
|
+
reordered.push(remaining);
|
|
420
|
+
}
|
|
421
|
+
if (reordered.length === columns.length) {
|
|
422
|
+
setColList(reordered);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}, [storageKey, columns]);
|
|
427
|
+
React4.useEffect(() => {
|
|
428
|
+
if (!storageKey) return;
|
|
429
|
+
const hiddenList = Object.entries(hiddenCols).filter(([_, isHidden]) => isHidden).map(([id]) => id);
|
|
430
|
+
saveGridState(storageKey, {
|
|
431
|
+
density,
|
|
432
|
+
columnWidths: colWidths,
|
|
433
|
+
columnOrder: colList.map(getColumnId2).filter(Boolean),
|
|
434
|
+
hiddenColumns: hiddenList
|
|
435
|
+
});
|
|
436
|
+
}, [storageKey, density, hiddenCols, colList, colWidths]);
|
|
304
437
|
const columnsMenu = useDropdown();
|
|
305
438
|
const densityMenu = useDropdown();
|
|
306
439
|
const exportMenu = useDropdown();
|
|
440
|
+
const handleResetView = React4.useCallback(() => {
|
|
441
|
+
if (storageKey) {
|
|
442
|
+
clearGridState(storageKey);
|
|
443
|
+
}
|
|
444
|
+
setDensity(initialDensity);
|
|
445
|
+
setColWidths({});
|
|
446
|
+
setColList(columns);
|
|
447
|
+
setHiddenCols(initialHiddenColumns(flattenColumns(columns)));
|
|
448
|
+
columnsMenu.close();
|
|
449
|
+
}, [storageKey, initialDensity, columns, columnsMenu]);
|
|
450
|
+
const leafCols = React4.useMemo(() => flattenColumns(colList), [colList]);
|
|
451
|
+
const autoFitColumn = React4.useCallback((id) => {
|
|
452
|
+
const col = leafCols.find((c) => getColumnId2(c) === id);
|
|
453
|
+
if (!col) return;
|
|
454
|
+
const meta = col.meta ?? {};
|
|
455
|
+
let maxContentWidth = 0;
|
|
456
|
+
const headerTitle = getColumnTitle(col) || id;
|
|
457
|
+
maxContentWidth = Math.max(maxContentWidth, headerTitle.length * 8.5 + 50);
|
|
458
|
+
for (const row of rows) {
|
|
459
|
+
const rawVal = getCellValue2(col, row);
|
|
460
|
+
const val = getCellText2(rawVal);
|
|
461
|
+
if (val) {
|
|
462
|
+
maxContentWidth = Math.max(maxContentWidth, String(val).length * 8 + 26);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const minW = meta.minWidth ?? 60;
|
|
466
|
+
const maxW = 550;
|
|
467
|
+
const finalWidth = Math.min(maxW, Math.max(minW, Math.round(maxContentWidth)));
|
|
468
|
+
setColWidths((prev) => ({ ...prev, [id]: finalWidth }));
|
|
469
|
+
}, [leafCols, rows]);
|
|
307
470
|
const instanceId = React4.useId();
|
|
308
471
|
const columnsButtonId = `${instanceId}-columns`;
|
|
309
472
|
const densityButtonId = `${instanceId}-density`;
|
|
310
473
|
const exportButtonId = `${instanceId}-export`;
|
|
311
474
|
const jumpInputId = `${instanceId}-jump`;
|
|
475
|
+
const rootRef = React4.useRef(null);
|
|
312
476
|
const notify = (type, message) => {
|
|
313
477
|
onNotify?.({ type, message });
|
|
314
478
|
};
|
|
@@ -317,127 +481,193 @@ function NexGrid({
|
|
|
317
481
|
const totalPages = totalPagesFor(total, pageSize);
|
|
318
482
|
const range = getRecordRange(currentPage, pageSize, total);
|
|
319
483
|
const sort = primarySort(query);
|
|
484
|
+
const headerRows = React4.useMemo(
|
|
485
|
+
() => buildHeaderRows(colList, hiddenCols),
|
|
486
|
+
[colList, hiddenCols]
|
|
487
|
+
);
|
|
320
488
|
const visible = React4.useMemo(
|
|
321
|
-
() => visibleColumns(
|
|
322
|
-
[
|
|
489
|
+
() => visibleColumns(leafCols, hiddenCols),
|
|
490
|
+
[leafCols, hiddenCols]
|
|
323
491
|
);
|
|
324
|
-
const hideable = React4.useMemo(() =>
|
|
492
|
+
const hideable = React4.useMemo(() => leafCols.filter(isHideable), [leafCols]);
|
|
325
493
|
const pageItems = React4.useMemo(
|
|
326
494
|
() => getPageNumbers(currentPage, totalPages),
|
|
327
495
|
[currentPage, totalPages]
|
|
328
496
|
);
|
|
329
|
-
const pageRowIds = React4.useMemo(() =>
|
|
330
|
-
const columnCount = visible.length + (showSerialNumber ? 1 : 0) + (enableSelection ? 1 : 0);
|
|
497
|
+
const pageRowIds = React4.useMemo(() => rows.map((row) => getRowId(row)), [rows, getRowId]);
|
|
498
|
+
const columnCount = visible.length + (renderExpandedRow ? 1 : 0) + (showSerialNumber ? 1 : 0) + (enableSelection ? 1 : 0);
|
|
499
|
+
const getPinnedOffsets = (visibleCols) => {
|
|
500
|
+
const leftOffsets2 = /* @__PURE__ */ new Map();
|
|
501
|
+
const rightOffsets2 = /* @__PURE__ */ new Map();
|
|
502
|
+
let currentLeft = 0;
|
|
503
|
+
let lastLeftPinnedId2 = null;
|
|
504
|
+
if (renderExpandedRow) {
|
|
505
|
+
leftOffsets2.set("__expand", currentLeft);
|
|
506
|
+
currentLeft += 40;
|
|
507
|
+
lastLeftPinnedId2 = "__expand";
|
|
508
|
+
}
|
|
509
|
+
if (enableSelection) {
|
|
510
|
+
leftOffsets2.set("__select", currentLeft);
|
|
511
|
+
currentLeft += 44;
|
|
512
|
+
lastLeftPinnedId2 = "__select";
|
|
513
|
+
}
|
|
514
|
+
if (showSerialNumber) {
|
|
515
|
+
leftOffsets2.set("__serial", currentLeft);
|
|
516
|
+
currentLeft += 56;
|
|
517
|
+
lastLeftPinnedId2 = "__serial";
|
|
518
|
+
}
|
|
519
|
+
for (const col of visibleCols) {
|
|
520
|
+
const id = getColumnId2(col);
|
|
521
|
+
const pin = col.meta?.pinned;
|
|
522
|
+
const width = colWidths[id] ?? col.meta?.width ?? 140;
|
|
523
|
+
if (pin === "left") {
|
|
524
|
+
leftOffsets2.set(id, currentLeft);
|
|
525
|
+
currentLeft += width;
|
|
526
|
+
lastLeftPinnedId2 = id;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
let currentRight = 0;
|
|
530
|
+
let firstRightPinnedId2 = null;
|
|
531
|
+
for (let i = visibleCols.length - 1; i >= 0; i--) {
|
|
532
|
+
const col = visibleCols[i];
|
|
533
|
+
if (!col) continue;
|
|
534
|
+
const id = getColumnId2(col);
|
|
535
|
+
const pin = col.meta?.pinned;
|
|
536
|
+
const width = colWidths[id] ?? col.meta?.width ?? 140;
|
|
537
|
+
if (pin === "right") {
|
|
538
|
+
rightOffsets2.set(id, currentRight);
|
|
539
|
+
currentRight += width;
|
|
540
|
+
firstRightPinnedId2 = id;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return { leftOffsets: leftOffsets2, rightOffsets: rightOffsets2, lastLeftPinnedId: lastLeftPinnedId2, firstRightPinnedId: firstRightPinnedId2 };
|
|
544
|
+
};
|
|
545
|
+
const { leftOffsets, rightOffsets, lastLeftPinnedId, firstRightPinnedId } = getPinnedOffsets(visible);
|
|
331
546
|
const [searchText, setSearchText] = useDebouncedSearch(query.q ?? "", (text) => {
|
|
332
547
|
onQueryChange(withSearch(query, text));
|
|
333
548
|
});
|
|
334
549
|
const [jumpText, setJumpText] = React4.useState(() => String(currentPage));
|
|
335
550
|
React4.useEffect(() => setJumpText(String(currentPage)), [currentPage]);
|
|
336
|
-
const submitJump = (
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
setJumpText(String(parsed));
|
|
341
|
-
if (parsed !== currentPage) onQueryChange(withPage(query, parsed, totalPages));
|
|
551
|
+
const submitJump = (raw) => {
|
|
552
|
+
const page = Number.parseInt(raw, 10);
|
|
553
|
+
if (Number.isNaN(page) || page < 1 || page > totalPages) {
|
|
554
|
+
setJumpText(String(currentPage));
|
|
342
555
|
return;
|
|
343
556
|
}
|
|
344
|
-
|
|
557
|
+
if (page !== currentPage) {
|
|
558
|
+
onQueryChange(withPage(query, page, totalPages));
|
|
559
|
+
}
|
|
345
560
|
};
|
|
346
|
-
const toggleSort = (
|
|
347
|
-
|
|
561
|
+
const toggleSort = (field, multiSort = false) => {
|
|
562
|
+
const next = multiSort ? withToggledMultiSort(query, field) : withToggledSort(query, field);
|
|
563
|
+
onQueryChange(next);
|
|
348
564
|
};
|
|
349
|
-
const
|
|
350
|
-
const allPageSelected = pageRowIds.length > 0 &&
|
|
351
|
-
const somePageSelected =
|
|
352
|
-
const
|
|
565
|
+
const isSingleSelect = selectionMode === "single";
|
|
566
|
+
const allPageSelected = pageRowIds.length > 0 && pageRowIds.every((id) => selectedIds.has(id));
|
|
567
|
+
const somePageSelected = !allPageSelected && pageRowIds.some((id) => selectedIds.has(id));
|
|
568
|
+
const toggleSelectAll = () => {
|
|
569
|
+
if (isSingleSelect) return;
|
|
570
|
+
const next = new Set(selectedIds);
|
|
571
|
+
if (allPageSelected) {
|
|
572
|
+
for (const id of pageRowIds) next.delete(id);
|
|
573
|
+
} else {
|
|
574
|
+
for (const id of pageRowIds) next.add(id);
|
|
575
|
+
}
|
|
353
576
|
setSelectedIds(next);
|
|
354
577
|
onSelectionChange?.(Array.from(next), false);
|
|
355
578
|
};
|
|
356
|
-
const
|
|
357
|
-
const next = new Set(selectedIds);
|
|
358
|
-
|
|
359
|
-
if (
|
|
579
|
+
const toggleSelectRow = (id) => {
|
|
580
|
+
const next = isSingleSelect ? selectedIds.has(id) ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([id]) : new Set(selectedIds);
|
|
581
|
+
if (!isSingleSelect) {
|
|
582
|
+
if (next.has(id)) next.delete(id);
|
|
360
583
|
else next.add(id);
|
|
361
584
|
}
|
|
362
|
-
|
|
585
|
+
setSelectedIds(next);
|
|
586
|
+
onSelectionChange?.(Array.from(next), false);
|
|
363
587
|
};
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
588
|
+
const deselectAll = () => {
|
|
589
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
590
|
+
onSelectionChange?.([], false);
|
|
591
|
+
};
|
|
592
|
+
const toggleExpandRow = (id) => {
|
|
593
|
+
setExpandedRows((prev) => {
|
|
594
|
+
const next = new Set(prev);
|
|
595
|
+
if (next.has(id)) next.delete(id);
|
|
596
|
+
else next.add(id);
|
|
597
|
+
return next;
|
|
598
|
+
});
|
|
369
599
|
};
|
|
370
600
|
const toggleColumn = (columnId) => {
|
|
371
601
|
setHiddenCols((prev) => ({ ...prev, [columnId]: prev[columnId] !== true }));
|
|
372
602
|
};
|
|
373
|
-
const collectExportRows = async () => {
|
|
374
|
-
if (data.length >= total || !fetchEndpoint) return data;
|
|
375
|
-
notify("info", formatMessage(locale.exportFetchingAll, { total: total.toLocaleString() }));
|
|
376
|
-
try {
|
|
377
|
-
const result = await fetchAllPages(async (page, size) => {
|
|
378
|
-
const url = buildQueryUrl(fetchEndpoint, {
|
|
379
|
-
...query,
|
|
380
|
-
page,
|
|
381
|
-
pageSize: isPageSize(size) ? size : query.pageSize
|
|
382
|
-
});
|
|
383
|
-
const response = await fetch(url, { cache: "no-store" });
|
|
384
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
385
|
-
return await response.json();
|
|
386
|
-
});
|
|
387
|
-
return result.items;
|
|
388
|
-
} catch {
|
|
389
|
-
notify("error", locale.exportFetchFailed);
|
|
390
|
-
return data;
|
|
391
|
-
}
|
|
392
|
-
};
|
|
393
603
|
const handleExport = async (format) => {
|
|
394
604
|
exportMenu.close();
|
|
395
605
|
if (onExportAll) {
|
|
396
|
-
|
|
606
|
+
try {
|
|
607
|
+
await onExportAll();
|
|
608
|
+
} catch (err) {
|
|
609
|
+
notify("error", err instanceof Error ? err.message : "Export failed");
|
|
610
|
+
}
|
|
397
611
|
return;
|
|
398
612
|
}
|
|
399
613
|
setIsExporting(true);
|
|
614
|
+
notify("info", "Exporting...");
|
|
400
615
|
try {
|
|
401
|
-
|
|
402
|
-
if (
|
|
403
|
-
|
|
404
|
-
|
|
616
|
+
let exportRows = rows;
|
|
617
|
+
if (fetchEndpoint) {
|
|
618
|
+
const full = await fetchAllPages(async (page, size) => {
|
|
619
|
+
const url = buildQueryUrl(fetchEndpoint, {
|
|
620
|
+
...query,
|
|
621
|
+
page,
|
|
622
|
+
pageSize: isPageSize(size) ? size : query.pageSize
|
|
623
|
+
});
|
|
624
|
+
const response = await fetch(url, { cache: "no-store" });
|
|
625
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
626
|
+
return await response.json();
|
|
627
|
+
});
|
|
628
|
+
exportRows = full.items;
|
|
629
|
+
} else if (isClientSide) {
|
|
630
|
+
const full = queryClientData(data, query, { paginate: false });
|
|
631
|
+
exportRows = full.items;
|
|
405
632
|
}
|
|
406
633
|
const exportColumns = toExportColumns(visible, boolLabels);
|
|
407
634
|
const prefix = exportFileName ?? filePrefixFromCaption(caption);
|
|
408
|
-
if (format === "
|
|
409
|
-
const
|
|
635
|
+
if (format === "clipboard") {
|
|
636
|
+
const ok = await copyToClipboard(exportRows, exportColumns);
|
|
637
|
+
if (ok) notify("success", "Copied to clipboard");
|
|
638
|
+
else notify("error", "Failed to copy to clipboard");
|
|
639
|
+
} else if (format === "excel") {
|
|
640
|
+
downloadExcel({
|
|
410
641
|
filename: prefix,
|
|
411
642
|
caption,
|
|
412
|
-
rows,
|
|
643
|
+
rows: exportRows,
|
|
413
644
|
columns: exportColumns,
|
|
414
645
|
badgeRules,
|
|
415
646
|
serialHeader: locale.serialHeader
|
|
416
647
|
});
|
|
417
|
-
notify(
|
|
418
|
-
"success",
|
|
419
|
-
formatMessage(locale.exportExcelSuccess, { count: count.toLocaleString() })
|
|
420
|
-
);
|
|
648
|
+
notify("success", "Excel downloaded");
|
|
421
649
|
} else {
|
|
422
|
-
|
|
423
|
-
notify(
|
|
424
|
-
"success",
|
|
425
|
-
formatMessage(locale.exportCsvSuccess, { count: count.toLocaleString() })
|
|
426
|
-
);
|
|
650
|
+
downloadCsv(timestampedFilename(prefix), exportRows, exportColumns);
|
|
651
|
+
notify("success", "CSV downloaded");
|
|
427
652
|
}
|
|
653
|
+
} catch {
|
|
654
|
+
notify("error", "Export failed");
|
|
428
655
|
} finally {
|
|
429
656
|
setIsExporting(false);
|
|
430
657
|
}
|
|
431
658
|
};
|
|
432
|
-
const
|
|
433
|
-
"
|
|
434
|
-
theme === "dark" ? "
|
|
659
|
+
const rootClasses = [
|
|
660
|
+
"tbx-root",
|
|
661
|
+
theme === "dark" ? "tbx-dark" : theme === "auto" ? "tbx-auto" : void 0,
|
|
435
662
|
className
|
|
436
|
-
].filter(
|
|
663
|
+
].filter(Boolean);
|
|
437
664
|
if (error) {
|
|
438
|
-
return /* @__PURE__ */ jsx3("div", { className:
|
|
439
|
-
/* @__PURE__ */ jsx3("p", { className: "
|
|
440
|
-
onRetry ? /* @__PURE__ */
|
|
665
|
+
return /* @__PURE__ */ jsx3("div", { className: rootClasses.join(" "), "data-density": density, children: /* @__PURE__ */ jsxs2("div", { className: "tbx-state-card", children: [
|
|
666
|
+
/* @__PURE__ */ jsx3("p", { className: "tbx-state-text", children: locale.errorText }),
|
|
667
|
+
onRetry ? /* @__PURE__ */ jsxs2("button", { type: "button", className: "tbx-btn", onClick: onRetry, children: [
|
|
668
|
+
/* @__PURE__ */ jsx3(RotateCcwIcon, { className: "tbx-icon" }),
|
|
669
|
+
/* @__PURE__ */ jsx3("span", { children: locale.retryButton })
|
|
670
|
+
] }) : null
|
|
441
671
|
] }) });
|
|
442
672
|
}
|
|
443
673
|
const rowIsClickable = typeof onRowClick === "function";
|
|
@@ -449,56 +679,256 @@ function NexGrid({
|
|
|
449
679
|
event.preventDefault();
|
|
450
680
|
onRowClick?.(row);
|
|
451
681
|
};
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
682
|
+
const hasSummary = enableSummaryRow === true || visible.some((col) => col.meta?.aggregation !== void 0);
|
|
683
|
+
const renderLeafTh = (col, rowSpan = 1, isGroupChild = false) => {
|
|
684
|
+
const id = getColumnId2(col);
|
|
685
|
+
const sortable = isSortable(col) && enableSorting !== false;
|
|
686
|
+
const sortIndex = query.sort.findIndex((s) => s.field === id);
|
|
687
|
+
const sortItem = sortIndex >= 0 ? query.sort[sortIndex] : void 0;
|
|
688
|
+
const sorted = sortable && sortItem !== void 0;
|
|
689
|
+
const title = getColumnTitle(col) || id;
|
|
690
|
+
const meta = col.meta;
|
|
691
|
+
const activeFilter = query.filter?.[id];
|
|
692
|
+
const isFilterActive = activeFilter !== void 0 && activeFilter !== "";
|
|
693
|
+
const customWidth = colWidths[id];
|
|
694
|
+
const baseStyle = headerCellStyle(col);
|
|
695
|
+
const thStyle = {
|
|
696
|
+
...baseStyle,
|
|
697
|
+
...customWidth !== void 0 ? { width: `${customWidth}px` } : {},
|
|
698
|
+
...leftOffsets.has(id) ? { left: leftOffsets.get(id) } : {},
|
|
699
|
+
...rightOffsets.has(id) ? { right: rightOffsets.get(id) } : {}
|
|
700
|
+
};
|
|
701
|
+
const startResize = (e) => {
|
|
702
|
+
e.preventDefault();
|
|
703
|
+
e.stopPropagation();
|
|
704
|
+
const startX = e.clientX;
|
|
705
|
+
const targetTh = e.currentTarget.parentElement || null;
|
|
706
|
+
const startWidth = targetTh ? targetTh.getBoundingClientRect().width : customWidth ?? meta?.width ?? 120;
|
|
707
|
+
const onMove = (moveEvent) => {
|
|
708
|
+
const nextW = Math.max(meta?.minWidth ?? 60, Math.round(startWidth + (moveEvent.clientX - startX)));
|
|
709
|
+
setColWidths((prev) => ({ ...prev, [id]: nextW }));
|
|
710
|
+
};
|
|
711
|
+
const onUp = () => {
|
|
712
|
+
document.removeEventListener("pointermove", onMove);
|
|
713
|
+
document.removeEventListener("pointerup", onUp);
|
|
714
|
+
document.body?.classList.remove("tbx-resizing");
|
|
715
|
+
};
|
|
716
|
+
document.body?.classList.add("tbx-resizing");
|
|
717
|
+
document.addEventListener("pointermove", onMove);
|
|
718
|
+
document.addEventListener("pointerup", onUp);
|
|
719
|
+
};
|
|
720
|
+
return /* @__PURE__ */ jsxs2(
|
|
721
|
+
"th",
|
|
722
|
+
{
|
|
723
|
+
scope: "col",
|
|
724
|
+
rowSpan: rowSpan > 1 ? rowSpan : void 0,
|
|
725
|
+
"aria-sort": !sortable ? void 0 : sorted ? sortItem?.dir === "asc" ? "ascending" : "descending" : "none",
|
|
726
|
+
tabIndex: sortable ? 0 : void 0,
|
|
727
|
+
"data-column-id": id,
|
|
728
|
+
"data-tbx-focus": sortable ? `sort:${id}` : void 0,
|
|
729
|
+
draggable: enableColumnReorder && !isGroupChild,
|
|
730
|
+
onDragStart: enableColumnReorder && !isGroupChild ? (e) => {
|
|
731
|
+
setDraggedColId(id);
|
|
732
|
+
e.dataTransfer.effectAllowed = "move";
|
|
733
|
+
e.dataTransfer.setData("text/plain", id);
|
|
734
|
+
} : void 0,
|
|
735
|
+
onDragOver: enableColumnReorder && !isGroupChild ? (e) => {
|
|
736
|
+
e.preventDefault();
|
|
737
|
+
} : void 0,
|
|
738
|
+
onDrop: enableColumnReorder && !isGroupChild ? (e) => {
|
|
739
|
+
e.preventDefault();
|
|
740
|
+
if (!draggedColId || draggedColId === id) return;
|
|
741
|
+
const fromIdx = colList.findIndex((c) => getColumnId2(c) === draggedColId);
|
|
742
|
+
const toIdx = colList.findIndex((c) => getColumnId2(c) === id);
|
|
743
|
+
if (fromIdx >= 0 && toIdx >= 0) {
|
|
744
|
+
const nextCols = [...colList];
|
|
745
|
+
const moved = nextCols[fromIdx];
|
|
746
|
+
if (!moved) return;
|
|
747
|
+
nextCols.splice(fromIdx, 1);
|
|
748
|
+
nextCols.splice(toIdx, 0, moved);
|
|
749
|
+
setColList(nextCols);
|
|
750
|
+
onColumnOrderChange?.(nextCols.map(getColumnId2));
|
|
751
|
+
}
|
|
752
|
+
} : void 0,
|
|
753
|
+
onDragEnd: enableColumnReorder && !isGroupChild ? () => {
|
|
754
|
+
setDraggedColId(null);
|
|
755
|
+
} : void 0,
|
|
756
|
+
className: [
|
|
757
|
+
"tbx-th",
|
|
758
|
+
sortable ? "tbx-th--sortable" : void 0,
|
|
759
|
+
isGroupChild ? "tbx-th--grouped-child" : void 0,
|
|
760
|
+
enableColumnReorder && !isGroupChild ? "tbx-th--draggable" : void 0,
|
|
761
|
+
draggedColId === id ? "tbx-th--dragging" : void 0,
|
|
762
|
+
isPinned(col) === "left" ? "tbx-th--pinned-left" : void 0,
|
|
763
|
+
isPinned(col) === "right" ? "tbx-th--pinned-right" : void 0,
|
|
764
|
+
lastLeftPinnedId === id ? "tbx-pinned-border-left" : void 0,
|
|
765
|
+
firstRightPinnedId === id ? "tbx-pinned-border-right" : void 0
|
|
766
|
+
].filter(Boolean).join(" "),
|
|
767
|
+
style: thStyle,
|
|
768
|
+
onClick: sortable ? (event) => {
|
|
769
|
+
const t = event.target;
|
|
770
|
+
if (t?.closest(".tbx-col-filter-wrap") || t?.closest(".tbx-resize-handle")) return;
|
|
771
|
+
toggleSort(id, event.shiftKey);
|
|
772
|
+
} : void 0,
|
|
773
|
+
onKeyDown: sortable ? (event) => {
|
|
774
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
775
|
+
const t = event.target;
|
|
776
|
+
if (t?.closest(".tbx-col-filter-wrap")) return;
|
|
777
|
+
event.preventDefault();
|
|
778
|
+
toggleSort(id, event.shiftKey);
|
|
779
|
+
} : void 0,
|
|
780
|
+
children: [
|
|
781
|
+
/* @__PURE__ */ jsxs2("div", { className: headerInnerClass(col), children: [
|
|
782
|
+
/* @__PURE__ */ jsx3("span", { children: renderColumnHeader(col) }),
|
|
783
|
+
sortable ? /* @__PURE__ */ jsxs2("span", { className: "tbx-sort-icon-wrap", children: [
|
|
784
|
+
sorted ? sortItem?.dir === "asc" ? /* @__PURE__ */ jsx3(ArrowUpIcon, { className: "tbx-sort-icon" }) : /* @__PURE__ */ jsx3(ArrowDownIcon, { className: "tbx-sort-icon" }) : /* @__PURE__ */ jsx3(ArrowUpDownIcon, { className: "tbx-sort-icon tbx-sort-icon--idle" }),
|
|
785
|
+
query.sort.length > 1 && sortIndex >= 0 ? /* @__PURE__ */ jsx3("span", { className: "tbx-sort-order", children: sortIndex + 1 }) : null
|
|
786
|
+
] }) : null,
|
|
787
|
+
isFilterable(col, enableColumnFilters) ? /* @__PURE__ */ jsxs2("div", { className: "tbx-col-filter-wrap", children: [
|
|
788
|
+
/* @__PURE__ */ jsx3(
|
|
789
|
+
"button",
|
|
790
|
+
{
|
|
791
|
+
type: "button",
|
|
792
|
+
className: isFilterActive ? "tbx-col-filter-btn tbx-col-filter-btn--active" : "tbx-col-filter-btn",
|
|
793
|
+
"aria-label": `Filter ${title}`,
|
|
794
|
+
onClick: (e) => {
|
|
795
|
+
e.stopPropagation();
|
|
796
|
+
setOpenFilterCol(openFilterCol === id ? null : id);
|
|
797
|
+
},
|
|
798
|
+
children: /* @__PURE__ */ jsx3(DotsVerticalIcon, { className: "tbx-icon" })
|
|
799
|
+
}
|
|
800
|
+
),
|
|
801
|
+
openFilterCol === id ? /* @__PURE__ */ jsxs2(
|
|
802
|
+
"div",
|
|
803
|
+
{
|
|
804
|
+
className: "tbx-filter-popover",
|
|
805
|
+
onClick: (e) => e.stopPropagation(),
|
|
806
|
+
children: [
|
|
807
|
+
/* @__PURE__ */ jsx3(
|
|
808
|
+
"input",
|
|
809
|
+
{
|
|
810
|
+
autoFocus: true,
|
|
811
|
+
type: "text",
|
|
812
|
+
className: "tbx-filter-popover-input",
|
|
813
|
+
defaultValue: activeFilter ?? "",
|
|
814
|
+
placeholder: `Filter by ${title}...`,
|
|
815
|
+
onKeyDown: (e) => {
|
|
816
|
+
if (e.key === "Enter") {
|
|
817
|
+
e.preventDefault();
|
|
818
|
+
const val = e.currentTarget.value.trim();
|
|
819
|
+
setOpenFilterCol(null);
|
|
820
|
+
onQueryChange(withFilter(query, id, val || void 0));
|
|
821
|
+
} else if (e.key === "Escape") {
|
|
822
|
+
setOpenFilterCol(null);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
),
|
|
827
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-filter-popover-actions", children: [
|
|
828
|
+
/* @__PURE__ */ jsxs2(
|
|
829
|
+
"button",
|
|
830
|
+
{
|
|
831
|
+
type: "button",
|
|
832
|
+
className: "tbx-filter-popover-btn",
|
|
833
|
+
onClick: (e) => {
|
|
834
|
+
e.stopPropagation();
|
|
835
|
+
setOpenFilterCol(null);
|
|
836
|
+
onQueryChange(withFilter(query, id, void 0));
|
|
837
|
+
},
|
|
838
|
+
children: [
|
|
839
|
+
/* @__PURE__ */ jsx3(RotateCcwIcon, { className: "tbx-icon" }),
|
|
840
|
+
/* @__PURE__ */ jsx3("span", { children: locale.clearFilter })
|
|
841
|
+
]
|
|
842
|
+
}
|
|
843
|
+
),
|
|
844
|
+
/* @__PURE__ */ jsxs2(
|
|
845
|
+
"button",
|
|
846
|
+
{
|
|
847
|
+
type: "button",
|
|
848
|
+
className: "tbx-filter-popover-btn tbx-filter-popover-btn--primary",
|
|
849
|
+
onClick: (e) => {
|
|
850
|
+
e.stopPropagation();
|
|
851
|
+
const parent = e.currentTarget.closest(".tbx-filter-popover");
|
|
852
|
+
const inputEl = parent?.querySelector("input");
|
|
853
|
+
const val = inputEl?.value.trim();
|
|
854
|
+
setOpenFilterCol(null);
|
|
855
|
+
onQueryChange(withFilter(query, id, val || void 0));
|
|
856
|
+
},
|
|
857
|
+
children: [
|
|
858
|
+
/* @__PURE__ */ jsx3(CheckIcon, { className: "tbx-icon" }),
|
|
859
|
+
/* @__PURE__ */ jsx3("span", { children: locale.applyFilter })
|
|
860
|
+
]
|
|
861
|
+
}
|
|
862
|
+
)
|
|
863
|
+
] })
|
|
864
|
+
]
|
|
865
|
+
}
|
|
866
|
+
) : null
|
|
867
|
+
] }) : null
|
|
868
|
+
] }),
|
|
869
|
+
enableColumnResize ? /* @__PURE__ */ jsx3(
|
|
870
|
+
"div",
|
|
470
871
|
{
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
"aria-label": locale.clearSearch,
|
|
475
|
-
children: [
|
|
476
|
-
/* @__PURE__ */ jsx3(XIcon, { className: "nxg-icon" }),
|
|
477
|
-
/* @__PURE__ */ jsx3("span", { className: "nxg-sr-only", children: locale.clearSearch })
|
|
478
|
-
]
|
|
872
|
+
className: "tbx-resize-handle",
|
|
873
|
+
onPointerDown: startResize,
|
|
874
|
+
onDoubleClick: () => autoFitColumn(id)
|
|
479
875
|
}
|
|
480
876
|
) : null
|
|
481
|
-
]
|
|
482
|
-
|
|
877
|
+
]
|
|
878
|
+
},
|
|
879
|
+
id
|
|
880
|
+
);
|
|
881
|
+
};
|
|
882
|
+
return /* @__PURE__ */ jsxs2("div", { className: rootClasses.join(" "), "data-density": density, ref: rootRef, children: [
|
|
883
|
+
showToolbar ? /* @__PURE__ */ jsxs2("div", { className: "tbx-toolbar", children: [
|
|
884
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-toolbar-group", children: enableSearch ? /* @__PURE__ */ jsxs2("div", { className: "tbx-search", children: [
|
|
885
|
+
/* @__PURE__ */ jsx3(SearchIcon, { className: "tbx-search-icon" }),
|
|
886
|
+
/* @__PURE__ */ jsx3(
|
|
887
|
+
"input",
|
|
888
|
+
{
|
|
889
|
+
type: "search",
|
|
890
|
+
className: "tbx-search-input",
|
|
891
|
+
value: searchText,
|
|
892
|
+
onChange: (event) => setSearchText(event.target.value),
|
|
893
|
+
placeholder: searchPlaceholder ?? locale.searchPlaceholder,
|
|
894
|
+
"aria-label": `Search ${caption}`
|
|
895
|
+
}
|
|
896
|
+
),
|
|
897
|
+
searchText ? /* @__PURE__ */ jsxs2(
|
|
898
|
+
"button",
|
|
899
|
+
{
|
|
900
|
+
type: "button",
|
|
901
|
+
className: "tbx-search-clear",
|
|
902
|
+
onClick: () => setSearchText(""),
|
|
903
|
+
"aria-label": locale.clearSearch,
|
|
904
|
+
children: [
|
|
905
|
+
/* @__PURE__ */ jsx3(XIcon, { className: "tbx-icon" }),
|
|
906
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-sr-only", children: locale.clearSearch })
|
|
907
|
+
]
|
|
908
|
+
}
|
|
909
|
+
) : null
|
|
910
|
+
] }) : null }),
|
|
911
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-toolbar-group tbx-toolbar-group--end", children: [
|
|
912
|
+
isColumnsVisible ? /* @__PURE__ */ jsxs2("div", { className: "tbx-menu-wrap", ref: columnsMenu.containerRef, children: [
|
|
483
913
|
/* @__PURE__ */ jsxs2(
|
|
484
914
|
"button",
|
|
485
915
|
{
|
|
486
916
|
type: "button",
|
|
487
917
|
id: columnsButtonId,
|
|
488
|
-
className: "
|
|
918
|
+
className: "tbx-btn",
|
|
489
919
|
ref: columnsMenu.triggerRef,
|
|
490
920
|
"aria-haspopup": "menu",
|
|
491
921
|
"aria-expanded": columnsMenu.isOpen,
|
|
492
922
|
onClick: columnsMenu.toggle,
|
|
493
923
|
children: [
|
|
494
|
-
/* @__PURE__ */ jsx3(
|
|
924
|
+
/* @__PURE__ */ jsx3(ColumnsIcon, { className: "tbx-icon" }),
|
|
495
925
|
/* @__PURE__ */ jsx3("span", { children: locale.columnsButton })
|
|
496
926
|
]
|
|
497
927
|
}
|
|
498
928
|
),
|
|
499
|
-
columnsMenu.isOpen ? /* @__PURE__ */ jsxs2("div", { className: "
|
|
500
|
-
/* @__PURE__ */ jsx3("div", { className: "
|
|
501
|
-
/* @__PURE__ */ jsx3("div", { className: "
|
|
929
|
+
columnsMenu.isOpen ? /* @__PURE__ */ jsxs2("div", { className: "tbx-menu", role: "menu", "aria-labelledby": columnsButtonId, children: [
|
|
930
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-menu-label", children: locale.toggleColumnsLabel }),
|
|
931
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-menu-separator" }),
|
|
502
932
|
hideable.map((col) => {
|
|
503
933
|
const id = getColumnId2(col);
|
|
504
934
|
const checked = hiddenCols[id] !== true;
|
|
@@ -506,42 +936,55 @@ function NexGrid({
|
|
|
506
936
|
"button",
|
|
507
937
|
{
|
|
508
938
|
type: "button",
|
|
509
|
-
className: "
|
|
939
|
+
className: "tbx-menu-item",
|
|
510
940
|
role: "menuitemcheckbox",
|
|
511
941
|
"aria-checked": checked,
|
|
512
942
|
onClick: () => toggleColumn(id),
|
|
513
943
|
children: [
|
|
514
|
-
/* @__PURE__ */ jsx3(CheckIcon, { className: "
|
|
944
|
+
/* @__PURE__ */ jsx3(CheckIcon, { className: "tbx-check" }),
|
|
515
945
|
/* @__PURE__ */ jsx3("span", { children: getColumnTitle(col) || id })
|
|
516
946
|
]
|
|
517
947
|
},
|
|
518
948
|
id
|
|
519
949
|
);
|
|
520
|
-
})
|
|
950
|
+
}),
|
|
951
|
+
storageKey ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
952
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-menu-separator" }),
|
|
953
|
+
/* @__PURE__ */ jsx3(
|
|
954
|
+
"button",
|
|
955
|
+
{
|
|
956
|
+
type: "button",
|
|
957
|
+
className: "tbx-menu-item tbx-menu-item--reset",
|
|
958
|
+
role: "menuitem",
|
|
959
|
+
onClick: handleResetView,
|
|
960
|
+
children: /* @__PURE__ */ jsx3("span", { children: "Reset to default view" })
|
|
961
|
+
}
|
|
962
|
+
)
|
|
963
|
+
] }) : null
|
|
521
964
|
] }) : null
|
|
522
|
-
] }),
|
|
523
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
965
|
+
] }) : null,
|
|
966
|
+
isDensityVisible ? /* @__PURE__ */ jsxs2("div", { className: "tbx-menu-wrap", ref: densityMenu.containerRef, children: [
|
|
524
967
|
/* @__PURE__ */ jsxs2(
|
|
525
968
|
"button",
|
|
526
969
|
{
|
|
527
970
|
type: "button",
|
|
528
971
|
id: densityButtonId,
|
|
529
|
-
className: "
|
|
972
|
+
className: "tbx-btn tbx-capitalize",
|
|
530
973
|
ref: densityMenu.triggerRef,
|
|
531
974
|
"aria-haspopup": "menu",
|
|
532
975
|
"aria-expanded": densityMenu.isOpen,
|
|
533
976
|
onClick: densityMenu.toggle,
|
|
534
977
|
children: [
|
|
535
|
-
/* @__PURE__ */ jsx3(
|
|
978
|
+
/* @__PURE__ */ jsx3(DensityIcon, { className: "tbx-icon" }),
|
|
536
979
|
/* @__PURE__ */ jsx3("span", { children: formatMessage(locale.densityButton, { density }) })
|
|
537
980
|
]
|
|
538
981
|
}
|
|
539
982
|
),
|
|
540
|
-
densityMenu.isOpen ? /* @__PURE__ */ jsx3("div", { className: "
|
|
983
|
+
densityMenu.isOpen ? /* @__PURE__ */ jsx3("div", { className: "tbx-menu", role: "menu", "aria-labelledby": densityButtonId, children: DENSITIES.map((option) => /* @__PURE__ */ jsxs2(
|
|
541
984
|
"button",
|
|
542
985
|
{
|
|
543
986
|
type: "button",
|
|
544
|
-
className: "
|
|
987
|
+
className: "tbx-menu-item",
|
|
545
988
|
role: "menuitemcheckbox",
|
|
546
989
|
"aria-checked": density === option,
|
|
547
990
|
onClick: () => {
|
|
@@ -549,37 +992,36 @@ function NexGrid({
|
|
|
549
992
|
densityMenu.close();
|
|
550
993
|
},
|
|
551
994
|
children: [
|
|
552
|
-
/* @__PURE__ */ jsx3(CheckIcon, { className: "
|
|
995
|
+
/* @__PURE__ */ jsx3(CheckIcon, { className: "tbx-check" }),
|
|
553
996
|
/* @__PURE__ */ jsx3("span", { children: locale[DENSITY_LABEL_KEY[option]] })
|
|
554
997
|
]
|
|
555
998
|
},
|
|
556
999
|
option
|
|
557
1000
|
)) }) : null
|
|
558
|
-
] })
|
|
559
|
-
|
|
560
|
-
/* @__PURE__ */ jsxs2("div", { className: "nxg-toolbar-group nxg-toolbar-group--end", children: [
|
|
561
|
-
enableExport ? /* @__PURE__ */ jsxs2("div", { className: "nxg-menu-wrap", ref: exportMenu.containerRef, children: [
|
|
1001
|
+
] }) : null,
|
|
1002
|
+
isExportVisible ? /* @__PURE__ */ jsxs2("div", { className: "tbx-menu-wrap", ref: exportMenu.containerRef, children: [
|
|
562
1003
|
/* @__PURE__ */ jsxs2(
|
|
563
1004
|
"button",
|
|
564
1005
|
{
|
|
565
1006
|
type: "button",
|
|
566
1007
|
id: exportButtonId,
|
|
567
|
-
className: "
|
|
1008
|
+
className: "tbx-btn tbx-btn--export",
|
|
568
1009
|
ref: exportMenu.triggerRef,
|
|
569
1010
|
disabled: isExporting,
|
|
570
1011
|
"aria-haspopup": "menu",
|
|
571
1012
|
"aria-expanded": exportMenu.isOpen,
|
|
572
1013
|
onClick: exportMenu.toggle,
|
|
573
1014
|
children: [
|
|
574
|
-
/* @__PURE__ */ jsx3(
|
|
575
|
-
/* @__PURE__ */ jsx3("span", { children: isExporting ? locale.exportingButton : locale.exportButton })
|
|
1015
|
+
/* @__PURE__ */ jsx3(DownloadTrayIcon, { className: "tbx-icon" }),
|
|
1016
|
+
/* @__PURE__ */ jsx3("span", { children: isExporting ? locale.exportingButton : locale.exportButton }),
|
|
1017
|
+
/* @__PURE__ */ jsx3(ChevronDownIcon, { className: "tbx-icon tbx-chevron" })
|
|
576
1018
|
]
|
|
577
1019
|
}
|
|
578
1020
|
),
|
|
579
1021
|
exportMenu.isOpen ? /* @__PURE__ */ jsxs2(
|
|
580
1022
|
"div",
|
|
581
1023
|
{
|
|
582
|
-
className: "
|
|
1024
|
+
className: "tbx-menu tbx-menu--end",
|
|
583
1025
|
role: "menu",
|
|
584
1026
|
"aria-labelledby": exportButtonId,
|
|
585
1027
|
children: [
|
|
@@ -587,12 +1029,12 @@ function NexGrid({
|
|
|
587
1029
|
"button",
|
|
588
1030
|
{
|
|
589
1031
|
type: "button",
|
|
590
|
-
className: "
|
|
1032
|
+
className: "tbx-menu-item",
|
|
591
1033
|
role: "menuitem",
|
|
592
1034
|
onClick: () => void handleExport("excel"),
|
|
593
1035
|
children: [
|
|
594
|
-
/* @__PURE__ */ jsx3(FileSpreadsheetIcon, { className: "
|
|
595
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1036
|
+
/* @__PURE__ */ jsx3(FileSpreadsheetIcon, { className: "tbx-icon--excel" }),
|
|
1037
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-menu-item-title", children: [
|
|
596
1038
|
/* @__PURE__ */ jsx3("strong", { children: locale.exportExcelTitle }),
|
|
597
1039
|
/* @__PURE__ */ jsx3("small", { children: locale.exportExcelSubtitle })
|
|
598
1040
|
] })
|
|
@@ -603,17 +1045,33 @@ function NexGrid({
|
|
|
603
1045
|
"button",
|
|
604
1046
|
{
|
|
605
1047
|
type: "button",
|
|
606
|
-
className: "
|
|
1048
|
+
className: "tbx-menu-item",
|
|
607
1049
|
role: "menuitem",
|
|
608
1050
|
onClick: () => void handleExport("csv"),
|
|
609
1051
|
children: [
|
|
610
|
-
/* @__PURE__ */ jsx3(FileTextIcon, { className: "
|
|
611
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1052
|
+
/* @__PURE__ */ jsx3(FileTextIcon, { className: "tbx-icon--csv" }),
|
|
1053
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-menu-item-title", children: [
|
|
612
1054
|
/* @__PURE__ */ jsx3("strong", { children: locale.exportCsvTitle }),
|
|
613
1055
|
/* @__PURE__ */ jsx3("small", { children: locale.exportCsvSubtitle })
|
|
614
1056
|
] })
|
|
615
1057
|
]
|
|
616
1058
|
}
|
|
1059
|
+
),
|
|
1060
|
+
/* @__PURE__ */ jsxs2(
|
|
1061
|
+
"button",
|
|
1062
|
+
{
|
|
1063
|
+
type: "button",
|
|
1064
|
+
className: "tbx-menu-item",
|
|
1065
|
+
role: "menuitem",
|
|
1066
|
+
onClick: () => void handleExport("clipboard"),
|
|
1067
|
+
children: [
|
|
1068
|
+
/* @__PURE__ */ jsx3(FileTextIcon, { className: "tbx-icon--csv" }),
|
|
1069
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-menu-item-title", children: [
|
|
1070
|
+
/* @__PURE__ */ jsx3("strong", { children: locale.exportClipboardTitle }),
|
|
1071
|
+
/* @__PURE__ */ jsx3("small", { children: locale.exportClipboardSubtitle })
|
|
1072
|
+
] })
|
|
1073
|
+
]
|
|
1074
|
+
}
|
|
617
1075
|
)
|
|
618
1076
|
]
|
|
619
1077
|
}
|
|
@@ -621,137 +1079,400 @@ function NexGrid({
|
|
|
621
1079
|
] }) : null,
|
|
622
1080
|
toolbarActions
|
|
623
1081
|
] })
|
|
624
|
-
] }),
|
|
625
|
-
|
|
626
|
-
/* @__PURE__ */ jsx3("
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
"
|
|
1082
|
+
] }) : null,
|
|
1083
|
+
showFilterPills !== false && (Boolean(query.q?.trim()) || Object.keys(query.filter ?? {}).some((k) => query.filter?.[k])) ? /* @__PURE__ */ jsxs2("div", { className: "tbx-filter-pills-bar", children: [
|
|
1084
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-filter-pills-title", children: "Active filters:" }),
|
|
1085
|
+
query.q?.trim() ? /* @__PURE__ */ jsxs2("div", { className: "tbx-filter-pill", children: [
|
|
1086
|
+
/* @__PURE__ */ jsxs2("span", { className: "tbx-filter-pill-label", children: [
|
|
1087
|
+
searchPlaceholder || locale.searchPlaceholder || "Search",
|
|
1088
|
+
":"
|
|
1089
|
+
] }),
|
|
1090
|
+
/* @__PURE__ */ jsxs2("span", { className: "tbx-filter-pill-val", children: [
|
|
1091
|
+
'"',
|
|
1092
|
+
query.q,
|
|
1093
|
+
'"'
|
|
1094
|
+
] }),
|
|
1095
|
+
/* @__PURE__ */ jsx3(
|
|
1096
|
+
"button",
|
|
630
1097
|
{
|
|
631
|
-
type: "
|
|
632
|
-
className: "
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
onChange: toggleSelectAll,
|
|
638
|
-
"aria-label": locale.selectAllLabel
|
|
1098
|
+
type: "button",
|
|
1099
|
+
className: "tbx-filter-pill-remove",
|
|
1100
|
+
title: "Clear search",
|
|
1101
|
+
"aria-label": "Clear search",
|
|
1102
|
+
onClick: () => onQueryChange(withSearch(query, "")),
|
|
1103
|
+
children: "\u2715"
|
|
639
1104
|
}
|
|
640
|
-
)
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
1105
|
+
)
|
|
1106
|
+
] }) : null,
|
|
1107
|
+
Object.entries(query.filter ?? {}).map(([key, val]) => {
|
|
1108
|
+
if (val === void 0 || val === "") return null;
|
|
1109
|
+
const col = leafCols.find((c) => getColumnId2(c) === key);
|
|
1110
|
+
const title = col ? getColumnTitle(col) || key : key;
|
|
1111
|
+
return /* @__PURE__ */ jsxs2("div", { className: "tbx-filter-pill", children: [
|
|
1112
|
+
/* @__PURE__ */ jsxs2("span", { className: "tbx-filter-pill-label", children: [
|
|
1113
|
+
title,
|
|
1114
|
+
":"
|
|
1115
|
+
] }),
|
|
1116
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-filter-pill-val", children: String(val) }),
|
|
1117
|
+
/* @__PURE__ */ jsx3(
|
|
1118
|
+
"button",
|
|
1119
|
+
{
|
|
1120
|
+
type: "button",
|
|
1121
|
+
className: "tbx-filter-pill-remove",
|
|
1122
|
+
title: `Remove ${title} filter`,
|
|
1123
|
+
"aria-label": `Remove filter for ${title}`,
|
|
1124
|
+
onClick: () => onQueryChange(withFilter(query, key, void 0)),
|
|
1125
|
+
children: "\u2715"
|
|
1126
|
+
}
|
|
1127
|
+
)
|
|
1128
|
+
] }, key);
|
|
1129
|
+
}),
|
|
1130
|
+
/* @__PURE__ */ jsx3(
|
|
1131
|
+
"button",
|
|
1132
|
+
{
|
|
1133
|
+
type: "button",
|
|
1134
|
+
className: "tbx-filter-pill-clear-all",
|
|
1135
|
+
onClick: () => onQueryChange({ ...query, page: 1, q: void 0, filter: {} }),
|
|
1136
|
+
children: "Clear all"
|
|
1137
|
+
}
|
|
1138
|
+
)
|
|
1139
|
+
] }) : null,
|
|
1140
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-table-wrap", children: /* @__PURE__ */ jsxs2("table", { className: "tbx-table", "aria-label": caption, children: [
|
|
1141
|
+
/* @__PURE__ */ jsxs2("thead", { children: [
|
|
1142
|
+
/* @__PURE__ */ jsxs2("tr", { children: [
|
|
1143
|
+
renderExpandedRow ? /* @__PURE__ */ jsx3(
|
|
647
1144
|
"th",
|
|
648
1145
|
{
|
|
1146
|
+
rowSpan: headerRows.hasGroups ? 2 : void 0,
|
|
1147
|
+
className: [
|
|
1148
|
+
"tbx-th tbx-th--expand",
|
|
1149
|
+
leftOffsets.has("__expand") ? "tbx-th--pinned-left" : void 0,
|
|
1150
|
+
lastLeftPinnedId === "__expand" ? "tbx-pinned-border-left" : void 0
|
|
1151
|
+
].filter(Boolean).join(" "),
|
|
1152
|
+
style: {
|
|
1153
|
+
width: "40px",
|
|
1154
|
+
left: leftOffsets.get("__expand")
|
|
1155
|
+
},
|
|
1156
|
+
scope: "col"
|
|
1157
|
+
}
|
|
1158
|
+
) : null,
|
|
1159
|
+
enableSelection ? /* @__PURE__ */ jsx3(
|
|
1160
|
+
"th",
|
|
1161
|
+
{
|
|
1162
|
+
rowSpan: headerRows.hasGroups ? 2 : void 0,
|
|
1163
|
+
className: [
|
|
1164
|
+
"tbx-th tbx-th--select",
|
|
1165
|
+
leftOffsets.has("__select") ? "tbx-th--pinned-left" : void 0,
|
|
1166
|
+
lastLeftPinnedId === "__select" ? "tbx-pinned-border-left" : void 0
|
|
1167
|
+
].filter(Boolean).join(" "),
|
|
1168
|
+
style: {
|
|
1169
|
+
left: leftOffsets.get("__select")
|
|
1170
|
+
},
|
|
649
1171
|
scope: "col",
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
"aria-sort": sorted ? sort?.dir === "asc" ? "ascending" : "descending" : sortable ? "none" : void 0,
|
|
653
|
-
"aria-label": title || void 0,
|
|
654
|
-
tabIndex: sortable ? 0 : void 0,
|
|
655
|
-
onClick: sortable ? () => toggleSort(id) : void 0,
|
|
656
|
-
onKeyDown: sortable ? (event) => {
|
|
657
|
-
if (event.key !== "Enter" && event.key !== " ") return;
|
|
658
|
-
event.preventDefault();
|
|
659
|
-
toggleSort(id);
|
|
660
|
-
} : void 0,
|
|
661
|
-
children: /* @__PURE__ */ jsxs2("div", { className: headerInnerClass(col), children: [
|
|
662
|
-
/* @__PURE__ */ jsx3("span", { children: renderColumnHeader(col) }),
|
|
663
|
-
sortable ? /* @__PURE__ */ jsx3("span", { children: sorted ? sort?.dir === "asc" ? /* @__PURE__ */ jsx3(ArrowUpIcon, { className: "nxg-sort-icon" }) : /* @__PURE__ */ jsx3(ArrowDownIcon, { className: "nxg-sort-icon" }) : /* @__PURE__ */ jsx3(ArrowUpDownIcon, { className: "nxg-sort-icon nxg-sort-icon--idle" }) }) : null
|
|
664
|
-
] })
|
|
665
|
-
},
|
|
666
|
-
id || `col-${index}`
|
|
667
|
-
);
|
|
668
|
-
})
|
|
669
|
-
] }) }),
|
|
670
|
-
/* @__PURE__ */ jsx3("tbody", { children: isLoading ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsxs2("td", { className: "nxg-state", colSpan: Math.max(1, columnCount), children: [
|
|
671
|
-
/* @__PURE__ */ jsx3("span", { className: "nxg-spinner", "aria-hidden": "true" }),
|
|
672
|
-
/* @__PURE__ */ jsx3("div", { "aria-live": "polite", children: locale.loadingText })
|
|
673
|
-
] }) }) : data.length === 0 ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsx3("td", { className: "nxg-state", colSpan: Math.max(1, columnCount), children: locale.emptyText }) }) : data.map((row, index) => {
|
|
674
|
-
const id = pageRowIds[index] ?? String(index);
|
|
675
|
-
const isSelected = selectedIds.has(id);
|
|
676
|
-
return /* @__PURE__ */ jsxs2(
|
|
677
|
-
"tr",
|
|
678
|
-
{
|
|
679
|
-
className: [
|
|
680
|
-
"nxg-row",
|
|
681
|
-
isSelected ? "nxg-row--selected" : void 0,
|
|
682
|
-
rowIsClickable ? "nxg-row--clickable" : void 0
|
|
683
|
-
].filter(Boolean).join(" "),
|
|
684
|
-
onClick: rowIsClickable ? activateRow(row) : void 0,
|
|
685
|
-
onKeyDown: rowIsClickable ? rowKeyDown(row) : void 0,
|
|
686
|
-
tabIndex: rowIsClickable ? 0 : void 0,
|
|
687
|
-
children: [
|
|
688
|
-
showSerialNumber ? /* @__PURE__ */ jsx3("td", { className: "nxg-td nxg-td--serial", children: serialNumber(currentPage, pageSize, index) }) : null,
|
|
689
|
-
enableSelection ? /* @__PURE__ */ jsx3(
|
|
690
|
-
"td",
|
|
1172
|
+
children: !isSingleSelect ? /* @__PURE__ */ jsx3(
|
|
1173
|
+
"input",
|
|
691
1174
|
{
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
onChange: () => toggleSelectRow(id),
|
|
701
|
-
onClick: (event) => event.stopPropagation(),
|
|
702
|
-
"aria-label": formatMessage(locale.selectRowLabel, { id })
|
|
703
|
-
}
|
|
704
|
-
)
|
|
1175
|
+
type: "checkbox",
|
|
1176
|
+
className: "tbx-checkbox",
|
|
1177
|
+
checked: allPageSelected,
|
|
1178
|
+
ref: (el) => {
|
|
1179
|
+
if (el) el.indeterminate = somePageSelected;
|
|
1180
|
+
},
|
|
1181
|
+
onChange: toggleSelectAll,
|
|
1182
|
+
"aria-label": locale.selectAllLabel
|
|
705
1183
|
}
|
|
706
|
-
) : null
|
|
707
|
-
|
|
708
|
-
|
|
1184
|
+
) : null
|
|
1185
|
+
}
|
|
1186
|
+
) : null,
|
|
1187
|
+
showSerialNumber ? /* @__PURE__ */ jsx3(
|
|
1188
|
+
"th",
|
|
1189
|
+
{
|
|
1190
|
+
rowSpan: headerRows.hasGroups ? 2 : void 0,
|
|
1191
|
+
className: [
|
|
1192
|
+
"tbx-th tbx-th--serial",
|
|
1193
|
+
leftOffsets.has("__serial") ? "tbx-th--pinned-left" : void 0,
|
|
1194
|
+
lastLeftPinnedId === "__serial" ? "tbx-pinned-border-left" : void 0
|
|
1195
|
+
].filter(Boolean).join(" "),
|
|
1196
|
+
style: {
|
|
1197
|
+
left: leftOffsets.get("__serial")
|
|
1198
|
+
},
|
|
1199
|
+
scope: "col",
|
|
1200
|
+
children: locale.serialHeader
|
|
1201
|
+
}
|
|
1202
|
+
) : null,
|
|
1203
|
+
!headerRows.hasGroups ? visible.map((col) => renderLeafTh(col, 1, false)) : headerRows.topRow.map((cell, idx) => {
|
|
1204
|
+
if (cell.isGroup) {
|
|
1205
|
+
return /* @__PURE__ */ jsx3(
|
|
1206
|
+
"th",
|
|
709
1207
|
{
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
1208
|
+
colSpan: cell.colSpan,
|
|
1209
|
+
className: "tbx-th tbx-th--group",
|
|
1210
|
+
scope: "colgroup",
|
|
1211
|
+
children: /* @__PURE__ */ jsx3("span", { className: "tbx-th-group-title", children: cell.title })
|
|
713
1212
|
},
|
|
714
|
-
|
|
715
|
-
)
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
1213
|
+
`grp-${cell.id}-${idx}`
|
|
1214
|
+
);
|
|
1215
|
+
}
|
|
1216
|
+
if (cell.leafColumn) {
|
|
1217
|
+
return renderLeafTh(cell.leafColumn, cell.rowSpan, false);
|
|
1218
|
+
}
|
|
1219
|
+
return null;
|
|
1220
|
+
})
|
|
1221
|
+
] }),
|
|
1222
|
+
headerRows.hasGroups ? /* @__PURE__ */ jsx3("tr", { children: headerRows.bottomRow.map((cell) => {
|
|
1223
|
+
if (cell.leafColumn) {
|
|
1224
|
+
return renderLeafTh(cell.leafColumn, 1, true);
|
|
1225
|
+
}
|
|
1226
|
+
return null;
|
|
1227
|
+
}) }) : null
|
|
1228
|
+
] }),
|
|
1229
|
+
/* @__PURE__ */ jsx3("tbody", { children: isLoading ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsxs2("td", { className: "tbx-state", colSpan: Math.max(1, columnCount), children: [
|
|
1230
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-dotted-loader", "aria-hidden": "true", children: [
|
|
1231
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" }),
|
|
1232
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" }),
|
|
1233
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" }),
|
|
1234
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" })
|
|
1235
|
+
] }),
|
|
1236
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-loading-text", "aria-live": "polite", children: locale.loadingText })
|
|
1237
|
+
] }) }) : rows.length === 0 ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsx3("td", { className: "tbx-state", colSpan: Math.max(1, columnCount), children: locale.emptyText }) }) : rows.map((row, index) => {
|
|
1238
|
+
const id = pageRowIds[index] ?? String(index);
|
|
1239
|
+
const isSelected = selectedIds.has(id);
|
|
1240
|
+
const isExpanded = expandedRows.has(id);
|
|
1241
|
+
return /* @__PURE__ */ jsxs2(React4.Fragment, { children: [
|
|
1242
|
+
/* @__PURE__ */ jsxs2(
|
|
1243
|
+
"tr",
|
|
1244
|
+
{
|
|
1245
|
+
className: [
|
|
1246
|
+
"tbx-row",
|
|
1247
|
+
isSelected ? "tbx-row--selected" : void 0,
|
|
1248
|
+
isExpanded ? "tbx-row--expanded" : void 0,
|
|
1249
|
+
rowIsClickable ? "tbx-row--clickable" : void 0
|
|
1250
|
+
].filter(Boolean).join(" "),
|
|
1251
|
+
onClick: rowIsClickable ? activateRow(row) : void 0,
|
|
1252
|
+
onKeyDown: rowIsClickable ? rowKeyDown(row) : void 0,
|
|
1253
|
+
tabIndex: rowIsClickable ? 0 : void 0,
|
|
1254
|
+
children: [
|
|
1255
|
+
renderExpandedRow ? /* @__PURE__ */ jsx3(
|
|
1256
|
+
"td",
|
|
1257
|
+
{
|
|
1258
|
+
className: [
|
|
1259
|
+
"tbx-td tbx-td--expand",
|
|
1260
|
+
leftOffsets.has("__expand") ? "tbx-td--pinned-left" : void 0,
|
|
1261
|
+
lastLeftPinnedId === "__expand" ? "tbx-pinned-border-left" : void 0
|
|
1262
|
+
].filter(Boolean).join(" "),
|
|
1263
|
+
style: {
|
|
1264
|
+
width: "40px",
|
|
1265
|
+
left: leftOffsets.get("__expand")
|
|
1266
|
+
},
|
|
1267
|
+
onClick: (e) => e.stopPropagation(),
|
|
1268
|
+
children: /* @__PURE__ */ jsx3(
|
|
1269
|
+
"button",
|
|
1270
|
+
{
|
|
1271
|
+
type: "button",
|
|
1272
|
+
className: isExpanded ? "tbx-expand-btn tbx-expand-btn--open" : "tbx-expand-btn",
|
|
1273
|
+
"aria-label": isExpanded ? "Collapse row" : "Expand row",
|
|
1274
|
+
onClick: (e) => {
|
|
1275
|
+
e.stopPropagation();
|
|
1276
|
+
toggleExpandRow(id);
|
|
1277
|
+
},
|
|
1278
|
+
children: /* @__PURE__ */ jsx3(ChevronRightIcon, { className: "tbx-icon" })
|
|
1279
|
+
}
|
|
1280
|
+
)
|
|
1281
|
+
}
|
|
1282
|
+
) : null,
|
|
1283
|
+
enableSelection ? /* @__PURE__ */ jsx3(
|
|
1284
|
+
"td",
|
|
1285
|
+
{
|
|
1286
|
+
className: [
|
|
1287
|
+
"tbx-td tbx-td--select",
|
|
1288
|
+
leftOffsets.has("__select") ? "tbx-td--pinned-left" : void 0,
|
|
1289
|
+
lastLeftPinnedId === "__select" ? "tbx-pinned-border-left" : void 0
|
|
1290
|
+
].filter(Boolean).join(" "),
|
|
1291
|
+
style: {
|
|
1292
|
+
left: leftOffsets.get("__select")
|
|
1293
|
+
},
|
|
1294
|
+
onClick: (event) => event.stopPropagation(),
|
|
1295
|
+
children: /* @__PURE__ */ jsx3(
|
|
1296
|
+
"input",
|
|
1297
|
+
{
|
|
1298
|
+
type: isSingleSelect ? "radio" : "checkbox",
|
|
1299
|
+
name: isSingleSelect ? `${instanceId}-select` : void 0,
|
|
1300
|
+
className: "tbx-checkbox",
|
|
1301
|
+
checked: isSelected,
|
|
1302
|
+
onChange: () => toggleSelectRow(id),
|
|
1303
|
+
onClick: (event) => event.stopPropagation(),
|
|
1304
|
+
"aria-label": formatMessage(locale.selectRowLabel, { id })
|
|
1305
|
+
}
|
|
1306
|
+
)
|
|
1307
|
+
}
|
|
1308
|
+
) : null,
|
|
1309
|
+
showSerialNumber ? /* @__PURE__ */ jsx3(
|
|
1310
|
+
"td",
|
|
1311
|
+
{
|
|
1312
|
+
className: [
|
|
1313
|
+
"tbx-td tbx-td--serial",
|
|
1314
|
+
leftOffsets.has("__serial") ? "tbx-td--pinned-left" : void 0,
|
|
1315
|
+
lastLeftPinnedId === "__serial" ? "tbx-pinned-border-left" : void 0
|
|
1316
|
+
].filter(Boolean).join(" "),
|
|
1317
|
+
style: {
|
|
1318
|
+
left: leftOffsets.get("__serial")
|
|
1319
|
+
},
|
|
1320
|
+
children: serialNumber(currentPage, pageSize, index)
|
|
1321
|
+
}
|
|
1322
|
+
) : null,
|
|
1323
|
+
visible.map((col, colIndex) => {
|
|
1324
|
+
const colId = getColumnId2(col);
|
|
1325
|
+
const isPinnedLeft = leftOffsets.has(colId);
|
|
1326
|
+
const isPinnedRight = rightOffsets.has(colId);
|
|
1327
|
+
const isLastLeft = lastLeftPinnedId === colId;
|
|
1328
|
+
const isFirstRight = firstRightPinnedId === colId;
|
|
1329
|
+
const isCellEditable = isEditable(col);
|
|
1330
|
+
const isCurrentlyEditing = editingCell?.rowId === id && editingCell?.columnId === colId;
|
|
1331
|
+
const tdStyle = {
|
|
1332
|
+
...bodyCellStyle(col),
|
|
1333
|
+
...isPinnedLeft ? { left: leftOffsets.get(colId) } : {},
|
|
1334
|
+
...isPinnedRight ? { right: rightOffsets.get(colId) } : {}
|
|
1335
|
+
};
|
|
1336
|
+
return /* @__PURE__ */ jsx3(
|
|
1337
|
+
"td",
|
|
1338
|
+
{
|
|
1339
|
+
className: [
|
|
1340
|
+
"tbx-td",
|
|
1341
|
+
isCellEditable ? "tbx-cell--editable" : void 0,
|
|
1342
|
+
isPinnedLeft ? "tbx-td--pinned-left" : void 0,
|
|
1343
|
+
isPinnedRight ? "tbx-td--pinned-right" : void 0,
|
|
1344
|
+
isLastLeft ? "tbx-pinned-border-left" : void 0,
|
|
1345
|
+
isFirstRight ? "tbx-pinned-border-right" : void 0
|
|
1346
|
+
].filter(Boolean).join(" "),
|
|
1347
|
+
style: tdStyle,
|
|
1348
|
+
onDoubleClick: isCellEditable ? (e) => {
|
|
1349
|
+
e.stopPropagation();
|
|
1350
|
+
setEditingCell({ rowId: id, columnId: colId });
|
|
1351
|
+
} : void 0,
|
|
1352
|
+
children: isCurrentlyEditing ? /* @__PURE__ */ jsxs2(
|
|
1353
|
+
"div",
|
|
1354
|
+
{
|
|
1355
|
+
className: "tbx-cell-edit-wrap",
|
|
1356
|
+
onClick: (e) => e.stopPropagation(),
|
|
1357
|
+
children: [
|
|
1358
|
+
col.meta?.editType === "select" && col.meta.editOptions ? /* @__PURE__ */ jsx3(
|
|
1359
|
+
"select",
|
|
1360
|
+
{
|
|
1361
|
+
autoFocus: true,
|
|
1362
|
+
className: "tbx-cell-edit-select tbx-cell-edit-input",
|
|
1363
|
+
defaultValue: String(row[colId] ?? ""),
|
|
1364
|
+
id: `${instanceId}-edit-${id}-${colId}`,
|
|
1365
|
+
children: col.meta.editOptions.map((opt) => /* @__PURE__ */ jsx3("option", { value: opt, children: opt }, opt))
|
|
1366
|
+
}
|
|
1367
|
+
) : /* @__PURE__ */ jsx3(
|
|
1368
|
+
"input",
|
|
1369
|
+
{
|
|
1370
|
+
autoFocus: true,
|
|
1371
|
+
type: col.meta?.editType === "number" ? "number" : "text",
|
|
1372
|
+
className: "tbx-cell-edit-input",
|
|
1373
|
+
defaultValue: String(row[colId] ?? ""),
|
|
1374
|
+
id: `${instanceId}-edit-${id}-${colId}`,
|
|
1375
|
+
onKeyDown: (e) => {
|
|
1376
|
+
if (e.key === "Enter") {
|
|
1377
|
+
e.preventDefault();
|
|
1378
|
+
const el = e.currentTarget;
|
|
1379
|
+
const val = col.meta?.editType === "number" ? Number(el.value) : el.value;
|
|
1380
|
+
const oldVal = row[colId];
|
|
1381
|
+
row[colId] = val;
|
|
1382
|
+
onCellEdit?.({ row, columnId: colId, oldValue: oldVal, newValue: val });
|
|
1383
|
+
setEditingCell(null);
|
|
1384
|
+
} else if (e.key === "Escape") {
|
|
1385
|
+
e.preventDefault();
|
|
1386
|
+
setEditingCell(null);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
),
|
|
1391
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-cell-edit-actions", children: [
|
|
1392
|
+
/* @__PURE__ */ jsx3(
|
|
1393
|
+
"button",
|
|
1394
|
+
{
|
|
1395
|
+
type: "button",
|
|
1396
|
+
className: "tbx-cell-edit-btn tbx-cell-edit-btn--save",
|
|
1397
|
+
onClick: (e) => {
|
|
1398
|
+
e.stopPropagation();
|
|
1399
|
+
const el = document.getElementById(`${instanceId}-edit-${id}-${colId}`);
|
|
1400
|
+
if (el) {
|
|
1401
|
+
const val = col.meta?.editType === "number" ? Number(el.value) : el.value;
|
|
1402
|
+
const oldVal = row[colId];
|
|
1403
|
+
row[colId] = val;
|
|
1404
|
+
onCellEdit?.({ row, columnId: colId, oldValue: oldVal, newValue: val });
|
|
1405
|
+
}
|
|
1406
|
+
setEditingCell(null);
|
|
1407
|
+
},
|
|
1408
|
+
children: /* @__PURE__ */ jsx3(CheckIcon, { className: "tbx-icon" })
|
|
1409
|
+
}
|
|
1410
|
+
),
|
|
1411
|
+
/* @__PURE__ */ jsx3(
|
|
1412
|
+
"button",
|
|
1413
|
+
{
|
|
1414
|
+
type: "button",
|
|
1415
|
+
className: "tbx-cell-edit-btn tbx-cell-edit-btn--cancel",
|
|
1416
|
+
onClick: (e) => {
|
|
1417
|
+
e.stopPropagation();
|
|
1418
|
+
setEditingCell(null);
|
|
1419
|
+
},
|
|
1420
|
+
children: /* @__PURE__ */ jsx3(XIcon, { className: "tbx-icon" })
|
|
1421
|
+
}
|
|
1422
|
+
)
|
|
1423
|
+
] })
|
|
1424
|
+
]
|
|
1425
|
+
}
|
|
1426
|
+
) : renderCellContent(col, row, boolLabels)
|
|
1427
|
+
},
|
|
1428
|
+
colId || `col-${colIndex}`
|
|
1429
|
+
);
|
|
1430
|
+
})
|
|
1431
|
+
]
|
|
1432
|
+
}
|
|
1433
|
+
),
|
|
1434
|
+
isExpanded && renderExpandedRow ? /* @__PURE__ */ jsx3("tr", { className: "tbx-expanded-row", children: /* @__PURE__ */ jsx3("td", { className: "tbx-expanded-cell", colSpan: columnCount, children: /* @__PURE__ */ jsx3("div", { className: "tbx-detail-panel", children: renderExpandedRow(row) }) }) }) : null
|
|
1435
|
+
] }, id || index);
|
|
720
1436
|
}) })
|
|
721
1437
|
] }) }),
|
|
722
|
-
/* @__PURE__ */ jsx3("div", { className: "
|
|
723
|
-
/* @__PURE__ */
|
|
724
|
-
|
|
725
|
-
|
|
1438
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-cards", children: isLoading ? /* @__PURE__ */ jsx3("div", { className: "tbx-card", children: /* @__PURE__ */ jsxs2("div", { className: "tbx-state", children: [
|
|
1439
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-dotted-loader", "aria-hidden": "true", children: [
|
|
1440
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" }),
|
|
1441
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" }),
|
|
1442
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" }),
|
|
1443
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-dot" })
|
|
1444
|
+
] }),
|
|
1445
|
+
/* @__PURE__ */ jsx3("div", { className: "tbx-loading-text", "aria-live": "polite", children: locale.loadingText })
|
|
1446
|
+
] }) }) : rows.length === 0 ? /* @__PURE__ */ jsx3("div", { className: "tbx-card", children: /* @__PURE__ */ jsx3("div", { className: "tbx-state", children: locale.emptyText }) }) : rows.map((row, index) => {
|
|
726
1447
|
const id = pageRowIds[index] ?? String(index);
|
|
727
1448
|
const isSelected = selectedIds.has(id);
|
|
728
1449
|
return /* @__PURE__ */ jsxs2(
|
|
729
1450
|
"div",
|
|
730
1451
|
{
|
|
731
1452
|
className: [
|
|
732
|
-
"
|
|
733
|
-
isSelected ? "
|
|
734
|
-
rowIsClickable ? "
|
|
1453
|
+
"tbx-card",
|
|
1454
|
+
isSelected ? "tbx-card--selected" : void 0,
|
|
1455
|
+
rowIsClickable ? "tbx-card--clickable" : void 0
|
|
735
1456
|
].filter(Boolean).join(" "),
|
|
736
1457
|
onClick: rowIsClickable ? activateRow(row) : void 0,
|
|
737
1458
|
onKeyDown: rowIsClickable ? rowKeyDown(row) : void 0,
|
|
738
1459
|
tabIndex: rowIsClickable ? 0 : void 0,
|
|
739
1460
|
children: [
|
|
740
|
-
showSerialNumber || enableSelection ? /* @__PURE__ */ jsxs2("div", { className: "
|
|
741
|
-
showSerialNumber ? /* @__PURE__ */ jsxs2("span", { className: "
|
|
1461
|
+
showSerialNumber || enableSelection ? /* @__PURE__ */ jsxs2("div", { className: "tbx-card-head", children: [
|
|
1462
|
+
showSerialNumber ? /* @__PURE__ */ jsxs2("span", { className: "tbx-card-serial", children: [
|
|
742
1463
|
"#",
|
|
743
1464
|
serialNumber(currentPage, pageSize, index)
|
|
744
1465
|
] }) : null,
|
|
745
1466
|
enableSelection ? /* @__PURE__ */ jsx3(
|
|
746
1467
|
"span",
|
|
747
1468
|
{
|
|
748
|
-
className: "
|
|
1469
|
+
className: "tbx-card-select",
|
|
749
1470
|
onClick: (event) => event.stopPropagation(),
|
|
750
1471
|
children: /* @__PURE__ */ jsx3(
|
|
751
1472
|
"input",
|
|
752
1473
|
{
|
|
753
1474
|
type: "checkbox",
|
|
754
|
-
className: "
|
|
1475
|
+
className: "tbx-checkbox",
|
|
755
1476
|
checked: isSelected,
|
|
756
1477
|
onChange: () => toggleSelectRow(id),
|
|
757
1478
|
onClick: (event) => event.stopPropagation(),
|
|
@@ -761,9 +1482,9 @@ function NexGrid({
|
|
|
761
1482
|
}
|
|
762
1483
|
) : null
|
|
763
1484
|
] }) : null,
|
|
764
|
-
/* @__PURE__ */ jsx3("dl", { className: "
|
|
1485
|
+
/* @__PURE__ */ jsx3("dl", { className: "tbx-card-rows", children: visible.map((col, colIndex) => {
|
|
765
1486
|
const colId = getColumnId2(col);
|
|
766
|
-
return /* @__PURE__ */ jsxs2("div", { className: "
|
|
1487
|
+
return /* @__PURE__ */ jsxs2("div", { className: "tbx-card-row", children: [
|
|
767
1488
|
/* @__PURE__ */ jsx3("dt", { children: getColumnTitle(col) || colId }),
|
|
768
1489
|
/* @__PURE__ */ jsx3("dd", { children: renderCellContent(col, row, boolLabels) })
|
|
769
1490
|
] }, colId || `col-${colIndex}`);
|
|
@@ -773,52 +1494,55 @@ function NexGrid({
|
|
|
773
1494
|
id || index
|
|
774
1495
|
);
|
|
775
1496
|
}) }),
|
|
776
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
777
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1497
|
+
showFooter ? /* @__PURE__ */ jsxs2("div", { className: "tbx-footer", children: [
|
|
1498
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-range", children: [
|
|
778
1499
|
/* @__PURE__ */ jsx3("span", { children: renderTemplate(locale.showingRange, {
|
|
779
1500
|
start: /* @__PURE__ */ jsx3("strong", { children: range.start }),
|
|
780
1501
|
end: /* @__PURE__ */ jsx3("strong", { children: range.end }),
|
|
781
|
-
total: /* @__PURE__ */ jsx3("strong", { className: "
|
|
1502
|
+
total: /* @__PURE__ */ jsx3("strong", { className: "tbx-range-total", children: total.toLocaleString() })
|
|
782
1503
|
}) }),
|
|
783
|
-
selectedIds.size > 0 ? /* @__PURE__ */ jsx3("span", { className: "
|
|
1504
|
+
selectedIds.size > 0 ? /* @__PURE__ */ jsx3("span", { className: "tbx-selected-badge", children: formatMessage(locale.selectedBadge, { count: selectedIds.size }) }) : null
|
|
784
1505
|
] }),
|
|
785
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
786
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1506
|
+
/* @__PURE__ */ jsxs2("div", { className: "tbx-pagination", children: [
|
|
1507
|
+
isRowsPerPageVisible ? /* @__PURE__ */ jsxs2("div", { className: "tbx-rows-per-page", children: [
|
|
787
1508
|
/* @__PURE__ */ jsx3("span", { children: locale.rowsPerPage }),
|
|
788
1509
|
/* @__PURE__ */ jsx3(
|
|
789
1510
|
"select",
|
|
790
1511
|
{
|
|
791
|
-
className: "
|
|
1512
|
+
className: "tbx-rows-select",
|
|
792
1513
|
value: String(pageSize),
|
|
793
1514
|
onChange: (event) => {
|
|
794
1515
|
onQueryChange(withPageSize(query, Number.parseInt(event.target.value, 10)));
|
|
795
1516
|
},
|
|
796
1517
|
"aria-label": locale.rowsPerPage,
|
|
797
|
-
children: PAGE_SIZES.map((size) => /* @__PURE__ */
|
|
1518
|
+
children: PAGE_SIZES.map((size) => /* @__PURE__ */ jsxs2("option", { value: size, children: [
|
|
1519
|
+
size,
|
|
1520
|
+
" rows"
|
|
1521
|
+
] }, size))
|
|
798
1522
|
}
|
|
799
1523
|
)
|
|
800
|
-
] }),
|
|
801
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1524
|
+
] }) : null,
|
|
1525
|
+
isPaginationVisible ? /* @__PURE__ */ jsxs2("div", { className: "tbx-pager", children: [
|
|
802
1526
|
/* @__PURE__ */ jsxs2(
|
|
803
1527
|
"button",
|
|
804
1528
|
{
|
|
805
1529
|
type: "button",
|
|
806
|
-
className: "
|
|
1530
|
+
className: "tbx-page-nav",
|
|
807
1531
|
disabled: currentPage <= 1,
|
|
808
1532
|
onClick: () => onQueryChange(withPage(query, currentPage - 1, totalPages)),
|
|
809
1533
|
"aria-label": locale.previousPage,
|
|
810
1534
|
children: [
|
|
811
1535
|
/* @__PURE__ */ jsx3(ChevronLeftIcon, { size: 16 }),
|
|
812
|
-
/* @__PURE__ */ jsx3("span", { className: "
|
|
1536
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-sr-only", children: locale.previousPage })
|
|
813
1537
|
]
|
|
814
1538
|
}
|
|
815
1539
|
),
|
|
816
1540
|
pageItems.map(
|
|
817
|
-
(item, index) => item === "..." ? /* @__PURE__ */ jsx3("span", { className: "
|
|
1541
|
+
(item, index) => item === "..." ? /* @__PURE__ */ jsx3("span", { className: "tbx-page-ellipsis", children: "\u2026" }, `gap-${index}`) : /* @__PURE__ */ jsx3(
|
|
818
1542
|
"button",
|
|
819
1543
|
{
|
|
820
1544
|
type: "button",
|
|
821
|
-
className: item === currentPage ? "
|
|
1545
|
+
className: item === currentPage ? "tbx-page-btn tbx-page-btn--current" : "tbx-page-btn",
|
|
822
1546
|
onClick: () => onQueryChange(withPage(query, item, totalPages)),
|
|
823
1547
|
"aria-label": formatMessage(locale.pageLabel, { page: item }),
|
|
824
1548
|
"aria-current": item === currentPage ? "page" : void 0,
|
|
@@ -831,52 +1555,63 @@ function NexGrid({
|
|
|
831
1555
|
"button",
|
|
832
1556
|
{
|
|
833
1557
|
type: "button",
|
|
834
|
-
className: "
|
|
1558
|
+
className: "tbx-page-nav",
|
|
835
1559
|
disabled: currentPage >= totalPages,
|
|
836
1560
|
onClick: () => onQueryChange(withPage(query, currentPage + 1, totalPages)),
|
|
837
1561
|
"aria-label": locale.nextPage,
|
|
838
1562
|
children: [
|
|
839
1563
|
/* @__PURE__ */ jsx3(ChevronRightIcon, { size: 16 }),
|
|
840
|
-
/* @__PURE__ */ jsx3("span", { className: "
|
|
1564
|
+
/* @__PURE__ */ jsx3("span", { className: "tbx-sr-only", children: locale.nextPage })
|
|
841
1565
|
]
|
|
842
1566
|
}
|
|
843
1567
|
)
|
|
844
|
-
] }),
|
|
845
|
-
/* @__PURE__ */ jsxs2(
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
"
|
|
849
|
-
{
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1568
|
+
] }) : null,
|
|
1569
|
+
isJumpToPageVisible ? /* @__PURE__ */ jsxs2(
|
|
1570
|
+
"form",
|
|
1571
|
+
{
|
|
1572
|
+
className: "tbx-jump",
|
|
1573
|
+
onSubmit: (event) => {
|
|
1574
|
+
event.preventDefault();
|
|
1575
|
+
submitJump(jumpText);
|
|
1576
|
+
},
|
|
1577
|
+
children: [
|
|
1578
|
+
/* @__PURE__ */ jsx3("label", { className: "tbx-jump-label", htmlFor: jumpInputId, children: locale.goToPage }),
|
|
1579
|
+
/* @__PURE__ */ jsx3(
|
|
1580
|
+
"input",
|
|
1581
|
+
{
|
|
1582
|
+
id: jumpInputId,
|
|
1583
|
+
type: "number",
|
|
1584
|
+
className: "tbx-jump-input",
|
|
1585
|
+
min: 1,
|
|
1586
|
+
max: totalPages,
|
|
1587
|
+
value: jumpText,
|
|
1588
|
+
onChange: (event) => setJumpText(event.target.value),
|
|
1589
|
+
onBlur: () => submitJump(jumpText),
|
|
1590
|
+
"aria-label": locale.goToPageOf
|
|
1591
|
+
}
|
|
1592
|
+
)
|
|
1593
|
+
]
|
|
1594
|
+
}
|
|
1595
|
+
) : null
|
|
862
1596
|
] })
|
|
863
|
-
] })
|
|
1597
|
+
] }) : null
|
|
864
1598
|
] });
|
|
865
1599
|
}
|
|
1600
|
+
var NexGrid = TableX;
|
|
866
1601
|
|
|
867
|
-
// src/use-client-
|
|
1602
|
+
// src/use-client-table-x.ts
|
|
868
1603
|
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
869
1604
|
import {
|
|
870
|
-
defaultQuery,
|
|
871
|
-
queryClientData
|
|
1605
|
+
defaultQuery as defaultQuery2,
|
|
1606
|
+
queryClientData as queryClientData2
|
|
872
1607
|
} from "@nexgrid/core";
|
|
873
|
-
function
|
|
1608
|
+
function useClientTableX(allData, options) {
|
|
874
1609
|
const [query, setQuery] = useState4(() => ({
|
|
875
|
-
...
|
|
1610
|
+
...defaultQuery2(),
|
|
876
1611
|
...options?.initialQuery
|
|
877
1612
|
}));
|
|
878
1613
|
const page = useMemo2(
|
|
879
|
-
() =>
|
|
1614
|
+
() => queryClientData2(allData, query, options),
|
|
880
1615
|
[allData, query, options]
|
|
881
1616
|
);
|
|
882
1617
|
return {
|
|
@@ -890,11 +1625,12 @@ function useClientNexGrid(allData, options) {
|
|
|
890
1625
|
setQuery
|
|
891
1626
|
};
|
|
892
1627
|
}
|
|
1628
|
+
var useClientNexGrid = useClientTableX;
|
|
893
1629
|
|
|
894
1630
|
// src/index.ts
|
|
895
1631
|
import {
|
|
896
|
-
queryClientData as
|
|
897
|
-
defaultQuery as
|
|
1632
|
+
queryClientData as queryClientData3,
|
|
1633
|
+
defaultQuery as defaultQuery3,
|
|
898
1634
|
parseQuery,
|
|
899
1635
|
serializeQuery,
|
|
900
1636
|
buildQueryUrl as buildQueryUrl2,
|
|
@@ -903,11 +1639,12 @@ import {
|
|
|
903
1639
|
fromODataResponse,
|
|
904
1640
|
primarySort as primarySort2,
|
|
905
1641
|
withToggledSort as withToggledSort2,
|
|
1642
|
+
withToggledMultiSort as withToggledMultiSort2,
|
|
906
1643
|
withSort,
|
|
907
1644
|
withSearch as withSearch2,
|
|
908
1645
|
withPage as withPage2,
|
|
909
1646
|
withPageSize as withPageSize2,
|
|
910
|
-
withFilter,
|
|
1647
|
+
withFilter as withFilter2,
|
|
911
1648
|
totalPagesFor as totalPagesFor2,
|
|
912
1649
|
isPageSize as isPageSize2,
|
|
913
1650
|
PAGE_SIZES as PAGE_SIZES2,
|
|
@@ -920,24 +1657,27 @@ export {
|
|
|
920
1657
|
DEFAULT_PAGE_SIZE,
|
|
921
1658
|
NexGrid,
|
|
922
1659
|
PAGE_SIZES2 as PAGE_SIZES,
|
|
1660
|
+
TableX,
|
|
923
1661
|
buildODataUrl,
|
|
924
1662
|
buildQueryUrl2 as buildQueryUrl,
|
|
925
|
-
|
|
1663
|
+
defaultQuery3 as defaultQuery,
|
|
926
1664
|
fromODataResponse,
|
|
927
1665
|
isPageSize2 as isPageSize,
|
|
928
1666
|
parseQuery,
|
|
929
1667
|
primarySort2 as primarySort,
|
|
930
|
-
|
|
1668
|
+
queryClientData3 as queryClientData,
|
|
931
1669
|
resolveLocale2 as resolveLocale,
|
|
932
1670
|
serializeQuery,
|
|
933
1671
|
toODataParams,
|
|
934
1672
|
totalPagesFor2 as totalPagesFor,
|
|
935
1673
|
useClientNexGrid,
|
|
936
|
-
|
|
1674
|
+
useClientTableX,
|
|
1675
|
+
withFilter2 as withFilter,
|
|
937
1676
|
withPage2 as withPage,
|
|
938
1677
|
withPageSize2 as withPageSize,
|
|
939
1678
|
withSearch2 as withSearch,
|
|
940
1679
|
withSort,
|
|
1680
|
+
withToggledMultiSort2 as withToggledMultiSort,
|
|
941
1681
|
withToggledSort2 as withToggledSort
|
|
942
1682
|
};
|
|
943
1683
|
//# sourceMappingURL=index.js.map
|