@datum-cloud/datum-ui 1.0.0 → 1.2.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/core/filter-engine.d.ts +5 -2
- package/dist/components/features/data-table/core/filter-engine.d.ts.map +1 -1
- package/dist/components/features/data-table/index.d.ts +4 -0
- package/dist/components/features/data-table/index.d.ts.map +1 -1
- package/dist/components/features/grouped-table/components/grouped-skeleton.d.ts +7 -0
- package/dist/components/features/grouped-table/components/grouped-skeleton.d.ts.map +1 -0
- package/dist/components/features/grouped-table/components/grouped-toolbar.d.ts +9 -0
- package/dist/components/features/grouped-table/components/grouped-toolbar.d.ts.map +1 -0
- package/dist/components/features/grouped-table/grouped-table.d.ts +3 -0
- package/dist/components/features/grouped-table/grouped-table.d.ts.map +1 -0
- package/dist/components/features/grouped-table/index.d.ts +3 -0
- package/dist/components/features/grouped-table/index.d.ts.map +1 -0
- package/dist/components/features/grouped-table/lib/bucket-rows.d.ts +14 -0
- package/dist/components/features/grouped-table/lib/bucket-rows.d.ts.map +1 -0
- package/dist/components/features/grouped-table/lib/compose-columns.d.ts +11 -0
- package/dist/components/features/grouped-table/lib/compose-columns.d.ts.map +1 -0
- package/dist/components/features/grouped-table/lib/sort-rows.d.ts +7 -0
- package/dist/components/features/grouped-table/lib/sort-rows.d.ts.map +1 -0
- package/dist/components/features/grouped-table/lib/use-controllable-state.d.ts +8 -0
- package/dist/components/features/grouped-table/lib/use-controllable-state.d.ts.map +1 -0
- package/dist/components/features/grouped-table/types.d.ts +74 -0
- package/dist/components/features/grouped-table/types.d.ts.map +1 -0
- package/dist/components/features/grouped-table/use-grouped-expansion.d.ts +10 -0
- package/dist/components/features/grouped-table/use-grouped-expansion.d.ts.map +1 -0
- package/dist/data-table/index.mjs +2 -1588
- package/dist/data-table-BTIxzB7O.mjs +1588 -0
- package/dist/grouped-table/index.mjs +352 -0
- package/package.json +8 -3
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { t as cn } from "../cn-dlASUkDY.mjs";
|
|
2
|
+
import { t as Icon } from "../icon-wrapper-DKfJlJd0.mjs";
|
|
3
|
+
import { n as CollapsibleContent, r as CollapsibleTrigger, t as Collapsible } from "../collapsible-BeCdkxTJ.mjs";
|
|
4
|
+
import { t as Input } from "../input-DBzgl-pN.mjs";
|
|
5
|
+
import { t as Skeleton } from "../skeleton-CGU89HPB.mjs";
|
|
6
|
+
import { c as TableRow, i as TableCell, n as TableBody, o as TableHead, s as TableHeader } from "../table-BR3mwU8X.mjs";
|
|
7
|
+
import { f as rowMatchesSearch, h as createSelectionColumn, m as DataTableColumnHeader, p as DataTableRowActions } from "../data-table-BTIxzB7O.mjs";
|
|
8
|
+
import { ChevronRight } from "lucide-react";
|
|
9
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
10
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { flexRender, getCoreRowModel, getFilteredRowModel, useReactTable } from "@tanstack/react-table";
|
|
12
|
+
//#region src/components/features/grouped-table/components/grouped-skeleton.tsx
|
|
13
|
+
function GroupedSkeleton({ columns = 4, groups = 2, rowsPerGroup = 3 }) {
|
|
14
|
+
return /* @__PURE__ */ jsx("div", {
|
|
15
|
+
"data-slot": "gt-skeleton",
|
|
16
|
+
children: Array.from({ length: groups }, (_, g) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
17
|
+
"data-slot": "gt-skeleton-band",
|
|
18
|
+
className: "flex items-center gap-2 bg-muted/40 px-3 py-2 [&:not(:first-child)]:border-t",
|
|
19
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "size-4 rounded" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" })]
|
|
20
|
+
}), Array.from({ length: rowsPerGroup }, (_, r) => /* @__PURE__ */ jsx("div", {
|
|
21
|
+
"data-slot": "gt-skeleton-row",
|
|
22
|
+
className: "flex items-center gap-3 px-3 py-2 [&:not(:last-child)]:border-b",
|
|
23
|
+
children: Array.from({ length: columns }, (_, c) => /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }, c))
|
|
24
|
+
}, r))] }, g))
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/components/features/grouped-table/components/grouped-toolbar.tsx
|
|
29
|
+
const DEFAULT_DEBOUNCE_MS = 300;
|
|
30
|
+
function GroupedToolbar({ search, onSearchChange, placeholder = "Search...", debounceMs = DEFAULT_DEBOUNCE_MS, className }) {
|
|
31
|
+
const [value, setValue] = useState(search);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setValue(search);
|
|
34
|
+
}, [search]);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const timer = setTimeout(() => {
|
|
37
|
+
if (value !== search) onSearchChange(value);
|
|
38
|
+
}, debounceMs);
|
|
39
|
+
return () => clearTimeout(timer);
|
|
40
|
+
}, [
|
|
41
|
+
value,
|
|
42
|
+
debounceMs,
|
|
43
|
+
search,
|
|
44
|
+
onSearchChange
|
|
45
|
+
]);
|
|
46
|
+
return /* @__PURE__ */ jsx("div", {
|
|
47
|
+
className: cn("pb-3", className),
|
|
48
|
+
"data-slot": "gt-toolbar",
|
|
49
|
+
children: /* @__PURE__ */ jsx(Input, {
|
|
50
|
+
placeholder,
|
|
51
|
+
value,
|
|
52
|
+
onChange: (e) => setValue(e.target.value),
|
|
53
|
+
"aria-label": placeholder,
|
|
54
|
+
"data-slot": "gt-search"
|
|
55
|
+
})
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/components/features/grouped-table/lib/bucket-rows.ts
|
|
60
|
+
/**
|
|
61
|
+
* Build per-group buckets of `filteredRows`, preserving the filtered order.
|
|
62
|
+
* `coreRows` are the unfiltered rows in group-concatenated order; we use their
|
|
63
|
+
* positions to learn which row id belongs to which group, so bucketing is correct
|
|
64
|
+
* regardless of a custom getRowId.
|
|
65
|
+
*/
|
|
66
|
+
function bucketRows(groups, coreRows, filteredRows) {
|
|
67
|
+
const idToGroup = /* @__PURE__ */ new Map();
|
|
68
|
+
let offset = 0;
|
|
69
|
+
for (const group of groups) {
|
|
70
|
+
for (let i = 0; i < group.rows.length; i++) {
|
|
71
|
+
const core = coreRows[offset + i];
|
|
72
|
+
if (core) idToGroup.set(core.id, group.id);
|
|
73
|
+
}
|
|
74
|
+
offset += group.rows.length;
|
|
75
|
+
}
|
|
76
|
+
const buckets = new Map(groups.map((g) => [g.id, []]));
|
|
77
|
+
for (const row of filteredRows) {
|
|
78
|
+
const groupId = idToGroup.get(row.id);
|
|
79
|
+
if (groupId) buckets.get(groupId).push(row);
|
|
80
|
+
}
|
|
81
|
+
return buckets;
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/components/features/grouped-table/lib/compose-columns.tsx
|
|
85
|
+
/** Wrap plain string headers in the sortable header; leave all other columns untouched. */
|
|
86
|
+
function withSortableHeaders(columns) {
|
|
87
|
+
return columns.map((col) => {
|
|
88
|
+
if (typeof col.header !== "string") return col;
|
|
89
|
+
const title = col.header;
|
|
90
|
+
return {
|
|
91
|
+
...col,
|
|
92
|
+
enableSorting: col.enableSorting ?? true,
|
|
93
|
+
header: ({ column }) => /* @__PURE__ */ jsx(DataTableColumnHeader, {
|
|
94
|
+
column,
|
|
95
|
+
title
|
|
96
|
+
})
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function composeColumns(columns, options) {
|
|
101
|
+
const { enableRowSelection, enableSorting, rowActions, rowActionsSheetTitle } = options;
|
|
102
|
+
let cols = columns;
|
|
103
|
+
if (enableSorting) cols = withSortableHeaders(cols);
|
|
104
|
+
if (enableRowSelection) cols = [createSelectionColumn(typeof enableRowSelection === "object" ? enableRowSelection : {}), ...cols];
|
|
105
|
+
if (rowActions) cols = [...cols, {
|
|
106
|
+
id: "actions",
|
|
107
|
+
size: 44,
|
|
108
|
+
enableSorting: false,
|
|
109
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(DataTableRowActions, {
|
|
110
|
+
row,
|
|
111
|
+
actions: rowActions(row.original),
|
|
112
|
+
sheetTitle: rowActionsSheetTitle
|
|
113
|
+
})
|
|
114
|
+
}];
|
|
115
|
+
return cols;
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/components/features/grouped-table/lib/sort-rows.ts
|
|
119
|
+
function compare(a, b) {
|
|
120
|
+
if (a == null && b == null) return 0;
|
|
121
|
+
if (a == null) return -1;
|
|
122
|
+
if (b == null) return 1;
|
|
123
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
124
|
+
return String(a).localeCompare(String(b));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Sort a single group's rows by the active sort (first entry; v1 is single-sort).
|
|
128
|
+
* Returns the same reference when there is no sort, so React can skip re-renders.
|
|
129
|
+
*/
|
|
130
|
+
function sortRows(rows, sorting) {
|
|
131
|
+
if (sorting.length === 0) return rows;
|
|
132
|
+
const { id, desc } = sorting[0];
|
|
133
|
+
const sorted = [...rows].sort((ra, rb) => compare(ra.getValue(id), rb.getValue(id)));
|
|
134
|
+
if (desc) sorted.reverse();
|
|
135
|
+
return sorted;
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/components/features/grouped-table/lib/use-controllable-state.ts
|
|
139
|
+
/**
|
|
140
|
+
* Uncontrolled-by-default state with an optional controlled override.
|
|
141
|
+
* When `controlled` is undefined the hook owns the value; otherwise the prop wins.
|
|
142
|
+
* `onChange` always fires. Accepts TanStack-style updater functions.
|
|
143
|
+
*/
|
|
144
|
+
function useControllableState(controlled, defaultValue, onChange) {
|
|
145
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
146
|
+
const isControlled = controlled !== void 0;
|
|
147
|
+
const value = isControlled ? controlled : internal;
|
|
148
|
+
return [value, useCallback((next) => {
|
|
149
|
+
const resolved = typeof next === "function" ? next(value) : next;
|
|
150
|
+
if (!isControlled) setInternal(resolved);
|
|
151
|
+
onChange?.(resolved);
|
|
152
|
+
}, [
|
|
153
|
+
isControlled,
|
|
154
|
+
onChange,
|
|
155
|
+
value
|
|
156
|
+
])];
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/components/features/grouped-table/use-grouped-expansion.ts
|
|
160
|
+
function defaultFor(group, def) {
|
|
161
|
+
const fallback = def === "all" ? true : def === "none" ? false : Array.isArray(def) ? def.includes(group.id) : true;
|
|
162
|
+
return group.defaultOpen ?? fallback;
|
|
163
|
+
}
|
|
164
|
+
function useGroupedExpansion(groups, opts) {
|
|
165
|
+
const { defaultExpanded = "all", expanded, onExpandedChange } = opts;
|
|
166
|
+
const controlled = expanded !== void 0;
|
|
167
|
+
const [overrides, setOverrides] = useState({});
|
|
168
|
+
const isOpen = useCallback((id) => {
|
|
169
|
+
if (controlled) return expanded.includes(id);
|
|
170
|
+
if (id in overrides) return overrides[id];
|
|
171
|
+
const g = groups.find((x) => x.id === id);
|
|
172
|
+
return g ? defaultFor(g, defaultExpanded) : false;
|
|
173
|
+
}, [
|
|
174
|
+
controlled,
|
|
175
|
+
expanded,
|
|
176
|
+
overrides,
|
|
177
|
+
groups,
|
|
178
|
+
defaultExpanded
|
|
179
|
+
]);
|
|
180
|
+
return {
|
|
181
|
+
isOpen,
|
|
182
|
+
toggle: useCallback((id) => {
|
|
183
|
+
const now = isOpen(id);
|
|
184
|
+
if (!controlled) setOverrides((o) => ({
|
|
185
|
+
...o,
|
|
186
|
+
[id]: !now
|
|
187
|
+
}));
|
|
188
|
+
const next = groups.filter((g) => g.id === id ? !now : isOpen(g.id)).map((g) => g.id);
|
|
189
|
+
onExpandedChange?.(next);
|
|
190
|
+
}, [
|
|
191
|
+
controlled,
|
|
192
|
+
groups,
|
|
193
|
+
isOpen,
|
|
194
|
+
onExpandedChange
|
|
195
|
+
])
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region src/components/features/grouped-table/grouped-table.tsx
|
|
200
|
+
/** Floor width for unsized (flex) columns so they keep their share instead of collapsing on narrow viewports. */
|
|
201
|
+
const MIN_FLEX_COLUMN_WIDTH = 120;
|
|
202
|
+
function columnWidth(col) {
|
|
203
|
+
return typeof col.size === "number" ? `${col.size}px` : "auto";
|
|
204
|
+
}
|
|
205
|
+
/** Minimum width the table track needs so every column keeps a usable size; below this the area scrolls horizontally. */
|
|
206
|
+
function trackMinWidth(resolvedColumns) {
|
|
207
|
+
return resolvedColumns.reduce((total, col) => total + (typeof col.size === "number" ? col.size : MIN_FLEX_COLUMN_WIDTH), 0);
|
|
208
|
+
}
|
|
209
|
+
function renderColGroup(resolvedColumns) {
|
|
210
|
+
return /* @__PURE__ */ jsx("colgroup", { children: resolvedColumns.map((col, i) => /* @__PURE__ */ jsx("col", { style: { width: columnWidth(col) } }, `col-${i}`)) });
|
|
211
|
+
}
|
|
212
|
+
/** Resolve a static or per-item className override (mirrors data-table). */
|
|
213
|
+
function resolveClassName(value, item) {
|
|
214
|
+
return typeof value === "function" ? value(item) : value;
|
|
215
|
+
}
|
|
216
|
+
function GroupedTable(props) {
|
|
217
|
+
const { columns, groups, defaultExpanded, expanded, onExpandedChange, getRowId, enableRowSelection, rowSelection: rowSelectionProp, onRowSelectionChange, rowActions, rowActionsSheetTitle, enableSorting, sorting: sortingProp, onSortingChange, enableSearch, searchPlaceholder, searchableColumns, searchFn, search: searchProp, onSearchChange, searchDebounceMs, isLoading, empty, className, toolbarClassName, tableClassName, headerRowClassName, headerCellClassName, groupHeaderClassName, bodyClassName, rowClassName, cellClassName } = props;
|
|
218
|
+
const [sorting, setSorting] = useControllableState(sortingProp, [], onSortingChange);
|
|
219
|
+
const [rowSelection, setRowSelection] = useControllableState(rowSelectionProp, {}, onRowSelectionChange);
|
|
220
|
+
const [search, setSearch] = useControllableState(searchProp, "", onSearchChange);
|
|
221
|
+
const isSearching = search.trim().length > 0;
|
|
222
|
+
const { isOpen, toggle } = useGroupedExpansion(groups, {
|
|
223
|
+
defaultExpanded,
|
|
224
|
+
expanded,
|
|
225
|
+
onExpandedChange
|
|
226
|
+
});
|
|
227
|
+
const resolvedColumns = useMemo(() => composeColumns(columns, {
|
|
228
|
+
enableRowSelection,
|
|
229
|
+
enableSorting,
|
|
230
|
+
rowActions,
|
|
231
|
+
rowActionsSheetTitle
|
|
232
|
+
}), [
|
|
233
|
+
columns,
|
|
234
|
+
enableRowSelection,
|
|
235
|
+
enableSorting,
|
|
236
|
+
rowActions,
|
|
237
|
+
rowActionsSheetTitle
|
|
238
|
+
]);
|
|
239
|
+
const minWidth = useMemo(() => trackMinWidth(resolvedColumns), [resolvedColumns]);
|
|
240
|
+
const flatData = useMemo(() => groups.flatMap((g) => g.rows), [groups]);
|
|
241
|
+
const table = useReactTable({
|
|
242
|
+
data: flatData,
|
|
243
|
+
columns: resolvedColumns,
|
|
244
|
+
state: {
|
|
245
|
+
sorting,
|
|
246
|
+
rowSelection,
|
|
247
|
+
globalFilter: search
|
|
248
|
+
},
|
|
249
|
+
onSortingChange: setSorting,
|
|
250
|
+
onRowSelectionChange: setRowSelection,
|
|
251
|
+
onGlobalFilterChange: setSearch,
|
|
252
|
+
enableRowSelection: Boolean(enableRowSelection),
|
|
253
|
+
manualSorting: true,
|
|
254
|
+
enableMultiSort: false,
|
|
255
|
+
globalFilterFn: (row, _columnId, value) => rowMatchesSearch(row.original, String(value ?? ""), {
|
|
256
|
+
searchFn,
|
|
257
|
+
searchableColumns
|
|
258
|
+
}),
|
|
259
|
+
getRowId,
|
|
260
|
+
getCoreRowModel: getCoreRowModel(),
|
|
261
|
+
getFilteredRowModel: getFilteredRowModel()
|
|
262
|
+
});
|
|
263
|
+
const headerGroups = table.getHeaderGroups();
|
|
264
|
+
const coreRows = table.getCoreRowModel().rows;
|
|
265
|
+
const filteredRows = table.getRowModel().rows;
|
|
266
|
+
const buckets = useMemo(() => bucketRows(groups, coreRows, filteredRows), [
|
|
267
|
+
groups,
|
|
268
|
+
coreRows,
|
|
269
|
+
filteredRows
|
|
270
|
+
]);
|
|
271
|
+
const slices = useMemo(() => groups.map((g) => ({
|
|
272
|
+
group: g,
|
|
273
|
+
id: g.id,
|
|
274
|
+
title: g.title,
|
|
275
|
+
meta: g.meta,
|
|
276
|
+
rows: sortRows(buckets.get(g.id) ?? [], sorting)
|
|
277
|
+
})), [
|
|
278
|
+
groups,
|
|
279
|
+
buckets,
|
|
280
|
+
sorting
|
|
281
|
+
]);
|
|
282
|
+
const visibleSlices = isSearching ? slices.filter((s) => s.rows.length > 0) : slices;
|
|
283
|
+
const renderShell = (body, scrollable) => /* @__PURE__ */ jsxs("div", {
|
|
284
|
+
className: cn("w-full", className),
|
|
285
|
+
children: [enableSearch && /* @__PURE__ */ jsx(GroupedToolbar, {
|
|
286
|
+
search,
|
|
287
|
+
onSearchChange: setSearch,
|
|
288
|
+
placeholder: searchPlaceholder,
|
|
289
|
+
debounceMs: searchDebounceMs,
|
|
290
|
+
className: toolbarClassName
|
|
291
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
292
|
+
className: cn("w-full rounded-md border", scrollable ? "overflow-x-auto" : "overflow-hidden"),
|
|
293
|
+
children: scrollable ? /* @__PURE__ */ jsx("div", {
|
|
294
|
+
style: { minWidth },
|
|
295
|
+
children: body
|
|
296
|
+
}) : body
|
|
297
|
+
})]
|
|
298
|
+
});
|
|
299
|
+
if (isLoading) return renderShell(/* @__PURE__ */ jsx(GroupedSkeleton, { columns: resolvedColumns.length }), false);
|
|
300
|
+
if (flatData.length === 0 || isSearching && visibleSlices.length === 0) return renderShell(empty ?? null, false);
|
|
301
|
+
return renderShell(/* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("table", {
|
|
302
|
+
className: cn("w-full table-fixed text-sm", tableClassName),
|
|
303
|
+
children: [renderColGroup(resolvedColumns), /* @__PURE__ */ jsx(TableHeader, { children: headerGroups.map((hg) => /* @__PURE__ */ jsx(TableRow, {
|
|
304
|
+
className: headerRowClassName,
|
|
305
|
+
children: hg.headers.map((header) => /* @__PURE__ */ jsx(TableHead, {
|
|
306
|
+
scope: "col",
|
|
307
|
+
className: headerCellClassName,
|
|
308
|
+
children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())
|
|
309
|
+
}, header.id))
|
|
310
|
+
}, hg.id)) })]
|
|
311
|
+
}), visibleSlices.map((slice) => {
|
|
312
|
+
const open = isSearching ? true : isOpen(slice.id);
|
|
313
|
+
return /* @__PURE__ */ jsxs(Collapsible, {
|
|
314
|
+
open,
|
|
315
|
+
onOpenChange: () => toggle(slice.id),
|
|
316
|
+
children: [/* @__PURE__ */ jsxs(CollapsibleTrigger, {
|
|
317
|
+
className: cn("flex h-10 w-full items-center gap-2 border-b bg-muted/40 px-2 text-left align-middle text-sm font-medium text-muted-foreground transition-colors hover:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", resolveClassName(groupHeaderClassName, slice.group)),
|
|
318
|
+
children: [
|
|
319
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
320
|
+
icon: ChevronRight,
|
|
321
|
+
"aria-hidden": true,
|
|
322
|
+
className: cn("size-4 shrink-0 transition-transform", open && "rotate-90")
|
|
323
|
+
}),
|
|
324
|
+
/* @__PURE__ */ jsx("span", { children: slice.title }),
|
|
325
|
+
slice.meta != null && /* @__PURE__ */ jsx("span", {
|
|
326
|
+
className: "ml-auto flex items-center gap-2 font-medium",
|
|
327
|
+
children: slice.meta
|
|
328
|
+
})
|
|
329
|
+
]
|
|
330
|
+
}), /* @__PURE__ */ jsx(CollapsibleContent, {
|
|
331
|
+
className: "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
|
|
332
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
333
|
+
className: cn("w-full table-fixed text-sm", tableClassName),
|
|
334
|
+
"aria-label": typeof slice.title === "string" ? slice.title : void 0,
|
|
335
|
+
children: [renderColGroup(resolvedColumns), /* @__PURE__ */ jsx(TableBody, {
|
|
336
|
+
className: bodyClassName,
|
|
337
|
+
children: slice.rows.map((row) => /* @__PURE__ */ jsx(TableRow, {
|
|
338
|
+
"data-state": row.getIsSelected() ? "selected" : void 0,
|
|
339
|
+
className: resolveClassName(rowClassName, row),
|
|
340
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, {
|
|
341
|
+
className: resolveClassName(cellClassName, cell),
|
|
342
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
343
|
+
}, cell.id))
|
|
344
|
+
}, row.id))
|
|
345
|
+
})]
|
|
346
|
+
})
|
|
347
|
+
})]
|
|
348
|
+
}, slice.id);
|
|
349
|
+
})] }), true);
|
|
350
|
+
}
|
|
351
|
+
//#endregion
|
|
352
|
+
export { GroupedTable };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datum-cloud/datum-ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "https://github.com/datum-cloud/datum-ui"
|
|
@@ -193,6 +193,11 @@
|
|
|
193
193
|
"types": "./dist/components/base/table/index.d.ts",
|
|
194
194
|
"default": "./dist/table/index.mjs"
|
|
195
195
|
},
|
|
196
|
+
"./grouped-table": {
|
|
197
|
+
"source": "./src/components/features/grouped-table/index.ts",
|
|
198
|
+
"types": "./dist/components/features/grouped-table/index.d.ts",
|
|
199
|
+
"default": "./dist/grouped-table/index.mjs"
|
|
200
|
+
},
|
|
196
201
|
"./tabs": {
|
|
197
202
|
"source": "./src/components/base/tabs/index.ts",
|
|
198
203
|
"types": "./dist/components/base/tabs/index.d.ts",
|
|
@@ -625,8 +630,8 @@
|
|
|
625
630
|
"typescript": "^6.0.3",
|
|
626
631
|
"vitest": "^4.1.8",
|
|
627
632
|
"zod": "^4.4.3",
|
|
628
|
-
"@repo/
|
|
629
|
-
"@repo/
|
|
633
|
+
"@repo/shadcn": "0.0.0",
|
|
634
|
+
"@repo/config": "0.0.0"
|
|
630
635
|
},
|
|
631
636
|
"publishConfig": {
|
|
632
637
|
"access": "public"
|