gridular 2.2.0 → 3.0.0

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.
Files changed (38) hide show
  1. package/README.md +88 -107
  2. package/dist/DataGrid.d.ts +3 -0
  3. package/dist/Pagination.d.ts +12 -0
  4. package/dist/__tests__/DataGrid.test.d.ts +1 -0
  5. package/dist/__tests__/setup.d.ts +0 -0
  6. package/dist/__tests__/utils.d.ts +17 -0
  7. package/dist/components/ColumnManager.d.ts +13 -0
  8. package/dist/components/GroupManager.d.ts +11 -0
  9. package/dist/components/Skeleton.d.ts +7 -0
  10. package/dist/gridular.css +1 -0
  11. package/dist/hooks/useDataGrouping.d.ts +14 -0
  12. package/dist/hooks/useGridPersistence.d.ts +12 -0
  13. package/dist/hooks/useSelectCell.d.ts +10 -0
  14. package/dist/index.d.ts +11 -797
  15. package/dist/lib/utils.d.ts +21 -0
  16. package/dist/logo.svg +26 -0
  17. package/dist/stories/customization/CustomRendering.stories.d.ts +8 -0
  18. package/dist/stories/customization/Themes.stories.d.ts +8 -0
  19. package/dist/stories/examples/BasicExample.stories.d.ts +9 -0
  20. package/dist/stories/examples/ComprehensiveDemo.stories.d.ts +6 -0
  21. package/dist/stories/examples/Pagination.stories.d.ts +6 -0
  22. package/dist/stories/examples/ServerPagination.stories.d.ts +8 -0
  23. package/dist/stories/examples/Sorting.stories.d.ts +7 -0
  24. package/dist/stories/features/CellSelection.stories.d.ts +6 -0
  25. package/dist/stories/features/ColumnFiltering.stories.d.ts +25 -0
  26. package/dist/stories/features/ColumnManagement.stories.d.ts +9 -0
  27. package/dist/stories/features/ColumnMenu.stories.d.ts +33 -0
  28. package/dist/stories/features/ContextMenu.stories.d.ts +15 -0
  29. package/dist/stories/features/ExpandableRows.stories.d.ts +7 -0
  30. package/dist/stories/features/Grouping.stories.d.ts +8 -0
  31. package/dist/stories/features/RowSelection.stories.d.ts +9 -0
  32. package/dist/types.d.ts +278 -0
  33. package/dist/virtualized-grid.js +8915 -0
  34. package/package.json +71 -80
  35. package/LICENSE +0 -21
  36. package/dist/index.d.mts +0 -797
  37. package/dist/index.js +0 -2866
  38. package/dist/index.mjs +0 -2766
package/dist/index.mjs DELETED
@@ -1,2766 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __objRest = (source, exclude) => {
21
- var target = {};
22
- for (var prop in source)
23
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
- target[prop] = source[prop];
25
- if (source != null && __getOwnPropSymbols)
26
- for (var prop of __getOwnPropSymbols(source)) {
27
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
- target[prop] = source[prop];
29
- }
30
- return target;
31
- };
32
-
33
- // components/data-grid/data-grid.tsx
34
- import React15, { useState as useState6, useRef, useEffect as useEffect3, useMemo as useMemo3 } from "react";
35
-
36
- // lib/utils.ts
37
- import { clsx } from "clsx";
38
- import { twMerge } from "tailwind-merge";
39
- function cn(...inputs) {
40
- return twMerge(clsx(inputs));
41
- }
42
- function mergeStyles(tssStyles, tailwindClasses) {
43
- const tailwindClassString = Array.isArray(tailwindClasses) ? tailwindClasses.join(" ") : tailwindClasses;
44
- if (!tssStyles) {
45
- return { className: tailwindClassString };
46
- }
47
- const _a = tssStyles, { className: tssClassName } = _a, otherStyles = __objRest(_a, ["className"]);
48
- const mergedClassName = tssClassName ? cn(tssClassName, tailwindClassString) : tailwindClassString;
49
- return __spreadProps(__spreadValues({}, otherStyles), {
50
- className: mergedClassName
51
- });
52
- }
53
-
54
- // components/data-grid/table-header.tsx
55
- import React3, { useState as useState3 } from "react";
56
-
57
- // components/data-grid/filter-menu.tsx
58
- import React2, { useState as useState2, useEffect } from "react";
59
-
60
- // components/theme-provider/theme-provider.tsx
61
- import React, { createContext, useContext, useMemo, useState } from "react";
62
- import { createMakeStyles } from "tss-react";
63
- var lightTheme = {
64
- colors: {
65
- primary: "#536976",
66
- // Logo slate - sophisticated primary
67
- secondary: "#BBD2C5",
68
- // Logo sage - elegant accent
69
- background: "#fafbfc",
70
- // Slightly off-white
71
- foreground: "#292E49",
72
- // Logo navy - strong text
73
- muted: "rgba(187, 210, 197, 0.08)",
74
- // Subtle sage tint
75
- mutedForeground: "#536976",
76
- // Logo slate for muted text
77
- border: "rgba(83, 105, 118, 0.2)",
78
- // Transparent slate
79
- popover: "#ffffff",
80
- accent: "#BBD2C5"
81
- // Logo sage
82
- }
83
- };
84
- var darkTheme = {
85
- colors: {
86
- primary: "#BBD2C5",
87
- // Logo sage - glowing primary in dark
88
- secondary: "#536976",
89
- // Logo slate
90
- background: "#0a0b0d",
91
- // Deep technical black
92
- foreground: "#e8eaed",
93
- // Technical pearl
94
- muted: "rgba(41, 46, 73, 0.3)",
95
- // Logo navy transparency
96
- mutedForeground: "#a8abb2",
97
- // Technical silver
98
- border: "rgba(83, 105, 118, 0.25)",
99
- // Transparent slate
100
- popover: "rgba(26, 28, 32, 0.95)",
101
- // Semi-transparent charcoal
102
- accent: "#BBD2C5"
103
- // Logo sage
104
- }
105
- };
106
- var defaultTailwindTheme = {
107
- container: "bg-background border border-border/30 rounded-lg overflow-hidden shadow-sm",
108
- header: "bg-muted/50 border-b border-border/40 backdrop-blur-sm",
109
- headerCell: "text-foreground font-semibold px-4 py-3.5 text-sm font-sans tracking-tight border-r border-border/20 last:border-r-0 relative",
110
- row: "border-b border-border/30 hover:bg-primary/5 transition-colors duration-200 group",
111
- cell: "px-4 py-3 text-sm font-sans text-foreground/90",
112
- pagination: "bg-background/50 border-t border-border/30 px-4 py-3 flex justify-between items-center font-sans text-sm",
113
- filterMenu: "bg-popover border border-border/40 shadow-lg rounded-lg backdrop-blur-xl",
114
- filterMenuContent: "p-4 space-y-3",
115
- filterMenuHeader: "font-semibold mb-3 text-sm font-sans border-b border-border/30 pb-2",
116
- filterMenuInput: "font-sans text-sm",
117
- filterMenuClearButton: "font-sans text-sm font-medium",
118
- filterMenuApplyButton: "font-sans text-sm font-semibold",
119
- columnResizeHandle: "w-[3px] bg-border/40 hover:bg-primary cursor-col-resize h-full absolute right-0 top-0 transition-all duration-200 opacity-0 group-hover:opacity-100",
120
- columnResizeHandleActive: "bg-primary opacity-100 w-[3px]",
121
- sortIcon: "text-muted-foreground transition-all duration-200",
122
- sortIconActive: "text-primary"
123
- };
124
- var createSpacingFunction = (baseSpacing = 4) => {
125
- const spacingFn = (...args) => {
126
- if (args.length === 0) return "0";
127
- return args.map((factor) => factor === 0 ? "0" : `${factor * baseSpacing}px`).join(" ");
128
- };
129
- spacingFn.baseSpacing = baseSpacing;
130
- return spacingFn;
131
- };
132
- var defaultTssTheme = {
133
- colors: {
134
- primary: "#2563eb",
135
- // blue-600
136
- secondary: "#6b7280",
137
- // gray-500
138
- background: "#ffffff",
139
- foreground: "#020617",
140
- // slate-950
141
- muted: "#f1f5f9",
142
- // slate-100
143
- mutedForeground: "#64748b",
144
- // slate-500
145
- border: "#e2e8f0"
146
- // slate-200
147
- },
148
- spacing: createSpacingFunction(4)
149
- };
150
- var defaultUnifiedTheme = {
151
- classes: defaultTailwindTheme,
152
- colors: defaultTssTheme.colors,
153
- spacing: defaultTssTheme.spacing
154
- };
155
- var ThemeContext = createContext({
156
- theme: defaultUnifiedTheme,
157
- setTailwindTheme: () => {
158
- },
159
- setTssTheme: () => {
160
- },
161
- resetTheme: () => {
162
- },
163
- toggleThemeMode: () => {
164
- }
165
- // Add default no-op implementation
166
- });
167
- var ThemeProvider = ({
168
- children,
169
- initialTailwindTheme = {},
170
- initialTssTheme = {},
171
- darkMode = false
172
- }) => {
173
- const baseTheme = darkMode ? darkTheme : lightTheme;
174
- const [tailwindTheme, setTailwindThemeState] = useState(initialTailwindTheme);
175
- const [tssTheme, setTssThemeState] = useState(() => {
176
- const _a = initialTssTheme, { spacing } = _a, rest = __objRest(_a, ["spacing"]);
177
- const processedSpacing = spacing !== void 0 ? typeof spacing === "number" ? createSpacingFunction(spacing) : spacing : void 0;
178
- return __spreadValues(__spreadValues(__spreadValues({}, baseTheme), rest), processedSpacing && { spacing: processedSpacing });
179
- });
180
- const setTailwindTheme = (newTheme) => {
181
- setTailwindThemeState((prev) => __spreadValues(__spreadValues({}, prev), newTheme));
182
- };
183
- const setTssTheme = (newTheme) => {
184
- setTssThemeState((prev) => {
185
- const updatedTheme = __spreadValues({}, prev);
186
- if (newTheme.colors) {
187
- updatedTheme.colors = __spreadValues(__spreadValues({}, prev.colors || {}), newTheme.colors);
188
- }
189
- if (newTheme.spacing !== void 0) {
190
- if (typeof newTheme.spacing === "number") {
191
- updatedTheme.spacing = createSpacingFunction(newTheme.spacing);
192
- } else {
193
- updatedTheme.spacing = newTheme.spacing;
194
- }
195
- }
196
- const otherKeys = Object.keys(newTheme).filter(
197
- (key) => key !== "colors" && key !== "spacing"
198
- );
199
- otherKeys.forEach((key) => {
200
- updatedTheme[key] = newTheme[key];
201
- });
202
- return updatedTheme;
203
- });
204
- };
205
- const resetTheme = () => {
206
- setTailwindThemeState(initialTailwindTheme);
207
- setTssThemeState(() => {
208
- const _a = initialTssTheme, { spacing } = _a, rest = __objRest(_a, ["spacing"]);
209
- const processedSpacing = spacing !== void 0 ? typeof spacing === "number" ? createSpacingFunction(spacing) : spacing : void 0;
210
- return __spreadValues(__spreadValues(__spreadValues({}, baseTheme), rest), processedSpacing && { spacing: processedSpacing });
211
- });
212
- };
213
- const toggleThemeMode = () => {
214
- setTssThemeState((prev) => {
215
- var _a, _b;
216
- const isDarkMode = ((_a = prev.colors) == null ? void 0 : _a.background) === ((_b = darkTheme.colors) == null ? void 0 : _b.background);
217
- const newBaseTheme = isDarkMode ? lightTheme : darkTheme;
218
- return __spreadProps(__spreadValues({}, prev), {
219
- colors: __spreadValues(__spreadValues({}, newBaseTheme.colors), Object.fromEntries(
220
- Object.entries(prev.colors || {}).filter(
221
- ([key]) => !(key in newBaseTheme.colors)
222
- )
223
- ))
224
- });
225
- });
226
- setTailwindThemeState((prev) => {
227
- var _a, _b;
228
- const isDarkMode = ((_a = tssTheme.colors) == null ? void 0 : _a.background) === ((_b = darkTheme.colors) == null ? void 0 : _b.background);
229
- const rowClass = isDarkMode ? "border-b border-border hover:bg-muted/30 transition-colors" : "border-b border-border hover:bg-muted/50 transition-colors";
230
- return __spreadProps(__spreadValues({}, prev), {
231
- row: rowClass
232
- // Other class adjustments as needed
233
- });
234
- });
235
- };
236
- const value = useMemo(() => {
237
- const mergedTailwindTheme = Object.keys(defaultTailwindTheme).reduce(
238
- (acc, key) => {
239
- const k = key;
240
- acc[k] = tailwindTheme[k] !== void 0 ? cn(defaultTailwindTheme[k], tailwindTheme[k]) : defaultTailwindTheme[k];
241
- return acc;
242
- },
243
- {}
244
- );
245
- const mergedTssTheme = {
246
- colors: __spreadValues(__spreadValues({}, defaultTssTheme.colors), tssTheme.colors || {}),
247
- spacing: tssTheme.spacing || defaultTssTheme.spacing
248
- };
249
- const otherKeys = Object.keys(tssTheme).filter(
250
- (key) => key !== "colors" && key !== "spacing"
251
- );
252
- const extraProperties = {};
253
- otherKeys.forEach((key) => {
254
- extraProperties[key] = tssTheme[key];
255
- });
256
- const unifiedTheme = __spreadValues({
257
- classes: mergedTailwindTheme,
258
- colors: mergedTssTheme.colors,
259
- spacing: mergedTssTheme.spacing
260
- }, extraProperties);
261
- return {
262
- theme: unifiedTheme,
263
- setTailwindTheme,
264
- setTssTheme,
265
- resetTheme,
266
- toggleThemeMode
267
- // Include the new toggle function
268
- };
269
- }, [tailwindTheme, tssTheme]);
270
- return /* @__PURE__ */ React.createElement(ThemeContext.Provider, { value }, children);
271
- };
272
- var useTheme = () => useContext(ThemeContext);
273
- var useTailwindTheme = () => useTheme().theme.classes;
274
- var useTssTheme = () => ({
275
- colors: useTheme().theme.colors,
276
- spacing: useTheme().theme.spacing
277
- });
278
- var { makeStyles, useStyles: useTssStyles } = createMakeStyles({
279
- useTheme: () => useTssTheme()
280
- });
281
- var useStyles = (stylesFn) => {
282
- const { css, cx } = useTssStyles();
283
- const styles = {};
284
- const styleObj = stylesFn(useTssTheme());
285
- Object.entries(styleObj).forEach(([key, value]) => {
286
- styles[key] = css(value);
287
- });
288
- return { styles, cx };
289
- };
290
-
291
- // components/data-grid/filter-menu.tsx
292
- var FilterMenu = ({
293
- column,
294
- filterValue,
295
- setFilterValue,
296
- onApplyFilter,
297
- onClearFilter,
298
- isOpen,
299
- onOpenChange,
300
- trigger,
301
- isActive = false,
302
- classes = {},
303
- renderHeader,
304
- renderCurrentFilter,
305
- renderInput,
306
- renderButtons,
307
- renderCustomContent,
308
- totalColumns = 1
309
- }) => {
310
- const { theme } = useTheme();
311
- const [localFilterValue, setLocalFilterValue] = useState2(filterValue);
312
- const menuRef = React2.useRef(null);
313
- useEffect(() => {
314
- setLocalFilterValue(filterValue);
315
- }, [filterValue]);
316
- useEffect(() => {
317
- if (isOpen) {
318
- setLocalFilterValue(filterValue);
319
- }
320
- }, [isOpen, filterValue]);
321
- const handleApplyFilter = () => {
322
- setFilterValue(localFilterValue);
323
- onApplyFilter(localFilterValue);
324
- onOpenChange(false);
325
- };
326
- const handleClearFilter = () => {
327
- setLocalFilterValue("");
328
- onClearFilter();
329
- onOpenChange(false);
330
- };
331
- const handleKeyDown = (e) => {
332
- if (e.key === "Enter") {
333
- handleApplyFilter();
334
- } else if (e.key === "Escape") {
335
- onOpenChange(false);
336
- }
337
- };
338
- if (!isOpen) {
339
- return /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement("div", { onClick: () => onOpenChange(true) }, trigger), isActive && /* @__PURE__ */ React2.createElement("div", { className: "absolute -top-1 -right-1 w-3 h-3 bg-primary rounded-full text-[10px] flex items-center justify-center text-primary-foreground" }, "\u2022"));
340
- }
341
- const menuContent = /* @__PURE__ */ React2.createElement("div", { className: cn("p-4", theme.classes.filterMenuContent) }, /* @__PURE__ */ React2.createElement(
342
- "div",
343
- {
344
- className: cn(
345
- "font-semibold mb-3 text-sm text-gray-700 dark:text-gray-200",
346
- theme.classes.filterMenuHeader,
347
- classes.header
348
- )
349
- },
350
- renderHeader ? renderHeader(column, isActive) : /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React2.createElement("span", null, "Filter: ", column.header), isActive && /* @__PURE__ */ React2.createElement(
351
- "span",
352
- {
353
- className: cn(
354
- "ml-2 text-xs px-2 py-0.5 rounded-full bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-200",
355
- classes.activeIndicator
356
- )
357
- },
358
- "Active"
359
- ))
360
- ), isActive && filterValue && /* @__PURE__ */ React2.createElement("div", { className: "mb-3" }, renderCurrentFilter ? renderCurrentFilter(filterValue) : /* @__PURE__ */ React2.createElement(
361
- "div",
362
- {
363
- className: cn(
364
- "text-xs bg-gray-50 dark:bg-gray-800 p-2 rounded border border-gray-200 dark:border-gray-700",
365
- classes.currentFilter
366
- )
367
- },
368
- "Current: ",
369
- /* @__PURE__ */ React2.createElement("strong", { className: "font-semibold" }, filterValue)
370
- )), renderInput ? renderInput({
371
- value: localFilterValue,
372
- onChange: setLocalFilterValue,
373
- onKeyDown: handleKeyDown,
374
- isActive
375
- }) : /* @__PURE__ */ React2.createElement(
376
- "input",
377
- {
378
- type: "text",
379
- value: localFilterValue,
380
- onChange: (e) => setLocalFilterValue(e.target.value),
381
- onKeyDown: handleKeyDown,
382
- className: cn(
383
- "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md",
384
- "focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",
385
- "bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",
386
- "placeholder-gray-400 dark:placeholder-gray-500",
387
- theme.classes.filterMenuInput,
388
- classes.input
389
- ),
390
- placeholder: "Filter value...",
391
- autoFocus: true
392
- }
393
- ), renderButtons ? renderButtons({
394
- onClear: handleClearFilter,
395
- onApply: handleApplyFilter,
396
- isActive
397
- }) : /* @__PURE__ */ React2.createElement(
398
- "div",
399
- {
400
- className: cn(
401
- "flex justify-end mt-3 gap-2",
402
- classes.buttonContainer
403
- )
404
- },
405
- /* @__PURE__ */ React2.createElement(
406
- "button",
407
- {
408
- onClick: handleClearFilter,
409
- className: cn(
410
- "px-4 py-2 text-sm font-medium rounded-md border border-gray-300 dark:border-gray-600",
411
- "hover:bg-gray-50 dark:hover:bg-gray-800",
412
- "text-gray-700 dark:text-gray-200",
413
- "transition-colors",
414
- theme.classes.filterMenuClearButton,
415
- classes.clearButton
416
- )
417
- },
418
- "Clear"
419
- ),
420
- /* @__PURE__ */ React2.createElement(
421
- "button",
422
- {
423
- onClick: handleApplyFilter,
424
- className: cn(
425
- "px-4 py-2 text-sm font-medium rounded-md",
426
- "bg-blue-600 hover:bg-blue-700 text-white",
427
- "transition-colors",
428
- theme.classes.filterMenuApplyButton,
429
- classes.applyButton
430
- )
431
- },
432
- "Apply"
433
- )
434
- ));
435
- if (renderCustomContent) {
436
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", null, trigger), /* @__PURE__ */ React2.createElement(
437
- "div",
438
- {
439
- ref: menuRef,
440
- className: cn(
441
- "absolute top-full left-0 z-50 mt-2 min-w-[280px]",
442
- "bg-white dark:bg-gray-900",
443
- "border border-gray-200 dark:border-gray-700",
444
- "rounded-lg shadow-xl",
445
- "backdrop-blur-sm",
446
- theme.classes.filterMenu,
447
- classes.container,
448
- column.index === totalColumns - 1 && "right-0 left-auto"
449
- )
450
- },
451
- renderCustomContent({
452
- column,
453
- filterValue: localFilterValue,
454
- setFilterValue: setLocalFilterValue,
455
- onApply: handleApplyFilter,
456
- onClear: handleClearFilter,
457
- isActive
458
- })
459
- ));
460
- }
461
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", null, trigger), /* @__PURE__ */ React2.createElement(
462
- "div",
463
- {
464
- ref: menuRef,
465
- className: cn(
466
- "absolute top-full left-0 z-50 mt-2 min-w-[280px]",
467
- "bg-white dark:bg-gray-900",
468
- "border border-gray-200 dark:border-gray-700",
469
- "rounded-lg shadow-xl",
470
- "backdrop-blur-sm",
471
- theme.classes.filterMenu,
472
- classes.container,
473
- column.index === totalColumns - 1 && "right-0 left-auto"
474
- )
475
- },
476
- menuContent
477
- ));
478
- };
479
-
480
- // components/data-grid/table-header.tsx
481
- import {
482
- ArrowDown,
483
- ArrowUp,
484
- ChevronDown,
485
- ChevronUp,
486
- Filter
487
- } from "lucide-react";
488
- function TableHeader({
489
- columns,
490
- sortState,
491
- onSortChange,
492
- enableSorting,
493
- filterState,
494
- filterMenuOpen,
495
- onFilterMenuToggle,
496
- columnWidths,
497
- onColumnResize,
498
- headerClassName,
499
- filterValueRefs,
500
- onApplyFilter,
501
- onClearFilter,
502
- onColumnReorder,
503
- renderHeader = void 0,
504
- renderSortIcon,
505
- renderFilterIcon,
506
- sortIconVariant = "arrows",
507
- filterMenu,
508
- filterMenuRef
509
- }) {
510
- const { theme } = useTheme();
511
- const [draggedColumn, setDraggedColumn] = useState3(null);
512
- const [dragOverColumn, setDragOverColumn] = useState3(null);
513
- const handleColumnResizeStart = (columnId, e) => {
514
- e.preventDefault();
515
- const startX = e.clientX;
516
- const startWidth = columnWidths[columnId] || 150;
517
- const handleMouseMove = (moveEvent) => {
518
- const deltaX = moveEvent.clientX - startX;
519
- const newWidth = Math.max(50, startWidth + deltaX);
520
- onColumnResize(columnId, newWidth);
521
- };
522
- const handleMouseUp = () => {
523
- document.removeEventListener("mousemove", handleMouseMove);
524
- document.removeEventListener("mouseup", handleMouseUp);
525
- };
526
- document.addEventListener("mousemove", handleMouseMove);
527
- document.addEventListener("mouseup", handleMouseUp);
528
- };
529
- const handleDragStart = (e, columnId) => {
530
- e.dataTransfer.setData("text/plain", columnId);
531
- e.dataTransfer.effectAllowed = "move";
532
- setDraggedColumn(columnId);
533
- };
534
- const handleDragOver = (e, columnId) => {
535
- e.preventDefault();
536
- e.dataTransfer.dropEffect = "move";
537
- if (draggedColumn && draggedColumn !== columnId) {
538
- setDragOverColumn(columnId);
539
- }
540
- };
541
- const handleDragEnter = (e) => {
542
- e.preventDefault();
543
- };
544
- const handleDragLeave = () => {
545
- setDragOverColumn(null);
546
- };
547
- const handleDrop = (e, targetId) => {
548
- e.preventDefault();
549
- const sourceId = e.dataTransfer.getData("text/plain");
550
- if (sourceId && targetId && sourceId !== targetId) {
551
- onColumnReorder(sourceId, targetId);
552
- }
553
- setDraggedColumn(null);
554
- setDragOverColumn(null);
555
- };
556
- const handleDragEnd = () => {
557
- setDraggedColumn(null);
558
- setDragOverColumn(null);
559
- };
560
- const defaultSortIcon = (column, sortDirection) => {
561
- if (!sortDirection) return null;
562
- if (sortIconVariant === "none") return null;
563
- if (sortIconVariant === "chevrons") {
564
- return sortDirection === "asc" ? /* @__PURE__ */ React3.createElement(ChevronUp, { className: "ml-1 h-3 w-3 text-primary" }) : /* @__PURE__ */ React3.createElement(ChevronDown, { className: "ml-1 h-3 w-3 text-primary" });
565
- }
566
- return sortDirection === "asc" ? /* @__PURE__ */ React3.createElement(ArrowUp, { className: "ml-1 h-3 w-3 text-primary" }) : /* @__PURE__ */ React3.createElement(ArrowDown, { className: "ml-1 h-3 w-3 text-primary" });
567
- };
568
- const defaultFilterIcon = (column, isActive) => {
569
- return /* @__PURE__ */ React3.createElement(
570
- Filter,
571
- {
572
- className: cn(
573
- "h-3.5 w-3.5 transition-colors",
574
- isActive ? "text-blue-500 fill-blue-100" : "text-gray-400 hover:text-gray-600"
575
- )
576
- }
577
- );
578
- };
579
- console.info(!!renderSortIcon);
580
- return /* @__PURE__ */ React3.createElement("thead", null, /* @__PURE__ */ React3.createElement("tr", { className: cn(theme.classes.header, headerClassName) }, columns.map((column, index) => {
581
- column = __spreadProps(__spreadValues({}, column), { index });
582
- const sortDirection = sortState && sortState.column === column.id ? sortState.direction : null;
583
- const hasActiveFilter = !!(filterState == null ? void 0 : filterState[column.id]);
584
- const width = columnWidths[column.id] || column.width || 150;
585
- return /* @__PURE__ */ React3.createElement(
586
- "th",
587
- {
588
- key: column.id,
589
- className: cn(
590
- theme.classes.headerCell,
591
- column.headerClassName,
592
- dragOverColumn === column.id && "bg-primary/10"
593
- ),
594
- style: {
595
- width: `${width}px`,
596
- minWidth: `${width}px`,
597
- maxWidth: `${width}px`,
598
- position: "relative"
599
- },
600
- draggable: true,
601
- onDragStart: (e) => handleDragStart(e, column.id),
602
- onDragOver: (e) => handleDragOver(e, column.id),
603
- onDragEnter: handleDragEnter,
604
- onDragLeave: handleDragLeave,
605
- onDrop: (e) => handleDrop(e, column.id),
606
- onDragEnd: handleDragEnd,
607
- role: "columnheader",
608
- "aria-label": column.header
609
- },
610
- /* @__PURE__ */ React3.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React3.createElement(
611
- "div",
612
- {
613
- className: cn(
614
- "cursor-pointer flex items-center",
615
- enableSorting && column.enableSorting !== false && "hover:text-foreground"
616
- ),
617
- onClick: () => {
618
- if (enableSorting && column.enableSorting !== false) {
619
- onSortChange(column.id);
620
- }
621
- }
622
- },
623
- renderHeader ? renderHeader(column, sortDirection) : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", null, column.header), enableSorting && column.enableSorting !== false && /* @__PURE__ */ React3.createElement(React3.Fragment, null, sortDirection && /* @__PURE__ */ React3.createElement("span", { className: "inline-flex ml-1", role: "img" }, renderSortIcon ? renderSortIcon(column, sortDirection) : defaultSortIcon(column, sortDirection))))
624
- ), column.enableFiltering !== false && /* @__PURE__ */ React3.createElement(
625
- "div",
626
- {
627
- className: "flex items-center",
628
- ref: filterMenuOpen === column.id ? filterMenuRef : null
629
- },
630
- /* @__PURE__ */ React3.createElement(
631
- FilterMenu,
632
- __spreadValues({
633
- column: __spreadProps(__spreadValues({}, column), { index }),
634
- totalColumns: columns.length,
635
- filterValue: filterValueRefs.current[column.id] || "",
636
- setFilterValue: (value) => {
637
- filterValueRefs.current[column.id] = value;
638
- },
639
- onApplyFilter,
640
- onClearFilter,
641
- isOpen: filterMenuOpen === column.id,
642
- onOpenChange: (open) => {
643
- onFilterMenuToggle(open ? column.id : null);
644
- },
645
- isActive: hasActiveFilter,
646
- trigger: /* @__PURE__ */ React3.createElement(
647
- "button",
648
- {
649
- onClick: (e) => {
650
- e.stopPropagation();
651
- onFilterMenuToggle(
652
- filterMenuOpen === column.id ? null : column.id
653
- );
654
- },
655
- className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1"
656
- },
657
- renderFilterIcon ? renderFilterIcon(column, hasActiveFilter) : defaultFilterIcon(column, hasActiveFilter)
658
- )
659
- }, filterMenu)
660
- )
661
- )),
662
- column.enableResize !== false && /* @__PURE__ */ React3.createElement(
663
- "div",
664
- {
665
- className: cn(theme.classes.columnResizeHandle),
666
- onMouseDown: (e) => handleColumnResizeStart(column.id, e)
667
- }
668
- )
669
- );
670
- })));
671
- }
672
-
673
- // components/data-grid/table-body.tsx
674
- import React9 from "react";
675
-
676
- // components/data-grid/group-row.tsx
677
- import React4 from "react";
678
- import { ChevronRight, ChevronDown as ChevronDown2 } from "lucide-react";
679
- function GroupRow({
680
- columnId,
681
- value,
682
- depth,
683
- isExpanded,
684
- onToggleExpand,
685
- count,
686
- columns,
687
- groupKey,
688
- formatter,
689
- renderGroupRow,
690
- expandIcon,
691
- collapseIcon,
692
- // Style props
693
- className,
694
- rowClassName,
695
- cellClassName,
696
- contentClassName,
697
- labelClassName,
698
- iconClassName,
699
- countClassName,
700
- indentSize = 16,
701
- // Style objects
702
- style,
703
- rowStyle,
704
- cellStyle,
705
- contentStyle
706
- }) {
707
- const formattedValue = formatter ? formatter(value) : value;
708
- const displayValue = value === null || value === void 0 ? "(empty)" : formattedValue;
709
- if (renderGroupRow) {
710
- return /* @__PURE__ */ React4.createElement(
711
- "tr",
712
- {
713
- className: cn("group-row bg-muted/30", rowClassName, className),
714
- style: __spreadValues(__spreadValues({}, rowStyle), style)
715
- },
716
- /* @__PURE__ */ React4.createElement(
717
- "td",
718
- {
719
- colSpan: columns,
720
- className: cn("p-2 border-b", cellClassName),
721
- onClick: onToggleExpand,
722
- style: __spreadValues({ cursor: "pointer" }, cellStyle)
723
- },
724
- renderGroupRow({
725
- groupKey,
726
- columnId,
727
- value,
728
- depth,
729
- isExpanded,
730
- onToggleExpand,
731
- count
732
- })
733
- )
734
- );
735
- }
736
- return /* @__PURE__ */ React4.createElement(
737
- "tr",
738
- {
739
- className: cn("group-row bg-muted/20", rowClassName, className),
740
- style: __spreadValues(__spreadValues({}, rowStyle), style)
741
- },
742
- /* @__PURE__ */ React4.createElement(
743
- "td",
744
- {
745
- colSpan: columns,
746
- className: cn("p-2 border-b", cellClassName),
747
- onClick: onToggleExpand,
748
- style: __spreadValues({ cursor: "pointer" }, cellStyle)
749
- },
750
- /* @__PURE__ */ React4.createElement(
751
- "div",
752
- {
753
- className: cn("flex items-center", contentClassName),
754
- style: contentStyle
755
- },
756
- /* @__PURE__ */ React4.createElement(
757
- "div",
758
- {
759
- style: __spreadValues({ marginLeft: `${depth * indentSize}px` }, contentStyle),
760
- className: cn("flex items-center text-sm")
761
- },
762
- /* @__PURE__ */ React4.createElement("button", { className: cn("mr-1 focus:outline-none", iconClassName) }, isExpanded ? collapseIcon || /* @__PURE__ */ React4.createElement(ChevronDown2, { className: "h-3.5 w-3.5" }) : expandIcon || /* @__PURE__ */ React4.createElement(ChevronRight, { className: "h-3.5 w-3.5" })),
763
- /* @__PURE__ */ React4.createElement("span", { className: cn(labelClassName) }, displayValue, /* @__PURE__ */ React4.createElement("span", { className: cn(countClassName) }, "(", count, ")"))
764
- )
765
- )
766
- )
767
- );
768
- }
769
-
770
- // components/data-grid/table-body.tsx
771
- import { ChevronDown as ChevronDown3, ChevronRight as ChevronRight2 } from "lucide-react";
772
-
773
- // components/data-grid/table-row.tsx
774
- import React7 from "react";
775
-
776
- // components/data-grid/table-cell.tsx
777
- import React6 from "react";
778
-
779
- // components/ui/context-menu.tsx
780
- import * as React5 from "react";
781
- import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
782
- import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
783
- function ContextMenu(_a) {
784
- var props = __objRest(_a, []);
785
- return /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.Root, __spreadValues({ "data-slot": "context-menu" }, props));
786
- }
787
- function ContextMenuTrigger(_a) {
788
- var props = __objRest(_a, []);
789
- return /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.Trigger, __spreadValues({ "data-slot": "context-menu-trigger" }, props));
790
- }
791
- function ContextMenuGroup(_a) {
792
- var props = __objRest(_a, []);
793
- return /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.Group, __spreadValues({ "data-slot": "context-menu-group" }, props));
794
- }
795
- function ContextMenuPortal(_a) {
796
- var props = __objRest(_a, []);
797
- return /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.Portal, __spreadValues({ "data-slot": "context-menu-portal" }, props));
798
- }
799
- function ContextMenuSub(_a) {
800
- var props = __objRest(_a, []);
801
- return /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.Sub, __spreadValues({ "data-slot": "context-menu-sub" }, props));
802
- }
803
- function ContextMenuRadioGroup(_a) {
804
- var props = __objRest(_a, []);
805
- return /* @__PURE__ */ React5.createElement(
806
- ContextMenuPrimitive.RadioGroup,
807
- __spreadValues({
808
- "data-slot": "context-menu-radio-group"
809
- }, props)
810
- );
811
- }
812
- function ContextMenuSubTrigger(_a) {
813
- var _b = _a, {
814
- className,
815
- inset,
816
- children
817
- } = _b, props = __objRest(_b, [
818
- "className",
819
- "inset",
820
- "children"
821
- ]);
822
- return /* @__PURE__ */ React5.createElement(
823
- ContextMenuPrimitive.SubTrigger,
824
- __spreadValues({
825
- "data-slot": "context-menu-sub-trigger",
826
- "data-inset": inset,
827
- className: cn(
828
- "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
829
- className
830
- )
831
- }, props),
832
- children,
833
- /* @__PURE__ */ React5.createElement(ChevronRightIcon, { className: "ml-auto" })
834
- );
835
- }
836
- function ContextMenuSubContent(_a) {
837
- var _b = _a, {
838
- className
839
- } = _b, props = __objRest(_b, [
840
- "className"
841
- ]);
842
- return /* @__PURE__ */ React5.createElement(
843
- ContextMenuPrimitive.SubContent,
844
- __spreadValues({
845
- "data-slot": "context-menu-sub-content",
846
- className: cn(
847
- "bg-popover text-popover-foreground 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 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
848
- className
849
- )
850
- }, props)
851
- );
852
- }
853
- function ContextMenuContent(_a) {
854
- var _b = _a, {
855
- className
856
- } = _b, props = __objRest(_b, [
857
- "className"
858
- ]);
859
- return /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.Portal, null, /* @__PURE__ */ React5.createElement(
860
- ContextMenuPrimitive.Content,
861
- __spreadValues({
862
- "data-slot": "context-menu-content",
863
- className: cn(
864
- "bg-popover text-popover-foreground 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 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
865
- className
866
- )
867
- }, props)
868
- ));
869
- }
870
- function ContextMenuItem(_a) {
871
- var _b = _a, {
872
- className,
873
- inset,
874
- variant = "default"
875
- } = _b, props = __objRest(_b, [
876
- "className",
877
- "inset",
878
- "variant"
879
- ]);
880
- return /* @__PURE__ */ React5.createElement(
881
- ContextMenuPrimitive.Item,
882
- __spreadValues({
883
- "data-slot": "context-menu-item",
884
- "data-inset": inset,
885
- "data-variant": variant,
886
- className: cn(
887
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
888
- className
889
- )
890
- }, props)
891
- );
892
- }
893
- function ContextMenuCheckboxItem(_a) {
894
- var _b = _a, {
895
- className,
896
- children,
897
- checked
898
- } = _b, props = __objRest(_b, [
899
- "className",
900
- "children",
901
- "checked"
902
- ]);
903
- return /* @__PURE__ */ React5.createElement(
904
- ContextMenuPrimitive.CheckboxItem,
905
- __spreadValues({
906
- "data-slot": "context-menu-checkbox-item",
907
- className: cn(
908
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
909
- className
910
- ),
911
- checked
912
- }, props),
913
- /* @__PURE__ */ React5.createElement("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center" }, /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.ItemIndicator, null, /* @__PURE__ */ React5.createElement(CheckIcon, { className: "size-4" }))),
914
- children
915
- );
916
- }
917
- function ContextMenuRadioItem(_a) {
918
- var _b = _a, {
919
- className,
920
- children
921
- } = _b, props = __objRest(_b, [
922
- "className",
923
- "children"
924
- ]);
925
- return /* @__PURE__ */ React5.createElement(
926
- ContextMenuPrimitive.RadioItem,
927
- __spreadValues({
928
- "data-slot": "context-menu-radio-item",
929
- className: cn(
930
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
931
- className
932
- )
933
- }, props),
934
- /* @__PURE__ */ React5.createElement("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center" }, /* @__PURE__ */ React5.createElement(ContextMenuPrimitive.ItemIndicator, null, /* @__PURE__ */ React5.createElement(CircleIcon, { className: "size-2 fill-current" }))),
935
- children
936
- );
937
- }
938
- function ContextMenuLabel(_a) {
939
- var _b = _a, {
940
- className,
941
- inset
942
- } = _b, props = __objRest(_b, [
943
- "className",
944
- "inset"
945
- ]);
946
- return /* @__PURE__ */ React5.createElement(
947
- ContextMenuPrimitive.Label,
948
- __spreadValues({
949
- "data-slot": "context-menu-label",
950
- "data-inset": inset,
951
- className: cn(
952
- "text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
953
- className
954
- )
955
- }, props)
956
- );
957
- }
958
- function ContextMenuSeparator(_a) {
959
- var _b = _a, {
960
- className
961
- } = _b, props = __objRest(_b, [
962
- "className"
963
- ]);
964
- return /* @__PURE__ */ React5.createElement(
965
- ContextMenuPrimitive.Separator,
966
- __spreadValues({
967
- "data-slot": "context-menu-separator",
968
- className: cn("bg-border -mx-1 my-1 h-px", className)
969
- }, props)
970
- );
971
- }
972
- function ContextMenuShortcut(_a) {
973
- var _b = _a, {
974
- className
975
- } = _b, props = __objRest(_b, [
976
- "className"
977
- ]);
978
- return /* @__PURE__ */ React5.createElement(
979
- "span",
980
- __spreadValues({
981
- "data-slot": "context-menu-shortcut",
982
- className: cn(
983
- "text-muted-foreground ml-auto text-xs tracking-widest",
984
- className
985
- )
986
- }, props)
987
- );
988
- }
989
-
990
- // components/data-grid/table-cell.tsx
991
- var TableCell = ({
992
- column,
993
- row,
994
- cellClassName,
995
- isSelected = false,
996
- onSelect,
997
- contextMenuContent,
998
- selectedCellClassName = "ring-2 ring-primary ring-inset",
999
- preventRowSelection = true,
1000
- enableExpandableRows = false,
1001
- isExpanded = false,
1002
- onToggleExpand,
1003
- expandIcon,
1004
- collapseIcon
1005
- }) => {
1006
- const themeClasses = useTailwindTheme();
1007
- const cellContent = column.renderCell ? column.renderCell(row) : column.cell ? column.cell(row) : row[column.id];
1008
- const content = /* @__PURE__ */ React6.createElement("div", { className: "relative z-0 flex items-center gap-2" }, enableExpandableRows && /* @__PURE__ */ React6.createElement(
1009
- "button",
1010
- {
1011
- onClick: (e) => {
1012
- e.stopPropagation();
1013
- onToggleExpand == null ? void 0 : onToggleExpand();
1014
- },
1015
- className: "p-1 rounded hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors",
1016
- "aria-label": isExpanded ? "Collapse row" : "Expand row"
1017
- },
1018
- isExpanded ? expandIcon : collapseIcon
1019
- ), /* @__PURE__ */ React6.createElement("span", { className: "flex-1" }, cellContent));
1020
- const cell = contextMenuContent ? /* @__PURE__ */ React6.createElement(
1021
- ContextMenu,
1022
- {
1023
- onOpenChange: (open) => {
1024
- if (onSelect) {
1025
- if (open) {
1026
- onSelect(true);
1027
- } else {
1028
- onSelect(false);
1029
- }
1030
- }
1031
- }
1032
- },
1033
- /* @__PURE__ */ React6.createElement(ContextMenuTrigger, { className: "flex h-full w-full" }, content),
1034
- contextMenuContent(row, column)
1035
- ) : content;
1036
- return /* @__PURE__ */ React6.createElement(
1037
- "td",
1038
- {
1039
- className: cn(
1040
- themeClasses.cell,
1041
- // Apply theme cell class
1042
- column.cellClassName,
1043
- // Apply column-specific cell class
1044
- cellClassName,
1045
- // Apply custom cell class passed as prop
1046
- // Use an approach that works with border-collapse
1047
- isSelected ? "relative after:absolute after:inset-0 after:pointer-events-none" : ""
1048
- ),
1049
- style: {
1050
- width: column.width || 150,
1051
- minWidth: column.width || 150,
1052
- maxWidth: column.width || 150,
1053
- cursor: onSelect ? "pointer" : "default"
1054
- },
1055
- onClick: (e) => {
1056
- if (onSelect) {
1057
- onSelect(!isSelected);
1058
- if (preventRowSelection) {
1059
- e.stopPropagation();
1060
- }
1061
- }
1062
- }
1063
- },
1064
- cell,
1065
- isSelected && /* @__PURE__ */ React6.createElement(
1066
- "div",
1067
- {
1068
- className: cn(
1069
- "absolute inset-0 pointer-events-none z-10",
1070
- selectedCellClassName
1071
- ),
1072
- "aria-hidden": "true"
1073
- }
1074
- )
1075
- );
1076
- };
1077
-
1078
- // components/data-grid/table-row.tsx
1079
- function TableRow({
1080
- row,
1081
- columns,
1082
- rowId,
1083
- isSelected,
1084
- onRowSelect,
1085
- onRowClick,
1086
- selectedRowClassName,
1087
- rowClassName,
1088
- cellClassName,
1089
- columnWidths,
1090
- selectedCell,
1091
- onCellSelect,
1092
- selectedCellClassName,
1093
- preventRowSelection,
1094
- contextMenuContent,
1095
- enableExpandableRows = false,
1096
- isExpanded = false,
1097
- onToggleExpand,
1098
- expandIcon,
1099
- collapseIcon
1100
- }) {
1101
- return /* @__PURE__ */ React7.createElement(
1102
- "tr",
1103
- {
1104
- className: cn(
1105
- "border-b border-border/30 hover:bg-primary/5 transition-colors duration-200 group",
1106
- isSelected && (selectedRowClassName || "bg-primary/10"),
1107
- rowClassName
1108
- ),
1109
- onClick: () => {
1110
- if (onRowSelect) {
1111
- onRowSelect();
1112
- }
1113
- if (onRowClick) {
1114
- onRowClick(row);
1115
- }
1116
- },
1117
- style: {
1118
- cursor: onRowSelect || onRowClick ? "pointer" : "default"
1119
- }
1120
- },
1121
- columns.map((column, index) => {
1122
- const isCellSelected = selectedCell && selectedCell.rowId === rowId && selectedCell.columnId === column.id;
1123
- return /* @__PURE__ */ React7.createElement(
1124
- TableCell,
1125
- {
1126
- key: `${rowId}-${column.id}`,
1127
- column: __spreadProps(__spreadValues({}, column), {
1128
- width: columnWidths[column.id] || column.width
1129
- }),
1130
- row,
1131
- cellClassName,
1132
- isSelected: !!isCellSelected,
1133
- selectedCellClassName,
1134
- onSelect: (selected) => {
1135
- if (onCellSelect) {
1136
- if (selected) {
1137
- onCellSelect(rowId, column.id);
1138
- } else {
1139
- onCellSelect("", "");
1140
- }
1141
- }
1142
- },
1143
- preventRowSelection,
1144
- contextMenuContent,
1145
- enableExpandableRows: enableExpandableRows && index === 0,
1146
- isExpanded,
1147
- onToggleExpand,
1148
- expandIcon,
1149
- collapseIcon
1150
- }
1151
- );
1152
- })
1153
- );
1154
- }
1155
-
1156
- // components/data-grid/expandable-row.tsx
1157
- import React8 from "react";
1158
- function ExpandableRow({
1159
- row,
1160
- rowId,
1161
- columns,
1162
- isExpanded,
1163
- onToggleExpand,
1164
- renderExpandedContent,
1165
- expandIcon,
1166
- collapseIcon,
1167
- expandButtonClassName
1168
- }) {
1169
- if (!isExpanded) return null;
1170
- return /* @__PURE__ */ React8.createElement("tr", { key: `${rowId}-expanded`, className: "border-b bg-gray-50 dark:bg-gray-900" }, /* @__PURE__ */ React8.createElement("td", { colSpan: columns.length, className: "p-0" }, /* @__PURE__ */ React8.createElement("div", { className: "px-4 py-3 bg-white dark:bg-gray-950 border-t" }, renderExpandedContent(row))));
1171
- }
1172
-
1173
- // components/data-grid/table-body.tsx
1174
- var TableBody = ({
1175
- paginatedData,
1176
- columns,
1177
- selectedRows,
1178
- enableRowSelection,
1179
- onRowSelect,
1180
- onRowClick,
1181
- rowClassName,
1182
- cellClassName,
1183
- columnWidths,
1184
- theme,
1185
- selectedRowClassName,
1186
- enableGrouping = false,
1187
- groupingState,
1188
- toggleGroupExpanded,
1189
- renderGroupRow,
1190
- groupExpandIcon = /* @__PURE__ */ React9.createElement(ChevronDown3, { className: "h-4 w-4" }),
1191
- groupCollapseIcon = /* @__PURE__ */ React9.createElement(ChevronRight2, { className: "h-4 w-4" }),
1192
- groupRowProps = {},
1193
- selectedCell = null,
1194
- onCellSelect,
1195
- selectedCellClassName = "ring-2 ring-primary ring-inset",
1196
- preventRowSelection,
1197
- contextMenuContent,
1198
- enableExpandableRows = false,
1199
- expandedRows = {},
1200
- onToggleRowExpand,
1201
- renderExpandedRow,
1202
- expandIcon = /* @__PURE__ */ React9.createElement(ChevronDown3, { className: "h-4 w-4" }),
1203
- collapseIcon = /* @__PURE__ */ React9.createElement(ChevronRight2, { className: "h-4 w-4" }),
1204
- getRowId = (row, index) => row.id || `row-${index}`
1205
- }) => {
1206
- return /* @__PURE__ */ React9.createElement("tbody", { className: theme.classes.tbody }, paginatedData.map((row, rowIndex) => {
1207
- if (enableGrouping && row.isGroupRow) {
1208
- return /* @__PURE__ */ React9.createElement(
1209
- GroupRow,
1210
- __spreadValues({
1211
- key: row.groupKey,
1212
- columnId: row.columnId,
1213
- value: row.groupValue,
1214
- depth: row.depth,
1215
- isExpanded: (groupingState == null ? void 0 : groupingState.expandedGroups[row.groupKey]) || false,
1216
- onToggleExpand: () => toggleGroupExpanded == null ? void 0 : toggleGroupExpanded(row.groupKey),
1217
- count: row.count,
1218
- columns: columns.length,
1219
- groupKey: row.groupKey,
1220
- expandIcon: groupExpandIcon,
1221
- collapseIcon: groupCollapseIcon,
1222
- renderGroupRow
1223
- }, groupRowProps)
1224
- );
1225
- }
1226
- const rowId = getRowId(row, rowIndex);
1227
- const isSelected = selectedRows[rowId];
1228
- const isExpanded = expandedRows[rowId] || false;
1229
- return /* @__PURE__ */ React9.createElement(React9.Fragment, { key: rowId }, /* @__PURE__ */ React9.createElement(
1230
- TableRow,
1231
- {
1232
- row,
1233
- rowId,
1234
- columns,
1235
- isSelected,
1236
- onRowSelect: enableRowSelection ? () => onRowSelect(rowId) : void 0,
1237
- onRowClick,
1238
- selectedRowClassName,
1239
- rowClassName,
1240
- cellClassName,
1241
- columnWidths,
1242
- selectedCell,
1243
- onCellSelect,
1244
- selectedCellClassName,
1245
- preventRowSelection,
1246
- contextMenuContent,
1247
- enableExpandableRows,
1248
- isExpanded,
1249
- onToggleExpand: enableExpandableRows && onToggleRowExpand ? () => onToggleRowExpand(rowId) : void 0,
1250
- expandIcon,
1251
- collapseIcon
1252
- }
1253
- ), enableExpandableRows && isExpanded && renderExpandedRow && /* @__PURE__ */ React9.createElement(
1254
- ExpandableRow,
1255
- {
1256
- row,
1257
- rowId,
1258
- columns,
1259
- isExpanded,
1260
- onToggleExpand: () => onToggleRowExpand == null ? void 0 : onToggleRowExpand(rowId),
1261
- renderExpandedContent: renderExpandedRow,
1262
- expandIcon,
1263
- collapseIcon
1264
- }
1265
- ));
1266
- }));
1267
- };
1268
-
1269
- // components/data-grid/pagination.tsx
1270
- import React10 from "react";
1271
- var Pagination = ({
1272
- pageIndex,
1273
- pageCount,
1274
- pageSize,
1275
- totalRows,
1276
- setPageIndex,
1277
- setPageSize,
1278
- pageSizeOptions,
1279
- processedDataLength,
1280
- // Custom props
1281
- className,
1282
- showFirstLastButtons = true,
1283
- showPageSizeSelector = true,
1284
- showPageInfo = true,
1285
- renderPageSizeSelector,
1286
- renderPageInfo,
1287
- renderFirstPageButton,
1288
- renderPrevPageButton,
1289
- renderNextPageButton,
1290
- renderLastPageButton,
1291
- pageSizeClassName,
1292
- pageInfoClassName,
1293
- buttonsClassName,
1294
- buttonClassName
1295
- }) => {
1296
- const start = processedDataLength === 0 ? 0 : pageIndex * pageSize + 1;
1297
- const end = Math.min((pageIndex + 1) * pageSize, totalRows);
1298
- const isFirstPage = pageIndex === 0;
1299
- const isLastPage = pageIndex >= pageCount - 1;
1300
- const handlePageSizeChange = (size) => {
1301
- setPageSize(size);
1302
- setPageIndex(0);
1303
- };
1304
- const goToFirstPage = () => setPageIndex(0);
1305
- const goToPrevPage = () => setPageIndex(Math.max(0, pageIndex - 1));
1306
- const goToNextPage = () => setPageIndex(Math.min(pageCount - 1, pageIndex + 1));
1307
- const goToLastPage = () => setPageIndex(pageCount - 1);
1308
- return /* @__PURE__ */ React10.createElement("div", { className: cn("px-4 py-3 flex items-center justify-between border-t border-gray-200 dark:border-gray-700", className) }, showPageSizeSelector && /* @__PURE__ */ React10.createElement("div", { className: cn("flex items-center gap-3", pageSizeClassName) }, renderPageSizeSelector ? renderPageSizeSelector({
1309
- pageSize,
1310
- options: pageSizeOptions,
1311
- onChange: handlePageSizeChange
1312
- }) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("span", { className: "text-sm text-gray-600 dark:text-gray-400 font-medium" }, "Rows per page:"), /* @__PURE__ */ React10.createElement(
1313
- "select",
1314
- {
1315
- value: pageSize,
1316
- onChange: (e) => handlePageSizeChange(Number(e.target.value)),
1317
- className: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 px-3 py-1.5 text-sm rounded-md hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors cursor-pointer"
1318
- },
1319
- pageSizeOptions.map((option) => /* @__PURE__ */ React10.createElement("option", { key: option, value: option }, option))
1320
- ))), /* @__PURE__ */ React10.createElement(
1321
- "div",
1322
- {
1323
- className: cn("flex items-center gap-4", buttonsClassName)
1324
- },
1325
- showPageInfo && /* @__PURE__ */ React10.createElement("div", { className: cn("text-sm text-gray-600 dark:text-gray-400", pageInfoClassName) }, renderPageInfo ? renderPageInfo({ start, end, total: totalRows }) : /* @__PURE__ */ React10.createElement("span", null, start, "\u2013", end, " of ", totalRows)),
1326
- /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-1" }, showFirstLastButtons && (renderFirstPageButton ? renderFirstPageButton({
1327
- onClick: goToFirstPage,
1328
- disabled: isFirstPage
1329
- }) : /* @__PURE__ */ React10.createElement(
1330
- "button",
1331
- {
1332
- onClick: goToFirstPage,
1333
- disabled: isFirstPage,
1334
- className: cn(
1335
- "h-8 w-8 rounded-md border border-gray-300 dark:border-gray-600",
1336
- "bg-white dark:bg-gray-800",
1337
- "hover:bg-gray-50 dark:hover:bg-gray-700",
1338
- "text-gray-700 dark:text-gray-300",
1339
- "disabled:opacity-40 disabled:cursor-not-allowed",
1340
- "transition-colors",
1341
- "flex items-center justify-center text-sm",
1342
- buttonClassName
1343
- )
1344
- },
1345
- "<<"
1346
- )), renderPrevPageButton ? renderPrevPageButton({
1347
- onClick: goToPrevPage,
1348
- disabled: isFirstPage
1349
- }) : /* @__PURE__ */ React10.createElement(
1350
- "button",
1351
- {
1352
- onClick: goToPrevPage,
1353
- disabled: isFirstPage,
1354
- className: cn(
1355
- "h-8 w-8 rounded-md border border-gray-300 dark:border-gray-600",
1356
- "bg-white dark:bg-gray-800",
1357
- "hover:bg-gray-50 dark:hover:bg-gray-700",
1358
- "text-gray-700 dark:text-gray-300",
1359
- "disabled:opacity-40 disabled:cursor-not-allowed",
1360
- "transition-colors",
1361
- "flex items-center justify-center text-sm",
1362
- buttonClassName
1363
- )
1364
- },
1365
- "<"
1366
- ), renderNextPageButton ? renderNextPageButton({
1367
- onClick: goToNextPage,
1368
- disabled: isLastPage
1369
- }) : /* @__PURE__ */ React10.createElement(
1370
- "button",
1371
- {
1372
- onClick: goToNextPage,
1373
- disabled: isLastPage,
1374
- className: cn(
1375
- "h-8 w-8 rounded-md border border-gray-300 dark:border-gray-600",
1376
- "bg-white dark:bg-gray-800",
1377
- "hover:bg-gray-50 dark:hover:bg-gray-700",
1378
- "text-gray-700 dark:text-gray-300",
1379
- "disabled:opacity-40 disabled:cursor-not-allowed",
1380
- "transition-colors",
1381
- "flex items-center justify-center text-sm",
1382
- buttonClassName
1383
- )
1384
- },
1385
- ">"
1386
- ), showFirstLastButtons && (renderLastPageButton ? renderLastPageButton({
1387
- onClick: goToLastPage,
1388
- disabled: isLastPage
1389
- }) : /* @__PURE__ */ React10.createElement(
1390
- "button",
1391
- {
1392
- onClick: goToLastPage,
1393
- disabled: isLastPage,
1394
- className: cn(
1395
- "h-8 w-8 rounded-md border border-gray-300 dark:border-gray-600",
1396
- "bg-white dark:bg-gray-800",
1397
- "hover:bg-gray-50 dark:hover:bg-gray-700",
1398
- "text-gray-700 dark:text-gray-300",
1399
- "disabled:opacity-40 disabled:cursor-not-allowed",
1400
- "transition-colors",
1401
- "flex items-center justify-center text-sm",
1402
- buttonClassName
1403
- )
1404
- },
1405
- ">>"
1406
- )))
1407
- ));
1408
- };
1409
-
1410
- // components/data-grid/column-manager.tsx
1411
- import React13 from "react";
1412
-
1413
- // components/ui/dropdown-menu.tsx
1414
- import * as React11 from "react";
1415
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
1416
- import { Check, ChevronRight as ChevronRight3, Circle } from "lucide-react";
1417
- var DropdownMenu = DropdownMenuPrimitive.Root;
1418
- var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
1419
- var DropdownMenuGroup = DropdownMenuPrimitive.Group;
1420
- var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
1421
- var DropdownMenuSub = DropdownMenuPrimitive.Sub;
1422
- var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
1423
- var DropdownMenuSubTrigger = React11.forwardRef((_a, ref) => {
1424
- var _b = _a, { className, inset, children } = _b, props = __objRest(_b, ["className", "inset", "children"]);
1425
- return /* @__PURE__ */ React11.createElement(
1426
- DropdownMenuPrimitive.SubTrigger,
1427
- __spreadValues({
1428
- ref,
1429
- className: cn(
1430
- "flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1431
- inset && "pl-8",
1432
- className
1433
- )
1434
- }, props),
1435
- children,
1436
- /* @__PURE__ */ React11.createElement(ChevronRight3, { className: "ml-auto" })
1437
- );
1438
- });
1439
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
1440
- var DropdownMenuSubContent = React11.forwardRef((_a, ref) => {
1441
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1442
- return /* @__PURE__ */ React11.createElement(
1443
- DropdownMenuPrimitive.SubContent,
1444
- __spreadValues({
1445
- ref,
1446
- className: cn(
1447
- "z-50 min-w-[8rem] overflow-hidden rounded-md 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",
1448
- className
1449
- )
1450
- }, props)
1451
- );
1452
- });
1453
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
1454
- var DropdownMenuContent = React11.forwardRef((_a, ref) => {
1455
- var _b = _a, { className, sideOffset = 4 } = _b, props = __objRest(_b, ["className", "sideOffset"]);
1456
- return /* @__PURE__ */ React11.createElement(DropdownMenuPrimitive.Portal, null, /* @__PURE__ */ React11.createElement(
1457
- DropdownMenuPrimitive.Content,
1458
- __spreadValues({
1459
- ref,
1460
- sideOffset,
1461
- className: cn(
1462
- "z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
1463
- "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",
1464
- className
1465
- )
1466
- }, props)
1467
- ));
1468
- });
1469
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
1470
- var DropdownMenuItem = React11.forwardRef((_a, ref) => {
1471
- var _b = _a, { className, inset } = _b, props = __objRest(_b, ["className", "inset"]);
1472
- return /* @__PURE__ */ React11.createElement(
1473
- DropdownMenuPrimitive.Item,
1474
- __spreadValues({
1475
- ref,
1476
- className: cn(
1477
- "relative flex cursor-default select-none items-center gap-2 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 [&>svg]:size-4 [&>svg]:shrink-0",
1478
- inset && "pl-8",
1479
- className
1480
- )
1481
- }, props)
1482
- );
1483
- });
1484
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
1485
- var DropdownMenuCheckboxItem = React11.forwardRef((_a, ref) => {
1486
- var _b = _a, { className, children, checked } = _b, props = __objRest(_b, ["className", "children", "checked"]);
1487
- return /* @__PURE__ */ React11.createElement(
1488
- DropdownMenuPrimitive.CheckboxItem,
1489
- __spreadValues({
1490
- ref,
1491
- className: cn(
1492
- "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",
1493
- className
1494
- ),
1495
- checked
1496
- }, props),
1497
- /* @__PURE__ */ React11.createElement("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center" }, /* @__PURE__ */ React11.createElement(DropdownMenuPrimitive.ItemIndicator, null, /* @__PURE__ */ React11.createElement(Check, { className: "h-4 w-4" }))),
1498
- children
1499
- );
1500
- });
1501
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
1502
- var DropdownMenuRadioItem = React11.forwardRef((_a, ref) => {
1503
- var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
1504
- return /* @__PURE__ */ React11.createElement(
1505
- DropdownMenuPrimitive.RadioItem,
1506
- __spreadValues({
1507
- ref,
1508
- className: cn(
1509
- "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",
1510
- className
1511
- )
1512
- }, props),
1513
- /* @__PURE__ */ React11.createElement("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center" }, /* @__PURE__ */ React11.createElement(DropdownMenuPrimitive.ItemIndicator, null, /* @__PURE__ */ React11.createElement(Circle, { className: "h-2 w-2 fill-current" }))),
1514
- children
1515
- );
1516
- });
1517
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
1518
- var DropdownMenuLabel = React11.forwardRef((_a, ref) => {
1519
- var _b = _a, { className, inset } = _b, props = __objRest(_b, ["className", "inset"]);
1520
- return /* @__PURE__ */ React11.createElement(
1521
- DropdownMenuPrimitive.Label,
1522
- __spreadValues({
1523
- ref,
1524
- className: cn(
1525
- "px-2 py-1.5 text-sm font-semibold",
1526
- inset && "pl-8",
1527
- className
1528
- )
1529
- }, props)
1530
- );
1531
- });
1532
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
1533
- var DropdownMenuSeparator = React11.forwardRef((_a, ref) => {
1534
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1535
- return /* @__PURE__ */ React11.createElement(
1536
- DropdownMenuPrimitive.Separator,
1537
- __spreadValues({
1538
- ref,
1539
- className: cn("-mx-1 my-1 h-px bg-muted", className)
1540
- }, props)
1541
- );
1542
- });
1543
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
1544
- var DropdownMenuShortcut = (_a) => {
1545
- var _b = _a, {
1546
- className
1547
- } = _b, props = __objRest(_b, [
1548
- "className"
1549
- ]);
1550
- return /* @__PURE__ */ React11.createElement(
1551
- "span",
1552
- __spreadValues({
1553
- className: cn("ml-auto text-xs tracking-widest opacity-60", className)
1554
- }, props)
1555
- );
1556
- };
1557
- DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
1558
-
1559
- // components/ui/button.tsx
1560
- import * as React12 from "react";
1561
- import { Slot } from "@radix-ui/react-slot";
1562
- import { cva } from "class-variance-authority";
1563
- var buttonVariants = cva(
1564
- "inline-flex items-center justify-center gap-1.5 whitespace-nowrap text-sm font-mono font-bold uppercase tracking-[0.08em] transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-30 [&_svg]:pointer-events-none [&_svg]:size-3 [&_svg]:shrink-0 relative overflow-hidden",
1565
- {
1566
- variants: {
1567
- variant: {
1568
- default: "bg-primary text-primary-foreground border-2 border-foreground hover:bg-foreground hover:text-background active:translate-y-[1px] shadow-[3px_3px_0_0_rgba(0,0,0,1)] dark:shadow-[3px_3px_0_0_rgba(255,255,255,0.2)] hover:shadow-[1px_1px_0_0_rgba(0,0,0,1)] dark:hover:shadow-[1px_1px_0_0_rgba(255,255,255,0.2)]",
1569
- destructive: "bg-destructive text-destructive-foreground border-2 border-foreground hover:bg-destructive/90 active:translate-y-[1px] shadow-[3px_3px_0_0_rgba(0,0,0,1)] dark:shadow-[3px_3px_0_0_rgba(255,255,255,0.2)] hover:shadow-[1px_1px_0_0_rgba(0,0,0,1)] dark:hover:shadow-[1px_1px_0_0_rgba(255,255,255,0.2)]",
1570
- outline: "border-2 border-foreground bg-background hover:bg-foreground hover:text-background active:translate-y-[1px] shadow-[3px_3px_0_0_rgba(0,0,0,1)] dark:shadow-[3px_3px_0_0_rgba(255,255,255,0.2)] hover:shadow-[1px_1px_0_0_rgba(0,0,0,1)] dark:hover:shadow-[1px_1px_0_0_rgba(255,255,255,0.2)]",
1571
- secondary: "bg-secondary text-secondary-foreground border-2 border-border hover:bg-secondary/80 active:translate-y-[1px] shadow-[2px_2px_0_0_rgba(0,0,0,0.3)] dark:shadow-[2px_2px_0_0_rgba(255,255,255,0.1)] hover:shadow-[1px_1px_0_0_rgba(0,0,0,0.3)] dark:hover:shadow-[1px_1px_0_0_rgba(255,255,255,0.1)]",
1572
- ghost: "hover:bg-accent hover:text-accent-foreground border-2 border-transparent hover:border-border",
1573
- link: "text-primary underline-offset-4 hover:underline border-0 shadow-none"
1574
- },
1575
- size: {
1576
- default: "h-10 px-5 py-2.5 text-xs",
1577
- sm: "h-8 px-4 text-[10px]",
1578
- lg: "h-12 px-7 text-sm",
1579
- icon: "h-10 w-10"
1580
- }
1581
- },
1582
- defaultVariants: {
1583
- variant: "default",
1584
- size: "default"
1585
- }
1586
- }
1587
- );
1588
- var Button = React12.forwardRef(
1589
- (_a, ref) => {
1590
- var _b = _a, { className, variant, size, asChild = false } = _b, props = __objRest(_b, ["className", "variant", "size", "asChild"]);
1591
- const Comp = asChild ? Slot : "button";
1592
- return /* @__PURE__ */ React12.createElement(
1593
- Comp,
1594
- __spreadValues({
1595
- className: cn(buttonVariants({ variant, size, className })),
1596
- ref
1597
- }, props)
1598
- );
1599
- }
1600
- );
1601
- Button.displayName = "Button";
1602
-
1603
- // components/data-grid/column-manager.tsx
1604
- import { RotateCcw, Settings } from "lucide-react";
1605
- function ColumnManager({
1606
- columns,
1607
- visibleColumns,
1608
- toggleColumnVisibility,
1609
- resetGridPreferences,
1610
- renderTrigger,
1611
- renderResetButton,
1612
- renderColumnItem,
1613
- align = "end",
1614
- showResetButton = true,
1615
- className,
1616
- triggerClassName,
1617
- contentClassName,
1618
- itemClassName,
1619
- resetClassName
1620
- }) {
1621
- return /* @__PURE__ */ React13.createElement(DropdownMenu, null, /* @__PURE__ */ React13.createElement(DropdownMenuTrigger, { asChild: true, className }, renderTrigger ? renderTrigger({ onClick: () => {
1622
- } }) : /* @__PURE__ */ React13.createElement(
1623
- Button,
1624
- {
1625
- variant: "outline",
1626
- size: "sm",
1627
- className: cn("ml-auto", triggerClassName)
1628
- },
1629
- /* @__PURE__ */ React13.createElement(Settings, { className: "h-3 w-3 mr-1.5" }),
1630
- /* @__PURE__ */ React13.createElement("span", null, "Columns")
1631
- )), /* @__PURE__ */ React13.createElement(DropdownMenuContent, { align, className: contentClassName }, columns.map((column) => {
1632
- const isVisible = visibleColumns.includes(column.id);
1633
- const handleToggle = (checked) => toggleColumnVisibility(column.id, checked);
1634
- return renderColumnItem ? /* @__PURE__ */ React13.createElement(React13.Fragment, { key: column.id }, renderColumnItem({ column, isVisible, onToggle: handleToggle })) : /* @__PURE__ */ React13.createElement(
1635
- DropdownMenuCheckboxItem,
1636
- {
1637
- key: column.id,
1638
- checked: isVisible,
1639
- onCheckedChange: handleToggle,
1640
- className: itemClassName
1641
- },
1642
- column.header
1643
- );
1644
- }), showResetButton && /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(DropdownMenuSeparator, null), renderResetButton ? renderResetButton({ onClick: resetGridPreferences }) : /* @__PURE__ */ React13.createElement(
1645
- DropdownMenuItem,
1646
- {
1647
- onClick: resetGridPreferences,
1648
- className: cn(
1649
- "focus:bg-destructive/10 cursor-pointer",
1650
- resetClassName
1651
- )
1652
- },
1653
- /* @__PURE__ */ React13.createElement(RotateCcw, { className: "h-3 w-3 mr-1.5" }),
1654
- "Reset all columns"
1655
- ))));
1656
- }
1657
-
1658
- // components/data-grid/group-manager.tsx
1659
- import React14 from "react";
1660
- import { Layers, X } from "lucide-react";
1661
- function GroupManager({
1662
- columns,
1663
- groupByColumns,
1664
- updateGroupByColumns,
1665
- removeGroupByColumn,
1666
- clearGrouping,
1667
- className,
1668
- triggerClassName,
1669
- contentClassName,
1670
- itemClassName,
1671
- activeGroupsClassName,
1672
- renderTrigger,
1673
- renderActiveGroup,
1674
- align = "end"
1675
- }) {
1676
- const groupableColumns = columns.filter(
1677
- (col) => col.enableGrouping !== false
1678
- );
1679
- const toggleColumnGrouping = (columnId) => {
1680
- if (groupByColumns.includes(columnId)) {
1681
- updateGroupByColumns(groupByColumns.filter((id) => id !== columnId));
1682
- } else {
1683
- updateGroupByColumns([...groupByColumns, columnId]);
1684
- }
1685
- };
1686
- return /* @__PURE__ */ React14.createElement("div", { className: "flex flex-col" }, groupByColumns.length > 0 && /* @__PURE__ */ React14.createElement("div", { className: cn("flex flex-wrap gap-1 mb-2", activeGroupsClassName) }, groupByColumns.map((columnId) => {
1687
- const column = columns.find((col) => col.id === columnId);
1688
- if (!column) return null;
1689
- return renderActiveGroup ? /* @__PURE__ */ React14.createElement(React14.Fragment, { key: columnId }, renderActiveGroup({
1690
- column,
1691
- onRemove: () => removeGroupByColumn(columnId)
1692
- })) : /* @__PURE__ */ React14.createElement(
1693
- "div",
1694
- {
1695
- key: columnId,
1696
- className: "bg-primary/10 rounded-md px-2 py-1 text-xs flex items-center"
1697
- },
1698
- /* @__PURE__ */ React14.createElement("span", { className: "mr-1" }, column.header),
1699
- /* @__PURE__ */ React14.createElement(
1700
- "button",
1701
- {
1702
- onClick: () => removeGroupByColumn(columnId),
1703
- className: "hover:text-destructive focus:outline-none"
1704
- },
1705
- /* @__PURE__ */ React14.createElement(X, { className: "h-3 w-3" })
1706
- )
1707
- );
1708
- }), /* @__PURE__ */ React14.createElement(
1709
- Button,
1710
- {
1711
- variant: "ghost",
1712
- size: "sm",
1713
- onClick: clearGrouping,
1714
- className: "text-xs h-6"
1715
- },
1716
- "Clear All"
1717
- )), /* @__PURE__ */ React14.createElement(DropdownMenu, null, /* @__PURE__ */ React14.createElement(DropdownMenuTrigger, { asChild: true, className }, renderTrigger ? renderTrigger({ onClick: () => {
1718
- } }) : /* @__PURE__ */ React14.createElement(
1719
- Button,
1720
- {
1721
- variant: "outline",
1722
- size: "sm",
1723
- className: cn(triggerClassName)
1724
- },
1725
- /* @__PURE__ */ React14.createElement(Layers, { className: "h-3 w-3 mr-1.5" }),
1726
- /* @__PURE__ */ React14.createElement("span", null, "Group by")
1727
- )), /* @__PURE__ */ React14.createElement(DropdownMenuContent, { align, className: contentClassName }, groupableColumns.length > 0 ? groupableColumns.map((column) => {
1728
- const isGrouped = groupByColumns.includes(column.id);
1729
- return /* @__PURE__ */ React14.createElement(
1730
- DropdownMenuCheckboxItem,
1731
- {
1732
- key: column.id,
1733
- checked: isGrouped,
1734
- onCheckedChange: () => toggleColumnGrouping(column.id),
1735
- className: itemClassName
1736
- },
1737
- column.header
1738
- );
1739
- }) : /* @__PURE__ */ React14.createElement(DropdownMenuItem, { disabled: true }, "No groupable columns"), groupByColumns.length > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(DropdownMenuSeparator, null), /* @__PURE__ */ React14.createElement(DropdownMenuItem, { onClick: clearGrouping }, "Clear all groups")))));
1740
- }
1741
-
1742
- // components/data-grid/use-grid-persistence.ts
1743
- import { useState as useState4, useEffect as useEffect2 } from "react";
1744
- function useGridPersistence(gridId, columns, defaultColumnWidth = 150) {
1745
- const storageKey = `gridular-preferences-${gridId}`;
1746
- const getDefaultPreferences = () => ({
1747
- columnWidths: columns.reduce((acc, col) => {
1748
- acc[col.id] = defaultColumnWidth;
1749
- return acc;
1750
- }, {}),
1751
- columnOrder: columns.map((col) => col.id),
1752
- hiddenColumns: [],
1753
- groupByColumns: [],
1754
- // Initialize with empty array
1755
- expandedGroups: {}
1756
- // Initialize with empty object
1757
- });
1758
- const loadPreferences = () => {
1759
- if (typeof window === "undefined") return getDefaultPreferences();
1760
- try {
1761
- const stored = localStorage.getItem(storageKey);
1762
- if (!stored) return getDefaultPreferences();
1763
- const parsed = JSON.parse(stored);
1764
- const updated = __spreadProps(__spreadValues({}, parsed), {
1765
- // Ensure these fields exist
1766
- groupByColumns: parsed.groupByColumns || [],
1767
- expandedGroups: parsed.expandedGroups || {}
1768
- });
1769
- columns.forEach((col) => {
1770
- if (!parsed.columnWidths[col.id]) {
1771
- updated.columnWidths[col.id] = defaultColumnWidth;
1772
- }
1773
- if (!parsed.columnOrder.includes(col.id)) {
1774
- updated.columnOrder.push(col.id);
1775
- }
1776
- });
1777
- return updated;
1778
- } catch (error) {
1779
- console.error("Failed to load grid preferences", error);
1780
- return getDefaultPreferences();
1781
- }
1782
- };
1783
- const [preferences, setPreferences] = useState4(
1784
- getDefaultPreferences()
1785
- );
1786
- useEffect2(() => {
1787
- setPreferences(loadPreferences());
1788
- }, []);
1789
- const savePreferences = (newPreferences) => {
1790
- if (typeof window === "undefined") return;
1791
- try {
1792
- localStorage.setItem(storageKey, JSON.stringify(newPreferences));
1793
- setPreferences(newPreferences);
1794
- } catch (error) {
1795
- console.error("Failed to save grid preferences", error);
1796
- }
1797
- };
1798
- const updateColumnWidth = (columnId, width) => {
1799
- savePreferences(__spreadProps(__spreadValues({}, preferences), {
1800
- columnWidths: __spreadProps(__spreadValues({}, preferences.columnWidths), {
1801
- [columnId]: width
1802
- })
1803
- }));
1804
- };
1805
- const updateColumnOrder = (newOrder) => {
1806
- savePreferences(__spreadProps(__spreadValues({}, preferences), {
1807
- columnOrder: newOrder
1808
- }));
1809
- };
1810
- const toggleColumnVisibility = (columnId, visible) => {
1811
- const hiddenColumns = [...preferences.hiddenColumns];
1812
- if (!visible && !hiddenColumns.includes(columnId)) {
1813
- hiddenColumns.push(columnId);
1814
- } else if (visible) {
1815
- const index = hiddenColumns.indexOf(columnId);
1816
- if (index !== -1) {
1817
- hiddenColumns.splice(index, 1);
1818
- }
1819
- }
1820
- savePreferences(__spreadProps(__spreadValues({}, preferences), {
1821
- hiddenColumns
1822
- }));
1823
- };
1824
- const updateGroupByColumns = (groupByColumns) => {
1825
- savePreferences(__spreadProps(__spreadValues({}, preferences), {
1826
- groupByColumns
1827
- }));
1828
- };
1829
- const toggleGroupExpanded = (groupKey, expanded) => {
1830
- savePreferences(__spreadProps(__spreadValues({}, preferences), {
1831
- expandedGroups: __spreadProps(__spreadValues({}, preferences.expandedGroups), {
1832
- [groupKey]: expanded
1833
- })
1834
- }));
1835
- };
1836
- const resetPreferences = () => {
1837
- savePreferences(getDefaultPreferences());
1838
- };
1839
- return {
1840
- preferences,
1841
- updateColumnWidth,
1842
- updateColumnOrder,
1843
- toggleColumnVisibility,
1844
- updateGroupByColumns,
1845
- toggleGroupExpanded,
1846
- resetPreferences
1847
- };
1848
- }
1849
-
1850
- // components/data-grid/use-data-grouping.ts
1851
- import { useMemo as useMemo2 } from "react";
1852
- function useDataGrouping(data, groupingState, idAccessor) {
1853
- const { groupByColumns, expandedGroups } = groupingState;
1854
- const groupedData = useMemo2(() => {
1855
- if (!groupByColumns.length) return { rows: data, flattenedRows: data };
1856
- const createGroupingStructure = (rows, groupBy, depth = 0) => {
1857
- if (depth >= groupBy.length || groupBy.length === 0) {
1858
- return rows;
1859
- }
1860
- const columnId = groupBy[depth];
1861
- const groupMap = /* @__PURE__ */ new Map();
1862
- for (const row of rows) {
1863
- const value = row[columnId];
1864
- if (!groupMap.has(value)) {
1865
- groupMap.set(value, []);
1866
- }
1867
- groupMap.get(value).push(row);
1868
- }
1869
- const result = [];
1870
- for (const [value, groupRows] of groupMap.entries()) {
1871
- const groupKey = `${columnId}:${value}:${depth}`;
1872
- const groupRow = {
1873
- isGroupRow: true,
1874
- groupKey,
1875
- groupValue: value,
1876
- columnId,
1877
- depth,
1878
- count: groupRows.length,
1879
- children: createGroupingStructure(groupRows, groupBy, depth + 1)
1880
- };
1881
- result.push(groupRow);
1882
- }
1883
- return result;
1884
- };
1885
- const groupedRows = createGroupingStructure(data, groupByColumns);
1886
- const flattenRows = (rows, result = [], parentGroupKeys = []) => {
1887
- for (const row of rows) {
1888
- if (row.isGroupRow) {
1889
- const groupRow = row;
1890
- result.push(groupRow);
1891
- if (expandedGroups[groupRow.groupKey]) {
1892
- flattenRows(groupRow.children, result, [
1893
- ...parentGroupKeys,
1894
- groupRow.groupKey
1895
- ]);
1896
- }
1897
- } else {
1898
- const rowWithGroupInfo = __spreadProps(__spreadValues({}, row), {
1899
- _groupParentKeys: parentGroupKeys
1900
- });
1901
- result.push(rowWithGroupInfo);
1902
- }
1903
- }
1904
- return result;
1905
- };
1906
- const flattenedRows = flattenRows(groupedRows);
1907
- return { rows: groupedRows, flattenedRows };
1908
- }, [data, groupByColumns, expandedGroups]);
1909
- return groupedData;
1910
- }
1911
-
1912
- // components/data-grid/use-select-cell.tsx
1913
- import { useState as useState5, useCallback } from "react";
1914
- function useSelectCell() {
1915
- const [selectedCell, setSelectedCell] = useState5(null);
1916
- const selectCell = useCallback((rowId, columnId) => {
1917
- setSelectedCell({ rowId, columnId });
1918
- }, []);
1919
- const clearSelection = useCallback(() => {
1920
- setSelectedCell(null);
1921
- }, []);
1922
- const isCellSelected = useCallback(
1923
- (rowId, columnId) => {
1924
- return selectedCell !== null && selectedCell.rowId === rowId && selectedCell.columnId === columnId;
1925
- },
1926
- [selectedCell]
1927
- );
1928
- return {
1929
- selectedCell,
1930
- selectCell,
1931
- clearSelection,
1932
- isCellSelected
1933
- };
1934
- }
1935
-
1936
- // components/data-grid/data-grid.tsx
1937
- function DataGrid({
1938
- columns,
1939
- data,
1940
- sortState = null,
1941
- onSortChange,
1942
- filterState = {},
1943
- onFilterChange,
1944
- selectedRows = {},
1945
- onRowSelectionChange,
1946
- pageIndex,
1947
- pageCount,
1948
- pageSize,
1949
- onPageChange,
1950
- onPageSizeChange,
1951
- onRowClick,
1952
- enableSorting = true,
1953
- enableFiltering = true,
1954
- enableColumnResize = true,
1955
- enableRowSelection = false,
1956
- enablePagination = true,
1957
- enableGrouping = false,
1958
- enableExpandableRows = false,
1959
- hideGroupControls = false,
1960
- hideColumnManager = false,
1961
- pageSizeOptions = [5, 10, 20, 50, 100],
1962
- emptyMessage = "No data available",
1963
- loadingMessage = "Loading data...",
1964
- isLoading = false,
1965
- gridId = "default",
1966
- classes = {},
1967
- className,
1968
- renderCell,
1969
- renderHeader,
1970
- renderSortIcon,
1971
- renderFilterIcon,
1972
- renderGroupRow,
1973
- sortIconVariant = "arrows",
1974
- columnManagerProps = {},
1975
- paginationProps = {},
1976
- groupManagerProps = {},
1977
- groupRowProps = {},
1978
- groupingState,
1979
- onGroupingChange,
1980
- groupExpandIcon,
1981
- groupCollapseIcon,
1982
- totalRows,
1983
- filterMenu,
1984
- selectedCell: propSelectedCell,
1985
- enableCellSelection = false,
1986
- onCellSelect,
1987
- preventRowSelection,
1988
- contextMenuContent,
1989
- expandedRows = {},
1990
- onExpandedRowsChange,
1991
- renderExpandedRow,
1992
- expandIcon,
1993
- collapseIcon,
1994
- getRowId
1995
- }) {
1996
- const { theme } = useTheme();
1997
- const filterValueRefs = useRef(filterState || {});
1998
- const [filterMenuOpen, setFilterMenuOpen] = useState6(null);
1999
- const [activeFilterColumn, setActiveFilterColumn] = useState6(null);
2000
- const filterMenuRef = useRef(null);
2001
- const effectiveEnablePagination = enableGrouping ? false : enablePagination;
2002
- const {
2003
- preferences,
2004
- updateColumnWidth,
2005
- updateColumnOrder,
2006
- toggleColumnVisibility,
2007
- updateGroupByColumns,
2008
- toggleGroupExpanded,
2009
- resetPreferences
2010
- } = useGridPersistence(gridId, columns);
2011
- const { selectedCell, selectCell, clearSelection, isCellSelected } = useSelectCell();
2012
- const handleCellSelect = (rowId, columnId) => {
2013
- if (enableCellSelection) {
2014
- selectCell(rowId, columnId);
2015
- if (onCellSelect) {
2016
- onCellSelect(rowId, columnId);
2017
- }
2018
- }
2019
- };
2020
- const [internalGroupingState, setInternalGroupingState] = useState6({
2021
- groupByColumns: (groupingState == null ? void 0 : groupingState.groupByColumns) || preferences.groupByColumns || [],
2022
- expandedGroups: (groupingState == null ? void 0 : groupingState.expandedGroups) || preferences.expandedGroups || {}
2023
- });
2024
- const effectiveGroupingState = groupingState || internalGroupingState;
2025
- const visibleColumns = useMemo3(() => {
2026
- const hiddenIds = new Set(preferences.hiddenColumns);
2027
- const visible = columns.filter((col) => !hiddenIds.has(col.id)).map((col) => col.id);
2028
- const orderedIds = preferences.columnOrder.filter(
2029
- (id) => visible.includes(id)
2030
- );
2031
- visible.forEach((id) => {
2032
- if (!orderedIds.includes(id)) {
2033
- orderedIds.push(id);
2034
- }
2035
- });
2036
- return orderedIds;
2037
- }, [columns, preferences.hiddenColumns, preferences.columnOrder]);
2038
- const orderedColumns = useMemo3(() => {
2039
- const colMap = new Map(columns.map((col) => [col.id, col]));
2040
- return visibleColumns.map((id) => colMap.get(id)).filter(Boolean);
2041
- }, [columns, visibleColumns]);
2042
- useEffect3(() => {
2043
- if (filterState) {
2044
- filterValueRefs.current = __spreadValues({}, filterState);
2045
- }
2046
- }, [filterState]);
2047
- useEffect3(() => {
2048
- function handleClickOutside(event) {
2049
- if (filterMenuRef.current && !filterMenuRef.current.contains(event.target)) {
2050
- setFilterMenuOpen(null);
2051
- }
2052
- }
2053
- document.addEventListener("mousedown", handleClickOutside);
2054
- return () => {
2055
- document.removeEventListener("mousedown", handleClickOutside);
2056
- };
2057
- }, [filterMenuOpen]);
2058
- const { flattenedRows } = useDataGrouping(
2059
- data,
2060
- enableGrouping ? effectiveGroupingState : { groupByColumns: [], expandedGroups: {} },
2061
- (row) => row.id || `row-${Math.random()}`
2062
- );
2063
- const paginatedData = useMemo3(() => {
2064
- const displayData = enableGrouping ? flattenedRows : data;
2065
- if (!effectiveEnablePagination || !pageSize) {
2066
- return displayData;
2067
- }
2068
- const effectivePageIndex = pageIndex != null ? pageIndex : 0;
2069
- const totalPages = Math.max(1, Math.ceil(displayData.length / pageSize));
2070
- const safePageIndex = Math.min(effectivePageIndex, totalPages - 1);
2071
- const start = safePageIndex * pageSize;
2072
- const end = start + pageSize;
2073
- const slicedData = displayData.slice(
2074
- start,
2075
- Math.min(end, displayData.length)
2076
- );
2077
- return slicedData;
2078
- }, [
2079
- data,
2080
- flattenedRows,
2081
- enableGrouping,
2082
- effectiveEnablePagination,
2083
- pageIndex,
2084
- pageSize
2085
- ]);
2086
- const handleFilterMenuToggle = (columnId) => {
2087
- if (columnId === filterMenuOpen) {
2088
- setFilterMenuOpen(null);
2089
- setActiveFilterColumn(null);
2090
- } else if (columnId) {
2091
- const column = columns.find((col) => col.id === columnId);
2092
- if (column) {
2093
- setFilterMenuOpen(columnId);
2094
- setActiveFilterColumn(column);
2095
- }
2096
- } else {
2097
- setFilterMenuOpen(null);
2098
- setActiveFilterColumn(null);
2099
- }
2100
- };
2101
- const handleApplyFilter = (value) => {
2102
- if (!activeFilterColumn || !onFilterChange) return;
2103
- const newFilterState = __spreadValues({}, filterState);
2104
- if (value) {
2105
- newFilterState[activeFilterColumn.id] = value;
2106
- } else {
2107
- delete newFilterState[activeFilterColumn.id];
2108
- }
2109
- onFilterChange(newFilterState);
2110
- setFilterMenuOpen(null);
2111
- };
2112
- const handleClearFilter = () => {
2113
- if (!activeFilterColumn || !onFilterChange) return;
2114
- const newFilterState = __spreadValues({}, filterState);
2115
- delete newFilterState[activeFilterColumn.id];
2116
- onFilterChange(newFilterState);
2117
- setFilterMenuOpen(null);
2118
- };
2119
- const handleColumnReorder = (draggedId, targetId) => {
2120
- if (draggedId === targetId) return;
2121
- const currentOrder = [...preferences.columnOrder];
2122
- const draggedIndex = currentOrder.indexOf(draggedId);
2123
- const targetIndex = currentOrder.indexOf(targetId);
2124
- if (draggedIndex !== -1 && targetIndex !== -1) {
2125
- currentOrder.splice(draggedIndex, 1);
2126
- currentOrder.splice(targetIndex, 0, draggedId);
2127
- updateColumnOrder(currentOrder);
2128
- }
2129
- };
2130
- const handleColumnResize = (columnId, width) => {
2131
- updateColumnWidth(columnId, width);
2132
- };
2133
- const handleGroupByColumnsUpdate = (groupByColumns) => {
2134
- const newGroupingState = __spreadProps(__spreadValues({}, effectiveGroupingState), {
2135
- groupByColumns
2136
- });
2137
- if (onGroupingChange) {
2138
- onGroupingChange(newGroupingState);
2139
- } else {
2140
- setInternalGroupingState(newGroupingState);
2141
- updateGroupByColumns(groupByColumns);
2142
- }
2143
- };
2144
- const handleRemoveGroupByColumn = (columnId) => {
2145
- const newGroupByColumns = effectiveGroupingState.groupByColumns.filter(
2146
- (id) => id !== columnId
2147
- );
2148
- handleGroupByColumnsUpdate(newGroupByColumns);
2149
- };
2150
- const handleClearGrouping = () => {
2151
- handleGroupByColumnsUpdate([]);
2152
- };
2153
- const handleToggleGroupExpanded = (groupKey) => {
2154
- const isCurrentlyExpanded = !!effectiveGroupingState.expandedGroups[groupKey];
2155
- const newExpandedGroups = __spreadProps(__spreadValues({}, effectiveGroupingState.expandedGroups), {
2156
- [groupKey]: !isCurrentlyExpanded
2157
- });
2158
- const newGroupingState = __spreadProps(__spreadValues({}, effectiveGroupingState), {
2159
- expandedGroups: newExpandedGroups
2160
- });
2161
- if (onGroupingChange) {
2162
- onGroupingChange(newGroupingState);
2163
- } else {
2164
- setInternalGroupingState(newGroupingState);
2165
- toggleGroupExpanded(groupKey, !isCurrentlyExpanded);
2166
- }
2167
- };
2168
- const handleToggleColumnVisibility = (columnId, visible) => {
2169
- toggleColumnVisibility(columnId, visible);
2170
- };
2171
- const handleResetGridPreferences = () => {
2172
- resetPreferences();
2173
- setInternalGroupingState({
2174
- groupByColumns: [],
2175
- expandedGroups: {}
2176
- });
2177
- };
2178
- if (!isLoading && (!data || data.length === 0)) {
2179
- return /* @__PURE__ */ React15.createElement(
2180
- "div",
2181
- {
2182
- className: cn(
2183
- "flex items-center justify-center p-8 border rounded-md",
2184
- theme.classes.container,
2185
- classes.emptyState
2186
- )
2187
- },
2188
- emptyMessage
2189
- );
2190
- }
2191
- if (isLoading) {
2192
- return /* @__PURE__ */ React15.createElement(
2193
- "div",
2194
- {
2195
- className: cn(
2196
- "flex items-center justify-center p-8 border rounded-md",
2197
- theme.classes.container,
2198
- classes.loadingState
2199
- )
2200
- },
2201
- loadingMessage
2202
- );
2203
- }
2204
- const showToolbar = enableGrouping && !hideGroupControls || !hideColumnManager;
2205
- return /* @__PURE__ */ React15.createElement(
2206
- "div",
2207
- {
2208
- className: cn(
2209
- "w-full border rounded-md overflow-hidden",
2210
- theme.classes.container,
2211
- className,
2212
- classes.container
2213
- )
2214
- },
2215
- showToolbar ? /* @__PURE__ */ React15.createElement(
2216
- "div",
2217
- {
2218
- className: cn(
2219
- "p-2 flex items-center justify-end border-b gap-2",
2220
- classes.columnManager
2221
- )
2222
- },
2223
- enableGrouping && !hideGroupControls ? /* @__PURE__ */ React15.createElement(
2224
- GroupManager,
2225
- __spreadValues({
2226
- columns,
2227
- groupByColumns: effectiveGroupingState.groupByColumns,
2228
- updateGroupByColumns: handleGroupByColumnsUpdate,
2229
- removeGroupByColumn: handleRemoveGroupByColumn,
2230
- clearGrouping: handleClearGrouping
2231
- }, groupManagerProps)
2232
- ) : null,
2233
- !hideColumnManager ? /* @__PURE__ */ React15.createElement(
2234
- ColumnManager,
2235
- __spreadValues({
2236
- columns,
2237
- visibleColumns,
2238
- toggleColumnVisibility: handleToggleColumnVisibility,
2239
- resetGridPreferences: handleResetGridPreferences
2240
- }, columnManagerProps)
2241
- ) : null
2242
- ) : null,
2243
- /* @__PURE__ */ React15.createElement("div", { className: "w-full overflow-auto" }, /* @__PURE__ */ React15.createElement("table", { className: "w-full border-separate border-spacing-0" }, /* @__PURE__ */ React15.createElement(
2244
- TableHeader,
2245
- {
2246
- columns: orderedColumns,
2247
- sortState,
2248
- onSortChange: (columnId) => {
2249
- if (!onSortChange || !enableSorting) return;
2250
- let newSortState = null;
2251
- if (!sortState || sortState.column !== columnId) {
2252
- newSortState = { column: columnId, direction: "asc" };
2253
- } else if (sortState.direction === "asc") {
2254
- newSortState = { column: columnId, direction: "desc" };
2255
- }
2256
- onSortChange(newSortState);
2257
- },
2258
- enableSorting,
2259
- filterState: filterState || {},
2260
- filterMenuOpen,
2261
- onFilterMenuToggle: handleFilterMenuToggle,
2262
- columnWidths: preferences.columnWidths,
2263
- onColumnResize: handleColumnResize,
2264
- headerClassName: classes.header,
2265
- filterValueRefs,
2266
- onApplyFilter: handleApplyFilter,
2267
- onClearFilter: handleClearFilter,
2268
- onColumnReorder: handleColumnReorder,
2269
- renderHeader: renderHeader ? (column, sortDirection) => renderHeader({ column, sortDirection }) : void 0,
2270
- renderSortIcon: !!renderSortIcon ? (column, sortDirection) => renderSortIcon({
2271
- isSorted: sortDirection !== void 0,
2272
- sortDirection
2273
- }) : void 0,
2274
- renderFilterIcon: !!renderFilterIcon ? (column, isActive) => renderFilterIcon({
2275
- isFiltered: isActive
2276
- }) : void 0,
2277
- sortIconVariant,
2278
- filterMenu,
2279
- filterMenuRef
2280
- }
2281
- ), /* @__PURE__ */ React15.createElement(
2282
- TableBody,
2283
- {
2284
- paginatedData,
2285
- columns: orderedColumns,
2286
- selectedRows: selectedRows || {},
2287
- enableRowSelection,
2288
- selectedCell,
2289
- onCellSelect: enableCellSelection ? handleCellSelect : void 0,
2290
- selectedCellClassName: classes.selectedCell,
2291
- onRowSelect: (rowId) => {
2292
- if (enableRowSelection && onRowSelectionChange) {
2293
- const newSelectedRows = __spreadValues({}, selectedRows);
2294
- newSelectedRows[rowId] = !newSelectedRows[rowId];
2295
- onRowSelectionChange(newSelectedRows);
2296
- }
2297
- },
2298
- onRowClick,
2299
- rowClassName: classes.row,
2300
- cellClassName: classes.cell,
2301
- columnWidths: preferences.columnWidths,
2302
- theme,
2303
- selectedRowClassName: classes.selectedRow,
2304
- renderCell: renderCell ? (row, column) => renderCell({
2305
- value: row[column.id],
2306
- row,
2307
- column
2308
- }) : void 0,
2309
- enableGrouping,
2310
- groupingState: effectiveGroupingState,
2311
- toggleGroupExpanded: handleToggleGroupExpanded,
2312
- renderGroupRow,
2313
- groupExpandIcon,
2314
- groupCollapseIcon,
2315
- groupRowProps,
2316
- preventRowSelection,
2317
- contextMenuContent,
2318
- enableExpandableRows,
2319
- expandedRows,
2320
- onToggleRowExpand: (rowId) => {
2321
- if (onExpandedRowsChange) {
2322
- const newExpandedRows = __spreadValues({}, expandedRows);
2323
- newExpandedRows[rowId] = !newExpandedRows[rowId];
2324
- onExpandedRowsChange(newExpandedRows);
2325
- }
2326
- },
2327
- renderExpandedRow,
2328
- expandIcon,
2329
- collapseIcon,
2330
- getRowId
2331
- }
2332
- ))),
2333
- effectiveEnablePagination ? /* @__PURE__ */ React15.createElement(
2334
- Pagination,
2335
- __spreadValues({
2336
- pageIndex: pageIndex != null ? pageIndex : 0,
2337
- pageCount: pageCount || Math.max(
2338
- 1,
2339
- Math.ceil(
2340
- (totalRows || (enableGrouping ? flattenedRows.length : data.length)) / (pageSize || 10)
2341
- )
2342
- ),
2343
- pageSize: pageSize || 10,
2344
- totalRows: totalRows || (enableGrouping ? flattenedRows.length : data.length),
2345
- setPageIndex: onPageChange || (() => {
2346
- }),
2347
- setPageSize: onPageSizeChange || (() => {
2348
- }),
2349
- pageSizeOptions,
2350
- processedDataLength: paginatedData.length,
2351
- className: classes.pagination
2352
- }, paginationProps)
2353
- ) : null
2354
- );
2355
- }
2356
-
2357
- // components/data-grid/use-column-resize.ts
2358
- import { useState as useState7, useCallback as useCallback2 } from "react";
2359
- var useColumnResize = (enableColumnResize) => {
2360
- const [columnResizeState, setColumnResizeState] = useState7({});
2361
- const [isResizing, setIsResizing] = useState7(false);
2362
- const handleColumnResizeStart = useCallback2(
2363
- (columnId, startWidth, e) => {
2364
- if (!enableColumnResize) return;
2365
- setIsResizing(true);
2366
- const startX = e.clientX;
2367
- const handleMouseMove = (moveEvent) => {
2368
- const deltaX = moveEvent.clientX - startX;
2369
- const newWidth = Math.max(50, startWidth + deltaX);
2370
- setColumnResizeState((prev) => __spreadProps(__spreadValues({}, prev), {
2371
- [columnId]: newWidth
2372
- }));
2373
- };
2374
- const handleMouseUp = () => {
2375
- document.removeEventListener("mousemove", handleMouseMove);
2376
- document.removeEventListener("mouseup", handleMouseUp);
2377
- setIsResizing(false);
2378
- };
2379
- document.addEventListener("mousemove", handleMouseMove);
2380
- document.addEventListener("mouseup", handleMouseUp);
2381
- },
2382
- [enableColumnResize]
2383
- );
2384
- return {
2385
- columnResizeState,
2386
- isResizing,
2387
- handleColumnResizeStart
2388
- };
2389
- };
2390
-
2391
- // components/theme-provider/theme-switcher.tsx
2392
- import React16 from "react";
2393
- import { Moon, Sun } from "lucide-react";
2394
- var ThemeSwitcher = ({ className }) => {
2395
- const { theme, setTssTheme, setTailwindTheme } = useTheme();
2396
- const isDarkMode = theme.colors.background === "#121314";
2397
- const toggleTheme = () => {
2398
- if (isDarkMode) {
2399
- setTssTheme({
2400
- colors: {
2401
- primary: "#2563eb",
2402
- secondary: "#6b7280",
2403
- background: "#ffffff",
2404
- foreground: "#1e1e21",
2405
- muted: "#f1f5f9",
2406
- mutedForeground: "#64748b",
2407
- border: "#e2e8f0",
2408
- popover: "#ffffff"
2409
- }
2410
- });
2411
- setTailwindTheme({
2412
- container: "bg-background border border-border text-foreground",
2413
- cell: "px-4 py-2 text-sm border-border",
2414
- row: "border-b border-border hover:bg-muted/30"
2415
- });
2416
- } else {
2417
- setTssTheme({
2418
- colors: {
2419
- primary: "#3b82f6",
2420
- secondary: "#9ca3af",
2421
- background: "#121314",
2422
- foreground: "#f8fafc",
2423
- muted: "#1e293b",
2424
- mutedForeground: "#94a3b8",
2425
- border: "#334155",
2426
- popover: "#1a1c1e"
2427
- }
2428
- });
2429
- setTailwindTheme({
2430
- container: "bg-muted border border-border text-foreground",
2431
- cell: "px-4 py-2 text-sm border-border",
2432
- row: "border-b border-border hover:bg-muted/50"
2433
- });
2434
- }
2435
- };
2436
- return /* @__PURE__ */ React16.createElement(
2437
- Button,
2438
- {
2439
- onClick: toggleTheme,
2440
- variant: "outline",
2441
- size: "icon",
2442
- className,
2443
- title: isDarkMode ? "Switch to light mode" : "Switch to dark mode"
2444
- },
2445
- isDarkMode ? /* @__PURE__ */ React16.createElement(Sun, { className: "h-4 w-4" }) : /* @__PURE__ */ React16.createElement(Moon, { className: "h-4 w-4" })
2446
- );
2447
- };
2448
-
2449
- // components/theme-provider/theme-wrapper.tsx
2450
- import React17 from "react";
2451
- var ThemeWrapper = ({
2452
- children,
2453
- customTheme
2454
- }) => {
2455
- return /* @__PURE__ */ React17.createElement(
2456
- ThemeProvider,
2457
- {
2458
- initialTssTheme: __spreadValues({}, customTheme || {})
2459
- },
2460
- /* @__PURE__ */ React17.createElement("div", null, children)
2461
- );
2462
- };
2463
-
2464
- // components/ui/badge.tsx
2465
- import * as React18 from "react";
2466
- import { Slot as Slot2 } from "@radix-ui/react-slot";
2467
- import { cva as cva2 } from "class-variance-authority";
2468
- var badgeVariants = cva2(
2469
- "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-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 transition-[color,box-shadow] overflow-hidden",
2470
- {
2471
- variants: {
2472
- variant: {
2473
- default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
2474
- secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
2475
- destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/70",
2476
- outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
2477
- }
2478
- },
2479
- defaultVariants: {
2480
- variant: "default"
2481
- }
2482
- }
2483
- );
2484
- function Badge(_a) {
2485
- var _b = _a, {
2486
- className,
2487
- variant,
2488
- asChild = false
2489
- } = _b, props = __objRest(_b, [
2490
- "className",
2491
- "variant",
2492
- "asChild"
2493
- ]);
2494
- const Comp = asChild ? Slot2 : "span";
2495
- return /* @__PURE__ */ React18.createElement(
2496
- Comp,
2497
- __spreadValues({
2498
- "data-slot": "badge",
2499
- className: cn(badgeVariants({ variant }), className)
2500
- }, props)
2501
- );
2502
- }
2503
-
2504
- // components/ui/checkbox.tsx
2505
- import * as React19 from "react";
2506
- import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
2507
- import { Check as Check2 } from "lucide-react";
2508
- var Checkbox = React19.forwardRef((_a, ref) => {
2509
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2510
- return /* @__PURE__ */ React19.createElement(
2511
- CheckboxPrimitive.Root,
2512
- __spreadValues({
2513
- ref,
2514
- className: cn(
2515
- "peer h-3.5 w-3.5 shrink-0 border-2 border-border shadow-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-foreground",
2516
- className
2517
- )
2518
- }, props),
2519
- /* @__PURE__ */ React19.createElement(
2520
- CheckboxPrimitive.Indicator,
2521
- {
2522
- className: cn("flex items-center justify-center text-current")
2523
- },
2524
- /* @__PURE__ */ React19.createElement(Check2, { className: "h-3 w-3", strokeWidth: 3 })
2525
- )
2526
- );
2527
- });
2528
- Checkbox.displayName = CheckboxPrimitive.Root.displayName;
2529
-
2530
- // components/ui/input.tsx
2531
- import * as React20 from "react";
2532
- var Input = React20.forwardRef(
2533
- (_a, ref) => {
2534
- var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
2535
- return /* @__PURE__ */ React20.createElement(
2536
- "input",
2537
- __spreadValues({
2538
- type,
2539
- className: cn(
2540
- "flex h-10 w-full border-2 border-border bg-background px-3 py-2 text-sm font-mono font-medium transition-all duration-150 file:border-0 file:bg-transparent file:text-sm file:font-mono file:font-bold file:text-foreground placeholder:text-muted-foreground placeholder:text-xs placeholder:uppercase placeholder:tracking-[0.08em] placeholder:font-bold focus-visible:outline-none focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/20 hover:border-foreground disabled:cursor-not-allowed disabled:opacity-30 disabled:bg-muted shadow-[inset_2px_2px_0_0_rgba(0,0,0,0.1)] dark:shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.05)] focus-visible:shadow-[inset_0_0_0_0_rgba(0,0,0,0)]",
2541
- className
2542
- ),
2543
- ref
2544
- }, props)
2545
- );
2546
- }
2547
- );
2548
- Input.displayName = "Input";
2549
-
2550
- // components/ui/popover.tsx
2551
- import * as React21 from "react";
2552
- import * as PopoverPrimitive from "@radix-ui/react-popover";
2553
- var Popover = PopoverPrimitive.Root;
2554
- var PopoverTrigger = PopoverPrimitive.Trigger;
2555
- var PopoverAnchor = PopoverPrimitive.Anchor;
2556
- var PopoverContent = React21.forwardRef((_a, ref) => {
2557
- var _b = _a, { className, align = "center", sideOffset = 4 } = _b, props = __objRest(_b, ["className", "align", "sideOffset"]);
2558
- return /* @__PURE__ */ React21.createElement(PopoverPrimitive.Portal, null, /* @__PURE__ */ React21.createElement(
2559
- PopoverPrimitive.Content,
2560
- __spreadValues({
2561
- ref,
2562
- align,
2563
- sideOffset,
2564
- className: cn(
2565
- "z-50 w-72 border-2 border-foreground bg-popover p-4 text-popover-foreground shadow-[4px_4px_0_0_rgba(0,0,0,1)] dark:shadow-[4px_4px_0_0_rgba(255,255,255,0.2)] 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-98 data-[state=open]:zoom-in-98",
2566
- className
2567
- )
2568
- }, props)
2569
- ));
2570
- });
2571
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
2572
-
2573
- // components/ui/select.tsx
2574
- import * as React22 from "react";
2575
- import * as SelectPrimitive from "@radix-ui/react-select";
2576
- import { Check as Check3, ChevronDown as ChevronDown4, ChevronUp as ChevronUp2 } from "lucide-react";
2577
- var Select = SelectPrimitive.Root;
2578
- var SelectGroup = SelectPrimitive.Group;
2579
- var SelectValue = SelectPrimitive.Value;
2580
- var SelectTrigger = React22.forwardRef((_a, ref) => {
2581
- var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
2582
- return /* @__PURE__ */ React22.createElement(
2583
- SelectPrimitive.Trigger,
2584
- __spreadValues({
2585
- ref,
2586
- className: cn(
2587
- "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 data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
2588
- className
2589
- )
2590
- }, props),
2591
- children,
2592
- /* @__PURE__ */ React22.createElement(SelectPrimitive.Icon, { asChild: true }, /* @__PURE__ */ React22.createElement(ChevronDown4, { className: "h-4 w-4 opacity-50" }))
2593
- );
2594
- });
2595
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
2596
- var SelectScrollUpButton = React22.forwardRef((_a, ref) => {
2597
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2598
- return /* @__PURE__ */ React22.createElement(
2599
- SelectPrimitive.ScrollUpButton,
2600
- __spreadValues({
2601
- ref,
2602
- className: cn(
2603
- "flex cursor-default items-center justify-center py-1",
2604
- className
2605
- )
2606
- }, props),
2607
- /* @__PURE__ */ React22.createElement(ChevronUp2, { className: "h-4 w-4" })
2608
- );
2609
- });
2610
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
2611
- var SelectScrollDownButton = React22.forwardRef((_a, ref) => {
2612
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2613
- return /* @__PURE__ */ React22.createElement(
2614
- SelectPrimitive.ScrollDownButton,
2615
- __spreadValues({
2616
- ref,
2617
- className: cn(
2618
- "flex cursor-default items-center justify-center py-1",
2619
- className
2620
- )
2621
- }, props),
2622
- /* @__PURE__ */ React22.createElement(ChevronDown4, { className: "h-4 w-4" })
2623
- );
2624
- });
2625
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
2626
- var SelectContent = React22.forwardRef((_a, ref) => {
2627
- var _b = _a, { className, children, position = "popper" } = _b, props = __objRest(_b, ["className", "children", "position"]);
2628
- return /* @__PURE__ */ React22.createElement(SelectPrimitive.Portal, null, /* @__PURE__ */ React22.createElement(
2629
- SelectPrimitive.Content,
2630
- __spreadValues({
2631
- ref,
2632
- className: cn(
2633
- "relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md 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",
2634
- 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",
2635
- className
2636
- ),
2637
- position
2638
- }, props),
2639
- /* @__PURE__ */ React22.createElement(SelectScrollUpButton, null),
2640
- /* @__PURE__ */ React22.createElement(
2641
- SelectPrimitive.Viewport,
2642
- {
2643
- className: cn(
2644
- "p-1",
2645
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
2646
- )
2647
- },
2648
- children
2649
- ),
2650
- /* @__PURE__ */ React22.createElement(SelectScrollDownButton, null)
2651
- ));
2652
- });
2653
- SelectContent.displayName = SelectPrimitive.Content.displayName;
2654
- var SelectLabel = React22.forwardRef((_a, ref) => {
2655
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2656
- return /* @__PURE__ */ React22.createElement(
2657
- SelectPrimitive.Label,
2658
- __spreadValues({
2659
- ref,
2660
- className: cn("px-2 py-1.5 text-sm font-semibold", className)
2661
- }, props)
2662
- );
2663
- });
2664
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
2665
- var SelectItem = React22.forwardRef((_a, ref) => {
2666
- var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
2667
- return /* @__PURE__ */ React22.createElement(
2668
- SelectPrimitive.Item,
2669
- __spreadValues({
2670
- ref,
2671
- className: cn(
2672
- "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",
2673
- className
2674
- )
2675
- }, props),
2676
- /* @__PURE__ */ React22.createElement("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center" }, /* @__PURE__ */ React22.createElement(SelectPrimitive.ItemIndicator, null, /* @__PURE__ */ React22.createElement(Check3, { className: "h-4 w-4" }))),
2677
- /* @__PURE__ */ React22.createElement(SelectPrimitive.ItemText, null, children)
2678
- );
2679
- });
2680
- SelectItem.displayName = SelectPrimitive.Item.displayName;
2681
- var SelectSeparator = React22.forwardRef((_a, ref) => {
2682
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2683
- return /* @__PURE__ */ React22.createElement(
2684
- SelectPrimitive.Separator,
2685
- __spreadValues({
2686
- ref,
2687
- className: cn("-mx-1 my-1 h-px bg-muted", className)
2688
- }, props)
2689
- );
2690
- });
2691
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
2692
- export {
2693
- Badge,
2694
- Button,
2695
- Checkbox,
2696
- ContextMenu,
2697
- ContextMenuCheckboxItem,
2698
- ContextMenuContent,
2699
- ContextMenuGroup,
2700
- ContextMenuItem,
2701
- ContextMenuLabel,
2702
- ContextMenuPortal,
2703
- ContextMenuRadioGroup,
2704
- ContextMenuRadioItem,
2705
- ContextMenuSeparator,
2706
- ContextMenuShortcut,
2707
- ContextMenuSub,
2708
- ContextMenuSubContent,
2709
- ContextMenuSubTrigger,
2710
- ContextMenuTrigger,
2711
- DataGrid,
2712
- DropdownMenu,
2713
- DropdownMenuCheckboxItem,
2714
- DropdownMenuContent,
2715
- DropdownMenuGroup,
2716
- DropdownMenuItem,
2717
- DropdownMenuLabel,
2718
- DropdownMenuPortal,
2719
- DropdownMenuRadioGroup,
2720
- DropdownMenuRadioItem,
2721
- DropdownMenuSeparator,
2722
- DropdownMenuShortcut,
2723
- DropdownMenuSub,
2724
- DropdownMenuSubContent,
2725
- DropdownMenuSubTrigger,
2726
- DropdownMenuTrigger,
2727
- ExpandableRow,
2728
- FilterMenu,
2729
- Input,
2730
- Pagination,
2731
- Popover,
2732
- PopoverAnchor,
2733
- PopoverContent,
2734
- PopoverTrigger,
2735
- Select,
2736
- SelectContent,
2737
- SelectGroup,
2738
- SelectItem,
2739
- SelectLabel,
2740
- SelectScrollDownButton,
2741
- SelectScrollUpButton,
2742
- SelectSeparator,
2743
- SelectTrigger,
2744
- SelectValue,
2745
- TableBody,
2746
- TableCell,
2747
- TableHeader,
2748
- TableRow,
2749
- ThemeProvider,
2750
- ThemeSwitcher,
2751
- ThemeWrapper,
2752
- badgeVariants,
2753
- buttonVariants,
2754
- cn,
2755
- darkTheme,
2756
- lightTheme,
2757
- makeStyles,
2758
- mergeStyles,
2759
- useColumnResize,
2760
- useGridPersistence,
2761
- useStyles,
2762
- useTailwindTheme,
2763
- useTheme,
2764
- useTssStyles,
2765
- useTssTheme
2766
- };