@moontra/moonui 2.3.4 → 2.3.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui",
3
- "version": "2.3.4",
3
+ "version": "2.3.6",
4
4
  "description": "Premium React component library with modern design and customization",
5
5
  "author": "MoonUI",
6
6
  "license": "MIT",
@@ -0,0 +1,261 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import {
5
+ ColumnDef,
6
+ SortingState,
7
+ flexRender,
8
+ getCoreRowModel,
9
+ getPaginationRowModel,
10
+ getSortedRowModel,
11
+ getFilteredRowModel,
12
+ useReactTable,
13
+ } from "@tanstack/react-table";
14
+ import { cn } from "../../lib/utils";
15
+ import { Button } from "./button";
16
+ import { Input } from "./input";
17
+ import {
18
+ Table,
19
+ TableBody,
20
+ TableCell,
21
+ TableHead,
22
+ TableHeader,
23
+ TableRow
24
+ } from "./table";
25
+ import {
26
+ ChevronLeft,
27
+ ChevronRight,
28
+ ArrowUpDown,
29
+ ArrowUp,
30
+ ArrowDown,
31
+ Search,
32
+ } from "lucide-react";
33
+
34
+ /**
35
+ * Basic DataTable Component
36
+ *
37
+ * A simple data table with sorting, filtering, and pagination.
38
+ * For advanced features, upgrade to MoonUI Pro.
39
+ */
40
+
41
+ interface DataTableBasicProps<TData, TValue> {
42
+ /**
43
+ * The table columns definition
44
+ */
45
+ columns: ColumnDef<TData, TValue>[];
46
+ /**
47
+ * The data to display
48
+ */
49
+ data: TData[];
50
+ /**
51
+ * Enable/disable sorting
52
+ */
53
+ enableSorting?: boolean;
54
+ /**
55
+ * Enable/disable pagination
56
+ */
57
+ enablePagination?: boolean;
58
+ /**
59
+ * Enable/disable global search
60
+ */
61
+ enableSearch?: boolean;
62
+ /**
63
+ * Default page size
64
+ */
65
+ pageSize?: number;
66
+ /**
67
+ * Search placeholder text
68
+ */
69
+ searchPlaceholder?: string;
70
+ /**
71
+ * Empty state message
72
+ */
73
+ emptyMessage?: string;
74
+ /**
75
+ * Class name
76
+ */
77
+ className?: string;
78
+ }
79
+
80
+ export function DataTableBasic<TData, TValue>({
81
+ columns,
82
+ data,
83
+ enableSorting = true,
84
+ enablePagination = true,
85
+ enableSearch = true,
86
+ pageSize = 10,
87
+ searchPlaceholder = "Search...",
88
+ emptyMessage = "No results found.",
89
+ className,
90
+ }: DataTableBasicProps<TData, TValue>) {
91
+ const [sorting, setSorting] = React.useState<SortingState>([]);
92
+ const [globalFilter, setGlobalFilter] = React.useState("");
93
+
94
+ const table = useReactTable({
95
+ data,
96
+ columns,
97
+ onSortingChange: enableSorting ? setSorting : undefined,
98
+ onGlobalFilterChange: enableSearch ? setGlobalFilter : undefined,
99
+ getCoreRowModel: getCoreRowModel(),
100
+ getPaginationRowModel: enablePagination ? getPaginationRowModel() : undefined,
101
+ getSortedRowModel: enableSorting ? getSortedRowModel() : undefined,
102
+ getFilteredRowModel: enableSearch ? getFilteredRowModel() : undefined,
103
+ state: {
104
+ sorting,
105
+ globalFilter,
106
+ },
107
+ initialState: {
108
+ pagination: {
109
+ pageSize,
110
+ },
111
+ },
112
+ });
113
+
114
+ return (
115
+ <div className={cn("space-y-4", className)}>
116
+ {/* Search */}
117
+ {enableSearch && (
118
+ <div className="flex items-center">
119
+ <div className="relative max-w-sm">
120
+ <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
121
+ <Input
122
+ placeholder={searchPlaceholder}
123
+ value={globalFilter}
124
+ onChange={(event) => setGlobalFilter(event.target.value)}
125
+ className="pl-8"
126
+ />
127
+ </div>
128
+ </div>
129
+ )}
130
+
131
+ {/* Table */}
132
+ <div className="rounded-md border">
133
+ <Table>
134
+ <TableHeader>
135
+ {table.getHeaderGroups().map((headerGroup) => (
136
+ <TableRow key={headerGroup.id}>
137
+ {headerGroup.headers.map((header) => {
138
+ return (
139
+ <TableHead key={header.id}>
140
+ {header.isPlaceholder ? null : (
141
+ <div
142
+ className={cn(
143
+ "flex items-center gap-2",
144
+ header.column.getCanSort() && "cursor-pointer select-none"
145
+ )}
146
+ onClick={header.column.getToggleSortingHandler()}
147
+ >
148
+ {flexRender(
149
+ header.column.columnDef.header,
150
+ header.getContext()
151
+ )}
152
+ {enableSorting && header.column.getCanSort() && (
153
+ <div className="ml-auto">
154
+ {header.column.getIsSorted() === "desc" ? (
155
+ <ArrowDown className="h-4 w-4" />
156
+ ) : header.column.getIsSorted() === "asc" ? (
157
+ <ArrowUp className="h-4 w-4" />
158
+ ) : (
159
+ <ArrowUpDown className="h-4 w-4 opacity-50" />
160
+ )}
161
+ </div>
162
+ )}
163
+ </div>
164
+ )}
165
+ </TableHead>
166
+ );
167
+ })}
168
+ </TableRow>
169
+ ))}
170
+ </TableHeader>
171
+ <TableBody>
172
+ {table.getRowModel().rows?.length ? (
173
+ table.getRowModel().rows.map((row) => (
174
+ <TableRow
175
+ key={row.id}
176
+ data-state={row.getIsSelected() && "selected"}
177
+ >
178
+ {row.getVisibleCells().map((cell) => (
179
+ <TableCell key={cell.id}>
180
+ {flexRender(
181
+ cell.column.columnDef.cell,
182
+ cell.getContext()
183
+ )}
184
+ </TableCell>
185
+ ))}
186
+ </TableRow>
187
+ ))
188
+ ) : (
189
+ <TableRow>
190
+ <TableCell
191
+ colSpan={columns.length}
192
+ className="h-24 text-center"
193
+ >
194
+ {emptyMessage}
195
+ </TableCell>
196
+ </TableRow>
197
+ )}
198
+ </TableBody>
199
+ </Table>
200
+ </div>
201
+
202
+ {/* Pagination */}
203
+ {enablePagination && (
204
+ <div className="flex items-center justify-end space-x-2">
205
+ <div className="flex-1 text-sm text-muted-foreground">
206
+ {table.getFilteredRowModel().rows.length} row(s)
207
+ </div>
208
+ <div className="space-x-2">
209
+ <Button
210
+ variant="outline"
211
+ size="sm"
212
+ onClick={() => table.previousPage()}
213
+ disabled={!table.getCanPreviousPage()}
214
+ >
215
+ <ChevronLeft className="h-4 w-4" />
216
+ Previous
217
+ </Button>
218
+ <span className="text-sm">
219
+ Page {table.getState().pagination.pageIndex + 1} of{" "}
220
+ {table.getPageCount()}
221
+ </span>
222
+ <Button
223
+ variant="outline"
224
+ size="sm"
225
+ onClick={() => table.nextPage()}
226
+ disabled={!table.getCanNextPage()}
227
+ >
228
+ Next
229
+ <ChevronRight className="h-4 w-4" />
230
+ </Button>
231
+ </div>
232
+ </div>
233
+ )}
234
+ </div>
235
+ );
236
+ }
237
+
238
+ /**
239
+ * Simple sortable header helper
240
+ */
241
+ export function createSortableHeader(label: string) {
242
+ return ({ column }: any) => (
243
+ <Button
244
+ variant="ghost"
245
+ className="-ml-3 h-8 data-[state=open]:bg-accent"
246
+ onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
247
+ >
248
+ {label}
249
+ {column.getIsSorted() === "desc" ? (
250
+ <ArrowDown className="ml-2 h-4 w-4" />
251
+ ) : column.getIsSorted() === "asc" ? (
252
+ <ArrowUp className="ml-2 h-4 w-4" />
253
+ ) : (
254
+ <ArrowUpDown className="ml-2 h-4 w-4" />
255
+ )}
256
+ </Button>
257
+ );
258
+ }
259
+
260
+ // Export utilities
261
+ export { type ColumnDef } from "@tanstack/react-table";
@@ -104,8 +104,10 @@ export {
104
104
  CommandSeparator as MoonUICommandSeparator,
105
105
  } from "./command";
106
106
 
107
- // DataTable
108
- export { DataTable as MoonUIDataTable } from "./data-table";
107
+ // DataTable Basic (Free version with limited features)
108
+ export { DataTableBasic as MoonUIDataTableBasic } from "./data-table-basic";
109
+ export { createSortableHeader as moonUICreateSortableHeader } from "./data-table-basic";
110
+ export type { ColumnDef as MoonUIColumnDef } from "./data-table-basic";
109
111
 
110
112
  // DatePicker
111
113
  export {
@@ -322,7 +324,6 @@ export * from "./checkbox";
322
324
  export * from "./collapsible";
323
325
  export * from "./color-picker";
324
326
  export * from "./command";
325
- export * from "./data-table";
326
327
  export * from "./date-picker";
327
328
  export * from "./dialog";
328
329
  export * from "./draggable-list";
@@ -187,7 +187,7 @@ const TabsContent = React.forwardRef<
187
187
  ref={ref}
188
188
  className={cn(
189
189
  "moonui-theme",
190
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
190
+ "mt-6 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
191
191
  animated && "data-[state=active]:animate-fadeIn data-[state=inactive]:animate-fadeOut",
192
192
  className
193
193
  )}