@reactorui/datagrid 1.0.22 → 1.0.24
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/README.md +96 -13
- package/dist/components/DataGrid/DataGrid.d.ts +1 -1
- package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/DataGrid.js +40 -4
- package/dist/components/Filter/FilterControls.d.ts +0 -2
- package/dist/components/Filter/FilterControls.d.ts.map +1 -1
- package/dist/components/Filter/FilterControls.js +50 -15
- package/dist/components/Table/TableBody.d.ts.map +1 -1
- package/dist/components/Table/TableBody.js +1 -1
- package/dist/hooks/useDataGrid.d.ts +8 -1
- package/dist/hooks/useDataGrid.d.ts.map +1 -1
- package/dist/hooks/useDataGrid.js +34 -24
- package/dist/types/index.d.ts +79 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -372,15 +372,22 @@ For large datasets, enable scrollable body with fixed headers:
|
|
|
372
372
|
|
|
373
373
|
### Features
|
|
374
374
|
|
|
375
|
-
| Prop | Type
|
|
376
|
-
| -------------------- |
|
|
377
|
-
| `enableSearch` | `boolean`
|
|
378
|
-
| `enableSorting` | `boolean`
|
|
379
|
-
| `enableFilters` | `boolean`
|
|
380
|
-
| `enableSelection` | `boolean`
|
|
381
|
-
| `enableDelete` | `boolean`
|
|
382
|
-
| `enableRefresh` | `boolean`
|
|
383
|
-
| `deleteConfirmation` | `boolean`
|
|
375
|
+
| Prop | Type | Default | Description |
|
|
376
|
+
| -------------------- | ----------------------------------------- | ---------- | --------------------------- |
|
|
377
|
+
| `enableSearch` | `boolean` | `true` | Show search input |
|
|
378
|
+
| `enableSorting` | `boolean` | `true` | Enable column sorting |
|
|
379
|
+
| `enableFilters` | `boolean` | `true` | Show filter controls |
|
|
380
|
+
| `enableSelection` | `boolean` | `true` | Show row checkboxes |
|
|
381
|
+
| `enableDelete` | `boolean` | `false` | Show delete button |
|
|
382
|
+
| `enableRefresh` | `boolean` | `false` | Show refresh button |
|
|
383
|
+
| `deleteConfirmation` | `boolean` | `false` | Confirm before delete |
|
|
384
|
+
| `filterMode` | `'client' \| 'server' \| 'client&server'` | `'client'` | Filter behavior (see below) |
|
|
385
|
+
|
|
386
|
+
**filterMode options:**
|
|
387
|
+
|
|
388
|
+
- `'client'` - Filters locally, no callbacks fired
|
|
389
|
+
- `'server'` - Fires callbacks only, no local filtering
|
|
390
|
+
- `'client&server'` - Filters locally AND fires callbacks
|
|
384
391
|
|
|
385
392
|
### Pagination
|
|
386
393
|
|
|
@@ -393,10 +400,10 @@ For large datasets, enable scrollable body with fixed headers:
|
|
|
393
400
|
|
|
394
401
|
| Event | Signature | Description |
|
|
395
402
|
| ----------------------- | ------------------------------------- | -------------------- |
|
|
396
|
-
| `onApplyFilter
|
|
397
|
-
| `onRemoveFilter
|
|
398
|
-
| `onClearFilters
|
|
399
|
-
| `onFilterChange
|
|
403
|
+
| `onApplyFilter`\* | `(filter, allFilters) => void` | Filter applied |
|
|
404
|
+
| `onRemoveFilter`\* | `(removed, remaining) => void` | Filter tag removed |
|
|
405
|
+
| `onClearFilters`\* | `() => void` | Clear All clicked |
|
|
406
|
+
| `onFilterChange`\* | `(filters) => void` | Any filter change |
|
|
400
407
|
| `onSearchChange` | `(term) => void` | Search input changed |
|
|
401
408
|
| `onSortChange` | `(sortConfig) => void` | Column sort changed |
|
|
402
409
|
| `onPageChange` | `(page, info) => void` | Page navigation |
|
|
@@ -410,6 +417,8 @@ For large datasets, enable scrollable body with fixed headers:
|
|
|
410
417
|
| `onCellClick` | `(value, row, column, event) => void` | Cell clicked |
|
|
411
418
|
| `onBulkDelete` | `(rows) => void` | Delete clicked |
|
|
412
419
|
|
|
420
|
+
_\* Filter callbacks only fire when `filterMode="server"` or `filterMode="client&server"`_
|
|
421
|
+
|
|
413
422
|
## Column Configuration
|
|
414
423
|
|
|
415
424
|
```tsx
|
|
@@ -482,6 +491,80 @@ test('handles filter application', async () => {
|
|
|
482
491
|
});
|
|
483
492
|
```
|
|
484
493
|
|
|
494
|
+
## ⚠️ Migration Guide
|
|
495
|
+
|
|
496
|
+
### Deprecated Props (v1.x → v2.0)
|
|
497
|
+
|
|
498
|
+
The following props are **deprecated** and will show console warnings. They will be removed in the next major version:
|
|
499
|
+
|
|
500
|
+
| Deprecated Prop | Replacement | Notes |
|
|
501
|
+
| ---------------------- | ------------------- | ----------------------------------- |
|
|
502
|
+
| `endpoint` | Use `data` prop | Fetch data in parent, pass to grid |
|
|
503
|
+
| `httpConfig` | Use `data` prop | Handle auth/headers in parent fetch |
|
|
504
|
+
| `serverPageSize` | `pageSize` | Use standard `pageSize` prop |
|
|
505
|
+
| `onDataLoad` | Use `data` prop | Handle in parent after fetch |
|
|
506
|
+
| `onDataError` | `error` prop | Pass error message as prop |
|
|
507
|
+
| `onLoadingStateChange` | `loadingState` prop | Use granular loading states |
|
|
508
|
+
|
|
509
|
+
### Before (Old API)
|
|
510
|
+
|
|
511
|
+
```tsx
|
|
512
|
+
// ❌ Deprecated approach
|
|
513
|
+
<DataGrid
|
|
514
|
+
endpoint="/api/users"
|
|
515
|
+
httpConfig={{ bearerToken: 'xxx' }}
|
|
516
|
+
serverPageSize={100}
|
|
517
|
+
onDataLoad={(res) => console.log(res)}
|
|
518
|
+
onDataError={(err) => console.error(err)}
|
|
519
|
+
/>
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### After (New API)
|
|
523
|
+
|
|
524
|
+
```tsx
|
|
525
|
+
// ✅ Recommended approach
|
|
526
|
+
function MyGrid() {
|
|
527
|
+
const [data, setData] = useState([]);
|
|
528
|
+
const [loading, setLoading] = useState(false);
|
|
529
|
+
const [error, setError] = useState(null);
|
|
530
|
+
|
|
531
|
+
const fetchData = async () => {
|
|
532
|
+
setLoading(true);
|
|
533
|
+
try {
|
|
534
|
+
const res = await fetch('/api/users', {
|
|
535
|
+
headers: { Authorization: 'Bearer xxx' },
|
|
536
|
+
});
|
|
537
|
+
setData(await res.json());
|
|
538
|
+
} catch (err) {
|
|
539
|
+
setError(err.message);
|
|
540
|
+
} finally {
|
|
541
|
+
setLoading(false);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
return <DataGrid data={data} loadingState={{ data: loading }} error={error} pageSize={25} />;
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Filter Mode Change
|
|
550
|
+
|
|
551
|
+
**Breaking:** Filter callbacks now require `filterMode` to be set:
|
|
552
|
+
|
|
553
|
+
```tsx
|
|
554
|
+
// ❌ Won't fire callbacks (filterMode defaults to 'client')
|
|
555
|
+
<DataGrid
|
|
556
|
+
data={data}
|
|
557
|
+
onApplyFilter={(f) => console.log(f)} // Never called!
|
|
558
|
+
/>
|
|
559
|
+
|
|
560
|
+
// ✅ Set filterMode to enable callbacks
|
|
561
|
+
<DataGrid
|
|
562
|
+
data={data}
|
|
563
|
+
filterMode="server" // or "both"
|
|
564
|
+
onApplyFilter={(f) => fetchWithFilter(f)}
|
|
565
|
+
/>
|
|
566
|
+
```
|
|
567
|
+
|
|
485
568
|
## 🔧 Development
|
|
486
569
|
|
|
487
570
|
```bash
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DataGridProps } from '../../types';
|
|
2
2
|
export declare const DataGrid: <T extends {
|
|
3
3
|
[key: string]: any;
|
|
4
|
-
} = any>({ data, columns: columnsProp, loading: simpleLoading, loadingState: externalLoadingState, totalRecords: externalTotalRecords, error: externalError, currentPage: externalCurrentPage, enableSearch, enableSorting, enableFilters, enableSelection, enableDelete, enableRefresh, deleteConfirmation, maxHeight, stickyHeader, pageSize, pageSizeOptions, variant, size, className, onPageChange, onPageSizeChange, onSortChange, onSearchChange, onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange, onTableRowClick, onTableRowDoubleClick, onRowSelect, onSelectionChange, onTableRowHover, onCellClick, onTableRefresh, onBulkDelete, ...rest }: DataGridProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
} = any>({ data, columns: columnsProp, loading: simpleLoading, loadingState: externalLoadingState, totalRecords: externalTotalRecords, error: externalError, currentPage: externalCurrentPage, enableSearch, enableSorting, enableFilters, enableSelection, enableDelete, enableRefresh, deleteConfirmation, filterMode, maxHeight, stickyHeader, pageSize, pageSizeOptions, variant, size, className, onPageChange, onPageSizeChange, onSortChange, onSearchChange, onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange, onTableRowClick, onTableRowDoubleClick, onRowSelect, onSelectionChange, onTableRowHover, onCellClick, onTableRefresh, onBulkDelete, endpoint, httpConfig, serverPageSize, onDataLoad, onDataError, onLoadingStateChange, ...rest }: DataGridProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
//# sourceMappingURL=DataGrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataGrid.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/DataGrid.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAwB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"DataGrid.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/DataGrid.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAwB,MAAM,aAAa,CAAC;AA0ClE,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GAAG,GAAG,EAAE,+tBAwE9D,aAAa,CAAC,CAAC,CAAC,4CA6YlB,CAAC"}
|
|
@@ -10,7 +10,7 @@ import { inferDataType } from '../../utils';
|
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Spinner Component (reusable)
|
|
12
12
|
// ============================================================================
|
|
13
|
-
const Spinner = ({ className = 'w-4 h-4' }) => (_jsxs("svg", { className:
|
|
13
|
+
const Spinner = ({ className = 'w-4 h-4' }) => (_jsxs("svg", { className: `${className}`, style: { animation: 'spin 1s linear infinite' }, xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("style", { children: `@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }` }), _jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", style: { opacity: 0.25 } }), _jsx("path", { style: { opacity: 0.75 }, fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }));
|
|
14
14
|
// ============================================================================
|
|
15
15
|
// Main Component
|
|
16
16
|
// ============================================================================
|
|
@@ -22,7 +22,7 @@ loading: simpleLoading = false, loadingState: externalLoadingState,
|
|
|
22
22
|
// External state (controlled mode)
|
|
23
23
|
totalRecords: externalTotalRecords, error: externalError, currentPage: externalCurrentPage,
|
|
24
24
|
// Features
|
|
25
|
-
enableSearch = true, enableSorting = true, enableFilters = true, enableSelection = true, enableDelete = false, enableRefresh = false, deleteConfirmation = false,
|
|
25
|
+
enableSearch = true, enableSorting = true, enableFilters = true, enableSelection = true, enableDelete = false, enableRefresh = false, deleteConfirmation = false, filterMode = 'client',
|
|
26
26
|
// Layout
|
|
27
27
|
maxHeight, stickyHeader = false,
|
|
28
28
|
// Pagination
|
|
@@ -38,8 +38,43 @@ onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange,
|
|
|
38
38
|
// Row & Cell Events
|
|
39
39
|
onTableRowClick, onTableRowDoubleClick, onRowSelect, onSelectionChange, onTableRowHover, onCellClick,
|
|
40
40
|
// Action Events
|
|
41
|
-
onTableRefresh, onBulkDelete,
|
|
41
|
+
onTableRefresh, onBulkDelete,
|
|
42
|
+
// DEPRECATED Props (kept for backward compatibility)
|
|
43
|
+
endpoint, httpConfig, serverPageSize, onDataLoad, onDataError, onLoadingStateChange, ...rest }) => {
|
|
42
44
|
const theme = getTheme(variant);
|
|
45
|
+
// ===== Deprecation Warnings =====
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
48
|
+
if (endpoint) {
|
|
49
|
+
console.warn('[@reactorui/datagrid] `endpoint` prop is deprecated and will be removed in the next major version. ' +
|
|
50
|
+
'Use controlled mode instead: fetch data in your parent component and pass via `data` prop. ' +
|
|
51
|
+
'See migration guide: https://github.com/reactorui/datagrid#migration');
|
|
52
|
+
}
|
|
53
|
+
if (httpConfig) {
|
|
54
|
+
console.warn('[@reactorui/datagrid] `httpConfig` prop is deprecated and will be removed in the next major version. ' +
|
|
55
|
+
'Use controlled mode instead.');
|
|
56
|
+
}
|
|
57
|
+
if (serverPageSize) {
|
|
58
|
+
console.warn('[@reactorui/datagrid] `serverPageSize` prop is deprecated. Use `pageSize` prop instead.');
|
|
59
|
+
}
|
|
60
|
+
if (onDataLoad) {
|
|
61
|
+
console.warn('[@reactorui/datagrid] `onDataLoad` callback is deprecated and will be removed in the next major version. ' +
|
|
62
|
+
'Handle data loading in your parent component.');
|
|
63
|
+
}
|
|
64
|
+
if (onDataError) {
|
|
65
|
+
console.warn('[@reactorui/datagrid] `onDataError` callback is deprecated. Use the `error` prop instead.');
|
|
66
|
+
}
|
|
67
|
+
if (onLoadingStateChange) {
|
|
68
|
+
console.warn('[@reactorui/datagrid] `onLoadingStateChange` callback is deprecated. Use the `loadingState` prop instead.');
|
|
69
|
+
}
|
|
70
|
+
// Warn if filter callbacks provided but filterMode is 'client'
|
|
71
|
+
if (filterMode === 'client' && (onApplyFilter || onRemoveFilter || onClearFilters)) {
|
|
72
|
+
console.warn('[@reactorui/datagrid] Filter callbacks (onApplyFilter, onRemoveFilter, onClearFilters) are provided but ' +
|
|
73
|
+
'`filterMode` is "client" (default). These callbacks will NOT be fired. ' +
|
|
74
|
+
'Set `filterMode="server"` or `filterMode="both"` to enable filter callbacks.');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, []); // Run once on mount
|
|
43
78
|
// ===== Normalize Loading State =====
|
|
44
79
|
// If simple `loading` is passed, convert to loadingState.data
|
|
45
80
|
// If loadingState is passed, use it directly
|
|
@@ -65,6 +100,7 @@ onTableRefresh, onBulkDelete, ...rest }) => {
|
|
|
65
100
|
totalRecords: externalTotalRecords,
|
|
66
101
|
currentPage: externalCurrentPage,
|
|
67
102
|
loading: isDataLoading,
|
|
103
|
+
filterMode,
|
|
68
104
|
onPageChange,
|
|
69
105
|
onPageSizeChange,
|
|
70
106
|
onSortChange,
|
|
@@ -143,7 +179,7 @@ onTableRefresh, onBulkDelete, ...rest }) => {
|
|
|
143
179
|
}
|
|
144
180
|
return (_jsxs("div", { className: `${theme.container} ${className} ${hasFixedLayout ? 'flex flex-col' : ''}`, style: hasFixedLayout && maxHeight
|
|
145
181
|
? { maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight }
|
|
146
|
-
: undefined, ...rest, children: [
|
|
182
|
+
: undefined, ...rest, children: [_jsx("div", { className: "px-4 py-4 flex-shrink-0", children: _jsxs("div", { className: "flex justify-between items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: "Show" }), _jsx("select", { value: currentPageSize, onChange: (e) => setCurrentPageSize(parseInt(e.target.value)), disabled: isAnyLoading, className: "px-2 py-1 border border-gray-300 dark:border-gray-600 rounded text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:opacity-50", children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) }), _jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: "entries" }), enableFilters && (_jsx(FilterControls, { columns: columns, activeFilters: activeFilters, onApplyFilter: addFilter, onRemoveFilter: removeFilter, onClearFilters: clearFilters, disabled: isDataLoading, filterLoading: isFilterLoading }))] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [enableSearch && (_jsxs("div", { className: "w-64 relative", children: [_jsx(SearchInput, { value: searchTerm, onChange: setSearchTerm, placeholder: "Search...", disabled: isAnyLoading, className: theme.searchInput }), isSearchLoading && (_jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2", children: _jsx(Spinner, { className: "w-4 h-4 text-gray-400" }) }))] })), enableRefresh && (_jsx("button", { onClick: handleRefresh, disabled: isAnyLoading, title: isRefreshLoading ? 'Refreshing...' : 'Refresh data', className: "px-3 py-2 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 transition-colors duration-150 flex items-center justify-center", children: _jsx("svg", { className: "w-4 h-4", style: isRefreshLoading ? { animation: 'spin 1s linear infinite' } : undefined, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }) })), enableDelete && enableSelection && (_jsxs("button", { onClick: handleDelete, disabled: selectedRows.size === 0 || isAnyLoading, title: selectedRows.size === 0
|
|
147
183
|
? 'Select rows to delete'
|
|
148
184
|
: isDeleteLoading
|
|
149
185
|
? 'Deleting...'
|
|
@@ -5,9 +5,7 @@ interface FilterControlsProps<T> {
|
|
|
5
5
|
onApplyFilter: (filter: Omit<ActiveFilter, 'label'>) => void;
|
|
6
6
|
onRemoveFilter: (index: number) => void;
|
|
7
7
|
onClearFilters: () => void;
|
|
8
|
-
/** Disables all controls (e.g., when data is loading) */
|
|
9
8
|
disabled?: boolean;
|
|
10
|
-
/** Shows spinner specifically on Apply Filter button */
|
|
11
9
|
filterLoading?: boolean;
|
|
12
10
|
}
|
|
13
11
|
export declare const FilterControls: <T>({ columns, activeFilters, onApplyFilter, onRemoveFilter, onClearFilters, disabled, filterLoading, }: FilterControlsProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterControls.d.ts","sourceRoot":"","sources":["../../../src/components/Filter/FilterControls.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AAMnE,UAAU,mBAAmB,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,
|
|
1
|
+
{"version":3,"file":"FilterControls.d.ts","sourceRoot":"","sources":["../../../src/components/Filter/FilterControls.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AAMnE,UAAU,mBAAmB,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA6FD,eAAO,MAAM,cAAc,GAAI,CAAC,EAAG,qGAQhC,mBAAmB,CAAC,CAAC,CAAC,4CA2RxB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// File: src/components/Filter/FilterControls.tsx
|
|
3
|
-
import { useState, useCallback, useMemo } from 'react';
|
|
3
|
+
import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
|
|
4
4
|
// ============================================================================
|
|
5
5
|
// Operator Configuration
|
|
6
6
|
// ============================================================================
|
|
@@ -38,32 +38,60 @@ const OPERATORS = {
|
|
|
38
38
|
};
|
|
39
39
|
const DEFAULT_OPERATORS = [{ value: 'eq', label: 'equals' }];
|
|
40
40
|
// ============================================================================
|
|
41
|
-
//
|
|
42
|
-
// ============================================================================
|
|
43
|
-
const Spinner = ({ className = 'w-4 h-4' }) => (_jsxs("svg", { className: `animate-spin ${className}`, xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }));
|
|
44
|
-
// ============================================================================
|
|
45
|
-
// Styles (centralized for DRY)
|
|
41
|
+
// Styles
|
|
46
42
|
// ============================================================================
|
|
47
43
|
const styles = {
|
|
48
44
|
select: 'w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:bg-gray-50 dark:disabled:bg-gray-700 disabled:text-gray-500 dark:disabled:text-gray-400 disabled:cursor-not-allowed',
|
|
49
|
-
input: 'px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:bg-gray-50 dark:disabled:bg-gray-700 disabled:cursor-not-allowed',
|
|
50
|
-
inputDisabled: 'px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-gray-50 dark:bg-gray-700 text-gray-500 dark:text-gray-400 cursor-not-allowed',
|
|
51
|
-
buttonPrimary: 'px-4 py-2 bg-blue-600 dark:bg-blue-700 text-white text-sm rounded-md hover:bg-blue-700 dark:hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:bg-gray-300 dark:disabled:bg-gray-600 disabled:text-gray-500 dark:disabled:text-gray-400 disabled:cursor-not-allowed transition-colors duration-150
|
|
52
|
-
buttonSecondary: 'px-4 py-2 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 text-sm rounded-md hover:bg-gray-200 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 dark:focus:ring-gray-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150',
|
|
53
|
-
filterTag: '
|
|
54
|
-
filterTagRemove: '
|
|
45
|
+
input: 'w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:bg-gray-50 dark:disabled:bg-gray-700 disabled:cursor-not-allowed',
|
|
46
|
+
inputDisabled: 'w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-gray-50 dark:bg-gray-700 text-gray-500 dark:text-gray-400 cursor-not-allowed',
|
|
47
|
+
buttonPrimary: 'w-full px-4 py-2 bg-blue-600 dark:bg-blue-700 text-white text-sm rounded-md hover:bg-blue-700 dark:hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:bg-gray-300 dark:disabled:bg-gray-600 disabled:text-gray-500 dark:disabled:text-gray-400 disabled:cursor-not-allowed transition-colors duration-150',
|
|
48
|
+
buttonSecondary: 'w-full px-4 py-2 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 text-sm rounded-md hover:bg-gray-200 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 dark:focus:ring-gray-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150',
|
|
49
|
+
filterTag: 'flex items-center justify-between gap-2 px-3 py-2 bg-blue-50 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 rounded-md text-sm',
|
|
50
|
+
filterTagRemove: 'text-blue-600 dark:text-blue-300 hover:text-blue-800 dark:hover:text-blue-100 focus:outline-none transition-colors duration-150',
|
|
55
51
|
label: 'block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1',
|
|
56
52
|
};
|
|
57
53
|
// ============================================================================
|
|
54
|
+
// Filter Icon
|
|
55
|
+
// ============================================================================
|
|
56
|
+
const FilterIcon = ({ className = 'w-4 h-4' }) => (_jsx("svg", { className: className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" }) }));
|
|
57
|
+
// ============================================================================
|
|
58
58
|
// Component
|
|
59
59
|
// ============================================================================
|
|
60
60
|
export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemoveFilter, onClearFilters, disabled = false, filterLoading = false, }) => {
|
|
61
|
-
|
|
61
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
62
62
|
const [filterColumn, setFilterColumn] = useState('');
|
|
63
63
|
const [filterOperator, setFilterOperator] = useState('eq');
|
|
64
64
|
const [filterValue, setFilterValue] = useState('');
|
|
65
|
-
|
|
65
|
+
const popoverRef = useRef(null);
|
|
66
|
+
const buttonRef = useRef(null);
|
|
66
67
|
const isDisabled = disabled || filterLoading;
|
|
68
|
+
const filterCount = activeFilters.length;
|
|
69
|
+
// Close on outside click
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const handleClickOutside = (event) => {
|
|
72
|
+
if (popoverRef.current &&
|
|
73
|
+
buttonRef.current &&
|
|
74
|
+
!popoverRef.current.contains(event.target) &&
|
|
75
|
+
!buttonRef.current.contains(event.target)) {
|
|
76
|
+
setIsOpen(false);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
if (isOpen) {
|
|
80
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
81
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
82
|
+
}
|
|
83
|
+
}, [isOpen]);
|
|
84
|
+
// Close on Escape
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const handleEscape = (event) => {
|
|
87
|
+
if (event.key === 'Escape')
|
|
88
|
+
setIsOpen(false);
|
|
89
|
+
};
|
|
90
|
+
if (isOpen) {
|
|
91
|
+
document.addEventListener('keydown', handleEscape);
|
|
92
|
+
return () => document.removeEventListener('keydown', handleEscape);
|
|
93
|
+
}
|
|
94
|
+
}, [isOpen]);
|
|
67
95
|
// Derived state
|
|
68
96
|
const filterableColumns = useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);
|
|
69
97
|
const selectedColumn = useMemo(() => filterableColumns.find((col) => col.key === filterColumn), [filterableColumns, filterColumn]);
|
|
@@ -84,6 +112,11 @@ export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemove
|
|
|
84
112
|
value: filterValue.trim(),
|
|
85
113
|
dataType: selectedColumn.dataType ?? 'string',
|
|
86
114
|
});
|
|
115
|
+
// Reset form and close popover
|
|
116
|
+
setFilterColumn('');
|
|
117
|
+
setFilterOperator('eq');
|
|
118
|
+
setFilterValue('');
|
|
119
|
+
setIsOpen(false);
|
|
87
120
|
}, [
|
|
88
121
|
canApply,
|
|
89
122
|
filterColumn,
|
|
@@ -129,5 +162,7 @@ export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemove
|
|
|
129
162
|
return _jsx("input", { ...commonProps, type: "text", placeholder: "Enter value" });
|
|
130
163
|
}
|
|
131
164
|
};
|
|
132
|
-
return (_jsxs("div", { className: "
|
|
165
|
+
return (_jsxs("div", { className: "relative inline-block", children: [_jsxs("button", { ref: buttonRef, onClick: () => setIsOpen(!isOpen), disabled: isDisabled, title: filterCount > 0
|
|
166
|
+
? `${filterCount} filter${filterCount === 1 ? '' : 's'} active`
|
|
167
|
+
: 'Add filter', className: "relative p-2 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", children: [_jsx(FilterIcon, { className: "w-5 h-5" }), filterCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 min-w-[18px] h-[18px] flex items-center justify-center px-1 text-xs font-medium text-white bg-blue-600 dark:bg-blue-500 rounded-full", children: filterCount }))] }), isOpen && (_jsx("div", { ref: popoverRef, className: "absolute top-full left-0 mt-2 w-72 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 z-50", children: _jsxs("div", { className: "p-4 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h3", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Filter" }), _jsx("button", { onClick: () => setIsOpen(false), className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsxs("div", { children: [_jsx("label", { className: styles.label, children: "Column" }), _jsxs("select", { value: filterColumn, onChange: (e) => handleColumnChange(e.target.value), disabled: isDisabled, className: styles.select, children: [_jsx("option", { value: "", children: "Select column" }), filterableColumns.map((col) => (_jsx("option", { value: String(col.key), children: col.label }, String(col.key))))] })] }), _jsxs("div", { children: [_jsx("label", { className: styles.label, children: "Operator" }), _jsx("select", { value: filterOperator, onChange: (e) => setFilterOperator(e.target.value), disabled: isDisabled || !filterColumn, className: styles.select, children: operatorOptions.map((op) => (_jsx("option", { value: op.value, children: op.label }, op.value))) })] }), _jsxs("div", { children: [_jsx("label", { className: styles.label, children: "Value" }), renderValueInput()] }), _jsx("button", { onClick: handleApply, disabled: isDisabled || !canApply, className: styles.buttonPrimary, children: "Apply Filter" }), activeFilters.length > 0 && (_jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4 space-y-2", children: [_jsx("div", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide", children: "Active Filters" }), _jsx("div", { className: "space-y-2 max-h-32 overflow-y-auto", children: activeFilters.map((filter, index) => (_jsxs("div", { className: styles.filterTag, children: [_jsx("span", { className: "truncate", children: filter.label }), _jsx("button", { onClick: () => onRemoveFilter(index), disabled: isDisabled, className: styles.filterTagRemove, "aria-label": `Remove filter: ${filter.label}`, children: "\u00D7" })] }, `${filter.column}-${index}`))) }), _jsx("button", { onClick: handleClear, disabled: isDisabled, className: styles.buttonSecondary, children: "Clear All" })] }))] }) }))] }));
|
|
133
168
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableBody.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7D,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC9D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvF,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,+JActD,cAAc,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"TableBody.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7D,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC9D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvF,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,+JActD,cAAc,CAAC,CAAC,CAAC,4CAwKnB,CAAC"}
|
|
@@ -50,7 +50,7 @@ export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
if (loading) {
|
|
53
|
-
return (_jsx("tbody", { className: "bg-white dark:bg-gray-800", children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: "px-4 py-12 text-center text-gray-500 dark:text-gray-400", children: _jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsxs("svg", { className: "
|
|
53
|
+
return (_jsx("tbody", { className: "bg-white dark:bg-gray-800", children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: "px-4 py-12 text-center text-gray-500 dark:text-gray-400", children: _jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsxs("svg", { className: "h-5 w-5 text-blue-600 dark:text-blue-400", style: { animation: 'spin 1s linear infinite' }, xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("style", { children: `@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }` }), _jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", style: { opacity: 0.25 } }), _jsx("path", { style: { opacity: 0.75 }, fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), _jsx("span", { children: "Loading..." })] }) }) }) }));
|
|
54
54
|
}
|
|
55
55
|
if (data.length === 0) {
|
|
56
56
|
return (_jsx("tbody", { className: "bg-white dark:bg-gray-800", children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: "px-4 py-8 text-center text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800", children: emptyMessage }) }) }));
|
|
@@ -5,6 +5,13 @@ interface UseDataGridProps<T> {
|
|
|
5
5
|
totalRecords?: number;
|
|
6
6
|
currentPage?: number;
|
|
7
7
|
loading?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Filter behavior mode:
|
|
10
|
+
* - 'client' (default): Filters locally, no onApplyFilter callback
|
|
11
|
+
* - 'server': No local filtering, only fires onApplyFilter
|
|
12
|
+
* - 'client&server': Filters locally AND fires onApplyFilter
|
|
13
|
+
*/
|
|
14
|
+
filterMode?: 'client' | 'server' | 'client&server';
|
|
8
15
|
onPageChange?: (page: number, info: PaginationInfo) => void;
|
|
9
16
|
onPageSizeChange?: (size: number) => void;
|
|
10
17
|
onSortChange?: (config: SortConfig) => void;
|
|
@@ -14,7 +21,7 @@ interface UseDataGridProps<T> {
|
|
|
14
21
|
onClearFilters?: () => void;
|
|
15
22
|
onFilterChange?: (filters: ActiveFilter[]) => void;
|
|
16
23
|
}
|
|
17
|
-
export declare const useDataGrid: <T extends BaseRowData>({ data, pageSize: initialPageSize, totalRecords: externalTotalRecords, currentPage: externalCurrentPage, loading: externalLoading, onPageChange, onPageSizeChange, onSortChange, onSearchChange, onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange, }: UseDataGridProps<T>) => {
|
|
24
|
+
export declare const useDataGrid: <T extends BaseRowData>({ data, pageSize: initialPageSize, totalRecords: externalTotalRecords, currentPage: externalCurrentPage, loading: externalLoading, filterMode, onPageChange, onPageSizeChange, onSortChange, onSearchChange, onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange, }: UseDataGridProps<T>) => {
|
|
18
25
|
data: T[];
|
|
19
26
|
processedData: T[];
|
|
20
27
|
paginatedData: T[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDataGrid.d.ts","sourceRoot":"","sources":["../../src/hooks/useDataGrid.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAOjF,UAAU,gBAAgB,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useDataGrid.d.ts","sourceRoot":"","sources":["../../src/hooks/useDataGrid.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAOjF,UAAU,gBAAgB,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,eAAe,CAAC;IAGnD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC5D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACpE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAC5E,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;CACpD;AAMD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,WAAW,EAAE,+QAehD,gBAAgB,CAAC,CAAC,CAAC;;;;;;;;;;;0BA2GX,MAAM;sBASJ,MAAM;2BAaR,MAAM;+BAQN,MAAM;;;wBAsBJ,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;0BAoB5B,MAAM;;uBA4BsB,MAAM,YAAY,OAAO;0BASlD,OAAO;;;;;;oBA1LZ,CAAC,KAAG,MAAM;;CA0PnB,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { compareValues, sortData } from '../utils';
|
|
|
4
4
|
// ============================================================================
|
|
5
5
|
// Hook Implementation
|
|
6
6
|
// ============================================================================
|
|
7
|
-
export const useDataGrid = ({ data, pageSize: initialPageSize = 10, totalRecords: externalTotalRecords, currentPage: externalCurrentPage, loading: externalLoading = false, onPageChange, onPageSizeChange, onSortChange, onSearchChange, onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange, }) => {
|
|
7
|
+
export const useDataGrid = ({ data, pageSize: initialPageSize = 10, totalRecords: externalTotalRecords, currentPage: externalCurrentPage, loading: externalLoading = false, filterMode = 'client', onPageChange, onPageSizeChange, onSortChange, onSearchChange, onApplyFilter, onRemoveFilter, onClearFilters, onFilterChange, }) => {
|
|
8
8
|
// ===== Internal State =====
|
|
9
9
|
const [searchTerm, setSearchTermState] = useState('');
|
|
10
10
|
const [activeFilters, setActiveFilters] = useState([]);
|
|
@@ -34,29 +34,33 @@ export const useDataGrid = ({ data, pageSize: initialPageSize = 10, totalRecords
|
|
|
34
34
|
}, [rowIdMap]);
|
|
35
35
|
// ===== Data Processing (Client-side only) =====
|
|
36
36
|
const processedData = useMemo(() => {
|
|
37
|
-
if
|
|
38
|
-
|
|
37
|
+
// Determine if we should filter locally
|
|
38
|
+
const shouldFilterLocally = filterMode === 'client' || filterMode === 'client&server';
|
|
39
|
+
if (isControlled && filterMode === 'server') {
|
|
40
|
+
// Server mode with controlled data - parent handles everything, just sort
|
|
39
41
|
return sortConfig.column ? sortData(data, sortConfig.column, sortConfig.direction) : data;
|
|
40
42
|
}
|
|
41
43
|
let result = [...data];
|
|
42
|
-
// Search
|
|
44
|
+
// Search (always client-side for now)
|
|
43
45
|
if (searchTerm) {
|
|
44
46
|
const term = searchTerm.toLowerCase();
|
|
45
47
|
result = result.filter((row) => Object.values(row).some((value) => value?.toString().toLowerCase().includes(term)));
|
|
46
48
|
}
|
|
47
|
-
// Filters
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
// Filters - only apply locally if filterMode allows
|
|
50
|
+
if (shouldFilterLocally) {
|
|
51
|
+
activeFilters.forEach((filter) => {
|
|
52
|
+
result = result.filter((row) => {
|
|
53
|
+
const value = row[filter.column];
|
|
54
|
+
return compareValues(value, filter.value, filter.operator, filter.dataType);
|
|
55
|
+
});
|
|
52
56
|
});
|
|
53
|
-
}
|
|
57
|
+
}
|
|
54
58
|
// Sort
|
|
55
59
|
if (sortConfig.column) {
|
|
56
60
|
result = sortData(result, sortConfig.column, sortConfig.direction);
|
|
57
61
|
}
|
|
58
62
|
return result;
|
|
59
|
-
}, [data, searchTerm, activeFilters, sortConfig, isControlled]);
|
|
63
|
+
}, [data, searchTerm, activeFilters, sortConfig, isControlled, filterMode]);
|
|
60
64
|
// ===== Pagination =====
|
|
61
65
|
const paginatedData = useMemo(() => {
|
|
62
66
|
if (isControlled)
|
|
@@ -131,29 +135,35 @@ export const useDataGrid = ({ data, pageSize: initialPageSize = 10, totalRecords
|
|
|
131
135
|
setActiveFilters(newFilters);
|
|
132
136
|
if (!isControlled)
|
|
133
137
|
setInternalPage(1);
|
|
134
|
-
// Fire callbacks
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
// Fire callbacks only for 'server' or 'client&server' modes
|
|
139
|
+
if (filterMode !== 'client') {
|
|
140
|
+
onApplyFilter?.(fullFilter, newFilters);
|
|
141
|
+
onFilterChange?.(newFilters);
|
|
142
|
+
}
|
|
143
|
+
}, [activeFilters, isControlled, filterMode, onApplyFilter, onFilterChange]);
|
|
138
144
|
const removeFilter = useCallback((index) => {
|
|
139
145
|
const removed = activeFilters[index];
|
|
140
146
|
const newFilters = activeFilters.filter((_, i) => i !== index);
|
|
141
147
|
setActiveFilters(newFilters);
|
|
142
148
|
if (!isControlled)
|
|
143
149
|
setInternalPage(1);
|
|
144
|
-
// Fire callbacks
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
// Fire callbacks only for 'server' or 'client&server' modes
|
|
151
|
+
if (filterMode !== 'client') {
|
|
152
|
+
if (removed)
|
|
153
|
+
onRemoveFilter?.(removed, newFilters);
|
|
154
|
+
onFilterChange?.(newFilters);
|
|
155
|
+
}
|
|
156
|
+
}, [activeFilters, isControlled, filterMode, onRemoveFilter, onFilterChange]);
|
|
149
157
|
const clearFilters = useCallback(() => {
|
|
150
158
|
setActiveFilters([]);
|
|
151
159
|
if (!isControlled)
|
|
152
160
|
setInternalPage(1);
|
|
153
|
-
// Fire callbacks
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
// Fire callbacks only for 'server' or 'client&server' modes
|
|
162
|
+
if (filterMode !== 'client') {
|
|
163
|
+
onClearFilters?.();
|
|
164
|
+
onFilterChange?.([]);
|
|
165
|
+
}
|
|
166
|
+
}, [isControlled, filterMode, onClearFilters, onFilterChange]);
|
|
157
167
|
// ===== Selection Actions =====
|
|
158
168
|
const selectRow = useCallback((rowId, selected) => {
|
|
159
169
|
setSelectedRows((prev) => {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -49,6 +49,48 @@ export interface LoadingState {
|
|
|
49
49
|
/** Delete operation is in progress */
|
|
50
50
|
delete?: boolean;
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Use controlled mode instead. Pass data directly and handle fetching in parent.
|
|
54
|
+
*/
|
|
55
|
+
export interface HttpConfig {
|
|
56
|
+
bearerToken?: string;
|
|
57
|
+
apiKey?: string;
|
|
58
|
+
customHeaders?: Record<string, string>;
|
|
59
|
+
method?: 'GET' | 'POST';
|
|
60
|
+
postDataFormat?: 'json' | 'formdata';
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @deprecated Use controlled mode instead.
|
|
64
|
+
*/
|
|
65
|
+
export interface ServerRequest {
|
|
66
|
+
page: number;
|
|
67
|
+
pageSize: number;
|
|
68
|
+
sortColumn?: string;
|
|
69
|
+
sortDirection?: 'asc' | 'desc';
|
|
70
|
+
searchTerm?: string;
|
|
71
|
+
filters?: ActiveFilter[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* @deprecated Use controlled mode instead.
|
|
75
|
+
*/
|
|
76
|
+
export interface ServerResponse<T = BaseRowData> {
|
|
77
|
+
items: T[];
|
|
78
|
+
totalRecords: number;
|
|
79
|
+
page?: number;
|
|
80
|
+
pageSize?: number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated Use controlled mode instead.
|
|
84
|
+
*/
|
|
85
|
+
export type OnDataLoadCallback<T = BaseRowData> = (response: ServerResponse<T>) => void;
|
|
86
|
+
/**
|
|
87
|
+
* @deprecated Use controlled mode instead.
|
|
88
|
+
*/
|
|
89
|
+
export type OnDataErrorCallback = (error: Error, context: string) => void;
|
|
90
|
+
/**
|
|
91
|
+
* @deprecated Use loadingState prop instead.
|
|
92
|
+
*/
|
|
93
|
+
export type OnLoadingStateChangeCallback = (loading: boolean, context: string) => void;
|
|
52
94
|
export type OnPageChangeCallback = (page: number, paginationInfo: PaginationInfo) => void;
|
|
53
95
|
export type OnPageSizeChangeCallback = (pageSize: number) => void;
|
|
54
96
|
export type OnSortChangeCallback = (sortConfig: SortConfig) => void;
|
|
@@ -96,6 +138,13 @@ export interface DataGridProps<T = BaseRowData> extends Omit<HTMLAttributes<HTML
|
|
|
96
138
|
enableDelete?: boolean;
|
|
97
139
|
enableRefresh?: boolean;
|
|
98
140
|
deleteConfirmation?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Filter behavior mode:
|
|
143
|
+
* - 'client' (default): Filters data locally, no onApplyFilter callback fired
|
|
144
|
+
* - 'server': Fires onApplyFilter callback only, no local filtering
|
|
145
|
+
* - 'client&server': Filters locally AND fires callback
|
|
146
|
+
*/
|
|
147
|
+
filterMode?: 'client' | 'server' | 'client&server';
|
|
99
148
|
pageSize?: number;
|
|
100
149
|
pageSizeOptions?: number[];
|
|
101
150
|
/** Current page (controlled mode for server-side) */
|
|
@@ -133,6 +182,36 @@ export interface DataGridProps<T = BaseRowData> extends Omit<HTMLAttributes<HTML
|
|
|
133
182
|
onCellClick?: OnCellClickCallback<T>;
|
|
134
183
|
onTableRefresh?: OnTableRefreshCallback;
|
|
135
184
|
onBulkDelete?: OnBulkDeleteCallback<T>;
|
|
185
|
+
/**
|
|
186
|
+
* @deprecated Use controlled mode instead. Fetch data in parent and pass via `data` prop.
|
|
187
|
+
* Will be removed in next major version.
|
|
188
|
+
*/
|
|
189
|
+
endpoint?: string;
|
|
190
|
+
/**
|
|
191
|
+
* @deprecated Use controlled mode instead.
|
|
192
|
+
* Will be removed in next major version.
|
|
193
|
+
*/
|
|
194
|
+
httpConfig?: HttpConfig;
|
|
195
|
+
/**
|
|
196
|
+
* @deprecated Use `pageSize` prop instead.
|
|
197
|
+
* Will be removed in next major version.
|
|
198
|
+
*/
|
|
199
|
+
serverPageSize?: number;
|
|
200
|
+
/**
|
|
201
|
+
* @deprecated Use controlled mode. Handle data loading in parent component.
|
|
202
|
+
* Will be removed in next major version.
|
|
203
|
+
*/
|
|
204
|
+
onDataLoad?: OnDataLoadCallback<T>;
|
|
205
|
+
/**
|
|
206
|
+
* @deprecated Use `error` prop instead.
|
|
207
|
+
* Will be removed in next major version.
|
|
208
|
+
*/
|
|
209
|
+
onDataError?: OnDataErrorCallback;
|
|
210
|
+
/**
|
|
211
|
+
* @deprecated Use `loadingState` prop instead.
|
|
212
|
+
* Will be removed in next major version.
|
|
213
|
+
*/
|
|
214
|
+
onLoadingStateChange?: OnLoadingStateChangeCallback;
|
|
136
215
|
}
|
|
137
216
|
/** Request object that parent can use to build API calls */
|
|
138
217
|
export interface DataGridRequest {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAMlD,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,MAAM,CAAC,CAAC,GAAG,WAAW;IACrC,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;CAC3D;AAMD,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,KAAK,GACL,UAAU,GACV,YAAY,GACZ,UAAU,GACV,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,CAAC;AAEV,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC;IAClC,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAMD,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8BAA8B;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactorui/datagrid",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.24",
|
|
4
|
+
"description": "A flexible, high-performance React data grid component with TypeScript support, advanced filtering, pagination, sorting, and customizable theming",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|