@pagamio/frontend-commons-lib 0.8.212 → 0.8.214

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 (105) hide show
  1. package/lib/api/TanstackQueryProvider.d.ts +146 -0
  2. package/lib/api/TanstackQueryProvider.js +140 -0
  3. package/lib/api/index.d.ts +2 -0
  4. package/lib/api/index.js +2 -0
  5. package/lib/api/tanstackQuery.d.ts +249 -0
  6. package/lib/api/tanstackQuery.js +299 -0
  7. package/lib/components/layout/Sidebar.js +50 -16
  8. package/lib/components/ui/Sheet.d.ts +1 -1
  9. package/lib/context/SidebarContext.d.ts +20 -0
  10. package/lib/dashboard-visuals-v2/DashboardWrapperV2.d.ts +81 -0
  11. package/lib/dashboard-visuals-v2/DashboardWrapperV2.js +217 -0
  12. package/lib/dashboard-visuals-v2/cards/CardGrid.d.ts +22 -0
  13. package/lib/dashboard-visuals-v2/cards/CardGrid.js +27 -0
  14. package/lib/dashboard-visuals-v2/cards/InfoCard.d.ts +7 -0
  15. package/lib/dashboard-visuals-v2/cards/InfoCard.js +26 -0
  16. package/lib/dashboard-visuals-v2/cards/MetricCard.d.ts +7 -0
  17. package/lib/dashboard-visuals-v2/cards/MetricCard.js +37 -0
  18. package/lib/dashboard-visuals-v2/cards/StatCard.d.ts +7 -0
  19. package/lib/dashboard-visuals-v2/cards/StatCard.js +92 -0
  20. package/lib/dashboard-visuals-v2/cards/TopItemsCard.d.ts +7 -0
  21. package/lib/dashboard-visuals-v2/cards/TopItemsCard.js +34 -0
  22. package/lib/dashboard-visuals-v2/cards/TransactionListCard.d.ts +7 -0
  23. package/lib/dashboard-visuals-v2/cards/TransactionListCard.js +24 -0
  24. package/lib/dashboard-visuals-v2/cards/index.d.ts +9 -0
  25. package/lib/dashboard-visuals-v2/cards/index.js +9 -0
  26. package/lib/dashboard-visuals-v2/charts/AreaChart.d.ts +7 -0
  27. package/lib/dashboard-visuals-v2/charts/AreaChart.js +124 -0
  28. package/lib/dashboard-visuals-v2/charts/BarChart.d.ts +7 -0
  29. package/lib/dashboard-visuals-v2/charts/BarChart.js +106 -0
  30. package/lib/dashboard-visuals-v2/charts/BaseChart.d.ts +61 -0
  31. package/lib/dashboard-visuals-v2/charts/BaseChart.js +173 -0
  32. package/lib/dashboard-visuals-v2/charts/DonutChart.d.ts +7 -0
  33. package/lib/dashboard-visuals-v2/charts/DonutChart.js +108 -0
  34. package/lib/dashboard-visuals-v2/charts/HeatmapChart.d.ts +7 -0
  35. package/lib/dashboard-visuals-v2/charts/HeatmapChart.js +101 -0
  36. package/lib/dashboard-visuals-v2/charts/LineChart.d.ts +7 -0
  37. package/lib/dashboard-visuals-v2/charts/LineChart.js +109 -0
  38. package/lib/dashboard-visuals-v2/charts/MixedChart.d.ts +7 -0
  39. package/lib/dashboard-visuals-v2/charts/MixedChart.js +106 -0
  40. package/lib/dashboard-visuals-v2/charts/PieChart.d.ts +7 -0
  41. package/lib/dashboard-visuals-v2/charts/PieChart.js +10 -0
  42. package/lib/dashboard-visuals-v2/charts/RadialChart.d.ts +7 -0
  43. package/lib/dashboard-visuals-v2/charts/RadialChart.js +72 -0
  44. package/lib/dashboard-visuals-v2/charts/index.d.ts +12 -0
  45. package/lib/dashboard-visuals-v2/charts/index.js +12 -0
  46. package/lib/dashboard-visuals-v2/components/DataFetchingVisual.d.ts +0 -0
  47. package/lib/dashboard-visuals-v2/components/DataFetchingVisual.js +1 -0
  48. package/lib/dashboard-visuals-v2/components/index.d.ts +0 -0
  49. package/lib/dashboard-visuals-v2/components/index.js +1 -0
  50. package/lib/dashboard-visuals-v2/hooks/index.d.ts +4 -0
  51. package/lib/dashboard-visuals-v2/hooks/index.js +4 -0
  52. package/lib/dashboard-visuals-v2/hooks/useChartData.d.ts +72 -0
  53. package/lib/dashboard-visuals-v2/hooks/useChartData.js +122 -0
  54. package/lib/dashboard-visuals-v2/index.d.ts +10 -0
  55. package/lib/dashboard-visuals-v2/index.js +16 -0
  56. package/lib/dashboard-visuals-v2/types/card.types.d.ts +237 -0
  57. package/lib/dashboard-visuals-v2/types/card.types.js +30 -0
  58. package/lib/dashboard-visuals-v2/types/chart.types.d.ts +308 -0
  59. package/lib/dashboard-visuals-v2/types/chart.types.js +25 -0
  60. package/lib/dashboard-visuals-v2/types/index.d.ts +6 -0
  61. package/lib/dashboard-visuals-v2/types/index.js +6 -0
  62. package/lib/dashboard-visuals-v2/utils/index.d.ts +0 -0
  63. package/lib/dashboard-visuals-v2/utils/index.js +1 -0
  64. package/lib/dashboard-visuals-v2/utils/propsTransformer.d.ts +0 -0
  65. package/lib/dashboard-visuals-v2/utils/propsTransformer.js +1 -0
  66. package/lib/dashboard-visuals-v2/visualRegistry.d.ts +59 -0
  67. package/lib/dashboard-visuals-v2/visualRegistry.js +110 -0
  68. package/lib/data-table-v2/DataTable.d.ts +7 -0
  69. package/lib/data-table-v2/DataTable.js +206 -0
  70. package/lib/data-table-v2/components/DataTableBody.d.ts +19 -0
  71. package/lib/data-table-v2/components/DataTableBody.js +20 -0
  72. package/lib/data-table-v2/components/DataTableEmpty.d.ts +17 -0
  73. package/lib/data-table-v2/components/DataTableEmpty.js +13 -0
  74. package/lib/data-table-v2/components/DataTableError.d.ts +16 -0
  75. package/lib/data-table-v2/components/DataTableError.js +14 -0
  76. package/lib/data-table-v2/components/DataTableHeader.d.ts +15 -0
  77. package/lib/data-table-v2/components/DataTableHeader.js +31 -0
  78. package/lib/data-table-v2/components/DataTableLoading.d.ts +14 -0
  79. package/lib/data-table-v2/components/DataTableLoading.js +19 -0
  80. package/lib/data-table-v2/components/DataTablePagination.d.ts +36 -0
  81. package/lib/data-table-v2/components/DataTablePagination.js +20 -0
  82. package/lib/data-table-v2/components/DataTableRowActions.d.ts +13 -0
  83. package/lib/data-table-v2/components/DataTableRowActions.js +57 -0
  84. package/lib/data-table-v2/components/DataTableSearch.d.ts +19 -0
  85. package/lib/data-table-v2/components/DataTableSearch.js +33 -0
  86. package/lib/data-table-v2/components/DataTableToolbar.d.ts +54 -0
  87. package/lib/data-table-v2/components/DataTableToolbar.js +28 -0
  88. package/lib/data-table-v2/components/index.d.ts +12 -0
  89. package/lib/data-table-v2/components/index.js +12 -0
  90. package/lib/data-table-v2/hooks/index.d.ts +4 -0
  91. package/lib/data-table-v2/hooks/index.js +4 -0
  92. package/lib/data-table-v2/hooks/useTableData.d.ts +118 -0
  93. package/lib/data-table-v2/hooks/useTableData.js +210 -0
  94. package/lib/data-table-v2/index.d.ts +9 -0
  95. package/lib/data-table-v2/index.js +12 -0
  96. package/lib/data-table-v2/types/index.d.ts +296 -0
  97. package/lib/data-table-v2/types/index.js +1 -0
  98. package/lib/data-table-v2/utils/export.d.ts +26 -0
  99. package/lib/data-table-v2/utils/export.js +92 -0
  100. package/lib/data-table-v2/utils/index.d.ts +4 -0
  101. package/lib/data-table-v2/utils/index.js +4 -0
  102. package/lib/index.d.ts +4 -0
  103. package/lib/index.js +23 -0
  104. package/lib/styles.css +219 -0
  105. package/package.json +7 -1
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview V2 Visual Registry - Maps visual type strings to ApexCharts components
3
+ * Compatible with V1 registry keys for easy migration
4
+ */
5
+ import type React from 'react';
6
+ /**
7
+ * Visual type enum for type-safe visual selection
8
+ */
9
+ export declare const VisualType: {
10
+ readonly BarChart: "BarChart";
11
+ readonly LineChart: "LineChart";
12
+ readonly AreaChart: "AreaChart";
13
+ readonly DonutChart: "DonutChart";
14
+ readonly PieChart: "PieChart";
15
+ readonly HeatmapChart: "HeatmapChart";
16
+ readonly RadialChart: "RadialChart";
17
+ readonly GaugeChart: "GaugeChart";
18
+ readonly MixedChart: "MixedChart";
19
+ readonly BarLineChart: "BarLineChart";
20
+ readonly HorizontalBarChart: "HorizontalBarChart";
21
+ readonly GroupedBarChart: "GroupedBarChart";
22
+ readonly Tile: "Tile";
23
+ readonly StatCard: "StatCard";
24
+ readonly MetricCard: "MetricCard";
25
+ readonly InfoCard: "InfoCard";
26
+ readonly TopItemsCard: "TopItemsCard";
27
+ readonly ItemPerformanceCard: "ItemPerformanceCard";
28
+ readonly TransactionListCard: "TransactionListCard";
29
+ };
30
+ export type VisualTypeKey = keyof typeof VisualType;
31
+ /**
32
+ * V2 Component Registry
33
+ * Maps visual type strings to their corresponding V2 (ApexCharts) components
34
+ */
35
+ declare const visualRegistryV2: Record<string, React.FC<any>>;
36
+ /**
37
+ * Get a visual component from the registry
38
+ * @param type - The visual type string
39
+ * @returns The component or undefined if not found
40
+ */
41
+ export declare function getVisualComponent(type: string): React.FC<any> | undefined;
42
+ /**
43
+ * Check if a visual type is registered
44
+ * @param type - The visual type string
45
+ * @returns Boolean indicating if the type is registered
46
+ */
47
+ export declare function isRegisteredVisual(type: string): boolean;
48
+ /**
49
+ * Get all registered visual types
50
+ * @returns Array of registered visual type strings
51
+ */
52
+ export declare function getRegisteredVisualTypes(): string[];
53
+ /**
54
+ * Register a custom visual component
55
+ * @param type - The visual type string
56
+ * @param component - The React component to register
57
+ */
58
+ export declare function registerVisual(type: string, component: React.FC<any>): void;
59
+ export default visualRegistryV2;
@@ -0,0 +1,110 @@
1
+ import { InfoCard } from './cards/InfoCard';
2
+ import { MetricCard } from './cards/MetricCard';
3
+ import { StatCard } from './cards/StatCard';
4
+ import { TopItemsCard } from './cards/TopItemsCard';
5
+ import { TransactionListCard } from './cards/TransactionListCard';
6
+ import { AreaChart } from './charts/AreaChart';
7
+ import { BarChart } from './charts/BarChart';
8
+ import { DonutChart } from './charts/DonutChart';
9
+ import { HeatmapChart } from './charts/HeatmapChart';
10
+ import { LineChart } from './charts/LineChart';
11
+ import { MixedChart } from './charts/MixedChart';
12
+ import { PieChart } from './charts/PieChart';
13
+ import { RadialChart } from './charts/RadialChart';
14
+ /**
15
+ * Visual type enum for type-safe visual selection
16
+ */
17
+ export const VisualType = {
18
+ // Charts
19
+ BarChart: 'BarChart',
20
+ LineChart: 'LineChart',
21
+ AreaChart: 'AreaChart',
22
+ DonutChart: 'DonutChart',
23
+ PieChart: 'PieChart',
24
+ HeatmapChart: 'HeatmapChart',
25
+ RadialChart: 'RadialChart',
26
+ GaugeChart: 'GaugeChart', // Alias for RadialChart
27
+ MixedChart: 'MixedChart',
28
+ BarLineChart: 'BarLineChart', // Alias for MixedChart
29
+ HorizontalBarChart: 'HorizontalBarChart',
30
+ GroupedBarChart: 'GroupedBarChart',
31
+ // Cards/Tiles
32
+ Tile: 'Tile',
33
+ StatCard: 'StatCard',
34
+ MetricCard: 'MetricCard',
35
+ InfoCard: 'InfoCard',
36
+ TopItemsCard: 'TopItemsCard',
37
+ ItemPerformanceCard: 'ItemPerformanceCard',
38
+ TransactionListCard: 'TransactionListCard',
39
+ };
40
+ /**
41
+ * V2 Component Registry
42
+ * Maps visual type strings to their corresponding V2 (ApexCharts) components
43
+ */
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ const visualRegistryV2 = {
46
+ // Chart components
47
+ BarChart,
48
+ LineChart,
49
+ AreaChart,
50
+ DonutChart,
51
+ PieChart,
52
+ HeatmapChart,
53
+ RadialChart,
54
+ MixedChart,
55
+ // Aliases for V1 compatibility
56
+ GaugeChart: RadialChart,
57
+ MultiGaugeChart: RadialChart,
58
+ SpeedometerChart: RadialChart,
59
+ BarLineChart: MixedChart,
60
+ LineGraph: LineChart,
61
+ // Horizontal bar is bar chart with horizontal prop
62
+ // eslint-disable-next-line @typescript-eslint/naming-convention
63
+ HorizontalBarChart: (props) => BarChart({ ...props, horizontal: true }),
64
+ // Grouped bar is bar chart with multi-series
65
+ GroupedBarChart: BarChart,
66
+ // Card/Tile components
67
+ Tile: StatCard,
68
+ StatCard,
69
+ MetricCard,
70
+ InfoCard,
71
+ TopItemsCard,
72
+ TransactionListCard,
73
+ // Aliases for V1 compatibility
74
+ ItemPerformanceCard: TopItemsCard,
75
+ SelectedEventTile: StatCard,
76
+ };
77
+ /**
78
+ * Get a visual component from the registry
79
+ * @param type - The visual type string
80
+ * @returns The component or undefined if not found
81
+ */
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ export function getVisualComponent(type) {
84
+ return visualRegistryV2[type];
85
+ }
86
+ /**
87
+ * Check if a visual type is registered
88
+ * @param type - The visual type string
89
+ * @returns Boolean indicating if the type is registered
90
+ */
91
+ export function isRegisteredVisual(type) {
92
+ return type in visualRegistryV2;
93
+ }
94
+ /**
95
+ * Get all registered visual types
96
+ * @returns Array of registered visual type strings
97
+ */
98
+ export function getRegisteredVisualTypes() {
99
+ return Object.keys(visualRegistryV2);
100
+ }
101
+ /**
102
+ * Register a custom visual component
103
+ * @param type - The visual type string
104
+ * @param component - The React component to register
105
+ */
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
+ export function registerVisual(type, component) {
108
+ visualRegistryV2[type] = component;
109
+ }
110
+ export default visualRegistryV2;
@@ -0,0 +1,7 @@
1
+ import type { DataTableProps } from './types';
2
+ /**
3
+ * DataTable V2 Component
4
+ * Headless table powered by TanStack Table
5
+ */
6
+ export declare function DataTable<TData>({ data, columns: columnConfig, rowSelection: rowSelectionOptions, pagination: paginationOptions, sorting: sortingOptions, filtering: filteringOptions, columnVisibility: columnVisibilityOptions, export: exportOptions, rowActions, bulkActions, loading, error, emptyMessage, title, description, striped, hoverable, bordered, compact, stickyHeader, maxHeight, onRowClick, onRowDoubleClick, getRowId, rowClassName, className, classNames, headerContent, footerContent, onRefresh, }: DataTableProps<TData>): import("react/jsx-runtime").JSX.Element;
7
+ export default DataTable;
@@ -0,0 +1,206 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable V2 - Main Component using TanStack Table
4
+ */
5
+ import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table';
6
+ import React, { useCallback, useMemo, useState } from 'react';
7
+ import { cn } from '../helpers';
8
+ import { DataTableBody, DataTableEmpty, DataTableError, DataTableHeader, DataTableLoading, DataTablePagination, DataTableRowActions, DataTableToolbar, } from './components';
9
+ /**
10
+ * Convert DataTableColumn to TanStack ColumnDef
11
+ */
12
+ function toColumnDef(column) {
13
+ return {
14
+ id: column.id,
15
+ accessorKey: column.accessorKey,
16
+ accessorFn: column.accessorFn,
17
+ header: column.header,
18
+ cell: column.cell,
19
+ footer: column.footer,
20
+ enableSorting: column.enableSorting ?? true,
21
+ enableColumnFilter: column.enableFiltering ?? false,
22
+ enableHiding: column.enableHiding ?? true,
23
+ size: column.size,
24
+ minSize: column.minSize,
25
+ maxSize: column.maxSize,
26
+ filterFn: column.filterFn,
27
+ aggregationFn: column.aggregationFn,
28
+ meta: {
29
+ align: column.align,
30
+ },
31
+ };
32
+ }
33
+ /**
34
+ * DataTable V2 Component
35
+ * Headless table powered by TanStack Table
36
+ */
37
+ export function DataTable({ data, columns: columnConfig, rowSelection: rowSelectionOptions, pagination: paginationOptions, sorting: sortingOptions, filtering: filteringOptions, columnVisibility: columnVisibilityOptions, export: exportOptions, rowActions, bulkActions, loading = false, error, emptyMessage = 'No data available', title, description, striped = false, hoverable = true, bordered = false, compact = false, stickyHeader = false, maxHeight, onRowClick, onRowDoubleClick, getRowId, rowClassName, className, classNames, headerContent, footerContent, onRefresh, }) {
38
+ // State
39
+ const [sorting, setSorting] = useState(sortingOptions?.initialSorting ?? []);
40
+ const [columnFilters, setColumnFilters] = useState(filteringOptions?.initialFilters ?? []);
41
+ const [globalFilter, setGlobalFilter] = useState('');
42
+ const [columnVisibility, setColumnVisibility] = useState(columnVisibilityOptions?.initialVisibility ?? {});
43
+ const [rowSelectionState, setRowSelectionState] = useState(rowSelectionOptions?.selectedRowIds ?? {});
44
+ // Convert column config to TanStack ColumnDef
45
+ const columns = useMemo(() => {
46
+ const cols = [];
47
+ // Add selection column if enabled
48
+ if (rowSelectionOptions?.enabled) {
49
+ cols.push({
50
+ id: 'select',
51
+ header: rowSelectionOptions.enableSelectAll !== false
52
+ ? ({ table }) => (_jsx("input", { type: "checkbox", checked: table.getIsAllPageRowsSelected(), onChange: table.getToggleAllPageRowsSelectedHandler(), className: "rounded border-gray-300 text-blue-600 focus:ring-blue-500" }))
53
+ : undefined,
54
+ cell: ({ row }) => (_jsx("input", { type: "checkbox", checked: row.getIsSelected(), disabled: !row.getCanSelect(), onChange: row.getToggleSelectedHandler(), onClick: (e) => e.stopPropagation(), className: "rounded border-gray-300 text-blue-600 focus:ring-blue-500" })),
55
+ enableSorting: false,
56
+ enableHiding: false,
57
+ size: 40,
58
+ });
59
+ }
60
+ // Add data columns
61
+ cols.push(...columnConfig.map(toColumnDef));
62
+ // Add actions column if provided
63
+ if (rowActions && rowActions.length > 0) {
64
+ cols.push({
65
+ id: 'actions',
66
+ header: '',
67
+ cell: ({ row }) => _jsx(DataTableRowActions, { row: row.original, actions: rowActions }),
68
+ enableSorting: false,
69
+ enableHiding: false,
70
+ size: 50,
71
+ });
72
+ }
73
+ return cols;
74
+ }, [columnConfig, rowSelectionOptions, rowActions]);
75
+ // Create table instance
76
+ const table = useReactTable({
77
+ data,
78
+ columns,
79
+ state: {
80
+ sorting,
81
+ columnFilters,
82
+ globalFilter,
83
+ columnVisibility,
84
+ rowSelection: rowSelectionState,
85
+ },
86
+ onSortingChange: (updater) => {
87
+ const newSorting = typeof updater === 'function' ? updater(sorting) : updater;
88
+ setSorting(newSorting);
89
+ sortingOptions?.onSortingChange?.(newSorting);
90
+ },
91
+ onColumnFiltersChange: (updater) => {
92
+ const newFilters = typeof updater === 'function' ? updater(columnFilters) : updater;
93
+ setColumnFilters(newFilters);
94
+ filteringOptions?.onFiltersChange?.(newFilters);
95
+ },
96
+ onGlobalFilterChange: setGlobalFilter,
97
+ onColumnVisibilityChange: (updater) => {
98
+ const newVisibility = typeof updater === 'function' ? updater(columnVisibility) : updater;
99
+ setColumnVisibility(newVisibility);
100
+ columnVisibilityOptions?.onVisibilityChange?.(newVisibility);
101
+ },
102
+ onRowSelectionChange: (updater) => {
103
+ const newSelection = typeof updater === 'function' ? updater(rowSelectionState) : updater;
104
+ setRowSelectionState(newSelection);
105
+ },
106
+ getCoreRowModel: getCoreRowModel(),
107
+ getSortedRowModel: sortingOptions?.enabled !== false ? getSortedRowModel() : undefined,
108
+ getFilteredRowModel: filteringOptions?.enabled !== false ? getFilteredRowModel() : undefined,
109
+ getPaginationRowModel: paginationOptions?.enabled !== false ? getPaginationRowModel() : undefined,
110
+ getRowId: getRowId,
111
+ enableRowSelection: rowSelectionOptions?.enabled ?? false,
112
+ enableMultiRowSelection: rowSelectionOptions?.mode !== 'single',
113
+ enableSorting: sortingOptions?.enabled ?? true,
114
+ enableMultiSort: sortingOptions?.enableMultiSort ?? false,
115
+ enableGlobalFilter: filteringOptions?.enableGlobalFilter ?? true,
116
+ enableColumnFilters: filteringOptions?.enableColumnFilters ?? false,
117
+ manualSorting: sortingOptions?.serverSide,
118
+ manualFiltering: filteringOptions?.serverSide,
119
+ manualPagination: paginationOptions?.serverSide,
120
+ pageCount: paginationOptions?.serverSide
121
+ ? Math.ceil((paginationOptions.totalRows ?? 0) / (paginationOptions.pageSize ?? 10))
122
+ : undefined,
123
+ });
124
+ // Update pagination if controlled
125
+ React.useEffect(() => {
126
+ if (paginationOptions?.pageSize) {
127
+ table.setPageSize(paginationOptions.pageSize);
128
+ }
129
+ if (typeof paginationOptions?.pageIndex === 'number') {
130
+ table.setPageIndex(paginationOptions.pageIndex);
131
+ }
132
+ }, [paginationOptions?.pageSize, paginationOptions?.pageIndex, table]);
133
+ // Notify parent of selection changes
134
+ React.useEffect(() => {
135
+ if (rowSelectionOptions?.onSelectionChange) {
136
+ const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
137
+ rowSelectionOptions.onSelectionChange(selectedRows);
138
+ }
139
+ }, [rowSelectionState, table, rowSelectionOptions]);
140
+ // Export handler
141
+ const handleExport = useCallback((format) => {
142
+ if (exportOptions?.onExport) {
143
+ const exportData = table.getFilteredRowModel().rows.map((row) => row.original);
144
+ exportOptions.onExport(format, exportData);
145
+ return;
146
+ }
147
+ // Default export implementation
148
+ const rows = table.getFilteredRowModel().rows;
149
+ const exportColumns = columns.filter((col) => {
150
+ if (col.id === 'select' || col.id === 'actions')
151
+ return false;
152
+ if (exportOptions?.includeColumns?.length) {
153
+ return exportOptions.includeColumns.includes(col.id ?? '');
154
+ }
155
+ if (exportOptions?.excludeColumns?.length) {
156
+ return !exportOptions.excludeColumns.includes(col.id ?? '');
157
+ }
158
+ return true;
159
+ });
160
+ const exportData = rows.map((row) => {
161
+ const rowData = {};
162
+ exportColumns.forEach((col) => {
163
+ const cellValue = row.getValue(col.id ?? '');
164
+ rowData[col.id ?? ''] = cellValue;
165
+ });
166
+ return rowData;
167
+ });
168
+ const filename = exportOptions?.filename ?? 'export';
169
+ if (format === 'csv') {
170
+ const headers = exportColumns.map((col) => col.id ?? '').join(',');
171
+ const csvRows = exportData.map((row) => exportColumns.map((col) => JSON.stringify(row[col.id ?? ''] ?? '')).join(','));
172
+ const csv = [headers, ...csvRows].join('\n');
173
+ downloadFile(csv, `${filename}.csv`, 'text/csv');
174
+ }
175
+ else if (format === 'json') {
176
+ const json = JSON.stringify(exportData, null, 2);
177
+ downloadFile(json, `${filename}.json`, 'application/json');
178
+ }
179
+ }, [table, columns, exportOptions]);
180
+ // Get selected rows for bulk actions
181
+ const selectedRows = useMemo(() => table.getSelectedRowModel().rows.map((row) => row.original), [table, rowSelectionState]);
182
+ // Column count for empty/loading states
183
+ const colCount = columns.length;
184
+ return (_jsxs("div", { className: cn('bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden', className, classNames?.wrapper), children: [_jsx(DataTableToolbar, { title: title, description: description, globalFilter: globalFilter, setGlobalFilter: setGlobalFilter, enableGlobalFilter: filteringOptions?.enableGlobalFilter !== false, globalFilterPlaceholder: filteringOptions?.globalFilterPlaceholder, filterDebounceMs: filteringOptions?.filterDebounceMs, columnVisibility: columnVisibility, setColumnVisibility: setColumnVisibility, columnVisibilityOptions: columnVisibilityOptions, allColumns: table.getAllColumns(), exportOptions: exportOptions, onExport: exportOptions?.enabled ? handleExport : undefined, onRefresh: onRefresh, selectedCount: selectedRows.length, bulkActions: bulkActions, selectedRows: selectedRows, headerContent: headerContent, classNames: classNames }), _jsx("div", { className: cn('overflow-auto', maxHeight && 'overflow-y-auto'), style: { maxHeight: maxHeight }, children: _jsxs("table", { className: cn('w-full text-sm', bordered && 'border-collapse', compact && 'text-xs', classNames?.table), children: [_jsx(DataTableHeader, { table: table, stickyHeader: stickyHeader, classNames: classNames }), loading ? (_jsx(DataTableLoading, { rowCount: 5, colCount: colCount, classNames: classNames })) : error ? (_jsx("tbody", { children: _jsx(DataTableError, { error: error, onRetry: onRefresh, classNames: classNames, colSpan: colCount }) })) : table.getRowModel().rows.length === 0 ? (_jsx("tbody", { children: _jsx(DataTableEmpty, { message: emptyMessage, classNames: classNames, colSpan: colCount }) })) : (_jsx(DataTableBody, { table: table, striped: striped, hoverable: hoverable, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, rowClassName: rowClassName, classNames: classNames }))] }) }), paginationOptions?.enabled !== false && !loading && !error && data.length > 0 && (_jsx(DataTablePagination, { pageIndex: table.getState().pagination.pageIndex, pageSize: table.getState().pagination.pageSize, totalRows: paginationOptions?.serverSide ? (paginationOptions.totalRows ?? 0) : data.length, pageCount: table.getPageCount(), canPreviousPage: table.getCanPreviousPage(), canNextPage: table.getCanNextPage(), previousPage: table.previousPage, nextPage: table.nextPage, firstPage: () => table.setPageIndex(0), lastPage: () => table.setPageIndex(table.getPageCount() - 1), setPageIndex: table.setPageIndex, setPageSize: (size) => {
185
+ table.setPageSize(size);
186
+ paginationOptions?.onPaginationChange?.({
187
+ pageIndex: 0,
188
+ pageSize: size,
189
+ });
190
+ }, options: paginationOptions, classNames: classNames })), footerContent && _jsx("div", { className: "px-4 py-3 border-t border-gray-200", children: footerContent })] }));
191
+ }
192
+ /**
193
+ * Utility function to download file
194
+ */
195
+ function downloadFile(content, filename, mimeType) {
196
+ const blob = new Blob([content], { type: mimeType });
197
+ const url = URL.createObjectURL(blob);
198
+ const link = document.createElement('a');
199
+ link.href = url;
200
+ link.download = filename;
201
+ document.body.appendChild(link);
202
+ link.click();
203
+ document.body.removeChild(link);
204
+ URL.revokeObjectURL(url);
205
+ }
206
+ export default DataTable;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview DataTable Body Component
3
+ */
4
+ import { type Table } from '@tanstack/react-table';
5
+ import type { DataTableClassNames } from '../types';
6
+ interface DataTableBodyProps<TData> {
7
+ table: Table<TData>;
8
+ striped?: boolean;
9
+ hoverable?: boolean;
10
+ onRowClick?: (row: TData) => void;
11
+ onRowDoubleClick?: (row: TData) => void;
12
+ rowClassName?: string | ((row: TData, index: number) => string);
13
+ classNames?: DataTableClassNames;
14
+ }
15
+ /**
16
+ * DataTable Body Component
17
+ */
18
+ export declare function DataTableBody<TData>({ table, striped, hoverable, onRowClick, onRowDoubleClick, rowClassName, classNames, }: DataTableBodyProps<TData>): import("react/jsx-runtime").JSX.Element;
19
+ export default DataTableBody;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Body Component
4
+ */
5
+ import { flexRender } from '@tanstack/react-table';
6
+ import { cn } from '../../helpers';
7
+ /**
8
+ * DataTable Body Component
9
+ */
10
+ export function DataTableBody({ table, striped, hoverable, onRowClick, onRowDoubleClick, rowClassName, classNames, }) {
11
+ const rows = table.getRowModel().rows;
12
+ return (_jsx("tbody", { className: cn('divide-y divide-gray-200', classNames?.tbody), children: rows.map((row, index) => {
13
+ const customClassName = typeof rowClassName === 'function' ? rowClassName(row.original, index) : rowClassName;
14
+ return (_jsx("tr", { className: cn('transition-colors', striped && index % 2 === 1 && 'bg-gray-50/50', hoverable && 'hover:bg-gray-50', (onRowClick || onRowDoubleClick) && 'cursor-pointer', row.getIsSelected() && 'bg-blue-50', customClassName, classNames?.tr), onClick: () => onRowClick?.(row.original), onDoubleClick: () => onRowDoubleClick?.(row.original), children: row.getVisibleCells().map((cell) => {
15
+ const alignment = cell.column.columnDef.meta?.align ?? 'left';
16
+ return (_jsx("td", { className: cn('px-4 py-3 text-sm text-gray-900', alignment === 'center' && 'text-center', alignment === 'right' && 'text-right', classNames?.td), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
17
+ }) }, row.id));
18
+ }) }));
19
+ }
20
+ export default DataTableBody;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { DataTableClassNames } from '../types';
3
+ interface DataTableEmptyProps {
4
+ /** Empty message */
5
+ message?: string | React.ReactNode;
6
+ /** Custom icon */
7
+ icon?: React.ReactNode;
8
+ /** Custom classNames */
9
+ classNames?: DataTableClassNames;
10
+ /** Number of columns for colspan */
11
+ colSpan?: number;
12
+ }
13
+ /**
14
+ * DataTable Empty State Component
15
+ */
16
+ export declare function DataTableEmpty({ message, icon, classNames, colSpan }: DataTableEmptyProps): import("react/jsx-runtime").JSX.Element;
17
+ export default DataTableEmpty;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Empty State Component
4
+ */
5
+ import { Inbox } from 'lucide-react';
6
+ import { cn } from '../../helpers';
7
+ /**
8
+ * DataTable Empty State Component
9
+ */
10
+ export function DataTableEmpty({ message = 'No data available', icon, classNames, colSpan = 1 }) {
11
+ return (_jsx("tr", { children: _jsx("td", { colSpan: colSpan, className: cn('px-4 py-12', classNames?.empty), children: _jsxs("div", { className: "flex flex-col items-center justify-center text-gray-500", children: [icon ?? _jsx(Inbox, { className: "w-12 h-12 mb-3 text-gray-300" }), _jsx("div", { className: "text-sm", children: message })] }) }) }));
12
+ }
13
+ export default DataTableEmpty;
@@ -0,0 +1,16 @@
1
+ import type { DataTableClassNames } from '../types';
2
+ interface DataTableErrorProps {
3
+ /** Error message or object */
4
+ error?: Error | string | null;
5
+ /** Retry handler */
6
+ onRetry?: () => void;
7
+ /** Custom classNames */
8
+ classNames?: DataTableClassNames;
9
+ /** Number of columns for colspan */
10
+ colSpan?: number;
11
+ }
12
+ /**
13
+ * DataTable Error State Component
14
+ */
15
+ export declare function DataTableError({ error, onRetry, classNames, colSpan }: DataTableErrorProps): import("react/jsx-runtime").JSX.Element;
16
+ export default DataTableError;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Error State Component
4
+ */
5
+ import { AlertCircle, RefreshCw } from 'lucide-react';
6
+ import { cn } from '../../helpers';
7
+ /**
8
+ * DataTable Error State Component
9
+ */
10
+ export function DataTableError({ error, onRetry, classNames, colSpan = 1 }) {
11
+ const errorMessage = error instanceof Error ? error.message : typeof error === 'string' ? error : 'An error occurred while loading data';
12
+ return (_jsx("tr", { children: _jsx("td", { colSpan: colSpan, className: cn('px-4 py-12', classNames?.error), children: _jsxs("div", { className: "flex flex-col items-center justify-center", children: [_jsx(AlertCircle, { className: "w-12 h-12 mb-3 text-red-400" }), _jsx("div", { className: "text-sm text-red-600 mb-3", children: errorMessage }), onRetry && (_jsxs("button", { onClick: onRetry, className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 transition-colors", children: [_jsx(RefreshCw, { className: "w-4 h-4" }), "Retry"] }))] }) }) }));
13
+ }
14
+ export default DataTableError;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview DataTable Header Component
3
+ */
4
+ import { type Table } from '@tanstack/react-table';
5
+ import type { DataTableClassNames } from '../types';
6
+ interface DataTableHeaderProps<TData> {
7
+ table: Table<TData>;
8
+ stickyHeader?: boolean;
9
+ classNames?: DataTableClassNames;
10
+ }
11
+ /**
12
+ * DataTable Header Component
13
+ */
14
+ export declare function DataTableHeader<TData>({ table, stickyHeader, classNames }: DataTableHeaderProps<TData>): import("react/jsx-runtime").JSX.Element;
15
+ export default DataTableHeader;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Header Component
4
+ */
5
+ import { flexRender } from '@tanstack/react-table';
6
+ import { ChevronDown, ChevronUp, ChevronsUpDown } from 'lucide-react';
7
+ import { cn } from '../../helpers';
8
+ /**
9
+ * Sort indicator component
10
+ */
11
+ function SortIndicator({ direction }) {
12
+ if (direction === 'asc') {
13
+ return _jsx(ChevronUp, { className: "w-4 h-4 ml-1" });
14
+ }
15
+ if (direction === 'desc') {
16
+ return _jsx(ChevronDown, { className: "w-4 h-4 ml-1" });
17
+ }
18
+ return _jsx(ChevronsUpDown, { className: "w-4 h-4 ml-1 opacity-30" });
19
+ }
20
+ /**
21
+ * DataTable Header Component
22
+ */
23
+ export function DataTableHeader({ table, stickyHeader, classNames }) {
24
+ return (_jsx("thead", { className: cn('bg-gray-50 border-b border-gray-200', stickyHeader && 'sticky top-0 z-10', classNames?.thead), children: table.getHeaderGroups().map((headerGroup) => (_jsx("tr", { className: classNames?.tr, children: headerGroup.headers.map((header) => {
25
+ const canSort = header.column.getCanSort();
26
+ const sortDirection = header.column.getIsSorted();
27
+ const alignment = header.column.columnDef.meta?.align ?? 'left';
28
+ return (_jsx("th", { colSpan: header.colSpan, style: { width: header.getSize() !== 150 ? header.getSize() : undefined }, className: cn('px-4 py-3 text-xs font-semibold text-gray-600 uppercase tracking-wider', alignment === 'center' && 'text-center', alignment === 'right' && 'text-right', canSort && 'cursor-pointer select-none hover:bg-gray-100', classNames?.th), onClick: canSort ? header.column.getToggleSortingHandler() : undefined, children: header.isPlaceholder ? null : (_jsxs("div", { className: cn('flex items-center', alignment === 'center' && 'justify-center', alignment === 'right' && 'justify-end'), children: [flexRender(header.column.columnDef.header, header.getContext()), canSort && _jsx(SortIndicator, { direction: sortDirection })] })) }, header.id));
29
+ }) }, headerGroup.id))) }));
30
+ }
31
+ export default DataTableHeader;
@@ -0,0 +1,14 @@
1
+ import type { DataTableClassNames } from '../types';
2
+ interface DataTableLoadingProps {
3
+ /** Number of skeleton rows */
4
+ rowCount?: number;
5
+ /** Number of columns for skeleton */
6
+ colCount?: number;
7
+ /** Custom classNames */
8
+ classNames?: DataTableClassNames;
9
+ }
10
+ /**
11
+ * DataTable Loading State Component
12
+ */
13
+ export declare function DataTableLoading({ rowCount, colCount, classNames }: DataTableLoadingProps): import("react/jsx-runtime").JSX.Element;
14
+ export default DataTableLoading;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../../helpers';
3
+ /**
4
+ * DataTable Loading State Component
5
+ */
6
+ export function DataTableLoading({ rowCount = 5, colCount = 4, classNames }) {
7
+ return (_jsx("tbody", { className: cn('animate-pulse', classNames?.loading), children: Array.from({ length: rowCount })
8
+ .map((value, index) => {
9
+ void value;
10
+ return index;
11
+ })
12
+ .map((rowIndex) => (_jsx("tr", { className: "border-b border-gray-100", children: Array.from({ length: colCount })
13
+ .map((value, index) => {
14
+ void value;
15
+ return index;
16
+ })
17
+ .map((colIndex) => (_jsx("td", { className: "px-4 py-3", children: _jsx("div", { className: "h-4 bg-gray-200 rounded w-full max-w-[150px]" }) }, colIndex))) }, rowIndex))) }));
18
+ }
19
+ export default DataTableLoading;
@@ -0,0 +1,36 @@
1
+ import type { DataTableClassNames, PaginationOptions } from '../types';
2
+ interface DataTablePaginationProps {
3
+ /** Current page index (0-based) */
4
+ pageIndex: number;
5
+ /** Items per page */
6
+ pageSize: number;
7
+ /** Total number of rows */
8
+ totalRows: number;
9
+ /** Total number of pages */
10
+ pageCount: number;
11
+ /** Can go to previous page */
12
+ canPreviousPage: boolean;
13
+ /** Can go to next page */
14
+ canNextPage: boolean;
15
+ /** Go to previous page */
16
+ previousPage: () => void;
17
+ /** Go to next page */
18
+ nextPage: () => void;
19
+ /** Go to first page */
20
+ firstPage: () => void;
21
+ /** Go to last page */
22
+ lastPage: () => void;
23
+ /** Set page index */
24
+ setPageIndex: (index: number) => void;
25
+ /** Set page size */
26
+ setPageSize: (size: number) => void;
27
+ /** Pagination options */
28
+ options?: PaginationOptions;
29
+ /** Custom classNames */
30
+ classNames?: DataTableClassNames;
31
+ }
32
+ /**
33
+ * DataTable Pagination Component
34
+ */
35
+ export declare function DataTablePagination({ pageIndex, pageSize, totalRows, pageCount, canPreviousPage, canNextPage, previousPage, nextPage, firstPage, lastPage, setPageIndex, setPageSize, options, classNames, }: DataTablePaginationProps): import("react/jsx-runtime").JSX.Element;
36
+ export default DataTablePagination;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Pagination Component
4
+ */
5
+ import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';
6
+ import { cn } from '../../helpers';
7
+ /**
8
+ * DataTable Pagination Component
9
+ */
10
+ export function DataTablePagination({ pageIndex, pageSize, totalRows, pageCount, canPreviousPage, canNextPage, previousPage, nextPage, firstPage, lastPage, setPageIndex, setPageSize, options = {}, classNames, }) {
11
+ const { pageSizeOptions = [10, 25, 50, 100], showPageSizeSelector = true, showPageInfo = true } = options;
12
+ // Calculate display range
13
+ const start = totalRows === 0 ? 0 : pageIndex * pageSize + 1;
14
+ const end = Math.min((pageIndex + 1) * pageSize, totalRows);
15
+ return (_jsxs("div", { className: cn('flex items-center justify-between px-4 py-3 border-t border-gray-200 bg-white', classNames?.pagination), children: [_jsx("div", { className: "flex items-center gap-2", children: showPageSizeSelector && (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-sm text-gray-600", children: "Rows per page:" }), _jsx("select", { value: pageSize, onChange: (e) => setPageSize(Number(e.target.value)), className: "px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent", children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) })] })) }), showPageInfo && (_jsxs("div", { className: "text-sm text-gray-600", children: [start, "-", end, " of ", totalRows.toLocaleString()] })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: firstPage, disabled: !canPreviousPage, className: cn('p-1.5 rounded-md transition-colors', canPreviousPage ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed'), "aria-label": "First page", children: _jsx(ChevronsLeft, { className: "w-4 h-4" }) }), _jsx("button", { onClick: previousPage, disabled: !canPreviousPage, className: cn('p-1.5 rounded-md transition-colors', canPreviousPage ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed'), "aria-label": "Previous page", children: _jsx(ChevronLeft, { className: "w-4 h-4" }) }), _jsxs("div", { className: "flex items-center gap-1 mx-2", children: [_jsx("span", { className: "text-sm text-gray-600", children: "Page" }), _jsx("input", { type: "number", min: 1, max: pageCount, value: pageIndex + 1, onChange: (e) => {
16
+ const page = e.target.value ? Number(e.target.value) - 1 : 0;
17
+ setPageIndex(Math.min(Math.max(0, page), pageCount - 1));
18
+ }, className: "w-14 px-2 py-1 text-sm text-center border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" }), _jsxs("span", { className: "text-sm text-gray-600", children: ["of ", pageCount] })] }), _jsx("button", { onClick: nextPage, disabled: !canNextPage, className: cn('p-1.5 rounded-md transition-colors', canNextPage ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed'), "aria-label": "Next page", children: _jsx(ChevronRight, { className: "w-4 h-4" }) }), _jsx("button", { onClick: lastPage, disabled: !canNextPage, className: cn('p-1.5 rounded-md transition-colors', canNextPage ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed'), "aria-label": "Last page", children: _jsx(ChevronsRight, { className: "w-4 h-4" }) })] })] }));
19
+ }
20
+ export default DataTablePagination;