@stackshift-ui/data-table 1.0.0-beta.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/LICENSE +373 -0
- package/README.md +24 -0
- package/dist/chunk-2YVCA56U.mjs +1 -0
- package/dist/chunk-3EYN2AKU.mjs +1 -0
- package/dist/chunk-4II4GOHT.mjs +1 -0
- package/dist/chunk-VTWRQFOH.mjs +1 -0
- package/dist/chunk-WNXZYFCR.mjs +1 -0
- package/dist/data-table-column-header.d.ts +10 -0
- package/dist/data-table-column-header.js +1 -0
- package/dist/data-table-column-header.mjs +1 -0
- package/dist/data-table-pagination.d.ts +9 -0
- package/dist/data-table-pagination.js +1 -0
- package/dist/data-table-pagination.mjs +1 -0
- package/dist/data-table-view-options.d.ts +7 -0
- package/dist/data-table-view-options.js +2 -0
- package/dist/data-table-view-options.mjs +2 -0
- package/dist/data-table.d.ts +13 -0
- package/dist/data-table.js +2 -0
- package/dist/data-table.mjs +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.js +51 -0
- package/dist/setupTests.mjs +51 -0
- package/package.json +69 -0
- package/src/data-table-column-header.tsx +70 -0
- package/src/data-table-pagination.tsx +94 -0
- package/src/data-table-view-options.tsx +53 -0
- package/src/data-table.test.tsx +79 -0
- package/src/data-table.tsx +112 -0
- package/src/index.ts +4 -0
- package/src/setupTests.ts +4 -0
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stackshift-ui/data-table",
|
|
3
|
+
"description": "Powerful table and datagrids built using TanStack Table.",
|
|
4
|
+
"version": "1.0.0-beta.1",
|
|
5
|
+
"private": false,
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"author": "WebriQ <info@webriq.com>",
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@testing-library/jest-dom": "^6.5.0",
|
|
17
|
+
"@testing-library/react": "^16.0.1",
|
|
18
|
+
"@testing-library/user-event": "^14.6.1",
|
|
19
|
+
"@types/node": "^22.7.0",
|
|
20
|
+
"@types/react": "^18.3.9",
|
|
21
|
+
"@types/react-dom": "^18.3.0",
|
|
22
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
23
|
+
"@vitest/coverage-v8": "^2.1.1",
|
|
24
|
+
"esbuild-plugin-rdi": "^0.0.0",
|
|
25
|
+
"esbuild-plugin-react18": "^0.2.5",
|
|
26
|
+
"esbuild-plugin-react18-css": "^0.0.4",
|
|
27
|
+
"jsdom": "^25.0.1",
|
|
28
|
+
"react": "^18.3.1",
|
|
29
|
+
"react-dom": "^18.3.1",
|
|
30
|
+
"tsup": "^8.3.0",
|
|
31
|
+
"typescript": "^5.6.2",
|
|
32
|
+
"vite-tsconfig-paths": "^5.0.1",
|
|
33
|
+
"vitest": "^2.1.1",
|
|
34
|
+
"@stackshift-ui/typescript-config": "6.0.10",
|
|
35
|
+
"@stackshift-ui/eslint-config": "6.0.10"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@radix-ui/react-dropdown-menu": "^2.1.15",
|
|
39
|
+
"@tanstack/react-table": "^8.21.3",
|
|
40
|
+
"classnames": "^2.5.1",
|
|
41
|
+
"lucide-react": "^0.468.0",
|
|
42
|
+
"@stackshift-ui/button": "6.1.0-beta.0",
|
|
43
|
+
"@stackshift-ui/select": "7.0.0-beta.0",
|
|
44
|
+
"@stackshift-ui/system": "6.1.0-beta.0",
|
|
45
|
+
"@stackshift-ui/scripts": "6.1.0-beta.0",
|
|
46
|
+
"@stackshift-ui/table": "1.0.0-beta.1",
|
|
47
|
+
"@stackshift-ui/dropdown-menu": "1.0.0-beta.1"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@stackshift-ui/system": ">=6.1.0-beta.0",
|
|
51
|
+
"@types/react": "16.8 - 19",
|
|
52
|
+
"next": "10 - 14",
|
|
53
|
+
"react": "16.8 - 19",
|
|
54
|
+
"react-dom": "16.8 - 19"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"next": {
|
|
58
|
+
"optional": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsup && tsc -p tsconfig-build.json",
|
|
63
|
+
"clean": "rm -rf dist",
|
|
64
|
+
"dev": "tsup --watch && tsc -p tsconfig-build.json -w",
|
|
65
|
+
"typecheck": "tsc --noEmit",
|
|
66
|
+
"lint": "eslint src/",
|
|
67
|
+
"test": "vitest run --coverage"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import {
|
|
3
|
+
DropdownMenu,
|
|
4
|
+
DropdownMenuContent,
|
|
5
|
+
DropdownMenuItem,
|
|
6
|
+
DropdownMenuSeparator,
|
|
7
|
+
DropdownMenuTrigger,
|
|
8
|
+
} from "@stackshift-ui/dropdown-menu";
|
|
9
|
+
import { cn, DefaultComponent, useStackShiftUIComponents } from "@stackshift-ui/system";
|
|
10
|
+
import { Column } from "@tanstack/react-table";
|
|
11
|
+
import { ArrowDown, ArrowUp, ChevronsUpDown, EyeOff } from "lucide-react";
|
|
12
|
+
|
|
13
|
+
const displayName = "DataTableColumnHeader";
|
|
14
|
+
|
|
15
|
+
interface DataTableColumnHeaderProps<TData, TValue> extends React.HTMLAttributes<HTMLDivElement> {
|
|
16
|
+
column: Column<TData, TValue>;
|
|
17
|
+
title: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function DataTableColumnHeader<TData, TValue>({
|
|
21
|
+
column,
|
|
22
|
+
title,
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}: DataTableColumnHeaderProps<TData, TValue>) {
|
|
26
|
+
const { [displayName]: Component = DefaultComponent } = useStackShiftUIComponents();
|
|
27
|
+
|
|
28
|
+
if (!column.getCanSort()) {
|
|
29
|
+
return (
|
|
30
|
+
<Component className={cn(className)} {...props}>
|
|
31
|
+
{title}
|
|
32
|
+
</Component>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Component className={cn("flex items-center gap-2", className)} {...props}>
|
|
38
|
+
<DropdownMenu>
|
|
39
|
+
<DropdownMenuTrigger asChild>
|
|
40
|
+
<Button variant="ghost" size="sm" className="data-[state=open]:bg-accent -ml-3 h-8">
|
|
41
|
+
<span>{title}</span>
|
|
42
|
+
{column.getIsSorted() === "desc" ? (
|
|
43
|
+
<ArrowDown />
|
|
44
|
+
) : column.getIsSorted() === "asc" ? (
|
|
45
|
+
<ArrowUp />
|
|
46
|
+
) : (
|
|
47
|
+
<ChevronsUpDown />
|
|
48
|
+
)}
|
|
49
|
+
</Button>
|
|
50
|
+
</DropdownMenuTrigger>
|
|
51
|
+
<DropdownMenuContent align="start">
|
|
52
|
+
<DropdownMenuItem onClick={() => column.toggleSorting(false)}>
|
|
53
|
+
<ArrowUp />
|
|
54
|
+
Asc
|
|
55
|
+
</DropdownMenuItem>
|
|
56
|
+
<DropdownMenuItem onClick={() => column.toggleSorting(true)}>
|
|
57
|
+
<ArrowDown />
|
|
58
|
+
Desc
|
|
59
|
+
</DropdownMenuItem>
|
|
60
|
+
<DropdownMenuSeparator />
|
|
61
|
+
<DropdownMenuItem onClick={() => column.toggleVisibility(false)}>
|
|
62
|
+
<EyeOff />
|
|
63
|
+
Hide
|
|
64
|
+
</DropdownMenuItem>
|
|
65
|
+
</DropdownMenuContent>
|
|
66
|
+
</DropdownMenu>
|
|
67
|
+
</Component>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
DataTableColumnHeader.displayName = displayName;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { DefaultComponent, useStackShiftUIComponents } from "@stackshift-ui/system";
|
|
2
|
+
import { Table } from "@tanstack/react-table";
|
|
3
|
+
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react";
|
|
4
|
+
|
|
5
|
+
import { Button } from "@stackshift-ui/button";
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue,
|
|
12
|
+
} from "@stackshift-ui/select";
|
|
13
|
+
|
|
14
|
+
const displayName = "DataTablePagination";
|
|
15
|
+
|
|
16
|
+
interface DataTablePaginationProps<TData> {
|
|
17
|
+
table: Table<TData>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function DataTablePagination<TData>({ table, ...props }: DataTablePaginationProps<TData>) {
|
|
21
|
+
const { [displayName]: Component = DefaultComponent } = useStackShiftUIComponents();
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Component className="flex items-center justify-between px-2" {...props}>
|
|
25
|
+
<div className="text-muted-foreground flex-1 text-sm">
|
|
26
|
+
{table.getFilteredSelectedRowModel().rows.length} of{" "}
|
|
27
|
+
{table.getFilteredRowModel().rows.length} row(s) selected.
|
|
28
|
+
</div>
|
|
29
|
+
<div className="flex items-center space-x-6 lg:space-x-8">
|
|
30
|
+
<div className="flex items-center space-x-2">
|
|
31
|
+
<p className="text-sm font-medium">Rows per page</p>
|
|
32
|
+
<Select
|
|
33
|
+
value={`${table.getState().pagination.pageSize}`}
|
|
34
|
+
onValueChange={value => {
|
|
35
|
+
table.setPageSize(Number(value));
|
|
36
|
+
}}>
|
|
37
|
+
<SelectTrigger className="h-8 w-[70px]">
|
|
38
|
+
<SelectValue placeholder={table.getState().pagination.pageSize} />
|
|
39
|
+
</SelectTrigger>
|
|
40
|
+
<SelectContent side="top">
|
|
41
|
+
{[10, 20, 25, 30, 40, 50].map(pageSize => (
|
|
42
|
+
<SelectItem key={pageSize} value={`${pageSize}`}>
|
|
43
|
+
{pageSize}
|
|
44
|
+
</SelectItem>
|
|
45
|
+
))}
|
|
46
|
+
</SelectContent>
|
|
47
|
+
</Select>
|
|
48
|
+
</div>
|
|
49
|
+
<div className="flex w-[100px] items-center justify-center text-sm font-medium">
|
|
50
|
+
Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
|
|
51
|
+
</div>
|
|
52
|
+
<div className="flex items-center space-x-2">
|
|
53
|
+
<Button
|
|
54
|
+
variant="outline"
|
|
55
|
+
size="icon"
|
|
56
|
+
className="hidden size-8 lg:flex"
|
|
57
|
+
onClick={() => table.setPageIndex(0)}
|
|
58
|
+
disabled={!table.getCanPreviousPage()}>
|
|
59
|
+
<span className="sr-only">Go to first page</span>
|
|
60
|
+
<ChevronsLeft />
|
|
61
|
+
</Button>
|
|
62
|
+
<Button
|
|
63
|
+
variant="outline"
|
|
64
|
+
size="icon"
|
|
65
|
+
className="size-8"
|
|
66
|
+
onClick={() => table.previousPage()}
|
|
67
|
+
disabled={!table.getCanPreviousPage()}>
|
|
68
|
+
<span className="sr-only">Go to previous page</span>
|
|
69
|
+
<ChevronLeft />
|
|
70
|
+
</Button>
|
|
71
|
+
<Button
|
|
72
|
+
variant="outline"
|
|
73
|
+
size="icon"
|
|
74
|
+
className="size-8"
|
|
75
|
+
onClick={() => table.nextPage()}
|
|
76
|
+
disabled={!table.getCanNextPage()}>
|
|
77
|
+
<span className="sr-only">Go to next page</span>
|
|
78
|
+
<ChevronRight />
|
|
79
|
+
</Button>
|
|
80
|
+
<Button
|
|
81
|
+
variant="outline"
|
|
82
|
+
size="icon"
|
|
83
|
+
className="hidden size-8 lg:flex"
|
|
84
|
+
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
|
|
85
|
+
disabled={!table.getCanNextPage()}>
|
|
86
|
+
<span className="sr-only">Go to last page</span>
|
|
87
|
+
<ChevronsRight />
|
|
88
|
+
</Button>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</Component>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
DataTablePagination.displayName = displayName;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu";
|
|
4
|
+
import { Table } from "@tanstack/react-table";
|
|
5
|
+
import { Settings2 } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
import { Button } from "@stackshift-ui/button";
|
|
8
|
+
import {
|
|
9
|
+
DropdownMenu,
|
|
10
|
+
DropdownMenuCheckboxItem,
|
|
11
|
+
DropdownMenuContent,
|
|
12
|
+
DropdownMenuLabel,
|
|
13
|
+
DropdownMenuSeparator,
|
|
14
|
+
} from "@stackshift-ui/dropdown-menu";
|
|
15
|
+
import { DefaultComponent, useStackShiftUIComponents } from "@stackshift-ui/system";
|
|
16
|
+
|
|
17
|
+
const displayName = "DataTableViewOptions";
|
|
18
|
+
|
|
19
|
+
export function DataTableViewOptions<TData>({ table, ...props }: { table: Table<TData> }) {
|
|
20
|
+
const { [displayName]: Component = DefaultComponent } = useStackShiftUIComponents();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Component {...props}>
|
|
24
|
+
<DropdownMenu>
|
|
25
|
+
<DropdownMenuTrigger asChild>
|
|
26
|
+
<Button variant="outline" size="sm" className="ml-auto hidden h-8 lg:flex">
|
|
27
|
+
<Settings2 />
|
|
28
|
+
View
|
|
29
|
+
</Button>
|
|
30
|
+
</DropdownMenuTrigger>
|
|
31
|
+
<DropdownMenuContent align="end" className="w-[150px]">
|
|
32
|
+
<DropdownMenuLabel>Toggle columns</DropdownMenuLabel>
|
|
33
|
+
<DropdownMenuSeparator />
|
|
34
|
+
{table
|
|
35
|
+
.getAllColumns()
|
|
36
|
+
.filter(column => typeof column.accessorFn !== "undefined" && column.getCanHide())
|
|
37
|
+
.map(column => {
|
|
38
|
+
return (
|
|
39
|
+
<DropdownMenuCheckboxItem
|
|
40
|
+
key={column.id}
|
|
41
|
+
className="capitalize"
|
|
42
|
+
checked={column.getIsVisible()}
|
|
43
|
+
onCheckedChange={value => column.toggleVisibility(!!value)}>
|
|
44
|
+
{column.id}
|
|
45
|
+
</DropdownMenuCheckboxItem>
|
|
46
|
+
);
|
|
47
|
+
})}
|
|
48
|
+
</DropdownMenuContent>
|
|
49
|
+
</DropdownMenu>
|
|
50
|
+
</Component>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
DataTableViewOptions.displayName = displayName;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { cleanup, render, screen } from "@testing-library/react";
|
|
2
|
+
import userEvent from "@testing-library/user-event";
|
|
3
|
+
import { afterEach, describe, test } from "vitest";
|
|
4
|
+
import { ColumnDef, DataTable } from "./data-table";
|
|
5
|
+
|
|
6
|
+
// TODO: add more tests
|
|
7
|
+
describe.concurrent("data-table", () => {
|
|
8
|
+
afterEach(cleanup);
|
|
9
|
+
|
|
10
|
+
test("Dummy test - test if renders without errors", ({ expect }) => {
|
|
11
|
+
const columns: ColumnDef<{ name: string }>[] = [
|
|
12
|
+
{
|
|
13
|
+
accessorKey: "name",
|
|
14
|
+
header: "Name",
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const data = [
|
|
19
|
+
{
|
|
20
|
+
name: "John Doe",
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
render(<DataTable data-testid="data-table" columns={columns} data={data} />);
|
|
25
|
+
expect(screen.getByText("John Doe")).not.toBeNull();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("Common: Data Table - test if renders with correct number of rows", ({ expect }) => {
|
|
29
|
+
const columns: ColumnDef<{ name: string }>[] = [
|
|
30
|
+
{
|
|
31
|
+
accessorKey: "name",
|
|
32
|
+
header: "Name",
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const data = [
|
|
37
|
+
{
|
|
38
|
+
name: "John Doe",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "Jane Doe",
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
render(<DataTable data-testid="data-table-2" columns={columns} data={data} />);
|
|
46
|
+
|
|
47
|
+
const table = screen.getByTestId("data-table-2");
|
|
48
|
+
const rows = table.querySelectorAll("tr");
|
|
49
|
+
|
|
50
|
+
expect(rows).toHaveLength(3);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("Common: Data Table - test if renders with correct number of columns", ({ expect }) => {
|
|
54
|
+
const columns: ColumnDef<{ name: string; email: string }>[] = [
|
|
55
|
+
{
|
|
56
|
+
accessorKey: "name",
|
|
57
|
+
header: "Name",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
accessorKey: "email",
|
|
61
|
+
header: "Email",
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const data = [
|
|
66
|
+
{
|
|
67
|
+
name: "John Doe",
|
|
68
|
+
email: "john@example.com",
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
render(<DataTable data-testid="data-table-3" columns={columns} data={data} />);
|
|
73
|
+
|
|
74
|
+
const table = screen.getByTestId("data-table-3");
|
|
75
|
+
const headers = table.querySelectorAll("th");
|
|
76
|
+
|
|
77
|
+
expect(headers).toHaveLength(2);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { DefaultComponent, useStackShiftUIComponents } from "@stackshift-ui/system";
|
|
4
|
+
import {
|
|
5
|
+
Table,
|
|
6
|
+
TableBody,
|
|
7
|
+
TableCell,
|
|
8
|
+
TableHead,
|
|
9
|
+
TableHeader,
|
|
10
|
+
TableRow,
|
|
11
|
+
} from "@stackshift-ui/table";
|
|
12
|
+
import {
|
|
13
|
+
ColumnDef,
|
|
14
|
+
ColumnFiltersState,
|
|
15
|
+
flexRender,
|
|
16
|
+
getCoreRowModel,
|
|
17
|
+
getFilteredRowModel,
|
|
18
|
+
getPaginationRowModel,
|
|
19
|
+
getSortedRowModel,
|
|
20
|
+
SortingState,
|
|
21
|
+
useReactTable,
|
|
22
|
+
} from "@tanstack/react-table";
|
|
23
|
+
import { useState } from "react";
|
|
24
|
+
import { DataTablePagination } from "./data-table-pagination";
|
|
25
|
+
|
|
26
|
+
const displayName = "DataTable";
|
|
27
|
+
|
|
28
|
+
interface DataTableProps<TData, TValue> {
|
|
29
|
+
columns: ColumnDef<TData, TValue>[];
|
|
30
|
+
data: TData[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function DataTable<TData, TValue>({
|
|
34
|
+
columns,
|
|
35
|
+
data,
|
|
36
|
+
...props
|
|
37
|
+
}: DataTableProps<TData, TValue>) {
|
|
38
|
+
const { [displayName]: Component = DefaultComponent } = useStackShiftUIComponents();
|
|
39
|
+
|
|
40
|
+
const [sorting, setSorting] = useState<SortingState>([]);
|
|
41
|
+
const [rowSelection, setRowSelection] = useState({});
|
|
42
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
43
|
+
|
|
44
|
+
const table = useReactTable({
|
|
45
|
+
data,
|
|
46
|
+
columns,
|
|
47
|
+
getCoreRowModel: getCoreRowModel(),
|
|
48
|
+
getPaginationRowModel: getPaginationRowModel(),
|
|
49
|
+
onSortingChange: setSorting,
|
|
50
|
+
getSortedRowModel: getSortedRowModel(),
|
|
51
|
+
onRowSelectionChange: setRowSelection,
|
|
52
|
+
onColumnFiltersChange: setColumnFilters,
|
|
53
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
54
|
+
state: {
|
|
55
|
+
sorting,
|
|
56
|
+
rowSelection,
|
|
57
|
+
columnFilters,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Component className="relative w-full h-full flex flex-col gap-2" {...props}>
|
|
63
|
+
<div className="rounded-md border">
|
|
64
|
+
<Table>
|
|
65
|
+
<TableHeader>
|
|
66
|
+
{table.getHeaderGroups().map(headerGroup => (
|
|
67
|
+
<TableRow key={headerGroup.id}>
|
|
68
|
+
{headerGroup.headers.map(header => {
|
|
69
|
+
return (
|
|
70
|
+
<TableHead key={header.id}>
|
|
71
|
+
{header.isPlaceholder
|
|
72
|
+
? null
|
|
73
|
+
: flexRender(header.column.columnDef.header, header.getContext())}
|
|
74
|
+
</TableHead>
|
|
75
|
+
);
|
|
76
|
+
})}
|
|
77
|
+
</TableRow>
|
|
78
|
+
))}
|
|
79
|
+
</TableHeader>
|
|
80
|
+
<TableBody>
|
|
81
|
+
{table.getRowModel().rows?.length ? (
|
|
82
|
+
table.getRowModel().rows.map(row => (
|
|
83
|
+
<TableRow key={row.id} data-state={row.getIsSelected() && "selected"}>
|
|
84
|
+
{row.getVisibleCells().map(cell => (
|
|
85
|
+
<TableCell key={cell.id}>
|
|
86
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
87
|
+
</TableCell>
|
|
88
|
+
))}
|
|
89
|
+
</TableRow>
|
|
90
|
+
))
|
|
91
|
+
) : (
|
|
92
|
+
<TableRow>
|
|
93
|
+
<TableCell colSpan={columns.length} className="h-24 text-center">
|
|
94
|
+
No results.
|
|
95
|
+
</TableCell>
|
|
96
|
+
</TableRow>
|
|
97
|
+
)}
|
|
98
|
+
</TableBody>
|
|
99
|
+
</Table>
|
|
100
|
+
</div>
|
|
101
|
+
<div className="w-full h-fit py-10">
|
|
102
|
+
<DataTablePagination table={table} />
|
|
103
|
+
</div>
|
|
104
|
+
</Component>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
DataTable.displayName = displayName;
|
|
108
|
+
|
|
109
|
+
export { type ColumnDef } from "@tanstack/react-table";
|
|
110
|
+
export { DataTableColumnHeader } from "./data-table-column-header";
|
|
111
|
+
export { DataTablePagination } from "./data-table-pagination";
|
|
112
|
+
export { DataTableViewOptions } from "./data-table-view-options";
|
package/src/index.ts
ADDED