luxtable 0.3.5 → 0.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/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/lux-table/lux-table.tsx
2
- import * as React7 from "react";
2
+ import * as React10 from "react";
3
3
  import {
4
4
  flexRender as flexRender2,
5
5
  getCoreRowModel,
@@ -34,7 +34,7 @@ var TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE_
34
34
  "thead",
35
35
  {
36
36
  ref,
37
- className: cn("[&_tr]:border-b [&_tr]:border-slate-200 dark:[&_tr]:border-slate-800", className),
37
+ className: cn("[&_tr]:border-b [&_tr]:border-[hsl(var(--lux-table-header-border))]", className),
38
38
  ...props
39
39
  }
40
40
  ));
@@ -53,7 +53,7 @@ var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE_
53
53
  {
54
54
  ref,
55
55
  className: cn(
56
- "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",
56
+ "border-t border-[hsl(var(--lux-table-footer-border))] bg-[hsl(var(--lux-table-footer-background))] text-[hsl(var(--lux-table-footer-foreground))] font-medium [&>tr]:last:border-b-0",
57
57
  className
58
58
  ),
59
59
  ...props
@@ -65,9 +65,9 @@ var TableRow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
65
65
  {
66
66
  ref,
67
67
  className: cn(
68
- "border-b border-slate-200 dark:border-slate-800 transition-colors",
69
- "hover:bg-slate-100/50 dark:hover:bg-slate-800/50",
70
- "data-[state=selected]:bg-slate-100 dark:data-[state=selected]:bg-slate-800",
68
+ "border-b border-[hsl(var(--lux-table-row-border))] transition-colors",
69
+ "hover:bg-[hsl(var(--lux-table-row-hover))]",
70
+ "data-[state=selected]:bg-[hsl(var(--lux-table-row-selected))]",
71
71
  className
72
72
  ),
73
73
  ...props
@@ -80,7 +80,7 @@ var TableHead = React.forwardRef(({ className, children, ...props }, ref) => {
80
80
  {
81
81
  ref,
82
82
  className: cn(
83
- "h-10 px-4 text-left align-middle font-medium text-slate-500 dark:text-slate-400",
83
+ "h-10 px-4 text-left align-middle font-medium text-[hsl(var(--lux-table-header-foreground))]",
84
84
  "[&:has([role=checkbox])]:pr-0",
85
85
  "group",
86
86
  // Enable group-hover for action buttons
@@ -97,9 +97,15 @@ var TableCell = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__
97
97
  {
98
98
  ref,
99
99
  className: cn(
100
- "p-4 align-middle [&:has([role=checkbox])]:pr-0",
100
+ "p-4 align-middle text-[hsl(var(--lux-table-cell-foreground))] [&:has([role=checkbox])]:pr-0",
101
+ "[&>*]:text-[hsl(var(--lux-table-cell-foreground))]",
102
+ "[&_*]:text-[hsl(var(--lux-table-cell-foreground))]",
101
103
  className
102
104
  ),
105
+ style: {
106
+ color: "hsl(var(--lux-table-cell-foreground))",
107
+ ...props.style
108
+ },
103
109
  ...props
104
110
  }
105
111
  ));
@@ -108,7 +114,7 @@ var TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE
108
114
  "caption",
109
115
  {
110
116
  ref,
111
- className: cn("mt-4 text-sm text-slate-500 dark:text-slate-400", className),
117
+ className: cn("mt-4 text-sm text-[hsl(var(--lux-table-cell-muted))]", className),
112
118
  ...props
113
119
  }
114
120
  ));
@@ -119,16 +125,16 @@ import { ChevronsUpDown, ChevronUp, ChevronDown } from "lucide-react";
119
125
  import { jsx as jsx2 } from "react/jsx-runtime";
120
126
  function SortIcon({ direction }) {
121
127
  if (!direction) {
122
- return /* @__PURE__ */ jsx2(ChevronsUpDown, { className: "h-4 w-4 text-slate-400 dark:text-slate-500" });
128
+ return /* @__PURE__ */ jsx2(ChevronsUpDown, { className: "h-4 w-4 text-slate-400/60 dark:text-slate-600" });
123
129
  }
124
130
  if (direction === "asc") {
125
- return /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-center rounded bg-blue-100 dark:bg-blue-900/50 p-0.5", children: /* @__PURE__ */ jsx2(ChevronUp, { className: "h-3.5 w-3.5 text-blue-600 dark:text-blue-400", strokeWidth: 2.5 }) });
131
+ return /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-center rounded-md bg-gradient-to-br from-emerald-500/15 to-teal-500/15 dark:from-emerald-400/20 dark:to-teal-400/20 p-0.5 ring-1 ring-emerald-500/20 dark:ring-emerald-400/25", children: /* @__PURE__ */ jsx2(ChevronUp, { className: "h-3.5 w-3.5 text-emerald-600 dark:text-emerald-400", strokeWidth: 2.5 }) });
126
132
  }
127
- return /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-center rounded bg-blue-100 dark:bg-blue-900/50 p-0.5", children: /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-blue-600 dark:text-blue-400", strokeWidth: 2.5 }) });
133
+ return /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-center rounded-md bg-gradient-to-br from-emerald-500/15 to-teal-500/15 dark:from-emerald-400/20 dark:to-teal-400/20 p-0.5 ring-1 ring-emerald-500/20 dark:ring-emerald-400/25", children: /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-emerald-600 dark:text-emerald-400", strokeWidth: 2.5 }) });
128
134
  }
129
135
 
130
136
  // src/components/lux-table/column-filter.tsx
131
- import * as React4 from "react";
137
+ import * as React6 from "react";
132
138
 
133
139
  // src/components/ui/input.tsx
134
140
  import * as React2 from "react";
@@ -139,7 +145,7 @@ var Input = React2.forwardRef(({ className, type, ...props }, ref) => {
139
145
  {
140
146
  type,
141
147
  className: cn(
142
- "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",
148
+ "flex h-9 w-full rounded-md border border-input 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-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
143
149
  className
144
150
  ),
145
151
  ref,
@@ -162,7 +168,7 @@ var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) =
162
168
  {
163
169
  ref,
164
170
  className: cn(
165
- "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",
171
+ "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
166
172
  className
167
173
  ),
168
174
  ...props,
@@ -204,7 +210,7 @@ var SelectContent = React3.forwardRef(({ className, children, position = "popper
204
210
  {
205
211
  ref,
206
212
  className: cn(
207
- "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",
213
+ "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover text-popover-foreground 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",
208
214
  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",
209
215
  className
210
216
  ),
@@ -241,7 +247,7 @@ var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /
241
247
  {
242
248
  ref,
243
249
  className: cn(
244
- "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",
250
+ "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-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
245
251
  className
246
252
  ),
247
253
  ...props,
@@ -256,19 +262,352 @@ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__
256
262
  SelectPrimitive.Separator,
257
263
  {
258
264
  ref,
259
- className: cn("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800", className),
265
+ className: cn("-mx-1 my-1 h-px bg-border", className),
260
266
  ...props
261
267
  }
262
268
  ));
263
269
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
264
270
 
265
- // src/components/lux-table/column-filter.tsx
271
+ // src/components/ui/slider.tsx
272
+ import * as React4 from "react";
266
273
  import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
267
- function ColumnFilter({ column }) {
274
+ var Slider = React4.forwardRef(
275
+ ({ className, value = [0, 100], onValueChange, min = 0, max = 100, step = 1, ...props }, ref) => {
276
+ const [localValue, setLocalValue] = React4.useState(value);
277
+ React4.useEffect(() => {
278
+ setLocalValue(value);
279
+ }, [value]);
280
+ const handleChange = (index, newValue) => {
281
+ const newValues = [...localValue];
282
+ newValues[index] = Math.max(min, Math.min(max, newValue));
283
+ if (newValues.length === 2) {
284
+ if (index === 0 && newValues[0] > newValues[1]) {
285
+ newValues[0] = newValues[1];
286
+ } else if (index === 1 && newValues[1] < newValues[0]) {
287
+ newValues[1] = newValues[0];
288
+ }
289
+ }
290
+ setLocalValue(newValues);
291
+ onValueChange?.(newValues);
292
+ };
293
+ const percentage = (val) => (val - min) / (max - min) * 100;
294
+ return /* @__PURE__ */ jsx5("div", { className: cn("relative flex w-full items-center", className), children: localValue.length === 2 ? (
295
+ // Range slider
296
+ /* @__PURE__ */ jsxs2("div", { className: "relative w-full", children: [
297
+ /* @__PURE__ */ jsx5(
298
+ "input",
299
+ {
300
+ ref,
301
+ type: "range",
302
+ min,
303
+ max,
304
+ step,
305
+ value: localValue[0],
306
+ onChange: (e) => handleChange(0, Number(e.target.value)),
307
+ className: "absolute h-2 w-full appearance-none bg-transparent pointer-events-none z-10 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[hsl(var(--lux-focus-ring))] [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-[hsl(var(--lux-filter-background))] [&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:pointer-events-auto [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[hsl(var(--lux-focus-ring))] [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-[hsl(var(--lux-filter-background))] [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:pointer-events-auto",
308
+ style: { zIndex: localValue[0] > localValue[1] ? 20 : 10 },
309
+ ...props
310
+ }
311
+ ),
312
+ /* @__PURE__ */ jsx5(
313
+ "input",
314
+ {
315
+ type: "range",
316
+ min,
317
+ max,
318
+ step,
319
+ value: localValue[1],
320
+ onChange: (e) => handleChange(1, Number(e.target.value)),
321
+ className: "absolute h-2 w-full appearance-none bg-transparent pointer-events-none z-10 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[hsl(var(--lux-focus-ring))] [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-[hsl(var(--lux-filter-background))] [&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:pointer-events-auto [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[hsl(var(--lux-focus-ring))] [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-[hsl(var(--lux-filter-background))] [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:pointer-events-auto",
322
+ style: { zIndex: localValue[1] > localValue[0] ? 20 : 10 }
323
+ }
324
+ ),
325
+ /* @__PURE__ */ jsx5("div", { className: "absolute h-2 w-full rounded-full bg-[hsl(var(--lux-filter-border))]" }),
326
+ /* @__PURE__ */ jsx5(
327
+ "div",
328
+ {
329
+ className: "absolute h-2 rounded-full bg-[hsl(var(--lux-focus-ring))]",
330
+ style: {
331
+ left: `${percentage(Math.min(localValue[0], localValue[1]))}%`,
332
+ width: `${percentage(Math.max(localValue[0], localValue[1])) - percentage(Math.min(localValue[0], localValue[1]))}%`
333
+ }
334
+ }
335
+ )
336
+ ] })
337
+ ) : (
338
+ // Single value slider
339
+ /* @__PURE__ */ jsxs2("div", { className: "relative w-full", children: [
340
+ /* @__PURE__ */ jsx5(
341
+ "input",
342
+ {
343
+ ref,
344
+ type: "range",
345
+ min,
346
+ max,
347
+ step,
348
+ value: localValue[0],
349
+ onChange: (e) => handleChange(0, Number(e.target.value)),
350
+ className: "h-2 w-full appearance-none rounded-full bg-[hsl(var(--lux-filter-border))] [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[hsl(var(--lux-focus-ring))] [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-[hsl(var(--lux-filter-background))] [&::-webkit-slider-thumb]:cursor-pointer [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-[hsl(var(--lux-focus-ring))] [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-[hsl(var(--lux-filter-background))] [&::-moz-range-thumb]:cursor-pointer",
351
+ ...props
352
+ }
353
+ ),
354
+ /* @__PURE__ */ jsx5(
355
+ "div",
356
+ {
357
+ className: "absolute top-0 h-2 rounded-full bg-[hsl(var(--lux-focus-ring))] pointer-events-none",
358
+ style: { width: `${percentage(localValue[0])}%` }
359
+ }
360
+ )
361
+ ] })
362
+ ) });
363
+ }
364
+ );
365
+ Slider.displayName = "Slider";
366
+
367
+ // src/components/ui/popover.tsx
368
+ import * as React5 from "react";
369
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
370
+ import { jsx as jsx6 } from "react/jsx-runtime";
371
+ var Popover = PopoverPrimitive.Root;
372
+ var PopoverTrigger = PopoverPrimitive.Trigger;
373
+ var PopoverAnchor = PopoverPrimitive.Anchor;
374
+ var PopoverContent = React5.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx6(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx6(
375
+ PopoverPrimitive.Content,
376
+ {
377
+ ref,
378
+ align,
379
+ sideOffset,
380
+ className: cn(
381
+ "z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground 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",
382
+ className
383
+ ),
384
+ ...props
385
+ }
386
+ ) }));
387
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
388
+
389
+ // src/components/ui/button.tsx
390
+ import { Slot } from "@radix-ui/react-slot";
391
+ import { cva } from "class-variance-authority";
392
+ import { jsx as jsx7 } from "react/jsx-runtime";
393
+ var buttonVariants = cva(
394
+ "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",
395
+ {
396
+ variants: {
397
+ variant: {
398
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
399
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
400
+ 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",
401
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
402
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
403
+ link: "text-primary underline-offset-4 hover:underline"
404
+ },
405
+ size: {
406
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
407
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
408
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
409
+ icon: "size-9",
410
+ "icon-sm": "size-8",
411
+ "icon-lg": "size-10"
412
+ }
413
+ },
414
+ defaultVariants: {
415
+ variant: "default",
416
+ size: "default"
417
+ }
418
+ }
419
+ );
420
+ function Button({
421
+ className,
422
+ variant = "default",
423
+ size = "default",
424
+ asChild = false,
425
+ ...props
426
+ }) {
427
+ const Comp = asChild ? Slot : "button";
428
+ return /* @__PURE__ */ jsx7(
429
+ Comp,
430
+ {
431
+ "data-slot": "button",
432
+ "data-variant": variant,
433
+ "data-size": size,
434
+ className: cn(buttonVariants({ variant, size, className })),
435
+ ...props
436
+ }
437
+ );
438
+ }
439
+
440
+ // src/components/ui/calendar.tsx
441
+ import { ChevronLeft, ChevronRight } from "lucide-react";
442
+ import { DayPicker } from "react-day-picker";
443
+ import { jsx as jsx8 } from "react/jsx-runtime";
444
+ function Calendar({
445
+ className,
446
+ classNames,
447
+ showOutsideDays = true,
448
+ ...props
449
+ }) {
450
+ return /* @__PURE__ */ jsx8(
451
+ DayPicker,
452
+ {
453
+ showOutsideDays,
454
+ className: cn("p-3", className),
455
+ classNames: {
456
+ months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
457
+ month: "space-y-4",
458
+ caption: "flex justify-center pt-1 relative items-center",
459
+ caption_label: "text-sm font-medium",
460
+ nav: "space-x-1 flex items-center",
461
+ nav_button: cn(
462
+ "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
463
+ "border border-[hsl(var(--lux-filter-border))] rounded-md",
464
+ "hover:bg-[hsl(var(--lux-table-row-hover))]",
465
+ "inline-flex items-center justify-center"
466
+ ),
467
+ nav_button_previous: "absolute left-1",
468
+ nav_button_next: "absolute right-1",
469
+ table: "w-full border-collapse space-y-1",
470
+ head_row: "flex",
471
+ head_cell: "text-[hsl(var(--lux-toolbar-icon))] rounded-md w-9 font-normal text-[0.8rem]",
472
+ row: "flex w-full mt-2",
473
+ cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-[hsl(var(--lux-table-row-hover))]/50 [&:has([aria-selected])]:bg-[hsl(var(--lux-focus-ring))]/10 first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
474
+ day: cn(
475
+ "h-9 w-9 p-0 font-normal aria-selected:opacity-100",
476
+ "rounded-md hover:bg-[hsl(var(--lux-table-row-hover))]",
477
+ "inline-flex items-center justify-center"
478
+ ),
479
+ day_range_end: "day-range-end",
480
+ day_selected: "bg-[hsl(var(--lux-focus-ring))] text-[hsl(var(--lux-filter-background))] hover:bg-[hsl(var(--lux-focus-ring))] hover:text-[hsl(var(--lux-filter-background))] focus:bg-[hsl(var(--lux-focus-ring))] focus:text-[hsl(var(--lux-filter-background))]",
481
+ day_today: "bg-[hsl(var(--lux-filter-border))] text-[hsl(var(--lux-filter-foreground))]",
482
+ day_outside: "day-outside text-[hsl(var(--lux-toolbar-icon))] opacity-50 aria-selected:bg-[hsl(var(--lux-table-row-hover))]/50 aria-selected:text-[hsl(var(--lux-toolbar-icon))] aria-selected:opacity-30",
483
+ day_disabled: "text-[hsl(var(--lux-toolbar-icon))] opacity-50",
484
+ day_range_middle: "aria-selected:bg-[hsl(var(--lux-focus-ring))]/20 aria-selected:text-[hsl(var(--lux-filter-foreground))]",
485
+ day_hidden: "invisible",
486
+ ...classNames
487
+ },
488
+ components: {
489
+ IconLeft: ({ ...props2 }) => /* @__PURE__ */ jsx8(ChevronLeft, { className: "h-4 w-4" }),
490
+ IconRight: ({ ...props2 }) => /* @__PURE__ */ jsx8(ChevronRight, { className: "h-4 w-4" })
491
+ },
492
+ ...props
493
+ }
494
+ );
495
+ }
496
+ Calendar.displayName = "Calendar";
497
+
498
+ // src/components/lux-table/column-filter.tsx
499
+ import { CalendarIcon, X } from "lucide-react";
500
+
501
+ // src/components/cell-renderers/status-cell.tsx
502
+ import { jsx as jsx9 } from "react/jsx-runtime";
503
+ var createStatusColor = (bg, text, darkBg, darkText) => ({
504
+ bg,
505
+ text,
506
+ darkBg,
507
+ darkText
508
+ });
509
+ var statusColorMap = {
510
+ active: createStatusColor(
511
+ "bg-[hsl(var(--lux-status-active-bg))]",
512
+ "text-[hsl(var(--lux-status-active-text))]",
513
+ "",
514
+ ""
515
+ ),
516
+ inactive: createStatusColor(
517
+ "bg-[hsl(var(--lux-status-inactive-bg))]",
518
+ "text-[hsl(var(--lux-status-inactive-text))]",
519
+ "",
520
+ ""
521
+ ),
522
+ pending: createStatusColor(
523
+ "bg-[hsl(var(--lux-status-pending-bg))]",
524
+ "text-[hsl(var(--lux-status-pending-text))]",
525
+ "",
526
+ ""
527
+ ),
528
+ completed: createStatusColor(
529
+ "bg-[hsl(var(--lux-status-completed-bg))]",
530
+ "text-[hsl(var(--lux-status-completed-text))]",
531
+ "",
532
+ ""
533
+ ),
534
+ cancelled: createStatusColor(
535
+ "bg-[hsl(var(--lux-status-cancelled-bg))]",
536
+ "text-[hsl(var(--lux-status-cancelled-text))]",
537
+ "",
538
+ ""
539
+ )
540
+ };
541
+ var defaultStatusColors = {
542
+ // Lowercase versions
543
+ ...statusColorMap,
544
+ // Capitalized versions
545
+ Active: statusColorMap.active,
546
+ Inactive: statusColorMap.inactive,
547
+ Pending: statusColorMap.pending,
548
+ Completed: statusColorMap.completed,
549
+ Cancelled: statusColorMap.cancelled
550
+ };
551
+ function StatusCell({ value, colors, className }) {
552
+ const mergedColors = { ...defaultStatusColors, ...colors };
553
+ const normalizedValue = value.toLowerCase();
554
+ const capitalizedValue = value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
555
+ const colorConfig = mergedColors[normalizedValue] || mergedColors[value] || mergedColors[capitalizedValue];
556
+ const displayValue = capitalizedValue;
557
+ if (!colorConfig) {
558
+ return /* @__PURE__ */ jsx9("span", { className: `px-2 py-1 rounded-full text-xs font-medium bg-[hsl(var(--lux-status-default-bg))] text-[hsl(var(--lux-status-default-text))] ${className || ""}`, children: displayValue });
559
+ }
560
+ const { bg, text } = colorConfig;
561
+ return /* @__PURE__ */ jsx9("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${className || ""}`, children: displayValue });
562
+ }
563
+
564
+ // src/components/lux-table/column-filter.tsx
565
+ import { format } from "date-fns";
566
+ import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
567
+ function detectFilterType(column, data) {
568
+ const meta = column.columnDef.meta;
569
+ if (meta?.filterVariant) {
570
+ return meta.filterVariant;
571
+ }
572
+ const columnId = column.id.toLowerCase();
573
+ const accessorKey = "accessorKey" in column.columnDef ? String(column.columnDef.accessorKey || "").toLowerCase() : "";
574
+ const datePatterns = ["date", "createdat", "updatedat", "joindate", "startdate", "enddate", "birthdate", "publishedat"];
575
+ if (datePatterns.some((pattern) => columnId.includes(pattern) || accessorKey.includes(pattern))) {
576
+ return "date";
577
+ }
578
+ const statusPatterns = ["status", "state", "stage", "phase"];
579
+ if (statusPatterns.some((pattern) => columnId.includes(pattern) || accessorKey.includes(pattern))) {
580
+ return "status";
581
+ }
582
+ const numericPatterns = ["salary", "price", "amount", "cost", "revenue", "total", "balance", "fee"];
583
+ if (numericPatterns.some((pattern) => columnId.includes(pattern) || accessorKey.includes(pattern))) {
584
+ return "slider";
585
+ }
586
+ if (data && data.length > 0) {
587
+ const firstValue = column.getFacetedUniqueValues().keys().next().value;
588
+ if (firstValue !== void 0) {
589
+ if (typeof firstValue === "string" && /^\d{4}-\d{2}-\d{2}/.test(firstValue)) {
590
+ const date = new Date(firstValue);
591
+ if (!isNaN(date.getTime())) {
592
+ return "date";
593
+ }
594
+ }
595
+ if (typeof firstValue === "number") {
596
+ return "slider";
597
+ }
598
+ const statusValues = ["active", "inactive", "pending", "completed", "cancelled", "approved", "rejected"];
599
+ if (typeof firstValue === "string" && statusValues.includes(firstValue.toLowerCase())) {
600
+ return "status";
601
+ }
602
+ }
603
+ }
604
+ return "text";
605
+ }
606
+ function ColumnFilter({ column, data }) {
268
607
  const columnFilterValue = column.getFilterValue();
269
- const filterVariant = column.columnDef.meta?.filterVariant ?? "text";
270
- const sortedUniqueValues = React4.useMemo(() => {
271
- if (filterVariant !== "select") return [];
608
+ const filterVariant = detectFilterType(column, data);
609
+ const sortedUniqueValues = React6.useMemo(() => {
610
+ if (filterVariant !== "select" && filterVariant !== "status") return [];
272
611
  const values = /* @__PURE__ */ new Set();
273
612
  column.getFacetedUniqueValues().forEach((_, key) => {
274
613
  if (key !== null && key !== void 0) {
@@ -277,35 +616,322 @@ function ColumnFilter({ column }) {
277
616
  });
278
617
  return Array.from(values).sort();
279
618
  }, [column, filterVariant]);
619
+ if (filterVariant === "date") {
620
+ const dateRange = columnFilterValue || {};
621
+ const [fromDate, setFromDate] = React6.useState(
622
+ dateRange.from ? new Date(dateRange.from) : void 0
623
+ );
624
+ const [toDate, setToDate] = React6.useState(
625
+ dateRange.to ? new Date(dateRange.to) : void 0
626
+ );
627
+ const [fromOpen, setFromOpen] = React6.useState(false);
628
+ const [toOpen, setToOpen] = React6.useState(false);
629
+ React6.useEffect(() => {
630
+ if (columnFilterValue) {
631
+ const range = columnFilterValue;
632
+ setFromDate(range.from ? new Date(range.from) : void 0);
633
+ setToDate(range.to ? new Date(range.to) : void 0);
634
+ } else {
635
+ setFromDate(void 0);
636
+ setToDate(void 0);
637
+ }
638
+ }, [columnFilterValue]);
639
+ const handleFromDateChange = (date) => {
640
+ setFromDate(date);
641
+ const newRange = {
642
+ from: date ? format(date, "yyyy-MM-dd") : void 0,
643
+ to: toDate ? format(toDate, "yyyy-MM-dd") : void 0
644
+ };
645
+ column.setFilterValue(
646
+ newRange.from || newRange.to ? newRange : void 0
647
+ );
648
+ };
649
+ const handleToDateChange = (date) => {
650
+ setToDate(date);
651
+ const newRange = {
652
+ from: fromDate ? format(fromDate, "yyyy-MM-dd") : void 0,
653
+ to: date ? format(date, "yyyy-MM-dd") : void 0
654
+ };
655
+ column.setFilterValue(
656
+ newRange.from || newRange.to ? newRange : void 0
657
+ );
658
+ };
659
+ const clearDates = () => {
660
+ setFromDate(void 0);
661
+ setToDate(void 0);
662
+ column.setFilterValue(void 0);
663
+ };
664
+ return /* @__PURE__ */ jsxs3("div", { className: "flex gap-1 items-center", onClick: (e) => e.stopPropagation(), children: [
665
+ /* @__PURE__ */ jsxs3(Popover, { open: fromOpen, onOpenChange: setFromOpen, children: [
666
+ /* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
667
+ Button,
668
+ {
669
+ variant: "outline",
670
+ size: "sm",
671
+ className: cn(
672
+ "h-8 text-xs w-32 justify-start text-left font-normal",
673
+ !fromDate && "text-[hsl(var(--lux-toolbar-input-placeholder))]",
674
+ "border-[hsl(var(--lux-filter-border))]",
675
+ "bg-[hsl(var(--lux-filter-background))]",
676
+ "text-[hsl(var(--lux-filter-foreground))]"
677
+ ),
678
+ children: [
679
+ /* @__PURE__ */ jsx10(CalendarIcon, { className: "mr-2 h-3 w-3" }),
680
+ fromDate ? format(fromDate, "MMM dd, yyyy") : "From"
681
+ ]
682
+ }
683
+ ) }),
684
+ /* @__PURE__ */ jsx10(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx10(
685
+ Calendar,
686
+ {
687
+ mode: "single",
688
+ selected: fromDate,
689
+ onSelect: handleFromDateChange,
690
+ initialFocus: true
691
+ }
692
+ ) })
693
+ ] }),
694
+ /* @__PURE__ */ jsx10("span", { className: "text-xs text-[hsl(var(--lux-toolbar-icon))]", children: "-" }),
695
+ /* @__PURE__ */ jsxs3(Popover, { open: toOpen, onOpenChange: setToOpen, children: [
696
+ /* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
697
+ Button,
698
+ {
699
+ variant: "outline",
700
+ size: "sm",
701
+ className: cn(
702
+ "h-8 text-xs w-32 justify-start text-left font-normal",
703
+ !toDate && "text-[hsl(var(--lux-toolbar-input-placeholder))]",
704
+ "border-[hsl(var(--lux-filter-border))]",
705
+ "bg-[hsl(var(--lux-filter-background))]",
706
+ "text-[hsl(var(--lux-filter-foreground))]"
707
+ ),
708
+ children: [
709
+ /* @__PURE__ */ jsx10(CalendarIcon, { className: "mr-2 h-3 w-3" }),
710
+ toDate ? format(toDate, "MMM dd, yyyy") : "To"
711
+ ]
712
+ }
713
+ ) }),
714
+ /* @__PURE__ */ jsx10(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx10(
715
+ Calendar,
716
+ {
717
+ mode: "single",
718
+ selected: toDate,
719
+ onSelect: handleToDateChange,
720
+ initialFocus: true
721
+ }
722
+ ) })
723
+ ] }),
724
+ (fromDate || toDate) && /* @__PURE__ */ jsx10(
725
+ Button,
726
+ {
727
+ variant: "ghost",
728
+ size: "sm",
729
+ onClick: clearDates,
730
+ className: "h-8 w-8 p-0",
731
+ children: /* @__PURE__ */ jsx10(X, { className: "h-3 w-3" })
732
+ }
733
+ )
734
+ ] });
735
+ }
736
+ if (filterVariant === "slider") {
737
+ const numericValues = React6.useMemo(() => {
738
+ const values = [];
739
+ column.getFacetedUniqueValues().forEach((_, key) => {
740
+ if (typeof key === "number") {
741
+ values.push(key);
742
+ } else if (typeof key === "string") {
743
+ const num = parseFloat(key);
744
+ if (!isNaN(num)) {
745
+ values.push(num);
746
+ }
747
+ }
748
+ });
749
+ return values;
750
+ }, [column]);
751
+ const min = numericValues.length > 0 ? Math.min(...numericValues) : 0;
752
+ const max = numericValues.length > 0 ? Math.max(...numericValues) : 100;
753
+ const avg = numericValues.length > 0 ? (min + max) / 2 : 50;
754
+ const sliderValue = columnFilterValue || { min, max };
755
+ const [range, setRange] = React6.useState([
756
+ sliderValue.min ?? min,
757
+ sliderValue.max ?? max
758
+ ]);
759
+ React6.useEffect(() => {
760
+ if (columnFilterValue) {
761
+ const val = columnFilterValue;
762
+ setRange([val.min ?? min, val.max ?? max]);
763
+ } else {
764
+ setRange([min, max]);
765
+ }
766
+ }, [columnFilterValue, min, max]);
767
+ const handleSliderChange = (newRange) => {
768
+ setRange(newRange);
769
+ column.setFilterValue({ min: newRange[0], max: newRange[1] });
770
+ };
771
+ const clearSlider = () => {
772
+ setRange([min, max]);
773
+ column.setFilterValue(void 0);
774
+ };
775
+ return /* @__PURE__ */ jsxs3(Popover, { children: [
776
+ /* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
777
+ Button,
778
+ {
779
+ variant: "outline",
780
+ size: "sm",
781
+ className: cn(
782
+ "h-8 text-xs w-full justify-start",
783
+ "border-[hsl(var(--lux-filter-border))]",
784
+ "bg-[hsl(var(--lux-filter-background))]",
785
+ "text-[hsl(var(--lux-filter-foreground))]"
786
+ ),
787
+ onClick: (e) => e.stopPropagation(),
788
+ children: /* @__PURE__ */ jsx10("span", { children: range[0] === min && range[1] === max ? "All" : `${Math.round(range[0])} - ${Math.round(range[1])}` })
789
+ }
790
+ ) }),
791
+ /* @__PURE__ */ jsx10(PopoverContent, { className: "w-64", align: "start", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs3("div", { className: "space-y-3", children: [
792
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between text-sm", children: [
793
+ /* @__PURE__ */ jsx10("span", { className: "text-[hsl(var(--lux-filter-foreground))]", children: "Range" }),
794
+ /* @__PURE__ */ jsxs3("span", { className: "text-[hsl(var(--lux-toolbar-icon))]", children: [
795
+ Math.round(range[0]),
796
+ " - ",
797
+ Math.round(range[1])
798
+ ] })
799
+ ] }),
800
+ /* @__PURE__ */ jsx10(
801
+ Slider,
802
+ {
803
+ value: range,
804
+ onValueChange: handleSliderChange,
805
+ min,
806
+ max,
807
+ step: (max - min) / 100
808
+ }
809
+ ),
810
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between text-xs text-[hsl(var(--lux-toolbar-icon))]", children: [
811
+ /* @__PURE__ */ jsxs3("span", { children: [
812
+ "Min: ",
813
+ Math.round(min)
814
+ ] }),
815
+ /* @__PURE__ */ jsxs3("span", { children: [
816
+ "Avg: ",
817
+ Math.round(avg)
818
+ ] }),
819
+ /* @__PURE__ */ jsxs3("span", { children: [
820
+ "Max: ",
821
+ Math.round(max)
822
+ ] })
823
+ ] }),
824
+ /* @__PURE__ */ jsx10(
825
+ Button,
826
+ {
827
+ variant: "ghost",
828
+ size: "sm",
829
+ onClick: clearSlider,
830
+ className: "w-full h-7 text-xs",
831
+ children: "Clear"
832
+ }
833
+ )
834
+ ] }) })
835
+ ] });
836
+ }
837
+ if (filterVariant === "status") {
838
+ const selectedStatuses = columnFilterValue || [];
839
+ const [open, setOpen] = React6.useState(false);
840
+ const toggleStatus = (status) => {
841
+ const newSelection = selectedStatuses.includes(status) ? selectedStatuses.filter((s) => s !== status) : [...selectedStatuses, status];
842
+ column.setFilterValue(newSelection.length > 0 ? newSelection : void 0);
843
+ };
844
+ const clearStatuses = () => {
845
+ column.setFilterValue(void 0);
846
+ };
847
+ return /* @__PURE__ */ jsxs3(Popover, { open, onOpenChange: setOpen, children: [
848
+ /* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
849
+ Button,
850
+ {
851
+ variant: "outline",
852
+ size: "sm",
853
+ className: cn(
854
+ "h-8 text-xs w-full justify-start",
855
+ "border-[hsl(var(--lux-filter-border))]",
856
+ "bg-[hsl(var(--lux-filter-background))]",
857
+ "text-[hsl(var(--lux-filter-foreground))]"
858
+ ),
859
+ onClick: (e) => {
860
+ e.stopPropagation();
861
+ setOpen(!open);
862
+ },
863
+ children: /* @__PURE__ */ jsx10("span", { children: selectedStatuses.length === 0 ? "All Status" : `${selectedStatuses.length} selected` })
864
+ }
865
+ ) }),
866
+ /* @__PURE__ */ jsx10(PopoverContent, { className: "w-48", align: "start", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
867
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
868
+ /* @__PURE__ */ jsx10("span", { className: "text-sm font-medium text-[hsl(var(--lux-filter-foreground))]", children: "Status" }),
869
+ selectedStatuses.length > 0 && /* @__PURE__ */ jsx10(
870
+ Button,
871
+ {
872
+ variant: "ghost",
873
+ size: "sm",
874
+ onClick: clearStatuses,
875
+ className: "h-6 text-xs",
876
+ children: "Clear"
877
+ }
878
+ )
879
+ ] }),
880
+ /* @__PURE__ */ jsx10("div", { className: "space-y-1.5", children: sortedUniqueValues.map((status) => /* @__PURE__ */ jsxs3(
881
+ "button",
882
+ {
883
+ onClick: () => toggleStatus(status),
884
+ className: cn(
885
+ "w-full flex items-center gap-2 p-2 rounded-md text-left text-xs transition-colors",
886
+ selectedStatuses.includes(status) ? "bg-[hsl(var(--lux-focus-ring))]/20" : "hover:bg-[hsl(var(--lux-table-row-hover))]"
887
+ ),
888
+ children: [
889
+ /* @__PURE__ */ jsx10(
890
+ "input",
891
+ {
892
+ type: "checkbox",
893
+ checked: selectedStatuses.includes(status),
894
+ onChange: () => toggleStatus(status),
895
+ className: "h-3 w-3"
896
+ }
897
+ ),
898
+ /* @__PURE__ */ jsx10(StatusCell, { value: status })
899
+ ]
900
+ },
901
+ status
902
+ )) })
903
+ ] }) })
904
+ ] });
905
+ }
280
906
  if (filterVariant === "select") {
281
- return /* @__PURE__ */ jsxs2(
907
+ return /* @__PURE__ */ jsxs3(
282
908
  Select,
283
909
  {
284
910
  value: columnFilterValue ?? "",
285
911
  onValueChange: (value) => column.setFilterValue(value === "__all__" ? void 0 : value),
286
912
  children: [
287
- /* @__PURE__ */ jsx5(
913
+ /* @__PURE__ */ jsx10(
288
914
  SelectTrigger,
289
915
  {
290
916
  className: cn(
291
917
  "h-8 text-xs",
292
- "border-slate-200 dark:border-slate-700",
293
- "bg-white dark:bg-slate-900",
294
- "text-slate-900 dark:text-slate-100"
918
+ "border-[hsl(var(--lux-filter-border))]",
919
+ "bg-[hsl(var(--lux-filter-background))]",
920
+ "text-[hsl(var(--lux-filter-foreground))]"
295
921
  ),
296
922
  onClick: (e) => e.stopPropagation(),
297
- children: /* @__PURE__ */ jsx5(SelectValue, { placeholder: "All" })
923
+ children: /* @__PURE__ */ jsx10(SelectValue, { placeholder: "All" })
298
924
  }
299
925
  ),
300
- /* @__PURE__ */ jsxs2(SelectContent, { children: [
301
- /* @__PURE__ */ jsx5(SelectItem, { value: "__all__", children: "All" }),
302
- sortedUniqueValues.map((value) => /* @__PURE__ */ jsx5(SelectItem, { value, children: value }, value))
926
+ /* @__PURE__ */ jsxs3(SelectContent, { children: [
927
+ /* @__PURE__ */ jsx10(SelectItem, { value: "__all__", children: "All" }),
928
+ sortedUniqueValues.map((value) => /* @__PURE__ */ jsx10(SelectItem, { value, children: value }, value))
303
929
  ] })
304
930
  ]
305
931
  }
306
932
  );
307
933
  }
308
- return /* @__PURE__ */ jsx5(
934
+ return /* @__PURE__ */ jsx10(
309
935
  Input,
310
936
  {
311
937
  type: "text",
@@ -314,10 +940,10 @@ function ColumnFilter({ column }) {
314
940
  placeholder: "Filter...",
315
941
  className: cn(
316
942
  "h-8 text-xs",
317
- "border-slate-200 dark:border-slate-700",
318
- "bg-white dark:bg-slate-900",
319
- "text-slate-900 dark:text-slate-100",
320
- "placeholder:text-slate-400 dark:placeholder:text-slate-500"
943
+ "border-[hsl(var(--lux-filter-border))]",
944
+ "bg-[hsl(var(--lux-filter-background))]",
945
+ "text-[hsl(var(--lux-filter-foreground))]",
946
+ "placeholder:text-[hsl(var(--lux-toolbar-input-placeholder))]"
321
947
  ),
322
948
  onClick: (e) => e.stopPropagation()
323
949
  }
@@ -327,13 +953,13 @@ function ColumnFilter({ column }) {
327
953
  // src/components/lux-table/pagination.tsx
328
954
  import {
329
955
  ChevronsLeft,
330
- ChevronLeft,
331
- ChevronRight,
956
+ ChevronLeft as ChevronLeft2,
957
+ ChevronRight as ChevronRight2,
332
958
  ChevronsRight
333
959
  } from "lucide-react";
334
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
960
+ import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
335
961
  function PaginationButton({ onClick, disabled, title, children }) {
336
- return /* @__PURE__ */ jsx6(
962
+ return /* @__PURE__ */ jsx11(
337
963
  "button",
338
964
  {
339
965
  className: cn(
@@ -341,6 +967,7 @@ function PaginationButton({ onClick, disabled, title, children }) {
341
967
  "h-9 w-9",
342
968
  "border border-slate-200 dark:border-slate-800",
343
969
  "bg-white dark:bg-slate-950",
970
+ "text-slate-900 dark:text-slate-100",
344
971
  "hover:bg-slate-100 dark:hover:bg-slate-800",
345
972
  "disabled:pointer-events-none disabled:opacity-50",
346
973
  "transition-colors"
@@ -353,7 +980,7 @@ function PaginationButton({ onClick, disabled, title, children }) {
353
980
  );
354
981
  }
355
982
  function PageNumberButton({ pageNum, isActive, onClick }) {
356
- return /* @__PURE__ */ jsx6(
983
+ return /* @__PURE__ */ jsx11(
357
984
  "button",
358
985
  {
359
986
  onClick,
@@ -361,7 +988,7 @@ function PageNumberButton({ pageNum, isActive, onClick }) {
361
988
  "inline-flex items-center justify-center rounded-md text-sm font-medium",
362
989
  "h-9 w-9",
363
990
  "transition-colors",
364
- 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"
991
+ isActive ? "bg-slate-900 dark:bg-slate-100 text-white dark:text-slate-900 border border-slate-900 dark:border-slate-100" : "border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 text-slate-900 dark:text-slate-100 hover:bg-slate-100 dark:hover:bg-slate-800"
365
992
  ),
366
993
  children: pageNum + 1
367
994
  }
@@ -395,22 +1022,22 @@ function TablePagination({ table }) {
395
1022
  }
396
1023
  return pages;
397
1024
  };
398
- return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 px-2 py-3", children: [
399
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-4", children: [
400
- /* @__PURE__ */ jsxs3("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: [
401
- /* @__PURE__ */ jsx6("span", { className: "font-medium text-slate-700 dark:text-slate-300", children: startRow }),
1025
+ return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 px-2 py-3", children: [
1026
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-4", children: [
1027
+ /* @__PURE__ */ jsxs4("div", { className: "text-sm text-[hsl(var(--lux-table-cell-muted))]", children: [
1028
+ /* @__PURE__ */ jsx11("span", { className: "font-medium text-[hsl(var(--lux-table-foreground))]", children: startRow }),
402
1029
  "-",
403
- /* @__PURE__ */ jsx6("span", { className: "font-medium text-slate-700 dark:text-slate-300", children: endRow }),
1030
+ /* @__PURE__ */ jsx11("span", { className: "font-medium text-[hsl(var(--lux-table-foreground))]", children: endRow }),
404
1031
  " ",
405
1032
  "of",
406
1033
  " ",
407
- /* @__PURE__ */ jsx6("span", { className: "font-medium text-slate-700 dark:text-slate-300", children: totalRows }),
1034
+ /* @__PURE__ */ jsx11("span", { className: "font-medium text-[hsl(var(--lux-table-foreground))]", children: totalRows }),
408
1035
  " ",
409
1036
  "records shown"
410
1037
  ] }),
411
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
412
- /* @__PURE__ */ jsx6("span", { className: "text-sm text-slate-500 dark:text-slate-400", children: "Rows per page:" }),
413
- /* @__PURE__ */ jsx6(
1038
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1039
+ /* @__PURE__ */ jsx11("span", { className: "text-sm text-[hsl(var(--lux-table-cell-muted))]", children: "Rows per page:" }),
1040
+ /* @__PURE__ */ jsx11(
414
1041
  "select",
415
1042
  {
416
1043
  value: pageSize,
@@ -420,40 +1047,40 @@ function TablePagination({ table }) {
420
1047
  className: cn(
421
1048
  "h-9 rounded-md border border-slate-200 dark:border-slate-800",
422
1049
  "bg-white dark:bg-slate-950",
423
- "px-3 py-1 text-sm",
1050
+ "px-3 py-1 text-sm text-slate-900 dark:text-slate-100",
424
1051
  "focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1",
425
1052
  "cursor-pointer"
426
1053
  ),
427
- children: [10, 20, 30, 50, 100].map((size) => /* @__PURE__ */ jsx6("option", { value: size, children: size }, size))
1054
+ children: [10, 20, 30, 50, 100].map((size) => /* @__PURE__ */ jsx11("option", { value: size, children: size }, size))
428
1055
  }
429
1056
  )
430
1057
  ] })
431
1058
  ] }),
432
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
433
- /* @__PURE__ */ jsx6(
1059
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1060
+ /* @__PURE__ */ jsx11(
434
1061
  PaginationButton,
435
1062
  {
436
1063
  onClick: () => table.setPageIndex(0),
437
1064
  disabled: !table.getCanPreviousPage(),
438
1065
  title: "First page",
439
- children: /* @__PURE__ */ jsx6(ChevronsLeft, { className: "h-4 w-4" })
1066
+ children: /* @__PURE__ */ jsx11(ChevronsLeft, { className: "h-4 w-4" })
440
1067
  }
441
1068
  ),
442
- /* @__PURE__ */ jsx6(
1069
+ /* @__PURE__ */ jsx11(
443
1070
  PaginationButton,
444
1071
  {
445
1072
  onClick: () => table.previousPage(),
446
1073
  disabled: !table.getCanPreviousPage(),
447
1074
  title: "Previous page",
448
- children: /* @__PURE__ */ jsx6(ChevronLeft, { className: "h-4 w-4" })
1075
+ children: /* @__PURE__ */ jsx11(ChevronLeft2, { className: "h-4 w-4" })
449
1076
  }
450
1077
  ),
451
- /* @__PURE__ */ jsx6("div", { className: "flex items-center gap-1", children: getPageNumbers().map((page, idx) => {
1078
+ /* @__PURE__ */ jsx11("div", { className: "flex items-center gap-1", children: getPageNumbers().map((page, idx) => {
452
1079
  if (page === "...") {
453
- return /* @__PURE__ */ jsx6("span", { className: "px-2 text-slate-400", children: "..." }, `ellipsis-${idx}`);
1080
+ return /* @__PURE__ */ jsx11("span", { className: "px-2 text-[hsl(var(--lux-table-cell-muted))]", children: "..." }, `ellipsis-${idx}`);
454
1081
  }
455
1082
  const pageNum = page;
456
- return /* @__PURE__ */ jsx6(
1083
+ return /* @__PURE__ */ jsx11(
457
1084
  PageNumberButton,
458
1085
  {
459
1086
  pageNum,
@@ -463,22 +1090,22 @@ function TablePagination({ table }) {
463
1090
  pageNum
464
1091
  );
465
1092
  }) }),
466
- /* @__PURE__ */ jsx6(
1093
+ /* @__PURE__ */ jsx11(
467
1094
  PaginationButton,
468
1095
  {
469
1096
  onClick: () => table.nextPage(),
470
1097
  disabled: !table.getCanNextPage(),
471
1098
  title: "Next page",
472
- children: /* @__PURE__ */ jsx6(ChevronRight, { className: "h-4 w-4" })
1099
+ children: /* @__PURE__ */ jsx11(ChevronRight2, { className: "h-4 w-4" })
473
1100
  }
474
1101
  ),
475
- /* @__PURE__ */ jsx6(
1102
+ /* @__PURE__ */ jsx11(
476
1103
  PaginationButton,
477
1104
  {
478
1105
  onClick: () => table.setPageIndex(table.getPageCount() - 1),
479
1106
  disabled: !table.getCanNextPage(),
480
1107
  title: "Last page",
481
- children: /* @__PURE__ */ jsx6(ChevronsRight, { className: "h-4 w-4" })
1108
+ children: /* @__PURE__ */ jsx11(ChevronsRight, { className: "h-4 w-4" })
482
1109
  }
483
1110
  )
484
1111
  ] })
@@ -486,7 +1113,7 @@ function TablePagination({ table }) {
486
1113
  }
487
1114
 
488
1115
  // src/components/lux-table/table-toolbar.tsx
489
- import * as React6 from "react";
1116
+ import * as React8 from "react";
490
1117
  import {
491
1118
  Search,
492
1119
  Filter,
@@ -498,116 +1125,65 @@ import {
498
1125
  ChevronDown as ChevronDown3
499
1126
  } from "lucide-react";
500
1127
 
501
- // src/components/ui/button.tsx
502
- import { Slot } from "@radix-ui/react-slot";
503
- import { cva } from "class-variance-authority";
504
- import { jsx as jsx7 } from "react/jsx-runtime";
505
- var buttonVariants = cva(
506
- "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",
507
- {
508
- variants: {
509
- variant: {
510
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
511
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
512
- 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",
513
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
514
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
515
- link: "text-primary underline-offset-4 hover:underline"
516
- },
517
- size: {
518
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
519
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
520
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
521
- icon: "size-9",
522
- "icon-sm": "size-8",
523
- "icon-lg": "size-10"
524
- }
525
- },
526
- defaultVariants: {
527
- variant: "default",
528
- size: "default"
529
- }
530
- }
531
- );
532
- function Button({
533
- className,
534
- variant = "default",
535
- size = "default",
536
- asChild = false,
537
- ...props
538
- }) {
539
- const Comp = asChild ? Slot : "button";
540
- return /* @__PURE__ */ jsx7(
541
- Comp,
542
- {
543
- "data-slot": "button",
544
- "data-variant": variant,
545
- "data-size": size,
546
- className: cn(buttonVariants({ variant, size, className })),
547
- ...props
548
- }
549
- );
550
- }
551
-
552
- // src/components/ui/dropdown-menu.tsx
553
- import * as React5 from "react";
554
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
555
- import { Check as Check2, ChevronRight as ChevronRight2, Circle } from "lucide-react";
556
- import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
557
- var DropdownMenu = DropdownMenuPrimitive.Root;
558
- var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
559
- var DropdownMenuGroup = DropdownMenuPrimitive.Group;
560
- var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
561
- var DropdownMenuSub = DropdownMenuPrimitive.Sub;
562
- var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
563
- var DropdownMenuSubTrigger = React5.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
564
- DropdownMenuPrimitive.SubTrigger,
1128
+ // src/components/ui/dropdown-menu.tsx
1129
+ import * as React7 from "react";
1130
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
1131
+ import { Check as Check2, ChevronRight as ChevronRight3, Circle } from "lucide-react";
1132
+ import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
1133
+ var DropdownMenu = DropdownMenuPrimitive.Root;
1134
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
1135
+ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
1136
+ var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
1137
+ var DropdownMenuSub = DropdownMenuPrimitive.Sub;
1138
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
1139
+ var DropdownMenuSubTrigger = React7.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs5(
1140
+ DropdownMenuPrimitive.SubTrigger,
565
1141
  {
566
1142
  ref,
567
1143
  className: cn(
568
- "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",
1144
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
569
1145
  inset && "pl-8",
570
1146
  className
571
1147
  ),
572
1148
  ...props,
573
1149
  children: [
574
1150
  children,
575
- /* @__PURE__ */ jsx8(ChevronRight2, { className: "ml-auto h-4 w-4" })
1151
+ /* @__PURE__ */ jsx12(ChevronRight3, { className: "ml-auto h-4 w-4" })
576
1152
  ]
577
1153
  }
578
1154
  ));
579
1155
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
580
- var DropdownMenuSubContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
1156
+ var DropdownMenuSubContent = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
581
1157
  DropdownMenuPrimitive.SubContent,
582
1158
  {
583
1159
  ref,
584
1160
  className: cn(
585
- "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",
1161
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground 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",
586
1162
  className
587
1163
  ),
588
1164
  ...props
589
1165
  }
590
1166
  ));
591
1167
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
592
- var DropdownMenuContent = React5.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx8(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx8(
1168
+ var DropdownMenuContent = React7.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx12(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx12(
593
1169
  DropdownMenuPrimitive.Content,
594
1170
  {
595
1171
  ref,
596
1172
  sideOffset,
597
1173
  className: cn(
598
- "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",
1174
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground 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",
599
1175
  className
600
1176
  ),
601
1177
  ...props
602
1178
  }
603
1179
  ) }));
604
1180
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
605
- var DropdownMenuItem = React5.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx8(
1181
+ var DropdownMenuItem = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx12(
606
1182
  DropdownMenuPrimitive.Item,
607
1183
  {
608
1184
  ref,
609
1185
  className: cn(
610
- "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",
1186
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
611
1187
  inset && "pl-8",
612
1188
  className
613
1189
  ),
@@ -615,40 +1191,40 @@ var DropdownMenuItem = React5.forwardRef(({ className, inset, ...props }, ref) =
615
1191
  }
616
1192
  ));
617
1193
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
618
- var DropdownMenuCheckboxItem = React5.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs4(
1194
+ var DropdownMenuCheckboxItem = React7.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs5(
619
1195
  DropdownMenuPrimitive.CheckboxItem,
620
1196
  {
621
1197
  ref,
622
1198
  className: cn(
623
- "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",
1199
+ "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-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
624
1200
  className
625
1201
  ),
626
1202
  checked,
627
1203
  ...props,
628
1204
  children: [
629
- /* @__PURE__ */ jsx8("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx8(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx8(Check2, { className: "h-4 w-4" }) }) }),
1205
+ /* @__PURE__ */ jsx12("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx12(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx12(Check2, { className: "h-4 w-4" }) }) }),
630
1206
  children
631
1207
  ]
632
1208
  }
633
1209
  ));
634
1210
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
635
- var DropdownMenuRadioItem = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
1211
+ var DropdownMenuRadioItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs5(
636
1212
  DropdownMenuPrimitive.RadioItem,
637
1213
  {
638
1214
  ref,
639
1215
  className: cn(
640
- "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",
1216
+ "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-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
641
1217
  className
642
1218
  ),
643
1219
  ...props,
644
1220
  children: [
645
- /* @__PURE__ */ jsx8("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx8(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx8(Circle, { className: "h-2 w-2 fill-current" }) }) }),
1221
+ /* @__PURE__ */ jsx12("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx12(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx12(Circle, { className: "h-2 w-2 fill-current" }) }) }),
646
1222
  children
647
1223
  ]
648
1224
  }
649
1225
  ));
650
1226
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
651
- var DropdownMenuLabel = React5.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx8(
1227
+ var DropdownMenuLabel = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx12(
652
1228
  DropdownMenuPrimitive.Label,
653
1229
  {
654
1230
  ref,
@@ -661,11 +1237,11 @@ var DropdownMenuLabel = React5.forwardRef(({ className, inset, ...props }, ref)
661
1237
  }
662
1238
  ));
663
1239
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
664
- var DropdownMenuSeparator = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
1240
+ var DropdownMenuSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
665
1241
  DropdownMenuPrimitive.Separator,
666
1242
  {
667
1243
  ref,
668
- className: cn("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800", className),
1244
+ className: cn("-mx-1 my-1 h-px bg-border", className),
669
1245
  ...props
670
1246
  }
671
1247
  ));
@@ -674,7 +1250,7 @@ var DropdownMenuShortcut = ({
674
1250
  className,
675
1251
  ...props
676
1252
  }) => {
677
- return /* @__PURE__ */ jsx8(
1253
+ return /* @__PURE__ */ jsx12(
678
1254
  "span",
679
1255
  {
680
1256
  className: cn("ml-auto text-xs tracking-widest opacity-60", className),
@@ -685,7 +1261,7 @@ var DropdownMenuShortcut = ({
685
1261
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
686
1262
 
687
1263
  // src/components/lux-table/table-toolbar.tsx
688
- import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1264
+ import { Fragment, jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
689
1265
  function TableToolbar({
690
1266
  table,
691
1267
  showFiltering = true,
@@ -695,35 +1271,35 @@ function TableToolbar({
695
1271
  showColumnVisibility = true,
696
1272
  className
697
1273
  }) {
698
- const [globalFilter, setGlobalFilter] = React6.useState("");
1274
+ const [globalFilter, setGlobalFilter] = React8.useState("");
699
1275
  const hidableColumns = table.getAllColumns().filter((column) => column.getCanHide() && column.id !== "__selection__");
700
1276
  const hiddenColumns = hidableColumns.filter((column) => !column.getIsVisible());
701
- const handleGlobalSearch = React6.useCallback(
1277
+ const handleGlobalSearch = React8.useCallback(
702
1278
  (value) => {
703
1279
  setGlobalFilter(value);
704
1280
  table.setGlobalFilter(value);
705
1281
  },
706
1282
  [table]
707
1283
  );
708
- const handleResetVisibility = React6.useCallback(() => {
1284
+ const handleResetVisibility = React8.useCallback(() => {
709
1285
  table.resetColumnVisibility();
710
1286
  }, [table]);
711
- const handleShowAllColumns = React6.useCallback(() => {
1287
+ const handleShowAllColumns = React8.useCallback(() => {
712
1288
  hidableColumns.forEach((column) => {
713
1289
  column.toggleVisibility(true);
714
1290
  });
715
1291
  }, [hidableColumns]);
716
- return /* @__PURE__ */ jsxs5(
1292
+ return /* @__PURE__ */ jsxs6(
717
1293
  "div",
718
1294
  {
719
1295
  className: cn(
720
- "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",
1296
+ "flex flex-wrap items-center gap-2 p-3 rounded-lg border border-[hsl(var(--lux-toolbar-border))] bg-[hsl(var(--lux-toolbar-background))]",
721
1297
  className
722
1298
  ),
723
1299
  children: [
724
- showGlobalSearch && /* @__PURE__ */ jsxs5("div", { className: "relative flex-1 min-w-[200px] max-w-sm", children: [
725
- /* @__PURE__ */ jsx9(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" }),
726
- /* @__PURE__ */ jsx9(
1300
+ showGlobalSearch && /* @__PURE__ */ jsxs6("div", { className: "relative flex-1 min-w-[200px] max-w-sm", children: [
1301
+ /* @__PURE__ */ jsx13(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[hsl(var(--lux-toolbar-icon))]" }),
1302
+ /* @__PURE__ */ jsx13(
727
1303
  "input",
728
1304
  {
729
1305
  type: "text",
@@ -731,55 +1307,55 @@ function TableToolbar({
731
1307
  value: globalFilter,
732
1308
  onChange: (e) => handleGlobalSearch(e.target.value),
733
1309
  className: cn(
734
- "w-full h-9 pl-9 pr-3 rounded-md border border-slate-200 dark:border-slate-700",
735
- "bg-white dark:bg-slate-950 text-sm text-slate-900 dark:text-slate-100",
736
- "placeholder:text-slate-400 dark:placeholder:text-slate-500",
737
- "focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500",
1310
+ "w-full h-9 pl-9 pr-3 rounded-md border border-[hsl(var(--lux-toolbar-input-border))]",
1311
+ "bg-[hsl(var(--lux-toolbar-input-background))] text-sm text-[hsl(var(--lux-toolbar-input-foreground))]",
1312
+ "placeholder:text-[hsl(var(--lux-toolbar-input-placeholder))]",
1313
+ "focus:outline-none focus:ring-2 focus:ring-[hsl(var(--lux-focus-ring))]/50 focus:border-[hsl(var(--lux-focus-ring))]",
738
1314
  "transition-colors"
739
1315
  )
740
1316
  }
741
1317
  ),
742
- globalFilter && /* @__PURE__ */ jsx9(
1318
+ globalFilter && /* @__PURE__ */ jsx13(
743
1319
  "button",
744
1320
  {
745
1321
  onClick: () => handleGlobalSearch(""),
746
- 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",
747
- children: /* @__PURE__ */ jsx9(FilterX, { className: "h-3 w-3 text-slate-400" })
1322
+ className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded-full hover:bg-[hsl(var(--lux-table-row-hover))] transition-colors",
1323
+ children: /* @__PURE__ */ jsx13(FilterX, { className: "h-3 w-3 text-[hsl(var(--lux-toolbar-icon))]" })
748
1324
  }
749
1325
  )
750
1326
  ] }),
751
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 ml-auto", children: [
752
- showFiltering && onFilteringToggle && /* @__PURE__ */ jsx9(
1327
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 ml-auto", children: [
1328
+ showFiltering && onFilteringToggle && /* @__PURE__ */ jsx13(
753
1329
  Button,
754
1330
  {
755
1331
  variant: filteringEnabled ? "default" : "outline",
756
1332
  size: "sm",
757
1333
  onClick: () => onFilteringToggle(!filteringEnabled),
758
- className: "gap-2",
759
- children: filteringEnabled ? /* @__PURE__ */ jsxs5(Fragment, { children: [
760
- /* @__PURE__ */ jsx9(FilterX, { className: "h-4 w-4" }),
761
- /* @__PURE__ */ jsx9("span", { className: "hidden sm:inline", children: "Hide Filters" })
762
- ] }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
763
- /* @__PURE__ */ jsx9(Filter, { className: "h-4 w-4" }),
764
- /* @__PURE__ */ jsx9("span", { className: "hidden sm:inline", children: "Show Filters" })
1334
+ className: "gap-2 bg-white dark:bg-slate-950 border-slate-200 dark:border-slate-800 text-slate-900 dark:text-slate-100 hover:bg-slate-100 dark:hover:bg-slate-800",
1335
+ children: filteringEnabled ? /* @__PURE__ */ jsxs6(Fragment, { children: [
1336
+ /* @__PURE__ */ jsx13(FilterX, { className: "h-4 w-4" }),
1337
+ /* @__PURE__ */ jsx13("span", { className: "hidden sm:inline", children: "Hide Filters" })
1338
+ ] }) : /* @__PURE__ */ jsxs6(Fragment, { children: [
1339
+ /* @__PURE__ */ jsx13(Filter, { className: "h-4 w-4" }),
1340
+ /* @__PURE__ */ jsx13("span", { className: "hidden sm:inline", children: "Show Filters" })
765
1341
  ] })
766
1342
  }
767
1343
  ),
768
- showColumnVisibility && /* @__PURE__ */ jsxs5(DropdownMenu, { children: [
769
- /* @__PURE__ */ jsx9(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(Button, { variant: "outline", size: "sm", className: "gap-2", children: [
770
- /* @__PURE__ */ jsx9(Columns3, { className: "h-4 w-4" }),
771
- /* @__PURE__ */ jsx9("span", { className: "hidden sm:inline", children: "Columns" }),
772
- hiddenColumns.length > 0 && /* @__PURE__ */ jsx9("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 }),
773
- /* @__PURE__ */ jsx9(ChevronDown3, { className: "h-3 w-3 opacity-50" })
1344
+ showColumnVisibility && /* @__PURE__ */ jsxs6(DropdownMenu, { children: [
1345
+ /* @__PURE__ */ jsx13(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(Button, { variant: "outline", size: "sm", className: "gap-2 bg-white dark:bg-slate-950 border-slate-200 dark:border-slate-800 text-slate-900 dark:text-slate-100 hover:bg-slate-100 dark:hover:bg-slate-800", children: [
1346
+ /* @__PURE__ */ jsx13(Columns3, { className: "h-4 w-4" }),
1347
+ /* @__PURE__ */ jsx13("span", { className: "hidden sm:inline", children: "Columns" }),
1348
+ hiddenColumns.length > 0 && /* @__PURE__ */ jsx13("span", { className: "ml-1 flex h-5 w-5 items-center justify-center rounded-full bg-[hsl(var(--lux-focus-ring))] text-[10px] font-medium text-white", children: hiddenColumns.length }),
1349
+ /* @__PURE__ */ jsx13(ChevronDown3, { className: "h-3 w-3 opacity-50" })
774
1350
  ] }) }),
775
- /* @__PURE__ */ jsxs5(DropdownMenuContent, { align: "end", className: "w-56", children: [
776
- /* @__PURE__ */ jsxs5(DropdownMenuLabel, { className: "flex items-center gap-2", children: [
777
- /* @__PURE__ */ jsx9(Columns3, { className: "h-4 w-4" }),
1351
+ /* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "end", className: "w-56 bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-800", children: [
1352
+ /* @__PURE__ */ jsxs6(DropdownMenuLabel, { className: "flex items-center gap-2", children: [
1353
+ /* @__PURE__ */ jsx13(Columns3, { className: "h-4 w-4" }),
778
1354
  "Toggle Columns"
779
1355
  ] }),
780
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
781
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1 px-2 py-1.5", children: [
782
- /* @__PURE__ */ jsxs5(
1356
+ /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1357
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 px-2 py-1.5", children: [
1358
+ /* @__PURE__ */ jsxs6(
783
1359
  Button,
784
1360
  {
785
1361
  variant: "ghost",
@@ -788,12 +1364,12 @@ function TableToolbar({
788
1364
  disabled: hiddenColumns.length === 0,
789
1365
  className: "h-7 flex-1 text-xs",
790
1366
  children: [
791
- /* @__PURE__ */ jsx9(Eye, { className: "mr-1 h-3 w-3" }),
1367
+ /* @__PURE__ */ jsx13(Eye, { className: "mr-1 h-3 w-3" }),
792
1368
  "Show All"
793
1369
  ]
794
1370
  }
795
1371
  ),
796
- /* @__PURE__ */ jsxs5(
1372
+ /* @__PURE__ */ jsxs6(
797
1373
  Button,
798
1374
  {
799
1375
  variant: "ghost",
@@ -801,33 +1377,33 @@ function TableToolbar({
801
1377
  onClick: handleResetVisibility,
802
1378
  className: "h-7 flex-1 text-xs",
803
1379
  children: [
804
- /* @__PURE__ */ jsx9(RotateCcw, { className: "mr-1 h-3 w-3" }),
1380
+ /* @__PURE__ */ jsx13(RotateCcw, { className: "mr-1 h-3 w-3" }),
805
1381
  "Reset"
806
1382
  ]
807
1383
  }
808
1384
  )
809
1385
  ] }),
810
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
811
- /* @__PURE__ */ jsx9("div", { className: "max-h-[300px] overflow-y-auto", children: hidableColumns.map((column) => {
1386
+ /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1387
+ /* @__PURE__ */ jsx13("div", { className: "max-h-[300px] overflow-y-auto", children: hidableColumns.map((column) => {
812
1388
  const columnDef = column.columnDef;
813
1389
  const headerText = typeof columnDef.header === "string" ? columnDef.header : column.id;
814
- return /* @__PURE__ */ jsx9(
1390
+ return /* @__PURE__ */ jsx13(
815
1391
  DropdownMenuCheckboxItem,
816
1392
  {
817
1393
  checked: column.getIsVisible(),
818
1394
  onCheckedChange: (value) => column.toggleVisibility(!!value),
819
1395
  className: "capitalize",
820
- children: /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-2", children: [
821
- column.getIsVisible() ? /* @__PURE__ */ jsx9(Eye, { className: "h-3.5 w-3.5 text-green-500" }) : /* @__PURE__ */ jsx9(EyeOff, { className: "h-3.5 w-3.5 text-slate-400" }),
1396
+ children: /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-2", children: [
1397
+ column.getIsVisible() ? /* @__PURE__ */ jsx13(Eye, { className: "h-3.5 w-3.5 text-[hsl(var(--lux-status-active-bg))]" }) : /* @__PURE__ */ jsx13(EyeOff, { className: "h-3.5 w-3.5 text-[hsl(var(--lux-toolbar-icon))]" }),
822
1398
  headerText
823
1399
  ] })
824
1400
  },
825
1401
  column.id
826
1402
  );
827
1403
  }) }),
828
- hiddenColumns.length > 0 && /* @__PURE__ */ jsxs5(Fragment, { children: [
829
- /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
830
- /* @__PURE__ */ jsxs5("div", { className: "px-2 py-1.5 text-xs text-slate-500 dark:text-slate-400", children: [
1404
+ hiddenColumns.length > 0 && /* @__PURE__ */ jsxs6(Fragment, { children: [
1405
+ /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1406
+ /* @__PURE__ */ jsxs6("div", { className: "px-2 py-1.5 text-xs text-[hsl(var(--lux-table-cell-muted))]", children: [
831
1407
  hiddenColumns.length,
832
1408
  " column(s) hidden"
833
1409
  ] })
@@ -842,7 +1418,7 @@ function TableToolbar({
842
1418
 
843
1419
  // src/components/lux-table/sortable-header.tsx
844
1420
  import { flexRender } from "@tanstack/react-table";
845
- import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1421
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
846
1422
  function SortableHeader({
847
1423
  header,
848
1424
  showSortIndex = false
@@ -853,24 +1429,24 @@ function SortableHeader({
853
1429
  const sortIndex = column.getSortIndex();
854
1430
  const headerContent = header.isPlaceholder ? null : flexRender(column.columnDef.header, header.getContext());
855
1431
  if (!canSort) {
856
- return /* @__PURE__ */ jsx10(Fragment2, { children: headerContent });
1432
+ return /* @__PURE__ */ jsx14(Fragment2, { children: headerContent });
857
1433
  }
858
- return /* @__PURE__ */ jsxs6(
1434
+ return /* @__PURE__ */ jsxs7(
859
1435
  "button",
860
1436
  {
861
1437
  type: "button",
862
1438
  className: cn(
863
1439
  "flex items-center gap-1.5 w-full text-left font-medium group",
864
- "hover:text-slate-900 dark:hover:text-slate-100",
865
- "transition-colors duration-150",
1440
+ "hover:text-[hsl(var(--lux-table-foreground))]",
1441
+ "transition-all duration-200",
866
1442
  "-ml-2 px-2 py-1 rounded-md",
867
- "hover:bg-slate-100 dark:hover:bg-slate-800",
868
- isSorted && "text-blue-600 dark:text-blue-400"
1443
+ "hover:bg-[hsl(var(--lux-table-row-hover))]",
1444
+ isSorted && "text-[hsl(var(--lux-sort-sorted-text))]"
869
1445
  ),
870
1446
  onClick: header.column.getToggleSortingHandler(),
871
1447
  children: [
872
1448
  headerContent,
873
- showSortIndex && isSorted && sortIndex > 0 && /* @__PURE__ */ jsx10("span", { className: "ml-0.5 text-[10px] font-bold text-blue-500 dark:text-blue-400 bg-blue-100 dark:bg-blue-900/50 rounded-full w-4 h-4 flex items-center justify-center", children: sortIndex + 1 })
1449
+ showSortIndex && isSorted && sortIndex > 0 && /* @__PURE__ */ jsx14("span", { className: "ml-0.5 text-[10px] font-bold text-[hsl(var(--lux-sort-sorted-text))] bg-[hsl(var(--lux-sort-sorted-text))]/10 rounded-full w-4 h-4 flex items-center justify-center ring-1 ring-[hsl(var(--lux-sort-sorted-text))]/20", children: sortIndex + 1 })
874
1450
  ]
875
1451
  }
876
1452
  );
@@ -879,12 +1455,12 @@ function SortableHeader({
879
1455
  // src/components/ui/checkbox.tsx
880
1456
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
881
1457
  import { CheckIcon } from "lucide-react";
882
- import { jsx as jsx11 } from "react/jsx-runtime";
1458
+ import { jsx as jsx15 } from "react/jsx-runtime";
883
1459
  function Checkbox({
884
1460
  className,
885
1461
  ...props
886
1462
  }) {
887
- return /* @__PURE__ */ jsx11(
1463
+ return /* @__PURE__ */ jsx15(
888
1464
  CheckboxPrimitive.Root,
889
1465
  {
890
1466
  "data-slot": "checkbox",
@@ -893,239 +1469,348 @@ function Checkbox({
893
1469
  className
894
1470
  ),
895
1471
  ...props,
896
- children: /* @__PURE__ */ jsx11(
1472
+ children: /* @__PURE__ */ jsx15(
897
1473
  CheckboxPrimitive.Indicator,
898
1474
  {
899
1475
  "data-slot": "checkbox-indicator",
900
1476
  className: "grid place-content-center text-current transition-none",
901
- children: /* @__PURE__ */ jsx11(CheckIcon, { className: "size-3.5" })
1477
+ children: /* @__PURE__ */ jsx15(CheckIcon, { className: "size-3.5" })
902
1478
  }
903
1479
  )
904
1480
  }
905
1481
  );
906
1482
  }
907
1483
 
908
- // src/components/lux-table/lux-table.tsx
909
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
910
- function createSelectionColumn() {
911
- return {
912
- id: "__selection__",
913
- header: ({ table }) => /* @__PURE__ */ jsx12(
914
- Checkbox,
915
- {
916
- checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
917
- onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value),
918
- "aria-label": "Select all rows"
919
- }
920
- ),
921
- cell: ({ row }) => /* @__PURE__ */ jsx12(
922
- Checkbox,
1484
+ // src/components/cell-renderers/progress-cell.tsx
1485
+ import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1486
+ function ProgressCell({
1487
+ value,
1488
+ barColor = "bg-[hsl(var(--lux-progress-bar))]",
1489
+ bgColor = "bg-[hsl(var(--lux-progress-bg))]",
1490
+ showLabel = false,
1491
+ className
1492
+ }) {
1493
+ const clampedValue = Math.min(100, Math.max(0, value));
1494
+ return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
1495
+ /* @__PURE__ */ jsx16("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx16(
1496
+ "div",
923
1497
  {
924
- checked: row.getIsSelected(),
925
- disabled: !row.getCanSelect(),
926
- onCheckedChange: (value) => row.toggleSelected(!!value),
927
- "aria-label": "Select row"
1498
+ className: `${barColor} h-2.5 rounded-full transition-all`,
1499
+ style: { width: `${clampedValue}%` }
928
1500
  }
929
- ),
930
- size: 40,
931
- enableSorting: false,
932
- enableHiding: false
933
- };
1501
+ ) }),
1502
+ showLabel && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-[hsl(var(--lux-progress-text))] w-8", children: [
1503
+ value,
1504
+ "%"
1505
+ ] })
1506
+ ] });
934
1507
  }
935
- function LuxTable({
936
- columns,
937
- data,
1508
+
1509
+ // src/components/cell-renderers/boolean-cell.tsx
1510
+ import { jsx as jsx17 } from "react/jsx-runtime";
1511
+ function BooleanCell({
1512
+ value,
1513
+ trueLabel = "Yes",
1514
+ falseLabel = "No",
1515
+ trueColor = "text-[hsl(var(--lux-boolean-true))]",
1516
+ falseColor = "text-[hsl(var(--lux-boolean-false))]"
1517
+ }) {
1518
+ return /* @__PURE__ */ jsx17("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
1519
+ }
1520
+
1521
+ // src/components/cell-renderers/date-cell.tsx
1522
+ import { jsx as jsx18 } from "react/jsx-runtime";
1523
+ function DateCell({ value, format: format2 = "short", locale = "en-US" }) {
1524
+ const date = typeof value === "string" ? new Date(value) : value;
1525
+ if (isNaN(date.getTime())) {
1526
+ return /* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--lux-table-cell-muted))]", children: "-" });
1527
+ }
1528
+ let formatted;
1529
+ switch (format2) {
1530
+ case "long":
1531
+ formatted = date.toLocaleDateString(locale, {
1532
+ year: "numeric",
1533
+ month: "long",
1534
+ day: "numeric"
1535
+ });
1536
+ break;
1537
+ case "relative": {
1538
+ const now = /* @__PURE__ */ new Date();
1539
+ const diffMs = now.getTime() - date.getTime();
1540
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1541
+ if (diffDays === 0) formatted = "Today";
1542
+ else if (diffDays === 1) formatted = "Yesterday";
1543
+ else if (diffDays < 7) formatted = `${diffDays} days ago`;
1544
+ else formatted = date.toLocaleDateString(locale);
1545
+ break;
1546
+ }
1547
+ default:
1548
+ formatted = date.toLocaleDateString(locale);
1549
+ }
1550
+ return /* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: formatted });
1551
+ }
1552
+
1553
+ // src/components/cell-renderers/currency-cell.tsx
1554
+ import { jsx as jsx19 } from "react/jsx-runtime";
1555
+ function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
1556
+ const formatted = new Intl.NumberFormat(locale, {
1557
+ style: "currency",
1558
+ currency
1559
+ }).format(value);
1560
+ return /* @__PURE__ */ jsx19("span", { className: "font-medium text-[hsl(var(--lux-table-cell-foreground))]", children: formatted });
1561
+ }
1562
+
1563
+ // src/components/cell-renderers/copyable-cell.tsx
1564
+ import * as React9 from "react";
1565
+ import { Copy, Check as Check3 } from "lucide-react";
1566
+ import { jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
1567
+ function CopyableCell({
1568
+ value,
1569
+ feedbackDuration = 2e3,
1570
+ onCopy,
938
1571
  className,
939
- options,
940
- sorting: controlledSorting,
941
- onSortingChange,
942
- rowSelection: controlledRowSelection,
943
- onRowSelectionChange,
944
- onSelectedRowsChange,
945
- getRowId
1572
+ tooltip = "Click to copy",
1573
+ alwaysShowIcon = false
946
1574
  }) {
947
- const [internalSorting, setInternalSorting] = React7.useState([]);
948
- const [columnFilters, setColumnFilters] = React7.useState([]);
949
- const [globalFilter, setGlobalFilter] = React7.useState("");
950
- const [filteringVisible, setFilteringVisible] = React7.useState(options?.filtering ?? false);
951
- const [internalRowSelection, setInternalRowSelection] = React7.useState({});
952
- const isControlledSorting = controlledSorting !== void 0;
953
- const sorting = isControlledSorting ? controlledSorting : internalSorting;
954
- const isControlledRowSelection = controlledRowSelection !== void 0;
955
- const rowSelection = isControlledRowSelection ? controlledRowSelection : internalRowSelection;
956
- const selectionMode = options?.selection ?? "none";
957
- const showCheckbox = options?.showSelectionCheckbox ?? selectionMode !== "none";
958
- const enableRowSelection = selectionMode !== "none";
959
- const enableMultiRowSelection = selectionMode === "multiple";
960
- const tableColumns = React7.useMemo(() => {
961
- if (showCheckbox && enableRowSelection) {
962
- return [createSelectionColumn(), ...columns];
1575
+ const [copied, setCopied] = React9.useState(false);
1576
+ const [isHovered, setIsHovered] = React9.useState(false);
1577
+ const handleCopy = async (e) => {
1578
+ e.stopPropagation();
1579
+ const textToCopy = String(value);
1580
+ try {
1581
+ await navigator.clipboard.writeText(textToCopy);
1582
+ setCopied(true);
1583
+ onCopy?.(textToCopy);
1584
+ setTimeout(() => {
1585
+ setCopied(false);
1586
+ }, feedbackDuration);
1587
+ } catch (err) {
1588
+ console.error("Copy error:", err);
1589
+ }
1590
+ };
1591
+ return /* @__PURE__ */ jsxs9(
1592
+ "button",
1593
+ {
1594
+ type: "button",
1595
+ onClick: handleCopy,
1596
+ onMouseEnter: () => setIsHovered(true),
1597
+ onMouseLeave: () => setIsHovered(false),
1598
+ title: tooltip,
1599
+ className: `
1600
+ group inline-flex items-center gap-2
1601
+ px-2 py-1 -mx-2 -my-1
1602
+ rounded-md
1603
+ transition-all duration-200
1604
+ hover:bg-slate-100 dark:hover:bg-slate-800
1605
+ focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1
1606
+ cursor-pointer
1607
+ ${className || ""}
1608
+ `,
1609
+ children: [
1610
+ /* @__PURE__ */ jsx20("span", { className: "select-none text-[hsl(var(--lux-table-cell-foreground))]", children: value }),
1611
+ /* @__PURE__ */ jsx20(
1612
+ "span",
1613
+ {
1614
+ className: `
1615
+ inline-flex items-center justify-center
1616
+ transition-all duration-200
1617
+ ${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
1618
+ `,
1619
+ children: copied ? /* @__PURE__ */ jsx20(Check3, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx20(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" })
1620
+ }
1621
+ )
1622
+ ]
963
1623
  }
964
- return columns;
965
- }, [columns, showCheckbox, enableRowSelection]);
966
- const handleRowSelectionChange = React7.useCallback(
967
- (updater) => {
968
- const newSelection = typeof updater === "function" ? updater(rowSelection) : updater;
969
- if (isControlledRowSelection && onRowSelectionChange) {
970
- onRowSelectionChange(newSelection);
971
- } else {
972
- setInternalRowSelection(newSelection);
973
- }
974
- },
975
- [isControlledRowSelection, onRowSelectionChange, rowSelection]
976
1624
  );
977
- const enableSorting = options?.sorting !== false;
978
- const enableMultiSort = options?.multiSort !== false;
979
- const table = useReactTable({
980
- data,
981
- columns: tableColumns,
982
- enableSorting,
983
- enableMultiSort,
984
- // Shift+Click for multi-sort (default behavior)
985
- isMultiSortEvent: (e) => e.shiftKey,
986
- // Max columns for multi-sort (undefined = unlimited)
987
- maxMultiSortColCount: options?.maxMultiSortColCount,
988
- state: {
989
- sorting,
990
- columnFilters,
991
- rowSelection,
992
- globalFilter
993
- },
994
- onGlobalFilterChange: setGlobalFilter,
995
- onSortingChange: (updater) => {
996
- const newSorting = typeof updater === "function" ? updater(sorting) : updater;
997
- if (isControlledSorting && onSortingChange) {
998
- onSortingChange(newSorting);
999
- } else {
1000
- setInternalSorting(newSorting);
1001
- }
1002
- },
1003
- onColumnFiltersChange: setColumnFilters,
1004
- onRowSelectionChange: handleRowSelectionChange,
1005
- enableRowSelection,
1006
- enableMultiRowSelection,
1007
- getRowId: getRowId ?? ((row, index) => {
1008
- if (typeof row === "object" && row !== null && "id" in row) {
1009
- return String(row.id);
1010
- }
1011
- return String(index);
1012
- }),
1013
- getCoreRowModel: getCoreRowModel(),
1014
- getPaginationRowModel: options?.pagination ? getPaginationRowModel() : void 0,
1015
- getSortedRowModel: getSortedRowModel(),
1016
- getFilteredRowModel: getFilteredRowModel(),
1017
- getFacetedUniqueValues: getFacetedUniqueValues(),
1018
- initialState: {
1019
- pagination: {
1020
- pageSize: options?.pageSize ?? 10
1021
- }
1625
+ }
1626
+ function createCopyableCell(value, options) {
1627
+ return /* @__PURE__ */ jsx20(CopyableCell, { value, ...options });
1628
+ }
1629
+
1630
+ // src/lib/cell-config.tsx
1631
+ import { jsx as jsx21 } from "react/jsx-runtime";
1632
+ var defaultPatterns = {
1633
+ status: ["status", "state", "stage", "phase"],
1634
+ date: ["date", "createdAt", "updatedAt", "joinDate", "startDate", "endDate", "birthDate", "publishedAt"],
1635
+ currency: ["price", "amount", "salary", "cost", "revenue", "total", "balance", "fee"],
1636
+ boolean: ["isActive", "isVerified", "isEnabled", "isDeleted", "isPublished", "isPublic"],
1637
+ copyable: ["id", "email", "phone", "code", "token", "reference", "orderId"]
1638
+ };
1639
+ function detectFieldTypeFromName(fieldName, patterns) {
1640
+ const name = fieldName.toLowerCase();
1641
+ const mergedPatterns = {
1642
+ status: [...defaultPatterns.status, ...patterns?.status || []],
1643
+ date: [...defaultPatterns.date, ...patterns?.date || []],
1644
+ currency: [...defaultPatterns.currency, ...patterns?.currency || []],
1645
+ boolean: [...defaultPatterns.boolean, ...patterns?.boolean || []],
1646
+ copyable: [...defaultPatterns.copyable, ...patterns?.copyable || []]
1647
+ };
1648
+ if (mergedPatterns.status.some((pattern) => name.includes(pattern.toLowerCase()))) {
1649
+ return "status";
1650
+ }
1651
+ if (mergedPatterns.date.some((pattern) => name.includes(pattern.toLowerCase()))) {
1652
+ return "date";
1653
+ }
1654
+ if (mergedPatterns.currency.some((pattern) => name.includes(pattern.toLowerCase()))) {
1655
+ return "currency";
1656
+ }
1657
+ if (mergedPatterns.boolean.some((pattern) => name.includes(pattern.toLowerCase()))) {
1658
+ return "boolean";
1659
+ }
1660
+ if (mergedPatterns.copyable.some((pattern) => name.includes(pattern.toLowerCase()))) {
1661
+ return "copyable";
1662
+ }
1663
+ return null;
1664
+ }
1665
+ function detectFieldTypeFromValue(value) {
1666
+ if (value === null || value === void 0) return null;
1667
+ if (typeof value === "boolean") {
1668
+ return "boolean";
1669
+ }
1670
+ if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value)) {
1671
+ const date = new Date(value);
1672
+ if (!isNaN(date.getTime())) {
1673
+ return "date";
1022
1674
  }
1023
- });
1024
- React7.useEffect(() => {
1025
- if (onSelectedRowsChange) {
1026
- const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
1027
- onSelectedRowsChange(selectedRows);
1675
+ }
1676
+ if (value instanceof Date) {
1677
+ return "date";
1678
+ }
1679
+ if (typeof value === "number") {
1680
+ return null;
1681
+ }
1682
+ if (typeof value === "string") {
1683
+ const lowerValue = value.toLowerCase();
1684
+ const statusValues = ["active", "inactive", "pending", "completed", "cancelled", "approved", "rejected"];
1685
+ if (statusValues.includes(lowerValue)) {
1686
+ return "status";
1028
1687
  }
1029
- }, [rowSelection, onSelectedRowsChange, table]);
1030
- const visibleColumnCount = tableColumns.length;
1031
- const showToolbar = options?.showToolbar ?? false;
1032
- const showGlobalSearch = options?.showGlobalSearch ?? true;
1033
- const showColumnVisibility = options?.showColumnVisibility ?? true;
1034
- return /* @__PURE__ */ jsxs7("div", { className: cn("w-full space-y-4", className), children: [
1035
- showToolbar && /* @__PURE__ */ jsx12(
1036
- TableToolbar,
1688
+ }
1689
+ return null;
1690
+ }
1691
+ function getFieldConfig(fieldName, value, config) {
1692
+ if (config?.fields?.[fieldName]) {
1693
+ return config.fields[fieldName];
1694
+ }
1695
+ if (config?.autoDetect === false) {
1696
+ return null;
1697
+ }
1698
+ const nameType = detectFieldTypeFromName(fieldName, config?.patterns);
1699
+ if (nameType) {
1700
+ switch (nameType) {
1701
+ case "status":
1702
+ return { type: "status" };
1703
+ case "date":
1704
+ return { type: "date", format: "short" };
1705
+ case "currency":
1706
+ return { type: "currency", currency: "USD" };
1707
+ case "boolean":
1708
+ return { type: "boolean" };
1709
+ case "copyable":
1710
+ return { type: "copyable" };
1711
+ }
1712
+ }
1713
+ const valueType = detectFieldTypeFromValue(value);
1714
+ if (valueType) {
1715
+ switch (valueType) {
1716
+ case "status":
1717
+ return { type: "status" };
1718
+ case "date":
1719
+ return { type: "date", format: "short" };
1720
+ case "boolean":
1721
+ return { type: "boolean" };
1722
+ }
1723
+ }
1724
+ return null;
1725
+ }
1726
+ var defaultGlobalCellConfig = {
1727
+ defaultStatusColors,
1728
+ autoDetect: true,
1729
+ patterns: defaultPatterns
1730
+ };
1731
+ function renderCell(context, fieldName, config) {
1732
+ const value = context.getValue();
1733
+ const fieldConfig = getFieldConfig(fieldName, value, config);
1734
+ if (!fieldConfig) {
1735
+ if (value === null || value === void 0) {
1736
+ return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: "-" });
1737
+ }
1738
+ return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: String(value) });
1739
+ }
1740
+ if (fieldConfig.type === "custom") {
1741
+ return fieldConfig.render(context);
1742
+ }
1743
+ if (fieldConfig.type === "status") {
1744
+ const statusValue = String(value);
1745
+ const colors = {
1746
+ ...config?.defaultStatusColors,
1747
+ ...defaultStatusColors,
1748
+ ...fieldConfig.colors
1749
+ };
1750
+ return /* @__PURE__ */ jsx21(StatusCell, { value: statusValue, colors });
1751
+ }
1752
+ if (fieldConfig.type === "progress") {
1753
+ return /* @__PURE__ */ jsx21(
1754
+ ProgressCell,
1037
1755
  {
1038
- table,
1039
- showFiltering: options?.filtering !== void 0,
1040
- filteringEnabled: filteringVisible,
1041
- onFilteringToggle: setFilteringVisible,
1042
- showGlobalSearch,
1043
- showColumnVisibility
1756
+ value: Number(value),
1757
+ barColor: fieldConfig.barColor,
1758
+ showLabel: fieldConfig.showLabel ?? false
1044
1759
  }
1045
- ),
1046
- enableRowSelection && Object.keys(rowSelection).length > 0 && /* @__PURE__ */ jsxs7("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: [
1047
- /* @__PURE__ */ jsx12(CheckCircle2, { className: "w-4 h-4" }),
1048
- /* @__PURE__ */ jsxs7("span", { children: [
1049
- /* @__PURE__ */ jsx12("strong", { children: Object.keys(rowSelection).length }),
1050
- " rows selected",
1051
- table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ jsxs7("span", { className: "text-blue-500 dark:text-blue-400", children: [
1052
- " / ",
1053
- table.getFilteredRowModel().rows.length,
1054
- " total"
1055
- ] })
1056
- ] }),
1057
- /* @__PURE__ */ jsx12(
1058
- "button",
1059
- {
1060
- type: "button",
1061
- onClick: () => handleRowSelectionChange({}),
1062
- className: "ml-auto text-xs hover:text-blue-900 dark:hover:text-blue-100 underline underline-offset-2",
1063
- children: "Clear selection"
1064
- }
1065
- )
1066
- ] }),
1067
- /* @__PURE__ */ jsx12("div", { className: "rounded-md border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 overflow-hidden", children: /* @__PURE__ */ jsxs7(Table, { children: [
1068
- /* @__PURE__ */ jsxs7(TableHeader, { children: [
1069
- table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx12(TableRow, { children: headerGroup.headers.map((header) => {
1070
- const isSelectionColumn = header.id === "__selection__";
1071
- return /* @__PURE__ */ jsx12(
1072
- TableHead,
1073
- {
1074
- style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
1075
- children: header.isPlaceholder ? null : isSelectionColumn ? flexRender2(
1076
- header.column.columnDef.header,
1077
- header.getContext()
1078
- ) : /* @__PURE__ */ jsx12(
1079
- SortableHeader,
1080
- {
1081
- header,
1082
- showSortIndex: enableMultiSort && sorting.length > 1
1083
- }
1084
- )
1085
- },
1086
- header.id
1087
- );
1088
- }) }, headerGroup.id)),
1089
- filteringVisible && /* @__PURE__ */ jsx12(TableRow, { className: "bg-slate-50/50 dark:bg-slate-900/50", children: table.getHeaderGroups()[0]?.headers.map((header) => {
1090
- const isSelectionColumn = header.id === "__selection__";
1091
- return /* @__PURE__ */ jsx12(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ jsx12(ColumnFilter, { column: header.column }) : null }, `filter-${header.id}`);
1092
- }) })
1093
- ] }),
1094
- /* @__PURE__ */ jsx12(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx12(
1095
- TableRow,
1096
- {
1097
- "data-state": row.getIsSelected() && "selected",
1098
- className: cn(
1099
- enableRowSelection && "cursor-pointer",
1100
- row.getIsSelected() && "bg-blue-50/50 dark:bg-blue-950/30"
1101
- ),
1102
- onClick: enableRowSelection && !showCheckbox ? () => {
1103
- if (selectionMode === "single") {
1104
- handleRowSelectionChange({ [row.id]: true });
1105
- } else {
1106
- row.toggleSelected();
1107
- }
1108
- } : void 0,
1109
- children: row.getVisibleCells().map((cell) => {
1110
- const isSelectionColumn = cell.column.id === "__selection__";
1111
- return /* @__PURE__ */ jsx12(
1112
- TableCell,
1113
- {
1114
- style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
1115
- onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
1116
- children: flexRender2(cell.column.columnDef.cell, cell.getContext())
1117
- },
1118
- cell.id
1119
- );
1120
- })
1121
- },
1122
- row.id
1123
- )) : /* @__PURE__ */ jsx12(TableRow, { children: /* @__PURE__ */ jsx12(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
1124
- ] }) }),
1125
- options?.pagination && /* @__PURE__ */ jsx12(TablePagination, { table })
1126
- ] });
1760
+ );
1761
+ }
1762
+ if (fieldConfig.type === "boolean") {
1763
+ return /* @__PURE__ */ jsx21(
1764
+ BooleanCell,
1765
+ {
1766
+ value: Boolean(value),
1767
+ trueLabel: fieldConfig.trueLabel,
1768
+ falseLabel: fieldConfig.falseLabel,
1769
+ trueColor: fieldConfig.trueColor,
1770
+ falseColor: fieldConfig.falseColor
1771
+ }
1772
+ );
1773
+ }
1774
+ if (fieldConfig.type === "date") {
1775
+ return /* @__PURE__ */ jsx21(
1776
+ DateCell,
1777
+ {
1778
+ value,
1779
+ format: fieldConfig.format,
1780
+ locale: fieldConfig.locale
1781
+ }
1782
+ );
1783
+ }
1784
+ if (fieldConfig.type === "currency") {
1785
+ return /* @__PURE__ */ jsx21(
1786
+ CurrencyCell,
1787
+ {
1788
+ value: Number(value),
1789
+ currency: fieldConfig.currency || "USD",
1790
+ locale: fieldConfig.locale || "en-US"
1791
+ }
1792
+ );
1793
+ }
1794
+ if (fieldConfig.type === "copyable") {
1795
+ return /* @__PURE__ */ jsx21(
1796
+ CopyableCell,
1797
+ {
1798
+ value: String(value),
1799
+ alwaysShowIcon: fieldConfig.alwaysShowIcon,
1800
+ tooltip: fieldConfig.tooltip,
1801
+ onCopy: fieldConfig.onCopy
1802
+ }
1803
+ );
1804
+ }
1805
+ if (value === null || value === void 0) {
1806
+ return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: "-" });
1807
+ }
1808
+ return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: String(value) });
1127
1809
  }
1128
1810
 
1811
+ // src/lib/column-helper.tsx
1812
+ import { createColumnHelper as tanstackCreateColumnHelper } from "@tanstack/react-table";
1813
+
1129
1814
  // src/components/lux-table/column-header.tsx
1130
1815
  import {
1131
1816
  ArrowDown,
@@ -1133,9 +1818,9 @@ import {
1133
1818
  ArrowUpDown,
1134
1819
  EyeOff as EyeOff2,
1135
1820
  MoreVertical,
1136
- X
1821
+ X as X2
1137
1822
  } from "lucide-react";
1138
- import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1823
+ import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
1139
1824
  function LuxDataTableColumnHeader({
1140
1825
  column,
1141
1826
  title,
@@ -1145,327 +1830,74 @@ function LuxDataTableColumnHeader({
1145
1830
  const canSort = column.getCanSort();
1146
1831
  const SortIndicator = () => {
1147
1832
  if (isSorted === "desc") {
1148
- return /* @__PURE__ */ jsx13(ArrowDown, { className: "h-4 w-4 text-blue-600 dark:text-blue-400" });
1833
+ return /* @__PURE__ */ jsx22(ArrowDown, { className: "h-4 w-4 text-[hsl(var(--lux-sort-active))]" });
1149
1834
  }
1150
1835
  if (isSorted === "asc") {
1151
- return /* @__PURE__ */ jsx13(ArrowUp, { className: "h-4 w-4 text-blue-600 dark:text-blue-400" });
1836
+ return /* @__PURE__ */ jsx22(ArrowUp, { className: "h-4 w-4 text-[hsl(var(--lux-sort-active))]" });
1152
1837
  }
1153
1838
  if (canSort) {
1154
- return /* @__PURE__ */ jsx13(ArrowUpDown, { className: "h-4 w-4 text-slate-400 dark:text-slate-500" });
1839
+ return /* @__PURE__ */ jsx22(ArrowUpDown, { className: "h-4 w-4 text-[hsl(var(--lux-sort-idle))]" });
1155
1840
  }
1156
1841
  return null;
1157
1842
  };
1158
1843
  if (!canSort) {
1159
- return /* @__PURE__ */ jsx13("span", { className: cn("text-sm font-medium", className), children: title });
1844
+ return /* @__PURE__ */ jsx22("span", { className: cn("text-sm font-medium", className), children: title });
1160
1845
  }
1161
- return /* @__PURE__ */ jsxs8("div", { className: cn("flex items-center gap-2", className), children: [
1162
- /* @__PURE__ */ jsx13(SortIndicator, {}),
1163
- /* @__PURE__ */ jsx13("span", { className: "text-sm font-medium", children: title }),
1164
- /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
1165
- /* @__PURE__ */ jsx13(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
1846
+ return /* @__PURE__ */ jsxs10("div", { className: cn("flex items-center gap-2", className), children: [
1847
+ /* @__PURE__ */ jsx22(SortIndicator, {}),
1848
+ /* @__PURE__ */ jsx22("span", { className: "text-sm font-medium", children: title }),
1849
+ /* @__PURE__ */ jsxs10(DropdownMenu, { children: [
1850
+ /* @__PURE__ */ jsx22(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
1166
1851
  Button,
1167
1852
  {
1168
1853
  variant: "ghost",
1169
1854
  size: "icon",
1170
- className: "h-6 w-6 ml-auto opacity-0 group-hover:opacity-100 hover:opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
1855
+ className: "h-6 w-6 ml-auto opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
1171
1856
  children: [
1172
- /* @__PURE__ */ jsx13(MoreVertical, { className: "h-3.5 w-3.5" }),
1173
- /* @__PURE__ */ jsx13("span", { className: "sr-only", children: "Column actions" })
1857
+ /* @__PURE__ */ jsx22(MoreVertical, { className: "h-3.5 w-3.5" }),
1858
+ /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Column actions" })
1174
1859
  ]
1175
1860
  }
1176
1861
  ) }),
1177
- /* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", children: [
1178
- /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1862
+ /* @__PURE__ */ jsxs10(DropdownMenuContent, { align: "end", className: "bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-800", children: [
1863
+ /* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
1179
1864
  e.stopPropagation();
1180
1865
  column.toggleSorting(false);
1181
1866
  }, children: [
1182
- /* @__PURE__ */ jsx13(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1867
+ /* @__PURE__ */ jsx22(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1183
1868
  "Sort Ascending"
1184
1869
  ] }),
1185
- /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1870
+ /* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
1186
1871
  e.stopPropagation();
1187
1872
  column.toggleSorting(true);
1188
1873
  }, children: [
1189
- /* @__PURE__ */ jsx13(ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1190
- "Sort Descending"
1191
- ] }),
1192
- isSorted && /* @__PURE__ */ jsxs8(Fragment3, { children: [
1193
- /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1194
- /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1195
- e.stopPropagation();
1196
- column.clearSorting();
1197
- }, children: [
1198
- /* @__PURE__ */ jsx13(X, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1199
- "Clear sorting"
1200
- ] })
1201
- ] }),
1202
- /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1203
- /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1204
- e.stopPropagation();
1205
- column.toggleVisibility(false);
1206
- }, children: [
1207
- /* @__PURE__ */ jsx13(EyeOff2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1208
- "Hide column"
1209
- ] })
1210
- ] })
1211
- ] })
1212
- ] });
1213
- }
1214
-
1215
- // src/components/cell-renderers/status-cell.tsx
1216
- import { jsx as jsx14 } from "react/jsx-runtime";
1217
- var defaultStatusColors = {
1218
- Active: {
1219
- bg: "bg-green-100",
1220
- text: "text-green-800",
1221
- darkBg: "dark:bg-green-900",
1222
- darkText: "dark:text-green-300"
1223
- },
1224
- Inactive: {
1225
- bg: "bg-red-100",
1226
- text: "text-red-800",
1227
- darkBg: "dark:bg-red-900",
1228
- darkText: "dark:text-red-300"
1229
- },
1230
- Pending: {
1231
- bg: "bg-yellow-100",
1232
- text: "text-yellow-800",
1233
- darkBg: "dark:bg-yellow-900",
1234
- darkText: "dark:text-yellow-300"
1235
- },
1236
- Completed: {
1237
- bg: "bg-blue-100",
1238
- text: "text-blue-800",
1239
- darkBg: "dark:bg-blue-900",
1240
- darkText: "dark:text-blue-300"
1241
- },
1242
- Cancelled: {
1243
- bg: "bg-gray-100",
1244
- text: "text-gray-800",
1245
- darkBg: "dark:bg-gray-900",
1246
- darkText: "dark:text-gray-300"
1247
- }
1248
- };
1249
- function StatusCell({ value, colors, className }) {
1250
- const mergedColors = { ...defaultStatusColors, ...colors };
1251
- const colorConfig = mergedColors[value];
1252
- if (!colorConfig) {
1253
- return /* @__PURE__ */ jsx14("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 });
1254
- }
1255
- const { bg, text, darkBg, darkText } = colorConfig;
1256
- return /* @__PURE__ */ jsx14("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${darkBg || ""} ${darkText || ""} ${className || ""}`, children: value });
1257
- }
1258
-
1259
- // src/components/cell-renderers/progress-cell.tsx
1260
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1261
- function ProgressCell({
1262
- value,
1263
- barColor = "bg-blue-600",
1264
- bgColor = "bg-gray-200 dark:bg-gray-700",
1265
- showLabel = false,
1266
- className
1267
- }) {
1268
- const clampedValue = Math.min(100, Math.max(0, value));
1269
- return /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
1270
- /* @__PURE__ */ jsx15("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx15(
1271
- "div",
1272
- {
1273
- className: `${barColor} h-2.5 rounded-full transition-all`,
1274
- style: { width: `${clampedValue}%` }
1275
- }
1276
- ) }),
1277
- showLabel && /* @__PURE__ */ jsxs9("span", { className: "text-xs text-gray-500 dark:text-gray-400 w-8", children: [
1278
- value,
1279
- "%"
1280
- ] })
1281
- ] });
1282
- }
1283
-
1284
- // src/components/cell-renderers/boolean-cell.tsx
1285
- import { jsx as jsx16 } from "react/jsx-runtime";
1286
- function BooleanCell({
1287
- value,
1288
- trueLabel = "Yes",
1289
- falseLabel = "No",
1290
- trueColor = "text-green-600 dark:text-green-400",
1291
- falseColor = "text-red-600 dark:text-red-400"
1292
- }) {
1293
- return /* @__PURE__ */ jsx16("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
1294
- }
1295
-
1296
- // src/components/cell-renderers/date-cell.tsx
1297
- import { jsx as jsx17 } from "react/jsx-runtime";
1298
- function DateCell({ value, format = "short", locale = "en-US" }) {
1299
- const date = typeof value === "string" ? new Date(value) : value;
1300
- if (isNaN(date.getTime())) {
1301
- return /* @__PURE__ */ jsx17("span", { className: "text-gray-400", children: "-" });
1302
- }
1303
- let formatted;
1304
- switch (format) {
1305
- case "long":
1306
- formatted = date.toLocaleDateString(locale, {
1307
- year: "numeric",
1308
- month: "long",
1309
- day: "numeric"
1310
- });
1311
- break;
1312
- case "relative": {
1313
- const now = /* @__PURE__ */ new Date();
1314
- const diffMs = now.getTime() - date.getTime();
1315
- const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1316
- if (diffDays === 0) formatted = "Today";
1317
- else if (diffDays === 1) formatted = "Yesterday";
1318
- else if (diffDays < 7) formatted = `${diffDays} days ago`;
1319
- else formatted = date.toLocaleDateString(locale);
1320
- break;
1321
- }
1322
- default:
1323
- formatted = date.toLocaleDateString(locale);
1324
- }
1325
- return /* @__PURE__ */ jsx17("span", { children: formatted });
1326
- }
1327
-
1328
- // src/components/cell-renderers/currency-cell.tsx
1329
- import { jsx as jsx18 } from "react/jsx-runtime";
1330
- function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
1331
- const formatted = new Intl.NumberFormat(locale, {
1332
- style: "currency",
1333
- currency
1334
- }).format(value);
1335
- return /* @__PURE__ */ jsx18("span", { className: "font-medium", children: formatted });
1336
- }
1337
-
1338
- // src/components/cell-renderers/copyable-cell.tsx
1339
- import * as React8 from "react";
1340
- import { Copy, Check as Check3 } from "lucide-react";
1341
- import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
1342
- function CopyableCell({
1343
- value,
1344
- feedbackDuration = 2e3,
1345
- onCopy,
1346
- className,
1347
- tooltip = "Click to copy",
1348
- alwaysShowIcon = false
1349
- }) {
1350
- const [copied, setCopied] = React8.useState(false);
1351
- const [isHovered, setIsHovered] = React8.useState(false);
1352
- const handleCopy = async (e) => {
1353
- e.stopPropagation();
1354
- const textToCopy = String(value);
1355
- try {
1356
- await navigator.clipboard.writeText(textToCopy);
1357
- setCopied(true);
1358
- onCopy?.(textToCopy);
1359
- setTimeout(() => {
1360
- setCopied(false);
1361
- }, feedbackDuration);
1362
- } catch (err) {
1363
- console.error("Copy error:", err);
1364
- }
1365
- };
1366
- return /* @__PURE__ */ jsxs10(
1367
- "button",
1368
- {
1369
- type: "button",
1370
- onClick: handleCopy,
1371
- onMouseEnter: () => setIsHovered(true),
1372
- onMouseLeave: () => setIsHovered(false),
1373
- title: tooltip,
1374
- className: `
1375
- group inline-flex items-center gap-2
1376
- px-2 py-1 -mx-2 -my-1
1377
- rounded-md
1378
- transition-all duration-200
1379
- hover:bg-slate-100 dark:hover:bg-slate-800
1380
- focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1
1381
- cursor-pointer
1382
- ${className || ""}
1383
- `,
1384
- children: [
1385
- /* @__PURE__ */ jsx19("span", { className: "select-none", children: value }),
1386
- /* @__PURE__ */ jsx19(
1387
- "span",
1388
- {
1389
- className: `
1390
- inline-flex items-center justify-center
1391
- transition-all duration-200
1392
- ${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
1393
- `,
1394
- children: copied ? /* @__PURE__ */ jsx19(Check3, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx19(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" })
1395
- }
1396
- )
1397
- ]
1398
- }
1399
- );
1400
- }
1401
- function createCopyableCell(value, options) {
1402
- return /* @__PURE__ */ jsx19(CopyableCell, { value, ...options });
1403
- }
1404
-
1405
- // src/components/ui/label.tsx
1406
- import * as React9 from "react";
1407
- import * as LabelPrimitive from "@radix-ui/react-label";
1408
- import { cva as cva2 } from "class-variance-authority";
1409
- import { jsx as jsx20 } from "react/jsx-runtime";
1410
- var labelVariants = cva2(
1411
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
1412
- );
1413
- var Label3 = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
1414
- LabelPrimitive.Root,
1415
- {
1416
- ref,
1417
- className: cn(labelVariants(), className),
1418
- ...props
1419
- }
1420
- ));
1421
- Label3.displayName = LabelPrimitive.Root.displayName;
1422
-
1423
- // src/components/ui/popover.tsx
1424
- import * as React10 from "react";
1425
- import * as PopoverPrimitive from "@radix-ui/react-popover";
1426
- import { jsx as jsx21 } from "react/jsx-runtime";
1427
- var Popover = PopoverPrimitive.Root;
1428
- var PopoverTrigger = PopoverPrimitive.Trigger;
1429
- var PopoverAnchor = PopoverPrimitive.Anchor;
1430
- var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx21(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx21(
1431
- PopoverPrimitive.Content,
1432
- {
1433
- ref,
1434
- align,
1435
- sideOffset,
1436
- className: cn(
1437
- "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",
1438
- className
1439
- ),
1440
- ...props
1441
- }
1442
- ) }));
1443
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
1444
-
1445
- // src/components/ui/separator.tsx
1446
- import * as React11 from "react";
1447
- import * as SeparatorPrimitive from "@radix-ui/react-separator";
1448
- import { jsx as jsx22 } from "react/jsx-runtime";
1449
- var Separator3 = React11.forwardRef(
1450
- ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx22(
1451
- SeparatorPrimitive.Root,
1452
- {
1453
- ref,
1454
- decorative,
1455
- orientation,
1456
- className: cn(
1457
- "shrink-0 bg-slate-200 dark:bg-slate-800",
1458
- orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
1459
- className
1460
- ),
1461
- ...props
1462
- }
1463
- )
1464
- );
1465
- Separator3.displayName = SeparatorPrimitive.Root.displayName;
1874
+ /* @__PURE__ */ jsx22(ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1875
+ "Sort Descending"
1876
+ ] }),
1877
+ isSorted && /* @__PURE__ */ jsxs10(Fragment3, { children: [
1878
+ /* @__PURE__ */ jsx22(DropdownMenuSeparator, {}),
1879
+ /* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
1880
+ e.stopPropagation();
1881
+ column.clearSorting();
1882
+ }, children: [
1883
+ /* @__PURE__ */ jsx22(X2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1884
+ "Clear sorting"
1885
+ ] })
1886
+ ] }),
1887
+ /* @__PURE__ */ jsx22(DropdownMenuSeparator, {}),
1888
+ /* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
1889
+ e.stopPropagation();
1890
+ column.toggleVisibility(false);
1891
+ }, children: [
1892
+ /* @__PURE__ */ jsx22(EyeOff2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1893
+ "Hide column"
1894
+ ] })
1895
+ ] })
1896
+ ] })
1897
+ ] });
1898
+ }
1466
1899
 
1467
1900
  // src/lib/column-helper.tsx
1468
- import { createColumnHelper as tanstackCreateColumnHelper } from "@tanstack/react-table";
1469
1901
  import { jsx as jsx23 } from "react/jsx-runtime";
1470
1902
  var toTitleCase = (str) => {
1471
1903
  return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
@@ -1482,6 +1914,8 @@ function createColumnHelper() {
1482
1914
  ...column,
1483
1915
  // enableSorting is true by default
1484
1916
  enableSorting: column?.enableSorting !== false,
1917
+ // Pass size if provided
1918
+ size: column?.size,
1485
1919
  // Pass meta information (filterVariant etc.)
1486
1920
  meta: column?.meta,
1487
1921
  // Use LuxDataTableColumnHeader if header is string or undefined
@@ -1492,14 +1926,9 @@ function createColumnHelper() {
1492
1926
  title: typeof headerContent === "string" ? headerContent : toTitleCase(accessor)
1493
1927
  }
1494
1928
  ),
1495
- // If cell is not defined, show value directly
1496
- cell: column?.cell || ((info) => {
1497
- const value = info.getValue();
1498
- if (value === null || value === void 0) {
1499
- return "-";
1500
- }
1501
- return String(value);
1502
- })
1929
+ // Only add default cell if cell is not explicitly provided
1930
+ // This allows LuxTable's cellConfig to work
1931
+ ...column?.cell ? { cell: column.cell } : {}
1503
1932
  };
1504
1933
  return helper.accessor(accessor, finalColumn);
1505
1934
  },
@@ -1556,15 +1985,395 @@ function createColumnsFromData(data, options) {
1556
1985
  const cellRenderer = options?.cells?.[key];
1557
1986
  return helper.accessor(key, {
1558
1987
  header: ({ column }) => /* @__PURE__ */ jsx23(LuxDataTableColumnHeader, { column, title: headerText }),
1559
- cell: cellRenderer || ((info) => {
1560
- const value = info.getValue();
1561
- if (value === null || value === void 0) return "-";
1562
- return String(value);
1563
- })
1988
+ // Only add cell if explicitly provided - this allows LuxTable's cellConfig to work
1989
+ ...cellRenderer ? { cell: cellRenderer } : {}
1990
+ });
1991
+ });
1992
+ }
1993
+
1994
+ // src/components/lux-table/lux-table.tsx
1995
+ import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
1996
+ function createSelectionColumn() {
1997
+ return {
1998
+ id: "__selection__",
1999
+ header: ({ table }) => /* @__PURE__ */ jsx24(
2000
+ Checkbox,
2001
+ {
2002
+ checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
2003
+ onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value),
2004
+ "aria-label": "Select all rows"
2005
+ }
2006
+ ),
2007
+ cell: ({ row }) => /* @__PURE__ */ jsx24(
2008
+ Checkbox,
2009
+ {
2010
+ checked: row.getIsSelected(),
2011
+ disabled: !row.getCanSelect(),
2012
+ onCheckedChange: (value) => row.toggleSelected(!!value),
2013
+ "aria-label": "Select row"
2014
+ }
2015
+ ),
2016
+ size: 40,
2017
+ enableSorting: false,
2018
+ enableHiding: false
2019
+ };
2020
+ }
2021
+ function LuxTable({
2022
+ columns,
2023
+ data,
2024
+ className,
2025
+ options,
2026
+ cellConfig,
2027
+ sorting: controlledSorting,
2028
+ onSortingChange,
2029
+ rowSelection: controlledRowSelection,
2030
+ onRowSelectionChange,
2031
+ onSelectedRowsChange,
2032
+ getRowId
2033
+ }) {
2034
+ const [internalSorting, setInternalSorting] = React10.useState([]);
2035
+ const [columnFilters, setColumnFilters] = React10.useState([]);
2036
+ const [globalFilter, setGlobalFilter] = React10.useState("");
2037
+ const [filteringVisible, setFilteringVisible] = React10.useState(options?.filtering ?? false);
2038
+ const [internalRowSelection, setInternalRowSelection] = React10.useState({});
2039
+ const isControlledSorting = controlledSorting !== void 0;
2040
+ const sorting = isControlledSorting ? controlledSorting : internalSorting;
2041
+ const isControlledRowSelection = controlledRowSelection !== void 0;
2042
+ const rowSelection = isControlledRowSelection ? controlledRowSelection : internalRowSelection;
2043
+ const selectionMode = options?.selection ?? "none";
2044
+ const showCheckbox = options?.showSelectionCheckbox ?? selectionMode !== "none";
2045
+ const enableRowSelection = selectionMode !== "none";
2046
+ const enableMultiRowSelection = selectionMode === "multiple";
2047
+ const mergedCellConfig = React10.useMemo(() => {
2048
+ const baseConfig = defaultGlobalCellConfig;
2049
+ if (cellConfig) {
2050
+ return {
2051
+ ...baseConfig,
2052
+ ...cellConfig,
2053
+ fields: {
2054
+ ...cellConfig.fields
2055
+ // User's fields override defaults
2056
+ },
2057
+ patterns: {
2058
+ ...baseConfig.patterns,
2059
+ ...cellConfig.patterns
2060
+ // Merge patterns
2061
+ },
2062
+ defaultStatusColors: {
2063
+ ...baseConfig.defaultStatusColors,
2064
+ ...cellConfig.defaultStatusColors
2065
+ // Merge status colors
2066
+ }
2067
+ };
2068
+ }
2069
+ return baseConfig;
2070
+ }, [cellConfig]);
2071
+ const autoColumns = React10.useMemo(() => {
2072
+ if (columns) return columns;
2073
+ if (!data || data.length === 0) return [];
2074
+ if (typeof data[0] === "object" && data[0] !== null) {
2075
+ const generatedColumns = createColumnsFromData(data);
2076
+ return generatedColumns;
2077
+ }
2078
+ return [];
2079
+ }, [columns, data]);
2080
+ const dateFilterFn = React10.useCallback((row, columnId, filterValue) => {
2081
+ if (!filterValue || !filterValue.from && !filterValue.to) return true;
2082
+ const cellValue = row.getValue(columnId);
2083
+ if (!cellValue) return false;
2084
+ const cellDate = new Date(String(cellValue));
2085
+ if (isNaN(cellDate.getTime())) return false;
2086
+ if (filterValue.from) {
2087
+ const fromDate = new Date(filterValue.from);
2088
+ fromDate.setHours(0, 0, 0, 0);
2089
+ if (cellDate < fromDate) return false;
2090
+ }
2091
+ if (filterValue.to) {
2092
+ const toDate = new Date(filterValue.to);
2093
+ toDate.setHours(23, 59, 59, 999);
2094
+ if (cellDate > toDate) return false;
2095
+ }
2096
+ return true;
2097
+ }, []);
2098
+ const sliderFilterFn = React10.useCallback((row, columnId, filterValue) => {
2099
+ if (!filterValue || filterValue.min === void 0 && filterValue.max === void 0) return true;
2100
+ const cellValue = row.getValue(columnId);
2101
+ const numValue = typeof cellValue === "number" ? cellValue : parseFloat(String(cellValue));
2102
+ if (isNaN(numValue)) return false;
2103
+ if (filterValue.min !== void 0 && numValue < filterValue.min) return false;
2104
+ if (filterValue.max !== void 0 && numValue > filterValue.max) return false;
2105
+ return true;
2106
+ }, []);
2107
+ const statusFilterFn = React10.useCallback((row, columnId, filterValue) => {
2108
+ if (!filterValue || filterValue.length === 0) return true;
2109
+ const cellValue = String(row.getValue(columnId)).toLowerCase();
2110
+ return filterValue.some((status) => status.toLowerCase() === cellValue);
2111
+ }, []);
2112
+ const tableColumns = React10.useMemo(() => {
2113
+ let processedColumns = autoColumns.map((col) => {
2114
+ const accessorKey = "accessorKey" in col ? col.accessorKey : void 0;
2115
+ const fieldName = accessorKey ? String(accessorKey) : "id" in col ? String(col.id) : void 0;
2116
+ let filterFn = col.filterFn;
2117
+ const meta = col.meta || {};
2118
+ if (fieldName && !meta.filterVariant) {
2119
+ const fieldNameLower = fieldName.toLowerCase();
2120
+ const datePatterns = ["date", "createdat", "updatedat", "joindate", "startdate", "enddate", "birthdate", "publishedat"];
2121
+ if (datePatterns.some((pattern) => fieldNameLower.includes(pattern))) {
2122
+ meta.filterVariant = "date";
2123
+ filterFn = dateFilterFn;
2124
+ }
2125
+ const statusPatterns = ["status", "state", "stage", "phase"];
2126
+ if (statusPatterns.some((pattern) => fieldNameLower.includes(pattern))) {
2127
+ meta.filterVariant = "status";
2128
+ filterFn = statusFilterFn;
2129
+ }
2130
+ const numericPatterns = ["salary", "price", "amount", "cost", "revenue", "total", "balance", "fee"];
2131
+ if (numericPatterns.some((pattern) => fieldNameLower.includes(pattern))) {
2132
+ meta.filterVariant = "slider";
2133
+ filterFn = sliderFilterFn;
2134
+ }
2135
+ } else if (meta.filterVariant) {
2136
+ if (meta.filterVariant === "date" && !filterFn) {
2137
+ filterFn = dateFilterFn;
2138
+ } else if (meta.filterVariant === "slider" && !filterFn) {
2139
+ filterFn = sliderFilterFn;
2140
+ } else if (meta.filterVariant === "status" && !filterFn) {
2141
+ filterFn = statusFilterFn;
2142
+ }
2143
+ }
2144
+ if (mergedCellConfig && fieldName) {
2145
+ const sampleValue = data && data.length > 0 ? data[0]?.[fieldName] : void 0;
2146
+ const fieldConfig = getFieldConfig(fieldName, sampleValue, mergedCellConfig);
2147
+ if (fieldConfig) {
2148
+ return {
2149
+ ...col,
2150
+ cell: (context) => renderCell(context, fieldName, mergedCellConfig),
2151
+ filterFn,
2152
+ meta
2153
+ };
2154
+ }
2155
+ }
2156
+ if (col.cell || filterFn || meta.filterVariant) {
2157
+ return {
2158
+ ...col,
2159
+ filterFn,
2160
+ meta
2161
+ };
2162
+ }
2163
+ return {
2164
+ ...col,
2165
+ filterFn,
2166
+ meta
2167
+ };
1564
2168
  });
2169
+ if (showCheckbox && enableRowSelection) {
2170
+ return [createSelectionColumn(), ...processedColumns];
2171
+ }
2172
+ return processedColumns;
2173
+ }, [autoColumns, showCheckbox, enableRowSelection, mergedCellConfig, data, dateFilterFn, sliderFilterFn, statusFilterFn]);
2174
+ const handleRowSelectionChange = React10.useCallback(
2175
+ (updater) => {
2176
+ const newSelection = typeof updater === "function" ? updater(rowSelection) : updater;
2177
+ if (isControlledRowSelection && onRowSelectionChange) {
2178
+ onRowSelectionChange(newSelection);
2179
+ } else {
2180
+ setInternalRowSelection(newSelection);
2181
+ }
2182
+ },
2183
+ [isControlledRowSelection, onRowSelectionChange, rowSelection]
2184
+ );
2185
+ const enableSorting = options?.sorting !== false;
2186
+ const enableMultiSort = options?.multiSort !== false;
2187
+ const table = useReactTable({
2188
+ data,
2189
+ columns: tableColumns,
2190
+ enableSorting,
2191
+ enableMultiSort,
2192
+ // Shift+Click for multi-sort (default behavior)
2193
+ isMultiSortEvent: (e) => e.shiftKey,
2194
+ // Max columns for multi-sort (undefined = unlimited)
2195
+ maxMultiSortColCount: options?.maxMultiSortColCount,
2196
+ state: {
2197
+ sorting,
2198
+ columnFilters,
2199
+ rowSelection,
2200
+ globalFilter
2201
+ },
2202
+ onGlobalFilterChange: setGlobalFilter,
2203
+ onSortingChange: (updater) => {
2204
+ const newSorting = typeof updater === "function" ? updater(sorting) : updater;
2205
+ if (isControlledSorting && onSortingChange) {
2206
+ onSortingChange(newSorting);
2207
+ } else {
2208
+ setInternalSorting(newSorting);
2209
+ }
2210
+ },
2211
+ onColumnFiltersChange: setColumnFilters,
2212
+ onRowSelectionChange: handleRowSelectionChange,
2213
+ enableRowSelection,
2214
+ enableMultiRowSelection,
2215
+ getRowId: getRowId ?? ((row, index) => {
2216
+ if (typeof row === "object" && row !== null && "id" in row) {
2217
+ return String(row.id);
2218
+ }
2219
+ return String(index);
2220
+ }),
2221
+ getCoreRowModel: getCoreRowModel(),
2222
+ getPaginationRowModel: options?.pagination ? getPaginationRowModel() : void 0,
2223
+ getSortedRowModel: getSortedRowModel(),
2224
+ getFilteredRowModel: getFilteredRowModel(),
2225
+ getFacetedUniqueValues: getFacetedUniqueValues(),
2226
+ initialState: {
2227
+ pagination: {
2228
+ pageSize: options?.pageSize ?? 10
2229
+ }
2230
+ }
1565
2231
  });
2232
+ React10.useEffect(() => {
2233
+ if (onSelectedRowsChange) {
2234
+ const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
2235
+ onSelectedRowsChange(selectedRows);
2236
+ }
2237
+ }, [rowSelection, onSelectedRowsChange, table]);
2238
+ const visibleColumnCount = tableColumns.length;
2239
+ const showToolbar = options?.showToolbar ?? false;
2240
+ const showGlobalSearch = options?.showGlobalSearch ?? true;
2241
+ const showColumnVisibility = options?.showColumnVisibility ?? true;
2242
+ return /* @__PURE__ */ jsxs11("div", { className: cn("w-full space-y-4", className), children: [
2243
+ showToolbar && /* @__PURE__ */ jsx24(
2244
+ TableToolbar,
2245
+ {
2246
+ table,
2247
+ showFiltering: options?.filtering !== void 0,
2248
+ filteringEnabled: filteringVisible,
2249
+ onFilteringToggle: setFilteringVisible,
2250
+ showGlobalSearch,
2251
+ showColumnVisibility
2252
+ }
2253
+ ),
2254
+ enableRowSelection && Object.keys(rowSelection).length > 0 && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-4 py-2 text-sm bg-[hsl(var(--lux-selection-info-background))] text-[hsl(var(--lux-selection-info-foreground))] rounded-lg border border-[hsl(var(--lux-selection-info-border))]", children: [
2255
+ /* @__PURE__ */ jsx24(CheckCircle2, { className: "w-4 h-4" }),
2256
+ /* @__PURE__ */ jsxs11("span", { children: [
2257
+ /* @__PURE__ */ jsx24("strong", { children: Object.keys(rowSelection).length }),
2258
+ " rows selected",
2259
+ table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ jsxs11("span", { className: "opacity-80", children: [
2260
+ " / ",
2261
+ table.getFilteredRowModel().rows.length,
2262
+ " total"
2263
+ ] })
2264
+ ] }),
2265
+ /* @__PURE__ */ jsx24(
2266
+ "button",
2267
+ {
2268
+ type: "button",
2269
+ onClick: () => handleRowSelectionChange({}),
2270
+ className: "ml-auto text-xs hover:opacity-80 underline underline-offset-2",
2271
+ children: "Clear selection"
2272
+ }
2273
+ )
2274
+ ] }),
2275
+ /* @__PURE__ */ jsx24("div", { className: "rounded-md border border-[hsl(var(--lux-table-border))] bg-[hsl(var(--lux-table-background))] overflow-hidden", children: /* @__PURE__ */ jsxs11(Table, { children: [
2276
+ /* @__PURE__ */ jsxs11(TableHeader, { children: [
2277
+ table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx24(TableRow, { children: headerGroup.headers.map((header) => {
2278
+ const isSelectionColumn = header.id === "__selection__";
2279
+ return /* @__PURE__ */ jsx24(
2280
+ TableHead,
2281
+ {
2282
+ style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
2283
+ children: header.isPlaceholder ? null : isSelectionColumn ? flexRender2(
2284
+ header.column.columnDef.header,
2285
+ header.getContext()
2286
+ ) : /* @__PURE__ */ jsx24(
2287
+ SortableHeader,
2288
+ {
2289
+ header,
2290
+ showSortIndex: enableMultiSort && sorting.length > 1
2291
+ }
2292
+ )
2293
+ },
2294
+ header.id
2295
+ );
2296
+ }) }, headerGroup.id)),
2297
+ filteringVisible && /* @__PURE__ */ jsx24(TableRow, { className: "bg-[hsl(var(--lux-filter-background))]", children: table.getHeaderGroups()[0]?.headers.map((header) => {
2298
+ const isSelectionColumn = header.id === "__selection__";
2299
+ return /* @__PURE__ */ jsx24(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ jsx24(ColumnFilter, { column: header.column, data }) : null }, `filter-${header.id}`);
2300
+ }) })
2301
+ ] }),
2302
+ /* @__PURE__ */ jsx24(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx24(
2303
+ TableRow,
2304
+ {
2305
+ "data-state": row.getIsSelected() && "selected",
2306
+ className: cn(
2307
+ enableRowSelection && "cursor-pointer",
2308
+ row.getIsSelected() && "bg-[hsl(var(--lux-selection-background))]"
2309
+ ),
2310
+ onClick: enableRowSelection && !showCheckbox ? () => {
2311
+ if (selectionMode === "single") {
2312
+ handleRowSelectionChange({ [row.id]: true });
2313
+ } else {
2314
+ row.toggleSelected();
2315
+ }
2316
+ } : void 0,
2317
+ children: row.getVisibleCells().map((cell) => {
2318
+ const isSelectionColumn = cell.column.id === "__selection__";
2319
+ return /* @__PURE__ */ jsx24(
2320
+ TableCell,
2321
+ {
2322
+ style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
2323
+ onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
2324
+ children: flexRender2(cell.column.columnDef.cell, cell.getContext())
2325
+ },
2326
+ cell.id
2327
+ );
2328
+ })
2329
+ },
2330
+ row.id
2331
+ )) : /* @__PURE__ */ jsx24(TableRow, { children: /* @__PURE__ */ jsx24(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
2332
+ ] }) }),
2333
+ options?.pagination && /* @__PURE__ */ jsx24(TablePagination, { table })
2334
+ ] });
1566
2335
  }
1567
2336
 
2337
+ // src/components/ui/label.tsx
2338
+ import * as React11 from "react";
2339
+ import * as LabelPrimitive from "@radix-ui/react-label";
2340
+ import { cva as cva2 } from "class-variance-authority";
2341
+ import { jsx as jsx25 } from "react/jsx-runtime";
2342
+ var labelVariants = cva2(
2343
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
2344
+ );
2345
+ var Label3 = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
2346
+ LabelPrimitive.Root,
2347
+ {
2348
+ ref,
2349
+ className: cn(labelVariants(), className),
2350
+ ...props
2351
+ }
2352
+ ));
2353
+ Label3.displayName = LabelPrimitive.Root.displayName;
2354
+
2355
+ // src/components/ui/separator.tsx
2356
+ import * as React12 from "react";
2357
+ import * as SeparatorPrimitive from "@radix-ui/react-separator";
2358
+ import { jsx as jsx26 } from "react/jsx-runtime";
2359
+ var Separator3 = React12.forwardRef(
2360
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx26(
2361
+ SeparatorPrimitive.Root,
2362
+ {
2363
+ ref,
2364
+ decorative,
2365
+ orientation,
2366
+ className: cn(
2367
+ "shrink-0 bg-border",
2368
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
2369
+ className
2370
+ ),
2371
+ ...props
2372
+ }
2373
+ )
2374
+ );
2375
+ Separator3.displayName = SeparatorPrimitive.Root.displayName;
2376
+
1568
2377
  // src/index.ts
1569
2378
  import {
1570
2379
  flexRender as flexRender3,
@@ -1633,10 +2442,13 @@ export {
1633
2442
  createColumnHelper,
1634
2443
  createColumnsFromData,
1635
2444
  createCopyableCell,
2445
+ defaultGlobalCellConfig,
1636
2446
  defaultStatusColors,
1637
2447
  flexRender3 as flexRender,
1638
2448
  getCoreRowModel2 as getCoreRowModel,
2449
+ getFieldConfig,
1639
2450
  getFilteredRowModel2 as getFilteredRowModel,
1640
2451
  getPaginationRowModel2 as getPaginationRowModel,
1641
- getSortedRowModel2 as getSortedRowModel
2452
+ getSortedRowModel2 as getSortedRowModel,
2453
+ renderCell
1642
2454
  };