@datum-cloud/datum-ui 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/features/data-table/types.d.ts +6 -0
- package/dist/components/features/grouped-table/components/grouped-collapsible-body.d.ts +18 -0
- package/dist/data-table/index.mjs +1 -1
- package/dist/{data-table-Du7_FLBi.mjs → data-table-ClfRpyHq.mjs} +25 -5
- package/dist/grouped-table/index.mjs +1 -1
- package/dist/{grouped-table-Dldsvwz6.mjs → grouped-table-Bb9KoI1e.mjs} +53 -8
- package/dist/index.mjs +2 -2
- package/dist/table/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -333,4 +333,10 @@ export interface CreateStoreOptions<TData extends RowData> {
|
|
|
333
333
|
readonly filterFns?: FilterFnMap;
|
|
334
334
|
readonly isLoading?: boolean;
|
|
335
335
|
readonly columnCount?: number;
|
|
336
|
+
/**
|
|
337
|
+
* Row identity, used to reconcile `rowSelection` across data changes.
|
|
338
|
+
* When omitted, TanStack falls back to array-index ids, which are
|
|
339
|
+
* meaningless across a data change — so selection is cleared instead.
|
|
340
|
+
*/
|
|
341
|
+
readonly getRowId?: (row: TData) => string;
|
|
336
342
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Height animation for a group body. Do not use Radix CollapsibleContent:
|
|
4
|
+
* it measures `--radix-collapsible-content-height` with getBoundingClientRect,
|
|
5
|
+
* and later groups inside `overflow-x-auto` often measure as 0px.
|
|
6
|
+
*
|
|
7
|
+
* Keep this node mounted. AnimatePresence exit from `height: auto` has to
|
|
8
|
+
* measure on the way out, which is the beat of delay after a click.
|
|
9
|
+
* `initial={false}` skips the enter animation for groups that start open.
|
|
10
|
+
*
|
|
11
|
+
* Overflow stays hidden. The header/body divider is a 1px rule inside this
|
|
12
|
+
* wrapper, not a row `border-t`, so it is not clipped.
|
|
13
|
+
*/
|
|
14
|
+
export declare function GroupedCollapsibleBody({ open, reduceMotion, children, }: {
|
|
15
|
+
open: boolean;
|
|
16
|
+
reduceMotion: boolean;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as useNuqsAdapter, a as useDataTablePagination, b as DEFAULT_PAGE_SIZE, c as useDataTableSelection, d as resolvePath, f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, i as useDataTableLoading, l as useDataTableSorting, m as DataTableRowActions, n as useDataTableFilters, o as useDataTableRows, p as dataTableFeatures, r as useDataTableInlineContents, s as useDataTableSearch, t as DataTable, u as createDataTableStore, v as DEFAULT_DEBOUNCE_MS, x as DEFAULT_PAGE_SIZES, y as DEFAULT_LOADING_ROWS } from "../data-table-
|
|
1
|
+
import { _ as useNuqsAdapter, a as useDataTablePagination, b as DEFAULT_PAGE_SIZE, c as useDataTableSelection, d as resolvePath, f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, i as useDataTableLoading, l as useDataTableSorting, m as DataTableRowActions, n as useDataTableFilters, o as useDataTableRows, p as dataTableFeatures, r as useDataTableInlineContents, s as useDataTableSearch, t as DataTable, u as createDataTableStore, v as DEFAULT_DEBOUNCE_MS, x as DEFAULT_PAGE_SIZES, y as DEFAULT_LOADING_ROWS } from "../data-table-ClfRpyHq.mjs";
|
|
2
2
|
export { DEFAULT_DEBOUNCE_MS, DEFAULT_LOADING_ROWS, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZES, DataTable, DataTableColumnHeader, DataTableRowActions, createDataTableStore, createSelectionColumn, dataTableFeatures, resolvePath, rowMatchesSearch, useDataTableFilters, useDataTableInlineContents, useDataTableLoading, useDataTablePagination, useDataTableRows, useDataTableSearch, useDataTableSelection, useDataTableSorting, useNuqsAdapter };
|
|
@@ -313,6 +313,20 @@ function applyFilters(data, filters, search, registeredFilters, customFilterFns,
|
|
|
313
313
|
}
|
|
314
314
|
//#endregion
|
|
315
315
|
//#region src/components/features/data-table/core/store.ts
|
|
316
|
+
/**
|
|
317
|
+
* Keep only the selection keys whose rows survive a data change.
|
|
318
|
+
* Dropping vanished keys stops a deleted row's selection from
|
|
319
|
+
* resurrecting if a row with the same id reappears later.
|
|
320
|
+
*/
|
|
321
|
+
function pruneSelection(selection, rows, getRowId) {
|
|
322
|
+
const keys = Object.keys(selection);
|
|
323
|
+
if (keys.length === 0) return selection;
|
|
324
|
+
const surviving = /* @__PURE__ */ new Set();
|
|
325
|
+
for (const row of rows) surviving.add(getRowId(row));
|
|
326
|
+
const next = {};
|
|
327
|
+
for (const key of keys) if (selection[key] && surviving.has(key)) next[key] = true;
|
|
328
|
+
return next;
|
|
329
|
+
}
|
|
316
330
|
function createDataTableStore(options) {
|
|
317
331
|
let registeredFilters = /* @__PURE__ */ new Map();
|
|
318
332
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -362,13 +376,17 @@ function createDataTableStore(options) {
|
|
|
362
376
|
setData: (data) => {
|
|
363
377
|
const next = {
|
|
364
378
|
...state,
|
|
365
|
-
data
|
|
366
|
-
pageIndex: 0,
|
|
367
|
-
rowSelection: {}
|
|
379
|
+
data
|
|
368
380
|
};
|
|
381
|
+
const filteredData = computeFilteredData(next);
|
|
382
|
+
const pageCount = Math.max(1, Math.ceil(filteredData.length / state.pageSize));
|
|
383
|
+
const pageIndex = Math.min(state.pageIndex, pageCount - 1);
|
|
384
|
+
const rowSelection = options.getRowId ? pruneSelection(state.rowSelection, filteredData, options.getRowId) : {};
|
|
369
385
|
setState({
|
|
370
386
|
...next,
|
|
371
|
-
filteredData
|
|
387
|
+
filteredData,
|
|
388
|
+
pageIndex,
|
|
389
|
+
rowSelection
|
|
372
390
|
});
|
|
373
391
|
},
|
|
374
392
|
setServerData: (data) => {
|
|
@@ -1168,6 +1186,7 @@ function useClientTable(store, options) {
|
|
|
1168
1186
|
}) : updater;
|
|
1169
1187
|
store.setPagination(next.pageIndex, next.pageSize);
|
|
1170
1188
|
},
|
|
1189
|
+
autoResetPageIndex: false,
|
|
1171
1190
|
getRowId,
|
|
1172
1191
|
enableRowSelection: !!enableRowSelection
|
|
1173
1192
|
});
|
|
@@ -1239,7 +1258,8 @@ function ClientProvider(props) {
|
|
|
1239
1258
|
columnCount: columns.length,
|
|
1240
1259
|
searchableColumns,
|
|
1241
1260
|
searchFn,
|
|
1242
|
-
filterFns
|
|
1261
|
+
filterFns,
|
|
1262
|
+
getRowId
|
|
1243
1263
|
}), []);
|
|
1244
1264
|
const isInitialRender = useRef(true);
|
|
1245
1265
|
useEffect(() => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as GroupedTable } from "../grouped-table-
|
|
1
|
+
import { t as GroupedTable } from "../grouped-table-Bb9KoI1e.mjs";
|
|
2
2
|
export { GroupedTable };
|
|
@@ -1,17 +1,56 @@
|
|
|
1
1
|
import { t as cn } from "./utils-Bu32wN-x.mjs";
|
|
2
2
|
import { t as Button } from "./button-A1qTjZ8U.mjs";
|
|
3
3
|
import { t as Icon } from "./icon-wrapper-DKfJlJd0.mjs";
|
|
4
|
-
import { Collapsible,
|
|
4
|
+
import { Collapsible, CollapsibleTrigger } from "./collapsible/index.mjs";
|
|
5
5
|
import { t as useControllableState } from "./use-controllable-state-Dna7u3r9.mjs";
|
|
6
6
|
import { Skeleton } from "./skeleton/index.mjs";
|
|
7
7
|
import { TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table/index.mjs";
|
|
8
|
-
import { f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, m as DataTableRowActions, p as dataTableFeatures } from "./data-table-
|
|
8
|
+
import { f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, m as DataTableRowActions, p as dataTableFeatures } from "./data-table-ClfRpyHq.mjs";
|
|
9
9
|
import { n as useDebouncedSearchInput } from "./use-debounced-search-input-yu_F0QBt.mjs";
|
|
10
10
|
import { InputWithAddons } from "./input-with-addons/index.mjs";
|
|
11
11
|
import { ChevronRight, Search, X } from "lucide-react";
|
|
12
12
|
import { useCallback, useMemo, useState } from "react";
|
|
13
13
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { motion, useReducedMotion } from "motion/react";
|
|
14
15
|
import { flexRender, useTable } from "@tanstack/react-table";
|
|
16
|
+
//#region src/components/features/grouped-table/components/grouped-collapsible-body.tsx
|
|
17
|
+
const OPEN_TRANSITION = {
|
|
18
|
+
duration: .18,
|
|
19
|
+
ease: [
|
|
20
|
+
.23,
|
|
21
|
+
1,
|
|
22
|
+
.32,
|
|
23
|
+
1
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
const INSTANT = { duration: 0 };
|
|
27
|
+
/**
|
|
28
|
+
* Height animation for a group body. Do not use Radix CollapsibleContent:
|
|
29
|
+
* it measures `--radix-collapsible-content-height` with getBoundingClientRect,
|
|
30
|
+
* and later groups inside `overflow-x-auto` often measure as 0px.
|
|
31
|
+
*
|
|
32
|
+
* Keep this node mounted. AnimatePresence exit from `height: auto` has to
|
|
33
|
+
* measure on the way out, which is the beat of delay after a click.
|
|
34
|
+
* `initial={false}` skips the enter animation for groups that start open.
|
|
35
|
+
*
|
|
36
|
+
* Overflow stays hidden. The header/body divider is a 1px rule inside this
|
|
37
|
+
* wrapper, not a row `border-t`, so it is not clipped.
|
|
38
|
+
*/
|
|
39
|
+
function GroupedCollapsibleBody({ open, reduceMotion, children }) {
|
|
40
|
+
return /* @__PURE__ */ jsxs(motion.div, {
|
|
41
|
+
"data-slot": "grouped-table-group-content",
|
|
42
|
+
initial: false,
|
|
43
|
+
animate: { height: open ? "auto" : 0 },
|
|
44
|
+
transition: reduceMotion ? INSTANT : OPEN_TRANSITION,
|
|
45
|
+
className: "overflow-hidden",
|
|
46
|
+
inert: !open,
|
|
47
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
48
|
+
"data-slot": "grouped-table-group-rule",
|
|
49
|
+
className: "bg-border h-px"
|
|
50
|
+
}), children]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
15
54
|
//#region src/components/features/grouped-table/components/grouped-skeleton.tsx
|
|
16
55
|
function GroupedSkeleton({ columns = 4, groups = 2, rowsPerGroup = 3 }) {
|
|
17
56
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -228,6 +267,7 @@ function GroupedTable(props) {
|
|
|
228
267
|
expanded,
|
|
229
268
|
onExpandedChange
|
|
230
269
|
});
|
|
270
|
+
const reduceMotion = Boolean(useReducedMotion());
|
|
231
271
|
const resolvedColumns = useMemo(() => composeColumns(columns, {
|
|
232
272
|
enableRowSelection,
|
|
233
273
|
enableSorting,
|
|
@@ -249,7 +289,11 @@ function GroupedTable(props) {
|
|
|
249
289
|
state: {
|
|
250
290
|
sorting,
|
|
251
291
|
rowSelection,
|
|
252
|
-
globalFilter: search
|
|
292
|
+
globalFilter: search,
|
|
293
|
+
pagination: {
|
|
294
|
+
pageIndex: 0,
|
|
295
|
+
pageSize: Math.max(flatData.length, 1)
|
|
296
|
+
}
|
|
253
297
|
},
|
|
254
298
|
onSortingChange: setSorting,
|
|
255
299
|
onRowSelectionChange: setRowSelection,
|
|
@@ -265,7 +309,7 @@ function GroupedTable(props) {
|
|
|
265
309
|
});
|
|
266
310
|
const headerGroups = table.getHeaderGroups();
|
|
267
311
|
const coreRows = table.getCoreRowModel().rows;
|
|
268
|
-
const filteredRows = table.
|
|
312
|
+
const filteredRows = table.getFilteredRowModel().rows;
|
|
269
313
|
const buckets = useMemo(() => bucketRows(groups, coreRows, filteredRows), [
|
|
270
314
|
groups,
|
|
271
315
|
coreRows,
|
|
@@ -334,8 +378,9 @@ function GroupedTable(props) {
|
|
|
334
378
|
children: slice.meta
|
|
335
379
|
})
|
|
336
380
|
]
|
|
337
|
-
}), /* @__PURE__ */ jsx(
|
|
338
|
-
|
|
381
|
+
}), /* @__PURE__ */ jsx(GroupedCollapsibleBody, {
|
|
382
|
+
open,
|
|
383
|
+
reduceMotion,
|
|
339
384
|
children: /* @__PURE__ */ jsxs("table", {
|
|
340
385
|
className: cn("w-full table-fixed text-sm", tableClassName),
|
|
341
386
|
"aria-label": typeof slice.title === "string" ? slice.title : void 0,
|
|
@@ -350,9 +395,9 @@ function GroupedTable(props) {
|
|
|
350
395
|
}),
|
|
351
396
|
/* @__PURE__ */ jsx(TableBody, {
|
|
352
397
|
className: bodyClassName,
|
|
353
|
-
children: slice.rows.map((row
|
|
398
|
+
children: slice.rows.map((row) => /* @__PURE__ */ jsx(TableRow, {
|
|
354
399
|
"data-state": row.getIsSelected() ? "selected" : void 0,
|
|
355
|
-
className:
|
|
400
|
+
className: resolveClassName(rowClassName, row),
|
|
356
401
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, {
|
|
357
402
|
className: resolveClassName(cellClassName, cell),
|
|
358
403
|
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
package/dist/index.mjs
CHANGED
|
@@ -53,7 +53,7 @@ import { i as ClientOnly, n as useTheme, r as ThemeScript, t as ThemeProvider }
|
|
|
53
53
|
import { a as formatJson, c as isValidYaml, d as CodeEditor, i as CodeEditorTabs, l as jsonToYaml, n as jsonSchema, o as formatYaml, r as yamlSchema, s as isValidJson, t as createCodeEditorSchema, u as yamlToJson } from "./types-agDpVXBG.mjs";
|
|
54
54
|
import { t as toast } from "./toast-BUPlDkN3.mjs";
|
|
55
55
|
import { n as Toaster, t as useToast } from "./use-toast-Bpq0yJIT.mjs";
|
|
56
|
-
import { _ as useNuqsAdapter, a as useDataTablePagination, b as DEFAULT_PAGE_SIZE, c as useDataTableSelection, d as resolvePath, f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, i as useDataTableLoading, l as useDataTableSorting, m as DataTableRowActions, n as useDataTableFilters, o as useDataTableRows, p as dataTableFeatures, r as useDataTableInlineContents, s as useDataTableSearch, t as DataTable, u as createDataTableStore, v as DEFAULT_DEBOUNCE_MS, x as DEFAULT_PAGE_SIZES, y as DEFAULT_LOADING_ROWS } from "./data-table-
|
|
56
|
+
import { _ as useNuqsAdapter, a as useDataTablePagination, b as DEFAULT_PAGE_SIZE, c as useDataTableSelection, d as resolvePath, f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, i as useDataTableLoading, l as useDataTableSorting, m as DataTableRowActions, n as useDataTableFilters, o as useDataTableRows, p as dataTableFeatures, r as useDataTableInlineContents, s as useDataTableSearch, t as DataTable, u as createDataTableStore, v as DEFAULT_DEBOUNCE_MS, x as DEFAULT_PAGE_SIZES, y as DEFAULT_LOADING_ROWS } from "./data-table-ClfRpyHq.mjs";
|
|
57
57
|
import { t as ActionRow } from "./action-row-DTvs91_3.mjs";
|
|
58
58
|
import { n as useDebouncedSearchInput, t as DEFAULT_SEARCH_DEBOUNCE_MS } from "./use-debounced-search-input-yu_F0QBt.mjs";
|
|
59
59
|
import { t as MultiSelect } from "./multi-select-PtdMChPF.mjs";
|
|
@@ -69,7 +69,7 @@ import { InputWithAddons } from "./input-with-addons/index.mjs";
|
|
|
69
69
|
import { t as TimePicker } from "./time-picker-CFhaHTtI.mjs";
|
|
70
70
|
import { t as Transfer } from "./transfer-CEq9AhL7.mjs";
|
|
71
71
|
import { a as getResponsiveValue, c as GRID_COLUMNS, d as RESPONSIVE_MAP, i as getGutter, l as GRID_PREFIX, n as Row, o as registerMediaQuery, r as RowContext, s as GRID_BREAKPOINTS, t as Col, u as RESPONSIVE_ARRAY } from "./col-BYGWTB4j.mjs";
|
|
72
|
-
import { t as GroupedTable } from "./grouped-table-
|
|
72
|
+
import { t as GroupedTable } from "./grouped-table-Bb9KoI1e.mjs";
|
|
73
73
|
import { t as InputNumber } from "./input-number-TXmW-X9o.mjs";
|
|
74
74
|
import { a as logoStyles, i as LogoFlat, n as LogoStacked, r as LogoIcon, t as LogoText } from "./logo-text-Dpm5O6Kg.mjs";
|
|
75
75
|
import { t as Logo } from "./logo-C3FxD7jb.mjs";
|
package/dist/table/index.mjs
CHANGED
|
@@ -23,7 +23,7 @@ function TableHeader({ className, ...props }) {
|
|
|
23
23
|
function TableBody({ className, ...props }) {
|
|
24
24
|
return /* @__PURE__ */ jsx("tbody", {
|
|
25
25
|
"data-slot": "table-body",
|
|
26
|
-
className: cn("[&_tr:last-child]:border-0", className),
|
|
26
|
+
className: cn("[&_tr:last-child]:border-b-0", className),
|
|
27
27
|
...props
|
|
28
28
|
});
|
|
29
29
|
}
|