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