@ackplus/mui-tanstack-data-grid 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +22 -0
  2. package/dist/components/data-table.d.ts +4 -0
  3. package/dist/components/data-table.d.ts.map +1 -0
  4. package/dist/components/data-table.js +24 -0
  5. package/dist/components/filters/filter-value-input.d.ts +10 -0
  6. package/dist/components/filters/filter-value-input.d.ts.map +1 -0
  7. package/dist/components/filters/filter-value-input.js +39 -0
  8. package/dist/components/filters/index.d.ts +3 -0
  9. package/dist/components/filters/index.d.ts.map +1 -0
  10. package/dist/components/filters/index.js +18 -0
  11. package/dist/components/filters/operators.d.ts +93 -0
  12. package/dist/components/filters/operators.d.ts.map +1 -0
  13. package/dist/components/filters/operators.js +42 -0
  14. package/dist/components/grid/grid-view.d.ts +8 -0
  15. package/dist/components/grid/grid-view.d.ts.map +1 -0
  16. package/dist/components/grid/grid-view.js +151 -0
  17. package/dist/components/grid/styled.d.ts +17 -0
  18. package/dist/components/grid/styled.d.ts.map +1 -0
  19. package/dist/components/grid/styled.js +68 -0
  20. package/dist/components/index.d.ts +8 -0
  21. package/dist/components/index.d.ts.map +1 -0
  22. package/dist/components/index.js +23 -0
  23. package/dist/components/toolbar/bulk-actions-toolbar.d.ts +10 -0
  24. package/dist/components/toolbar/bulk-actions-toolbar.d.ts.map +1 -0
  25. package/dist/components/toolbar/bulk-actions-toolbar.js +20 -0
  26. package/dist/components/toolbar/column-filter-control.d.ts +8 -0
  27. package/dist/components/toolbar/column-filter-control.d.ts.map +1 -0
  28. package/dist/components/toolbar/column-filter-control.js +93 -0
  29. package/dist/components/toolbar/data-table-toolbar.d.ts +16 -0
  30. package/dist/components/toolbar/data-table-toolbar.d.ts.map +1 -0
  31. package/dist/components/toolbar/data-table-toolbar.js +44 -0
  32. package/dist/core/index.d.ts +2 -0
  33. package/dist/core/index.d.ts.map +1 -0
  34. package/dist/core/index.js +17 -0
  35. package/dist/core/use-data-table.d.ts +83 -0
  36. package/dist/core/use-data-table.d.ts.map +1 -0
  37. package/dist/core/use-data-table.js +1081 -0
  38. package/dist/features/column-filter.feature.d.ts +48 -0
  39. package/dist/features/column-filter.feature.d.ts.map +1 -0
  40. package/dist/features/column-filter.feature.js +270 -0
  41. package/dist/features/index.d.ts +3 -0
  42. package/dist/features/index.d.ts.map +1 -0
  43. package/dist/features/index.js +18 -0
  44. package/dist/features/selection.feature.d.ts +49 -0
  45. package/dist/features/selection.feature.d.ts.map +1 -0
  46. package/dist/features/selection.feature.js +159 -0
  47. package/dist/index.d.ts +13 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +34 -0
  50. package/dist/theme/create-data-table-theme.d.ts +16 -0
  51. package/dist/theme/create-data-table-theme.d.ts.map +1 -0
  52. package/dist/theme/create-data-table-theme.js +18 -0
  53. package/dist/theme/index.d.ts +7 -0
  54. package/dist/theme/index.d.ts.map +1 -0
  55. package/dist/theme/index.js +22 -0
  56. package/dist/theme/mui-augmentation.d.ts +40 -0
  57. package/dist/theme/mui-augmentation.d.ts.map +1 -0
  58. package/dist/theme/mui-augmentation.js +2 -0
  59. package/dist/theme/palette.d.ts +24 -0
  60. package/dist/theme/palette.d.ts.map +1 -0
  61. package/dist/theme/palette.js +23 -0
  62. package/dist/theme/tokens.d.ts +43 -0
  63. package/dist/theme/tokens.d.ts.map +1 -0
  64. package/dist/theme/tokens.js +40 -0
  65. package/dist/theme/use-data-table-tokens.d.ts +4 -0
  66. package/dist/theme/use-data-table-tokens.d.ts.map +1 -0
  67. package/dist/theme/use-data-table-tokens.js +42 -0
  68. package/dist/types/api.types.d.ts +156 -0
  69. package/dist/types/api.types.d.ts.map +1 -0
  70. package/dist/types/api.types.js +2 -0
  71. package/dist/types/column.types.d.ts +60 -0
  72. package/dist/types/column.types.d.ts.map +1 -0
  73. package/dist/types/column.types.js +7 -0
  74. package/dist/types/data-table.types.d.ts +161 -0
  75. package/dist/types/data-table.types.d.ts.map +1 -0
  76. package/dist/types/data-table.types.js +2 -0
  77. package/dist/types/export.types.d.ts +32 -0
  78. package/dist/types/export.types.d.ts.map +1 -0
  79. package/dist/types/export.types.js +2 -0
  80. package/dist/types/filter.types.d.ts +15 -0
  81. package/dist/types/filter.types.d.ts.map +1 -0
  82. package/dist/types/filter.types.js +2 -0
  83. package/dist/types/index.d.ts +10 -0
  84. package/dist/types/index.d.ts.map +1 -0
  85. package/dist/types/index.js +25 -0
  86. package/dist/types/logging.types.d.ts +23 -0
  87. package/dist/types/logging.types.d.ts.map +1 -0
  88. package/dist/types/logging.types.js +2 -0
  89. package/dist/types/selection.types.d.ts +7 -0
  90. package/dist/types/selection.types.d.ts.map +1 -0
  91. package/dist/types/selection.types.js +2 -0
  92. package/dist/types/slots.types.d.ts +41 -0
  93. package/dist/types/slots.types.d.ts.map +1 -0
  94. package/dist/types/slots.types.js +2 -0
  95. package/dist/types/state.types.d.ts +46 -0
  96. package/dist/types/state.types.d.ts.map +1 -0
  97. package/dist/types/state.types.js +2 -0
  98. package/dist/utils/column-helpers.d.ts +9 -0
  99. package/dist/utils/column-helpers.d.ts.map +1 -0
  100. package/dist/utils/column-helpers.js +46 -0
  101. package/dist/utils/debounced-fetch.utils.d.ts +22 -0
  102. package/dist/utils/debounced-fetch.utils.d.ts.map +1 -0
  103. package/dist/utils/debounced-fetch.utils.js +85 -0
  104. package/dist/utils/export-utils.d.ts +49 -0
  105. package/dist/utils/export-utils.d.ts.map +1 -0
  106. package/dist/utils/export-utils.js +372 -0
  107. package/dist/utils/index.d.ts +7 -0
  108. package/dist/utils/index.d.ts.map +1 -0
  109. package/dist/utils/index.js +22 -0
  110. package/dist/utils/logger.d.ts +24 -0
  111. package/dist/utils/logger.d.ts.map +1 -0
  112. package/dist/utils/logger.js +107 -0
  113. package/dist/utils/special-columns.d.ts +9 -0
  114. package/dist/utils/special-columns.d.ts.map +1 -0
  115. package/dist/utils/special-columns.js +80 -0
  116. package/dist/utils/table-helpers.d.ts +16 -0
  117. package/dist/utils/table-helpers.d.ts.map +1 -0
  118. package/dist/utils/table-helpers.js +50 -0
  119. package/package.json +74 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Custom Column Filter feature for TanStack Table.
3
+ *
4
+ * Advanced column filtering: draft (pending) → apply, AND/OR logic, per-type
5
+ * operators (text/number/date/boolean/select). Ported from v1 with `moment`
6
+ * replaced by `dayjs` (lightweight pass). Shared types now live in
7
+ * `../types/filter.types`.
8
+ */
9
+ import { Table, TableFeature, RowData, Updater, RowModel } from '@tanstack/react-table';
10
+ import type { ColumnFilterRule, ColumnFilterState } from '../types/filter.types';
11
+ export interface ColumnFilterOptions {
12
+ enableAdvanceColumnFilter?: boolean;
13
+ onColumnFilterChange?: (updater: Updater<ColumnFilterState>) => void;
14
+ onColumnFilterApply?: (state: ColumnFilterState) => void;
15
+ }
16
+ declare module '@tanstack/react-table' {
17
+ interface TableState {
18
+ columnFilter: ColumnFilterState;
19
+ }
20
+ interface TableOptionsResolved<TData extends RowData> {
21
+ enableAdvanceColumnFilter?: boolean;
22
+ onColumnFilterChange?: (updater: Updater<ColumnFilterState>) => void;
23
+ onColumnFilterApply?: (state: ColumnFilterState) => void;
24
+ }
25
+ interface Table<TData extends RowData> {
26
+ setColumnFilterState: (updater: Updater<ColumnFilterState> | ColumnFilterState) => void;
27
+ addPendingColumnFilter: (columnId: string, operator: string, value: any) => void;
28
+ updatePendingColumnFilter: (filterId: string, updates: Partial<ColumnFilterRule>) => void;
29
+ removePendingColumnFilter: (filterId: string) => void;
30
+ clearAllPendingColumnFilters: () => void;
31
+ setPendingFilterLogic: (logic: 'AND' | 'OR') => void;
32
+ applyPendingColumnFilters: () => void;
33
+ resetColumnFilter: () => 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
+ getColumnFilterState: () => ColumnFilterState;
42
+ }
43
+ }
44
+ export declare const ColumnFilterFeature: TableFeature<any>;
45
+ /** Client-side predicate: does a row match the given custom column filters? */
46
+ export declare function matchesCustomColumnFilters(row: any, filters: ColumnFilterRule[], logic?: 'AND' | 'OR'): boolean;
47
+ export declare const getCombinedFilteredRowModel: <TData>() => (table: Table<TData>) => () => RowModel<TData>;
48
+ //# sourceMappingURL=column-filter.feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column-filter.feature.d.ts","sourceRoot":"","sources":["../../src/features/column-filter.feature.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACH,KAAK,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EAGP,QAAQ,EAGX,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAEjF,MAAM,WAAW,mBAAmB;IAChC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACrE,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC5D;AAED,OAAO,QAAQ,uBAAuB,CAAC;IACnC,UAAU,UAAU;QAChB,YAAY,EAAE,iBAAiB,CAAC;KACnC;IAED,UAAU,oBAAoB,CAAC,KAAK,SAAS,OAAO;QAChD,yBAAyB,CAAC,EAAE,OAAO,CAAC;QACpC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;QACrE,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;KAC5D;IAED,UAAU,KAAK,CAAC,KAAK,SAAS,OAAO;QACjC,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,KAAK,IAAI,CAAC;QACxF,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;QACjF,yBAAyB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;QAC1F,yBAAyB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QACtD,4BAA4B,EAAE,MAAM,IAAI,CAAC;QACzC,qBAAqB,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;QACrD,yBAAyB,EAAE,MAAM,IAAI,CAAC;QACtC,iBAAiB,EAAE,MAAM,IAAI,CAAC;QAC9B,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;QAC1E,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;QACnF,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/C,qBAAqB,EAAE,MAAM,IAAI,CAAC;QAClC,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;QAC9C,sBAAsB,EAAE,MAAM,gBAAgB,EAAE,CAAC;QACjD,uBAAuB,EAAE,MAAM,gBAAgB,EAAE,CAAC;QAClD,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;KACjD;CACJ;AAID,eAAO,MAAM,mBAAmB,EAAE,YAAY,CAAC,GAAG,CA6GjD,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,0BAA0B,CACtC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,gBAAgB,EAAE,EAC3B,KAAK,GAAE,KAAK,GAAG,IAAY,GAC5B,OAAO,CAwBT;AAED,eAAO,MAAM,2BAA2B,GAAI,KAAK,QACrC,OAAO,KAAK,CAAC,KAAK,CAAC,WAAS,QAAQ,CAAC,KAAK,CA2BrD,CAAC"}
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getCombinedFilteredRowModel = exports.ColumnFilterFeature = void 0;
7
+ exports.matchesCustomColumnFilters = matchesCustomColumnFilters;
8
+ /**
9
+ * Custom Column Filter feature for TanStack Table.
10
+ *
11
+ * Advanced column filtering: draft (pending) → apply, AND/OR logic, per-type
12
+ * operators (text/number/date/boolean/select). Ported from v1 with `moment`
13
+ * replaced by `dayjs` (lightweight pass). Shared types now live in
14
+ * `../types/filter.types`.
15
+ */
16
+ const react_table_1 = require("@tanstack/react-table");
17
+ const dayjs_1 = __importDefault(require("dayjs"));
18
+ const makeFilterId = () => `filter_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
19
+ exports.ColumnFilterFeature = {
20
+ getInitialState: (state) => ({
21
+ columnFilter: { filters: [], logic: 'AND', pendingFilters: [], pendingLogic: 'AND' },
22
+ ...state,
23
+ }),
24
+ getDefaultOptions: (table) => ({
25
+ enableAdvanceColumnFilter: true,
26
+ onColumnFilterChange: (0, react_table_1.makeStateUpdater)('columnFilter', table),
27
+ onColumnFilterApply: () => undefined,
28
+ }),
29
+ createTable: (table) => {
30
+ table.setColumnFilterState = (updater) => {
31
+ var _a, _b;
32
+ if (!table.options.enableAdvanceColumnFilter)
33
+ return;
34
+ const safeUpdater = (old) => (0, react_table_1.functionalUpdate)(updater, old);
35
+ return (_b = (_a = table.options).onColumnFilterChange) === null || _b === void 0 ? void 0 : _b.call(_a, safeUpdater);
36
+ };
37
+ // Pending (draft) filters
38
+ table.addPendingColumnFilter = (columnId, operator, value) => {
39
+ if (!table.options.enableAdvanceColumnFilter)
40
+ return;
41
+ table.setColumnFilterState((old) => ({
42
+ ...old,
43
+ pendingFilters: [...old.pendingFilters, { id: makeFilterId(), columnId, operator, value }],
44
+ }));
45
+ };
46
+ table.updatePendingColumnFilter = (filterId, updates) => {
47
+ if (!table.options.enableAdvanceColumnFilter)
48
+ return;
49
+ table.setColumnFilterState((old) => ({
50
+ ...old,
51
+ pendingFilters: old.pendingFilters.map((f) => (f.id === filterId ? { ...f, ...updates } : f)),
52
+ }));
53
+ };
54
+ table.removePendingColumnFilter = (filterId) => {
55
+ if (!table.options.enableAdvanceColumnFilter)
56
+ return;
57
+ table.setColumnFilterState((old) => ({
58
+ ...old,
59
+ pendingFilters: old.pendingFilters.filter((f) => f.id !== filterId),
60
+ }));
61
+ };
62
+ table.clearAllPendingColumnFilters = () => {
63
+ if (!table.options.enableAdvanceColumnFilter)
64
+ return;
65
+ table.setColumnFilterState((old) => ({ ...old, pendingFilters: [] }));
66
+ };
67
+ table.resetColumnFilter = () => {
68
+ var _a, _b;
69
+ if (!table.options.enableAdvanceColumnFilter)
70
+ return;
71
+ const newState = { pendingFilters: [], pendingLogic: 'AND', filters: [], logic: 'AND' };
72
+ table.setColumnFilterState(newState);
73
+ (_b = (_a = table.options).onColumnFilterApply) === null || _b === void 0 ? void 0 : _b.call(_a, newState);
74
+ };
75
+ table.setPendingFilterLogic = (logic) => {
76
+ if (!table.options.enableAdvanceColumnFilter)
77
+ return;
78
+ table.setColumnFilterState((old) => ({ ...old, pendingLogic: logic }));
79
+ };
80
+ table.applyPendingColumnFilters = () => {
81
+ if (!table.options.enableAdvanceColumnFilter)
82
+ return;
83
+ table.setColumnFilterState((old) => {
84
+ const newState = { ...old, filters: [...old.pendingFilters], logic: old.pendingLogic };
85
+ setTimeout(() => { var _a, _b; return (_b = (_a = table.options).onColumnFilterApply) === null || _b === void 0 ? void 0 : _b.call(_a, newState); }, 0);
86
+ return newState;
87
+ });
88
+ };
89
+ // Active filters (direct)
90
+ table.addColumnFilter = (columnId, operator, value) => {
91
+ if (!table.options.enableAdvanceColumnFilter)
92
+ return;
93
+ table.setColumnFilterState((old) => ({
94
+ ...old,
95
+ filters: [...old.filters, { id: makeFilterId(), columnId, operator, value }],
96
+ }));
97
+ };
98
+ table.updateColumnFilter = (filterId, updates) => {
99
+ if (!table.options.enableAdvanceColumnFilter)
100
+ return;
101
+ table.setColumnFilterState((old) => ({
102
+ ...old,
103
+ filters: old.filters.map((f) => (f.id === filterId ? { ...f, ...updates } : f)),
104
+ }));
105
+ };
106
+ table.removeColumnFilter = (filterId) => {
107
+ if (!table.options.enableAdvanceColumnFilter)
108
+ return;
109
+ table.setColumnFilterState((old) => ({ ...old, filters: old.filters.filter((f) => f.id !== filterId) }));
110
+ };
111
+ table.clearAllColumnFilters = () => {
112
+ if (!table.options.enableAdvanceColumnFilter)
113
+ return;
114
+ table.setColumnFilterState((old) => ({ ...old, filters: [] }));
115
+ };
116
+ table.setFilterLogic = (logic) => {
117
+ if (!table.options.enableAdvanceColumnFilter)
118
+ return;
119
+ table.setColumnFilterState((old) => ({ ...old, logic }));
120
+ };
121
+ // Getters
122
+ table.getActiveColumnFilters = () => table.getState().columnFilter.filters.filter((f) => f.columnId && f.operator);
123
+ table.getPendingColumnFilters = () => table.getState().columnFilter.pendingFilters.filter((f) => f.columnId && f.operator);
124
+ table.getColumnFilterState = () => table.getState().columnFilter;
125
+ },
126
+ };
127
+ /** Client-side predicate: does a row match the given custom column filters? */
128
+ function matchesCustomColumnFilters(row, filters, logic = 'AND') {
129
+ if (filters.length === 0)
130
+ return true;
131
+ const activeFilters = filters.filter((f) => f.columnId && f.operator);
132
+ if (activeFilters.length === 0)
133
+ return true;
134
+ const results = activeFilters.map((filter) => {
135
+ var _a, _b;
136
+ let columnValue;
137
+ let columnType = filter.columnType || 'text';
138
+ try {
139
+ const cell = row.getAllCells().find((c) => c.column.id === filter.columnId);
140
+ if (cell) {
141
+ columnValue = cell.getValue();
142
+ if (!filter.columnType && ((_a = cell.column.columnDef) === null || _a === void 0 ? void 0 : _a.type)) {
143
+ columnType = cell.column.columnDef.type;
144
+ }
145
+ }
146
+ }
147
+ catch (error) {
148
+ console.warn(`Error getting value for column ${filter.columnId}:`, error);
149
+ columnValue = ((_b = row.original) === null || _b === void 0 ? void 0 : _b[filter.columnId]) || '';
150
+ }
151
+ return evaluateFilterCondition(columnValue, filter.operator, filter.value, columnType);
152
+ });
153
+ return logic === 'AND' ? results.every(Boolean) : results.some(Boolean);
154
+ }
155
+ const getCombinedFilteredRowModel = () => {
156
+ return (table) => () => {
157
+ var _a;
158
+ if (table.options.manualFiltering) {
159
+ return table.getCoreRowModel();
160
+ }
161
+ const baseFilteredModel = (0, react_table_1.getFilteredRowModel)()(table)();
162
+ const { filters, logic } = (_a = table.getState().columnFilter) !== null && _a !== void 0 ? _a : { filters: [], logic: 'AND' };
163
+ if (!filters.length || !table.options.enableAdvanceColumnFilter) {
164
+ return baseFilteredModel;
165
+ }
166
+ const filteredRows = baseFilteredModel.rows.filter((row) => matchesCustomColumnFilters(row, filters, logic));
167
+ const flatRows = [];
168
+ const rowsById = {};
169
+ const addRow = (row) => {
170
+ var _a;
171
+ flatRows.push(row);
172
+ rowsById[row.id] = row;
173
+ (_a = row.subRows) === null || _a === void 0 ? void 0 : _a.forEach(addRow);
174
+ };
175
+ filteredRows.forEach(addRow);
176
+ return { rows: filteredRows, flatRows, rowsById };
177
+ };
178
+ };
179
+ exports.getCombinedFilteredRowModel = getCombinedFilteredRowModel;
180
+ function evaluateFilterCondition(columnValue, operator, filterValue, type = 'text') {
181
+ const toDay = (val) => {
182
+ if (!val)
183
+ return null;
184
+ const d = (0, dayjs_1.default)(val);
185
+ return d.isValid() ? d : null;
186
+ };
187
+ if (type === 'date') {
188
+ if (operator === 'isEmpty')
189
+ return columnValue === null || columnValue === undefined || columnValue === '';
190
+ if (operator === 'isNotEmpty')
191
+ return columnValue !== null && columnValue !== undefined && columnValue !== '';
192
+ const dCol = columnValue ? toDay(columnValue) : null;
193
+ const dFilter = filterValue ? toDay(filterValue) : null;
194
+ if (!dCol || !dFilter)
195
+ return false;
196
+ switch (operator) {
197
+ case 'equals':
198
+ return dCol.isSame(dFilter, 'day');
199
+ case 'notEquals':
200
+ return !dCol.isSame(dFilter, 'day');
201
+ case 'after':
202
+ return dCol.isAfter(dFilter, 'day');
203
+ case 'before':
204
+ return dCol.isBefore(dFilter, 'day');
205
+ default:
206
+ return true;
207
+ }
208
+ }
209
+ if (type === 'boolean') {
210
+ if (operator === 'is') {
211
+ if (filterValue === 'any')
212
+ return true;
213
+ if (filterValue === 'true')
214
+ return columnValue === true || columnValue === 'true' || columnValue === 1 || columnValue === '1' || columnValue === 'Yes' || columnValue === 'yes';
215
+ if (filterValue === 'false')
216
+ return columnValue === false || columnValue === 'false' || columnValue === 0 || columnValue === '0' || columnValue === 'No' || columnValue === 'no';
217
+ return false;
218
+ }
219
+ return true;
220
+ }
221
+ if (type === 'select') {
222
+ if (operator === 'in' || operator === 'notIn') {
223
+ const values = Array.isArray(filterValue)
224
+ ? filterValue
225
+ : [filterValue].filter((v) => v !== undefined && v !== null && v !== '');
226
+ if (values.length === 0)
227
+ return operator === 'notIn';
228
+ return operator === 'in' ? values.includes(columnValue) : !values.includes(columnValue);
229
+ }
230
+ if (operator === 'equals' || operator === 'notEquals') {
231
+ return operator === 'equals' ? columnValue === filterValue : columnValue !== filterValue;
232
+ }
233
+ }
234
+ if (type === 'number') {
235
+ switch (operator) {
236
+ case 'equals':
237
+ return Number(columnValue) === Number(filterValue);
238
+ case 'notEquals':
239
+ return Number(columnValue) !== Number(filterValue);
240
+ case 'greaterThan':
241
+ return Number(columnValue) > Number(filterValue);
242
+ case 'greaterThanOrEqual':
243
+ return Number(columnValue) >= Number(filterValue);
244
+ case 'lessThan':
245
+ return Number(columnValue) < Number(filterValue);
246
+ case 'lessThanOrEqual':
247
+ return Number(columnValue) <= Number(filterValue);
248
+ }
249
+ }
250
+ switch (operator) {
251
+ case 'contains':
252
+ return String(columnValue).toLowerCase().includes(String(filterValue).toLowerCase());
253
+ case 'notContains':
254
+ return !String(columnValue).toLowerCase().includes(String(filterValue).toLowerCase());
255
+ case 'startsWith':
256
+ return String(columnValue).toLowerCase().startsWith(String(filterValue).toLowerCase());
257
+ case 'endsWith':
258
+ return String(columnValue).toLowerCase().endsWith(String(filterValue).toLowerCase());
259
+ case 'equals':
260
+ return columnValue === filterValue;
261
+ case 'notEquals':
262
+ return columnValue !== filterValue;
263
+ case 'isEmpty':
264
+ return columnValue === null || columnValue === undefined || columnValue === '';
265
+ case 'isNotEmpty':
266
+ return columnValue !== null && columnValue !== undefined && columnValue !== '';
267
+ default:
268
+ return true;
269
+ }
270
+ }
@@ -0,0 +1,3 @@
1
+ export * from './selection.feature';
2
+ export * from './column-filter.feature';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/features/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./selection.feature"), exports);
18
+ __exportStar(require("./column-filter.feature"), exports);
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Custom Selection feature for TanStack Table.
3
+ *
4
+ * Adds advanced selection (page vs all, include/exclude semantics) following the
5
+ * official custom-features pattern. Ported from v1 with no behaviour change;
6
+ * `SelectionState`/`SelectMode` now live in `../types/selection.types`.
7
+ */
8
+ import { TableFeature, RowData, Updater, Row } from '@tanstack/react-table';
9
+ import type { SelectionState, SelectMode } from '../types/selection.types';
10
+ export type IsRowSelectableFunction<T = any> = (params: {
11
+ row: T;
12
+ id: string;
13
+ }) => boolean;
14
+ export interface SelectionOptions {
15
+ enableAdvanceSelection?: boolean;
16
+ selectMode?: SelectMode;
17
+ isRowSelectable?: IsRowSelectableFunction;
18
+ onSelectionStateChange?: (updater: Updater<SelectionState>) => void;
19
+ }
20
+ export interface SelectionTableState {
21
+ selectionState: SelectionState;
22
+ }
23
+ declare module '@tanstack/react-table' {
24
+ interface TableState extends SelectionTableState {
25
+ }
26
+ interface TableOptionsResolved<TData extends RowData> extends SelectionOptions {
27
+ }
28
+ interface Table<TData extends RowData> extends SelectionInstance<TData> {
29
+ }
30
+ }
31
+ export interface SelectionInstance<TData extends RowData> {
32
+ setSelectionState: (updater: Updater<SelectionState>) => void;
33
+ toggleAllRowsSelected: () => void;
34
+ toggleRowSelected: (rowId: string) => void;
35
+ selectRow: (rowId: string) => void;
36
+ deselectRow: (rowId: string) => void;
37
+ selectAll: () => void;
38
+ deselectAll: () => void;
39
+ getIsAllRowsSelected: () => boolean;
40
+ getIsSomeRowsSelected: () => boolean;
41
+ getIsRowSelected: (rowId: string) => boolean;
42
+ getSelectionState: () => SelectionState;
43
+ getSelectedCount: () => number;
44
+ getSelectedRows: () => Row<TData>[];
45
+ getSelectedRowIds: () => string[];
46
+ canSelectRow: (rowId: string) => boolean;
47
+ }
48
+ export declare const SelectionFeature: TableFeature<any>;
49
+ //# sourceMappingURL=selection.feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.feature.d.ts","sourceRoot":"","sources":["../../src/features/selection.feature.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAEH,YAAY,EACZ,OAAO,EACP,OAAO,EAGP,GAAG,EACN,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC;AAE3F,MAAM,WAAW,gBAAgB;IAC7B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CACvE;AAED,MAAM,WAAW,mBAAmB;IAChC,cAAc,EAAE,cAAc,CAAC;CAClC;AAED,OAAO,QAAQ,uBAAuB,CAAC;IAEnC,UAAU,UAAW,SAAQ,mBAAmB;KAAG;IAEnD,UAAU,oBAAoB,CAAC,KAAK,SAAS,OAAO,CAAE,SAAQ,gBAAgB;KAAG;IAEjF,UAAU,KAAK,CAAC,KAAK,SAAS,OAAO,CAAE,SAAQ,iBAAiB,CAAC,KAAK,CAAC;KAAG;CAC7E;AAED,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,OAAO;IACpD,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC9D,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,oBAAoB,EAAE,MAAM,OAAO,CAAC;IACpC,qBAAqB,EAAE,MAAM,OAAO,CAAC;IACrC,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,iBAAiB,EAAE,MAAM,cAAc,CAAC;IACxC,gBAAgB,EAAE,MAAM,MAAM,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;IACpC,iBAAiB,EAAE,MAAM,MAAM,EAAE,CAAC;IAClC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5C;AAED,eAAO,MAAM,gBAAgB,EAAE,YAAY,CAAC,GAAG,CA+I9C,CAAC"}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectionFeature = void 0;
4
+ /**
5
+ * Custom Selection feature for TanStack Table.
6
+ *
7
+ * Adds advanced selection (page vs all, include/exclude semantics) following the
8
+ * official custom-features pattern. Ported from v1 with no behaviour change;
9
+ * `SelectionState`/`SelectMode` now live in `../types/selection.types`.
10
+ */
11
+ const react_table_1 = require("@tanstack/react-table");
12
+ exports.SelectionFeature = {
13
+ getInitialState: (state) => ({
14
+ selectionState: { ids: [], type: 'include', selectMode: 'page' },
15
+ ...state,
16
+ }),
17
+ getDefaultOptions: (table) => ({
18
+ enableAdvanceSelection: true,
19
+ selectMode: 'page',
20
+ onSelectionStateChange: (0, react_table_1.makeStateUpdater)('selectionState', table),
21
+ }),
22
+ createTable: (table) => {
23
+ const getRowsForSelection = () => {
24
+ var _a;
25
+ if (table.options.manualPagination) {
26
+ return table.getRowModel().rows;
27
+ }
28
+ return ((_a = table.getPrePaginationRowModel) === null || _a === void 0 ? void 0 : _a.call(table).rows) || table.getRowModel().rows;
29
+ };
30
+ table.setSelectionState = (updater) => {
31
+ var _a, _b;
32
+ if (!table.options.enableAdvanceSelection)
33
+ return;
34
+ const safeUpdater = (old) => (0, react_table_1.functionalUpdate)(updater, old);
35
+ return (_b = (_a = table.options).onSelectionStateChange) === null || _b === void 0 ? void 0 : _b.call(_a, safeUpdater);
36
+ };
37
+ table.selectRow = (rowId) => {
38
+ if (!table.options.enableAdvanceSelection)
39
+ return;
40
+ if (!table.canSelectRow(rowId))
41
+ return;
42
+ table.setSelectionState((old) => {
43
+ if (old.type === 'exclude') {
44
+ return { ...old, ids: old.ids.filter((id) => id !== rowId) };
45
+ }
46
+ const newIds = old.ids.includes(rowId) ? old.ids : [...old.ids, rowId];
47
+ return { ...old, ids: newIds };
48
+ });
49
+ };
50
+ table.deselectRow = (rowId) => {
51
+ if (!table.options.enableAdvanceSelection)
52
+ return;
53
+ table.setSelectionState((old) => {
54
+ if (old.type === 'exclude') {
55
+ const newIds = old.ids.includes(rowId) ? old.ids : [...old.ids, rowId];
56
+ return { ...old, ids: newIds };
57
+ }
58
+ return { ...old, ids: old.ids.filter((id) => id !== rowId) };
59
+ });
60
+ };
61
+ table.toggleRowSelected = (rowId) => {
62
+ if (!table.options.enableAdvanceSelection)
63
+ return;
64
+ if (table.getIsRowSelected(rowId))
65
+ table.deselectRow(rowId);
66
+ else
67
+ table.selectRow(rowId);
68
+ };
69
+ table.selectAll = () => {
70
+ var _a, _b;
71
+ if (!table.options.enableAdvanceSelection)
72
+ return;
73
+ const selectMode = table.options.selectMode || 'page';
74
+ const currentRows = ((_b = (_a = table.getPaginationRowModel) === null || _a === void 0 ? void 0 : _a.call(table)) === null || _b === void 0 ? void 0 : _b.rows) || table.getRowModel().rows;
75
+ if (selectMode === 'all') {
76
+ table.setSelectionState((old) => ({ ...old, ids: [], type: 'exclude' }));
77
+ }
78
+ else {
79
+ const selectableRowIds = currentRows
80
+ .filter((row) => table.canSelectRow(row.id))
81
+ .map((row) => row.id);
82
+ table.setSelectionState((old) => ({ ...old, ids: selectableRowIds, type: 'include' }));
83
+ }
84
+ };
85
+ table.deselectAll = () => {
86
+ if (!table.options.enableAdvanceSelection)
87
+ return;
88
+ table.setSelectionState((old) => ({ ...old, ids: [], type: 'include' }));
89
+ };
90
+ table.toggleAllRowsSelected = () => {
91
+ if (!table.options.enableAdvanceSelection)
92
+ return;
93
+ if (table.getIsAllRowsSelected())
94
+ table.deselectAll();
95
+ else
96
+ table.selectAll();
97
+ };
98
+ table.getIsRowSelected = (rowId) => {
99
+ const state = table.getSelectionState();
100
+ return state.type === 'exclude' ? !state.ids.includes(rowId) : state.ids.includes(rowId);
101
+ };
102
+ table.getIsAllRowsSelected = () => {
103
+ var _a, _b;
104
+ const state = table.getSelectionState();
105
+ const selectMode = table.options.selectMode || 'page';
106
+ if (selectMode === 'all') {
107
+ const totalCount = table.getRowCount();
108
+ if (totalCount === 0)
109
+ return false;
110
+ return state.type === 'exclude' ? state.ids.length === 0 : state.ids.length === totalCount;
111
+ }
112
+ const currentPageRows = ((_b = (_a = table.getPaginationRowModel) === null || _a === void 0 ? void 0 : _a.call(table)) === null || _b === void 0 ? void 0 : _b.rows) || table.getRowModel().rows;
113
+ const selectableRows = currentPageRows.filter((row) => table.canSelectRow(row.id));
114
+ if (selectableRows.length === 0)
115
+ return false;
116
+ return selectableRows.every((row) => table.getIsRowSelected(row.id));
117
+ };
118
+ table.getIsSomeRowsSelected = () => {
119
+ const state = table.getSelectionState();
120
+ const selectMode = table.options.selectMode || 'page';
121
+ if (selectMode === 'all' && state.type === 'exclude') {
122
+ const totalCount = table.getRowCount();
123
+ return totalCount > 0 && state.ids.length < totalCount;
124
+ }
125
+ return state.ids.length > 0;
126
+ };
127
+ table.getSelectionState = () => table.getState().selectionState || { ids: [], type: 'include', selectMode: 'page' };
128
+ table.getSelectedCount = () => {
129
+ const state = table.getSelectionState();
130
+ const selectMode = table.options.selectMode || 'page';
131
+ if (selectMode === 'all' && state.type === 'exclude') {
132
+ const totalCount = table.getRowCount();
133
+ return Math.max(0, totalCount - state.ids.length);
134
+ }
135
+ return state.ids.length;
136
+ };
137
+ table.getSelectedRowIds = () => {
138
+ const state = table.getSelectionState();
139
+ if (state.type === 'exclude')
140
+ return table.getSelectedRows().map((row) => row.id);
141
+ return state.ids;
142
+ };
143
+ table.getSelectedRows = () => {
144
+ const state = table.getSelectionState();
145
+ const allRows = getRowsForSelection();
146
+ return state.type === 'exclude'
147
+ ? allRows.filter((row) => !state.ids.includes(row.id))
148
+ : allRows.filter((row) => state.ids.includes(row.id));
149
+ };
150
+ table.canSelectRow = (rowId) => {
151
+ if (!table.options.isRowSelectable)
152
+ return true;
153
+ const row = table.getRowModel().rows.find((r) => r.id === rowId);
154
+ if (!row)
155
+ return false;
156
+ return table.options.isRowSelectable({ row: row.original, id: rowId });
157
+ };
158
+ },
159
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @ackplus/react-tanstack-data-table — v2 (dev)
3
+ *
4
+ * Phase 1 scaffold: theming system + types. The headless core, render layer,
5
+ * and `<DataTable>` component land in later phases.
6
+ */
7
+ export * from './theme';
8
+ export * from './types';
9
+ export * from './features';
10
+ export * from './utils';
11
+ export * from './core';
12
+ export * from './components';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC;AAG3B,cAAc,SAAS,CAAC;AAGxB,cAAc,QAAQ,CAAC;AAGvB,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * @ackplus/react-tanstack-data-table — v2 (dev)
4
+ *
5
+ * Phase 1 scaffold: theming system + types. The headless core, render layer,
6
+ * and `<DataTable>` component land in later phases.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ // Theming (tokens, palette, MUI component registration, helpers)
24
+ __exportStar(require("./theme"), exports);
25
+ // Public types (props, API, column, slots, state, features)
26
+ __exportStar(require("./types"), exports);
27
+ // Custom TanStack features (selection, advanced column filtering)
28
+ __exportStar(require("./features"), exports);
29
+ // Utilities (pure helpers, debounced fetch)
30
+ __exportStar(require("./utils"), exports);
31
+ // Headless engine
32
+ __exportStar(require("./core"), exports);
33
+ // Render layer + <DataTable> component
34
+ __exportStar(require("./components"), exports);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Convenience helper to build a `ThemeOptions` fragment for the grid, to spread
3
+ * into `createTheme()`. Equivalent to writing `palette.tanstackDataGrid` +
4
+ * `components.MuiTanstackDataGrid` by hand.
5
+ */
6
+ import type { ThemeOptions } from '@mui/material/styles';
7
+ import type { TanstackDataGridPalette } from './palette';
8
+ import type { DataTableClassKey } from './mui-augmentation';
9
+ import type { DataTableProps } from '../types/data-table.types';
10
+ export interface CreateDataTableThemeOptions {
11
+ palette?: Partial<TanstackDataGridPalette>;
12
+ defaultProps?: Partial<DataTableProps<any>>;
13
+ styleOverrides?: Partial<Record<DataTableClassKey, any>>;
14
+ }
15
+ export declare function createDataTableTheme(options?: CreateDataTableThemeOptions): ThemeOptions;
16
+ //# sourceMappingURL=create-data-table-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-data-table-theme.d.ts","sourceRoot":"","sources":["../../src/theme/create-data-table-theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,MAAM,WAAW,2BAA2B;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC;CAC5D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAAgC,GAAG,YAAY,CAiB5F"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDataTableTheme = createDataTableTheme;
4
+ function createDataTableTheme(options = {}) {
5
+ const { palette, defaultProps, styleOverrides } = options;
6
+ const result = {
7
+ components: {
8
+ MuiTanstackDataGrid: {
9
+ ...(defaultProps ? { defaultProps } : {}),
10
+ ...(styleOverrides ? { styleOverrides } : {}),
11
+ },
12
+ },
13
+ };
14
+ if (palette) {
15
+ result.palette = { tanstackDataGrid: palette };
16
+ }
17
+ return result;
18
+ }