@eifi1/ui-kit 0.47.0 → 0.48.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 +5 -3
- package/dist/admin/admin-sections.d.ts +8 -0
- package/dist/admin/admin-sections.js +2 -1
- package/dist/admin/admin-sections.js.map +1 -1
- package/dist/auth/verify-email.d.ts +9 -1
- package/dist/auth/verify-email.js +22 -13
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/components/alert-banner.d.ts +29 -1
- package/dist/components/alert-banner.js +84 -7
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/button-look.d.ts +4 -0
- package/dist/components/button-look.js +2 -0
- package/dist/components/button-look.js.map +1 -1
- package/dist/components/combobox-core.js +5 -1
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/data-table-column-settings.d.ts +6 -1
- package/dist/components/data-table-column-settings.js +12 -2
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-fit.d.ts +44 -0
- package/dist/components/data-table-fit.js +103 -0
- package/dist/components/data-table-fit.js.map +1 -0
- package/dist/components/data-table-groups.d.ts +95 -0
- package/dist/components/data-table-groups.js +165 -0
- package/dist/components/data-table-groups.js.map +1 -0
- package/dist/components/data-table-head.js +3 -1
- package/dist/components/data-table-head.js.map +1 -1
- package/dist/components/data-table-labels.d.ts +7 -0
- package/dist/components/data-table-labels.js +3 -0
- package/dist/components/data-table-labels.js.map +1 -1
- package/dist/components/data-table-leading-row.d.ts +17 -0
- package/dist/components/data-table-leading-row.js +41 -0
- package/dist/components/data-table-leading-row.js.map +1 -0
- package/dist/components/data-table-resize.js +1 -1
- package/dist/components/data-table-resize.js.map +1 -1
- package/dist/components/data-table.d.ts +78 -2
- package/dist/components/data-table.js +348 -257
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/disclosure.d.ts +3 -1
- package/dist/components/disclosure.js +10 -4
- package/dist/components/disclosure.js.map +1 -1
- package/dist/components/dropdown.js +8 -1
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/floating-panel.d.ts +14 -1
- package/dist/components/floating-panel.js +7 -2
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/hover-menu.js +5 -1
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.js +2 -1
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/popover.js +5 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/table-skeleton.d.ts +35 -0
- package/dist/components/table-skeleton.js +75 -0
- package/dist/components/table-skeleton.js.map +1 -0
- package/dist/components/tabs.d.ts +10 -12
- package/dist/components/tabs.js +20 -10
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/use-table-state.d.ts +8 -7
- package/dist/components/use-table-state.js +37 -3
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/data-table.d.ts +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/feedback/feedback-table.d.ts +5 -0
- package/dist/feedback/feedback-table.js +30 -7
- package/dist/feedback/feedback-table.js.map +1 -1
- package/dist/hooks/use-dismiss.d.ts +30 -1
- package/dist/hooks/use-dismiss.js +30 -2
- package/dist/hooks/use-dismiss.js.map +1 -1
- package/dist/i18n/german.js +6 -1
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +4 -0
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +6 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/es.js +6 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +6 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +6 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +6 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +6 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/shared-labels.js +3 -1
- package/dist/i18n/shared-labels.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/float-clearance.d.ts +8 -0
- package/dist/lib/float-clearance.js +29 -0
- package/dist/lib/float-clearance.js.map +1 -0
- package/dist/settings/settings-catalogue.d.ts +10 -0
- package/dist/settings/settings-catalogue.js.map +1 -1
- package/dist/settings/settings-layout.js +10 -3
- package/dist/settings/settings-layout.js.map +1 -1
- package/dist/shell/app-shell.d.ts +5 -0
- package/dist/shell/app-shell.js +5 -3
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/option-switcher-menu.d.ts +2 -0
- package/dist/shell/option-switcher-menu.js +6 -2
- package/dist/shell/option-switcher-menu.js.map +1 -1
- package/dist/shell/topbar-action-menu.js +2 -1
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell/topbar-controls.js +5 -3
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/tour/tour.js +1 -0
- package/dist/tour/tour.js.map +1 -1
- package/package.json +1 -1
- package/src/admin/admin-sections.tsx +8 -0
- package/src/auth/verify-email.tsx +34 -9
- package/src/components/alert-banner.tsx +131 -7
- package/src/components/button-look.ts +6 -0
- package/src/components/combobox-core.tsx +7 -1
- package/src/components/data-table-column-settings.tsx +23 -2
- package/src/components/data-table-fit.ts +187 -0
- package/src/components/data-table-groups.tsx +275 -0
- package/src/components/data-table-head.tsx +4 -1
- package/src/components/data-table-labels.ts +13 -0
- package/src/components/data-table-leading-row.tsx +55 -0
- package/src/components/data-table-resize.ts +2 -1
- package/src/components/data-table.tsx +246 -43
- package/src/components/disclosure.tsx +22 -5
- package/src/components/dropdown.tsx +11 -1
- package/src/components/floating-panel.tsx +24 -1
- package/src/components/hover-menu.tsx +6 -1
- package/src/components/icon-button.tsx +3 -3
- package/src/components/popover.tsx +7 -1
- package/src/components/table-skeleton.tsx +133 -0
- package/src/components/tabs.tsx +67 -37
- package/src/components/use-table-state.ts +54 -3
- package/src/data-table.ts +2 -0
- package/src/feedback/feedback-table.tsx +33 -1
- package/src/hooks/use-dismiss.ts +65 -3
- package/src/i18n/german.ts +5 -0
- package/src/i18n/kit-labels.tsx +4 -0
- package/src/i18n/locales/es.ts +5 -0
- package/src/i18n/locales/fr.ts +5 -0
- package/src/i18n/locales/hu.ts +5 -0
- package/src/i18n/locales/it.ts +5 -0
- package/src/i18n/locales/zh.ts +5 -0
- package/src/i18n/shared-labels.ts +2 -0
- package/src/index.ts +3 -0
- package/src/lib/float-clearance.ts +54 -0
- package/src/settings/settings-catalogue.ts +10 -0
- package/src/settings/settings-layout.tsx +18 -4
- package/src/shell/app-shell.tsx +17 -3
- package/src/shell/option-switcher-menu.tsx +16 -4
- package/src/shell/topbar-action-menu.tsx +22 -10
- package/src/shell/topbar-controls.tsx +18 -12
- package/src/tour/tour.tsx +5 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createElement } from "react";
|
|
4
|
-
import { Fragment, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { Fragment as Fragment2, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { Card } from "./card.js";
|
|
6
6
|
import { Spinner } from "./spinner.js";
|
|
7
7
|
import { isTableOwnColumn, useRowActionColumn } from "./data-table-row-actions.js";
|
|
@@ -19,6 +19,14 @@ import {
|
|
|
19
19
|
} from "./data-table-shared.js";
|
|
20
20
|
import { MobileFilters, MobileRow, MobileSelectBar, MobileSort, StackedFields } from "./data-table-mobile.js";
|
|
21
21
|
import { DataTableHead } from "./data-table-head.js";
|
|
22
|
+
import { DataTableLeadingRow } from "./data-table-leading-row.js";
|
|
23
|
+
import {
|
|
24
|
+
DataTableGroupBand,
|
|
25
|
+
DataTableLoadMoreFooter,
|
|
26
|
+
groupLevels,
|
|
27
|
+
groupRows,
|
|
28
|
+
useGroupBandTops
|
|
29
|
+
} from "./data-table-groups.js";
|
|
22
30
|
import { ColumnSettingsPanel } from "./data-table-column-settings.js";
|
|
23
31
|
import { useLargeText } from "../hooks/use-large-text.js";
|
|
24
32
|
import { cn } from "../lib/cn.js";
|
|
@@ -42,10 +50,12 @@ const DEFAULT_DATA_TABLE_SORT_LABELS = {
|
|
|
42
50
|
const flipDir = (d) => d === "asc" ? "desc" : "asc";
|
|
43
51
|
function moveRowFocus(from, key) {
|
|
44
52
|
if (!(key in ROW_NAV_KEYS)) return false;
|
|
45
|
-
const
|
|
46
|
-
if (!
|
|
47
|
-
const rows = Array.from(
|
|
48
|
-
(
|
|
53
|
+
const table = from.closest("table");
|
|
54
|
+
if (!table) return false;
|
|
55
|
+
const rows = Array.from(table.tBodies).flatMap(
|
|
56
|
+
(body) => Array.from(body.children).filter(
|
|
57
|
+
(el) => el instanceof HTMLElement && el.hasAttribute("data-row-nav")
|
|
58
|
+
)
|
|
49
59
|
);
|
|
50
60
|
const i = rows.indexOf(from);
|
|
51
61
|
const target = key === "ArrowDown" ? rows[i + 1] : key === "ArrowUp" ? rows[i - 1] : key === "Home" ? rows[0] : key === "End" ? rows[rows.length - 1] : void 0;
|
|
@@ -55,6 +65,7 @@ function moveRowFocus(from, key) {
|
|
|
55
65
|
const ROW_NAV_KEYS = { ArrowDown: 1, ArrowUp: 1, Home: 1, End: 1 };
|
|
56
66
|
import { DEFAULT_PERSIST_PREFIX, useTableState } from "./use-table-state.js";
|
|
57
67
|
import { useMobileReveal } from "./use-mobile-reveal.js";
|
|
68
|
+
import { GROW_CELL_CLASS, GROW_PEER_CELL_CLASS, useColumnFit } from "./data-table-fit.js";
|
|
58
69
|
function DataTable({
|
|
59
70
|
rows,
|
|
60
71
|
columns: columnsProp,
|
|
@@ -94,6 +105,9 @@ function DataTable({
|
|
|
94
105
|
mobileSwipeActions,
|
|
95
106
|
desktopSwipeActions,
|
|
96
107
|
leadingRow,
|
|
108
|
+
leadingRowSticky = false,
|
|
109
|
+
groupBy,
|
|
110
|
+
loadMore,
|
|
97
111
|
density = "comfortable",
|
|
98
112
|
sortCycle = "tri",
|
|
99
113
|
chrome = "full",
|
|
@@ -160,7 +174,13 @@ function DataTable({
|
|
|
160
174
|
// Ignored in `serverPagination` mode, where the owner's is the page size.
|
|
161
175
|
pageSizeProp: isServer ? void 0 : pageSizeProp
|
|
162
176
|
});
|
|
163
|
-
const widths = useMemo(() =>
|
|
177
|
+
const widths = useMemo(() => {
|
|
178
|
+
if (!resizable) return {};
|
|
179
|
+
const grow = columns.find((c) => c.grow)?.key;
|
|
180
|
+
if (!grow || !(grow in storedWidths)) return storedWidths;
|
|
181
|
+
const { [grow]: _ignored, ...rest } = storedWidths;
|
|
182
|
+
return rest;
|
|
183
|
+
}, [resizable, storedWidths, columns]);
|
|
164
184
|
const hiddenCols = useMemo(
|
|
165
185
|
() => columnSettings ? storedHiddenCols : /* @__PURE__ */ new Set(),
|
|
166
186
|
[columnSettings, storedHiddenCols]
|
|
@@ -221,7 +241,7 @@ function DataTable({
|
|
|
221
241
|
});
|
|
222
242
|
return copy;
|
|
223
243
|
}, [filtered, sorts, columnSig, isServer]);
|
|
224
|
-
const unpaged = !isServer && !paginated;
|
|
244
|
+
const unpaged = !isServer && (!paginated || !!loadMore);
|
|
225
245
|
const effectivePageSize = isServer ? serverPagination.pageSize : unpaged || pageSize === Infinity ? sorted.length || 1 : pageSize;
|
|
226
246
|
const paginationTotal = isServer ? serverPagination.total : sorted.length;
|
|
227
247
|
const paginationPageSize = isServer ? serverPagination.pageSize : pageSize;
|
|
@@ -297,17 +317,26 @@ function DataTable({
|
|
|
297
317
|
else setPage(p);
|
|
298
318
|
announce(labels.pageChanged(p + 1, totalPages));
|
|
299
319
|
};
|
|
320
|
+
const { autoHidden, keep: keepColumn } = useColumnFit({
|
|
321
|
+
columns,
|
|
322
|
+
hiddenCols,
|
|
323
|
+
headRefs,
|
|
324
|
+
scroller: () => desktopScroller.current,
|
|
325
|
+
enabled: !usePhoneLayout()
|
|
326
|
+
});
|
|
300
327
|
const visibleColumns = useMemo(
|
|
301
|
-
() => columns.filter((c) => !hiddenCols.has(c.key)),
|
|
302
|
-
[columns, hiddenCols]
|
|
328
|
+
() => columns.filter((c) => !hiddenCols.has(c.key) && !autoHidden.has(c.key)),
|
|
329
|
+
[columns, hiddenCols, autoHidden]
|
|
303
330
|
);
|
|
331
|
+
const growDrawn = visibleColumns.some((c) => c.grow);
|
|
304
332
|
const linkColumn = rowHref ? visibleColumns.find((c) => c.mobilePrimary && !c.noRowLink) ?? visibleColumns.find((c) => !c.noRowLink) : void 0;
|
|
305
333
|
const { startResize, moveResize, finishResize, autoSizeAll } = useColumnResize({
|
|
306
334
|
headRefs,
|
|
307
335
|
widths,
|
|
308
336
|
setWidths,
|
|
309
337
|
columns,
|
|
310
|
-
|
|
338
|
+
// The columns left out for width have no header to measure either.
|
|
339
|
+
hiddenCols: autoHidden.size > 0 ? /* @__PURE__ */ new Set([...hiddenCols, ...autoHidden]) : hiddenCols
|
|
311
340
|
});
|
|
312
341
|
const visibleCount = visibleColumns.length;
|
|
313
342
|
const totalCount = columns.length;
|
|
@@ -323,7 +352,8 @@ function DataTable({
|
|
|
323
352
|
const columnsCountLabel = labels.columnsCount(visibleCount - ownVisible, totalCount - ownColumns);
|
|
324
353
|
const isMdUp = !usePhoneLayout();
|
|
325
354
|
const desktopScroller = useRef(null);
|
|
326
|
-
const
|
|
355
|
+
const levels = groupLevels(groupBy);
|
|
356
|
+
const measuresVisibleWidth = isMdUp && (!!expandedRow || levels.length > 0 || !!loadMore);
|
|
327
357
|
useEffect(() => {
|
|
328
358
|
const el = desktopScroller.current;
|
|
329
359
|
if (!measuresVisibleWidth || !el || typeof ResizeObserver === "undefined") return;
|
|
@@ -436,8 +466,17 @@ function DataTable({
|
|
|
436
466
|
},
|
|
437
467
|
rowKey(row)
|
|
438
468
|
);
|
|
439
|
-
const
|
|
440
|
-
|
|
469
|
+
const tableRef = useRef(null);
|
|
470
|
+
const desktopGroups = isMdUp && levels.length > 0 ? groupRows(slice, levels) : null;
|
|
471
|
+
const bandTops = useGroupBandTops(
|
|
472
|
+
tableRef,
|
|
473
|
+
!!desktopGroups,
|
|
474
|
+
`${levels.length}:${leadingRowSticky && !!leadingRow}:${desktopGroups?.[0]?.key ?? ""}`
|
|
475
|
+
);
|
|
476
|
+
const mobileLevel = typeof mobileGroupBy === "function" ? null : mobileGroupBy ?? null;
|
|
477
|
+
const mobileKey = typeof mobileGroupBy === "function" ? mobileGroupBy : mobileGroupBy?.key;
|
|
478
|
+
const mobileGroups = mobileKey ? mobileSlice.reduce((acc, row) => {
|
|
479
|
+
const key = mobileKey(row);
|
|
441
480
|
const last = acc[acc.length - 1];
|
|
442
481
|
if (last && last.key === key) last.rows.push(row);
|
|
443
482
|
else acc.push({ key, rows: [row] });
|
|
@@ -552,8 +591,11 @@ function DataTable({
|
|
|
552
591
|
),
|
|
553
592
|
"aria-busy": isLoading || void 0,
|
|
554
593
|
children: [
|
|
555
|
-
mobileGroups ? mobileGroups.map((g) => /* @__PURE__ */ jsxs(
|
|
556
|
-
/* @__PURE__ */
|
|
594
|
+
mobileGroups ? mobileGroups.map((g) => /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
595
|
+
/* @__PURE__ */ jsxs("li", { className: "sticky top-0 z-10 flex flex-wrap items-baseline justify-between gap-x-3 bg-surface-2 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-muted backdrop-blur", children: [
|
|
596
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0", children: mobileGroupLabel ? mobileGroupLabel(g.key) : mobileLevel?.label ? mobileLevel.label(g.key, g.rows) : g.key }),
|
|
597
|
+
mobileLevel?.end && /* @__PURE__ */ jsx("span", { className: "ms-auto tabular-nums", children: mobileLevel.end(g.key, g.rows) })
|
|
598
|
+
] }),
|
|
557
599
|
g.rows.map(renderMobileRow)
|
|
558
600
|
] }, `hb-group:${g.key}`)) : mobileSlice.map(renderMobileRow),
|
|
559
601
|
mobileSlice.length === 0 && /* @__PURE__ */ jsx(
|
|
@@ -573,6 +615,16 @@ function DataTable({
|
|
|
573
615
|
className: "px-4 py-4 text-center text-xs text-placeholder",
|
|
574
616
|
children: /* @__PURE__ */ jsx("bdi", { children: labels.loading })
|
|
575
617
|
}
|
|
618
|
+
),
|
|
619
|
+
loadMore && !canRevealMoreMobile && /* @__PURE__ */ jsx(
|
|
620
|
+
DataTableLoadMoreFooter,
|
|
621
|
+
{
|
|
622
|
+
as: "li",
|
|
623
|
+
loadMore,
|
|
624
|
+
rowCount: sorted.length,
|
|
625
|
+
labels,
|
|
626
|
+
compact
|
|
627
|
+
}
|
|
576
628
|
)
|
|
577
629
|
]
|
|
578
630
|
}
|
|
@@ -596,7 +648,7 @@ function DataTable({
|
|
|
596
648
|
"grid grid-cols-[auto_1fr] gap-x-3",
|
|
597
649
|
compact ? "gap-y-0.5 text-xs" : "gap-y-1 text-sm"
|
|
598
650
|
),
|
|
599
|
-
children: mobileColumns.filter((c) => c.footer).map((col) => /* @__PURE__ */ jsxs(
|
|
651
|
+
children: mobileColumns.filter((c) => c.footer).map((col) => /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
600
652
|
/* @__PURE__ */ jsx("dt", { className: "self-center text-xs uppercase tracking-wide text-muted", children: col.header }),
|
|
601
653
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0 self-center font-semibold text-primary", children: footerValue(col) })
|
|
602
654
|
] }, col.key))
|
|
@@ -605,7 +657,7 @@ function DataTable({
|
|
|
605
657
|
]
|
|
606
658
|
}
|
|
607
659
|
),
|
|
608
|
-
isServer && /* @__PURE__ */ jsx(
|
|
660
|
+
isServer && !loadMore && /* @__PURE__ */ jsx(
|
|
609
661
|
Pagination,
|
|
610
662
|
{
|
|
611
663
|
page: safePage,
|
|
@@ -633,7 +685,7 @@ function DataTable({
|
|
|
633
685
|
] }),
|
|
634
686
|
isMdUp && /* @__PURE__ */ jsxs("div", { className: cn("flex", fillHeight && "flex-1"), children: [
|
|
635
687
|
/* @__PURE__ */ jsxs("div", { className: cn("relative min-w-0 flex-1", fillHeight && "flex flex-col"), children: [
|
|
636
|
-
/* @__PURE__ */
|
|
688
|
+
/* @__PURE__ */ jsxs(
|
|
637
689
|
"div",
|
|
638
690
|
{
|
|
639
691
|
ref: desktopScroller,
|
|
@@ -641,257 +693,294 @@ function DataTable({
|
|
|
641
693
|
className: cn("overflow-auto [scrollbar-gutter:stable]", fillHeight && "min-h-0 grow basis-48"),
|
|
642
694
|
...edgeFadeProps,
|
|
643
695
|
style: fillHeight ? edgeFadeProps.style : { ...edgeFadeProps.style, maxHeight: maxBodyHeight },
|
|
644
|
-
children:
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
696
|
+
children: [
|
|
697
|
+
/* @__PURE__ */ jsxs(
|
|
698
|
+
"table",
|
|
699
|
+
{
|
|
700
|
+
ref: tableRef,
|
|
701
|
+
className: cn("w-full", compact ? "text-xs" : "text-sm"),
|
|
702
|
+
"data-fit-grow": growDrawn ? "" : void 0,
|
|
703
|
+
"aria-label": labels.table,
|
|
704
|
+
"aria-busy": isLoading || void 0,
|
|
705
|
+
children: [
|
|
706
|
+
/* @__PURE__ */ jsx(
|
|
707
|
+
DataTableHead,
|
|
708
|
+
{
|
|
709
|
+
visibleColumns,
|
|
710
|
+
selection,
|
|
711
|
+
compact,
|
|
712
|
+
labels,
|
|
713
|
+
locale,
|
|
714
|
+
isServer,
|
|
715
|
+
hasSortCallback: !!onSortsChange,
|
|
716
|
+
hasFilterCallback: !!onFiltersChange,
|
|
717
|
+
sorts,
|
|
718
|
+
filters,
|
|
719
|
+
selectOptionsByKey,
|
|
720
|
+
multiSort,
|
|
721
|
+
resizable,
|
|
722
|
+
widths,
|
|
723
|
+
setWidths,
|
|
724
|
+
headRefs,
|
|
725
|
+
toggleSort,
|
|
726
|
+
setFilterValue,
|
|
727
|
+
clearFilter,
|
|
728
|
+
startResize,
|
|
729
|
+
moveResize,
|
|
730
|
+
finishResize
|
|
731
|
+
}
|
|
732
|
+
),
|
|
733
|
+
(() => {
|
|
734
|
+
const bodyClass = cn(isLoading && slice.length > 0 && "opacity-60 transition-opacity");
|
|
735
|
+
const leading = leadingRow ? /* @__PURE__ */ jsx(DataTableLeadingRow, { colSpan: totalColSpan, sticky: leadingRowSticky, children: leadingRow }) : null;
|
|
736
|
+
const renderRow = (row, rowIndex) => {
|
|
737
|
+
const expanded = isExpanded?.(row) ?? false;
|
|
738
|
+
const expansion = expanded ? expandedRow?.(row) : null;
|
|
739
|
+
const rowInteractive = !!onRowClick || !!selection;
|
|
740
|
+
const href = rowHref?.(row);
|
|
741
|
+
const key = rowKey(row);
|
|
742
|
+
const detailId = `${detailIdBase}-${rowIndex}`;
|
|
743
|
+
const disclosure = rowsFocusable && expandedRow ? /* @__PURE__ */ jsx(
|
|
744
|
+
"button",
|
|
745
|
+
{
|
|
746
|
+
type: "button",
|
|
747
|
+
tabIndex: -1,
|
|
748
|
+
className: "sr-only-fixed",
|
|
749
|
+
"aria-label": labels.rowDetails,
|
|
750
|
+
"aria-expanded": expanded,
|
|
751
|
+
"aria-controls": expansion ? detailId : void 0,
|
|
752
|
+
onClick: () => onRowClick(row)
|
|
753
|
+
}
|
|
754
|
+
) : null;
|
|
755
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
756
|
+
/* @__PURE__ */ jsxs(
|
|
757
|
+
"tr",
|
|
693
758
|
{
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
759
|
+
...cleanAttrs(rowAttributes?.(row)),
|
|
760
|
+
"data-row-nav": rowsFocusable ? "" : void 0,
|
|
761
|
+
tabIndex: rowsFocusable ? key === tabRowKey ? 0 : -1 : void 0,
|
|
762
|
+
onFocus: rowsFocusable ? (e) => {
|
|
763
|
+
if (e.target === e.currentTarget) setFocusRowKey(key);
|
|
764
|
+
} : void 0,
|
|
765
|
+
onKeyDown: rowsFocusable ? (e) => {
|
|
766
|
+
if (e.target !== e.currentTarget) return;
|
|
767
|
+
if (e.altKey || e.ctrlKey || e.metaKey) return;
|
|
768
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
769
|
+
e.preventDefault();
|
|
770
|
+
onRowClick(row);
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
if (e.shiftKey) return;
|
|
774
|
+
if (moveRowFocus(e.currentTarget, e.key)) e.preventDefault();
|
|
775
|
+
} : void 0,
|
|
776
|
+
className: cn(
|
|
777
|
+
"border-t border-subtle",
|
|
778
|
+
rowInteractive && "cursor-pointer hover:bg-hover",
|
|
779
|
+
// The kit's focus frame width (§5, `--focus-ring-width`), drawn as an
|
|
780
|
+
// OUTLINE rather than FOCUS_RING's box-shadow: a shadow on a `<tr>`
|
|
781
|
+
// is not painted by every engine, an outline is.
|
|
782
|
+
rowsFocusable && "focus-visible:bg-hover focus-visible:outline-focus focus-visible:-outline-offset-2 focus-visible:outline-brand",
|
|
783
|
+
rowClassName?.(row)
|
|
784
|
+
),
|
|
785
|
+
onClick: rowInteractive ? (e) => {
|
|
786
|
+
if (fromOwnControl(e.target, e.currentTarget)) return;
|
|
787
|
+
if (fromOutside(e.target, e.currentTarget)) return;
|
|
788
|
+
if (selection && canSelect(row)) {
|
|
789
|
+
if (e.shiftKey) {
|
|
790
|
+
window.getSelection?.()?.removeAllRanges();
|
|
791
|
+
if (selectRange(rowIndex)) return;
|
|
792
|
+
selectionAnchor.current = rowKey(row);
|
|
793
|
+
selection.onToggle(row, !selection.isSelected(row));
|
|
719
794
|
return;
|
|
720
795
|
}
|
|
721
|
-
if (e.
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
"border-t border-subtle",
|
|
726
|
-
rowInteractive && "cursor-pointer hover:bg-hover",
|
|
727
|
-
// The kit's focus frame width (§5, `--focus-ring-width`), drawn as an
|
|
728
|
-
// OUTLINE rather than FOCUS_RING's box-shadow: a shadow on a `<tr>`
|
|
729
|
-
// is not painted by every engine, an outline is.
|
|
730
|
-
rowsFocusable && "focus-visible:bg-hover focus-visible:outline-focus focus-visible:-outline-offset-2 focus-visible:outline-brand",
|
|
731
|
-
rowClassName?.(row)
|
|
732
|
-
),
|
|
733
|
-
onClick: rowInteractive ? (e) => {
|
|
734
|
-
if (fromOwnControl(e.target, e.currentTarget)) return;
|
|
735
|
-
if (fromOutside(e.target, e.currentTarget)) return;
|
|
736
|
-
if (selection && canSelect(row)) {
|
|
737
|
-
if (e.shiftKey) {
|
|
738
|
-
window.getSelection?.()?.removeAllRanges();
|
|
739
|
-
if (selectRange(rowIndex)) return;
|
|
740
|
-
selectionAnchor.current = rowKey(row);
|
|
741
|
-
selection.onToggle(row, !selection.isSelected(row));
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
if (e.metaKey || e.ctrlKey) {
|
|
745
|
-
selectionAnchor.current = rowKey(row);
|
|
746
|
-
selection.onToggle(row, !selection.isSelected(row));
|
|
747
|
-
return;
|
|
748
|
-
}
|
|
796
|
+
if (e.metaKey || e.ctrlKey) {
|
|
797
|
+
selectionAnchor.current = rowKey(row);
|
|
798
|
+
selection.onToggle(row, !selection.isSelected(row));
|
|
799
|
+
return;
|
|
749
800
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
801
|
+
}
|
|
802
|
+
onRowClick?.(row);
|
|
803
|
+
} : void 0,
|
|
804
|
+
children: [
|
|
805
|
+
selection && /* @__PURE__ */ jsx(
|
|
806
|
+
"td",
|
|
807
|
+
{
|
|
808
|
+
className: cn("align-top", compact ? "w-8 px-2 py-1" : "w-10 px-3 py-2"),
|
|
809
|
+
onClick: (e) => e.stopPropagation(),
|
|
810
|
+
children: canSelect(row) && /* @__PURE__ */ jsx(
|
|
811
|
+
"input",
|
|
812
|
+
{
|
|
813
|
+
type: "checkbox",
|
|
814
|
+
className: cn("accent-indigo-600", compact ? "size-3.5" : "size-4"),
|
|
815
|
+
checked: selection.isSelected(row),
|
|
816
|
+
onClick: (e) => {
|
|
817
|
+
if (e.shiftKey && selectRange(rowIndex)) {
|
|
818
|
+
e.preventDefault();
|
|
819
|
+
rangeClick.current = e.nativeEvent;
|
|
820
|
+
}
|
|
821
|
+
},
|
|
822
|
+
onChange: (e) => {
|
|
823
|
+
if (rangeClick.current && e.nativeEvent === rangeClick.current) {
|
|
824
|
+
rangeClick.current = null;
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
selectionAnchor.current = rowKey(row);
|
|
828
|
+
selection.onToggle(row, e.target.checked);
|
|
829
|
+
},
|
|
830
|
+
"aria-label": labels.selectRow
|
|
831
|
+
}
|
|
832
|
+
)
|
|
833
|
+
}
|
|
834
|
+
),
|
|
835
|
+
visibleColumns.map((col, colIndex) => {
|
|
836
|
+
const width = widths[col.key];
|
|
837
|
+
const own = splitCellProps(col.cellProps?.(row));
|
|
838
|
+
const pinned = width ? { width, minWidth: width, maxWidth: width } : void 0;
|
|
839
|
+
return /* @__PURE__ */ createElement(
|
|
754
840
|
"td",
|
|
755
841
|
{
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
rangeClick.current = e.nativeEvent;
|
|
768
|
-
}
|
|
769
|
-
},
|
|
770
|
-
onChange: (e) => {
|
|
771
|
-
if (rangeClick.current && e.nativeEvent === rangeClick.current) {
|
|
772
|
-
rangeClick.current = null;
|
|
773
|
-
return;
|
|
774
|
-
}
|
|
775
|
-
selectionAnchor.current = rowKey(row);
|
|
776
|
-
selection.onToggle(row, e.target.checked);
|
|
777
|
-
},
|
|
778
|
-
"aria-label": labels.selectRow
|
|
779
|
-
}
|
|
842
|
+
...own.attrs,
|
|
843
|
+
key: col.key,
|
|
844
|
+
"data-col": col.key,
|
|
845
|
+
style: own.style || pinned ? { ...own.style, ...pinned } : void 0,
|
|
846
|
+
className: cn(
|
|
847
|
+
"align-top",
|
|
848
|
+
compact ? "px-2 py-1" : "px-3 py-2",
|
|
849
|
+
width && "overflow-hidden text-ellipsis",
|
|
850
|
+
col.grow ? GROW_CELL_CLASS : growDrawn && GROW_PEER_CELL_CLASS,
|
|
851
|
+
logicalAlign(own.className),
|
|
852
|
+
logicalAlign(col.className)
|
|
780
853
|
)
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
854
|
+
},
|
|
855
|
+
colIndex === 0 && disclosure,
|
|
856
|
+
col === linkColumn && href ? (
|
|
857
|
+
// No `onActivate`: the click is left to bubble to the
|
|
858
|
+
// <tr> handler above, which already owns expand-vs-select.
|
|
859
|
+
// Calling it here as well would toggle the row twice.
|
|
860
|
+
/* @__PURE__ */ jsx(RowLink, { href, className: "block", "data-row-link": "", children: col.cell(row) })
|
|
861
|
+
) : col.cell(row)
|
|
862
|
+
);
|
|
863
|
+
})
|
|
864
|
+
]
|
|
865
|
+
}
|
|
866
|
+
),
|
|
867
|
+
expansion && /* @__PURE__ */ jsx("tr", { id: disclosure ? detailId : void 0, className: "bg-surface-2 border-t border-subtle", children: /* @__PURE__ */ jsx("td", { colSpan: totalColSpan, className: "p-0", children: /* @__PURE__ */ jsx("div", { className: "w-0 min-w-full", children: /* @__PURE__ */ jsx(
|
|
868
|
+
"div",
|
|
869
|
+
{
|
|
870
|
+
className: cn(
|
|
871
|
+
"sticky start-0 w-[var(--dt-visible-w,100%)] max-w-full",
|
|
872
|
+
compact ? "px-2 py-2" : "px-3 py-3"
|
|
873
|
+
),
|
|
874
|
+
children: expansion
|
|
875
|
+
}
|
|
876
|
+
) }) }) })
|
|
877
|
+
] }, key);
|
|
878
|
+
};
|
|
879
|
+
const emptyRow = slice.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
880
|
+
"td",
|
|
881
|
+
{
|
|
882
|
+
colSpan: totalColSpan,
|
|
883
|
+
className: cn("text-center text-muted", compact ? "px-2 py-2" : "px-3 py-4"),
|
|
884
|
+
children: isLoading ? /* @__PURE__ */ jsx(LoadingText, { label: labels.loading }) : empty ?? labels.empty
|
|
885
|
+
}
|
|
886
|
+
) }) : null;
|
|
887
|
+
if (!desktopGroups) {
|
|
888
|
+
return /* @__PURE__ */ jsxs("tbody", { className: bodyClass, children: [
|
|
889
|
+
leading,
|
|
890
|
+
slice.map(renderRow),
|
|
891
|
+
emptyRow
|
|
892
|
+
] });
|
|
893
|
+
}
|
|
894
|
+
const band = (level, def, g) => /* @__PURE__ */ jsx(
|
|
895
|
+
DataTableGroupBand,
|
|
896
|
+
{
|
|
897
|
+
level,
|
|
898
|
+
colSpan: totalColSpan,
|
|
899
|
+
top: level === 1 ? bandTops[0] : bandTops[1],
|
|
900
|
+
compact,
|
|
901
|
+
label: def.label ? def.label(g.key, g.rows) : g.key,
|
|
902
|
+
end: def.end?.(g.key, g.rows)
|
|
903
|
+
}
|
|
904
|
+
);
|
|
905
|
+
const rowsOf = (g) => g.rows.map((r, i) => renderRow(r, g.start + i));
|
|
906
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
907
|
+
(leading || emptyRow) && /* @__PURE__ */ jsxs("tbody", { className: bodyClass, children: [
|
|
908
|
+
leading,
|
|
909
|
+
emptyRow
|
|
910
|
+
] }),
|
|
911
|
+
desktopGroups.map(
|
|
912
|
+
(g1) => g1.children ? g1.children.map((g2, j) => /* @__PURE__ */ jsxs("tbody", { className: bodyClass, children: [
|
|
913
|
+
j === 0 && band(1, levels[0], g1),
|
|
914
|
+
band(2, levels[1], g2),
|
|
915
|
+
rowsOf(g2)
|
|
916
|
+
] }, `g:${g1.key}:${g2.key}:${g2.start}`)) : /* @__PURE__ */ jsxs("tbody", { className: bodyClass, children: [
|
|
917
|
+
band(1, levels[0], g1),
|
|
918
|
+
rowsOf(g1)
|
|
919
|
+
] }, `g:${g1.key}:${g1.start}`)
|
|
920
|
+
)
|
|
921
|
+
] });
|
|
922
|
+
})(),
|
|
923
|
+
showFooter && // Sticky to the scroller's bottom edge for the same reason the header is
|
|
924
|
+
// sticky to its top: the body scrolls inside a bounded wrapper, and a
|
|
925
|
+
// total that scrolls away with the last row is a total nobody sees on a
|
|
926
|
+
// 25-row page. Each cell carries its own background and its own `sticky`,
|
|
927
|
+
// as the header's do — `position: sticky` on a `<tfoot>` is not reliable.
|
|
928
|
+
/* @__PURE__ */ jsx(
|
|
929
|
+
"tfoot",
|
|
930
|
+
{
|
|
931
|
+
"data-table-footer": "",
|
|
932
|
+
className: cn(
|
|
933
|
+
"font-semibold text-primary",
|
|
934
|
+
isLoading && "opacity-60 transition-opacity"
|
|
859
935
|
),
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
const isLabel = col === footerLabelCol;
|
|
864
|
-
const Cell = isLabel ? "th" : "td";
|
|
865
|
-
return /* @__PURE__ */ jsx(
|
|
866
|
-
Cell,
|
|
936
|
+
children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
937
|
+
selection && /* @__PURE__ */ jsx(
|
|
938
|
+
"td",
|
|
867
939
|
{
|
|
868
|
-
"data-col": col.key,
|
|
869
|
-
scope: isLabel ? "row" : void 0,
|
|
870
|
-
style: pinned,
|
|
871
940
|
className: cn(
|
|
872
941
|
FOOTER_CELL,
|
|
873
|
-
"
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
942
|
+
compact ? "w-8 px-2 py-1" : "w-10 px-3 py-2"
|
|
943
|
+
)
|
|
944
|
+
}
|
|
945
|
+
),
|
|
946
|
+
visibleColumns.map((col) => {
|
|
947
|
+
const width = widths[col.key];
|
|
948
|
+
const pinned = width ? { width, minWidth: width, maxWidth: width } : void 0;
|
|
949
|
+
const isLabel = col === footerLabelCol;
|
|
950
|
+
const Cell = isLabel ? "th" : "td";
|
|
951
|
+
return /* @__PURE__ */ jsx(
|
|
952
|
+
Cell,
|
|
953
|
+
{
|
|
954
|
+
"data-col": col.key,
|
|
955
|
+
scope: isLabel ? "row" : void 0,
|
|
956
|
+
style: pinned,
|
|
957
|
+
className: cn(
|
|
958
|
+
FOOTER_CELL,
|
|
959
|
+
"align-top",
|
|
960
|
+
compact ? "px-2 py-1" : "px-3 py-2",
|
|
961
|
+
width && "overflow-hidden text-ellipsis",
|
|
962
|
+
// A `<th>` centres by default; the label reads from the start
|
|
963
|
+
// like the cells above it, unless the column says otherwise.
|
|
964
|
+
isLabel && "text-start",
|
|
965
|
+
col.grow ? GROW_CELL_CLASS : growDrawn && GROW_PEER_CELL_CLASS,
|
|
966
|
+
logicalAlign(col.className)
|
|
967
|
+
),
|
|
968
|
+
children: col.footer ? footerValue(col) : isLabel ? footerLabel : null
|
|
969
|
+
},
|
|
970
|
+
col.key
|
|
971
|
+
);
|
|
972
|
+
})
|
|
973
|
+
] })
|
|
974
|
+
}
|
|
975
|
+
)
|
|
976
|
+
]
|
|
977
|
+
}
|
|
978
|
+
),
|
|
979
|
+
loadMore && /* @__PURE__ */ jsx(DataTableLoadMoreFooter, { loadMore, rowCount: sorted.length, labels, compact })
|
|
980
|
+
]
|
|
892
981
|
}
|
|
893
982
|
),
|
|
894
|
-
!unpaged && /* @__PURE__ */ jsx(
|
|
983
|
+
!unpaged && !loadMore && /* @__PURE__ */ jsx(
|
|
895
984
|
Pagination,
|
|
896
985
|
{
|
|
897
986
|
page: safePage,
|
|
@@ -916,6 +1005,8 @@ function DataTable({
|
|
|
916
1005
|
columns,
|
|
917
1006
|
hiddenCols,
|
|
918
1007
|
setHiddenCols,
|
|
1008
|
+
autoHidden,
|
|
1009
|
+
keepColumn,
|
|
919
1010
|
showSettings,
|
|
920
1011
|
setShowSettings,
|
|
921
1012
|
columnsCountLabel,
|