@moontra/moonui 2.3.5 → 2.3.8

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.5",
3
+ "version": "2.3.8",
4
4
  "description": "Premium React component library with modern design and customization",
5
5
  "author": "MoonUI",
6
6
  "license": "MIT",
@@ -15,7 +15,9 @@ const badgeVariants = cva(
15
15
  ["inline-flex items-center justify-center gap-1.5",
16
16
  "font-medium transition-colors duration-200",
17
17
  "border focus:outline-none",
18
- "focus-visible:ring-2 focus-visible:ring-offset-1"],
18
+ "focus-visible:ring-2 focus-visible:ring-offset-1",
19
+ // Auto spacing between badges
20
+ "mr-2 mb-2 last:mr-0"],
19
21
  {
20
22
  variants: {
21
23
  variant: {
@@ -106,6 +108,8 @@ export interface BadgeProps
106
108
  leftIcon?: React.ReactNode;
107
109
  rightIcon?: React.ReactNode;
108
110
  variant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning' | 'ghost' | 'pro' | 'admin';
111
+ /** Disable automatic spacing between badges */
112
+ noAutoSpacing?: boolean;
109
113
  }
110
114
 
111
115
  /**
@@ -121,6 +125,7 @@ export interface BadgeProps
121
125
  * @param props.onRemove - Kaldırma işlevi
122
126
  * @param props.leftIcon - Badge'in solunda görüntülenecek ikon
123
127
  * @param props.rightIcon - Badge'in sağında görüntülenecek ikon
128
+ * @param props.noAutoSpacing - Otomatik spacing'i devre dışı bırak
124
129
  */
125
130
  function Badge({
126
131
  className,
@@ -133,6 +138,7 @@ function Badge({
133
138
  onRemove,
134
139
  leftIcon,
135
140
  rightIcon,
141
+ noAutoSpacing,
136
142
  children,
137
143
  ...props
138
144
  }: BadgeProps) {
@@ -164,7 +170,13 @@ function Badge({
164
170
 
165
171
  return (
166
172
  <div
167
- className={cn("moonui-theme", badgeVariants({ variant, size, radius }), className)}
173
+ className={cn(
174
+ "moonui-theme",
175
+ badgeVariants({ variant, size, radius }),
176
+ // Remove auto-spacing if noAutoSpacing is true
177
+ noAutoSpacing && "mr-0 mb-0",
178
+ className
179
+ )}
168
180
  data-removable={removable ? "" : undefined}
169
181
  {...props}
170
182
  >
@@ -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";