@reactorui/datagrid 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.
- package/LICENSE +21 -0
- package/README.md +778 -0
- package/dist/components/DataGrid/DataGrid.d.ts +5 -0
- package/dist/components/DataGrid/DataGrid.d.ts.map +1 -0
- package/dist/components/DataGrid/DataGrid.js +87 -0
- package/dist/components/DataGrid/index.d.ts +3 -0
- package/dist/components/DataGrid/index.d.ts.map +1 -0
- package/dist/components/DataGrid/index.js +1 -0
- package/dist/components/Filter/FilterControls.d.ts +11 -0
- package/dist/components/Filter/FilterControls.d.ts.map +1 -0
- package/dist/components/Filter/FilterControls.js +78 -0
- package/dist/components/Filter/index.d.ts +2 -0
- package/dist/components/Filter/index.d.ts.map +1 -0
- package/dist/components/Filter/index.js +1 -0
- package/dist/components/Pagination/Pagination.d.ts +17 -0
- package/dist/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination/Pagination.js +12 -0
- package/dist/components/Pagination/index.d.ts +2 -0
- package/dist/components/Pagination/index.d.ts.map +1 -0
- package/dist/components/Pagination/index.js +1 -0
- package/dist/components/Search/SearchInput.d.ts +11 -0
- package/dist/components/Search/SearchInput.d.ts.map +1 -0
- package/dist/components/Search/SearchInput.js +9 -0
- package/dist/components/Search/index.d.ts +2 -0
- package/dist/components/Search/index.d.ts.map +1 -0
- package/dist/components/Search/index.js +1 -0
- package/dist/components/Table/TableBody.d.ts +20 -0
- package/dist/components/Table/TableBody.d.ts.map +1 -0
- package/dist/components/Table/TableBody.js +56 -0
- package/dist/components/Table/TableHeader.d.ts +13 -0
- package/dist/components/Table/TableHeader.d.ts.map +1 -0
- package/dist/components/Table/TableHeader.js +24 -0
- package/dist/components/Table/index.d.ts +3 -0
- package/dist/components/Table/index.d.ts.map +1 -0
- package/dist/components/Table/index.js +2 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useDataGrid.d.ts +49 -0
- package/dist/hooks/useDataGrid.d.ts.map +1 -0
- package/dist/hooks/useDataGrid.js +356 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/setupTests.d.ts +12 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/setupTests.js +1 -0
- package/dist/themes/index.d.ts +22 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +31 -0
- package/dist/types/index.d.ts +108 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +209 -0
- package/package.json +80 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
+
import { createApiRequest, compareValues, sortData } from '../utils';
|
|
3
|
+
export const useDataGrid = ({ data: staticData, endpoint, httpConfig, pageSize = 10, serverPageSize = 100, onDataLoad, onDataError, onLoadingStateChange, onPageChange, onPageSizeChange, onSortChange, onFilterChange, onSearchChange, }) => {
|
|
4
|
+
// Core state
|
|
5
|
+
const [loading, setLoading] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const [serverData, setServerData] = useState([]);
|
|
8
|
+
const [lastServerResponse, setLastServerResponse] = useState(null);
|
|
9
|
+
// UI state
|
|
10
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
11
|
+
const [activeFilters, setActiveFilters] = useState([]);
|
|
12
|
+
const [sortConfig, setSortConfig] = useState({ column: '', direction: 'asc' });
|
|
13
|
+
const [selectedRows, setSelectedRows] = useState(new Set());
|
|
14
|
+
// Pagination state (simplified)
|
|
15
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
16
|
+
const [currentPageSize, setCurrentPageSize] = useState(pageSize);
|
|
17
|
+
const [continuationToken, setContinuationToken] = useState();
|
|
18
|
+
const [tokenHistory, setTokenHistory] = useState([]);
|
|
19
|
+
// Determine data source
|
|
20
|
+
const sourceData = staticData || serverData;
|
|
21
|
+
// Internal loading state handler
|
|
22
|
+
const handleLoadingChange = useCallback((newLoading, context) => {
|
|
23
|
+
setLoading(newLoading);
|
|
24
|
+
onLoadingStateChange?.(newLoading, context);
|
|
25
|
+
}, [onLoadingStateChange]);
|
|
26
|
+
// Internal error handler
|
|
27
|
+
const handleError = useCallback((err, context) => {
|
|
28
|
+
const errorMessage = err.message || 'An unknown error occurred';
|
|
29
|
+
setError(errorMessage);
|
|
30
|
+
onDataError?.(err, context);
|
|
31
|
+
}, [onDataError]);
|
|
32
|
+
// Process data (search, filter, sort) - sorting is ALWAYS client-side
|
|
33
|
+
const processedData = useMemo(() => {
|
|
34
|
+
let processed = [...sourceData];
|
|
35
|
+
// Apply search (client-side for static data)
|
|
36
|
+
if (searchTerm && staticData) {
|
|
37
|
+
processed = processed.filter((row) => Object.values(row).some((value) => value?.toString().toLowerCase().includes(searchTerm.toLowerCase())));
|
|
38
|
+
}
|
|
39
|
+
// Apply filters (client-side for static data)
|
|
40
|
+
if (staticData) {
|
|
41
|
+
activeFilters.forEach((filter) => {
|
|
42
|
+
processed = processed.filter((row) => {
|
|
43
|
+
const value = row[filter.column];
|
|
44
|
+
return compareValues(value, filter.value, filter.operator, filter.dataType);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Apply sorting (ALWAYS client-side)
|
|
49
|
+
if (sortConfig.column) {
|
|
50
|
+
processed = sortData(processed, sortConfig.column, sortConfig.direction);
|
|
51
|
+
}
|
|
52
|
+
return processed;
|
|
53
|
+
}, [sourceData, searchTerm, activeFilters, sortConfig, staticData]);
|
|
54
|
+
// Paginate data - only for client-side data
|
|
55
|
+
const paginatedData = useMemo(() => {
|
|
56
|
+
if (!staticData)
|
|
57
|
+
return sourceData; // For server-side, return as-is
|
|
58
|
+
const start = (currentPage - 1) * currentPageSize;
|
|
59
|
+
const end = start + currentPageSize;
|
|
60
|
+
return processedData.slice(start, end);
|
|
61
|
+
}, [processedData, currentPage, currentPageSize, staticData, sourceData]);
|
|
62
|
+
// Pagination info
|
|
63
|
+
const paginationInfo = useMemo(() => {
|
|
64
|
+
if (!staticData && lastServerResponse) {
|
|
65
|
+
// Server-side pagination info
|
|
66
|
+
const displayedCount = sourceData.length;
|
|
67
|
+
const start = displayedCount === 0 ? 0 : 1;
|
|
68
|
+
const end = displayedCount;
|
|
69
|
+
return {
|
|
70
|
+
currentPage,
|
|
71
|
+
totalPages: 1, // Not meaningful with continuation tokens
|
|
72
|
+
pageSize: currentPageSize,
|
|
73
|
+
totalRecords: lastServerResponse.Count,
|
|
74
|
+
start,
|
|
75
|
+
end,
|
|
76
|
+
hasNext: lastServerResponse.HasMore,
|
|
77
|
+
hasPrevious: tokenHistory.length > 0,
|
|
78
|
+
continuationToken: lastServerResponse.ContinuationToken,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Client-side pagination info
|
|
82
|
+
const totalPages = Math.ceil(processedData.length / currentPageSize);
|
|
83
|
+
const start = processedData.length === 0 ? 0 : (currentPage - 1) * currentPageSize + 1;
|
|
84
|
+
const end = Math.min(currentPage * currentPageSize, processedData.length);
|
|
85
|
+
return {
|
|
86
|
+
currentPage,
|
|
87
|
+
totalPages,
|
|
88
|
+
pageSize: currentPageSize,
|
|
89
|
+
totalRecords: processedData.length,
|
|
90
|
+
start,
|
|
91
|
+
end,
|
|
92
|
+
hasNext: currentPage < totalPages,
|
|
93
|
+
hasPrevious: currentPage > 1,
|
|
94
|
+
};
|
|
95
|
+
}, [
|
|
96
|
+
processedData.length,
|
|
97
|
+
currentPage,
|
|
98
|
+
currentPageSize,
|
|
99
|
+
staticData,
|
|
100
|
+
sourceData,
|
|
101
|
+
lastServerResponse,
|
|
102
|
+
tokenHistory.length,
|
|
103
|
+
]);
|
|
104
|
+
// Load server data
|
|
105
|
+
const loadServerData = useCallback(async (resetPagination = false, navigationDirection) => {
|
|
106
|
+
if (!endpoint || staticData)
|
|
107
|
+
return;
|
|
108
|
+
handleLoadingChange(true, 'data-load');
|
|
109
|
+
setError(null);
|
|
110
|
+
try {
|
|
111
|
+
let requestToken = continuationToken;
|
|
112
|
+
// Handle navigation
|
|
113
|
+
if (resetPagination) {
|
|
114
|
+
requestToken = undefined;
|
|
115
|
+
setContinuationToken(undefined);
|
|
116
|
+
setTokenHistory([]);
|
|
117
|
+
setCurrentPage(1);
|
|
118
|
+
}
|
|
119
|
+
else if (navigationDirection === 'previous' && tokenHistory.length > 0) {
|
|
120
|
+
// Go back to previous token
|
|
121
|
+
const newHistory = [...tokenHistory];
|
|
122
|
+
requestToken = newHistory.pop();
|
|
123
|
+
setTokenHistory(newHistory);
|
|
124
|
+
setContinuationToken(requestToken);
|
|
125
|
+
}
|
|
126
|
+
const request = {
|
|
127
|
+
page: currentPage,
|
|
128
|
+
pageSize: serverPageSize,
|
|
129
|
+
search: searchTerm,
|
|
130
|
+
filters: activeFilters,
|
|
131
|
+
continuationToken: requestToken,
|
|
132
|
+
};
|
|
133
|
+
const response = await createApiRequest(endpoint, request, httpConfig);
|
|
134
|
+
// Handle response
|
|
135
|
+
setServerData(response.Items);
|
|
136
|
+
setLastServerResponse(response);
|
|
137
|
+
// Update token for next navigation
|
|
138
|
+
if (navigationDirection === 'next' && continuationToken) {
|
|
139
|
+
// Save current token to history
|
|
140
|
+
setTokenHistory((prev) => [...prev, continuationToken]);
|
|
141
|
+
}
|
|
142
|
+
if (response.ContinuationToken) {
|
|
143
|
+
setContinuationToken(response.ContinuationToken);
|
|
144
|
+
}
|
|
145
|
+
onDataLoad?.(response);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
handleError(err instanceof Error ? err : new Error('Failed to load data'), 'data-load');
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
handleLoadingChange(false, 'data-load');
|
|
152
|
+
}
|
|
153
|
+
}, [
|
|
154
|
+
endpoint,
|
|
155
|
+
staticData,
|
|
156
|
+
currentPage,
|
|
157
|
+
serverPageSize,
|
|
158
|
+
searchTerm,
|
|
159
|
+
sortConfig,
|
|
160
|
+
activeFilters,
|
|
161
|
+
continuationToken,
|
|
162
|
+
tokenHistory,
|
|
163
|
+
httpConfig,
|
|
164
|
+
onDataLoad,
|
|
165
|
+
handleLoadingChange,
|
|
166
|
+
handleError,
|
|
167
|
+
]);
|
|
168
|
+
// Load data on mount and when dependencies change (no sorting here - that's client-side)
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
if (!staticData) {
|
|
171
|
+
loadServerData(true); // Reset pagination on mount
|
|
172
|
+
}
|
|
173
|
+
}, [staticData, searchTerm, activeFilters]); // Note: sortConfig removed - sorting is client-side only
|
|
174
|
+
// Actions
|
|
175
|
+
const setSort = useCallback((column) => {
|
|
176
|
+
const newSortConfig = {
|
|
177
|
+
column,
|
|
178
|
+
direction: sortConfig.column === column && sortConfig.direction === 'asc' ? 'desc' : 'asc',
|
|
179
|
+
};
|
|
180
|
+
setSortConfig(newSortConfig);
|
|
181
|
+
onSortChange?.(newSortConfig);
|
|
182
|
+
// No server reload needed - sorting is client-side only
|
|
183
|
+
if (staticData) {
|
|
184
|
+
setCurrentPage(1);
|
|
185
|
+
}
|
|
186
|
+
}, [sortConfig, onSortChange, staticData]);
|
|
187
|
+
const setPage = useCallback((page) => {
|
|
188
|
+
if (staticData) {
|
|
189
|
+
// Client-side pagination
|
|
190
|
+
setCurrentPage(page);
|
|
191
|
+
onPageChange?.(page, {
|
|
192
|
+
...paginationInfo,
|
|
193
|
+
currentPage: page,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// Server-side with continuation tokens doesn't support arbitrary page jumps
|
|
198
|
+
console.warn('Direct page navigation not supported with continuation tokens. Use navigateNext/navigatePrevious instead.');
|
|
199
|
+
}
|
|
200
|
+
}, [staticData, paginationInfo, onPageChange]);
|
|
201
|
+
const navigateNext = useCallback(() => {
|
|
202
|
+
if (!paginationInfo.hasNext)
|
|
203
|
+
return;
|
|
204
|
+
if (!staticData) {
|
|
205
|
+
// Server-side navigation
|
|
206
|
+
loadServerData(false, 'next');
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// Client-side navigation
|
|
210
|
+
setPage(currentPage + 1);
|
|
211
|
+
}
|
|
212
|
+
}, [paginationInfo.hasNext, staticData, loadServerData, setPage, currentPage]);
|
|
213
|
+
const navigatePrevious = useCallback(() => {
|
|
214
|
+
if (!paginationInfo.hasPrevious)
|
|
215
|
+
return;
|
|
216
|
+
if (!staticData) {
|
|
217
|
+
// Server-side navigation
|
|
218
|
+
loadServerData(false, 'previous');
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
// Client-side navigation
|
|
222
|
+
setPage(currentPage - 1);
|
|
223
|
+
}
|
|
224
|
+
}, [paginationInfo.hasPrevious, staticData, loadServerData, setPage, currentPage]);
|
|
225
|
+
const setPageSize = useCallback((newPageSize) => {
|
|
226
|
+
setCurrentPageSize(newPageSize);
|
|
227
|
+
setCurrentPage(1);
|
|
228
|
+
const newPaginationInfo = {
|
|
229
|
+
...paginationInfo,
|
|
230
|
+
pageSize: newPageSize,
|
|
231
|
+
currentPage: 1,
|
|
232
|
+
totalPages: staticData ? Math.ceil(processedData.length / newPageSize) : 1,
|
|
233
|
+
};
|
|
234
|
+
onPageSizeChange?.(newPageSize, newPaginationInfo);
|
|
235
|
+
// Reset pagination for server-side
|
|
236
|
+
if (!staticData) {
|
|
237
|
+
setContinuationToken(undefined);
|
|
238
|
+
setTokenHistory([]);
|
|
239
|
+
loadServerData(true);
|
|
240
|
+
}
|
|
241
|
+
}, [paginationInfo, staticData, processedData.length, onPageSizeChange, loadServerData]);
|
|
242
|
+
const updateSearchTerm = useCallback((term) => {
|
|
243
|
+
setSearchTerm(term);
|
|
244
|
+
onSearchChange?.(term);
|
|
245
|
+
// Reset pagination when search changes
|
|
246
|
+
setCurrentPage(1);
|
|
247
|
+
if (!staticData) {
|
|
248
|
+
setContinuationToken(undefined);
|
|
249
|
+
setTokenHistory([]);
|
|
250
|
+
}
|
|
251
|
+
}, [onSearchChange, staticData]);
|
|
252
|
+
const addFilter = useCallback((filter) => {
|
|
253
|
+
const label = `${filter.column} ${filter.operator} "${filter.value}"`;
|
|
254
|
+
const newFilters = [
|
|
255
|
+
...activeFilters.filter((f) => f.column !== filter.column),
|
|
256
|
+
{ ...filter, label },
|
|
257
|
+
];
|
|
258
|
+
setActiveFilters(newFilters);
|
|
259
|
+
onFilterChange?.(newFilters);
|
|
260
|
+
// Reset pagination when filters change
|
|
261
|
+
setCurrentPage(1);
|
|
262
|
+
if (!staticData) {
|
|
263
|
+
setContinuationToken(undefined);
|
|
264
|
+
setTokenHistory([]);
|
|
265
|
+
}
|
|
266
|
+
}, [activeFilters, onFilterChange, staticData]);
|
|
267
|
+
const removeFilter = useCallback((index) => {
|
|
268
|
+
const newFilters = activeFilters.filter((_, i) => i !== index);
|
|
269
|
+
setActiveFilters(newFilters);
|
|
270
|
+
onFilterChange?.(newFilters);
|
|
271
|
+
// Reset pagination when filters change
|
|
272
|
+
setCurrentPage(1);
|
|
273
|
+
if (!staticData) {
|
|
274
|
+
setContinuationToken(undefined);
|
|
275
|
+
setTokenHistory([]);
|
|
276
|
+
}
|
|
277
|
+
}, [activeFilters, onFilterChange, staticData]);
|
|
278
|
+
const clearFilters = useCallback(() => {
|
|
279
|
+
setActiveFilters([]);
|
|
280
|
+
onFilterChange?.([]);
|
|
281
|
+
// Reset pagination when filters change
|
|
282
|
+
setCurrentPage(1);
|
|
283
|
+
if (!staticData) {
|
|
284
|
+
setContinuationToken(undefined);
|
|
285
|
+
setTokenHistory([]);
|
|
286
|
+
}
|
|
287
|
+
}, [onFilterChange, staticData]);
|
|
288
|
+
const selectRow = useCallback((rowId, selected) => {
|
|
289
|
+
setSelectedRows((prev) => {
|
|
290
|
+
const newSet = new Set(prev);
|
|
291
|
+
if (selected) {
|
|
292
|
+
newSet.add(rowId);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
newSet.delete(rowId);
|
|
296
|
+
}
|
|
297
|
+
return newSet;
|
|
298
|
+
});
|
|
299
|
+
}, []);
|
|
300
|
+
const selectAll = useCallback((selected) => {
|
|
301
|
+
if (selected) {
|
|
302
|
+
const currentPageData = staticData ? paginatedData : sourceData;
|
|
303
|
+
const allIds = currentPageData.map((row) => String(row.id)).filter(Boolean);
|
|
304
|
+
setSelectedRows(new Set(allIds));
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
setSelectedRows(new Set());
|
|
308
|
+
}
|
|
309
|
+
}, [staticData, paginatedData, sourceData]);
|
|
310
|
+
const refresh = useCallback(() => {
|
|
311
|
+
if (staticData) {
|
|
312
|
+
setSearchTerm('');
|
|
313
|
+
setActiveFilters([]);
|
|
314
|
+
setSortConfig({ column: '', direction: 'asc' });
|
|
315
|
+
setCurrentPage(1);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
loadServerData(true);
|
|
319
|
+
}
|
|
320
|
+
}, [staticData, loadServerData]);
|
|
321
|
+
return {
|
|
322
|
+
// Data
|
|
323
|
+
data: sourceData,
|
|
324
|
+
processedData,
|
|
325
|
+
paginatedData: staticData ? paginatedData : sourceData,
|
|
326
|
+
loading,
|
|
327
|
+
error,
|
|
328
|
+
// State
|
|
329
|
+
searchTerm,
|
|
330
|
+
activeFilters,
|
|
331
|
+
sortConfig,
|
|
332
|
+
selectedRows,
|
|
333
|
+
currentPage,
|
|
334
|
+
currentPageSize,
|
|
335
|
+
totalRecords: paginationInfo.totalRecords,
|
|
336
|
+
hasMore: paginationInfo.hasNext,
|
|
337
|
+
continuationToken: paginationInfo.continuationToken,
|
|
338
|
+
// Actions
|
|
339
|
+
setSearchTerm: updateSearchTerm,
|
|
340
|
+
setSort,
|
|
341
|
+
setCurrentPage: setPage,
|
|
342
|
+
setCurrentPageSize: setPageSize,
|
|
343
|
+
navigateNext,
|
|
344
|
+
navigatePrevious,
|
|
345
|
+
addFilter,
|
|
346
|
+
removeFilter,
|
|
347
|
+
clearFilters,
|
|
348
|
+
selectRow,
|
|
349
|
+
selectAll,
|
|
350
|
+
refresh,
|
|
351
|
+
// Computed
|
|
352
|
+
paginationInfo,
|
|
353
|
+
selectedData: sourceData.filter((row) => selectedRows.has(String(row.id))),
|
|
354
|
+
hasSelection: selectedRows.size > 0,
|
|
355
|
+
};
|
|
356
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { DataGrid } from './components/DataGrid';
|
|
2
|
+
export { useDataGrid } from './hooks';
|
|
3
|
+
export type { BaseRowData, Column, DataGridProps, ActiveFilter, SortConfig, PaginationInfo, ServerRequest, ServerResponse, HttpConfig, OnDataLoadCallback, OnDataErrorCallback, OnLoadingStateChangeCallback, OnPageChangeCallback, OnPageSizeChangeCallback, OnSortChangeCallback, OnFilterChangeCallback, OnSearchChangeCallback, OnTableRowClickCallback, OnTableRowDoubleClickCallback, OnRowSelectCallback, OnSelectionChangeCallback, OnTableRowHoverCallback, OnCellClickCallback, OnTableRefreshCallback, } from './types';
|
|
4
|
+
export { getTheme, themes } from './themes';
|
|
5
|
+
export type { Theme } from './themes';
|
|
6
|
+
export { formatters, compareValues, createApiRequest } from './utils';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,YAAY,EACV,WAAW,EACX,MAAM,EACN,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC5B,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,6BAA6B,EAC7B,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGtC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Main component
|
|
2
|
+
export { DataGrid } from './components/DataGrid';
|
|
3
|
+
// Hooks
|
|
4
|
+
export { useDataGrid } from './hooks';
|
|
5
|
+
// Themes
|
|
6
|
+
export { getTheme, themes } from './themes';
|
|
7
|
+
// Utilities
|
|
8
|
+
export { formatters, compareValues, createApiRequest } from './utils';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
declare global {
|
|
3
|
+
namespace jest {
|
|
4
|
+
interface Matchers<R> {
|
|
5
|
+
toBeInTheDocument(): R;
|
|
6
|
+
toHaveTextContent(text: string): R;
|
|
7
|
+
toBeVisible(): R;
|
|
8
|
+
toBeDisabled(): R;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=setupTests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupTests.d.ts","sourceRoot":"","sources":["../src/setupTests.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AAGnC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,IAAI,CAAC;QACb,UAAU,QAAQ,CAAC,CAAC;YAClB,iBAAiB,IAAI,CAAC,CAAC;YACvB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC;YACnC,WAAW,IAAI,CAAC,CAAC;YACjB,YAAY,IAAI,CAAC,CAAC;SACnB;KACF;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Theme {
|
|
2
|
+
container: string;
|
|
3
|
+
table: string;
|
|
4
|
+
header: string;
|
|
5
|
+
headerCell: string;
|
|
6
|
+
row: string;
|
|
7
|
+
cell: string;
|
|
8
|
+
selectedRow: string;
|
|
9
|
+
searchInput: string;
|
|
10
|
+
button: string;
|
|
11
|
+
pagination: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const defaultTheme: Theme;
|
|
14
|
+
export declare const stripedTheme: Theme;
|
|
15
|
+
export declare const borderedTheme: Theme;
|
|
16
|
+
export declare const themes: {
|
|
17
|
+
default: Theme;
|
|
18
|
+
striped: Theme;
|
|
19
|
+
bordered: Theme;
|
|
20
|
+
};
|
|
21
|
+
export declare const getTheme: (variant?: keyof typeof themes) => Theme;
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,KAa1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAO3B,CAAC;AAEF,eAAO,MAAM,MAAM;;;;CAIlB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,UAAS,MAAM,OAAO,MAAkB,KAAG,KAEnE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const defaultTheme = {
|
|
2
|
+
container: 'bg-white rounded-lg shadow-sm border border-gray-200',
|
|
3
|
+
table: 'w-full',
|
|
4
|
+
header: 'bg-gray-50 border-b border-gray-200',
|
|
5
|
+
headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider',
|
|
6
|
+
row: 'hover:bg-gray-50 transition-colors duration-150',
|
|
7
|
+
cell: 'px-4 py-3 text-sm text-gray-900',
|
|
8
|
+
selectedRow: 'bg-blue-50 hover:bg-blue-100',
|
|
9
|
+
searchInput: 'px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500',
|
|
10
|
+
button: 'px-3 py-2 bg-blue-600 text-white text-sm rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500',
|
|
11
|
+
pagination: 'flex items-center justify-between px-4 py-3 bg-white border-t border-gray-200',
|
|
12
|
+
};
|
|
13
|
+
export const stripedTheme = {
|
|
14
|
+
...defaultTheme,
|
|
15
|
+
row: 'odd:bg-gray-50 even:bg-white hover:bg-gray-100 transition-colors duration-150',
|
|
16
|
+
};
|
|
17
|
+
export const borderedTheme = {
|
|
18
|
+
...defaultTheme,
|
|
19
|
+
container: 'bg-white rounded-lg shadow-sm border border-gray-200',
|
|
20
|
+
table: 'w-full border-collapse',
|
|
21
|
+
cell: 'px-4 py-3 text-sm text-gray-900 border-r border-gray-200 last:border-r-0',
|
|
22
|
+
headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider border-r border-gray-200 last:border-r-0',
|
|
23
|
+
};
|
|
24
|
+
export const themes = {
|
|
25
|
+
default: defaultTheme,
|
|
26
|
+
striped: stripedTheme,
|
|
27
|
+
bordered: borderedTheme,
|
|
28
|
+
};
|
|
29
|
+
export const getTheme = (variant = 'default') => {
|
|
30
|
+
return themes[variant] || themes.default;
|
|
31
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ReactNode, HTMLAttributes } from 'react';
|
|
2
|
+
export interface BaseRowData {
|
|
3
|
+
id?: string | number;
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
export interface Column<T = BaseRowData> {
|
|
7
|
+
key: keyof T | string;
|
|
8
|
+
label: string;
|
|
9
|
+
sortable?: boolean;
|
|
10
|
+
filterable?: boolean;
|
|
11
|
+
dataType?: 'string' | 'number' | 'boolean' | 'date' | 'datetime';
|
|
12
|
+
width?: string | number;
|
|
13
|
+
minWidth?: string | number;
|
|
14
|
+
maxWidth?: string | number;
|
|
15
|
+
align?: 'left' | 'center' | 'right';
|
|
16
|
+
render?: (value: any, row: T, index: number) => ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export interface ActiveFilter {
|
|
19
|
+
column: string;
|
|
20
|
+
operator: string;
|
|
21
|
+
value: any;
|
|
22
|
+
dataType: string;
|
|
23
|
+
label: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SortConfig {
|
|
26
|
+
column: string;
|
|
27
|
+
direction: 'asc' | 'desc';
|
|
28
|
+
}
|
|
29
|
+
export interface PaginationInfo {
|
|
30
|
+
currentPage: number;
|
|
31
|
+
totalPages: number;
|
|
32
|
+
pageSize: number;
|
|
33
|
+
totalRecords: number;
|
|
34
|
+
start: number;
|
|
35
|
+
end: number;
|
|
36
|
+
hasNext: boolean;
|
|
37
|
+
hasPrevious: boolean;
|
|
38
|
+
continuationToken?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface ServerRequest {
|
|
41
|
+
page: number;
|
|
42
|
+
pageSize: number;
|
|
43
|
+
search: string;
|
|
44
|
+
filters: ActiveFilter[];
|
|
45
|
+
continuationToken?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface ServerResponse<T = BaseRowData> {
|
|
48
|
+
Items: T[];
|
|
49
|
+
ContinuationToken?: string;
|
|
50
|
+
HasMore: boolean;
|
|
51
|
+
Count: number;
|
|
52
|
+
}
|
|
53
|
+
export interface HttpConfig {
|
|
54
|
+
bearerToken?: string;
|
|
55
|
+
apiKey?: string;
|
|
56
|
+
customHeaders?: Record<string, string>;
|
|
57
|
+
method?: 'GET' | 'POST';
|
|
58
|
+
postDataFormat?: 'form' | 'json';
|
|
59
|
+
withCredentials?: boolean;
|
|
60
|
+
timeout?: number;
|
|
61
|
+
}
|
|
62
|
+
export type OnDataLoadCallback<T = BaseRowData> = (data: ServerResponse<T>) => void;
|
|
63
|
+
export type OnDataErrorCallback = (error: Error, context: string) => void;
|
|
64
|
+
export type OnLoadingStateChangeCallback = (loading: boolean, context: string) => void;
|
|
65
|
+
export type OnPageChangeCallback = (page: number, paginationInfo: PaginationInfo) => void;
|
|
66
|
+
export type OnPageSizeChangeCallback = (pageSize: number, paginationInfo: PaginationInfo) => void;
|
|
67
|
+
export type OnSortChangeCallback = (sortConfig: SortConfig) => void;
|
|
68
|
+
export type OnFilterChangeCallback = (filters: ActiveFilter[]) => void;
|
|
69
|
+
export type OnSearchChangeCallback = (searchTerm: string) => void;
|
|
70
|
+
export type OnTableRowClickCallback<T = BaseRowData> = (row: T, event: React.MouseEvent) => void;
|
|
71
|
+
export type OnTableRowDoubleClickCallback<T = BaseRowData> = (row: T, event: React.MouseEvent) => boolean | void;
|
|
72
|
+
export type OnRowSelectCallback<T = BaseRowData> = (row: T, isSelected: boolean) => void;
|
|
73
|
+
export type OnSelectionChangeCallback<T = BaseRowData> = (selectedRows: T[]) => void;
|
|
74
|
+
export type OnTableRowHoverCallback<T = BaseRowData> = (row: T | null, event: React.MouseEvent) => void;
|
|
75
|
+
export type OnCellClickCallback<T = BaseRowData> = (value: any, row: T, column: Column<T>, event: React.MouseEvent) => void;
|
|
76
|
+
export type OnTableRefreshCallback = () => void;
|
|
77
|
+
export interface DataGridProps<T = BaseRowData> extends Omit<HTMLAttributes<HTMLDivElement>, 'onError'> {
|
|
78
|
+
data?: T[];
|
|
79
|
+
endpoint?: string;
|
|
80
|
+
columns?: Column<T>[];
|
|
81
|
+
enableSearch?: boolean;
|
|
82
|
+
enableSorting?: boolean;
|
|
83
|
+
enableFilters?: boolean;
|
|
84
|
+
enableSelection?: boolean;
|
|
85
|
+
pageSize?: number;
|
|
86
|
+
serverPageSize?: number;
|
|
87
|
+
pageSizeOptions?: number[];
|
|
88
|
+
httpConfig?: HttpConfig;
|
|
89
|
+
className?: string;
|
|
90
|
+
variant?: 'default' | 'striped' | 'bordered';
|
|
91
|
+
size?: 'sm' | 'md' | 'lg';
|
|
92
|
+
onDataLoad?: OnDataLoadCallback<T>;
|
|
93
|
+
onDataError?: OnDataErrorCallback;
|
|
94
|
+
onLoadingStateChange?: OnLoadingStateChangeCallback;
|
|
95
|
+
onPageChange?: OnPageChangeCallback;
|
|
96
|
+
onPageSizeChange?: OnPageSizeChangeCallback;
|
|
97
|
+
onSortChange?: OnSortChangeCallback;
|
|
98
|
+
onFilterChange?: OnFilterChangeCallback;
|
|
99
|
+
onSearchChange?: OnSearchChangeCallback;
|
|
100
|
+
onTableRefresh?: OnTableRefreshCallback;
|
|
101
|
+
onTableRowClick?: OnTableRowClickCallback<T>;
|
|
102
|
+
onTableRowDoubleClick?: OnTableRowDoubleClickCallback<T>;
|
|
103
|
+
onRowSelect?: OnRowSelectCallback<T>;
|
|
104
|
+
onSelectionChange?: OnSelectionChangeCallback<T>;
|
|
105
|
+
onTableRowHover?: OnTableRowHoverCallback<T>;
|
|
106
|
+
onCellClick?: OnCellClickCallback<T>;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { HttpConfig, ServerRequest, ServerResponse } from '../types';
|
|
2
|
+
export declare const formatters: {
|
|
3
|
+
date: (value: string, includeTime?: boolean) => string;
|
|
4
|
+
currency: (value: number, currency?: string) => string;
|
|
5
|
+
number: (value: number, decimals?: number) => string;
|
|
6
|
+
truncate: (text: string, length: number) => string;
|
|
7
|
+
};
|
|
8
|
+
export declare const compareValues: (dataValue: any, filterValue: any, operator: string, dataType: string) => boolean;
|
|
9
|
+
export declare const createApiRequest: <T>(endpoint: string, request: ServerRequest, config?: HttpConfig) => Promise<ServerResponse<T>>;
|
|
10
|
+
export declare const mapServerResponse: <T>(data: any) => ServerResponse<T>;
|
|
11
|
+
export declare const sortData: <T>(data: T[], sortColumn: string, direction: "asc" | "desc") => T[];
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGrE,eAAO,MAAM,UAAU;kBACP,MAAM;sBAMF,MAAM;oBAOR,MAAM;qBAOL,MAAM,UAAU,MAAM;CAIxC,CAAC;AAGF,eAAO,MAAM,aAAa,GACxB,WAAW,GAAG,EACd,aAAa,GAAG,EAChB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,OAkEF,CAAC;AAGF,eAAO,MAAM,gBAAgB,GAAU,CAAC,EACtC,UAAU,MAAM,EAChB,SAAS,aAAa,EACtB,SAAQ,UAAe,KACtB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CA2D3B,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,MAAM,GAAG,KAAG,cAAc,CAAC,CAAC,CA6DhE,CAAC;AAGF,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,YAAY,MAAM,EAAE,WAAW,KAAK,GAAG,MAAM,KAAG,CAAC,EAiBvF,CAAC"}
|