luxtable 0.3.4 → 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/EXAMPLE.md +348 -348
- package/README.md +178 -40
- package/USAGE.md +823 -631
- package/dist/index.d.mts +156 -23
- package/dist/index.d.ts +156 -23
- package/dist/index.js +1608 -729
- package/dist/index.mjs +1528 -652
- package/package.json +5 -2
- package/src/styles/README.md +141 -0
- package/src/styles/variables.css +283 -0
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/components/lux-table/lux-table.tsx
|
|
2
|
-
import * as
|
|
2
|
+
import * as React10 from "react";
|
|
3
3
|
import {
|
|
4
|
-
flexRender,
|
|
4
|
+
flexRender as flexRender2,
|
|
5
5
|
getCoreRowModel,
|
|
6
6
|
useReactTable,
|
|
7
7
|
getPaginationRowModel,
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
69
|
-
"hover:bg-
|
|
70
|
-
"data-[state=selected]:bg-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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/
|
|
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
|
-
|
|
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
|
|
270
|
-
const sortedUniqueValues =
|
|
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__ */
|
|
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__ */
|
|
913
|
+
/* @__PURE__ */ jsx10(
|
|
288
914
|
SelectTrigger,
|
|
289
915
|
{
|
|
290
916
|
className: cn(
|
|
291
917
|
"h-8 text-xs",
|
|
292
|
-
"border-
|
|
293
|
-
"bg-
|
|
294
|
-
"text-
|
|
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__ */
|
|
923
|
+
children: /* @__PURE__ */ jsx10(SelectValue, { placeholder: "All" })
|
|
298
924
|
}
|
|
299
925
|
),
|
|
300
|
-
/* @__PURE__ */
|
|
301
|
-
/* @__PURE__ */
|
|
302
|
-
sortedUniqueValues.map((value) => /* @__PURE__ */
|
|
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__ */
|
|
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-
|
|
318
|
-
"bg-
|
|
319
|
-
"text-
|
|
320
|
-
"placeholder:text-
|
|
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
|
|
960
|
+
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
335
961
|
function PaginationButton({ onClick, disabled, title, children }) {
|
|
336
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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-
|
|
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__ */
|
|
399
|
-
/* @__PURE__ */
|
|
400
|
-
/* @__PURE__ */
|
|
401
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1030
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium text-[hsl(var(--lux-table-foreground))]", children: endRow }),
|
|
404
1031
|
" ",
|
|
405
1032
|
"of",
|
|
406
1033
|
" ",
|
|
407
|
-
/* @__PURE__ */
|
|
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__ */
|
|
412
|
-
/* @__PURE__ */
|
|
413
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
433
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1066
|
+
children: /* @__PURE__ */ jsx11(ChevronsLeft, { className: "h-4 w-4" })
|
|
440
1067
|
}
|
|
441
1068
|
),
|
|
442
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1075
|
+
children: /* @__PURE__ */ jsx11(ChevronLeft2, { className: "h-4 w-4" })
|
|
449
1076
|
}
|
|
450
1077
|
),
|
|
451
|
-
/* @__PURE__ */
|
|
1078
|
+
/* @__PURE__ */ jsx11("div", { className: "flex items-center gap-1", children: getPageNumbers().map((page, idx) => {
|
|
452
1079
|
if (page === "...") {
|
|
453
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1099
|
+
children: /* @__PURE__ */ jsx11(ChevronRight2, { className: "h-4 w-4" })
|
|
473
1100
|
}
|
|
474
1101
|
),
|
|
475
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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/
|
|
502
|
-
import
|
|
503
|
-
import
|
|
504
|
-
import {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
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-
|
|
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__ */
|
|
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 =
|
|
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-
|
|
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 =
|
|
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-
|
|
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 =
|
|
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-
|
|
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 =
|
|
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-
|
|
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__ */
|
|
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 =
|
|
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-
|
|
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__ */
|
|
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 =
|
|
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 =
|
|
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-
|
|
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__ */
|
|
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
|
|
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] =
|
|
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 =
|
|
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 =
|
|
1284
|
+
const handleResetVisibility = React8.useCallback(() => {
|
|
709
1285
|
table.resetColumnVisibility();
|
|
710
1286
|
}, [table]);
|
|
711
|
-
const handleShowAllColumns =
|
|
1287
|
+
const handleShowAllColumns = React8.useCallback(() => {
|
|
712
1288
|
hidableColumns.forEach((column) => {
|
|
713
1289
|
column.toggleVisibility(true);
|
|
714
1290
|
});
|
|
715
1291
|
}, [hidableColumns]);
|
|
716
|
-
return /* @__PURE__ */
|
|
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-
|
|
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__ */
|
|
725
|
-
/* @__PURE__ */
|
|
726
|
-
/* @__PURE__ */
|
|
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-
|
|
735
|
-
"bg-
|
|
736
|
-
"placeholder:text-
|
|
737
|
-
"focus:outline-none focus:ring-2 focus:ring-
|
|
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__ */
|
|
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-
|
|
747
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
752
|
-
showFiltering && onFilteringToggle && /* @__PURE__ */
|
|
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__ */
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
] }) : /* @__PURE__ */
|
|
763
|
-
/* @__PURE__ */
|
|
764
|
-
/* @__PURE__ */
|
|
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__ */
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
771
|
-
/* @__PURE__ */
|
|
772
|
-
hiddenColumns.length > 0 && /* @__PURE__ */
|
|
773
|
-
/* @__PURE__ */
|
|
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__ */
|
|
776
|
-
/* @__PURE__ */
|
|
777
|
-
/* @__PURE__ */
|
|
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__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1367
|
+
/* @__PURE__ */ jsx13(Eye, { className: "mr-1 h-3 w-3" }),
|
|
792
1368
|
"Show All"
|
|
793
1369
|
]
|
|
794
1370
|
}
|
|
795
1371
|
),
|
|
796
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1380
|
+
/* @__PURE__ */ jsx13(RotateCcw, { className: "mr-1 h-3 w-3" }),
|
|
805
1381
|
"Reset"
|
|
806
1382
|
]
|
|
807
1383
|
}
|
|
808
1384
|
)
|
|
809
1385
|
] }),
|
|
810
|
-
/* @__PURE__ */
|
|
811
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
821
|
-
column.getIsVisible() ? /* @__PURE__ */
|
|
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__ */
|
|
829
|
-
/* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
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
|
] })
|
|
@@ -840,15 +1416,51 @@ function TableToolbar({
|
|
|
840
1416
|
);
|
|
841
1417
|
}
|
|
842
1418
|
|
|
1419
|
+
// src/components/lux-table/sortable-header.tsx
|
|
1420
|
+
import { flexRender } from "@tanstack/react-table";
|
|
1421
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1422
|
+
function SortableHeader({
|
|
1423
|
+
header,
|
|
1424
|
+
showSortIndex = false
|
|
1425
|
+
}) {
|
|
1426
|
+
const column = header.column;
|
|
1427
|
+
const canSort = column.getCanSort();
|
|
1428
|
+
const isSorted = column.getIsSorted();
|
|
1429
|
+
const sortIndex = column.getSortIndex();
|
|
1430
|
+
const headerContent = header.isPlaceholder ? null : flexRender(column.columnDef.header, header.getContext());
|
|
1431
|
+
if (!canSort) {
|
|
1432
|
+
return /* @__PURE__ */ jsx14(Fragment2, { children: headerContent });
|
|
1433
|
+
}
|
|
1434
|
+
return /* @__PURE__ */ jsxs7(
|
|
1435
|
+
"button",
|
|
1436
|
+
{
|
|
1437
|
+
type: "button",
|
|
1438
|
+
className: cn(
|
|
1439
|
+
"flex items-center gap-1.5 w-full text-left font-medium group",
|
|
1440
|
+
"hover:text-[hsl(var(--lux-table-foreground))]",
|
|
1441
|
+
"transition-all duration-200",
|
|
1442
|
+
"-ml-2 px-2 py-1 rounded-md",
|
|
1443
|
+
"hover:bg-[hsl(var(--lux-table-row-hover))]",
|
|
1444
|
+
isSorted && "text-[hsl(var(--lux-sort-sorted-text))]"
|
|
1445
|
+
),
|
|
1446
|
+
onClick: header.column.getToggleSortingHandler(),
|
|
1447
|
+
children: [
|
|
1448
|
+
headerContent,
|
|
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 })
|
|
1450
|
+
]
|
|
1451
|
+
}
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
843
1455
|
// src/components/ui/checkbox.tsx
|
|
844
1456
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
845
1457
|
import { CheckIcon } from "lucide-react";
|
|
846
|
-
import { jsx as
|
|
1458
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
847
1459
|
function Checkbox({
|
|
848
1460
|
className,
|
|
849
1461
|
...props
|
|
850
1462
|
}) {
|
|
851
|
-
return /* @__PURE__ */
|
|
1463
|
+
return /* @__PURE__ */ jsx15(
|
|
852
1464
|
CheckboxPrimitive.Root,
|
|
853
1465
|
{
|
|
854
1466
|
"data-slot": "checkbox",
|
|
@@ -857,387 +1469,64 @@ function Checkbox({
|
|
|
857
1469
|
className
|
|
858
1470
|
),
|
|
859
1471
|
...props,
|
|
860
|
-
children: /* @__PURE__ */
|
|
1472
|
+
children: /* @__PURE__ */ jsx15(
|
|
861
1473
|
CheckboxPrimitive.Indicator,
|
|
862
1474
|
{
|
|
863
1475
|
"data-slot": "checkbox-indicator",
|
|
864
1476
|
className: "grid place-content-center text-current transition-none",
|
|
865
|
-
children: /* @__PURE__ */
|
|
1477
|
+
children: /* @__PURE__ */ jsx15(CheckIcon, { className: "size-3.5" })
|
|
866
1478
|
}
|
|
867
1479
|
)
|
|
868
1480
|
}
|
|
869
1481
|
);
|
|
870
1482
|
}
|
|
871
1483
|
|
|
872
|
-
// src/components/
|
|
873
|
-
import { jsx as
|
|
874
|
-
function
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
|
|
881
|
-
onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value),
|
|
882
|
-
"aria-label": "Select all rows"
|
|
883
|
-
}
|
|
884
|
-
),
|
|
885
|
-
cell: ({ row }) => /* @__PURE__ */ jsx11(
|
|
886
|
-
Checkbox,
|
|
887
|
-
{
|
|
888
|
-
checked: row.getIsSelected(),
|
|
889
|
-
disabled: !row.getCanSelect(),
|
|
890
|
-
onCheckedChange: (value) => row.toggleSelected(!!value),
|
|
891
|
-
"aria-label": "Select row"
|
|
892
|
-
}
|
|
893
|
-
),
|
|
894
|
-
size: 40,
|
|
895
|
-
enableSorting: false,
|
|
896
|
-
enableHiding: false
|
|
897
|
-
};
|
|
898
|
-
}
|
|
899
|
-
function LuxTable({
|
|
900
|
-
columns,
|
|
901
|
-
data,
|
|
902
|
-
className,
|
|
903
|
-
options,
|
|
904
|
-
sorting: controlledSorting,
|
|
905
|
-
onSortingChange,
|
|
906
|
-
rowSelection: controlledRowSelection,
|
|
907
|
-
onRowSelectionChange,
|
|
908
|
-
onSelectedRowsChange,
|
|
909
|
-
getRowId
|
|
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
|
|
910
1492
|
}) {
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
const [internalRowSelection, setInternalRowSelection] = React7.useState({});
|
|
916
|
-
const isControlledSorting = controlledSorting !== void 0;
|
|
917
|
-
const sorting = isControlledSorting ? controlledSorting : internalSorting;
|
|
918
|
-
const isControlledRowSelection = controlledRowSelection !== void 0;
|
|
919
|
-
const rowSelection = isControlledRowSelection ? controlledRowSelection : internalRowSelection;
|
|
920
|
-
const selectionMode = options?.selection ?? "none";
|
|
921
|
-
const showCheckbox = options?.showSelectionCheckbox ?? selectionMode !== "none";
|
|
922
|
-
const enableRowSelection = selectionMode !== "none";
|
|
923
|
-
const enableMultiRowSelection = selectionMode === "multiple";
|
|
924
|
-
const tableColumns = React7.useMemo(() => {
|
|
925
|
-
if (showCheckbox && enableRowSelection) {
|
|
926
|
-
return [createSelectionColumn(), ...columns];
|
|
927
|
-
}
|
|
928
|
-
return columns;
|
|
929
|
-
}, [columns, showCheckbox, enableRowSelection]);
|
|
930
|
-
const handleRowSelectionChange = React7.useCallback(
|
|
931
|
-
(updater) => {
|
|
932
|
-
const newSelection = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
933
|
-
if (isControlledRowSelection && onRowSelectionChange) {
|
|
934
|
-
onRowSelectionChange(newSelection);
|
|
935
|
-
} else {
|
|
936
|
-
setInternalRowSelection(newSelection);
|
|
937
|
-
}
|
|
938
|
-
},
|
|
939
|
-
[isControlledRowSelection, onRowSelectionChange, rowSelection]
|
|
940
|
-
);
|
|
941
|
-
const table = useReactTable({
|
|
942
|
-
data,
|
|
943
|
-
columns: tableColumns,
|
|
944
|
-
state: {
|
|
945
|
-
sorting,
|
|
946
|
-
columnFilters,
|
|
947
|
-
rowSelection,
|
|
948
|
-
globalFilter
|
|
949
|
-
},
|
|
950
|
-
onGlobalFilterChange: setGlobalFilter,
|
|
951
|
-
onSortingChange: (updater) => {
|
|
952
|
-
const newSorting = typeof updater === "function" ? updater(sorting) : updater;
|
|
953
|
-
if (isControlledSorting && onSortingChange) {
|
|
954
|
-
onSortingChange(newSorting);
|
|
955
|
-
} else {
|
|
956
|
-
setInternalSorting(newSorting);
|
|
957
|
-
}
|
|
958
|
-
},
|
|
959
|
-
onColumnFiltersChange: setColumnFilters,
|
|
960
|
-
onRowSelectionChange: handleRowSelectionChange,
|
|
961
|
-
enableRowSelection,
|
|
962
|
-
enableMultiRowSelection,
|
|
963
|
-
getRowId: getRowId ?? ((row, index) => {
|
|
964
|
-
if (typeof row === "object" && row !== null && "id" in row) {
|
|
965
|
-
return String(row.id);
|
|
966
|
-
}
|
|
967
|
-
return String(index);
|
|
968
|
-
}),
|
|
969
|
-
getCoreRowModel: getCoreRowModel(),
|
|
970
|
-
getPaginationRowModel: options?.pagination ? getPaginationRowModel() : void 0,
|
|
971
|
-
getSortedRowModel: getSortedRowModel(),
|
|
972
|
-
getFilteredRowModel: getFilteredRowModel(),
|
|
973
|
-
getFacetedUniqueValues: getFacetedUniqueValues(),
|
|
974
|
-
initialState: {
|
|
975
|
-
pagination: {
|
|
976
|
-
pageSize: options?.pageSize ?? 10
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
});
|
|
980
|
-
React7.useEffect(() => {
|
|
981
|
-
if (onSelectedRowsChange) {
|
|
982
|
-
const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
|
|
983
|
-
onSelectedRowsChange(selectedRows);
|
|
984
|
-
}
|
|
985
|
-
}, [rowSelection, onSelectedRowsChange, table]);
|
|
986
|
-
const visibleColumnCount = tableColumns.length;
|
|
987
|
-
const showToolbar = options?.showToolbar ?? false;
|
|
988
|
-
const showGlobalSearch = options?.showGlobalSearch ?? true;
|
|
989
|
-
const showColumnVisibility = options?.showColumnVisibility ?? true;
|
|
990
|
-
return /* @__PURE__ */ jsxs6("div", { className: cn("w-full space-y-4", className), children: [
|
|
991
|
-
showToolbar && /* @__PURE__ */ jsx11(
|
|
992
|
-
TableToolbar,
|
|
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",
|
|
993
1497
|
{
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
filteringEnabled: filteringVisible,
|
|
997
|
-
onFilteringToggle: setFilteringVisible,
|
|
998
|
-
showGlobalSearch,
|
|
999
|
-
showColumnVisibility
|
|
1498
|
+
className: `${barColor} h-2.5 rounded-full transition-all`,
|
|
1499
|
+
style: { width: `${clampedValue}%` }
|
|
1000
1500
|
}
|
|
1001
|
-
),
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
" rows selected",
|
|
1007
|
-
table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ jsxs6("span", { className: "text-blue-500 dark:text-blue-400", children: [
|
|
1008
|
-
" / ",
|
|
1009
|
-
table.getFilteredRowModel().rows.length,
|
|
1010
|
-
" total"
|
|
1011
|
-
] })
|
|
1012
|
-
] }),
|
|
1013
|
-
/* @__PURE__ */ jsx11(
|
|
1014
|
-
"button",
|
|
1015
|
-
{
|
|
1016
|
-
type: "button",
|
|
1017
|
-
onClick: () => handleRowSelectionChange({}),
|
|
1018
|
-
className: "ml-auto text-xs hover:text-blue-900 dark:hover:text-blue-100 underline underline-offset-2",
|
|
1019
|
-
children: "Clear selection"
|
|
1020
|
-
}
|
|
1021
|
-
)
|
|
1022
|
-
] }),
|
|
1023
|
-
/* @__PURE__ */ jsx11("div", { className: "rounded-md border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 overflow-hidden", children: /* @__PURE__ */ jsxs6(Table, { children: [
|
|
1024
|
-
/* @__PURE__ */ jsxs6(TableHeader, { children: [
|
|
1025
|
-
table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx11(TableRow, { children: headerGroup.headers.map((header) => {
|
|
1026
|
-
const isSelectionColumn = header.id === "__selection__";
|
|
1027
|
-
return /* @__PURE__ */ jsx11(
|
|
1028
|
-
TableHead,
|
|
1029
|
-
{
|
|
1030
|
-
style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
|
|
1031
|
-
children: header.isPlaceholder ? null : flexRender(
|
|
1032
|
-
header.column.columnDef.header,
|
|
1033
|
-
header.getContext()
|
|
1034
|
-
)
|
|
1035
|
-
},
|
|
1036
|
-
header.id
|
|
1037
|
-
);
|
|
1038
|
-
}) }, headerGroup.id)),
|
|
1039
|
-
filteringVisible && /* @__PURE__ */ jsx11(TableRow, { className: "bg-slate-50/50 dark:bg-slate-900/50", children: table.getHeaderGroups()[0]?.headers.map((header) => {
|
|
1040
|
-
const isSelectionColumn = header.id === "__selection__";
|
|
1041
|
-
return /* @__PURE__ */ jsx11(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ jsx11(ColumnFilter, { column: header.column }) : null }, `filter-${header.id}`);
|
|
1042
|
-
}) })
|
|
1043
|
-
] }),
|
|
1044
|
-
/* @__PURE__ */ jsx11(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx11(
|
|
1045
|
-
TableRow,
|
|
1046
|
-
{
|
|
1047
|
-
"data-state": row.getIsSelected() && "selected",
|
|
1048
|
-
className: cn(
|
|
1049
|
-
enableRowSelection && "cursor-pointer",
|
|
1050
|
-
row.getIsSelected() && "bg-blue-50/50 dark:bg-blue-950/30"
|
|
1051
|
-
),
|
|
1052
|
-
onClick: enableRowSelection && !showCheckbox ? () => {
|
|
1053
|
-
if (selectionMode === "single") {
|
|
1054
|
-
handleRowSelectionChange({ [row.id]: true });
|
|
1055
|
-
} else {
|
|
1056
|
-
row.toggleSelected();
|
|
1057
|
-
}
|
|
1058
|
-
} : void 0,
|
|
1059
|
-
children: row.getVisibleCells().map((cell) => {
|
|
1060
|
-
const isSelectionColumn = cell.column.id === "__selection__";
|
|
1061
|
-
return /* @__PURE__ */ jsx11(
|
|
1062
|
-
TableCell,
|
|
1063
|
-
{
|
|
1064
|
-
style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
|
|
1065
|
-
onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
|
|
1066
|
-
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
1067
|
-
},
|
|
1068
|
-
cell.id
|
|
1069
|
-
);
|
|
1070
|
-
})
|
|
1071
|
-
},
|
|
1072
|
-
row.id
|
|
1073
|
-
)) : /* @__PURE__ */ jsx11(TableRow, { children: /* @__PURE__ */ jsx11(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
|
|
1074
|
-
] }) }),
|
|
1075
|
-
options?.pagination && /* @__PURE__ */ jsx11(TablePagination, { table })
|
|
1501
|
+
) }),
|
|
1502
|
+
showLabel && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-[hsl(var(--lux-progress-text))] w-8", children: [
|
|
1503
|
+
value,
|
|
1504
|
+
"%"
|
|
1505
|
+
] })
|
|
1076
1506
|
] });
|
|
1077
1507
|
}
|
|
1078
1508
|
|
|
1079
|
-
// src/components/
|
|
1080
|
-
import {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
} from "lucide-react";
|
|
1088
|
-
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1089
|
-
function LuxDataTableColumnHeader({
|
|
1090
|
-
column,
|
|
1091
|
-
title,
|
|
1092
|
-
className
|
|
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))]"
|
|
1093
1517
|
}) {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
size: "sm",
|
|
1104
|
-
className: "-ml-3 h-8 hover:bg-accent",
|
|
1105
|
-
onClick: () => column.toggleSorting(isSorted === "asc"),
|
|
1106
|
-
children: [
|
|
1107
|
-
/* @__PURE__ */ jsx12("span", { children: title }),
|
|
1108
|
-
isSorted === "desc" ? /* @__PURE__ */ jsx12(ArrowDown, { className: "ml-1.5 h-4 w-4 text-primary" }) : isSorted === "asc" ? /* @__PURE__ */ jsx12(ArrowUp, { className: "ml-1.5 h-4 w-4 text-primary" }) : /* @__PURE__ */ jsx12(ChevronsUpDown2, { className: "ml-1.5 h-4 w-4 text-muted-foreground/50" })
|
|
1109
|
-
]
|
|
1110
|
-
}
|
|
1111
|
-
),
|
|
1112
|
-
/* @__PURE__ */ jsxs7(DropdownMenu, { children: [
|
|
1113
|
-
/* @__PURE__ */ jsx12(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs7(
|
|
1114
|
-
Button,
|
|
1115
|
-
{
|
|
1116
|
-
variant: "ghost",
|
|
1117
|
-
size: "icon",
|
|
1118
|
-
className: "h-6 w-6 opacity-0 group-hover:opacity-100 hover:opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
|
|
1119
|
-
children: [
|
|
1120
|
-
/* @__PURE__ */ jsx12(MoreVertical, { className: "h-3.5 w-3.5" }),
|
|
1121
|
-
/* @__PURE__ */ jsx12("span", { className: "sr-only", children: "Column actions" })
|
|
1122
|
-
]
|
|
1123
|
-
}
|
|
1124
|
-
) }),
|
|
1125
|
-
/* @__PURE__ */ jsxs7(DropdownMenuContent, { align: "end", children: [
|
|
1126
|
-
/* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.toggleSorting(false), children: [
|
|
1127
|
-
/* @__PURE__ */ jsx12(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1128
|
-
"Sort Ascending"
|
|
1129
|
-
] }),
|
|
1130
|
-
/* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.toggleSorting(true), children: [
|
|
1131
|
-
/* @__PURE__ */ jsx12(ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1132
|
-
"Sort Descending"
|
|
1133
|
-
] }),
|
|
1134
|
-
isSorted && /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1135
|
-
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1136
|
-
/* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.clearSorting(), children: [
|
|
1137
|
-
/* @__PURE__ */ jsx12(X, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1138
|
-
"Clear sorting"
|
|
1139
|
-
] })
|
|
1140
|
-
] }),
|
|
1141
|
-
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1142
|
-
/* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.toggleVisibility(false), children: [
|
|
1143
|
-
/* @__PURE__ */ jsx12(EyeOff2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1144
|
-
"Hide column"
|
|
1145
|
-
] })
|
|
1146
|
-
] })
|
|
1147
|
-
] })
|
|
1148
|
-
] });
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
// src/components/cell-renderers/status-cell.tsx
|
|
1152
|
-
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1153
|
-
var defaultStatusColors = {
|
|
1154
|
-
Active: {
|
|
1155
|
-
bg: "bg-green-100",
|
|
1156
|
-
text: "text-green-800",
|
|
1157
|
-
darkBg: "dark:bg-green-900",
|
|
1158
|
-
darkText: "dark:text-green-300"
|
|
1159
|
-
},
|
|
1160
|
-
Inactive: {
|
|
1161
|
-
bg: "bg-red-100",
|
|
1162
|
-
text: "text-red-800",
|
|
1163
|
-
darkBg: "dark:bg-red-900",
|
|
1164
|
-
darkText: "dark:text-red-300"
|
|
1165
|
-
},
|
|
1166
|
-
Pending: {
|
|
1167
|
-
bg: "bg-yellow-100",
|
|
1168
|
-
text: "text-yellow-800",
|
|
1169
|
-
darkBg: "dark:bg-yellow-900",
|
|
1170
|
-
darkText: "dark:text-yellow-300"
|
|
1171
|
-
},
|
|
1172
|
-
Completed: {
|
|
1173
|
-
bg: "bg-blue-100",
|
|
1174
|
-
text: "text-blue-800",
|
|
1175
|
-
darkBg: "dark:bg-blue-900",
|
|
1176
|
-
darkText: "dark:text-blue-300"
|
|
1177
|
-
},
|
|
1178
|
-
Cancelled: {
|
|
1179
|
-
bg: "bg-gray-100",
|
|
1180
|
-
text: "text-gray-800",
|
|
1181
|
-
darkBg: "dark:bg-gray-900",
|
|
1182
|
-
darkText: "dark:text-gray-300"
|
|
1183
|
-
}
|
|
1184
|
-
};
|
|
1185
|
-
function StatusCell({ value, colors, className }) {
|
|
1186
|
-
const mergedColors = { ...defaultStatusColors, ...colors };
|
|
1187
|
-
const colorConfig = mergedColors[value];
|
|
1188
|
-
if (!colorConfig) {
|
|
1189
|
-
return /* @__PURE__ */ jsx13("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 });
|
|
1190
|
-
}
|
|
1191
|
-
const { bg, text, darkBg, darkText } = colorConfig;
|
|
1192
|
-
return /* @__PURE__ */ jsx13("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${darkBg || ""} ${darkText || ""} ${className || ""}`, children: value });
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
// src/components/cell-renderers/progress-cell.tsx
|
|
1196
|
-
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1197
|
-
function ProgressCell({
|
|
1198
|
-
value,
|
|
1199
|
-
barColor = "bg-blue-600",
|
|
1200
|
-
bgColor = "bg-gray-200 dark:bg-gray-700",
|
|
1201
|
-
showLabel = false,
|
|
1202
|
-
className
|
|
1203
|
-
}) {
|
|
1204
|
-
const clampedValue = Math.min(100, Math.max(0, value));
|
|
1205
|
-
return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
|
|
1206
|
-
/* @__PURE__ */ jsx14("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx14(
|
|
1207
|
-
"div",
|
|
1208
|
-
{
|
|
1209
|
-
className: `${barColor} h-2.5 rounded-full transition-all`,
|
|
1210
|
-
style: { width: `${clampedValue}%` }
|
|
1211
|
-
}
|
|
1212
|
-
) }),
|
|
1213
|
-
showLabel && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-gray-500 dark:text-gray-400 w-8", children: [
|
|
1214
|
-
value,
|
|
1215
|
-
"%"
|
|
1216
|
-
] })
|
|
1217
|
-
] });
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1220
|
-
// src/components/cell-renderers/boolean-cell.tsx
|
|
1221
|
-
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1222
|
-
function BooleanCell({
|
|
1223
|
-
value,
|
|
1224
|
-
trueLabel = "Yes",
|
|
1225
|
-
falseLabel = "No",
|
|
1226
|
-
trueColor = "text-green-600 dark:text-green-400",
|
|
1227
|
-
falseColor = "text-red-600 dark:text-red-400"
|
|
1228
|
-
}) {
|
|
1229
|
-
return /* @__PURE__ */ jsx15("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
// src/components/cell-renderers/date-cell.tsx
|
|
1233
|
-
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1234
|
-
function DateCell({ value, format = "short", locale = "en-US" }) {
|
|
1235
|
-
const date = typeof value === "string" ? new Date(value) : value;
|
|
1236
|
-
if (isNaN(date.getTime())) {
|
|
1237
|
-
return /* @__PURE__ */ jsx16("span", { className: "text-gray-400", children: "-" });
|
|
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: "-" });
|
|
1238
1527
|
}
|
|
1239
1528
|
let formatted;
|
|
1240
|
-
switch (
|
|
1529
|
+
switch (format2) {
|
|
1241
1530
|
case "long":
|
|
1242
1531
|
formatted = date.toLocaleDateString(locale, {
|
|
1243
1532
|
year: "numeric",
|
|
@@ -1258,23 +1547,23 @@ function DateCell({ value, format = "short", locale = "en-US" }) {
|
|
|
1258
1547
|
default:
|
|
1259
1548
|
formatted = date.toLocaleDateString(locale);
|
|
1260
1549
|
}
|
|
1261
|
-
return /* @__PURE__ */
|
|
1550
|
+
return /* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: formatted });
|
|
1262
1551
|
}
|
|
1263
1552
|
|
|
1264
1553
|
// src/components/cell-renderers/currency-cell.tsx
|
|
1265
|
-
import { jsx as
|
|
1554
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1266
1555
|
function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
|
|
1267
1556
|
const formatted = new Intl.NumberFormat(locale, {
|
|
1268
1557
|
style: "currency",
|
|
1269
1558
|
currency
|
|
1270
1559
|
}).format(value);
|
|
1271
|
-
return /* @__PURE__ */
|
|
1560
|
+
return /* @__PURE__ */ jsx19("span", { className: "font-medium text-[hsl(var(--lux-table-cell-foreground))]", children: formatted });
|
|
1272
1561
|
}
|
|
1273
1562
|
|
|
1274
1563
|
// src/components/cell-renderers/copyable-cell.tsx
|
|
1275
|
-
import * as
|
|
1564
|
+
import * as React9 from "react";
|
|
1276
1565
|
import { Copy, Check as Check3 } from "lucide-react";
|
|
1277
|
-
import { jsx as
|
|
1566
|
+
import { jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1278
1567
|
function CopyableCell({
|
|
1279
1568
|
value,
|
|
1280
1569
|
feedbackDuration = 2e3,
|
|
@@ -1283,8 +1572,8 @@ function CopyableCell({
|
|
|
1283
1572
|
tooltip = "Click to copy",
|
|
1284
1573
|
alwaysShowIcon = false
|
|
1285
1574
|
}) {
|
|
1286
|
-
const [copied, setCopied] =
|
|
1287
|
-
const [isHovered, setIsHovered] =
|
|
1575
|
+
const [copied, setCopied] = React9.useState(false);
|
|
1576
|
+
const [isHovered, setIsHovered] = React9.useState(false);
|
|
1288
1577
|
const handleCopy = async (e) => {
|
|
1289
1578
|
e.stopPropagation();
|
|
1290
1579
|
const textToCopy = String(value);
|
|
@@ -1318,8 +1607,8 @@ function CopyableCell({
|
|
|
1318
1607
|
${className || ""}
|
|
1319
1608
|
`,
|
|
1320
1609
|
children: [
|
|
1321
|
-
/* @__PURE__ */
|
|
1322
|
-
/* @__PURE__ */
|
|
1610
|
+
/* @__PURE__ */ jsx20("span", { className: "select-none text-[hsl(var(--lux-table-cell-foreground))]", children: value }),
|
|
1611
|
+
/* @__PURE__ */ jsx20(
|
|
1323
1612
|
"span",
|
|
1324
1613
|
{
|
|
1325
1614
|
className: `
|
|
@@ -1327,7 +1616,7 @@ function CopyableCell({
|
|
|
1327
1616
|
transition-all duration-200
|
|
1328
1617
|
${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
|
|
1329
1618
|
`,
|
|
1330
|
-
children: copied ? /* @__PURE__ */
|
|
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" })
|
|
1331
1620
|
}
|
|
1332
1621
|
)
|
|
1333
1622
|
]
|
|
@@ -1335,74 +1624,281 @@ function CopyableCell({
|
|
|
1335
1624
|
);
|
|
1336
1625
|
}
|
|
1337
1626
|
function createCopyableCell(value, options) {
|
|
1338
|
-
return /* @__PURE__ */
|
|
1627
|
+
return /* @__PURE__ */ jsx20(CopyableCell, { value, ...options });
|
|
1339
1628
|
}
|
|
1340
1629
|
|
|
1341
|
-
// src/
|
|
1342
|
-
import
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
"
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
...
|
|
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";
|
|
1355
1650
|
}
|
|
1356
|
-
))
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
// src/components/ui/popover.tsx
|
|
1360
|
-
import * as React10 from "react";
|
|
1361
|
-
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
1362
|
-
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1363
|
-
var Popover = PopoverPrimitive.Root;
|
|
1364
|
-
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
1365
|
-
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
1366
|
-
var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx20(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx20(
|
|
1367
|
-
PopoverPrimitive.Content,
|
|
1368
|
-
{
|
|
1369
|
-
ref,
|
|
1370
|
-
align,
|
|
1371
|
-
sideOffset,
|
|
1372
|
-
className: cn(
|
|
1373
|
-
"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",
|
|
1374
|
-
className
|
|
1375
|
-
),
|
|
1376
|
-
...props
|
|
1651
|
+
if (mergedPatterns.date.some((pattern) => name.includes(pattern.toLowerCase()))) {
|
|
1652
|
+
return "date";
|
|
1377
1653
|
}
|
|
1378
|
-
)
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
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";
|
|
1398
1674
|
}
|
|
1399
|
-
|
|
1400
|
-
)
|
|
1401
|
-
|
|
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";
|
|
1687
|
+
}
|
|
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,
|
|
1755
|
+
{
|
|
1756
|
+
value: Number(value),
|
|
1757
|
+
barColor: fieldConfig.barColor,
|
|
1758
|
+
showLabel: fieldConfig.showLabel ?? false
|
|
1759
|
+
}
|
|
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) });
|
|
1809
|
+
}
|
|
1402
1810
|
|
|
1403
1811
|
// src/lib/column-helper.tsx
|
|
1404
1812
|
import { createColumnHelper as tanstackCreateColumnHelper } from "@tanstack/react-table";
|
|
1405
|
-
|
|
1813
|
+
|
|
1814
|
+
// src/components/lux-table/column-header.tsx
|
|
1815
|
+
import {
|
|
1816
|
+
ArrowDown,
|
|
1817
|
+
ArrowUp,
|
|
1818
|
+
ArrowUpDown,
|
|
1819
|
+
EyeOff as EyeOff2,
|
|
1820
|
+
MoreVertical,
|
|
1821
|
+
X as X2
|
|
1822
|
+
} from "lucide-react";
|
|
1823
|
+
import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1824
|
+
function LuxDataTableColumnHeader({
|
|
1825
|
+
column,
|
|
1826
|
+
title,
|
|
1827
|
+
className
|
|
1828
|
+
}) {
|
|
1829
|
+
const isSorted = column.getIsSorted();
|
|
1830
|
+
const canSort = column.getCanSort();
|
|
1831
|
+
const SortIndicator = () => {
|
|
1832
|
+
if (isSorted === "desc") {
|
|
1833
|
+
return /* @__PURE__ */ jsx22(ArrowDown, { className: "h-4 w-4 text-[hsl(var(--lux-sort-active))]" });
|
|
1834
|
+
}
|
|
1835
|
+
if (isSorted === "asc") {
|
|
1836
|
+
return /* @__PURE__ */ jsx22(ArrowUp, { className: "h-4 w-4 text-[hsl(var(--lux-sort-active))]" });
|
|
1837
|
+
}
|
|
1838
|
+
if (canSort) {
|
|
1839
|
+
return /* @__PURE__ */ jsx22(ArrowUpDown, { className: "h-4 w-4 text-[hsl(var(--lux-sort-idle))]" });
|
|
1840
|
+
}
|
|
1841
|
+
return null;
|
|
1842
|
+
};
|
|
1843
|
+
if (!canSort) {
|
|
1844
|
+
return /* @__PURE__ */ jsx22("span", { className: cn("text-sm font-medium", className), children: title });
|
|
1845
|
+
}
|
|
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(
|
|
1851
|
+
Button,
|
|
1852
|
+
{
|
|
1853
|
+
variant: "ghost",
|
|
1854
|
+
size: "icon",
|
|
1855
|
+
className: "h-6 w-6 ml-auto opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
|
|
1856
|
+
children: [
|
|
1857
|
+
/* @__PURE__ */ jsx22(MoreVertical, { className: "h-3.5 w-3.5" }),
|
|
1858
|
+
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Column actions" })
|
|
1859
|
+
]
|
|
1860
|
+
}
|
|
1861
|
+
) }),
|
|
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) => {
|
|
1864
|
+
e.stopPropagation();
|
|
1865
|
+
column.toggleSorting(false);
|
|
1866
|
+
}, children: [
|
|
1867
|
+
/* @__PURE__ */ jsx22(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1868
|
+
"Sort Ascending"
|
|
1869
|
+
] }),
|
|
1870
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
|
|
1871
|
+
e.stopPropagation();
|
|
1872
|
+
column.toggleSorting(true);
|
|
1873
|
+
}, children: [
|
|
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
|
+
}
|
|
1899
|
+
|
|
1900
|
+
// src/lib/column-helper.tsx
|
|
1901
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1406
1902
|
var toTitleCase = (str) => {
|
|
1407
1903
|
return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
1408
1904
|
};
|
|
@@ -1418,24 +1914,21 @@ function createColumnHelper() {
|
|
|
1418
1914
|
...column,
|
|
1419
1915
|
// enableSorting is true by default
|
|
1420
1916
|
enableSorting: column?.enableSorting !== false,
|
|
1917
|
+
// Pass size if provided
|
|
1918
|
+
size: column?.size,
|
|
1421
1919
|
// Pass meta information (filterVariant etc.)
|
|
1422
1920
|
meta: column?.meta,
|
|
1423
1921
|
// Use LuxDataTableColumnHeader if header is string or undefined
|
|
1424
|
-
header: typeof headerContent === "function" ? headerContent : ({ column: colParam }) => /* @__PURE__ */
|
|
1922
|
+
header: typeof headerContent === "function" ? headerContent : ({ column: colParam }) => /* @__PURE__ */ jsx23(
|
|
1425
1923
|
LuxDataTableColumnHeader,
|
|
1426
1924
|
{
|
|
1427
1925
|
column: colParam,
|
|
1428
1926
|
title: typeof headerContent === "string" ? headerContent : toTitleCase(accessor)
|
|
1429
1927
|
}
|
|
1430
1928
|
),
|
|
1431
|
-
//
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
if (value === null || value === void 0) {
|
|
1435
|
-
return "-";
|
|
1436
|
-
}
|
|
1437
|
-
return String(value);
|
|
1438
|
-
})
|
|
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 } : {}
|
|
1439
1932
|
};
|
|
1440
1933
|
return helper.accessor(accessor, finalColumn);
|
|
1441
1934
|
},
|
|
@@ -1465,7 +1958,7 @@ function createColumnHelper() {
|
|
|
1465
1958
|
auto: (columns) => {
|
|
1466
1959
|
return columns.map((col) => {
|
|
1467
1960
|
return helper.accessor(col.accessor, {
|
|
1468
|
-
header: ({ column }) => /* @__PURE__ */
|
|
1961
|
+
header: ({ column }) => /* @__PURE__ */ jsx23(LuxDataTableColumnHeader, { column, title: col.header }),
|
|
1469
1962
|
cell: col.cell || ((info) => {
|
|
1470
1963
|
const value = info.getValue();
|
|
1471
1964
|
if (value === null || value === void 0) return "-";
|
|
@@ -1491,19 +1984,399 @@ function createColumnsFromData(data, options) {
|
|
|
1491
1984
|
const headerText = options?.headers?.[key] || toTitleCase(key);
|
|
1492
1985
|
const cellRenderer = options?.cells?.[key];
|
|
1493
1986
|
return helper.accessor(key, {
|
|
1494
|
-
header: ({ column }) => /* @__PURE__ */
|
|
1495
|
-
cell
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1987
|
+
header: ({ column }) => /* @__PURE__ */ jsx23(LuxDataTableColumnHeader, { column, title: headerText }),
|
|
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
|
+
};
|
|
1500
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
|
+
}
|
|
1501
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
|
+
] });
|
|
1502
2335
|
}
|
|
1503
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
|
+
|
|
1504
2377
|
// src/index.ts
|
|
1505
2378
|
import {
|
|
1506
|
-
flexRender as
|
|
2379
|
+
flexRender as flexRender3,
|
|
1507
2380
|
getCoreRowModel as getCoreRowModel2,
|
|
1508
2381
|
getPaginationRowModel as getPaginationRowModel2,
|
|
1509
2382
|
getSortedRowModel as getSortedRowModel2,
|
|
@@ -1569,10 +2442,13 @@ export {
|
|
|
1569
2442
|
createColumnHelper,
|
|
1570
2443
|
createColumnsFromData,
|
|
1571
2444
|
createCopyableCell,
|
|
2445
|
+
defaultGlobalCellConfig,
|
|
1572
2446
|
defaultStatusColors,
|
|
1573
|
-
|
|
2447
|
+
flexRender3 as flexRender,
|
|
1574
2448
|
getCoreRowModel2 as getCoreRowModel,
|
|
2449
|
+
getFieldConfig,
|
|
1575
2450
|
getFilteredRowModel2 as getFilteredRowModel,
|
|
1576
2451
|
getPaginationRowModel2 as getPaginationRowModel,
|
|
1577
|
-
getSortedRowModel2 as getSortedRowModel
|
|
2452
|
+
getSortedRowModel2 as getSortedRowModel,
|
|
2453
|
+
renderCell
|
|
1578
2454
|
};
|