luxtable 0.3.5 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EXAMPLE.md +348 -348
- package/README.md +179 -41
- package/USAGE.md +823 -631
- package/dist/index.d.mts +149 -23
- package/dist/index.d.ts +149 -23
- package/dist/index.js +1557 -742
- package/dist/index.mjs +1540 -728
- package/package.json +4 -1
- package/src/styles/README.md +141 -0
- package/src/styles/variables.css +283 -0
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/lux-table/lux-table.tsx
|
|
2
|
-
import * as
|
|
2
|
+
import * as React10 from "react";
|
|
3
3
|
import {
|
|
4
4
|
flexRender as flexRender2,
|
|
5
5
|
getCoreRowModel,
|
|
@@ -34,7 +34,7 @@ var TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
34
34
|
"thead",
|
|
35
35
|
{
|
|
36
36
|
ref,
|
|
37
|
-
className: cn("[&_tr]:border-b [&_tr]:border-
|
|
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
|
] })
|
|
@@ -842,7 +1418,7 @@ function TableToolbar({
|
|
|
842
1418
|
|
|
843
1419
|
// src/components/lux-table/sortable-header.tsx
|
|
844
1420
|
import { flexRender } from "@tanstack/react-table";
|
|
845
|
-
import { Fragment as Fragment2, jsx as
|
|
1421
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
846
1422
|
function SortableHeader({
|
|
847
1423
|
header,
|
|
848
1424
|
showSortIndex = false
|
|
@@ -853,24 +1429,24 @@ function SortableHeader({
|
|
|
853
1429
|
const sortIndex = column.getSortIndex();
|
|
854
1430
|
const headerContent = header.isPlaceholder ? null : flexRender(column.columnDef.header, header.getContext());
|
|
855
1431
|
if (!canSort) {
|
|
856
|
-
return /* @__PURE__ */
|
|
1432
|
+
return /* @__PURE__ */ jsx14(Fragment2, { children: headerContent });
|
|
857
1433
|
}
|
|
858
|
-
return /* @__PURE__ */
|
|
1434
|
+
return /* @__PURE__ */ jsxs7(
|
|
859
1435
|
"button",
|
|
860
1436
|
{
|
|
861
1437
|
type: "button",
|
|
862
1438
|
className: cn(
|
|
863
1439
|
"flex items-center gap-1.5 w-full text-left font-medium group",
|
|
864
|
-
"hover:text-
|
|
865
|
-
"transition-
|
|
1440
|
+
"hover:text-[hsl(var(--lux-table-foreground))]",
|
|
1441
|
+
"transition-all duration-200",
|
|
866
1442
|
"-ml-2 px-2 py-1 rounded-md",
|
|
867
|
-
"hover:bg-
|
|
868
|
-
isSorted && "text-
|
|
1443
|
+
"hover:bg-[hsl(var(--lux-table-row-hover))]",
|
|
1444
|
+
isSorted && "text-[hsl(var(--lux-sort-sorted-text))]"
|
|
869
1445
|
),
|
|
870
1446
|
onClick: header.column.getToggleSortingHandler(),
|
|
871
1447
|
children: [
|
|
872
1448
|
headerContent,
|
|
873
|
-
showSortIndex && isSorted && sortIndex > 0 && /* @__PURE__ */
|
|
1449
|
+
showSortIndex && isSorted && sortIndex > 0 && /* @__PURE__ */ jsx14("span", { className: "ml-0.5 text-[10px] font-bold text-[hsl(var(--lux-sort-sorted-text))] bg-[hsl(var(--lux-sort-sorted-text))]/10 rounded-full w-4 h-4 flex items-center justify-center ring-1 ring-[hsl(var(--lux-sort-sorted-text))]/20", children: sortIndex + 1 })
|
|
874
1450
|
]
|
|
875
1451
|
}
|
|
876
1452
|
);
|
|
@@ -879,12 +1455,12 @@ function SortableHeader({
|
|
|
879
1455
|
// src/components/ui/checkbox.tsx
|
|
880
1456
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
881
1457
|
import { CheckIcon } from "lucide-react";
|
|
882
|
-
import { jsx as
|
|
1458
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
883
1459
|
function Checkbox({
|
|
884
1460
|
className,
|
|
885
1461
|
...props
|
|
886
1462
|
}) {
|
|
887
|
-
return /* @__PURE__ */
|
|
1463
|
+
return /* @__PURE__ */ jsx15(
|
|
888
1464
|
CheckboxPrimitive.Root,
|
|
889
1465
|
{
|
|
890
1466
|
"data-slot": "checkbox",
|
|
@@ -893,239 +1469,348 @@ function Checkbox({
|
|
|
893
1469
|
className
|
|
894
1470
|
),
|
|
895
1471
|
...props,
|
|
896
|
-
children: /* @__PURE__ */
|
|
1472
|
+
children: /* @__PURE__ */ jsx15(
|
|
897
1473
|
CheckboxPrimitive.Indicator,
|
|
898
1474
|
{
|
|
899
1475
|
"data-slot": "checkbox-indicator",
|
|
900
1476
|
className: "grid place-content-center text-current transition-none",
|
|
901
|
-
children: /* @__PURE__ */
|
|
1477
|
+
children: /* @__PURE__ */ jsx15(CheckIcon, { className: "size-3.5" })
|
|
902
1478
|
}
|
|
903
1479
|
)
|
|
904
1480
|
}
|
|
905
1481
|
);
|
|
906
1482
|
}
|
|
907
1483
|
|
|
908
|
-
// src/components/
|
|
909
|
-
import { jsx as
|
|
910
|
-
function
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
cell: ({ row }) => /* @__PURE__ */ jsx12(
|
|
922
|
-
Checkbox,
|
|
1484
|
+
// src/components/cell-renderers/progress-cell.tsx
|
|
1485
|
+
import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1486
|
+
function ProgressCell({
|
|
1487
|
+
value,
|
|
1488
|
+
barColor = "bg-[hsl(var(--lux-progress-bar))]",
|
|
1489
|
+
bgColor = "bg-[hsl(var(--lux-progress-bg))]",
|
|
1490
|
+
showLabel = false,
|
|
1491
|
+
className
|
|
1492
|
+
}) {
|
|
1493
|
+
const clampedValue = Math.min(100, Math.max(0, value));
|
|
1494
|
+
return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
|
|
1495
|
+
/* @__PURE__ */ jsx16("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx16(
|
|
1496
|
+
"div",
|
|
923
1497
|
{
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
onCheckedChange: (value) => row.toggleSelected(!!value),
|
|
927
|
-
"aria-label": "Select row"
|
|
1498
|
+
className: `${barColor} h-2.5 rounded-full transition-all`,
|
|
1499
|
+
style: { width: `${clampedValue}%` }
|
|
928
1500
|
}
|
|
929
|
-
),
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1501
|
+
) }),
|
|
1502
|
+
showLabel && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-[hsl(var(--lux-progress-text))] w-8", children: [
|
|
1503
|
+
value,
|
|
1504
|
+
"%"
|
|
1505
|
+
] })
|
|
1506
|
+
] });
|
|
934
1507
|
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1508
|
+
|
|
1509
|
+
// src/components/cell-renderers/boolean-cell.tsx
|
|
1510
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1511
|
+
function BooleanCell({
|
|
1512
|
+
value,
|
|
1513
|
+
trueLabel = "Yes",
|
|
1514
|
+
falseLabel = "No",
|
|
1515
|
+
trueColor = "text-[hsl(var(--lux-boolean-true))]",
|
|
1516
|
+
falseColor = "text-[hsl(var(--lux-boolean-false))]"
|
|
1517
|
+
}) {
|
|
1518
|
+
return /* @__PURE__ */ jsx17("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
// src/components/cell-renderers/date-cell.tsx
|
|
1522
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1523
|
+
function DateCell({ value, format: format2 = "short", locale = "en-US" }) {
|
|
1524
|
+
const date = typeof value === "string" ? new Date(value) : value;
|
|
1525
|
+
if (isNaN(date.getTime())) {
|
|
1526
|
+
return /* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--lux-table-cell-muted))]", children: "-" });
|
|
1527
|
+
}
|
|
1528
|
+
let formatted;
|
|
1529
|
+
switch (format2) {
|
|
1530
|
+
case "long":
|
|
1531
|
+
formatted = date.toLocaleDateString(locale, {
|
|
1532
|
+
year: "numeric",
|
|
1533
|
+
month: "long",
|
|
1534
|
+
day: "numeric"
|
|
1535
|
+
});
|
|
1536
|
+
break;
|
|
1537
|
+
case "relative": {
|
|
1538
|
+
const now = /* @__PURE__ */ new Date();
|
|
1539
|
+
const diffMs = now.getTime() - date.getTime();
|
|
1540
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
1541
|
+
if (diffDays === 0) formatted = "Today";
|
|
1542
|
+
else if (diffDays === 1) formatted = "Yesterday";
|
|
1543
|
+
else if (diffDays < 7) formatted = `${diffDays} days ago`;
|
|
1544
|
+
else formatted = date.toLocaleDateString(locale);
|
|
1545
|
+
break;
|
|
1546
|
+
}
|
|
1547
|
+
default:
|
|
1548
|
+
formatted = date.toLocaleDateString(locale);
|
|
1549
|
+
}
|
|
1550
|
+
return /* @__PURE__ */ jsx18("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: formatted });
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
// src/components/cell-renderers/currency-cell.tsx
|
|
1554
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1555
|
+
function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
|
|
1556
|
+
const formatted = new Intl.NumberFormat(locale, {
|
|
1557
|
+
style: "currency",
|
|
1558
|
+
currency
|
|
1559
|
+
}).format(value);
|
|
1560
|
+
return /* @__PURE__ */ jsx19("span", { className: "font-medium text-[hsl(var(--lux-table-cell-foreground))]", children: formatted });
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// src/components/cell-renderers/copyable-cell.tsx
|
|
1564
|
+
import * as React9 from "react";
|
|
1565
|
+
import { Copy, Check as Check3 } from "lucide-react";
|
|
1566
|
+
import { jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1567
|
+
function CopyableCell({
|
|
1568
|
+
value,
|
|
1569
|
+
feedbackDuration = 2e3,
|
|
1570
|
+
onCopy,
|
|
938
1571
|
className,
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
onSortingChange,
|
|
942
|
-
rowSelection: controlledRowSelection,
|
|
943
|
-
onRowSelectionChange,
|
|
944
|
-
onSelectedRowsChange,
|
|
945
|
-
getRowId
|
|
1572
|
+
tooltip = "Click to copy",
|
|
1573
|
+
alwaysShowIcon = false
|
|
946
1574
|
}) {
|
|
947
|
-
const [
|
|
948
|
-
const [
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1575
|
+
const [copied, setCopied] = React9.useState(false);
|
|
1576
|
+
const [isHovered, setIsHovered] = React9.useState(false);
|
|
1577
|
+
const handleCopy = async (e) => {
|
|
1578
|
+
e.stopPropagation();
|
|
1579
|
+
const textToCopy = String(value);
|
|
1580
|
+
try {
|
|
1581
|
+
await navigator.clipboard.writeText(textToCopy);
|
|
1582
|
+
setCopied(true);
|
|
1583
|
+
onCopy?.(textToCopy);
|
|
1584
|
+
setTimeout(() => {
|
|
1585
|
+
setCopied(false);
|
|
1586
|
+
}, feedbackDuration);
|
|
1587
|
+
} catch (err) {
|
|
1588
|
+
console.error("Copy error:", err);
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
return /* @__PURE__ */ jsxs9(
|
|
1592
|
+
"button",
|
|
1593
|
+
{
|
|
1594
|
+
type: "button",
|
|
1595
|
+
onClick: handleCopy,
|
|
1596
|
+
onMouseEnter: () => setIsHovered(true),
|
|
1597
|
+
onMouseLeave: () => setIsHovered(false),
|
|
1598
|
+
title: tooltip,
|
|
1599
|
+
className: `
|
|
1600
|
+
group inline-flex items-center gap-2
|
|
1601
|
+
px-2 py-1 -mx-2 -my-1
|
|
1602
|
+
rounded-md
|
|
1603
|
+
transition-all duration-200
|
|
1604
|
+
hover:bg-slate-100 dark:hover:bg-slate-800
|
|
1605
|
+
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1
|
|
1606
|
+
cursor-pointer
|
|
1607
|
+
${className || ""}
|
|
1608
|
+
`,
|
|
1609
|
+
children: [
|
|
1610
|
+
/* @__PURE__ */ jsx20("span", { className: "select-none text-[hsl(var(--lux-table-cell-foreground))]", children: value }),
|
|
1611
|
+
/* @__PURE__ */ jsx20(
|
|
1612
|
+
"span",
|
|
1613
|
+
{
|
|
1614
|
+
className: `
|
|
1615
|
+
inline-flex items-center justify-center
|
|
1616
|
+
transition-all duration-200
|
|
1617
|
+
${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
|
|
1618
|
+
`,
|
|
1619
|
+
children: copied ? /* @__PURE__ */ jsx20(Check3, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx20(Copy, { className: "h-3.5 w-3.5 text-slate-400 dark:text-slate-500 group-hover:text-slate-600 dark:group-hover:text-slate-300" })
|
|
1620
|
+
}
|
|
1621
|
+
)
|
|
1622
|
+
]
|
|
963
1623
|
}
|
|
964
|
-
return columns;
|
|
965
|
-
}, [columns, showCheckbox, enableRowSelection]);
|
|
966
|
-
const handleRowSelectionChange = React7.useCallback(
|
|
967
|
-
(updater) => {
|
|
968
|
-
const newSelection = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
969
|
-
if (isControlledRowSelection && onRowSelectionChange) {
|
|
970
|
-
onRowSelectionChange(newSelection);
|
|
971
|
-
} else {
|
|
972
|
-
setInternalRowSelection(newSelection);
|
|
973
|
-
}
|
|
974
|
-
},
|
|
975
|
-
[isControlledRowSelection, onRowSelectionChange, rowSelection]
|
|
976
1624
|
);
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1625
|
+
}
|
|
1626
|
+
function createCopyableCell(value, options) {
|
|
1627
|
+
return /* @__PURE__ */ jsx20(CopyableCell, { value, ...options });
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// src/lib/cell-config.tsx
|
|
1631
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1632
|
+
var defaultPatterns = {
|
|
1633
|
+
status: ["status", "state", "stage", "phase"],
|
|
1634
|
+
date: ["date", "createdAt", "updatedAt", "joinDate", "startDate", "endDate", "birthDate", "publishedAt"],
|
|
1635
|
+
currency: ["price", "amount", "salary", "cost", "revenue", "total", "balance", "fee"],
|
|
1636
|
+
boolean: ["isActive", "isVerified", "isEnabled", "isDeleted", "isPublished", "isPublic"],
|
|
1637
|
+
copyable: ["id", "email", "phone", "code", "token", "reference", "orderId"]
|
|
1638
|
+
};
|
|
1639
|
+
function detectFieldTypeFromName(fieldName, patterns) {
|
|
1640
|
+
const name = fieldName.toLowerCase();
|
|
1641
|
+
const mergedPatterns = {
|
|
1642
|
+
status: [...defaultPatterns.status, ...patterns?.status || []],
|
|
1643
|
+
date: [...defaultPatterns.date, ...patterns?.date || []],
|
|
1644
|
+
currency: [...defaultPatterns.currency, ...patterns?.currency || []],
|
|
1645
|
+
boolean: [...defaultPatterns.boolean, ...patterns?.boolean || []],
|
|
1646
|
+
copyable: [...defaultPatterns.copyable, ...patterns?.copyable || []]
|
|
1647
|
+
};
|
|
1648
|
+
if (mergedPatterns.status.some((pattern) => name.includes(pattern.toLowerCase()))) {
|
|
1649
|
+
return "status";
|
|
1650
|
+
}
|
|
1651
|
+
if (mergedPatterns.date.some((pattern) => name.includes(pattern.toLowerCase()))) {
|
|
1652
|
+
return "date";
|
|
1653
|
+
}
|
|
1654
|
+
if (mergedPatterns.currency.some((pattern) => name.includes(pattern.toLowerCase()))) {
|
|
1655
|
+
return "currency";
|
|
1656
|
+
}
|
|
1657
|
+
if (mergedPatterns.boolean.some((pattern) => name.includes(pattern.toLowerCase()))) {
|
|
1658
|
+
return "boolean";
|
|
1659
|
+
}
|
|
1660
|
+
if (mergedPatterns.copyable.some((pattern) => name.includes(pattern.toLowerCase()))) {
|
|
1661
|
+
return "copyable";
|
|
1662
|
+
}
|
|
1663
|
+
return null;
|
|
1664
|
+
}
|
|
1665
|
+
function detectFieldTypeFromValue(value) {
|
|
1666
|
+
if (value === null || value === void 0) return null;
|
|
1667
|
+
if (typeof value === "boolean") {
|
|
1668
|
+
return "boolean";
|
|
1669
|
+
}
|
|
1670
|
+
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value)) {
|
|
1671
|
+
const date = new Date(value);
|
|
1672
|
+
if (!isNaN(date.getTime())) {
|
|
1673
|
+
return "date";
|
|
1022
1674
|
}
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1675
|
+
}
|
|
1676
|
+
if (value instanceof Date) {
|
|
1677
|
+
return "date";
|
|
1678
|
+
}
|
|
1679
|
+
if (typeof value === "number") {
|
|
1680
|
+
return null;
|
|
1681
|
+
}
|
|
1682
|
+
if (typeof value === "string") {
|
|
1683
|
+
const lowerValue = value.toLowerCase();
|
|
1684
|
+
const statusValues = ["active", "inactive", "pending", "completed", "cancelled", "approved", "rejected"];
|
|
1685
|
+
if (statusValues.includes(lowerValue)) {
|
|
1686
|
+
return "status";
|
|
1028
1687
|
}
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1688
|
+
}
|
|
1689
|
+
return null;
|
|
1690
|
+
}
|
|
1691
|
+
function getFieldConfig(fieldName, value, config) {
|
|
1692
|
+
if (config?.fields?.[fieldName]) {
|
|
1693
|
+
return config.fields[fieldName];
|
|
1694
|
+
}
|
|
1695
|
+
if (config?.autoDetect === false) {
|
|
1696
|
+
return null;
|
|
1697
|
+
}
|
|
1698
|
+
const nameType = detectFieldTypeFromName(fieldName, config?.patterns);
|
|
1699
|
+
if (nameType) {
|
|
1700
|
+
switch (nameType) {
|
|
1701
|
+
case "status":
|
|
1702
|
+
return { type: "status" };
|
|
1703
|
+
case "date":
|
|
1704
|
+
return { type: "date", format: "short" };
|
|
1705
|
+
case "currency":
|
|
1706
|
+
return { type: "currency", currency: "USD" };
|
|
1707
|
+
case "boolean":
|
|
1708
|
+
return { type: "boolean" };
|
|
1709
|
+
case "copyable":
|
|
1710
|
+
return { type: "copyable" };
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
const valueType = detectFieldTypeFromValue(value);
|
|
1714
|
+
if (valueType) {
|
|
1715
|
+
switch (valueType) {
|
|
1716
|
+
case "status":
|
|
1717
|
+
return { type: "status" };
|
|
1718
|
+
case "date":
|
|
1719
|
+
return { type: "date", format: "short" };
|
|
1720
|
+
case "boolean":
|
|
1721
|
+
return { type: "boolean" };
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
return null;
|
|
1725
|
+
}
|
|
1726
|
+
var defaultGlobalCellConfig = {
|
|
1727
|
+
defaultStatusColors,
|
|
1728
|
+
autoDetect: true,
|
|
1729
|
+
patterns: defaultPatterns
|
|
1730
|
+
};
|
|
1731
|
+
function renderCell(context, fieldName, config) {
|
|
1732
|
+
const value = context.getValue();
|
|
1733
|
+
const fieldConfig = getFieldConfig(fieldName, value, config);
|
|
1734
|
+
if (!fieldConfig) {
|
|
1735
|
+
if (value === null || value === void 0) {
|
|
1736
|
+
return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: "-" });
|
|
1737
|
+
}
|
|
1738
|
+
return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: String(value) });
|
|
1739
|
+
}
|
|
1740
|
+
if (fieldConfig.type === "custom") {
|
|
1741
|
+
return fieldConfig.render(context);
|
|
1742
|
+
}
|
|
1743
|
+
if (fieldConfig.type === "status") {
|
|
1744
|
+
const statusValue = String(value);
|
|
1745
|
+
const colors = {
|
|
1746
|
+
...config?.defaultStatusColors,
|
|
1747
|
+
...defaultStatusColors,
|
|
1748
|
+
...fieldConfig.colors
|
|
1749
|
+
};
|
|
1750
|
+
return /* @__PURE__ */ jsx21(StatusCell, { value: statusValue, colors });
|
|
1751
|
+
}
|
|
1752
|
+
if (fieldConfig.type === "progress") {
|
|
1753
|
+
return /* @__PURE__ */ jsx21(
|
|
1754
|
+
ProgressCell,
|
|
1037
1755
|
{
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
onFilteringToggle: setFilteringVisible,
|
|
1042
|
-
showGlobalSearch,
|
|
1043
|
-
showColumnVisibility
|
|
1756
|
+
value: Number(value),
|
|
1757
|
+
barColor: fieldConfig.barColor,
|
|
1758
|
+
showLabel: fieldConfig.showLabel ?? false
|
|
1044
1759
|
}
|
|
1045
|
-
)
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
/* @__PURE__ */ jsx12(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx12(
|
|
1095
|
-
TableRow,
|
|
1096
|
-
{
|
|
1097
|
-
"data-state": row.getIsSelected() && "selected",
|
|
1098
|
-
className: cn(
|
|
1099
|
-
enableRowSelection && "cursor-pointer",
|
|
1100
|
-
row.getIsSelected() && "bg-blue-50/50 dark:bg-blue-950/30"
|
|
1101
|
-
),
|
|
1102
|
-
onClick: enableRowSelection && !showCheckbox ? () => {
|
|
1103
|
-
if (selectionMode === "single") {
|
|
1104
|
-
handleRowSelectionChange({ [row.id]: true });
|
|
1105
|
-
} else {
|
|
1106
|
-
row.toggleSelected();
|
|
1107
|
-
}
|
|
1108
|
-
} : void 0,
|
|
1109
|
-
children: row.getVisibleCells().map((cell) => {
|
|
1110
|
-
const isSelectionColumn = cell.column.id === "__selection__";
|
|
1111
|
-
return /* @__PURE__ */ jsx12(
|
|
1112
|
-
TableCell,
|
|
1113
|
-
{
|
|
1114
|
-
style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
|
|
1115
|
-
onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
|
|
1116
|
-
children: flexRender2(cell.column.columnDef.cell, cell.getContext())
|
|
1117
|
-
},
|
|
1118
|
-
cell.id
|
|
1119
|
-
);
|
|
1120
|
-
})
|
|
1121
|
-
},
|
|
1122
|
-
row.id
|
|
1123
|
-
)) : /* @__PURE__ */ jsx12(TableRow, { children: /* @__PURE__ */ jsx12(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
|
|
1124
|
-
] }) }),
|
|
1125
|
-
options?.pagination && /* @__PURE__ */ jsx12(TablePagination, { table })
|
|
1126
|
-
] });
|
|
1760
|
+
);
|
|
1761
|
+
}
|
|
1762
|
+
if (fieldConfig.type === "boolean") {
|
|
1763
|
+
return /* @__PURE__ */ jsx21(
|
|
1764
|
+
BooleanCell,
|
|
1765
|
+
{
|
|
1766
|
+
value: Boolean(value),
|
|
1767
|
+
trueLabel: fieldConfig.trueLabel,
|
|
1768
|
+
falseLabel: fieldConfig.falseLabel,
|
|
1769
|
+
trueColor: fieldConfig.trueColor,
|
|
1770
|
+
falseColor: fieldConfig.falseColor
|
|
1771
|
+
}
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1774
|
+
if (fieldConfig.type === "date") {
|
|
1775
|
+
return /* @__PURE__ */ jsx21(
|
|
1776
|
+
DateCell,
|
|
1777
|
+
{
|
|
1778
|
+
value,
|
|
1779
|
+
format: fieldConfig.format,
|
|
1780
|
+
locale: fieldConfig.locale
|
|
1781
|
+
}
|
|
1782
|
+
);
|
|
1783
|
+
}
|
|
1784
|
+
if (fieldConfig.type === "currency") {
|
|
1785
|
+
return /* @__PURE__ */ jsx21(
|
|
1786
|
+
CurrencyCell,
|
|
1787
|
+
{
|
|
1788
|
+
value: Number(value),
|
|
1789
|
+
currency: fieldConfig.currency || "USD",
|
|
1790
|
+
locale: fieldConfig.locale || "en-US"
|
|
1791
|
+
}
|
|
1792
|
+
);
|
|
1793
|
+
}
|
|
1794
|
+
if (fieldConfig.type === "copyable") {
|
|
1795
|
+
return /* @__PURE__ */ jsx21(
|
|
1796
|
+
CopyableCell,
|
|
1797
|
+
{
|
|
1798
|
+
value: String(value),
|
|
1799
|
+
alwaysShowIcon: fieldConfig.alwaysShowIcon,
|
|
1800
|
+
tooltip: fieldConfig.tooltip,
|
|
1801
|
+
onCopy: fieldConfig.onCopy
|
|
1802
|
+
}
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
1805
|
+
if (value === null || value === void 0) {
|
|
1806
|
+
return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: "-" });
|
|
1807
|
+
}
|
|
1808
|
+
return /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--lux-table-cell-foreground))]", children: String(value) });
|
|
1127
1809
|
}
|
|
1128
1810
|
|
|
1811
|
+
// src/lib/column-helper.tsx
|
|
1812
|
+
import { createColumnHelper as tanstackCreateColumnHelper } from "@tanstack/react-table";
|
|
1813
|
+
|
|
1129
1814
|
// src/components/lux-table/column-header.tsx
|
|
1130
1815
|
import {
|
|
1131
1816
|
ArrowDown,
|
|
@@ -1133,9 +1818,9 @@ import {
|
|
|
1133
1818
|
ArrowUpDown,
|
|
1134
1819
|
EyeOff as EyeOff2,
|
|
1135
1820
|
MoreVertical,
|
|
1136
|
-
X
|
|
1821
|
+
X as X2
|
|
1137
1822
|
} from "lucide-react";
|
|
1138
|
-
import { Fragment as Fragment3, jsx as
|
|
1823
|
+
import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1139
1824
|
function LuxDataTableColumnHeader({
|
|
1140
1825
|
column,
|
|
1141
1826
|
title,
|
|
@@ -1145,327 +1830,74 @@ function LuxDataTableColumnHeader({
|
|
|
1145
1830
|
const canSort = column.getCanSort();
|
|
1146
1831
|
const SortIndicator = () => {
|
|
1147
1832
|
if (isSorted === "desc") {
|
|
1148
|
-
return /* @__PURE__ */
|
|
1833
|
+
return /* @__PURE__ */ jsx22(ArrowDown, { className: "h-4 w-4 text-[hsl(var(--lux-sort-active))]" });
|
|
1149
1834
|
}
|
|
1150
1835
|
if (isSorted === "asc") {
|
|
1151
|
-
return /* @__PURE__ */
|
|
1836
|
+
return /* @__PURE__ */ jsx22(ArrowUp, { className: "h-4 w-4 text-[hsl(var(--lux-sort-active))]" });
|
|
1152
1837
|
}
|
|
1153
1838
|
if (canSort) {
|
|
1154
|
-
return /* @__PURE__ */
|
|
1839
|
+
return /* @__PURE__ */ jsx22(ArrowUpDown, { className: "h-4 w-4 text-[hsl(var(--lux-sort-idle))]" });
|
|
1155
1840
|
}
|
|
1156
1841
|
return null;
|
|
1157
1842
|
};
|
|
1158
1843
|
if (!canSort) {
|
|
1159
|
-
return /* @__PURE__ */
|
|
1844
|
+
return /* @__PURE__ */ jsx22("span", { className: cn("text-sm font-medium", className), children: title });
|
|
1160
1845
|
}
|
|
1161
|
-
return /* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1846
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("flex items-center gap-2", className), children: [
|
|
1847
|
+
/* @__PURE__ */ jsx22(SortIndicator, {}),
|
|
1848
|
+
/* @__PURE__ */ jsx22("span", { className: "text-sm font-medium", children: title }),
|
|
1849
|
+
/* @__PURE__ */ jsxs10(DropdownMenu, { children: [
|
|
1850
|
+
/* @__PURE__ */ jsx22(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
|
|
1166
1851
|
Button,
|
|
1167
1852
|
{
|
|
1168
1853
|
variant: "ghost",
|
|
1169
1854
|
size: "icon",
|
|
1170
|
-
className: "h-6 w-6 ml-auto opacity-
|
|
1855
|
+
className: "h-6 w-6 ml-auto opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
|
|
1171
1856
|
children: [
|
|
1172
|
-
/* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
1857
|
+
/* @__PURE__ */ jsx22(MoreVertical, { className: "h-3.5 w-3.5" }),
|
|
1858
|
+
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Column actions" })
|
|
1174
1859
|
]
|
|
1175
1860
|
}
|
|
1176
1861
|
) }),
|
|
1177
|
-
/* @__PURE__ */
|
|
1178
|
-
/* @__PURE__ */
|
|
1862
|
+
/* @__PURE__ */ jsxs10(DropdownMenuContent, { align: "end", className: "bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-800", children: [
|
|
1863
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
|
|
1179
1864
|
e.stopPropagation();
|
|
1180
1865
|
column.toggleSorting(false);
|
|
1181
1866
|
}, children: [
|
|
1182
|
-
/* @__PURE__ */
|
|
1867
|
+
/* @__PURE__ */ jsx22(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1183
1868
|
"Sort Ascending"
|
|
1184
1869
|
] }),
|
|
1185
|
-
/* @__PURE__ */
|
|
1870
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
|
|
1186
1871
|
e.stopPropagation();
|
|
1187
1872
|
column.toggleSorting(true);
|
|
1188
1873
|
}, children: [
|
|
1189
|
-
/* @__PURE__ */
|
|
1190
|
-
"Sort Descending"
|
|
1191
|
-
] }),
|
|
1192
|
-
isSorted && /* @__PURE__ */
|
|
1193
|
-
/* @__PURE__ */
|
|
1194
|
-
/* @__PURE__ */
|
|
1195
|
-
e.stopPropagation();
|
|
1196
|
-
column.clearSorting();
|
|
1197
|
-
}, children: [
|
|
1198
|
-
/* @__PURE__ */
|
|
1199
|
-
"Clear sorting"
|
|
1200
|
-
] })
|
|
1201
|
-
] }),
|
|
1202
|
-
/* @__PURE__ */
|
|
1203
|
-
/* @__PURE__ */
|
|
1204
|
-
e.stopPropagation();
|
|
1205
|
-
column.toggleVisibility(false);
|
|
1206
|
-
}, children: [
|
|
1207
|
-
/* @__PURE__ */
|
|
1208
|
-
"Hide column"
|
|
1209
|
-
] })
|
|
1210
|
-
] })
|
|
1211
|
-
] })
|
|
1212
|
-
] });
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
// src/components/cell-renderers/status-cell.tsx
|
|
1216
|
-
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1217
|
-
var defaultStatusColors = {
|
|
1218
|
-
Active: {
|
|
1219
|
-
bg: "bg-green-100",
|
|
1220
|
-
text: "text-green-800",
|
|
1221
|
-
darkBg: "dark:bg-green-900",
|
|
1222
|
-
darkText: "dark:text-green-300"
|
|
1223
|
-
},
|
|
1224
|
-
Inactive: {
|
|
1225
|
-
bg: "bg-red-100",
|
|
1226
|
-
text: "text-red-800",
|
|
1227
|
-
darkBg: "dark:bg-red-900",
|
|
1228
|
-
darkText: "dark:text-red-300"
|
|
1229
|
-
},
|
|
1230
|
-
Pending: {
|
|
1231
|
-
bg: "bg-yellow-100",
|
|
1232
|
-
text: "text-yellow-800",
|
|
1233
|
-
darkBg: "dark:bg-yellow-900",
|
|
1234
|
-
darkText: "dark:text-yellow-300"
|
|
1235
|
-
},
|
|
1236
|
-
Completed: {
|
|
1237
|
-
bg: "bg-blue-100",
|
|
1238
|
-
text: "text-blue-800",
|
|
1239
|
-
darkBg: "dark:bg-blue-900",
|
|
1240
|
-
darkText: "dark:text-blue-300"
|
|
1241
|
-
},
|
|
1242
|
-
Cancelled: {
|
|
1243
|
-
bg: "bg-gray-100",
|
|
1244
|
-
text: "text-gray-800",
|
|
1245
|
-
darkBg: "dark:bg-gray-900",
|
|
1246
|
-
darkText: "dark:text-gray-300"
|
|
1247
|
-
}
|
|
1248
|
-
};
|
|
1249
|
-
function StatusCell({ value, colors, className }) {
|
|
1250
|
-
const mergedColors = { ...defaultStatusColors, ...colors };
|
|
1251
|
-
const colorConfig = mergedColors[value];
|
|
1252
|
-
if (!colorConfig) {
|
|
1253
|
-
return /* @__PURE__ */ jsx14("span", { className: `px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300 ${className || ""}`, children: value });
|
|
1254
|
-
}
|
|
1255
|
-
const { bg, text, darkBg, darkText } = colorConfig;
|
|
1256
|
-
return /* @__PURE__ */ jsx14("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${darkBg || ""} ${darkText || ""} ${className || ""}`, children: value });
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
// src/components/cell-renderers/progress-cell.tsx
|
|
1260
|
-
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1261
|
-
function ProgressCell({
|
|
1262
|
-
value,
|
|
1263
|
-
barColor = "bg-blue-600",
|
|
1264
|
-
bgColor = "bg-gray-200 dark:bg-gray-700",
|
|
1265
|
-
showLabel = false,
|
|
1266
|
-
className
|
|
1267
|
-
}) {
|
|
1268
|
-
const clampedValue = Math.min(100, Math.max(0, value));
|
|
1269
|
-
return /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
|
|
1270
|
-
/* @__PURE__ */ jsx15("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx15(
|
|
1271
|
-
"div",
|
|
1272
|
-
{
|
|
1273
|
-
className: `${barColor} h-2.5 rounded-full transition-all`,
|
|
1274
|
-
style: { width: `${clampedValue}%` }
|
|
1275
|
-
}
|
|
1276
|
-
) }),
|
|
1277
|
-
showLabel && /* @__PURE__ */ jsxs9("span", { className: "text-xs text-gray-500 dark:text-gray-400 w-8", children: [
|
|
1278
|
-
value,
|
|
1279
|
-
"%"
|
|
1280
|
-
] })
|
|
1281
|
-
] });
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
// src/components/cell-renderers/boolean-cell.tsx
|
|
1285
|
-
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1286
|
-
function BooleanCell({
|
|
1287
|
-
value,
|
|
1288
|
-
trueLabel = "Yes",
|
|
1289
|
-
falseLabel = "No",
|
|
1290
|
-
trueColor = "text-green-600 dark:text-green-400",
|
|
1291
|
-
falseColor = "text-red-600 dark:text-red-400"
|
|
1292
|
-
}) {
|
|
1293
|
-
return /* @__PURE__ */ jsx16("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
// src/components/cell-renderers/date-cell.tsx
|
|
1297
|
-
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1298
|
-
function DateCell({ value, format = "short", locale = "en-US" }) {
|
|
1299
|
-
const date = typeof value === "string" ? new Date(value) : value;
|
|
1300
|
-
if (isNaN(date.getTime())) {
|
|
1301
|
-
return /* @__PURE__ */ jsx17("span", { className: "text-gray-400", children: "-" });
|
|
1302
|
-
}
|
|
1303
|
-
let formatted;
|
|
1304
|
-
switch (format) {
|
|
1305
|
-
case "long":
|
|
1306
|
-
formatted = date.toLocaleDateString(locale, {
|
|
1307
|
-
year: "numeric",
|
|
1308
|
-
month: "long",
|
|
1309
|
-
day: "numeric"
|
|
1310
|
-
});
|
|
1311
|
-
break;
|
|
1312
|
-
case "relative": {
|
|
1313
|
-
const now = /* @__PURE__ */ new Date();
|
|
1314
|
-
const diffMs = now.getTime() - date.getTime();
|
|
1315
|
-
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
1316
|
-
if (diffDays === 0) formatted = "Today";
|
|
1317
|
-
else if (diffDays === 1) formatted = "Yesterday";
|
|
1318
|
-
else if (diffDays < 7) formatted = `${diffDays} days ago`;
|
|
1319
|
-
else formatted = date.toLocaleDateString(locale);
|
|
1320
|
-
break;
|
|
1321
|
-
}
|
|
1322
|
-
default:
|
|
1323
|
-
formatted = date.toLocaleDateString(locale);
|
|
1324
|
-
}
|
|
1325
|
-
return /* @__PURE__ */ jsx17("span", { children: formatted });
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
// src/components/cell-renderers/currency-cell.tsx
|
|
1329
|
-
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1330
|
-
function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
|
|
1331
|
-
const formatted = new Intl.NumberFormat(locale, {
|
|
1332
|
-
style: "currency",
|
|
1333
|
-
currency
|
|
1334
|
-
}).format(value);
|
|
1335
|
-
return /* @__PURE__ */ jsx18("span", { className: "font-medium", children: formatted });
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
// src/components/cell-renderers/copyable-cell.tsx
|
|
1339
|
-
import * as React8 from "react";
|
|
1340
|
-
import { Copy, Check as Check3 } from "lucide-react";
|
|
1341
|
-
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1342
|
-
function CopyableCell({
|
|
1343
|
-
value,
|
|
1344
|
-
feedbackDuration = 2e3,
|
|
1345
|
-
onCopy,
|
|
1346
|
-
className,
|
|
1347
|
-
tooltip = "Click to copy",
|
|
1348
|
-
alwaysShowIcon = false
|
|
1349
|
-
}) {
|
|
1350
|
-
const [copied, setCopied] = React8.useState(false);
|
|
1351
|
-
const [isHovered, setIsHovered] = React8.useState(false);
|
|
1352
|
-
const handleCopy = async (e) => {
|
|
1353
|
-
e.stopPropagation();
|
|
1354
|
-
const textToCopy = String(value);
|
|
1355
|
-
try {
|
|
1356
|
-
await navigator.clipboard.writeText(textToCopy);
|
|
1357
|
-
setCopied(true);
|
|
1358
|
-
onCopy?.(textToCopy);
|
|
1359
|
-
setTimeout(() => {
|
|
1360
|
-
setCopied(false);
|
|
1361
|
-
}, feedbackDuration);
|
|
1362
|
-
} catch (err) {
|
|
1363
|
-
console.error("Copy error:", err);
|
|
1364
|
-
}
|
|
1365
|
-
};
|
|
1366
|
-
return /* @__PURE__ */ jsxs10(
|
|
1367
|
-
"button",
|
|
1368
|
-
{
|
|
1369
|
-
type: "button",
|
|
1370
|
-
onClick: handleCopy,
|
|
1371
|
-
onMouseEnter: () => setIsHovered(true),
|
|
1372
|
-
onMouseLeave: () => setIsHovered(false),
|
|
1373
|
-
title: tooltip,
|
|
1374
|
-
className: `
|
|
1375
|
-
group inline-flex items-center gap-2
|
|
1376
|
-
px-2 py-1 -mx-2 -my-1
|
|
1377
|
-
rounded-md
|
|
1378
|
-
transition-all duration-200
|
|
1379
|
-
hover:bg-slate-100 dark:hover:bg-slate-800
|
|
1380
|
-
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1
|
|
1381
|
-
cursor-pointer
|
|
1382
|
-
${className || ""}
|
|
1383
|
-
`,
|
|
1384
|
-
children: [
|
|
1385
|
-
/* @__PURE__ */ jsx19("span", { className: "select-none", children: value }),
|
|
1386
|
-
/* @__PURE__ */ jsx19(
|
|
1387
|
-
"span",
|
|
1388
|
-
{
|
|
1389
|
-
className: `
|
|
1390
|
-
inline-flex items-center justify-center
|
|
1391
|
-
transition-all duration-200
|
|
1392
|
-
${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
|
|
1393
|
-
`,
|
|
1394
|
-
children: copied ? /* @__PURE__ */ jsx19(Check3, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx19(Copy, { className: "h-3.5 w-3.5 text-slate-400 dark:text-slate-500 group-hover:text-slate-600 dark:group-hover:text-slate-300" })
|
|
1395
|
-
}
|
|
1396
|
-
)
|
|
1397
|
-
]
|
|
1398
|
-
}
|
|
1399
|
-
);
|
|
1400
|
-
}
|
|
1401
|
-
function createCopyableCell(value, options) {
|
|
1402
|
-
return /* @__PURE__ */ jsx19(CopyableCell, { value, ...options });
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
// src/components/ui/label.tsx
|
|
1406
|
-
import * as React9 from "react";
|
|
1407
|
-
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
1408
|
-
import { cva as cva2 } from "class-variance-authority";
|
|
1409
|
-
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1410
|
-
var labelVariants = cva2(
|
|
1411
|
-
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
1412
|
-
);
|
|
1413
|
-
var Label3 = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
|
|
1414
|
-
LabelPrimitive.Root,
|
|
1415
|
-
{
|
|
1416
|
-
ref,
|
|
1417
|
-
className: cn(labelVariants(), className),
|
|
1418
|
-
...props
|
|
1419
|
-
}
|
|
1420
|
-
));
|
|
1421
|
-
Label3.displayName = LabelPrimitive.Root.displayName;
|
|
1422
|
-
|
|
1423
|
-
// src/components/ui/popover.tsx
|
|
1424
|
-
import * as React10 from "react";
|
|
1425
|
-
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
1426
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1427
|
-
var Popover = PopoverPrimitive.Root;
|
|
1428
|
-
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
1429
|
-
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
1430
|
-
var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx21(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx21(
|
|
1431
|
-
PopoverPrimitive.Content,
|
|
1432
|
-
{
|
|
1433
|
-
ref,
|
|
1434
|
-
align,
|
|
1435
|
-
sideOffset,
|
|
1436
|
-
className: cn(
|
|
1437
|
-
"z-50 w-72 rounded-md border border-slate-200 bg-white p-4 text-slate-950 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-50",
|
|
1438
|
-
className
|
|
1439
|
-
),
|
|
1440
|
-
...props
|
|
1441
|
-
}
|
|
1442
|
-
) }));
|
|
1443
|
-
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
1444
|
-
|
|
1445
|
-
// src/components/ui/separator.tsx
|
|
1446
|
-
import * as React11 from "react";
|
|
1447
|
-
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
1448
|
-
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1449
|
-
var Separator3 = React11.forwardRef(
|
|
1450
|
-
({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx22(
|
|
1451
|
-
SeparatorPrimitive.Root,
|
|
1452
|
-
{
|
|
1453
|
-
ref,
|
|
1454
|
-
decorative,
|
|
1455
|
-
orientation,
|
|
1456
|
-
className: cn(
|
|
1457
|
-
"shrink-0 bg-slate-200 dark:bg-slate-800",
|
|
1458
|
-
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
1459
|
-
className
|
|
1460
|
-
),
|
|
1461
|
-
...props
|
|
1462
|
-
}
|
|
1463
|
-
)
|
|
1464
|
-
);
|
|
1465
|
-
Separator3.displayName = SeparatorPrimitive.Root.displayName;
|
|
1874
|
+
/* @__PURE__ */ jsx22(ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1875
|
+
"Sort Descending"
|
|
1876
|
+
] }),
|
|
1877
|
+
isSorted && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1878
|
+
/* @__PURE__ */ jsx22(DropdownMenuSeparator, {}),
|
|
1879
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
|
|
1880
|
+
e.stopPropagation();
|
|
1881
|
+
column.clearSorting();
|
|
1882
|
+
}, children: [
|
|
1883
|
+
/* @__PURE__ */ jsx22(X2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1884
|
+
"Clear sorting"
|
|
1885
|
+
] })
|
|
1886
|
+
] }),
|
|
1887
|
+
/* @__PURE__ */ jsx22(DropdownMenuSeparator, {}),
|
|
1888
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem, { onClick: (e) => {
|
|
1889
|
+
e.stopPropagation();
|
|
1890
|
+
column.toggleVisibility(false);
|
|
1891
|
+
}, children: [
|
|
1892
|
+
/* @__PURE__ */ jsx22(EyeOff2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
|
|
1893
|
+
"Hide column"
|
|
1894
|
+
] })
|
|
1895
|
+
] })
|
|
1896
|
+
] })
|
|
1897
|
+
] });
|
|
1898
|
+
}
|
|
1466
1899
|
|
|
1467
1900
|
// src/lib/column-helper.tsx
|
|
1468
|
-
import { createColumnHelper as tanstackCreateColumnHelper } from "@tanstack/react-table";
|
|
1469
1901
|
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1470
1902
|
var toTitleCase = (str) => {
|
|
1471
1903
|
return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
@@ -1482,6 +1914,8 @@ function createColumnHelper() {
|
|
|
1482
1914
|
...column,
|
|
1483
1915
|
// enableSorting is true by default
|
|
1484
1916
|
enableSorting: column?.enableSorting !== false,
|
|
1917
|
+
// Pass size if provided
|
|
1918
|
+
size: column?.size,
|
|
1485
1919
|
// Pass meta information (filterVariant etc.)
|
|
1486
1920
|
meta: column?.meta,
|
|
1487
1921
|
// Use LuxDataTableColumnHeader if header is string or undefined
|
|
@@ -1492,14 +1926,9 @@ function createColumnHelper() {
|
|
|
1492
1926
|
title: typeof headerContent === "string" ? headerContent : toTitleCase(accessor)
|
|
1493
1927
|
}
|
|
1494
1928
|
),
|
|
1495
|
-
//
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
if (value === null || value === void 0) {
|
|
1499
|
-
return "-";
|
|
1500
|
-
}
|
|
1501
|
-
return String(value);
|
|
1502
|
-
})
|
|
1929
|
+
// Only add default cell if cell is not explicitly provided
|
|
1930
|
+
// This allows LuxTable's cellConfig to work
|
|
1931
|
+
...column?.cell ? { cell: column.cell } : {}
|
|
1503
1932
|
};
|
|
1504
1933
|
return helper.accessor(accessor, finalColumn);
|
|
1505
1934
|
},
|
|
@@ -1556,15 +1985,395 @@ function createColumnsFromData(data, options) {
|
|
|
1556
1985
|
const cellRenderer = options?.cells?.[key];
|
|
1557
1986
|
return helper.accessor(key, {
|
|
1558
1987
|
header: ({ column }) => /* @__PURE__ */ jsx23(LuxDataTableColumnHeader, { column, title: headerText }),
|
|
1559
|
-
cell
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1988
|
+
// Only add cell if explicitly provided - this allows LuxTable's cellConfig to work
|
|
1989
|
+
...cellRenderer ? { cell: cellRenderer } : {}
|
|
1990
|
+
});
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
// src/components/lux-table/lux-table.tsx
|
|
1995
|
+
import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1996
|
+
function createSelectionColumn() {
|
|
1997
|
+
return {
|
|
1998
|
+
id: "__selection__",
|
|
1999
|
+
header: ({ table }) => /* @__PURE__ */ jsx24(
|
|
2000
|
+
Checkbox,
|
|
2001
|
+
{
|
|
2002
|
+
checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
|
|
2003
|
+
onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value),
|
|
2004
|
+
"aria-label": "Select all rows"
|
|
2005
|
+
}
|
|
2006
|
+
),
|
|
2007
|
+
cell: ({ row }) => /* @__PURE__ */ jsx24(
|
|
2008
|
+
Checkbox,
|
|
2009
|
+
{
|
|
2010
|
+
checked: row.getIsSelected(),
|
|
2011
|
+
disabled: !row.getCanSelect(),
|
|
2012
|
+
onCheckedChange: (value) => row.toggleSelected(!!value),
|
|
2013
|
+
"aria-label": "Select row"
|
|
2014
|
+
}
|
|
2015
|
+
),
|
|
2016
|
+
size: 40,
|
|
2017
|
+
enableSorting: false,
|
|
2018
|
+
enableHiding: false
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
function LuxTable({
|
|
2022
|
+
columns,
|
|
2023
|
+
data,
|
|
2024
|
+
className,
|
|
2025
|
+
options,
|
|
2026
|
+
cellConfig,
|
|
2027
|
+
sorting: controlledSorting,
|
|
2028
|
+
onSortingChange,
|
|
2029
|
+
rowSelection: controlledRowSelection,
|
|
2030
|
+
onRowSelectionChange,
|
|
2031
|
+
onSelectedRowsChange,
|
|
2032
|
+
getRowId
|
|
2033
|
+
}) {
|
|
2034
|
+
const [internalSorting, setInternalSorting] = React10.useState([]);
|
|
2035
|
+
const [columnFilters, setColumnFilters] = React10.useState([]);
|
|
2036
|
+
const [globalFilter, setGlobalFilter] = React10.useState("");
|
|
2037
|
+
const [filteringVisible, setFilteringVisible] = React10.useState(options?.filtering ?? false);
|
|
2038
|
+
const [internalRowSelection, setInternalRowSelection] = React10.useState({});
|
|
2039
|
+
const isControlledSorting = controlledSorting !== void 0;
|
|
2040
|
+
const sorting = isControlledSorting ? controlledSorting : internalSorting;
|
|
2041
|
+
const isControlledRowSelection = controlledRowSelection !== void 0;
|
|
2042
|
+
const rowSelection = isControlledRowSelection ? controlledRowSelection : internalRowSelection;
|
|
2043
|
+
const selectionMode = options?.selection ?? "none";
|
|
2044
|
+
const showCheckbox = options?.showSelectionCheckbox ?? selectionMode !== "none";
|
|
2045
|
+
const enableRowSelection = selectionMode !== "none";
|
|
2046
|
+
const enableMultiRowSelection = selectionMode === "multiple";
|
|
2047
|
+
const mergedCellConfig = React10.useMemo(() => {
|
|
2048
|
+
const baseConfig = defaultGlobalCellConfig;
|
|
2049
|
+
if (cellConfig) {
|
|
2050
|
+
return {
|
|
2051
|
+
...baseConfig,
|
|
2052
|
+
...cellConfig,
|
|
2053
|
+
fields: {
|
|
2054
|
+
...cellConfig.fields
|
|
2055
|
+
// User's fields override defaults
|
|
2056
|
+
},
|
|
2057
|
+
patterns: {
|
|
2058
|
+
...baseConfig.patterns,
|
|
2059
|
+
...cellConfig.patterns
|
|
2060
|
+
// Merge patterns
|
|
2061
|
+
},
|
|
2062
|
+
defaultStatusColors: {
|
|
2063
|
+
...baseConfig.defaultStatusColors,
|
|
2064
|
+
...cellConfig.defaultStatusColors
|
|
2065
|
+
// Merge status colors
|
|
2066
|
+
}
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
return baseConfig;
|
|
2070
|
+
}, [cellConfig]);
|
|
2071
|
+
const autoColumns = React10.useMemo(() => {
|
|
2072
|
+
if (columns) return columns;
|
|
2073
|
+
if (!data || data.length === 0) return [];
|
|
2074
|
+
if (typeof data[0] === "object" && data[0] !== null) {
|
|
2075
|
+
const generatedColumns = createColumnsFromData(data);
|
|
2076
|
+
return generatedColumns;
|
|
2077
|
+
}
|
|
2078
|
+
return [];
|
|
2079
|
+
}, [columns, data]);
|
|
2080
|
+
const dateFilterFn = React10.useCallback((row, columnId, filterValue) => {
|
|
2081
|
+
if (!filterValue || !filterValue.from && !filterValue.to) return true;
|
|
2082
|
+
const cellValue = row.getValue(columnId);
|
|
2083
|
+
if (!cellValue) return false;
|
|
2084
|
+
const cellDate = new Date(String(cellValue));
|
|
2085
|
+
if (isNaN(cellDate.getTime())) return false;
|
|
2086
|
+
if (filterValue.from) {
|
|
2087
|
+
const fromDate = new Date(filterValue.from);
|
|
2088
|
+
fromDate.setHours(0, 0, 0, 0);
|
|
2089
|
+
if (cellDate < fromDate) return false;
|
|
2090
|
+
}
|
|
2091
|
+
if (filterValue.to) {
|
|
2092
|
+
const toDate = new Date(filterValue.to);
|
|
2093
|
+
toDate.setHours(23, 59, 59, 999);
|
|
2094
|
+
if (cellDate > toDate) return false;
|
|
2095
|
+
}
|
|
2096
|
+
return true;
|
|
2097
|
+
}, []);
|
|
2098
|
+
const sliderFilterFn = React10.useCallback((row, columnId, filterValue) => {
|
|
2099
|
+
if (!filterValue || filterValue.min === void 0 && filterValue.max === void 0) return true;
|
|
2100
|
+
const cellValue = row.getValue(columnId);
|
|
2101
|
+
const numValue = typeof cellValue === "number" ? cellValue : parseFloat(String(cellValue));
|
|
2102
|
+
if (isNaN(numValue)) return false;
|
|
2103
|
+
if (filterValue.min !== void 0 && numValue < filterValue.min) return false;
|
|
2104
|
+
if (filterValue.max !== void 0 && numValue > filterValue.max) return false;
|
|
2105
|
+
return true;
|
|
2106
|
+
}, []);
|
|
2107
|
+
const statusFilterFn = React10.useCallback((row, columnId, filterValue) => {
|
|
2108
|
+
if (!filterValue || filterValue.length === 0) return true;
|
|
2109
|
+
const cellValue = String(row.getValue(columnId)).toLowerCase();
|
|
2110
|
+
return filterValue.some((status) => status.toLowerCase() === cellValue);
|
|
2111
|
+
}, []);
|
|
2112
|
+
const tableColumns = React10.useMemo(() => {
|
|
2113
|
+
let processedColumns = autoColumns.map((col) => {
|
|
2114
|
+
const accessorKey = "accessorKey" in col ? col.accessorKey : void 0;
|
|
2115
|
+
const fieldName = accessorKey ? String(accessorKey) : "id" in col ? String(col.id) : void 0;
|
|
2116
|
+
let filterFn = col.filterFn;
|
|
2117
|
+
const meta = col.meta || {};
|
|
2118
|
+
if (fieldName && !meta.filterVariant) {
|
|
2119
|
+
const fieldNameLower = fieldName.toLowerCase();
|
|
2120
|
+
const datePatterns = ["date", "createdat", "updatedat", "joindate", "startdate", "enddate", "birthdate", "publishedat"];
|
|
2121
|
+
if (datePatterns.some((pattern) => fieldNameLower.includes(pattern))) {
|
|
2122
|
+
meta.filterVariant = "date";
|
|
2123
|
+
filterFn = dateFilterFn;
|
|
2124
|
+
}
|
|
2125
|
+
const statusPatterns = ["status", "state", "stage", "phase"];
|
|
2126
|
+
if (statusPatterns.some((pattern) => fieldNameLower.includes(pattern))) {
|
|
2127
|
+
meta.filterVariant = "status";
|
|
2128
|
+
filterFn = statusFilterFn;
|
|
2129
|
+
}
|
|
2130
|
+
const numericPatterns = ["salary", "price", "amount", "cost", "revenue", "total", "balance", "fee"];
|
|
2131
|
+
if (numericPatterns.some((pattern) => fieldNameLower.includes(pattern))) {
|
|
2132
|
+
meta.filterVariant = "slider";
|
|
2133
|
+
filterFn = sliderFilterFn;
|
|
2134
|
+
}
|
|
2135
|
+
} else if (meta.filterVariant) {
|
|
2136
|
+
if (meta.filterVariant === "date" && !filterFn) {
|
|
2137
|
+
filterFn = dateFilterFn;
|
|
2138
|
+
} else if (meta.filterVariant === "slider" && !filterFn) {
|
|
2139
|
+
filterFn = sliderFilterFn;
|
|
2140
|
+
} else if (meta.filterVariant === "status" && !filterFn) {
|
|
2141
|
+
filterFn = statusFilterFn;
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
if (mergedCellConfig && fieldName) {
|
|
2145
|
+
const sampleValue = data && data.length > 0 ? data[0]?.[fieldName] : void 0;
|
|
2146
|
+
const fieldConfig = getFieldConfig(fieldName, sampleValue, mergedCellConfig);
|
|
2147
|
+
if (fieldConfig) {
|
|
2148
|
+
return {
|
|
2149
|
+
...col,
|
|
2150
|
+
cell: (context) => renderCell(context, fieldName, mergedCellConfig),
|
|
2151
|
+
filterFn,
|
|
2152
|
+
meta
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
if (col.cell || filterFn || meta.filterVariant) {
|
|
2157
|
+
return {
|
|
2158
|
+
...col,
|
|
2159
|
+
filterFn,
|
|
2160
|
+
meta
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
return {
|
|
2164
|
+
...col,
|
|
2165
|
+
filterFn,
|
|
2166
|
+
meta
|
|
2167
|
+
};
|
|
1564
2168
|
});
|
|
2169
|
+
if (showCheckbox && enableRowSelection) {
|
|
2170
|
+
return [createSelectionColumn(), ...processedColumns];
|
|
2171
|
+
}
|
|
2172
|
+
return processedColumns;
|
|
2173
|
+
}, [autoColumns, showCheckbox, enableRowSelection, mergedCellConfig, data, dateFilterFn, sliderFilterFn, statusFilterFn]);
|
|
2174
|
+
const handleRowSelectionChange = React10.useCallback(
|
|
2175
|
+
(updater) => {
|
|
2176
|
+
const newSelection = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
2177
|
+
if (isControlledRowSelection && onRowSelectionChange) {
|
|
2178
|
+
onRowSelectionChange(newSelection);
|
|
2179
|
+
} else {
|
|
2180
|
+
setInternalRowSelection(newSelection);
|
|
2181
|
+
}
|
|
2182
|
+
},
|
|
2183
|
+
[isControlledRowSelection, onRowSelectionChange, rowSelection]
|
|
2184
|
+
);
|
|
2185
|
+
const enableSorting = options?.sorting !== false;
|
|
2186
|
+
const enableMultiSort = options?.multiSort !== false;
|
|
2187
|
+
const table = useReactTable({
|
|
2188
|
+
data,
|
|
2189
|
+
columns: tableColumns,
|
|
2190
|
+
enableSorting,
|
|
2191
|
+
enableMultiSort,
|
|
2192
|
+
// Shift+Click for multi-sort (default behavior)
|
|
2193
|
+
isMultiSortEvent: (e) => e.shiftKey,
|
|
2194
|
+
// Max columns for multi-sort (undefined = unlimited)
|
|
2195
|
+
maxMultiSortColCount: options?.maxMultiSortColCount,
|
|
2196
|
+
state: {
|
|
2197
|
+
sorting,
|
|
2198
|
+
columnFilters,
|
|
2199
|
+
rowSelection,
|
|
2200
|
+
globalFilter
|
|
2201
|
+
},
|
|
2202
|
+
onGlobalFilterChange: setGlobalFilter,
|
|
2203
|
+
onSortingChange: (updater) => {
|
|
2204
|
+
const newSorting = typeof updater === "function" ? updater(sorting) : updater;
|
|
2205
|
+
if (isControlledSorting && onSortingChange) {
|
|
2206
|
+
onSortingChange(newSorting);
|
|
2207
|
+
} else {
|
|
2208
|
+
setInternalSorting(newSorting);
|
|
2209
|
+
}
|
|
2210
|
+
},
|
|
2211
|
+
onColumnFiltersChange: setColumnFilters,
|
|
2212
|
+
onRowSelectionChange: handleRowSelectionChange,
|
|
2213
|
+
enableRowSelection,
|
|
2214
|
+
enableMultiRowSelection,
|
|
2215
|
+
getRowId: getRowId ?? ((row, index) => {
|
|
2216
|
+
if (typeof row === "object" && row !== null && "id" in row) {
|
|
2217
|
+
return String(row.id);
|
|
2218
|
+
}
|
|
2219
|
+
return String(index);
|
|
2220
|
+
}),
|
|
2221
|
+
getCoreRowModel: getCoreRowModel(),
|
|
2222
|
+
getPaginationRowModel: options?.pagination ? getPaginationRowModel() : void 0,
|
|
2223
|
+
getSortedRowModel: getSortedRowModel(),
|
|
2224
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
2225
|
+
getFacetedUniqueValues: getFacetedUniqueValues(),
|
|
2226
|
+
initialState: {
|
|
2227
|
+
pagination: {
|
|
2228
|
+
pageSize: options?.pageSize ?? 10
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
1565
2231
|
});
|
|
2232
|
+
React10.useEffect(() => {
|
|
2233
|
+
if (onSelectedRowsChange) {
|
|
2234
|
+
const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
|
|
2235
|
+
onSelectedRowsChange(selectedRows);
|
|
2236
|
+
}
|
|
2237
|
+
}, [rowSelection, onSelectedRowsChange, table]);
|
|
2238
|
+
const visibleColumnCount = tableColumns.length;
|
|
2239
|
+
const showToolbar = options?.showToolbar ?? false;
|
|
2240
|
+
const showGlobalSearch = options?.showGlobalSearch ?? true;
|
|
2241
|
+
const showColumnVisibility = options?.showColumnVisibility ?? true;
|
|
2242
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("w-full space-y-4", className), children: [
|
|
2243
|
+
showToolbar && /* @__PURE__ */ jsx24(
|
|
2244
|
+
TableToolbar,
|
|
2245
|
+
{
|
|
2246
|
+
table,
|
|
2247
|
+
showFiltering: options?.filtering !== void 0,
|
|
2248
|
+
filteringEnabled: filteringVisible,
|
|
2249
|
+
onFilteringToggle: setFilteringVisible,
|
|
2250
|
+
showGlobalSearch,
|
|
2251
|
+
showColumnVisibility
|
|
2252
|
+
}
|
|
2253
|
+
),
|
|
2254
|
+
enableRowSelection && Object.keys(rowSelection).length > 0 && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-4 py-2 text-sm bg-[hsl(var(--lux-selection-info-background))] text-[hsl(var(--lux-selection-info-foreground))] rounded-lg border border-[hsl(var(--lux-selection-info-border))]", children: [
|
|
2255
|
+
/* @__PURE__ */ jsx24(CheckCircle2, { className: "w-4 h-4" }),
|
|
2256
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
2257
|
+
/* @__PURE__ */ jsx24("strong", { children: Object.keys(rowSelection).length }),
|
|
2258
|
+
" rows selected",
|
|
2259
|
+
table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ jsxs11("span", { className: "opacity-80", children: [
|
|
2260
|
+
" / ",
|
|
2261
|
+
table.getFilteredRowModel().rows.length,
|
|
2262
|
+
" total"
|
|
2263
|
+
] })
|
|
2264
|
+
] }),
|
|
2265
|
+
/* @__PURE__ */ jsx24(
|
|
2266
|
+
"button",
|
|
2267
|
+
{
|
|
2268
|
+
type: "button",
|
|
2269
|
+
onClick: () => handleRowSelectionChange({}),
|
|
2270
|
+
className: "ml-auto text-xs hover:opacity-80 underline underline-offset-2",
|
|
2271
|
+
children: "Clear selection"
|
|
2272
|
+
}
|
|
2273
|
+
)
|
|
2274
|
+
] }),
|
|
2275
|
+
/* @__PURE__ */ jsx24("div", { className: "rounded-md border border-[hsl(var(--lux-table-border))] bg-[hsl(var(--lux-table-background))] overflow-hidden", children: /* @__PURE__ */ jsxs11(Table, { children: [
|
|
2276
|
+
/* @__PURE__ */ jsxs11(TableHeader, { children: [
|
|
2277
|
+
table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx24(TableRow, { children: headerGroup.headers.map((header) => {
|
|
2278
|
+
const isSelectionColumn = header.id === "__selection__";
|
|
2279
|
+
return /* @__PURE__ */ jsx24(
|
|
2280
|
+
TableHead,
|
|
2281
|
+
{
|
|
2282
|
+
style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
|
|
2283
|
+
children: header.isPlaceholder ? null : isSelectionColumn ? flexRender2(
|
|
2284
|
+
header.column.columnDef.header,
|
|
2285
|
+
header.getContext()
|
|
2286
|
+
) : /* @__PURE__ */ jsx24(
|
|
2287
|
+
SortableHeader,
|
|
2288
|
+
{
|
|
2289
|
+
header,
|
|
2290
|
+
showSortIndex: enableMultiSort && sorting.length > 1
|
|
2291
|
+
}
|
|
2292
|
+
)
|
|
2293
|
+
},
|
|
2294
|
+
header.id
|
|
2295
|
+
);
|
|
2296
|
+
}) }, headerGroup.id)),
|
|
2297
|
+
filteringVisible && /* @__PURE__ */ jsx24(TableRow, { className: "bg-[hsl(var(--lux-filter-background))]", children: table.getHeaderGroups()[0]?.headers.map((header) => {
|
|
2298
|
+
const isSelectionColumn = header.id === "__selection__";
|
|
2299
|
+
return /* @__PURE__ */ jsx24(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ jsx24(ColumnFilter, { column: header.column, data }) : null }, `filter-${header.id}`);
|
|
2300
|
+
}) })
|
|
2301
|
+
] }),
|
|
2302
|
+
/* @__PURE__ */ jsx24(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx24(
|
|
2303
|
+
TableRow,
|
|
2304
|
+
{
|
|
2305
|
+
"data-state": row.getIsSelected() && "selected",
|
|
2306
|
+
className: cn(
|
|
2307
|
+
enableRowSelection && "cursor-pointer",
|
|
2308
|
+
row.getIsSelected() && "bg-[hsl(var(--lux-selection-background))]"
|
|
2309
|
+
),
|
|
2310
|
+
onClick: enableRowSelection && !showCheckbox ? () => {
|
|
2311
|
+
if (selectionMode === "single") {
|
|
2312
|
+
handleRowSelectionChange({ [row.id]: true });
|
|
2313
|
+
} else {
|
|
2314
|
+
row.toggleSelected();
|
|
2315
|
+
}
|
|
2316
|
+
} : void 0,
|
|
2317
|
+
children: row.getVisibleCells().map((cell) => {
|
|
2318
|
+
const isSelectionColumn = cell.column.id === "__selection__";
|
|
2319
|
+
return /* @__PURE__ */ jsx24(
|
|
2320
|
+
TableCell,
|
|
2321
|
+
{
|
|
2322
|
+
style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
|
|
2323
|
+
onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
|
|
2324
|
+
children: flexRender2(cell.column.columnDef.cell, cell.getContext())
|
|
2325
|
+
},
|
|
2326
|
+
cell.id
|
|
2327
|
+
);
|
|
2328
|
+
})
|
|
2329
|
+
},
|
|
2330
|
+
row.id
|
|
2331
|
+
)) : /* @__PURE__ */ jsx24(TableRow, { children: /* @__PURE__ */ jsx24(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
|
|
2332
|
+
] }) }),
|
|
2333
|
+
options?.pagination && /* @__PURE__ */ jsx24(TablePagination, { table })
|
|
2334
|
+
] });
|
|
1566
2335
|
}
|
|
1567
2336
|
|
|
2337
|
+
// src/components/ui/label.tsx
|
|
2338
|
+
import * as React11 from "react";
|
|
2339
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
2340
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
2341
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2342
|
+
var labelVariants = cva2(
|
|
2343
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
2344
|
+
);
|
|
2345
|
+
var Label3 = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
2346
|
+
LabelPrimitive.Root,
|
|
2347
|
+
{
|
|
2348
|
+
ref,
|
|
2349
|
+
className: cn(labelVariants(), className),
|
|
2350
|
+
...props
|
|
2351
|
+
}
|
|
2352
|
+
));
|
|
2353
|
+
Label3.displayName = LabelPrimitive.Root.displayName;
|
|
2354
|
+
|
|
2355
|
+
// src/components/ui/separator.tsx
|
|
2356
|
+
import * as React12 from "react";
|
|
2357
|
+
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
2358
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2359
|
+
var Separator3 = React12.forwardRef(
|
|
2360
|
+
({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx26(
|
|
2361
|
+
SeparatorPrimitive.Root,
|
|
2362
|
+
{
|
|
2363
|
+
ref,
|
|
2364
|
+
decorative,
|
|
2365
|
+
orientation,
|
|
2366
|
+
className: cn(
|
|
2367
|
+
"shrink-0 bg-border",
|
|
2368
|
+
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
2369
|
+
className
|
|
2370
|
+
),
|
|
2371
|
+
...props
|
|
2372
|
+
}
|
|
2373
|
+
)
|
|
2374
|
+
);
|
|
2375
|
+
Separator3.displayName = SeparatorPrimitive.Root.displayName;
|
|
2376
|
+
|
|
1568
2377
|
// src/index.ts
|
|
1569
2378
|
import {
|
|
1570
2379
|
flexRender as flexRender3,
|
|
@@ -1633,10 +2442,13 @@ export {
|
|
|
1633
2442
|
createColumnHelper,
|
|
1634
2443
|
createColumnsFromData,
|
|
1635
2444
|
createCopyableCell,
|
|
2445
|
+
defaultGlobalCellConfig,
|
|
1636
2446
|
defaultStatusColors,
|
|
1637
2447
|
flexRender3 as flexRender,
|
|
1638
2448
|
getCoreRowModel2 as getCoreRowModel,
|
|
2449
|
+
getFieldConfig,
|
|
1639
2450
|
getFilteredRowModel2 as getFilteredRowModel,
|
|
1640
2451
|
getPaginationRowModel2 as getPaginationRowModel,
|
|
1641
|
-
getSortedRowModel2 as getSortedRowModel
|
|
2452
|
+
getSortedRowModel2 as getSortedRowModel,
|
|
2453
|
+
renderCell
|
|
1642
2454
|
};
|