luxtable 0.2.0 → 0.2.2

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/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,19 +17,91 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
18
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
19
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
29
 
21
30
  // src/index.ts
22
31
  var index_exports = {};
23
32
  __export(index_exports, {
33
+ BooleanCell: () => BooleanCell,
34
+ Button: () => Button,
35
+ Checkbox: () => Checkbox,
36
+ ColumnFilter: () => ColumnFilter,
37
+ CopyableCell: () => CopyableCell,
38
+ CurrencyCell: () => CurrencyCell,
39
+ DateCell: () => DateCell,
40
+ DropdownMenu: () => DropdownMenu,
41
+ DropdownMenuCheckboxItem: () => DropdownMenuCheckboxItem,
42
+ DropdownMenuContent: () => DropdownMenuContent,
43
+ DropdownMenuGroup: () => DropdownMenuGroup,
44
+ DropdownMenuItem: () => DropdownMenuItem,
45
+ DropdownMenuLabel: () => DropdownMenuLabel,
46
+ DropdownMenuPortal: () => DropdownMenuPortal,
47
+ DropdownMenuRadioGroup: () => DropdownMenuRadioGroup,
48
+ DropdownMenuRadioItem: () => DropdownMenuRadioItem,
49
+ DropdownMenuSeparator: () => DropdownMenuSeparator,
50
+ DropdownMenuShortcut: () => DropdownMenuShortcut,
51
+ DropdownMenuSub: () => DropdownMenuSub,
52
+ DropdownMenuSubContent: () => DropdownMenuSubContent,
53
+ DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
54
+ DropdownMenuTrigger: () => DropdownMenuTrigger,
55
+ Input: () => Input,
56
+ Label: () => Label3,
57
+ LuxDataTableColumnHeader: () => LuxDataTableColumnHeader,
24
58
  LuxTable: () => LuxTable,
25
- cn: () => cn
59
+ Popover: () => Popover,
60
+ PopoverAnchor: () => PopoverAnchor,
61
+ PopoverContent: () => PopoverContent,
62
+ PopoverTrigger: () => PopoverTrigger,
63
+ ProgressCell: () => ProgressCell,
64
+ Select: () => Select,
65
+ SelectContent: () => SelectContent,
66
+ SelectGroup: () => SelectGroup,
67
+ SelectItem: () => SelectItem,
68
+ SelectLabel: () => SelectLabel,
69
+ SelectScrollDownButton: () => SelectScrollDownButton,
70
+ SelectScrollUpButton: () => SelectScrollUpButton,
71
+ SelectSeparator: () => SelectSeparator,
72
+ SelectTrigger: () => SelectTrigger,
73
+ SelectValue: () => SelectValue,
74
+ Separator: () => Separator3,
75
+ SortIcon: () => SortIcon,
76
+ StatusCell: () => StatusCell,
77
+ Table: () => Table,
78
+ TableBody: () => TableBody,
79
+ TableCaption: () => TableCaption,
80
+ TableCell: () => TableCell,
81
+ TableFooter: () => TableFooter,
82
+ TableHead: () => TableHead,
83
+ TableHeader: () => TableHeader,
84
+ TablePagination: () => TablePagination,
85
+ TableRow: () => TableRow,
86
+ TableToolbar: () => TableToolbar,
87
+ buttonVariants: () => buttonVariants,
88
+ cn: () => cn,
89
+ createColumnHelper: () => createColumnHelper,
90
+ createColumnsFromData: () => createColumnsFromData,
91
+ createCopyableCell: () => createCopyableCell,
92
+ defaultStatusColors: () => defaultStatusColors,
93
+ flexRender: () => import_react_table3.flexRender,
94
+ getCoreRowModel: () => import_react_table3.getCoreRowModel,
95
+ getFilteredRowModel: () => import_react_table3.getFilteredRowModel,
96
+ getPaginationRowModel: () => import_react_table3.getPaginationRowModel,
97
+ getSortedRowModel: () => import_react_table3.getSortedRowModel
26
98
  });
27
99
  module.exports = __toCommonJS(index_exports);
28
100
 
29
- // src/components/LuxTable.tsx
101
+ // src/components/lux-table/lux-table.tsx
102
+ var React7 = __toESM(require("react"));
30
103
  var import_react_table = require("@tanstack/react-table");
104
+ var import_lucide_react7 = require("lucide-react");
31
105
 
32
106
  // src/lib/utils.ts
33
107
  var import_clsx = require("clsx");
@@ -36,75 +110,1535 @@ function cn(...inputs) {
36
110
  return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
37
111
  }
38
112
 
39
- // src/components/LuxTable.tsx
113
+ // src/components/table/table.tsx
114
+ var React = __toESM(require("react"));
40
115
  var import_jsx_runtime = require("react/jsx-runtime");
116
+ var Table = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
+ "table",
118
+ {
119
+ ref,
120
+ className: cn("w-full caption-bottom text-sm", className),
121
+ ...props
122
+ }
123
+ ) }));
124
+ Table.displayName = "Table";
125
+ var TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
126
+ "thead",
127
+ {
128
+ ref,
129
+ className: cn("[&_tr]:border-b [&_tr]:border-slate-200 dark:[&_tr]:border-slate-800", className),
130
+ ...props
131
+ }
132
+ ));
133
+ TableHeader.displayName = "TableHeader";
134
+ var TableBody = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
135
+ "tbody",
136
+ {
137
+ ref,
138
+ className: cn("[&_tr:last-child]:border-0", className),
139
+ ...props
140
+ }
141
+ ));
142
+ TableBody.displayName = "TableBody";
143
+ var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
144
+ "tfoot",
145
+ {
146
+ ref,
147
+ className: cn(
148
+ "border-t border-slate-200 dark:border-slate-800 bg-slate-100/50 dark:bg-slate-800/50 font-medium [&>tr]:last:border-b-0",
149
+ className
150
+ ),
151
+ ...props
152
+ }
153
+ ));
154
+ TableFooter.displayName = "TableFooter";
155
+ var TableRow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
156
+ "tr",
157
+ {
158
+ ref,
159
+ className: cn(
160
+ "border-b border-slate-200 dark:border-slate-800 transition-colors",
161
+ "hover:bg-slate-100/50 dark:hover:bg-slate-800/50",
162
+ "data-[state=selected]:bg-slate-100 dark:data-[state=selected]:bg-slate-800",
163
+ className
164
+ ),
165
+ ...props
166
+ }
167
+ ));
168
+ TableRow.displayName = "TableRow";
169
+ var TableHead = React.forwardRef(({ className, children, ...props }, ref) => {
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
171
+ "th",
172
+ {
173
+ ref,
174
+ className: cn(
175
+ "h-10 px-4 text-left align-middle font-medium text-slate-500 dark:text-slate-400",
176
+ "[&:has([role=checkbox])]:pr-0",
177
+ "group",
178
+ // Enable group-hover for action buttons
179
+ className
180
+ ),
181
+ ...props,
182
+ children
183
+ }
184
+ );
185
+ });
186
+ TableHead.displayName = "TableHead";
187
+ var TableCell = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
188
+ "td",
189
+ {
190
+ ref,
191
+ className: cn(
192
+ "p-4 align-middle [&:has([role=checkbox])]:pr-0",
193
+ className
194
+ ),
195
+ ...props
196
+ }
197
+ ));
198
+ TableCell.displayName = "TableCell";
199
+ var TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
200
+ "caption",
201
+ {
202
+ ref,
203
+ className: cn("mt-4 text-sm text-slate-500 dark:text-slate-400", className),
204
+ ...props
205
+ }
206
+ ));
207
+ TableCaption.displayName = "TableCaption";
208
+
209
+ // src/components/table/sort-icon.tsx
210
+ var import_lucide_react = require("lucide-react");
211
+ var import_jsx_runtime2 = require("react/jsx-runtime");
212
+ function SortIcon({ direction }) {
213
+ if (!direction) {
214
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronsUpDown, { className: "h-4 w-4 text-slate-400 dark:text-slate-500" });
215
+ }
216
+ if (direction === "asc") {
217
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center justify-center rounded bg-blue-100 dark:bg-blue-900/50 p-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronUp, { className: "h-3.5 w-3.5 text-blue-600 dark:text-blue-400", strokeWidth: 2.5 }) });
218
+ }
219
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center justify-center rounded bg-blue-100 dark:bg-blue-900/50 p-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronDown, { className: "h-3.5 w-3.5 text-blue-600 dark:text-blue-400", strokeWidth: 2.5 }) });
220
+ }
221
+
222
+ // src/components/lux-table/column-filter.tsx
223
+ var React4 = __toESM(require("react"));
224
+
225
+ // src/components/ui/input.tsx
226
+ var React2 = __toESM(require("react"));
227
+ var import_jsx_runtime3 = require("react/jsx-runtime");
228
+ var Input = React2.forwardRef(({ className, type, ...props }, ref) => {
229
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
230
+ "input",
231
+ {
232
+ type,
233
+ className: cn(
234
+ "flex h-9 w-full rounded-md border border-slate-200 bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-slate-950 placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-slate-950 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:file:text-slate-50 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",
235
+ className
236
+ ),
237
+ ref,
238
+ ...props
239
+ }
240
+ );
241
+ });
242
+ Input.displayName = "Input";
243
+
244
+ // src/components/ui/select.tsx
245
+ var React3 = __toESM(require("react"));
246
+ var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
247
+ var import_lucide_react2 = require("lucide-react");
248
+ var import_jsx_runtime4 = require("react/jsx-runtime");
249
+ var Select = SelectPrimitive.Root;
250
+ var SelectGroup = SelectPrimitive.Group;
251
+ var SelectValue = SelectPrimitive.Value;
252
+ var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
253
+ SelectPrimitive.Trigger,
254
+ {
255
+ ref,
256
+ className: cn(
257
+ "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-slate-200 bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-white placeholder:text-slate-500 focus:outline-none focus:ring-1 focus:ring-slate-950 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 dark:border-slate-700 dark:ring-offset-slate-950 dark:placeholder:text-slate-400 dark:focus:ring-slate-300",
258
+ className
259
+ ),
260
+ ...props,
261
+ children: [
262
+ children,
263
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
264
+ ]
265
+ }
266
+ ));
267
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
268
+ var SelectScrollUpButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
269
+ SelectPrimitive.ScrollUpButton,
270
+ {
271
+ ref,
272
+ className: cn(
273
+ "flex cursor-default items-center justify-center py-1",
274
+ className
275
+ ),
276
+ ...props,
277
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.ChevronUp, { className: "h-4 w-4" })
278
+ }
279
+ ));
280
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
281
+ var SelectScrollDownButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
282
+ SelectPrimitive.ScrollDownButton,
283
+ {
284
+ ref,
285
+ className: cn(
286
+ "flex cursor-default items-center justify-center py-1",
287
+ className
288
+ ),
289
+ ...props,
290
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.ChevronDown, { className: "h-4 w-4" })
291
+ }
292
+ ));
293
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
294
+ var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
295
+ SelectPrimitive.Content,
296
+ {
297
+ ref,
298
+ className: cn(
299
+ "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-50",
300
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
301
+ className
302
+ ),
303
+ position,
304
+ ...props,
305
+ children: [
306
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectScrollUpButton, {}),
307
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
308
+ SelectPrimitive.Viewport,
309
+ {
310
+ className: cn(
311
+ "p-1",
312
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
313
+ ),
314
+ children
315
+ }
316
+ ),
317
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectScrollDownButton, {})
318
+ ]
319
+ }
320
+ ) }));
321
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
322
+ var SelectLabel = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
323
+ SelectPrimitive.Label,
324
+ {
325
+ ref,
326
+ className: cn("px-2 py-1.5 text-sm font-semibold", className),
327
+ ...props
328
+ }
329
+ ));
330
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
331
+ var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
332
+ SelectPrimitive.Item,
333
+ {
334
+ ref,
335
+ className: cn(
336
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",
337
+ className
338
+ ),
339
+ ...props,
340
+ children: [
341
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Check, { className: "h-4 w-4" }) }) }),
342
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectPrimitive.ItemText, { children })
343
+ ]
344
+ }
345
+ ));
346
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
347
+ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
348
+ SelectPrimitive.Separator,
349
+ {
350
+ ref,
351
+ className: cn("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800", className),
352
+ ...props
353
+ }
354
+ ));
355
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
356
+
357
+ // src/components/lux-table/column-filter.tsx
358
+ var import_jsx_runtime5 = require("react/jsx-runtime");
359
+ function ColumnFilter({ column }) {
360
+ const columnFilterValue = column.getFilterValue();
361
+ const filterVariant = column.columnDef.meta?.filterVariant ?? "text";
362
+ const sortedUniqueValues = React4.useMemo(() => {
363
+ if (filterVariant !== "select") return [];
364
+ const values = /* @__PURE__ */ new Set();
365
+ column.getFacetedUniqueValues().forEach((_, key) => {
366
+ if (key !== null && key !== void 0) {
367
+ values.add(String(key));
368
+ }
369
+ });
370
+ return Array.from(values).sort();
371
+ }, [column, filterVariant]);
372
+ if (filterVariant === "select") {
373
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
374
+ Select,
375
+ {
376
+ value: columnFilterValue ?? "",
377
+ onValueChange: (value) => column.setFilterValue(value === "__all__" ? void 0 : value),
378
+ children: [
379
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
380
+ SelectTrigger,
381
+ {
382
+ className: cn(
383
+ "h-8 text-xs",
384
+ "border-slate-200 dark:border-slate-700",
385
+ "bg-white dark:bg-slate-900",
386
+ "text-slate-900 dark:text-slate-100"
387
+ ),
388
+ onClick: (e) => e.stopPropagation(),
389
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SelectValue, { placeholder: "All" })
390
+ }
391
+ ),
392
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(SelectContent, { children: [
393
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SelectItem, { value: "__all__", children: "All" }),
394
+ sortedUniqueValues.map((value) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SelectItem, { value, children: value }, value))
395
+ ] })
396
+ ]
397
+ }
398
+ );
399
+ }
400
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
401
+ Input,
402
+ {
403
+ type: "text",
404
+ value: columnFilterValue ?? "",
405
+ onChange: (e) => column.setFilterValue(e.target.value || void 0),
406
+ placeholder: "Filter...",
407
+ className: cn(
408
+ "h-8 text-xs",
409
+ "border-slate-200 dark:border-slate-700",
410
+ "bg-white dark:bg-slate-900",
411
+ "text-slate-900 dark:text-slate-100",
412
+ "placeholder:text-slate-400 dark:placeholder:text-slate-500"
413
+ ),
414
+ onClick: (e) => e.stopPropagation()
415
+ }
416
+ );
417
+ }
418
+
419
+ // src/components/lux-table/pagination.tsx
420
+ var import_lucide_react3 = require("lucide-react");
421
+ var import_jsx_runtime6 = require("react/jsx-runtime");
422
+ function PaginationButton({ onClick, disabled, title, children }) {
423
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
424
+ "button",
425
+ {
426
+ className: cn(
427
+ "inline-flex items-center justify-center rounded-md text-sm font-medium",
428
+ "h-9 w-9",
429
+ "border border-slate-200 dark:border-slate-800",
430
+ "bg-white dark:bg-slate-950",
431
+ "hover:bg-slate-100 dark:hover:bg-slate-800",
432
+ "disabled:pointer-events-none disabled:opacity-50",
433
+ "transition-colors"
434
+ ),
435
+ onClick,
436
+ disabled,
437
+ title,
438
+ children
439
+ }
440
+ );
441
+ }
442
+ function PageNumberButton({ pageNum, isActive, onClick }) {
443
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
444
+ "button",
445
+ {
446
+ onClick,
447
+ className: cn(
448
+ "inline-flex items-center justify-center rounded-md text-sm font-medium",
449
+ "h-9 w-9",
450
+ "transition-colors",
451
+ isActive ? "bg-blue-600 text-white border border-blue-600" : "border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 hover:bg-slate-100 dark:hover:bg-slate-800"
452
+ ),
453
+ children: pageNum + 1
454
+ }
455
+ );
456
+ }
457
+ function TablePagination({ table }) {
458
+ const currentPage = table.getState().pagination.pageIndex;
459
+ const totalPages = table.getPageCount();
460
+ const pageSize = table.getState().pagination.pageSize;
461
+ const totalRows = table.getFilteredRowModel().rows.length;
462
+ const startRow = currentPage * pageSize + 1;
463
+ const endRow = Math.min((currentPage + 1) * pageSize, totalRows);
464
+ const getPageNumbers = () => {
465
+ const pages = [];
466
+ if (totalPages <= 7) {
467
+ for (let i = 0; i < totalPages; i++) {
468
+ pages.push(i);
469
+ }
470
+ } else {
471
+ pages.push(0);
472
+ if (currentPage > 3) {
473
+ pages.push("...");
474
+ }
475
+ for (let i = Math.max(1, currentPage - 1); i <= Math.min(totalPages - 2, currentPage + 1); i++) {
476
+ pages.push(i);
477
+ }
478
+ if (currentPage < totalPages - 4) {
479
+ pages.push("...");
480
+ }
481
+ pages.push(totalPages - 1);
482
+ }
483
+ return pages;
484
+ };
485
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 px-2 py-3", children: [
486
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-4", children: [
487
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: [
488
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-medium text-slate-700 dark:text-slate-300", children: startRow }),
489
+ "-",
490
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-medium text-slate-700 dark:text-slate-300", children: endRow }),
491
+ " ",
492
+ "of",
493
+ " ",
494
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-medium text-slate-700 dark:text-slate-300", children: totalRows }),
495
+ " ",
496
+ "records shown"
497
+ ] }),
498
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2", children: [
499
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm text-slate-500 dark:text-slate-400", children: "Rows per page:" }),
500
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
501
+ "select",
502
+ {
503
+ value: pageSize,
504
+ onChange: (e) => {
505
+ table.setPageSize(Number(e.target.value));
506
+ },
507
+ className: cn(
508
+ "h-9 rounded-md border border-slate-200 dark:border-slate-800",
509
+ "bg-white dark:bg-slate-950",
510
+ "px-3 py-1 text-sm",
511
+ "focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1",
512
+ "cursor-pointer"
513
+ ),
514
+ children: [10, 20, 30, 50, 100].map((size) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: size, children: size }, size))
515
+ }
516
+ )
517
+ ] })
518
+ ] }),
519
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2", children: [
520
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
521
+ PaginationButton,
522
+ {
523
+ onClick: () => table.setPageIndex(0),
524
+ disabled: !table.getCanPreviousPage(),
525
+ title: "First page",
526
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.ChevronsLeft, { className: "h-4 w-4" })
527
+ }
528
+ ),
529
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
530
+ PaginationButton,
531
+ {
532
+ onClick: () => table.previousPage(),
533
+ disabled: !table.getCanPreviousPage(),
534
+ title: "Previous page",
535
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.ChevronLeft, { className: "h-4 w-4" })
536
+ }
537
+ ),
538
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex items-center gap-1", children: getPageNumbers().map((page, idx) => {
539
+ if (page === "...") {
540
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "px-2 text-slate-400", children: "..." }, `ellipsis-${idx}`);
541
+ }
542
+ const pageNum = page;
543
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
544
+ PageNumberButton,
545
+ {
546
+ pageNum,
547
+ isActive: pageNum === currentPage,
548
+ onClick: () => table.setPageIndex(pageNum)
549
+ },
550
+ pageNum
551
+ );
552
+ }) }),
553
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
554
+ PaginationButton,
555
+ {
556
+ onClick: () => table.nextPage(),
557
+ disabled: !table.getCanNextPage(),
558
+ title: "Next page",
559
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.ChevronRight, { className: "h-4 w-4" })
560
+ }
561
+ ),
562
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
563
+ PaginationButton,
564
+ {
565
+ onClick: () => table.setPageIndex(table.getPageCount() - 1),
566
+ disabled: !table.getCanNextPage(),
567
+ title: "Last page",
568
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.ChevronsRight, { className: "h-4 w-4" })
569
+ }
570
+ )
571
+ ] })
572
+ ] });
573
+ }
574
+
575
+ // src/components/lux-table/table-toolbar.tsx
576
+ var React6 = __toESM(require("react"));
577
+ var import_lucide_react5 = require("lucide-react");
578
+
579
+ // src/components/ui/button.tsx
580
+ var import_react_slot = require("@radix-ui/react-slot");
581
+ var import_class_variance_authority = require("class-variance-authority");
582
+ var import_jsx_runtime7 = require("react/jsx-runtime");
583
+ var buttonVariants = (0, import_class_variance_authority.cva)(
584
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
585
+ {
586
+ variants: {
587
+ variant: {
588
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
589
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
590
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
591
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
592
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
593
+ link: "text-primary underline-offset-4 hover:underline"
594
+ },
595
+ size: {
596
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
597
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
598
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
599
+ icon: "size-9",
600
+ "icon-sm": "size-8",
601
+ "icon-lg": "size-10"
602
+ }
603
+ },
604
+ defaultVariants: {
605
+ variant: "default",
606
+ size: "default"
607
+ }
608
+ }
609
+ );
610
+ function Button({
611
+ className,
612
+ variant = "default",
613
+ size = "default",
614
+ asChild = false,
615
+ ...props
616
+ }) {
617
+ const Comp = asChild ? import_react_slot.Slot : "button";
618
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
619
+ Comp,
620
+ {
621
+ "data-slot": "button",
622
+ "data-variant": variant,
623
+ "data-size": size,
624
+ className: cn(buttonVariants({ variant, size, className })),
625
+ ...props
626
+ }
627
+ );
628
+ }
629
+
630
+ // src/components/ui/dropdown-menu.tsx
631
+ var React5 = __toESM(require("react"));
632
+ var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
633
+ var import_lucide_react4 = require("lucide-react");
634
+ var import_jsx_runtime8 = require("react/jsx-runtime");
635
+ var DropdownMenu = DropdownMenuPrimitive.Root;
636
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
637
+ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
638
+ var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
639
+ var DropdownMenuSub = DropdownMenuPrimitive.Sub;
640
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
641
+ var DropdownMenuSubTrigger = React5.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
642
+ DropdownMenuPrimitive.SubTrigger,
643
+ {
644
+ ref,
645
+ className: cn(
646
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 dark:focus:bg-slate-800 dark:data-[state=open]:bg-slate-800",
647
+ inset && "pl-8",
648
+ className
649
+ ),
650
+ ...props,
651
+ children: [
652
+ children,
653
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronRight, { className: "ml-auto h-4 w-4" })
654
+ ]
655
+ }
656
+ ));
657
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
658
+ var DropdownMenuSubContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
659
+ DropdownMenuPrimitive.SubContent,
660
+ {
661
+ ref,
662
+ className: cn(
663
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",
664
+ className
665
+ ),
666
+ ...props
667
+ }
668
+ ));
669
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
670
+ var DropdownMenuContent = React5.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
671
+ DropdownMenuPrimitive.Content,
672
+ {
673
+ ref,
674
+ sideOffset,
675
+ className: cn(
676
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",
677
+ className
678
+ ),
679
+ ...props
680
+ }
681
+ ) }));
682
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
683
+ var DropdownMenuItem = React5.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
684
+ DropdownMenuPrimitive.Item,
685
+ {
686
+ ref,
687
+ className: cn(
688
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",
689
+ inset && "pl-8",
690
+ className
691
+ ),
692
+ ...props
693
+ }
694
+ ));
695
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
696
+ var DropdownMenuCheckboxItem = React5.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
697
+ DropdownMenuPrimitive.CheckboxItem,
698
+ {
699
+ ref,
700
+ className: cn(
701
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",
702
+ className
703
+ ),
704
+ checked,
705
+ ...props,
706
+ children: [
707
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.Check, { className: "h-4 w-4" }) }) }),
708
+ children
709
+ ]
710
+ }
711
+ ));
712
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
713
+ var DropdownMenuRadioItem = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
714
+ DropdownMenuPrimitive.RadioItem,
715
+ {
716
+ ref,
717
+ className: cn(
718
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",
719
+ className
720
+ ),
721
+ ...props,
722
+ children: [
723
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.Circle, { className: "h-2 w-2 fill-current" }) }) }),
724
+ children
725
+ ]
726
+ }
727
+ ));
728
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
729
+ var DropdownMenuLabel = React5.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
730
+ DropdownMenuPrimitive.Label,
731
+ {
732
+ ref,
733
+ className: cn(
734
+ "px-2 py-1.5 text-sm font-semibold",
735
+ inset && "pl-8",
736
+ className
737
+ ),
738
+ ...props
739
+ }
740
+ ));
741
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
742
+ var DropdownMenuSeparator = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
743
+ DropdownMenuPrimitive.Separator,
744
+ {
745
+ ref,
746
+ className: cn("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800", className),
747
+ ...props
748
+ }
749
+ ));
750
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
751
+ var DropdownMenuShortcut = ({
752
+ className,
753
+ ...props
754
+ }) => {
755
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
756
+ "span",
757
+ {
758
+ className: cn("ml-auto text-xs tracking-widest opacity-60", className),
759
+ ...props
760
+ }
761
+ );
762
+ };
763
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
764
+
765
+ // src/components/lux-table/table-toolbar.tsx
766
+ var import_jsx_runtime9 = require("react/jsx-runtime");
767
+ function TableToolbar({
768
+ table,
769
+ showFiltering = true,
770
+ onFilteringToggle,
771
+ filteringEnabled = false,
772
+ showGlobalSearch = true,
773
+ showColumnVisibility = true,
774
+ className
775
+ }) {
776
+ const [globalFilter, setGlobalFilter] = React6.useState("");
777
+ const hidableColumns = table.getAllColumns().filter((column) => column.getCanHide() && column.id !== "__selection__");
778
+ const hiddenColumns = hidableColumns.filter((column) => !column.getIsVisible());
779
+ const handleGlobalSearch = React6.useCallback(
780
+ (value) => {
781
+ setGlobalFilter(value);
782
+ table.setGlobalFilter(value);
783
+ },
784
+ [table]
785
+ );
786
+ const handleResetVisibility = React6.useCallback(() => {
787
+ table.resetColumnVisibility();
788
+ }, [table]);
789
+ const handleShowAllColumns = React6.useCallback(() => {
790
+ hidableColumns.forEach((column) => {
791
+ column.toggleVisibility(true);
792
+ });
793
+ }, [hidableColumns]);
794
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
795
+ "div",
796
+ {
797
+ className: cn(
798
+ "flex flex-wrap items-center gap-2 p-3 rounded-lg border border-slate-200 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50",
799
+ className
800
+ ),
801
+ children: [
802
+ showGlobalSearch && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative flex-1 min-w-[200px] max-w-sm", children: [
803
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" }),
804
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
805
+ "input",
806
+ {
807
+ type: "text",
808
+ placeholder: "Search in all columns...",
809
+ value: globalFilter,
810
+ onChange: (e) => handleGlobalSearch(e.target.value),
811
+ className: cn(
812
+ "w-full h-9 pl-9 pr-3 rounded-md border border-slate-200 dark:border-slate-700",
813
+ "bg-white dark:bg-slate-950 text-sm text-slate-900 dark:text-slate-100",
814
+ "placeholder:text-slate-400 dark:placeholder:text-slate-500",
815
+ "focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500",
816
+ "transition-colors"
817
+ )
818
+ }
819
+ ),
820
+ globalFilter && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
821
+ "button",
822
+ {
823
+ onClick: () => handleGlobalSearch(""),
824
+ className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded-full hover:bg-slate-200 dark:hover:bg-slate-700 transition-colors",
825
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.FilterX, { className: "h-3 w-3 text-slate-400" })
826
+ }
827
+ )
828
+ ] }),
829
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2 ml-auto", children: [
830
+ showFiltering && onFilteringToggle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
831
+ Button,
832
+ {
833
+ variant: filteringEnabled ? "default" : "outline",
834
+ size: "sm",
835
+ onClick: () => onFilteringToggle(!filteringEnabled),
836
+ className: "gap-2",
837
+ children: filteringEnabled ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
838
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.FilterX, { className: "h-4 w-4" }),
839
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "hidden sm:inline", children: "Hide Filters" })
840
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
841
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.Filter, { className: "h-4 w-4" }),
842
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "hidden sm:inline", children: "Show Filters" })
843
+ ] })
844
+ }
845
+ ),
846
+ showColumnVisibility && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenu, { children: [
847
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Button, { variant: "outline", size: "sm", className: "gap-2", children: [
848
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.Columns3, { className: "h-4 w-4" }),
849
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "hidden sm:inline", children: "Columns" }),
850
+ hiddenColumns.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ml-1 flex h-5 w-5 items-center justify-center rounded-full bg-blue-500 text-[10px] font-medium text-white", children: hiddenColumns.length }),
851
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.ChevronDown, { className: "h-3 w-3 opacity-50" })
852
+ ] }) }),
853
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenuContent, { align: "end", className: "w-56", children: [
854
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenuLabel, { className: "flex items-center gap-2", children: [
855
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.Columns3, { className: "h-4 w-4" }),
856
+ "Toggle Columns"
857
+ ] }),
858
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuSeparator, {}),
859
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-1 px-2 py-1.5", children: [
860
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
861
+ Button,
862
+ {
863
+ variant: "ghost",
864
+ size: "sm",
865
+ onClick: handleShowAllColumns,
866
+ disabled: hiddenColumns.length === 0,
867
+ className: "h-7 flex-1 text-xs",
868
+ children: [
869
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.Eye, { className: "mr-1 h-3 w-3" }),
870
+ "Show All"
871
+ ]
872
+ }
873
+ ),
874
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
875
+ Button,
876
+ {
877
+ variant: "ghost",
878
+ size: "sm",
879
+ onClick: handleResetVisibility,
880
+ className: "h-7 flex-1 text-xs",
881
+ children: [
882
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.RotateCcw, { className: "mr-1 h-3 w-3" }),
883
+ "Reset"
884
+ ]
885
+ }
886
+ )
887
+ ] }),
888
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuSeparator, {}),
889
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "max-h-[300px] overflow-y-auto", children: hidableColumns.map((column) => {
890
+ const columnDef = column.columnDef;
891
+ const headerText = typeof columnDef.header === "string" ? columnDef.header : column.id;
892
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
893
+ DropdownMenuCheckboxItem,
894
+ {
895
+ checked: column.getIsVisible(),
896
+ onCheckedChange: (value) => column.toggleVisibility(!!value),
897
+ className: "capitalize",
898
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex items-center gap-2", children: [
899
+ column.getIsVisible() ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.Eye, { className: "h-3.5 w-3.5 text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.EyeOff, { className: "h-3.5 w-3.5 text-slate-400" }),
900
+ headerText
901
+ ] })
902
+ },
903
+ column.id
904
+ );
905
+ }) }),
906
+ hiddenColumns.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
907
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuSeparator, {}),
908
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "px-2 py-1.5 text-xs text-slate-500 dark:text-slate-400", children: [
909
+ hiddenColumns.length,
910
+ " column(s) hidden"
911
+ ] })
912
+ ] })
913
+ ] })
914
+ ] })
915
+ ] })
916
+ ]
917
+ }
918
+ );
919
+ }
920
+
921
+ // src/components/ui/checkbox.tsx
922
+ var CheckboxPrimitive = __toESM(require("@radix-ui/react-checkbox"));
923
+ var import_lucide_react6 = require("lucide-react");
924
+ var import_jsx_runtime10 = require("react/jsx-runtime");
925
+ function Checkbox({
926
+ className,
927
+ ...props
928
+ }) {
929
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
930
+ CheckboxPrimitive.Root,
931
+ {
932
+ "data-slot": "checkbox",
933
+ className: cn(
934
+ "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
935
+ className
936
+ ),
937
+ ...props,
938
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
939
+ CheckboxPrimitive.Indicator,
940
+ {
941
+ "data-slot": "checkbox-indicator",
942
+ className: "grid place-content-center text-current transition-none",
943
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.CheckIcon, { className: "size-3.5" })
944
+ }
945
+ )
946
+ }
947
+ );
948
+ }
949
+
950
+ // src/components/lux-table/lux-table.tsx
951
+ var import_jsx_runtime11 = require("react/jsx-runtime");
952
+ function createSelectionColumn() {
953
+ return {
954
+ id: "__selection__",
955
+ header: ({ table }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
956
+ Checkbox,
957
+ {
958
+ checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
959
+ onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value),
960
+ "aria-label": "Select all rows"
961
+ }
962
+ ),
963
+ cell: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
964
+ Checkbox,
965
+ {
966
+ checked: row.getIsSelected(),
967
+ disabled: !row.getCanSelect(),
968
+ onCheckedChange: (value) => row.toggleSelected(!!value),
969
+ "aria-label": "Select row"
970
+ }
971
+ ),
972
+ size: 40,
973
+ enableSorting: false,
974
+ enableHiding: false
975
+ };
976
+ }
41
977
  function LuxTable({
42
978
  columns,
43
979
  data,
44
980
  className,
45
- options
981
+ options,
982
+ sorting: controlledSorting,
983
+ onSortingChange,
984
+ rowSelection: controlledRowSelection,
985
+ onRowSelectionChange,
986
+ onSelectedRowsChange,
987
+ getRowId
46
988
  }) {
989
+ const [internalSorting, setInternalSorting] = React7.useState([]);
990
+ const [columnFilters, setColumnFilters] = React7.useState([]);
991
+ const [globalFilter, setGlobalFilter] = React7.useState("");
992
+ const [filteringVisible, setFilteringVisible] = React7.useState(options?.filtering ?? false);
993
+ const [internalRowSelection, setInternalRowSelection] = React7.useState({});
994
+ const isControlledSorting = controlledSorting !== void 0;
995
+ const sorting = isControlledSorting ? controlledSorting : internalSorting;
996
+ const isControlledRowSelection = controlledRowSelection !== void 0;
997
+ const rowSelection = isControlledRowSelection ? controlledRowSelection : internalRowSelection;
998
+ const selectionMode = options?.selection ?? "none";
999
+ const showCheckbox = options?.showSelectionCheckbox ?? selectionMode !== "none";
1000
+ const enableRowSelection = selectionMode !== "none";
1001
+ const enableMultiRowSelection = selectionMode === "multiple";
1002
+ const tableColumns = React7.useMemo(() => {
1003
+ if (showCheckbox && enableRowSelection) {
1004
+ return [createSelectionColumn(), ...columns];
1005
+ }
1006
+ return columns;
1007
+ }, [columns, showCheckbox, enableRowSelection]);
1008
+ const handleRowSelectionChange = React7.useCallback(
1009
+ (updater) => {
1010
+ const newSelection = typeof updater === "function" ? updater(rowSelection) : updater;
1011
+ if (isControlledRowSelection && onRowSelectionChange) {
1012
+ onRowSelectionChange(newSelection);
1013
+ } else {
1014
+ setInternalRowSelection(newSelection);
1015
+ }
1016
+ },
1017
+ [isControlledRowSelection, onRowSelectionChange, rowSelection]
1018
+ );
47
1019
  const table = (0, import_react_table.useReactTable)({
48
1020
  data,
49
- columns,
1021
+ columns: tableColumns,
1022
+ state: {
1023
+ sorting,
1024
+ columnFilters,
1025
+ rowSelection,
1026
+ globalFilter
1027
+ },
1028
+ onGlobalFilterChange: setGlobalFilter,
1029
+ onSortingChange: (updater) => {
1030
+ const newSorting = typeof updater === "function" ? updater(sorting) : updater;
1031
+ if (isControlledSorting && onSortingChange) {
1032
+ onSortingChange(newSorting);
1033
+ } else {
1034
+ setInternalSorting(newSorting);
1035
+ }
1036
+ },
1037
+ onColumnFiltersChange: setColumnFilters,
1038
+ onRowSelectionChange: handleRowSelectionChange,
1039
+ enableRowSelection,
1040
+ enableMultiRowSelection,
1041
+ getRowId: getRowId ?? ((row, index) => {
1042
+ if (typeof row === "object" && row !== null && "id" in row) {
1043
+ return String(row.id);
1044
+ }
1045
+ return String(index);
1046
+ }),
50
1047
  getCoreRowModel: (0, import_react_table.getCoreRowModel)(),
51
1048
  getPaginationRowModel: options?.pagination ? (0, import_react_table.getPaginationRowModel)() : void 0,
52
1049
  getSortedRowModel: (0, import_react_table.getSortedRowModel)(),
53
- getFilteredRowModel: (0, import_react_table.getFilteredRowModel)()
1050
+ getFilteredRowModel: (0, import_react_table.getFilteredRowModel)(),
1051
+ getFacetedUniqueValues: (0, import_react_table.getFacetedUniqueValues)(),
1052
+ initialState: {
1053
+ pagination: {
1054
+ pageSize: options?.pageSize ?? 10
1055
+ }
1056
+ }
54
1057
  });
55
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cn("w-full space-y-4", className), children: [
56
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rounded-md border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "w-full caption-bottom text-sm text-left", children: [
57
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "[&_tr]:border-b [&_tr]:border-slate-200 dark:[&_tr]:border-slate-800", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { className: "border-b transition-colors hover:bg-slate-100/50 dark:hover:bg-slate-800/50 data-[state=selected]:bg-slate-100 dark:data-[state=selected]:bg-slate-800", children: headerGroup.headers.map((header) => {
58
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
59
- "th",
60
- {
61
- className: "h-10 px-4 text-left align-middle font-medium text-slate-500 [&:has([role=checkbox])]:pr-0 dark:text-slate-400",
62
- children: header.isPlaceholder ? null : (0, import_react_table.flexRender)(
63
- header.column.columnDef.header,
64
- header.getContext()
65
- )
66
- },
67
- header.id
68
- );
69
- }) }, headerGroup.id)) }),
70
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { className: "[&_tr:last-child]:border-0", children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
71
- "tr",
1058
+ React7.useEffect(() => {
1059
+ if (onSelectedRowsChange) {
1060
+ const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
1061
+ onSelectedRowsChange(selectedRows);
1062
+ }
1063
+ }, [rowSelection, onSelectedRowsChange, table]);
1064
+ const visibleColumnCount = tableColumns.length;
1065
+ const showToolbar = options?.showToolbar ?? false;
1066
+ const showGlobalSearch = options?.showGlobalSearch ?? true;
1067
+ const showColumnVisibility = options?.showColumnVisibility ?? true;
1068
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cn("w-full space-y-4", className), children: [
1069
+ showToolbar && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1070
+ TableToolbar,
1071
+ {
1072
+ table,
1073
+ showFiltering: options?.filtering !== void 0,
1074
+ filteringEnabled: filteringVisible,
1075
+ onFilteringToggle: setFilteringVisible,
1076
+ showGlobalSearch,
1077
+ showColumnVisibility
1078
+ }
1079
+ ),
1080
+ enableRowSelection && Object.keys(rowSelection).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 px-4 py-2 text-sm bg-blue-50 dark:bg-blue-950/50 text-blue-700 dark:text-blue-300 rounded-lg border border-blue-200 dark:border-blue-800", children: [
1081
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react7.CheckCircle2, { className: "w-4 h-4" }),
1082
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1083
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: Object.keys(rowSelection).length }),
1084
+ " rows selected",
1085
+ table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-blue-500 dark:text-blue-400", children: [
1086
+ " / ",
1087
+ table.getFilteredRowModel().rows.length,
1088
+ " total"
1089
+ ] })
1090
+ ] }),
1091
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1092
+ "button",
1093
+ {
1094
+ type: "button",
1095
+ onClick: () => handleRowSelectionChange({}),
1096
+ className: "ml-auto text-xs hover:text-blue-900 dark:hover:text-blue-100 underline underline-offset-2",
1097
+ children: "Clear selection"
1098
+ }
1099
+ )
1100
+ ] }),
1101
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rounded-md border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Table, { children: [
1102
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(TableHeader, { children: [
1103
+ table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableRow, { children: headerGroup.headers.map((header) => {
1104
+ const isSelectionColumn = header.id === "__selection__";
1105
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1106
+ TableHead,
1107
+ {
1108
+ style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
1109
+ children: header.isPlaceholder ? null : (0, import_react_table.flexRender)(
1110
+ header.column.columnDef.header,
1111
+ header.getContext()
1112
+ )
1113
+ },
1114
+ header.id
1115
+ );
1116
+ }) }, headerGroup.id)),
1117
+ filteringVisible && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableRow, { className: "bg-slate-50/50 dark:bg-slate-900/50", children: table.getHeaderGroups()[0]?.headers.map((header) => {
1118
+ const isSelectionColumn = header.id === "__selection__";
1119
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ColumnFilter, { column: header.column }) : null }, `filter-${header.id}`);
1120
+ }) })
1121
+ ] }),
1122
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1123
+ TableRow,
72
1124
  {
73
1125
  "data-state": row.getIsSelected() && "selected",
74
- className: "border-b border-slate-200 dark:border-slate-800 transition-colors hover:bg-slate-100/50 dark:hover:bg-slate-800/50",
75
- children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "p-4 align-middle [&:has([role=checkbox])]:pr-0", children: (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
1126
+ className: cn(
1127
+ enableRowSelection && "cursor-pointer",
1128
+ row.getIsSelected() && "bg-blue-50/50 dark:bg-blue-950/30"
1129
+ ),
1130
+ onClick: enableRowSelection && !showCheckbox ? () => {
1131
+ if (selectionMode === "single") {
1132
+ handleRowSelectionChange({ [row.id]: true });
1133
+ } else {
1134
+ row.toggleSelected();
1135
+ }
1136
+ } : void 0,
1137
+ children: row.getVisibleCells().map((cell) => {
1138
+ const isSelectionColumn = cell.column.id === "__selection__";
1139
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1140
+ TableCell,
1141
+ {
1142
+ style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
1143
+ onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
1144
+ children: (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext())
1145
+ },
1146
+ cell.id
1147
+ );
1148
+ })
76
1149
  },
77
1150
  row.id
78
- )) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { colSpan: columns.length, className: "h-24 text-center", children: "No results." }) }) })
79
- ] }) }) }),
80
- options?.pagination && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-end space-x-2 py-4", children: [
81
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
82
- "button",
83
- {
84
- className: "px-3 py-1 border rounded text-sm disabled:opacity-50",
85
- onClick: () => table.previousPage(),
86
- disabled: !table.getCanPreviousPage(),
87
- children: "Previous"
88
- }
89
- ),
90
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
91
- "button",
1151
+ )) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
1152
+ ] }) }),
1153
+ options?.pagination && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TablePagination, { table })
1154
+ ] });
1155
+ }
1156
+
1157
+ // src/components/lux-table/column-header.tsx
1158
+ var import_lucide_react8 = require("lucide-react");
1159
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1160
+ function LuxDataTableColumnHeader({
1161
+ column,
1162
+ title,
1163
+ className
1164
+ }) {
1165
+ const isSorted = column.getIsSorted();
1166
+ if (!column.getCanSort()) {
1167
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cn("flex items-center justify-between", className), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-sm font-medium text-muted-foreground", children: title }) });
1168
+ }
1169
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cn("flex items-center justify-between gap-1", className), children: [
1170
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1171
+ Button,
1172
+ {
1173
+ variant: "ghost",
1174
+ size: "sm",
1175
+ className: "-ml-3 h-8 hover:bg-accent",
1176
+ onClick: () => column.toggleSorting(isSorted === "asc"),
1177
+ children: [
1178
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: title }),
1179
+ isSorted === "desc" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.ArrowDown, { className: "ml-1.5 h-4 w-4 text-primary" }) : isSorted === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.ArrowUp, { className: "ml-1.5 h-4 w-4 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.ChevronsUpDown, { className: "ml-1.5 h-4 w-4 text-muted-foreground/50" })
1180
+ ]
1181
+ }
1182
+ ),
1183
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DropdownMenu, { children: [
1184
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1185
+ Button,
92
1186
  {
93
- className: "px-3 py-1 border rounded text-sm disabled:opacity-50",
94
- onClick: () => table.nextPage(),
95
- disabled: !table.getCanNextPage(),
96
- children: "Next"
1187
+ variant: "ghost",
1188
+ size: "icon",
1189
+ className: "h-6 w-6 opacity-0 group-hover:opacity-100 hover:opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
1190
+ children: [
1191
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.MoreVertical, { className: "h-3.5 w-3.5" }),
1192
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sr-only", children: "Column actions" })
1193
+ ]
97
1194
  }
98
- )
1195
+ ) }),
1196
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DropdownMenuContent, { align: "end", children: [
1197
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DropdownMenuItem, { onClick: () => column.toggleSorting(false), children: [
1198
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1199
+ "Sort Ascending"
1200
+ ] }),
1201
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DropdownMenuItem, { onClick: () => column.toggleSorting(true), children: [
1202
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1203
+ "Sort Descending"
1204
+ ] }),
1205
+ isSorted && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1206
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuSeparator, {}),
1207
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DropdownMenuItem, { onClick: () => column.clearSorting(), children: [
1208
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.X, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1209
+ "Clear sorting"
1210
+ ] })
1211
+ ] }),
1212
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuSeparator, {}),
1213
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DropdownMenuItem, { onClick: () => column.toggleVisibility(false), children: [
1214
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.EyeOff, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1215
+ "Hide column"
1216
+ ] })
1217
+ ] })
99
1218
  ] })
100
1219
  ] });
101
1220
  }
102
1221
 
1222
+ // src/components/cell-renderers/status-cell.tsx
1223
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1224
+ var defaultStatusColors = {
1225
+ Active: {
1226
+ bg: "bg-green-100",
1227
+ text: "text-green-800",
1228
+ darkBg: "dark:bg-green-900",
1229
+ darkText: "dark:text-green-300"
1230
+ },
1231
+ Inactive: {
1232
+ bg: "bg-red-100",
1233
+ text: "text-red-800",
1234
+ darkBg: "dark:bg-red-900",
1235
+ darkText: "dark:text-red-300"
1236
+ },
1237
+ Pending: {
1238
+ bg: "bg-yellow-100",
1239
+ text: "text-yellow-800",
1240
+ darkBg: "dark:bg-yellow-900",
1241
+ darkText: "dark:text-yellow-300"
1242
+ },
1243
+ Completed: {
1244
+ bg: "bg-blue-100",
1245
+ text: "text-blue-800",
1246
+ darkBg: "dark:bg-blue-900",
1247
+ darkText: "dark:text-blue-300"
1248
+ },
1249
+ Cancelled: {
1250
+ bg: "bg-gray-100",
1251
+ text: "text-gray-800",
1252
+ darkBg: "dark:bg-gray-900",
1253
+ darkText: "dark:text-gray-300"
1254
+ }
1255
+ };
1256
+ function StatusCell({ value, colors, className }) {
1257
+ const mergedColors = { ...defaultStatusColors, ...colors };
1258
+ const colorConfig = mergedColors[value];
1259
+ if (!colorConfig) {
1260
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: `px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300 ${className || ""}`, children: value });
1261
+ }
1262
+ const { bg, text, darkBg, darkText } = colorConfig;
1263
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${darkBg || ""} ${darkText || ""} ${className || ""}`, children: value });
1264
+ }
1265
+
1266
+ // src/components/cell-renderers/progress-cell.tsx
1267
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1268
+ function ProgressCell({
1269
+ value,
1270
+ barColor = "bg-blue-600",
1271
+ bgColor = "bg-gray-200 dark:bg-gray-700",
1272
+ showLabel = false,
1273
+ className
1274
+ }) {
1275
+ const clampedValue = Math.min(100, Math.max(0, value));
1276
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
1277
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1278
+ "div",
1279
+ {
1280
+ className: `${barColor} h-2.5 rounded-full transition-all`,
1281
+ style: { width: `${clampedValue}%` }
1282
+ }
1283
+ ) }),
1284
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-xs text-gray-500 dark:text-gray-400 w-8", children: [
1285
+ value,
1286
+ "%"
1287
+ ] })
1288
+ ] });
1289
+ }
1290
+
1291
+ // src/components/cell-renderers/boolean-cell.tsx
1292
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1293
+ function BooleanCell({
1294
+ value,
1295
+ trueLabel = "Yes",
1296
+ falseLabel = "No",
1297
+ trueColor = "text-green-600 dark:text-green-400",
1298
+ falseColor = "text-red-600 dark:text-red-400"
1299
+ }) {
1300
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
1301
+ }
1302
+
1303
+ // src/components/cell-renderers/date-cell.tsx
1304
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1305
+ function DateCell({ value, format = "short", locale = "en-US" }) {
1306
+ const date = typeof value === "string" ? new Date(value) : value;
1307
+ if (isNaN(date.getTime())) {
1308
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-gray-400", children: "-" });
1309
+ }
1310
+ let formatted;
1311
+ switch (format) {
1312
+ case "long":
1313
+ formatted = date.toLocaleDateString(locale, {
1314
+ year: "numeric",
1315
+ month: "long",
1316
+ day: "numeric"
1317
+ });
1318
+ break;
1319
+ case "relative": {
1320
+ const now = /* @__PURE__ */ new Date();
1321
+ const diffMs = now.getTime() - date.getTime();
1322
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1323
+ if (diffDays === 0) formatted = "Today";
1324
+ else if (diffDays === 1) formatted = "Yesterday";
1325
+ else if (diffDays < 7) formatted = `${diffDays} days ago`;
1326
+ else formatted = date.toLocaleDateString(locale);
1327
+ break;
1328
+ }
1329
+ default:
1330
+ formatted = date.toLocaleDateString(locale);
1331
+ }
1332
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: formatted });
1333
+ }
1334
+
1335
+ // src/components/cell-renderers/currency-cell.tsx
1336
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1337
+ function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
1338
+ const formatted = new Intl.NumberFormat(locale, {
1339
+ style: "currency",
1340
+ currency
1341
+ }).format(value);
1342
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "font-medium", children: formatted });
1343
+ }
1344
+
1345
+ // src/components/cell-renderers/copyable-cell.tsx
1346
+ var React8 = __toESM(require("react"));
1347
+ var import_lucide_react9 = require("lucide-react");
1348
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1349
+ function CopyableCell({
1350
+ value,
1351
+ feedbackDuration = 2e3,
1352
+ onCopy,
1353
+ className,
1354
+ tooltip = "Click to copy",
1355
+ alwaysShowIcon = false
1356
+ }) {
1357
+ const [copied, setCopied] = React8.useState(false);
1358
+ const [isHovered, setIsHovered] = React8.useState(false);
1359
+ const handleCopy = async (e) => {
1360
+ e.stopPropagation();
1361
+ const textToCopy = String(value);
1362
+ try {
1363
+ await navigator.clipboard.writeText(textToCopy);
1364
+ setCopied(true);
1365
+ onCopy?.(textToCopy);
1366
+ setTimeout(() => {
1367
+ setCopied(false);
1368
+ }, feedbackDuration);
1369
+ } catch (err) {
1370
+ console.error("Copy error:", err);
1371
+ }
1372
+ };
1373
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1374
+ "button",
1375
+ {
1376
+ type: "button",
1377
+ onClick: handleCopy,
1378
+ onMouseEnter: () => setIsHovered(true),
1379
+ onMouseLeave: () => setIsHovered(false),
1380
+ title: tooltip,
1381
+ className: `
1382
+ group inline-flex items-center gap-2
1383
+ px-2 py-1 -mx-2 -my-1
1384
+ rounded-md
1385
+ transition-all duration-200
1386
+ hover:bg-slate-100 dark:hover:bg-slate-800
1387
+ focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1
1388
+ cursor-pointer
1389
+ ${className || ""}
1390
+ `,
1391
+ children: [
1392
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "select-none", children: value }),
1393
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1394
+ "span",
1395
+ {
1396
+ className: `
1397
+ inline-flex items-center justify-center
1398
+ transition-all duration-200
1399
+ ${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
1400
+ `,
1401
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.Copy, { className: "h-3.5 w-3.5 text-slate-400 dark:text-slate-500 group-hover:text-slate-600 dark:group-hover:text-slate-300" })
1402
+ }
1403
+ )
1404
+ ]
1405
+ }
1406
+ );
1407
+ }
1408
+ function createCopyableCell(value, options) {
1409
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CopyableCell, { value, ...options });
1410
+ }
1411
+
1412
+ // src/components/ui/label.tsx
1413
+ var React9 = __toESM(require("react"));
1414
+ var LabelPrimitive = __toESM(require("@radix-ui/react-label"));
1415
+ var import_class_variance_authority2 = require("class-variance-authority");
1416
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1417
+ var labelVariants = (0, import_class_variance_authority2.cva)(
1418
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
1419
+ );
1420
+ var Label3 = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1421
+ LabelPrimitive.Root,
1422
+ {
1423
+ ref,
1424
+ className: cn(labelVariants(), className),
1425
+ ...props
1426
+ }
1427
+ ));
1428
+ Label3.displayName = LabelPrimitive.Root.displayName;
1429
+
1430
+ // src/components/ui/popover.tsx
1431
+ var React10 = __toESM(require("react"));
1432
+ var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"));
1433
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1434
+ var Popover = PopoverPrimitive.Root;
1435
+ var PopoverTrigger = PopoverPrimitive.Trigger;
1436
+ var PopoverAnchor = PopoverPrimitive.Anchor;
1437
+ var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PopoverPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1438
+ PopoverPrimitive.Content,
1439
+ {
1440
+ ref,
1441
+ align,
1442
+ sideOffset,
1443
+ className: cn(
1444
+ "z-50 w-72 rounded-md border border-slate-200 bg-white p-4 text-slate-950 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-50",
1445
+ className
1446
+ ),
1447
+ ...props
1448
+ }
1449
+ ) }));
1450
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
1451
+
1452
+ // src/components/ui/separator.tsx
1453
+ var React11 = __toESM(require("react"));
1454
+ var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"));
1455
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1456
+ var Separator3 = React11.forwardRef(
1457
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1458
+ SeparatorPrimitive.Root,
1459
+ {
1460
+ ref,
1461
+ decorative,
1462
+ orientation,
1463
+ className: cn(
1464
+ "shrink-0 bg-slate-200 dark:bg-slate-800",
1465
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
1466
+ className
1467
+ ),
1468
+ ...props
1469
+ }
1470
+ )
1471
+ );
1472
+ Separator3.displayName = SeparatorPrimitive.Root.displayName;
1473
+
1474
+ // src/lib/column-helper.tsx
1475
+ var import_react_table2 = require("@tanstack/react-table");
1476
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1477
+ var toTitleCase = (str) => {
1478
+ return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
1479
+ };
1480
+ function createColumnHelper() {
1481
+ const helper = (0, import_react_table2.createColumnHelper)();
1482
+ return {
1483
+ /**
1484
+ * Simple accessor - if cell is not provided, value is rendered automatically
1485
+ */
1486
+ accessor: (accessor, column) => {
1487
+ const headerContent = column?.header;
1488
+ const finalColumn = {
1489
+ ...column,
1490
+ // enableSorting is true by default
1491
+ enableSorting: column?.enableSorting !== false,
1492
+ // Pass meta information (filterVariant etc.)
1493
+ meta: column?.meta,
1494
+ // Use LuxDataTableColumnHeader if header is string or undefined
1495
+ header: typeof headerContent === "function" ? headerContent : ({ column: colParam }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1496
+ LuxDataTableColumnHeader,
1497
+ {
1498
+ column: colParam,
1499
+ title: typeof headerContent === "string" ? headerContent : toTitleCase(accessor)
1500
+ }
1501
+ ),
1502
+ // If cell is not defined, show value directly
1503
+ cell: column?.cell || ((info) => {
1504
+ const value = info.getValue();
1505
+ if (value === null || value === void 0) {
1506
+ return "-";
1507
+ }
1508
+ return String(value);
1509
+ })
1510
+ };
1511
+ return helper.accessor(accessor, finalColumn);
1512
+ },
1513
+ /**
1514
+ * Display column (for actions etc.)
1515
+ */
1516
+ display: (column) => {
1517
+ return helper.display(column);
1518
+ },
1519
+ /**
1520
+ * Action column - specialized display column for row actions
1521
+ * Disables sorting by default
1522
+ */
1523
+ action: (column) => {
1524
+ return helper.display({
1525
+ id: "actions",
1526
+ header: "",
1527
+ enableSorting: false,
1528
+ enableHiding: false,
1529
+ ...column
1530
+ });
1531
+ },
1532
+ /**
1533
+ * Create all columns automatically - Table directly from JSON
1534
+ * Just specifying headers is enough, cell is rendered automatically
1535
+ */
1536
+ auto: (columns) => {
1537
+ return columns.map((col) => {
1538
+ return helper.accessor(col.accessor, {
1539
+ header: ({ column }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LuxDataTableColumnHeader, { column, title: col.header }),
1540
+ cell: col.cell || ((info) => {
1541
+ const value = info.getValue();
1542
+ if (value === null || value === void 0) return "-";
1543
+ return String(value);
1544
+ })
1545
+ });
1546
+ });
1547
+ }
1548
+ };
1549
+ }
1550
+ function createColumnsFromData(data, options) {
1551
+ if (!data || data.length === 0) return [];
1552
+ const helper = (0, import_react_table2.createColumnHelper)();
1553
+ const firstRow = data[0];
1554
+ let keys = Object.keys(firstRow);
1555
+ if (options?.include) {
1556
+ keys = keys.filter((k) => options.include?.includes(k));
1557
+ }
1558
+ if (options?.exclude) {
1559
+ keys = keys.filter((k) => !options.exclude?.includes(k));
1560
+ }
1561
+ return keys.map((key) => {
1562
+ const headerText = options?.headers?.[key] || toTitleCase(key);
1563
+ const cellRenderer = options?.cells?.[key];
1564
+ return helper.accessor(key, {
1565
+ header: ({ column }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LuxDataTableColumnHeader, { column, title: headerText }),
1566
+ cell: cellRenderer || ((info) => {
1567
+ const value = info.getValue();
1568
+ if (value === null || value === void 0) return "-";
1569
+ return String(value);
1570
+ })
1571
+ });
1572
+ });
1573
+ }
1574
+
103
1575
  // src/index.ts
104
- __reExport(index_exports, require("@tanstack/react-table"), module.exports);
1576
+ var import_react_table3 = require("@tanstack/react-table");
105
1577
  // Annotate the CommonJS export names for ESM import in node:
106
1578
  0 && (module.exports = {
1579
+ BooleanCell,
1580
+ Button,
1581
+ Checkbox,
1582
+ ColumnFilter,
1583
+ CopyableCell,
1584
+ CurrencyCell,
1585
+ DateCell,
1586
+ DropdownMenu,
1587
+ DropdownMenuCheckboxItem,
1588
+ DropdownMenuContent,
1589
+ DropdownMenuGroup,
1590
+ DropdownMenuItem,
1591
+ DropdownMenuLabel,
1592
+ DropdownMenuPortal,
1593
+ DropdownMenuRadioGroup,
1594
+ DropdownMenuRadioItem,
1595
+ DropdownMenuSeparator,
1596
+ DropdownMenuShortcut,
1597
+ DropdownMenuSub,
1598
+ DropdownMenuSubContent,
1599
+ DropdownMenuSubTrigger,
1600
+ DropdownMenuTrigger,
1601
+ Input,
1602
+ Label,
1603
+ LuxDataTableColumnHeader,
107
1604
  LuxTable,
1605
+ Popover,
1606
+ PopoverAnchor,
1607
+ PopoverContent,
1608
+ PopoverTrigger,
1609
+ ProgressCell,
1610
+ Select,
1611
+ SelectContent,
1612
+ SelectGroup,
1613
+ SelectItem,
1614
+ SelectLabel,
1615
+ SelectScrollDownButton,
1616
+ SelectScrollUpButton,
1617
+ SelectSeparator,
1618
+ SelectTrigger,
1619
+ SelectValue,
1620
+ Separator,
1621
+ SortIcon,
1622
+ StatusCell,
1623
+ Table,
1624
+ TableBody,
1625
+ TableCaption,
1626
+ TableCell,
1627
+ TableFooter,
1628
+ TableHead,
1629
+ TableHeader,
1630
+ TablePagination,
1631
+ TableRow,
1632
+ TableToolbar,
1633
+ buttonVariants,
108
1634
  cn,
109
- ...require("@tanstack/react-table")
1635
+ createColumnHelper,
1636
+ createColumnsFromData,
1637
+ createCopyableCell,
1638
+ defaultStatusColors,
1639
+ flexRender,
1640
+ getCoreRowModel,
1641
+ getFilteredRowModel,
1642
+ getPaginationRowModel,
1643
+ getSortedRowModel
110
1644
  });