@nccirtu/tablefy 0.2.0 → 0.5.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.
Files changed (106) hide show
  1. package/README.md +20 -4
  2. package/cli/templates/tablefy/avatar-list.tsx +51 -0
  3. package/cli/templates/tablefy/data-table-empty.tsx +77 -0
  4. package/cli/templates/tablefy/data-table-header.tsx +208 -0
  5. package/cli/templates/tablefy/data-table-pagination.tsx +137 -0
  6. package/cli/templates/tablefy/data-table-schema.tsx +13 -0
  7. package/cli/templates/tablefy/data-table.tsx +222 -0
  8. package/dist/cli/index.js +475 -0
  9. package/dist/columns/avatar-group-column.d.ts +1 -1
  10. package/dist/columns/columns/avatar-group-column.d.ts +1 -1
  11. package/dist/columns/index.d.ts +2 -2
  12. package/dist/columns/index.esm.js +153 -7921
  13. package/dist/columns/index.esm.js.map +1 -1
  14. package/dist/columns/index.js +214 -8000
  15. package/dist/columns/index.js.map +1 -1
  16. package/dist/columns/tablefy/avatar-list.d.ts +15 -0
  17. package/dist/columns/{components/ui/data-table → tablefy}/data-table-header.d.ts +1 -1
  18. package/dist/columns/{components/ui/data-table → tablefy}/data-table-pagination.d.ts +1 -1
  19. package/dist/columns/tablefy/data-table-schema.d.ts +1 -0
  20. package/dist/columns/tablefy/index.d.ts +6 -0
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.esm.js +23 -7825
  23. package/dist/index.esm.js.map +1 -1
  24. package/dist/index.js +55 -7875
  25. package/dist/index.js.map +1 -1
  26. package/dist/tablefy/avatar-list.d.ts +15 -0
  27. package/dist/{components/ui/data-table → tablefy}/data-table-header.d.ts +1 -1
  28. package/dist/{components/ui/data-table → tablefy}/data-table-pagination.d.ts +1 -1
  29. package/dist/tablefy/data-table-schema.d.ts +1 -0
  30. package/dist/tablefy/index.d.ts +6 -0
  31. package/package.json +46 -13
  32. package/dist/columns/components/animata/list/avatar-list.d.ts +0 -12
  33. package/dist/columns/components/ui/badge.d.ts +0 -9
  34. package/dist/columns/components/ui/button.d.ts +0 -10
  35. package/dist/columns/components/ui/checkbox.d.ts +0 -4
  36. package/dist/columns/components/ui/data-table/data-table-schema.d.ts +0 -5
  37. package/dist/columns/components/ui/dropdown-menu.d.ts +0 -25
  38. package/dist/columns/components/ui/input.d.ts +0 -3
  39. package/dist/columns/components/ui/progress.d.ts +0 -4
  40. package/dist/columns/components/ui/select.d.ts +0 -15
  41. package/dist/columns/components/ui/table.d.ts +0 -10
  42. package/dist/columns/components/ui/tooltip.d.ts +0 -7
  43. package/dist/components/animata/list/avatar-list.d.ts +0 -12
  44. package/dist/components/ui/badge.d.ts +0 -9
  45. package/dist/components/ui/button.d.ts +0 -10
  46. package/dist/components/ui/checkbox.d.ts +0 -4
  47. package/dist/components/ui/data-table/data-table-schema.d.ts +0 -5
  48. package/dist/components/ui/dropdown-menu.d.ts +0 -25
  49. package/dist/components/ui/input.d.ts +0 -3
  50. package/dist/components/ui/progress.d.ts +0 -4
  51. package/dist/components/ui/select.d.ts +0 -15
  52. package/dist/components/ui/table.d.ts +0 -10
  53. package/dist/components/ui/tooltip.d.ts +0 -7
  54. package/dist/lib/table/schema/empty-state.d.ts +0 -23
  55. package/dist/lib/table/types.d.ts +0 -76
  56. package/dist/schema/data-table-schema.d.ts +0 -75
  57. package/dist/schema/empty-state.d.ts +0 -45
  58. package/dist/schema/table-schema.d.ts +0 -44
  59. package/dist/schema.d.ts +0 -11
  60. package/dist/src/columns/actions-column.d.ts +0 -26
  61. package/dist/src/columns/avatar-group-column.d.ts +0 -38
  62. package/dist/src/columns/badge-column.d.ts +0 -22
  63. package/dist/src/columns/base-column.d.ts +0 -19
  64. package/dist/src/columns/button-column.d.ts +0 -14
  65. package/dist/src/columns/checkbox-column.d.ts +0 -5
  66. package/dist/src/columns/date-column.d.ts +0 -24
  67. package/dist/src/columns/dropdown-column.d.ts +0 -17
  68. package/dist/src/columns/icon-column.d.ts +0 -58
  69. package/dist/src/columns/image-column.d.ts +0 -21
  70. package/dist/src/columns/index.d.ts +0 -13
  71. package/dist/src/columns/input-column.d.ts +0 -14
  72. package/dist/src/columns/link-column.d.ts +0 -27
  73. package/dist/src/columns/number-column.d.ts +0 -23
  74. package/dist/src/columns/progress-column.d.ts +0 -30
  75. package/dist/src/columns/select-column.d.ts +0 -19
  76. package/dist/src/columns/text-column.d.ts +0 -14
  77. package/dist/src/columns/types.d.ts +0 -37
  78. package/dist/src/components/animata/list/avatar-list.d.ts +0 -12
  79. package/dist/src/components/ui/badge.d.ts +0 -9
  80. package/dist/src/components/ui/button.d.ts +0 -10
  81. package/dist/src/components/ui/checkbox.d.ts +0 -4
  82. package/dist/src/components/ui/data-table/data-table-empty.d.ts +0 -8
  83. package/dist/src/components/ui/data-table/data-table-header.d.ts +0 -15
  84. package/dist/src/components/ui/data-table/data-table-pagination.d.ts +0 -9
  85. package/dist/src/components/ui/data-table/data-table-schema.d.ts +0 -5
  86. package/dist/src/components/ui/data-table/data-table.d.ts +0 -13
  87. package/dist/src/components/ui/dropdown-menu.d.ts +0 -25
  88. package/dist/src/components/ui/input.d.ts +0 -3
  89. package/dist/src/components/ui/progress.d.ts +0 -4
  90. package/dist/src/components/ui/select.d.ts +0 -15
  91. package/dist/src/components/ui/table.d.ts +0 -10
  92. package/dist/src/components/ui/tooltip.d.ts +0 -7
  93. package/dist/src/index.d.ts +0 -15
  94. package/dist/src/lib/table/schema/empty-state.d.ts +0 -23
  95. package/dist/src/lib/table/types.d.ts +0 -76
  96. package/dist/src/lib/utils.d.ts +0 -1
  97. package/dist/src/schema/data-table-schema.d.ts +0 -75
  98. package/dist/src/schema/empty-state.d.ts +0 -45
  99. package/dist/src/schema/table-schema.d.ts +0 -44
  100. package/dist/src/schema.d.ts +0 -11
  101. package/dist/src/types.d.ts +0 -76
  102. package/dist/types.d.ts +0 -76
  103. /package/dist/columns/{components/ui/data-table → tablefy}/data-table-empty.d.ts +0 -0
  104. /package/dist/columns/{components/ui/data-table → tablefy}/data-table.d.ts +0 -0
  105. /package/dist/{components/ui/data-table → tablefy}/data-table-empty.d.ts +0 -0
  106. /package/dist/{components/ui/data-table → tablefy}/data-table.d.ts +0 -0
package/README.md CHANGED
@@ -17,15 +17,31 @@ A powerful, type-safe React table package built with TanStack Table and shadcn/u
17
17
  ## Installation
18
18
 
19
19
  ```bash
20
- npm install tablefy
20
+ npm install @nccirtu/tablefy
21
21
  ```
22
22
 
23
- ### Prerequisites
23
+ **⚠️ Important:** Tablefy requires additional setup steps to work correctly.
24
24
 
25
- Tablefy requires the following peer dependencies:
25
+ ### What you need to install
26
+
27
+ 1. **Peer dependencies** (required libraries)
28
+ 2. **shadcn/ui components** (UI building blocks)
29
+ 3. **Tailwind configuration** (for styling)
30
+
31
+ 👉 **[Follow the complete installation guide →](./INSTALLATION.md)**
32
+
33
+ ### Quick Overview
26
34
 
27
35
  ```bash
36
+ # 1. Install dependencies
28
37
  npm install @tanstack/react-table lucide-react class-variance-authority clsx tailwind-merge
38
+
39
+ # 2. Install shadcn components
40
+ npx shadcn@latest add button table checkbox dropdown-menu input select badge progress tooltip
41
+
42
+ # 3. Configure Tailwind (see [INSTALLATION.md](./INSTALLATION.md) for instructions for React, Next.js, Vue and Svelte)
43
+
44
+ # 4. Restart dev server
29
45
  ```
30
46
 
31
47
  ## Quick Start
@@ -173,7 +189,7 @@ export const projectColumns = TableSchema.make<Project>()
173
189
 
174
190
  ## Documentation
175
191
 
176
- - [Installation Guide](./docs/INSTALLATION.md) - Detailed installation instructions
192
+ - [Installation Guide](./INSTALLATION.md) - Detailed installation instructions
177
193
  - [Usage Guide](./docs/USAGE.md) - Complete API reference and examples
178
194
  - [Column Types](./docs/USAGE.md#column-types) - All column types and their methods
179
195
 
@@ -0,0 +1,51 @@
1
+ import React from "react";
2
+
3
+ export const AvatarList = ({
4
+ items,
5
+ maxVisible = 5,
6
+ size = 32,
7
+ ...props
8
+ }: {
9
+ items: Array<{ id: string; src?: string; alt?: string; initials?: string }>;
10
+ maxVisible?: number;
11
+ size?: number | string;
12
+ [key: string]: any;
13
+ }) => {
14
+ const sizeValue = typeof size === "string" ? parseInt(size, 10) || 32 : size;
15
+ return (
16
+ <div
17
+ className="avatar-list"
18
+ style={{ "--avatar-size": `${sizeValue}px` } as React.CSSProperties}
19
+ {...props}
20
+ >
21
+ {items.slice(0, maxVisible).map((item) => (
22
+ <div key={item.id} className="avatar-item">
23
+ {item.src ? (
24
+ <img
25
+ src={item.src}
26
+ alt={item.alt || "Avatar"}
27
+ style={{ width: `${sizeValue}px`, height: `${sizeValue}px` }}
28
+ />
29
+ ) : (
30
+ <div
31
+ className="avatar-initials"
32
+ style={{ width: `${sizeValue}px`, height: `${sizeValue}px` }}
33
+ >
34
+ {item.initials || "?"}
35
+ </div>
36
+ )}
37
+ </div>
38
+ ))}
39
+ {items.length > maxVisible && (
40
+ <div
41
+ className="avatar-count"
42
+ style={{ width: `${sizeValue}px`, height: `${sizeValue}px` }}
43
+ >
44
+ +{items.length - maxVisible}
45
+ </div>
46
+ )}
47
+ </div>
48
+ );
49
+ };
50
+
51
+ export default AvatarList;
@@ -0,0 +1,77 @@
1
+ "use client";
2
+
3
+ // shadcn components - installed by user
4
+ import { Button } from "@/components/ui/button";
5
+ import { cn } from "@/lib/utils";
6
+ import { EmptyStateConfig } from "@/lib/types";
7
+
8
+ interface DataTableEmptyProps {
9
+ config: EmptyStateConfig;
10
+ colSpan: number;
11
+ className?: string;
12
+ }
13
+
14
+ export function DataTableEmpty({
15
+ config,
16
+ colSpan,
17
+ className,
18
+ }: DataTableEmptyProps) {
19
+ const { icon, imageUrl, title, description, action, variant } = config;
20
+
21
+ return (
22
+ <tr>
23
+ <td colSpan={colSpan} className={cn("h-[400px]", className)}>
24
+ <div className="flex h-full flex-col items-center justify-center gap-4 text-center p-8">
25
+ {imageUrl ? (
26
+ <img className="w-24 h-24" src={imageUrl} alt="Empty State" />
27
+ ) : icon ? (
28
+ <div
29
+ className={cn(
30
+ "rounded-full p-4",
31
+ variant === "error" ? "bg-destructive/10" : "bg-muted",
32
+ )}
33
+ >
34
+ {icon}
35
+ </div>
36
+ ) : null}
37
+
38
+ <div className="w-full flex flex-col items-center justify-center gap-2">
39
+ <h3 className="text-sm font-semibold text-foreground whitespace-normal break-words">
40
+ {title}
41
+ </h3>
42
+ {description && (
43
+ <p className="text-xs text-muted-foreground font-normal whitespace-normal break-words leading-relaxed">
44
+ {description}
45
+ </p>
46
+ )}
47
+ </div>
48
+
49
+ {action && (
50
+ <Button
51
+ variant={variant === "error" ? "outline" : "default"}
52
+ onClick={action.onClick}
53
+ asChild={!!action.href}
54
+ className="mt-2"
55
+ >
56
+ {action.href ? (
57
+ <a href={action.href}>
58
+ {action.icon}
59
+ <span className={cn(action.icon ? "ml-2" : "")}>
60
+ {action.label}
61
+ </span>
62
+ </a>
63
+ ) : (
64
+ <>
65
+ {action.icon}
66
+ <span className={cn(action.icon ? "ml-2" : "")}>
67
+ {action.label}
68
+ </span>
69
+ </>
70
+ )}
71
+ </Button>
72
+ )}
73
+ </div>
74
+ </td>
75
+ </tr>
76
+ );
77
+ }
@@ -0,0 +1,208 @@
1
+ "use client";
2
+
3
+ import { Table as TanstackTable } from "@tanstack/react-table";
4
+ // shadcn components - installed by user
5
+ import { Button } from "@/components/ui/button";
6
+ import { Input } from "@/components/ui/input";
7
+ import {
8
+ DropdownMenu,
9
+ DropdownMenuContent,
10
+ DropdownMenuItem,
11
+ DropdownMenuTrigger,
12
+ } from "@/components/ui/dropdown-menu";
13
+ import { ChevronDown, Search, X } from "lucide-react";
14
+ import { cn } from "@/lib/utils";
15
+ import { HeaderAction, SearchConfig } from "@/lib/types";
16
+
17
+ interface DataTableHeaderProps<TData> {
18
+ title?: string;
19
+ description?: string;
20
+ actions?: HeaderAction<TData>[];
21
+ search?: SearchConfig;
22
+ searchValue?: string;
23
+ onSearchChange?: (value: string) => void;
24
+ table?: TanstackTable<TData>;
25
+ selectedCount?: number;
26
+ className?: string;
27
+ }
28
+
29
+ export function DataTableHeader<TData>({
30
+ title,
31
+ description,
32
+ actions = [],
33
+ search,
34
+ searchValue = "",
35
+ onSearchChange,
36
+ table,
37
+ selectedCount = 0,
38
+ className,
39
+ }: DataTableHeaderProps<TData>) {
40
+ const normalActions = actions.filter((a) => !a.bulk && !a.hidden);
41
+ const bulkActions = actions.filter((a) => a.bulk && !a.hidden);
42
+ const showBulkActions = selectedCount > 0 && bulkActions.length > 0;
43
+
44
+ const getSelectedRows = (): TData[] => {
45
+ if (!table) return [];
46
+ return table.getFilteredSelectedRowModel().rows.map((row) => row.original);
47
+ };
48
+
49
+ const renderAction = (action: HeaderAction<TData>, index: number) => {
50
+ if (action.children && action.children.length > 0) {
51
+ return (
52
+ <DropdownMenu key={action.id || index}>
53
+ <DropdownMenuTrigger asChild>
54
+ <Button
55
+ variant={action.variant || "outline"}
56
+ size={action.size || "default"}
57
+ disabled={action.disabled || action.loading}
58
+ >
59
+ {action.icon}
60
+ <span className={cn(action.icon ? "ml-2" : "")}>
61
+ {action.label}
62
+ </span>
63
+ <ChevronDown className="ml-2 h-4 w-4" />
64
+ </Button>
65
+ </DropdownMenuTrigger>
66
+ <DropdownMenuContent align="end">
67
+ {action.children.map((child, childIndex) => (
68
+ <DropdownMenuItem
69
+ key={child.id || childIndex}
70
+ onClick={child.onClick}
71
+ className={cn(
72
+ child.variant === "destructive" &&
73
+ "text-destructive focus:text-destructive",
74
+ )}
75
+ >
76
+ {child.icon && <span className="mr-2">{child.icon}</span>}
77
+ {child.label}
78
+ </DropdownMenuItem>
79
+ ))}
80
+ </DropdownMenuContent>
81
+ </DropdownMenu>
82
+ );
83
+ }
84
+
85
+ if (action.href) {
86
+ return (
87
+ <Button
88
+ key={action.id || index}
89
+ variant={action.variant || "outline"}
90
+ size={action.size || "default"}
91
+ disabled={action.disabled || action.loading}
92
+ asChild
93
+ >
94
+ <a href={action.href}>
95
+ {action.icon}
96
+ {action.size !== "icon" && (
97
+ <span className={cn(action.icon ? "ml-2" : "")}>
98
+ {action.label}
99
+ </span>
100
+ )}
101
+ </a>
102
+ </Button>
103
+ );
104
+ }
105
+
106
+ return (
107
+ <Button
108
+ key={action.id || index}
109
+ variant={action.variant || "outline"}
110
+ size={action.size || "default"}
111
+ disabled={action.disabled || action.loading}
112
+ onClick={() => {
113
+ if (action.bulk && action.bulkOnClick) {
114
+ action.bulkOnClick(getSelectedRows());
115
+ } else if (action.onClick) {
116
+ action.onClick();
117
+ }
118
+ }}
119
+ >
120
+ {action.loading ? (
121
+ <svg className="animate-spin h-4 w-4" viewBox="0 0 24 24">
122
+ <circle
123
+ className="opacity-25"
124
+ cx="12"
125
+ cy="12"
126
+ r="10"
127
+ stroke="currentColor"
128
+ strokeWidth="4"
129
+ fill="none"
130
+ />
131
+ <path
132
+ className="opacity-75"
133
+ fill="currentColor"
134
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
135
+ />
136
+ </svg>
137
+ ) : (
138
+ action.icon
139
+ )}
140
+ {action.size !== "icon" && (
141
+ <span className={cn(action.icon || action.loading ? "ml-2" : "")}>
142
+ {action.label}
143
+ </span>
144
+ )}
145
+ </Button>
146
+ );
147
+ };
148
+
149
+ if (
150
+ !title &&
151
+ !description &&
152
+ normalActions.length === 0 &&
153
+ !search?.enabled
154
+ ) {
155
+ return null;
156
+ }
157
+
158
+ return (
159
+ <div className={cn("flex flex-col gap-4", className)}>
160
+ {(title || description) && (
161
+ <div className="space-y-1">
162
+ {title && (
163
+ <h2 className="text-xl font-semibold tracking-tight">{title}</h2>
164
+ )}
165
+ {description && (
166
+ <p className="text-sm text-muted-foreground">{description}</p>
167
+ )}
168
+ </div>
169
+ )}
170
+
171
+ {(search?.enabled || normalActions.length > 0 || showBulkActions) && (
172
+ <div className="flex items-center justify-between gap-4 mb-4">
173
+ {search?.enabled && (
174
+ <div className="relative max-w-sm flex-1">
175
+ <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
176
+ <Input
177
+ placeholder={search.placeholder || "Suchen..."}
178
+ value={searchValue}
179
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => onSearchChange?.(e.target.value)}
180
+ className="pl-9 pr-9"
181
+ />
182
+ {searchValue && (
183
+ <button
184
+ onClick={() => onSearchChange?.("")}
185
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
186
+ >
187
+ <X className="h-4 w-4" />
188
+ </button>
189
+ )}
190
+ </div>
191
+ )}
192
+
193
+ <div className="flex items-center gap-2">
194
+ {showBulkActions && (
195
+ <span className="text-sm text-muted-foreground">
196
+ {selectedCount} ausgewählt
197
+ </span>
198
+ )}
199
+ {showBulkActions &&
200
+ bulkActions.map((action, index) => renderAction(action, index))}
201
+ {normalActions.length > 0 &&
202
+ normalActions.map((action, index) => renderAction(action, index))}
203
+ </div>
204
+ </div>
205
+ )}
206
+ </div>
207
+ );
208
+ }
@@ -0,0 +1,137 @@
1
+ "use client";
2
+
3
+ import { Table as TanstackTable } from "@tanstack/react-table";
4
+ // shadcn components - installed by user
5
+ import { Button } from "@/components/ui/button";
6
+ import {
7
+ Select,
8
+ SelectContent,
9
+ SelectItem,
10
+ SelectTrigger,
11
+ SelectValue,
12
+ } from "@/components/ui/select";
13
+ import {
14
+ ChevronLeft,
15
+ ChevronRight,
16
+ ChevronsLeft,
17
+ ChevronsRight,
18
+ } from "lucide-react";
19
+ import { cn } from "@/lib/utils";
20
+ import { PaginationConfig } from "@/lib/types";
21
+
22
+ interface DataTablePaginationProps<TData> {
23
+ table: TanstackTable<TData>;
24
+ config?: PaginationConfig;
25
+ className?: string;
26
+ }
27
+
28
+ export function DataTablePagination<TData>({
29
+ table,
30
+ config,
31
+ className,
32
+ }: DataTablePaginationProps<TData>) {
33
+ if (!config?.enabled) return null;
34
+
35
+ const {
36
+ showPageInfo = true,
37
+ showPageSizeSelector = true,
38
+ pageSizeOptions = [10, 20, 30, 50, 100],
39
+ } = config;
40
+
41
+ return (
42
+ <div
43
+ className={cn(
44
+ "flex flex-col gap-4 px-4 py-4 sm:flex-row sm:items-center sm:justify-between",
45
+ className,
46
+ )}
47
+ >
48
+ <div className="text-sm text-muted-foreground">
49
+ {table.getFilteredSelectedRowModel().rows.length > 0 ? (
50
+ <span>
51
+ {table.getFilteredSelectedRowModel().rows.length} von{" "}
52
+ {table.getFilteredRowModel().rows.length} Zeile(n) ausgewählt
53
+ </span>
54
+ ) : showPageInfo ? (
55
+ <span>{table.getFilteredRowModel().rows.length} Einträge</span>
56
+ ) : null}
57
+ </div>
58
+
59
+ <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:gap-6">
60
+ {showPageSizeSelector && (
61
+ <div className="flex items-center gap-2">
62
+ <span className="text-sm text-muted-foreground whitespace-nowrap">
63
+ Zeilen pro Seite
64
+ </span>
65
+ <Select
66
+ value={`${table.getState().pagination.pageSize}`}
67
+ onValueChange={(value: string) => table.setPageSize(Number(value))}
68
+ >
69
+ <SelectTrigger className="h-8 w-[70px]">
70
+ <SelectValue
71
+ placeholder={table.getState().pagination.pageSize}
72
+ />
73
+ </SelectTrigger>
74
+ <SelectContent side="top">
75
+ {pageSizeOptions.map((pageSize) => (
76
+ <SelectItem key={pageSize} value={`${pageSize}`}>
77
+ {pageSize}
78
+ </SelectItem>
79
+ ))}
80
+ </SelectContent>
81
+ </Select>
82
+ </div>
83
+ )}
84
+
85
+ {showPageInfo && (
86
+ <div className="text-sm text-muted-foreground whitespace-nowrap">
87
+ Seite {table.getState().pagination.pageIndex + 1} von{" "}
88
+ {table.getPageCount()}
89
+ </div>
90
+ )}
91
+
92
+ <div className="flex items-center gap-1">
93
+ <Button
94
+ variant="outline"
95
+ size="icon"
96
+ className="h-8 w-8"
97
+ onClick={() => table.setPageIndex(0)}
98
+ disabled={!table.getCanPreviousPage()}
99
+ >
100
+ <ChevronsLeft className="h-4 w-4" />
101
+ <span className="sr-only">Erste Seite</span>
102
+ </Button>
103
+ <Button
104
+ variant="outline"
105
+ size="icon"
106
+ className="h-8 w-8"
107
+ onClick={() => table.previousPage()}
108
+ disabled={!table.getCanPreviousPage()}
109
+ >
110
+ <ChevronLeft className="h-4 w-4" />
111
+ <span className="sr-only">Vorherige Seite</span>
112
+ </Button>
113
+ <Button
114
+ variant="outline"
115
+ size="icon"
116
+ className="h-8 w-8"
117
+ onClick={() => table.nextPage()}
118
+ disabled={!table.getCanNextPage()}
119
+ >
120
+ <ChevronRight className="h-4 w-4" />
121
+ <span className="sr-only">Nächste Seite</span>
122
+ </Button>
123
+ <Button
124
+ variant="outline"
125
+ size="icon"
126
+ className="h-8 w-8"
127
+ onClick={() => table.setPageIndex(table.getPageCount() - 1)}
128
+ disabled={!table.getCanNextPage()}
129
+ >
130
+ <ChevronsRight className="h-4 w-4" />
131
+ <span className="sr-only">Letzte Seite</span>
132
+ </Button>
133
+ </div>
134
+ </div>
135
+ </div>
136
+ );
137
+ }
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ interface DataTableSchemaProps {
4
+ [key: string]: any;
5
+ }
6
+
7
+ export const DataTableSchema = (props: DataTableSchemaProps) => {
8
+ return (
9
+ <div className="data-table-schema">
10
+ <p>TableSchema Placeholder</p>
11
+ </div>
12
+ );
13
+ };