@ackplus/react-tanstack-data-table 1.0.19-beta-0.7 → 1.0.19-beta-0.8

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 (125) hide show
  1. package/README.md +599 -0
  2. package/package.json +1 -1
  3. package/src/index.d.ts +19 -0
  4. package/src/index.js +31 -0
  5. package/src/lib/components/droupdown/menu-dropdown.d.ts +17 -0
  6. package/src/lib/components/droupdown/menu-dropdown.js +52 -0
  7. package/src/lib/components/filters/filter-value-input.d.ts +9 -0
  8. package/src/lib/components/filters/filter-value-input.js +58 -0
  9. package/src/lib/components/filters/index.d.ts +23 -0
  10. package/src/lib/components/filters/index.js +129 -0
  11. package/src/lib/components/headers/draggable-header.d.ts +12 -0
  12. package/src/lib/components/headers/draggable-header.js +212 -0
  13. package/src/lib/components/headers/index.d.ts +2 -0
  14. package/src/lib/components/headers/index.js +5 -0
  15. package/src/lib/components/headers/table-header.d.ts +10 -0
  16. package/src/lib/components/headers/table-header.js +48 -0
  17. package/src/lib/components/index.d.ts +7 -0
  18. package/src/lib/components/index.js +10 -0
  19. package/src/lib/components/pagination/data-table-pagination.d.ts +11 -0
  20. package/src/lib/components/pagination/data-table-pagination.js +25 -0
  21. package/src/lib/components/pagination/index.d.ts +1 -0
  22. package/src/lib/components/pagination/index.js +4 -0
  23. package/src/lib/components/rows/data-table-row.d.ts +13 -0
  24. package/src/lib/components/rows/data-table-row.js +31 -0
  25. package/src/lib/components/rows/empty-data-row.d.ts +6 -0
  26. package/src/lib/components/rows/empty-data-row.js +11 -0
  27. package/src/lib/components/rows/index.d.ts +3 -0
  28. package/src/lib/components/rows/index.js +6 -0
  29. package/src/lib/components/rows/loading-rows.d.ts +5 -0
  30. package/src/lib/components/rows/loading-rows.js +49 -0
  31. package/src/lib/components/table/data-table.d.ts +3 -0
  32. package/src/lib/components/table/data-table.js +492 -0
  33. package/src/lib/components/table/data-table.types.d.ts +114 -0
  34. package/src/lib/components/table/data-table.types.js +2 -0
  35. package/src/lib/components/table/index.d.ts +2 -0
  36. package/src/lib/components/table/index.js +5 -0
  37. package/src/lib/components/toolbar/bulk-actions-toolbar.d.ts +9 -0
  38. package/src/lib/components/toolbar/bulk-actions-toolbar.js +25 -0
  39. package/src/lib/components/toolbar/column-custom-filter-control.d.ts +1 -0
  40. package/src/lib/components/toolbar/column-custom-filter-control.js +137 -0
  41. package/src/lib/components/toolbar/column-pinning-control.d.ts +1 -0
  42. package/src/lib/components/toolbar/column-pinning-control.js +105 -0
  43. package/src/lib/components/toolbar/column-reset-control.d.ts +1 -0
  44. package/src/lib/components/toolbar/column-reset-control.js +16 -0
  45. package/src/lib/components/toolbar/column-visibility-control.d.ts +1 -0
  46. package/src/lib/components/toolbar/column-visibility-control.js +31 -0
  47. package/src/lib/components/toolbar/data-table-toolbar.d.ts +14 -0
  48. package/src/lib/components/toolbar/data-table-toolbar.js +26 -0
  49. package/src/lib/components/toolbar/index.d.ts +8 -0
  50. package/src/lib/components/toolbar/index.js +17 -0
  51. package/src/lib/components/toolbar/table-export-control.d.ts +25 -0
  52. package/src/lib/components/toolbar/table-export-control.js +93 -0
  53. package/src/lib/components/toolbar/table-search-control.d.ts +1 -0
  54. package/src/lib/components/toolbar/table-search-control.js +61 -0
  55. package/src/lib/components/toolbar/table-size-control.d.ts +1 -0
  56. package/src/lib/components/toolbar/table-size-control.js +36 -0
  57. package/src/lib/contexts/data-table-context.d.ts +43 -0
  58. package/src/lib/contexts/data-table-context.js +54 -0
  59. package/src/lib/examples/advanced-features-example.d.ts +1 -0
  60. package/src/lib/examples/advanced-features-example.js +264 -0
  61. package/src/lib/examples/bulk-actions-test.d.ts +1 -0
  62. package/src/lib/examples/bulk-actions-test.js +44 -0
  63. package/src/lib/examples/custom-column-filter-example.d.ts +1 -0
  64. package/src/lib/examples/custom-column-filter-example.js +60 -0
  65. package/src/lib/examples/index.d.ts +5 -0
  66. package/src/lib/examples/index.js +13 -0
  67. package/src/lib/examples/selection-test-example.d.ts +1 -0
  68. package/src/lib/examples/selection-test-example.js +101 -0
  69. package/src/lib/examples/simple-local-example.d.ts +1 -0
  70. package/src/lib/examples/simple-local-example.js +97 -0
  71. package/src/lib/features/custom-column-filter.feature.d.ts +45 -0
  72. package/src/lib/features/custom-column-filter.feature.js +247 -0
  73. package/src/lib/features/custom-selection.feature.d.ts +46 -0
  74. package/src/lib/features/custom-selection.feature.js +172 -0
  75. package/src/lib/features/index.d.ts +2 -0
  76. package/src/lib/features/index.js +8 -0
  77. package/src/lib/hooks/index.d.ts +1 -0
  78. package/src/lib/hooks/index.js +4 -0
  79. package/src/lib/hooks/use-data-table-api.d.ts +56 -0
  80. package/src/lib/hooks/use-data-table-api.js +616 -0
  81. package/src/lib/icons/add-icon.d.ts +2 -0
  82. package/src/lib/icons/add-icon.js +8 -0
  83. package/src/lib/icons/csv-icon.d.ts +2 -0
  84. package/src/lib/icons/csv-icon.js +8 -0
  85. package/src/lib/icons/delete-icon.d.ts +2 -0
  86. package/src/lib/icons/delete-icon.js +8 -0
  87. package/src/lib/icons/excel-icon.d.ts +2 -0
  88. package/src/lib/icons/excel-icon.js +8 -0
  89. package/src/lib/icons/index.d.ts +7 -0
  90. package/src/lib/icons/index.js +17 -0
  91. package/src/lib/icons/unpin-icon.d.ts +2 -0
  92. package/src/lib/icons/unpin-icon.js +8 -0
  93. package/src/lib/icons/view-comfortable-icon.d.ts +2 -0
  94. package/src/lib/icons/view-comfortable-icon.js +8 -0
  95. package/src/lib/icons/view-compact-icon.d.ts +2 -0
  96. package/src/lib/icons/view-compact-icon.js +8 -0
  97. package/src/lib/types/column.types.d.ts +29 -0
  98. package/src/lib/types/column.types.js +5 -0
  99. package/src/lib/types/data-table-api.d.ts +134 -0
  100. package/src/lib/types/data-table-api.js +2 -0
  101. package/src/lib/types/export.types.d.ts +99 -0
  102. package/src/lib/types/export.types.js +2 -0
  103. package/src/lib/types/index.d.ts +6 -0
  104. package/src/lib/types/index.js +8 -0
  105. package/src/lib/types/slots.types.d.ts +272 -0
  106. package/src/lib/types/slots.types.js +2 -0
  107. package/src/lib/types/table.types.d.ts +63 -0
  108. package/src/lib/types/table.types.js +2 -0
  109. package/src/lib/utils/column-helpers.d.ts +7 -0
  110. package/src/lib/utils/column-helpers.js +43 -0
  111. package/src/lib/utils/debounced-fetch.utils.d.ts +11 -0
  112. package/src/lib/utils/debounced-fetch.utils.js +49 -0
  113. package/src/lib/utils/export-utils.d.ts +30 -0
  114. package/src/lib/utils/export-utils.js +152 -0
  115. package/src/lib/utils/index.d.ts +7 -0
  116. package/src/lib/utils/index.js +10 -0
  117. package/src/lib/utils/slot-helpers.d.ts +9 -0
  118. package/src/lib/utils/slot-helpers.js +21 -0
  119. package/src/lib/utils/special-columns.utils.d.ts +6 -0
  120. package/src/lib/utils/special-columns.utils.js +52 -0
  121. package/src/lib/utils/styling-helpers.d.ts +36 -0
  122. package/src/lib/utils/styling-helpers.js +61 -0
  123. package/src/lib/utils/table-helpers.d.ts +9 -0
  124. package/src/lib/utils/table-helpers.js +57 -0
  125. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CustomColumnFilterExample = CustomColumnFilterExample;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const material_1 = require("@mui/material");
7
+ const data_table_1 = require("../components/table/data-table");
8
+ const sampleData = [
9
+ { id: 1, name: 'John Doe', age: 30, department: 'Engineering', salary: 75000, isActive: true },
10
+ { id: 2, name: 'Jane Smith', age: 25, department: 'Marketing', salary: 60000, isActive: true },
11
+ { id: 3, name: 'Bob Johnson', age: 35, department: 'Engineering', salary: 85000, isActive: false },
12
+ { id: 4, name: 'Alice Brown', age: 28, department: 'HR', salary: 55000, isActive: true },
13
+ { id: 5, name: 'Charlie Wilson', age: 42, department: 'Sales', salary: 70000, isActive: true },
14
+ ];
15
+ const columns = [
16
+ {
17
+ accessorKey: 'name',
18
+ header: 'Name',
19
+ type: 'text',
20
+ },
21
+ {
22
+ accessorKey: 'age',
23
+ header: 'Age',
24
+ type: 'number',
25
+ },
26
+ {
27
+ accessorKey: 'department',
28
+ header: 'Department',
29
+ type: 'select',
30
+ options: [
31
+ { label: 'Engineering', value: 'Engineering' },
32
+ { label: 'Marketing', value: 'Marketing' },
33
+ { label: 'HR', value: 'HR' },
34
+ { label: 'Sales', value: 'Sales' },
35
+ ],
36
+ },
37
+ {
38
+ accessorKey: 'salary',
39
+ header: 'Salary',
40
+ type: 'number',
41
+ cell: ({ getValue }) => {
42
+ const value = getValue();
43
+ return new Intl.NumberFormat('en-US', {
44
+ style: 'currency',
45
+ currency: 'USD',
46
+ }).format(value);
47
+ },
48
+ },
49
+ {
50
+ accessorKey: 'isActive',
51
+ header: 'Active',
52
+ type: 'boolean',
53
+ },
54
+ ];
55
+ function CustomColumnFilterExample() {
56
+ const [data] = (0, react_1.useState)(sampleData);
57
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { p: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h4", gutterBottom: true, children: "Custom Column Filter Feature Example" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body1", sx: { mb: 3 }, children: "Click the filter icon in the toolbar to test the custom column filter feature." }), (0, jsx_runtime_1.jsx)(data_table_1.DataTable, { data: data, columns: columns, enableColumnFilter: true, enableGlobalFilter: true, enablePagination: true, enableSorting: true, onColumnFiltersChange: (filterState) => {
58
+ console.log('Custom Column Filter State Changed:', filterState);
59
+ } })] }));
60
+ }
@@ -0,0 +1,5 @@
1
+ export { CustomColumnFilterExample } from './custom-column-filter-example';
2
+ export { SelectionTestExample } from './selection-test-example';
3
+ export { AdvancedFeaturesExample } from './advanced-features-example';
4
+ export { SimpleLocalExample } from './simple-local-example';
5
+ export { BulkActionsTest } from './bulk-actions-test';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BulkActionsTest = exports.SimpleLocalExample = exports.AdvancedFeaturesExample = exports.SelectionTestExample = exports.CustomColumnFilterExample = void 0;
4
+ var custom_column_filter_example_1 = require("./custom-column-filter-example");
5
+ Object.defineProperty(exports, "CustomColumnFilterExample", { enumerable: true, get: function () { return custom_column_filter_example_1.CustomColumnFilterExample; } });
6
+ var selection_test_example_1 = require("./selection-test-example");
7
+ Object.defineProperty(exports, "SelectionTestExample", { enumerable: true, get: function () { return selection_test_example_1.SelectionTestExample; } });
8
+ var advanced_features_example_1 = require("./advanced-features-example");
9
+ Object.defineProperty(exports, "AdvancedFeaturesExample", { enumerable: true, get: function () { return advanced_features_example_1.AdvancedFeaturesExample; } });
10
+ var simple_local_example_1 = require("./simple-local-example");
11
+ Object.defineProperty(exports, "SimpleLocalExample", { enumerable: true, get: function () { return simple_local_example_1.SimpleLocalExample; } });
12
+ var bulk_actions_test_1 = require("./bulk-actions-test");
13
+ Object.defineProperty(exports, "BulkActionsTest", { enumerable: true, get: function () { return bulk_actions_test_1.BulkActionsTest; } });
@@ -0,0 +1 @@
1
+ export declare function SelectionTestExample(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectionTestExample = SelectionTestExample;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const material_1 = require("@mui/material");
7
+ const components_1 = require("../components");
8
+ const generateSampleData = () => {
9
+ const departments = ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance'];
10
+ const firstNames = ['John', 'Jane', 'Bob', 'Alice', 'Charlie', 'Diana', 'Eva', 'Frank', 'Grace', 'Henry'];
11
+ const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Rodriguez', 'Martinez'];
12
+ return Array.from({ length: 25 }, (_, index) => ({
13
+ id: index + 1,
14
+ name: `${firstNames[index % firstNames.length]} ${lastNames[index % lastNames.length]}`,
15
+ email: `user${index + 1}@example.com`,
16
+ department: departments[index % departments.length],
17
+ salary: 50000 + (index * 5000),
18
+ isActive: Math.random() > 0.3,
19
+ }));
20
+ };
21
+ const sampleData = generateSampleData();
22
+ const columns = [
23
+ {
24
+ accessorKey: 'name',
25
+ header: 'Name',
26
+ size: 150,
27
+ },
28
+ {
29
+ accessorKey: 'email',
30
+ header: 'Email',
31
+ size: 200,
32
+ },
33
+ {
34
+ accessorKey: 'department',
35
+ header: 'Department',
36
+ size: 120,
37
+ },
38
+ {
39
+ accessorKey: 'salary',
40
+ header: 'Salary',
41
+ size: 100,
42
+ cell: ({ getValue }) => `$${getValue().toLocaleString()}`,
43
+ },
44
+ {
45
+ accessorKey: 'isActive',
46
+ header: 'Status',
47
+ size: 100,
48
+ cell: ({ getValue }) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: getValue() ? 'Active' : 'Inactive', color: getValue() ? 'success' : 'default', size: "small" })),
49
+ },
50
+ ];
51
+ function SelectionTestExample() {
52
+ const [selectMode, setSelectMode] = (0, react_1.useState)('page');
53
+ const [selectionState, setSelectionState] = (0, react_1.useState)({
54
+ ids: [],
55
+ type: 'include',
56
+ });
57
+ const tableRef = (0, react_1.useRef)(null);
58
+ const handleSelectionChange = (0, react_1.useCallback)((newSelectionState) => {
59
+ setSelectionState(newSelectionState);
60
+ }, []);
61
+ const handleSelectAll = (0, react_1.useCallback)(() => {
62
+ var _a;
63
+ (_a = tableRef.current) === null || _a === void 0 ? void 0 : _a.selection.selectAll();
64
+ }, []);
65
+ const handleDeselectAll = (0, react_1.useCallback)(() => {
66
+ var _a;
67
+ (_a = tableRef.current) === null || _a === void 0 ? void 0 : _a.selection.deselectAll();
68
+ }, []);
69
+ const handleSelectFirst5 = (0, react_1.useCallback)(() => {
70
+ const firstFiveIds = sampleData.slice(0, 5).map(user => user.id.toString());
71
+ firstFiveIds.forEach(id => {
72
+ var _a;
73
+ (_a = tableRef.current) === null || _a === void 0 ? void 0 : _a.selection.selectRow(id);
74
+ });
75
+ }, []);
76
+ const handleToggleRow = (0, react_1.useCallback)(() => {
77
+ var _a;
78
+ (_a = tableRef.current) === null || _a === void 0 ? void 0 : _a.selection.toggleRowSelection('3');
79
+ }, []);
80
+ const isRowSelectable = (0, react_1.useCallback)(({ row }) => {
81
+ return row.salary <= 100000;
82
+ }, []);
83
+ const selectedCount = selectionState.ids.length;
84
+ const selectedType = selectionState.type;
85
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { p: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h4", gutterBottom: true, children: "Selection Test Example" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body1", color: "text.secondary", sx: { mb: 3 }, children: "Test the custom selection feature with different modes and operations. Users with salary > $100,000 are disabled for selection." }), (0, jsx_runtime_1.jsx)(material_1.Paper, { sx: { p: 2, mb: 3 }, children: (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', gap: 2, flexWrap: 'wrap', alignItems: 'center' }, children: [(0, jsx_runtime_1.jsxs)(material_1.FormControl, { size: "small", sx: { minWidth: 120 }, children: [(0, jsx_runtime_1.jsx)(material_1.InputLabel, { children: "Selection Mode" }), (0, jsx_runtime_1.jsxs)(material_1.Select, { value: selectMode, label: "Selection Mode", onChange: (e) => setSelectMode(e.target.value), children: [(0, jsx_runtime_1.jsx)(material_1.MenuItem, { value: "page", children: "Page Mode" }), (0, jsx_runtime_1.jsx)(material_1.MenuItem, { value: "all", children: "All Mode" })] })] }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: handleSelectAll, children: "Select All" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: handleDeselectAll, children: "Deselect All" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: handleSelectFirst5, children: "Select First 5" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: handleToggleRow, children: "Toggle User #3" })] }) }), (0, jsx_runtime_1.jsxs)(material_1.Paper, { sx: { p: 2, mb: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", gutterBottom: true, children: "Current Selection State" }), (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 2 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Mode:" }), " ", selectMode] }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Type:" }), " ", selectedType] }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Count:" }), " ", selectedCount] }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", sx: { gridColumn: '1 / -1' }, children: [(0, jsx_runtime_1.jsx)("strong", { children: "IDs:" }), " ", selectionState.ids.join(', ') || 'None'] })] })] }), (0, jsx_runtime_1.jsx)(material_1.Divider, { sx: { my: 2 } }), (0, jsx_runtime_1.jsx)(components_1.DataTable, { ref: tableRef, data: sampleData, totalRow: sampleData.length, columns: columns, enableRowSelection: true, enableMultiRowSelection: true, selectMode: selectMode, isRowSelectable: isRowSelectable, onSelectionChange: handleSelectionChange, enablePagination: true, initialState: {
86
+ pagination: {
87
+ pageIndex: 0,
88
+ pageSize: 10,
89
+ },
90
+ }, enableBulkActions: true, bulkActions: (selectionState) => ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', gap: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
91
+ const count = selectionState.type === 'include'
92
+ ? selectionState.ids.length
93
+ : sampleData.length - selectionState.ids.length;
94
+ alert(`Exporting ${count} selected users (${selectionState.type} mode)`);
95
+ }, children: "\uD83D\uDCE4 Export Selected" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", color: "error", onClick: () => {
96
+ const count = selectionState.type === 'include'
97
+ ? selectionState.ids.length
98
+ : sampleData.length - selectionState.ids.length;
99
+ alert(`Would delete ${count} selected users (${selectionState.type} mode)`);
100
+ }, children: "\uD83D\uDDD1\uFE0F Delete Selected" })] })), enableSorting: true, enableGlobalFilter: true, fitToScreen: true }), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { mt: 2 }, children: (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", color: "text.secondary", children: ["\uD83D\uDCA1 ", (0, jsx_runtime_1.jsx)("strong", { children: "Test Instructions:" }), (0, jsx_runtime_1.jsx)("br", {}), "1. Try selecting rows in \"Page\" mode, then switch pages - selections should be page-specific", (0, jsx_runtime_1.jsx)("br", {}), "2. Try \"All\" mode and select rows - this works across all pages", (0, jsx_runtime_1.jsx)("br", {}), "3. Note that users with salary > $100k are disabled (grayed out checkboxes)", (0, jsx_runtime_1.jsx)("br", {}), "4. Use the control buttons to test programmatic selection", (0, jsx_runtime_1.jsx)("br", {}), "5. Watch the \"Current Selection State\" panel to see how the selection data changes"] }) })] }));
101
+ }
@@ -0,0 +1 @@
1
+ export declare function SimpleLocalExample(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimpleLocalExample = SimpleLocalExample;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const material_1 = require("@mui/material");
7
+ const components_1 = require("../components");
8
+ const products = [
9
+ { id: 1, name: 'Laptop Pro', category: 'Electronics', price: 1299, inStock: true, rating: 4.5 },
10
+ { id: 2, name: 'Wireless Mouse', category: 'Electronics', price: 29, inStock: true, rating: 4.2 },
11
+ { id: 3, name: 'Coffee Mug', category: 'Kitchen', price: 12, inStock: false, rating: 4.8 },
12
+ { id: 4, name: 'Desk Chair', category: 'Furniture', price: 189, inStock: true, rating: 4.0 },
13
+ { id: 5, name: 'Notebook Set', category: 'Office', price: 15, inStock: true, rating: 4.3 },
14
+ { id: 6, name: 'Water Bottle', category: 'Kitchen', price: 22, inStock: true, rating: 4.7 },
15
+ { id: 7, name: 'Monitor Stand', category: 'Electronics', price: 45, inStock: false, rating: 4.1 },
16
+ { id: 8, name: 'Pen Set', category: 'Office', price: 8, inStock: true, rating: 3.9 },
17
+ { id: 9, name: 'Table Lamp', category: 'Furniture', price: 67, inStock: true, rating: 4.4 },
18
+ { id: 10, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
19
+ { id: 11, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
20
+ { id: 12, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
21
+ { id: 13, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
22
+ { id: 14, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
23
+ { id: 15, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
24
+ { id: 16, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
25
+ { id: 17, name: 'Phone Case', category: 'Electronics', price: 25, inStock: true, rating: 4.6 },
26
+ ];
27
+ const columns = [
28
+ {
29
+ accessorKey: 'name',
30
+ header: 'Product Name',
31
+ size: 180,
32
+ },
33
+ {
34
+ accessorKey: 'category',
35
+ header: 'Category',
36
+ size: 120,
37
+ cell: ({ getValue }) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: getValue(), size: "small", variant: "outlined", color: "primary" })),
38
+ },
39
+ {
40
+ accessorKey: 'price',
41
+ header: 'Price',
42
+ size: 100,
43
+ cell: ({ getValue }) => `$${getValue().toFixed(2)}`,
44
+ },
45
+ {
46
+ accessorKey: 'inStock',
47
+ header: 'In Stock',
48
+ size: 100,
49
+ cell: ({ getValue }) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: getValue() ? 'Yes' : 'No', color: getValue() ? 'success' : 'error', size: "small" })),
50
+ },
51
+ {
52
+ accessorKey: 'rating',
53
+ header: 'Rating',
54
+ size: 100,
55
+ cell: ({ getValue }) => `⭐ ${getValue().toFixed(1)}`,
56
+ },
57
+ ];
58
+ function SimpleLocalExample() {
59
+ const bulkActions = (0, react_1.useCallback)((selectionState) => ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', gap: 1 }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
60
+ const count = selectionState.type === 'include'
61
+ ? selectionState.ids.length
62
+ : products.length - selectionState.ids.length;
63
+ alert(`Selected ${count} products (${selectionState.type} mode)`);
64
+ }, style: {
65
+ padding: '8px 16px',
66
+ borderRadius: '4px',
67
+ border: '1px solid #ccc',
68
+ background: '#f5f5f5',
69
+ cursor: 'pointer'
70
+ }, children: "\uD83D\uDCCA Show Count" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
71
+ let selectedProducts;
72
+ if (selectionState.type === 'include') {
73
+ selectedProducts = products.filter(p => selectionState.ids.includes(p.id.toString()));
74
+ }
75
+ else {
76
+ selectedProducts = products.filter(p => !selectionState.ids.includes(p.id.toString()));
77
+ }
78
+ const total = selectedProducts.reduce((sum, product) => sum + product.price, 0);
79
+ alert(`Total value: $${total.toFixed(2)}`);
80
+ }, style: {
81
+ padding: '8px 16px',
82
+ borderRadius: '4px',
83
+ border: '1px solid #ccc',
84
+ background: '#f5f5f5',
85
+ cursor: 'pointer'
86
+ }, children: "\uD83D\uDCB0 Calculate Total" })] })), []);
87
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { p: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h4", gutterBottom: true, children: "Simple Local Data Example" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body1", color: "text.secondary", sx: { mb: 3 }, children: "A basic example using static local data with no API calls. Demonstrates essential DataTable features with minimal setup." }), (0, jsx_runtime_1.jsx)(components_1.DataTable, { data: products, totalRow: products.length, columns: columns, enableSorting: true, enableGlobalFilter: true, enableColumnFilter: true, enableColumnResizing: true, enableRowSelection: true, enableBulkActions: true, bulkActions: bulkActions, fitToScreen: true, initialState: {
88
+ pagination: {
89
+ pageIndex: 0,
90
+ pageSize: 5,
91
+ },
92
+ }, slotProps: {
93
+ pagination: {
94
+ rowsPerPageOptions: [5, 10, 20, 30, 40, 50],
95
+ },
96
+ } }), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { mt: 2, p: 2, backgroundColor: 'grey.50', borderRadius: 1 }, children: (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", color: "text.secondary", children: ["\uD83D\uDCA1 ", (0, jsx_runtime_1.jsx)("strong", { children: "This example demonstrates:" }), (0, jsx_runtime_1.jsx)("br", {}), "\u2022 Basic table with static local data", (0, jsx_runtime_1.jsx)("br", {}), "\u2022 Simple column definitions with custom cell renderers", (0, jsx_runtime_1.jsx)("br", {}), "\u2022 Sorting, filtering, and pagination", (0, jsx_runtime_1.jsx)("br", {}), "\u2022 Row selection with bulk actions", (0, jsx_runtime_1.jsx)("br", {}), "\u2022 Minimal setup - perfect for getting started"] }) })] }));
97
+ }
@@ -0,0 +1,45 @@
1
+ import { Table, TableFeature, RowData, Updater, RowModel } from '@tanstack/react-table';
2
+ import type { CustomColumnFilterState } from '../types/table.types';
3
+ export interface ColumnFilterRule {
4
+ id: string;
5
+ columnId: string;
6
+ operator: string;
7
+ value: any;
8
+ columnType?: string;
9
+ }
10
+ export interface CustomColumnFilterOptions {
11
+ enableCustomColumnFilter?: boolean;
12
+ onCustomColumnFilterChange?: (updater: Updater<CustomColumnFilterState>) => void;
13
+ onCustomColumnFilterApply?: (state: CustomColumnFilterState) => void;
14
+ }
15
+ export interface CustomColumnFilterTableState {
16
+ customColumnFilter: CustomColumnFilterState;
17
+ }
18
+ declare module '@tanstack/table-core' {
19
+ interface TableState extends CustomColumnFilterTableState {
20
+ }
21
+ interface TableOptionsResolved<TData extends RowData> extends CustomColumnFilterOptions {
22
+ }
23
+ interface Table<TData extends RowData> extends CustomColumnFilterInstance<TData> {
24
+ }
25
+ }
26
+ export interface CustomColumnFilterInstance<TData extends RowData> {
27
+ setCustomColumnFilter: (updater: Updater<CustomColumnFilterState>) => void;
28
+ addPendingColumnFilter: (columnId: string, operator: string, value: any) => void;
29
+ updatePendingColumnFilter: (filterId: string, updates: Partial<ColumnFilterRule>) => void;
30
+ removePendingColumnFilter: (filterId: string) => void;
31
+ clearAllPendingColumnFilters: () => void;
32
+ setPendingFilterLogic: (logic: 'AND' | 'OR') => void;
33
+ applyPendingColumnFilters: () => void;
34
+ addColumnFilter: (columnId: string, operator: string, value: any) => void;
35
+ updateColumnFilter: (filterId: string, updates: Partial<ColumnFilterRule>) => void;
36
+ removeColumnFilter: (filterId: string) => void;
37
+ clearAllColumnFilters: () => void;
38
+ setFilterLogic: (logic: 'AND' | 'OR') => void;
39
+ getActiveColumnFilters: () => ColumnFilterRule[];
40
+ getPendingColumnFilters: () => ColumnFilterRule[];
41
+ getCustomColumnFilterState: () => CustomColumnFilterState;
42
+ }
43
+ export declare const CustomColumnFilterFeature: TableFeature<any>;
44
+ export declare function matchesCustomColumnFilters<TData extends RowData>(row: any, filters: ColumnFilterRule[], logic?: 'AND' | 'OR'): boolean;
45
+ export declare const getCombinedFilteredRowModel: <TData>() => (table: Table<TData>) => () => RowModel<TData>;
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCombinedFilteredRowModel = exports.CustomColumnFilterFeature = void 0;
4
+ exports.matchesCustomColumnFilters = matchesCustomColumnFilters;
5
+ const tslib_1 = require("tslib");
6
+ const react_table_1 = require("@tanstack/react-table");
7
+ const moment_1 = tslib_1.__importDefault(require("moment"));
8
+ exports.CustomColumnFilterFeature = {
9
+ getInitialState: (state) => {
10
+ return Object.assign({ customColumnFilter: {
11
+ filters: [],
12
+ logic: 'AND',
13
+ pendingFilters: [],
14
+ pendingLogic: 'AND',
15
+ } }, state);
16
+ },
17
+ getDefaultOptions: (table) => {
18
+ return {
19
+ enableCustomColumnFilter: true,
20
+ onCustomColumnFilterChange: (0, react_table_1.makeStateUpdater)('customColumnFilter', table),
21
+ onCustomColumnFilterApply: (state) => {
22
+ },
23
+ };
24
+ },
25
+ createTable: (table) => {
26
+ table.setCustomColumnFilter = (updater) => {
27
+ var _a, _b;
28
+ const safeUpdater = (old) => {
29
+ const newState = (0, react_table_1.functionalUpdate)(updater, old);
30
+ return newState;
31
+ };
32
+ return (_b = (_a = table.options).onCustomColumnFilterChange) === null || _b === void 0 ? void 0 : _b.call(_a, safeUpdater);
33
+ };
34
+ table.addPendingColumnFilter = (columnId, operator, value) => {
35
+ table.setCustomColumnFilter((old) => {
36
+ const newFilter = {
37
+ id: `filter_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
38
+ columnId,
39
+ operator,
40
+ value,
41
+ };
42
+ return Object.assign(Object.assign({}, old), { pendingFilters: [...old.pendingFilters, newFilter] });
43
+ });
44
+ };
45
+ table.updatePendingColumnFilter = (filterId, updates) => {
46
+ table.setCustomColumnFilter((old) => {
47
+ const updatedFilters = old.pendingFilters.map((filter) => filter.id === filterId ? Object.assign(Object.assign({}, filter), updates) : filter);
48
+ return Object.assign(Object.assign({}, old), { pendingFilters: updatedFilters });
49
+ });
50
+ };
51
+ table.removePendingColumnFilter = (filterId) => {
52
+ table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { pendingFilters: old.pendingFilters.filter((filter) => filter.id !== filterId) })));
53
+ };
54
+ table.clearAllPendingColumnFilters = () => {
55
+ table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { pendingFilters: [] })));
56
+ };
57
+ table.setPendingFilterLogic = (logic) => {
58
+ table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { pendingLogic: logic })));
59
+ };
60
+ table.applyPendingColumnFilters = () => {
61
+ table.setCustomColumnFilter((old) => {
62
+ const newState = Object.assign(Object.assign({}, old), { filters: [...old.pendingFilters], logic: old.pendingLogic });
63
+ setTimeout(() => {
64
+ var _a, _b;
65
+ (_b = (_a = table.options).onCustomColumnFilterApply) === null || _b === void 0 ? void 0 : _b.call(_a, newState);
66
+ }, 0);
67
+ return newState;
68
+ });
69
+ };
70
+ table.addColumnFilter = (columnId, operator, value) => {
71
+ table.setCustomColumnFilter((old) => {
72
+ const newFilter = {
73
+ id: `filter_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
74
+ columnId,
75
+ operator,
76
+ value,
77
+ };
78
+ return Object.assign(Object.assign({}, old), { filters: [...old.filters, newFilter] });
79
+ });
80
+ };
81
+ table.updateColumnFilter = (filterId, updates) => {
82
+ table.setCustomColumnFilter((old) => {
83
+ const updatedFilters = old.filters.map((filter) => filter.id === filterId ? Object.assign(Object.assign({}, filter), updates) : filter);
84
+ return Object.assign(Object.assign({}, old), { filters: updatedFilters });
85
+ });
86
+ };
87
+ table.removeColumnFilter = (filterId) => {
88
+ table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { filters: old.filters.filter((filter) => filter.id !== filterId) })));
89
+ };
90
+ table.clearAllColumnFilters = () => {
91
+ table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { filters: [] })));
92
+ };
93
+ table.setFilterLogic = (logic) => {
94
+ table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { logic })));
95
+ };
96
+ table.getActiveColumnFilters = () => {
97
+ const state = table.getState().customColumnFilter;
98
+ return state.filters.filter((f) => f.columnId && f.operator);
99
+ };
100
+ table.getPendingColumnFilters = () => {
101
+ const state = table.getState().customColumnFilter;
102
+ return state.pendingFilters.filter((f) => f.columnId && f.operator);
103
+ };
104
+ table.getCustomColumnFilterState = () => {
105
+ return table.getState().customColumnFilter;
106
+ };
107
+ },
108
+ };
109
+ function matchesCustomColumnFilters(row, filters, logic = 'AND') {
110
+ if (filters.length === 0)
111
+ return true;
112
+ const activeFilters = filters.filter((f) => f.columnId && f.operator);
113
+ if (activeFilters.length === 0)
114
+ return true;
115
+ const results = activeFilters.map((filter) => {
116
+ var _a;
117
+ let columnValue;
118
+ let columnType = filter.columnType || 'text';
119
+ try {
120
+ const column = row.getAllCells().find((cell) => cell.column.id === filter.columnId);
121
+ if (column) {
122
+ columnValue = column.getValue();
123
+ if (!filter.columnType && column.column.columnDef && column.column.columnDef.type) {
124
+ columnType = column.column.columnDef.type;
125
+ }
126
+ }
127
+ }
128
+ catch (error) {
129
+ console.warn(`Error getting value for column ${filter.columnId}:`, error);
130
+ columnValue = ((_a = row.original) === null || _a === void 0 ? void 0 : _a[filter.columnId]) || '';
131
+ }
132
+ return evaluateFilterCondition(columnValue, filter.operator, filter.value, columnType);
133
+ });
134
+ return logic === 'AND' ? results.every(Boolean) : results.some(Boolean);
135
+ }
136
+ const getCombinedFilteredRowModel = () => {
137
+ return (table) => () => {
138
+ var _a;
139
+ const baseFilteredModel = (0, react_table_1.getFilteredRowModel)()(table)();
140
+ const { filters, logic } = (_a = table.getState().customColumnFilter) !== null && _a !== void 0 ? _a : {
141
+ filters: [],
142
+ logic: 'AND',
143
+ };
144
+ if (!filters.length)
145
+ return baseFilteredModel;
146
+ const filteredRows = baseFilteredModel.rows.filter(row => matchesCustomColumnFilters(row, filters, logic));
147
+ const flatRows = [];
148
+ const rowsById = {};
149
+ const addRow = (row) => {
150
+ var _a;
151
+ flatRows.push(row);
152
+ rowsById[row.id] = row;
153
+ (_a = row.subRows) === null || _a === void 0 ? void 0 : _a.forEach(addRow);
154
+ };
155
+ filteredRows.forEach(addRow);
156
+ return {
157
+ rows: filteredRows,
158
+ flatRows,
159
+ rowsById,
160
+ };
161
+ };
162
+ };
163
+ exports.getCombinedFilteredRowModel = getCombinedFilteredRowModel;
164
+ function evaluateFilterCondition(columnValue, operator, filterValue, type = 'text') {
165
+ function toMoment(val) {
166
+ if (!val)
167
+ return null;
168
+ const m = (0, moment_1.default)(val);
169
+ return m.isValid() ? m : null;
170
+ }
171
+ if (type === 'date') {
172
+ const mCol = toMoment(columnValue);
173
+ const mFilter = toMoment(filterValue);
174
+ if (!mCol || !mFilter)
175
+ return false;
176
+ switch (operator) {
177
+ case 'equals':
178
+ return mCol.isSame(mFilter, 'day');
179
+ case 'notEquals':
180
+ return !mCol.isSame(mFilter, 'day');
181
+ case 'after':
182
+ return mCol.isAfter(mFilter, 'day');
183
+ case 'before':
184
+ return mCol.isBefore(mFilter, 'day');
185
+ case 'isEmpty':
186
+ return !columnValue;
187
+ case 'isNotEmpty':
188
+ return !!columnValue;
189
+ default:
190
+ return true;
191
+ }
192
+ }
193
+ if (type === 'boolean') {
194
+ switch (operator) {
195
+ case 'is':
196
+ if (filterValue === 'any')
197
+ return true;
198
+ if (filterValue === 'true')
199
+ return (columnValue === true || columnValue === 'true' || columnValue === 1 || columnValue === '1' || columnValue === 'Yes' || columnValue === 'yes');
200
+ if (filterValue === 'false')
201
+ return (columnValue === false || columnValue === 'false' || columnValue === 0 || columnValue === '0' || columnValue === 'No' || columnValue === 'no');
202
+ return false;
203
+ default:
204
+ return true;
205
+ }
206
+ }
207
+ if (type === 'select') {
208
+ if (operator === 'in' || operator === 'notIn') {
209
+ if (Array.isArray(filterValue)) {
210
+ if (operator === 'in')
211
+ return filterValue.includes(columnValue);
212
+ if (operator === 'notIn')
213
+ return !filterValue.includes(columnValue);
214
+ }
215
+ return false;
216
+ }
217
+ if (operator === 'equals' || operator === 'notEquals') {
218
+ return operator === 'equals'
219
+ ? columnValue === filterValue
220
+ : columnValue !== filterValue;
221
+ }
222
+ }
223
+ switch (operator) {
224
+ case 'contains':
225
+ return String(columnValue).toLowerCase().includes(String(filterValue).toLowerCase());
226
+ case 'notContains':
227
+ return !String(columnValue).toLowerCase().includes(String(filterValue).toLowerCase());
228
+ case 'startsWith':
229
+ return String(columnValue).toLowerCase().startsWith(String(filterValue).toLowerCase());
230
+ case 'endsWith':
231
+ return String(columnValue).toLowerCase().endsWith(String(filterValue).toLowerCase());
232
+ case 'isEmpty':
233
+ return columnValue === null || columnValue === undefined || columnValue === '';
234
+ case 'isNotEmpty':
235
+ return columnValue !== null && columnValue !== undefined && columnValue !== '';
236
+ case 'greaterThan':
237
+ return Number(columnValue) > Number(filterValue);
238
+ case 'greaterThanOrEqual':
239
+ return Number(columnValue) >= Number(filterValue);
240
+ case 'lessThan':
241
+ return Number(columnValue) < Number(filterValue);
242
+ case 'lessThanOrEqual':
243
+ return Number(columnValue) <= Number(filterValue);
244
+ default:
245
+ return true;
246
+ }
247
+ }
@@ -0,0 +1,46 @@
1
+ import { TableFeature, RowData, Updater, Row } from '@tanstack/react-table';
2
+ export interface SelectionState {
3
+ ids: string[];
4
+ type: 'include' | 'exclude';
5
+ selectMode?: 'page' | 'all';
6
+ }
7
+ export type IsRowSelectableFunction<T = any> = (params: {
8
+ row: T;
9
+ id: string;
10
+ }) => boolean;
11
+ export type SelectMode = 'page' | 'all';
12
+ export interface CustomSelectionOptions {
13
+ enableCustomSelection?: boolean;
14
+ selectMode?: SelectMode;
15
+ isRowSelectable?: IsRowSelectableFunction;
16
+ onSelectionStateChange?: (updater: Updater<SelectionState>) => void;
17
+ }
18
+ export interface CustomSelectionTableState {
19
+ selectionState: SelectionState;
20
+ }
21
+ declare module '@tanstack/table-core' {
22
+ interface TableState extends CustomSelectionTableState {
23
+ }
24
+ interface TableOptionsResolved<TData extends RowData> extends CustomSelectionOptions {
25
+ }
26
+ interface Table<TData extends RowData> extends CustomSelectionInstance<TData> {
27
+ }
28
+ }
29
+ export interface CustomSelectionInstance<TData extends RowData> {
30
+ setSelectionState: (updater: Updater<SelectionState>) => void;
31
+ toggleAllRowsSelected: () => void;
32
+ toggleRowSelected: (rowId: string) => void;
33
+ selectRow: (rowId: string) => void;
34
+ deselectRow: (rowId: string) => void;
35
+ selectAll: () => void;
36
+ deselectAll: () => void;
37
+ getIsAllRowsSelected: () => boolean;
38
+ getIsSomeRowsSelected: () => boolean;
39
+ getIsRowSelected: (rowId: string) => boolean;
40
+ getSelectionState: () => SelectionState;
41
+ getSelectedCount: () => number;
42
+ getSelectedRows: () => Row<TData>[];
43
+ getSelectedRowIds: () => string[];
44
+ canSelectRow: (rowId: string) => boolean;
45
+ }
46
+ export declare const CustomSelectionFeature: TableFeature<any>;