@reactorui/datagrid 1.1.1 → 1.2.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/README.md CHANGED
@@ -22,8 +22,8 @@ A high-performance, feature-rich React data grid component with TypeScript suppo
22
22
  - 🔍 **Advanced Filtering** - Type-aware filters with multiple operators (string, number, date, boolean)
23
23
  - 🔄 **Flexible Data Sources** - Works with any data fetching strategy (REST, GraphQL, local)
24
24
  - 📱 **Responsive Design** - Mobile-first with touch-friendly interactions
25
- - 🎨 **Customizable Theming** - Multiple built-in variants and custom styling
26
- - 🌙 **Dark Mode Ready** - Built-in dark mode support
25
+ - 🎨 **Fully Customizable Theming** - Pass custom theme objects to match your design system
26
+ - 🌙 **Dark Mode Ready** - Built-in dark mode support with zinc palette option
27
27
  - ♿ **Accessibility First** - WCAG compliant with keyboard navigation and ARIA labels
28
28
  - 🔧 **TypeScript Native** - Full type safety and comprehensive IntelliSense support
29
29
  - 🎯 **Rich Event System** - 20+ events covering every user interaction
@@ -120,6 +120,149 @@ function App() {
120
120
  }
121
121
  ```
122
122
 
123
+ ## 🎨 Custom Theming
124
+
125
+ The DataGrid supports full theme customization via the `theme` prop. You can override any part of the default theme to match your design system.
126
+
127
+ ### Theme Interface
128
+
129
+ ```tsx
130
+ interface Theme {
131
+ // Container
132
+ container: string;
133
+
134
+ // Table
135
+ table: string;
136
+ header: string;
137
+ headerCell: string;
138
+ row: string;
139
+ cell: string;
140
+ selectedRow: string;
141
+
142
+ // Controls
143
+ searchInput: string;
144
+ select: string;
145
+ button: string;
146
+ buttonSecondary: string;
147
+ buttonDanger: string;
148
+
149
+ // Text
150
+ text: string;
151
+ textMuted: string;
152
+ textError: string;
153
+
154
+ // Pagination
155
+ pagination: string;
156
+ paginationButton: string;
157
+ paginationText: string;
158
+
159
+ // States
160
+ loadingSkeleton: string;
161
+ emptyState: string;
162
+ errorState: string;
163
+
164
+ // Filter
165
+ filterDropdown: string;
166
+ filterTag: string;
167
+ filterTagRemove: string;
168
+ }
169
+ ```
170
+
171
+ ### Custom Theme Example
172
+
173
+ ```tsx
174
+ import { DataGrid, Theme } from '@reactorui/datagrid';
175
+
176
+ // Define your custom theme (partial overrides supported)
177
+ const myTheme: Partial<Theme> = {
178
+ container: 'bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-700',
179
+ row: 'bg-white dark:bg-zinc-900 hover:bg-zinc-50 dark:hover:bg-zinc-800',
180
+ cell: 'px-4 py-3 text-sm text-gray-900 dark:text-zinc-100 border-b dark:border-zinc-700',
181
+ searchInput:
182
+ 'px-3 py-2 border dark:border-zinc-700 rounded-lg dark:bg-zinc-800 dark:text-zinc-100',
183
+ pagination:
184
+ 'flex items-center justify-between px-4 py-3 dark:bg-zinc-900 border-t dark:border-zinc-700',
185
+ };
186
+
187
+ function App() {
188
+ return <DataGrid data={data} theme={myTheme} />;
189
+ }
190
+ ```
191
+
192
+ ### Using createZincTheme Helper
193
+
194
+ For projects using the `zinc` color palette (like Tailwind's neutral grays), use the built-in helper:
195
+
196
+ ```tsx
197
+ import { DataGrid, createZincTheme } from '@reactorui/datagrid';
198
+
199
+ // Creates a complete theme with zinc palette for dark mode
200
+ const zincTheme = createZincTheme('default'); // or 'striped' or 'bordered'
201
+
202
+ function App() {
203
+ return <DataGrid data={data} theme={zincTheme} />;
204
+ }
205
+ ```
206
+
207
+ ### Theme + Variant
208
+
209
+ Custom themes merge with the selected variant:
210
+
211
+ ```tsx
212
+ // Striped variant + custom zinc dark mode
213
+ <DataGrid
214
+ data={data}
215
+ variant="striped"
216
+ theme={{
217
+ container: 'bg-white dark:bg-zinc-900 rounded-xl',
218
+ row: 'odd:bg-white dark:odd:bg-zinc-900 even:bg-zinc-50 dark:even:bg-zinc-800/50',
219
+ }}
220
+ />
221
+ ```
222
+
223
+ ### Integration with Design Systems
224
+
225
+ Example integrating with a custom ThemeStyles system:
226
+
227
+ ```tsx
228
+ // utils/dataGridTheme.ts
229
+ import { Theme } from '@reactorui/datagrid';
230
+
231
+ export const appDataGridTheme: Partial<Theme> = {
232
+ container:
233
+ 'bg-white dark:bg-zinc-900 rounded-lg shadow-sm border border-gray-200 dark:border-zinc-700',
234
+ table: 'w-full bg-white dark:bg-zinc-900',
235
+ header: 'bg-gray-50 dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700',
236
+ headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-zinc-400 uppercase',
237
+ row: 'bg-white dark:bg-zinc-900 hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors',
238
+ cell: 'px-4 py-3 text-sm text-gray-900 dark:text-zinc-100 border-b dark:border-zinc-700',
239
+ selectedRow: 'bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30',
240
+ searchInput:
241
+ 'px-3 py-2 border dark:border-zinc-700 rounded-md dark:bg-zinc-800 dark:text-zinc-100',
242
+ select: 'px-2 py-1 border dark:border-zinc-700 rounded dark:bg-zinc-800 dark:text-zinc-100',
243
+ button: 'px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700',
244
+ buttonSecondary:
245
+ 'px-3 py-2 bg-gray-100 dark:bg-zinc-800 text-gray-700 dark:text-zinc-300 rounded-md',
246
+ text: 'text-gray-700 dark:text-zinc-300',
247
+ textMuted: 'text-gray-500 dark:text-zinc-500',
248
+ textError: 'text-red-600 dark:text-red-400',
249
+ pagination:
250
+ 'flex items-center justify-between px-4 py-3 dark:bg-zinc-900 border-t dark:border-zinc-700',
251
+ paginationButton: 'px-3 py-1 text-sm border dark:border-zinc-700 rounded dark:bg-zinc-800',
252
+ paginationText: 'text-sm text-gray-700 dark:text-zinc-300',
253
+ emptyState: 'text-gray-500 dark:text-zinc-400',
254
+ filterDropdown:
255
+ 'absolute z-50 mt-2 bg-white dark:bg-zinc-800 border dark:border-zinc-700 rounded-lg shadow-lg',
256
+ filterTag:
257
+ 'inline-flex items-center gap-1 px-2 py-1 text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded-md',
258
+ };
259
+
260
+ // Usage
261
+ import { appDataGridTheme } from './utils/dataGridTheme';
262
+
263
+ <DataGrid data={data} theme={appDataGridTheme} />;
264
+ ```
265
+
123
266
  ## 🌐 Server-Side Data (Controlled Mode)
124
267
 
125
268
  The DataGrid is a **controlled presentation component**. You handle data fetching; the grid handles display.
@@ -247,7 +390,7 @@ For large datasets, enable scrollable body with fixed headers:
247
390
 
248
391
  ## 🎯 Event System
249
392
 
250
- ### Filter Events (NEW)
393
+ ### Filter Events
251
394
 
252
395
  ```tsx
253
396
  <DataGrid
@@ -360,15 +503,16 @@ For large datasets, enable scrollable body with fixed headers:
360
503
  | `currentPage` | `number` | - | Controlled current page |
361
504
  | `error` | `string \| null` | - | Error message to display |
362
505
 
363
- ### Layout
506
+ ### Layout & Styling
364
507
 
365
- | Prop | Type | Default | Description |
366
- | -------------- | -------------------------------------- | ----------- | --------------------------------- |
367
- | `maxHeight` | `string \| number` | - | Fixed height with scrollable body |
368
- | `stickyHeader` | `boolean` | `false` | Enable sticky table header |
369
- | `className` | `string` | `''` | Additional CSS classes |
370
- | `variant` | `'default' \| 'striped' \| 'bordered'` | `'default'` | Visual theme |
371
- | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Padding/text size |
508
+ | Prop | Type | Default | Description |
509
+ | -------------- | -------------------------------------- | ----------- | ------------------------------------ |
510
+ | `maxHeight` | `string \| number` | - | Fixed height with scrollable body |
511
+ | `stickyHeader` | `boolean` | `false` | Enable sticky table header |
512
+ | `className` | `string` | `''` | Additional CSS classes |
513
+ | `variant` | `'default' \| 'striped' \| 'bordered'` | `'default'` | Visual theme variant |
514
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Padding/text size |
515
+ | `theme` | `Partial<Theme>` | - | Custom theme overrides (see Theming) |
372
516
 
373
517
  ### Features
374
518
 
@@ -438,6 +582,8 @@ interface Column<T> {
438
582
 
439
583
  ## 🎨 Theming & Styling
440
584
 
585
+ ### Built-in Variants
586
+
441
587
  ```tsx
442
588
  // Clean, minimal design
443
589
  <DataGrid variant="default" data={data} />
@@ -459,6 +605,27 @@ interface Column<T> {
459
605
  </div>
460
606
  ```
461
607
 
608
+ ### Custom Theme
609
+
610
+ ```tsx
611
+ import { DataGrid, createZincTheme } from '@reactorui/datagrid';
612
+
613
+ // Option 1: Use zinc theme helper
614
+ <DataGrid data={data} theme={createZincTheme('default')} />
615
+
616
+ // Option 2: Partial overrides
617
+ <DataGrid
618
+ data={data}
619
+ theme={{
620
+ container: 'bg-white dark:bg-slate-900 rounded-2xl',
621
+ row: 'hover:bg-slate-50 dark:hover:bg-slate-800',
622
+ }}
623
+ />
624
+
625
+ // Option 3: Complete custom theme
626
+ <DataGrid data={data} theme={myCompleteTheme} />
627
+ ```
628
+
462
629
  ## 🧪 Testing
463
630
 
464
631
  ```bash
@@ -489,6 +656,13 @@ test('handles filter application', async () => {
489
656
  expect.any(Array)
490
657
  );
491
658
  });
659
+
660
+ test('applies custom theme', () => {
661
+ const customTheme = { container: 'custom-class dark:bg-zinc-900' };
662
+ const { container } = render(<DataGrid data={testData} theme={customTheme} />);
663
+
664
+ expect(container.firstChild).toHaveClass('dark:bg-zinc-900');
665
+ });
492
666
  ```
493
667
 
494
668
  ## ⚠️ Migration Guide
@@ -560,7 +734,7 @@ function MyGrid() {
560
734
  // ✅ Set filterMode to enable callbacks
561
735
  <DataGrid
562
736
  data={data}
563
- filterMode="server" // or "both"
737
+ filterMode="server" // or "client&server"
564
738
  onApplyFilter={(f) => fetchWithFilter(f)}
565
739
  />
566
740
  ```
@@ -575,6 +749,14 @@ npm run typecheck # Type checking
575
749
  npm run lint # Linting
576
750
  ```
577
751
 
752
+ ## 📤 Publishing
753
+
754
+ ```bash
755
+ npm run build # Build the package
756
+ npm version patch|minor|major # Bump version
757
+ npm publish --access public # Publish to npm
758
+ ```
759
+
578
760
  ## 📄 License
579
761
 
580
762
  MIT License - see [LICENSE](LICENSE) file for details.
@@ -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, 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;
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, theme: customTheme, 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;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"}
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,mvBAyE9D,aAAa,CAAC,CAAC,CAAC,4CAwYlB,CAAC"}
@@ -28,7 +28,7 @@ maxHeight, stickyHeader = false,
28
28
  // Pagination
29
29
  pageSize = 10, pageSizeOptions = [5, 10, 25, 50, 100],
30
30
  // Styling
31
- variant = 'default', size = 'md', className = '',
31
+ variant = 'default', size = 'md', className = '', theme: customTheme,
32
32
  // Pagination Events
33
33
  onPageChange, onPageSizeChange,
34
34
  // Sort & Search Events
@@ -41,7 +41,8 @@ onTableRowClick, onTableRowDoubleClick, onRowSelect, onSelectionChange, onTableR
41
41
  onTableRefresh, onBulkDelete,
42
42
  // DEPRECATED Props (kept for backward compatibility)
43
43
  endpoint, httpConfig, serverPageSize, onDataLoad, onDataError, onLoadingStateChange, ...rest }) => {
44
- const theme = getTheme(variant);
44
+ // Merge variant theme with custom theme overrides
45
+ const theme = useMemo(() => getTheme(variant, customTheme), [variant, customTheme]);
45
46
  // ===== Deprecation Warnings =====
46
47
  React.useEffect(() => {
47
48
  if (process.env.NODE_ENV !== 'production') {
@@ -110,55 +111,49 @@ endpoint, httpConfig, serverPageSize, onDataLoad, onDataError, onLoadingStateCha
110
111
  onClearFilters,
111
112
  onFilterChange,
112
113
  });
113
- // Auto-detect columns if not provided
114
+ // ===== Column Configuration =====
114
115
  const columns = useMemo(() => {
115
116
  if (columnsProp.length > 0)
116
117
  return columnsProp;
117
- if (data.length > 0) {
118
- const firstRow = data[0];
119
- return Object.keys(firstRow).map((key) => ({
120
- key,
121
- label: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1'),
122
- sortable: true,
123
- filterable: true,
124
- dataType: inferDataType(firstRow[key]),
125
- }));
126
- }
127
- return [];
118
+ if (!data || data.length === 0)
119
+ return [];
120
+ // Auto-detect columns from first row
121
+ return Object.keys(data[0]).map((key) => ({
122
+ key,
123
+ label: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1'),
124
+ sortable: true,
125
+ filterable: true,
126
+ dataType: inferDataType(data[0][key]),
127
+ }));
128
128
  }, [columnsProp, data]);
129
- // Selection change effect
130
- const previousSelectedData = React.useRef([]);
131
- React.useLayoutEffect(() => {
132
- const hasChanged = selectedData.length !== previousSelectedData.current.length ||
133
- selectedData.some((item, index) => item !== previousSelectedData.current[index]);
134
- if (hasChanged && onSelectionChange) {
135
- previousSelectedData.current = selectedData;
136
- onSelectionChange(selectedData);
137
- }
138
- }, [selectedData, onSelectionChange]);
139
129
  // Handle row selection with callback
140
- const handleRowSelect = useCallback((rowId, selected) => {
141
- selectRow(rowId, selected);
142
- if (onRowSelect) {
143
- const row = data.find((r) => getRowId(r) === rowId);
144
- if (row) {
145
- onRowSelect(row, selected);
146
- }
147
- }
148
- }, [selectRow, onRowSelect, data, getRowId]);
149
- // Handle delete action
130
+ const handleRowSelect = useCallback((row, isSelected) => {
131
+ const rowId = getRowId(row);
132
+ selectRow(rowId, isSelected);
133
+ onRowSelect?.(row, isSelected);
134
+ // Calculate new selection for callback
135
+ const newSelectedRows = new Set(selectedRows);
136
+ isSelected ? newSelectedRows.add(rowId) : newSelectedRows.delete(rowId);
137
+ const newSelectedData = data.filter((r) => newSelectedRows.has(getRowId(r)));
138
+ onSelectionChange?.(newSelectedData);
139
+ }, [selectRow, onRowSelect, onSelectionChange, getRowId, selectedRows, data]);
140
+ // Handle select all with callback
141
+ const handleSelectAll = useCallback((selected) => {
142
+ selectAll(selected);
143
+ // Call onSelectionChange with all or none
144
+ const newSelectedData = selected ? paginatedData : [];
145
+ onSelectionChange?.(newSelectedData);
146
+ }, [selectAll, onSelectionChange, paginatedData]);
147
+ // Handle delete
150
148
  const handleDelete = useCallback(() => {
151
149
  if (selectedRows.size === 0)
152
150
  return;
153
151
  const executeDelete = () => {
154
- if (onBulkDelete) {
155
- onBulkDelete(selectedData);
156
- }
152
+ onBulkDelete?.(selectedData);
157
153
  };
158
154
  if (deleteConfirmation) {
159
- const count = selectedRows.size;
160
- const message = `Are you sure you want to delete ${count} selected item${count === 1 ? '' : 's'}?`;
161
- if (window.confirm(message)) {
155
+ const confirmMessage = `Are you sure you want to delete ${selectedRows.size} selected item${selectedRows.size === 1 ? '' : 's'}?`;
156
+ if (window.confirm(confirmMessage)) {
162
157
  executeDelete();
163
158
  }
164
159
  }
@@ -175,17 +170,15 @@ endpoint, httpConfig, serverPageSize, onDataLoad, onDataError, onLoadingStateCha
175
170
  const hasFixedLayout = maxHeight !== undefined || stickyHeader;
176
171
  // Error state
177
172
  if (externalError) {
178
- return (_jsx("div", { className: `${theme.container} ${className}`, ...rest, children: _jsxs("div", { className: "px-4 py-8 text-center", children: [_jsx("div", { className: "text-red-600 dark:text-red-400 mb-2", children: "Error loading data" }), _jsx("div", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: externalError }), _jsx("button", { onClick: handleRefresh, className: theme.button, children: "Try Again" })] }) }));
173
+ return (_jsx("div", { className: `${theme.container} ${className}`, ...rest, children: _jsxs("div", { className: "px-4 py-8 text-center", children: [_jsx("div", { className: `${theme.textError} mb-2`, children: "Error loading data" }), _jsx("div", { className: `text-sm ${theme.textMuted} mb-4`, children: externalError }), _jsx("button", { onClick: handleRefresh, className: theme.button, children: "Try Again" })] }) }));
179
174
  }
180
175
  return (_jsxs("div", { className: `${theme.container} ${className} ${hasFixedLayout ? 'flex flex-col' : ''}`, style: hasFixedLayout && maxHeight
181
176
  ? { maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight }
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
177
+ : 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 ${theme.text}`, children: "Show" }), _jsx("select", { value: currentPageSize, onChange: (e) => setCurrentPageSize(parseInt(e.target.value)), disabled: isAnyLoading, className: theme.select, children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) }), _jsx("span", { className: `text-sm ${theme.text}`, children: "entries" }), enableFilters && (_jsx(FilterControls, { columns: columns, activeFilters: activeFilters, onApplyFilter: addFilter, onRemoveFilter: removeFilter, onClearFilters: clearFilters, disabled: isDataLoading, filterLoading: isFilterLoading, theme: theme }))] }), _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 ${theme.textMuted}` }) }))] })), enableRefresh && (_jsx("button", { onClick: handleRefresh, disabled: isAnyLoading, title: isRefreshLoading ? 'Refreshing...' : 'Refresh data', className: `${theme.buttonSecondary} 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
183
178
  ? 'Select rows to delete'
184
179
  : isDeleteLoading
185
180
  ? 'Deleting...'
186
- : `Delete ${selectedRows.size} selected item${selectedRows.size === 1 ? '' : 's'}`, className: `px-3 py-2 rounded focus:outline-none focus:ring-2 focus:ring-gray-500 dark:focus:ring-gray-400 transition-colors duration-150 flex items-center gap-1 ${selectedRows.size === 0 || isAnyLoading
187
- ? 'bg-gray-100 dark:bg-gray-700 text-gray-400 dark:text-gray-500 cursor-not-allowed'
188
- : 'bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-600 cursor-pointer'}`, children: [isDeleteLoading ? (_jsx(Spinner, { className: "w-4 h-4" })) : (_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: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })), selectedRows.size > 0 && (_jsx("span", { className: "text-sm", children: isDeleteLoading ? 'Deleting...' : `(${selectedRows.size} selected)` }))] }))] })] }) }), _jsx("div", { className: `
181
+ : `Delete ${selectedRows.size} selected item${selectedRows.size === 1 ? '' : 's'}`, className: `${theme.buttonSecondary} flex items-center gap-1 ${selectedRows.size === 0 || isAnyLoading ? 'opacity-50 cursor-not-allowed' : ''}`, children: [isDeleteLoading ? (_jsx(Spinner, { className: "w-4 h-4" })) : (_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: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })), selectedRows.size > 0 && (_jsx("span", { className: "text-sm", children: isDeleteLoading ? 'Deleting...' : `(${selectedRows.size} selected)` }))] }))] })] }) }), _jsx("div", { className: `
189
182
  ${hasFixedLayout ? 'flex-1 overflow-auto min-h-0' : 'overflow-x-auto'}
190
- `, children: _jsxs("table", { className: theme.table, children: [_jsx(TableHeader, { columns: columns, sortConfig: sortConfig, onSort: enableSorting ? setSort : undefined, enableSelection: enableSelection, selectedCount: selectedRows.size, totalCount: paginatedData.length, onSelectAll: enableSelection ? selectAll : undefined, theme: theme, sticky: hasFixedLayout }), _jsx(TableBody, { columns: columns, data: paginatedData, selectedRows: selectedRows, onSelectRow: enableSelection ? handleRowSelect : undefined, onRowClick: onTableRowClick, onRowDoubleClick: onTableRowDoubleClick, onRowHover: onTableRowHover, onCellClick: onCellClick, enableSelection: enableSelection, loading: isDataLoading, theme: theme, getRowId: getRowId })] }) }), _jsxs("div", { className: `${theme.pagination} flex-shrink-0`, children: [_jsxs("div", { className: "text-sm text-gray-700 dark:text-gray-300 flex-shrink-0", children: ["Showing ", paginationInfo.start, "-", paginationInfo.end, " of", ' ', paginationInfo.totalRecords.toLocaleString(), " records"] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: navigatePrevious, disabled: !paginationInfo.hasPrevious || isAnyLoading, className: "px-3 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 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: "Previous" }), _jsxs("span", { className: "text-sm text-gray-700 dark:text-gray-300 px-2", children: ["Page ", currentPage, " ", paginationInfo.totalPages > 0 && `of ${paginationInfo.totalPages}`] }), _jsx("button", { onClick: navigateNext, disabled: !paginationInfo.hasNext || isAnyLoading, className: "px-3 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 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: "Next" })] })] })] }));
183
+ `, children: _jsxs("table", { className: theme.table, children: [_jsx(TableHeader, { columns: columns, sortConfig: sortConfig, onSort: enableSorting ? setSort : undefined, enableSelection: enableSelection, selectedCount: selectedRows.size, totalCount: paginatedData.length, onSelectAll: enableSelection ? handleSelectAll : undefined, theme: theme, sticky: hasFixedLayout }), _jsx(TableBody, { columns: columns, data: paginatedData, selectedRows: selectedRows, onSelectRow: enableSelection ? handleRowSelect : undefined, onRowClick: onTableRowClick, onRowDoubleClick: onTableRowDoubleClick, onRowHover: onTableRowHover, onCellClick: onCellClick, enableSelection: enableSelection, loading: isDataLoading, theme: theme, getRowId: getRowId })] }) }), _jsxs("div", { className: `${theme.pagination} flex-shrink-0`, children: [_jsxs("div", { className: `${theme.paginationText} flex-shrink-0`, children: ["Showing ", paginationInfo.start, "-", paginationInfo.end, " of", ' ', paginationInfo.totalRecords.toLocaleString(), " records"] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: navigatePrevious, disabled: !paginationInfo.hasPrevious || isAnyLoading, className: theme.paginationButton, children: "Previous" }), _jsxs("span", { className: `${theme.paginationText} px-2`, children: ["Page ", currentPage, " ", paginationInfo.totalPages > 0 && `of ${paginationInfo.totalPages}`] }), _jsx("button", { onClick: navigateNext, disabled: !paginationInfo.hasNext || isAnyLoading, className: theme.paginationButton, children: "Next" })] })] })] }));
191
184
  };
@@ -1,4 +1,5 @@
1
1
  import { Column, ActiveFilter } from '../../types';
2
+ import { Theme } from '../../themes';
2
3
  interface FilterControlsProps<T> {
3
4
  columns: Column<T>[];
4
5
  activeFilters: ActiveFilter[];
@@ -7,7 +8,8 @@ interface FilterControlsProps<T> {
7
8
  onClearFilters: () => void;
8
9
  disabled?: boolean;
9
10
  filterLoading?: boolean;
11
+ theme: Theme;
10
12
  }
11
- export declare const FilterControls: <T>({ columns, activeFilters, onApplyFilter, onRemoveFilter, onClearFilters, disabled, filterLoading, }: FilterControlsProps<T>) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const FilterControls: <T>({ columns, activeFilters, onApplyFilter, onRemoveFilter, onClearFilters, disabled, filterLoading, theme, }: FilterControlsProps<T>) => import("react/jsx-runtime").JSX.Element;
12
14
  export {};
13
15
  //# sourceMappingURL=FilterControls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControls.d.ts","sourceRoot":"","sources":["../../../src/components/Filter/FilterControls.tsx"],"names":[],"mappings":"AAIA,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;AA2FD,eAAO,MAAM,cAAc,GAAI,CAAC,EAAG,qGAQhC,mBAAmB,CAAC,CAAC,CAAC,4CAkUxB,CAAC"}
1
+ {"version":3,"file":"FilterControls.d.ts","sourceRoot":"","sources":["../../../src/components/Filter/FilterControls.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAMrC,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;IACxB,KAAK,EAAE,KAAK,CAAC;CACd;AAuED,eAAO,MAAM,cAAc,GAAI,CAAC,EAAG,4GAShC,mBAAmB,CAAC,CAAC,CAAC,4CAuUxB,CAAC"}
@@ -39,25 +39,13 @@ const OPERATORS = {
39
39
  };
40
40
  const DEFAULT_OPERATORS = [{ value: 'eq', label: 'equals' }];
41
41
  // ============================================================================
42
- // Styles
43
- // ============================================================================
44
- const styles = {
45
- select: 'w-full px-3 py-2.5 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',
46
- input: 'w-full px-3 py-2.5 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',
47
- inputDisabled: 'w-full px-3 py-2.5 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',
48
- buttonPrimary: 'w-full px-4 py-2.5 bg-blue-600 dark:bg-blue-700 text-white text-sm font-medium 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',
49
- label: 'block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5',
50
- filterTag: 'inline-flex items-center gap-1.5 px-2.5 py-1 bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 rounded-md text-xs font-medium whitespace-nowrap',
51
- filterTagRemove: 'ml-0.5 text-blue-600 dark:text-blue-300 hover:text-blue-800 dark:hover:text-blue-100 focus:outline-none',
52
- };
53
- // ============================================================================
54
42
  // Filter Icon
55
43
  // ============================================================================
56
44
  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
45
  // ============================================================================
58
46
  // Component
59
47
  // ============================================================================
60
- export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemoveFilter, onClearFilters, disabled = false, filterLoading = false, }) => {
48
+ export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemoveFilter, onClearFilters, disabled = false, filterLoading = false, theme, }) => {
61
49
  const [isOpen, setIsOpen] = useState(false);
62
50
  const [filterColumn, setFilterColumn] = useState('');
63
51
  const [filterOperator, setFilterOperator] = useState('eq');
@@ -163,19 +151,21 @@ export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemove
163
151
  }, [canApply, handleApply, isDisabled]);
164
152
  // Render value input based on data type
165
153
  const renderValueInput = () => {
154
+ const inputClass = `w-full px-3 py-2.5 ${theme.searchInput}`;
155
+ const disabledClass = `w-full px-3 py-2.5 ${theme.select} opacity-50 cursor-not-allowed`;
166
156
  if (!selectedColumn) {
167
- return (_jsx("input", { type: "text", disabled: true, value: "", placeholder: "Select column first", className: styles.inputDisabled }));
157
+ return (_jsx("input", { type: "text", disabled: true, value: "", placeholder: "Select column first", className: disabledClass }));
168
158
  }
169
159
  const commonProps = {
170
160
  value: filterValue,
171
161
  onChange: (e) => setFilterValue(e.target.value),
172
162
  onKeyDown: handleKeyDown,
173
163
  disabled: isDisabled,
174
- className: styles.input,
164
+ className: inputClass,
175
165
  };
176
166
  switch (selectedColumn.dataType) {
177
167
  case 'boolean':
178
- return (_jsxs("select", { ...commonProps, className: styles.select, children: [_jsx("option", { value: "", children: "Select value" }), _jsx("option", { value: "true", children: "True" }), _jsx("option", { value: "false", children: "False" })] }));
168
+ return (_jsxs("select", { ...commonProps, className: `w-full px-3 py-2.5 ${theme.select}`, children: [_jsx("option", { value: "", children: "Select value" }), _jsx("option", { value: "true", children: "True" }), _jsx("option", { value: "false", children: "False" })] }));
179
169
  case 'date':
180
170
  return _jsx("input", { ...commonProps, type: "date" });
181
171
  case 'datetime':
@@ -188,11 +178,11 @@ export const FilterControls = ({ columns, activeFilters, onApplyFilter, onRemove
188
178
  };
189
179
  return (_jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [_jsxs("button", { ref: buttonRef, onClick: () => setIsOpen(!isOpen), disabled: isDisabled, title: filterCount > 0
190
180
  ? `${filterCount} filter${filterCount === 1 ? '' : 's'} active`
191
- : 'Add filter', className: "relative flex-shrink-0 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 }))] }), activeFilters.length > 0 && (_jsx("div", { className: "flex-1 min-w-0 overflow-x-auto", style: { scrollbarWidth: 'none', msOverflowStyle: 'none' }, children: _jsxs("div", { className: "flex items-center gap-1.5 py-0.5", children: [activeFilters.map((filter, index) => (_jsxs("span", { className: styles.filterTag, children: [filter.label, _jsx("button", { onClick: () => onRemoveFilter(index), disabled: isDisabled, className: styles.filterTagRemove, "aria-label": `Remove filter: ${filter.label}`, children: "\u00D7" })] }, `${filter.column}-${index}`))), activeFilters.length > 1 && (_jsx("button", { onClick: onClearFilters, disabled: isDisabled, className: "flex-shrink-0 text-xs text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300 whitespace-nowrap px-2 py-1 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors", children: "Clear all" }))] }) })), isOpen &&
192
- createPortal(_jsx("div", { ref: popoverRef, className: "fixed w-80 bg-white dark:bg-gray-800 rounded-lg shadow-xl border border-gray-200 dark:border-gray-700", style: {
181
+ : 'Add filter', className: `relative flex-shrink-0 p-2 ${theme.text} ${theme.buttonSecondary.replace(/px-3 py-2/g, '')} rounded-md 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 }))] }), activeFilters.length > 0 && (_jsx("div", { className: "flex-1 min-w-0 overflow-x-auto", style: { scrollbarWidth: 'none', msOverflowStyle: 'none' }, children: _jsxs("div", { className: "flex items-center gap-1.5 py-0.5", children: [activeFilters.map((filter, index) => (_jsxs("span", { className: theme.filterTag, children: [filter.label, _jsx("button", { onClick: () => onRemoveFilter(index), disabled: isDisabled, className: theme.filterTagRemove, "aria-label": `Remove filter: ${filter.label}`, children: "\u00D7" })] }, `${filter.column}-${index}`))), activeFilters.length > 1 && (_jsx("button", { onClick: onClearFilters, disabled: isDisabled, className: `flex-shrink-0 text-xs ${theme.textError} whitespace-nowrap px-2 py-1 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors`, children: "Clear all" }))] }) })), isOpen &&
182
+ createPortal(_jsx("div", { ref: popoverRef, className: `fixed w-80 ${theme.filterDropdown}`, style: {
193
183
  top: popoverPosition.top,
194
184
  padding: 14,
195
185
  left: popoverPosition.left,
196
186
  zIndex: 99999,
197
- }, children: _jsxs("div", { className: "p-5 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h3", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: "Add Filter" }), _jsx("button", { onClick: () => setIsOpen(false), className: "p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors", children: _jsx("svg", { className: "w-5 h-5", 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" })] }) }), document.body)] }));
187
+ }, children: _jsxs("div", { className: "p-5 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h3", { className: `text-base font-semibold ${theme.text.replace('text-gray-700', 'text-gray-900').replace('dark:text-zinc-300', 'dark:text-zinc-100')}`, children: "Add Filter" }), _jsx("button", { onClick: () => setIsOpen(false), className: `p-1 ${theme.textMuted} hover:${theme.text} rounded-md ${theme.buttonSecondary.replace(/px-3 py-2 bg-\S+ /g, '')} transition-colors`, children: _jsx("svg", { className: "w-5 h-5", 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: `block text-sm font-medium ${theme.text} mb-1.5`, children: "Column" }), _jsxs("select", { value: filterColumn, onChange: (e) => handleColumnChange(e.target.value), disabled: isDisabled, className: `w-full px-3 py-2.5 ${theme.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: `block text-sm font-medium ${theme.text} mb-1.5`, children: "Operator" }), _jsx("select", { value: filterOperator, onChange: (e) => setFilterOperator(e.target.value), disabled: isDisabled || !filterColumn, className: `w-full px-3 py-2.5 ${theme.select}`, children: operatorOptions.map((op) => (_jsx("option", { value: op.value, children: op.label }, op.value))) })] }), _jsxs("div", { children: [_jsx("label", { className: `block text-sm font-medium ${theme.text} mb-1.5`, children: "Value" }), renderValueInput()] }), _jsx("button", { onClick: handleApply, disabled: isDisabled || !canApply, className: `w-full px-4 py-2.5 ${theme.button} font-medium`, children: "Apply Filter" })] }) }), document.body)] }));
198
188
  };
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { Theme } from '../../themes';
2
3
  interface PaginationProps {
3
4
  currentPage: number;
4
5
  totalPages: number;
@@ -11,6 +12,8 @@ interface PaginationProps {
11
12
  onPageSizeChange: (size: number) => void;
12
13
  hasNext: boolean;
13
14
  hasPrevious: boolean;
15
+ disabled?: boolean;
16
+ theme: Theme;
14
17
  }
15
18
  export declare const Pagination: React.FC<PaginationProps>;
16
19
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/components/Pagination/Pagination.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA0EhD,CAAC"}
1
+ {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/components/Pagination/Pagination.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAiFhD,CAAC"}
@@ -1,12 +1,14 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- export const Pagination = ({ currentPage, totalPages, pageSize, pageSizeOptions, totalRecords, displayStart, displayEnd, onPageChange, onPageSizeChange, hasNext, hasPrevious, }) => {
2
+ export const Pagination = ({ currentPage, totalPages, pageSize, pageSizeOptions, totalRecords, displayStart, displayEnd, onPageChange, onPageSizeChange, hasNext, hasPrevious, disabled = false, theme, }) => {
3
3
  const handlePageChange = (page) => {
4
- if (page >= 1 && page <= totalPages) {
4
+ if (page >= 1 && page <= totalPages && !disabled) {
5
5
  onPageChange(page);
6
6
  }
7
7
  };
8
8
  const handlePageSizeChange = (newSize) => {
9
- onPageSizeChange(newSize);
9
+ if (!disabled) {
10
+ onPageSizeChange(newSize);
11
+ }
10
12
  };
11
- return (_jsxs("div", { className: "flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 px-4 py-3 bg-white border-t border-gray-200", children: [_jsxs("div", { className: "text-sm text-gray-700", children: ["Showing ", displayStart, "-", displayEnd, " of ", totalRecords, " records"] }), _jsxs("div", { className: "flex items-center gap-6", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-gray-700", children: "Show:" }), _jsx("select", { value: pageSize, onChange: (e) => handlePageSizeChange(parseInt(e.target.value)), className: "px-2 py-1 border border-gray-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) }), _jsx("span", { className: "text-sm text-gray-700", children: "entries" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: () => handlePageChange(currentPage - 1), disabled: !hasPrevious, className: "px-3 py-1 text-sm border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed", children: "Previous" }), _jsxs("span", { className: "text-sm text-gray-700", children: ["Page ", currentPage, " of ", totalPages] }), _jsx("button", { onClick: () => handlePageChange(currentPage + 1), disabled: !hasNext, className: "px-3 py-1 text-sm border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed", children: "Next" })] })] })] }));
13
+ return (_jsxs("div", { className: `flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 ${theme.pagination}`, children: [_jsxs("div", { className: theme.paginationText, children: ["Showing ", displayStart, "-", displayEnd, " of ", totalRecords.toLocaleString(), " records"] }), _jsxs("div", { className: "flex items-center gap-6", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: theme.paginationText, children: "Show:" }), _jsx("select", { value: pageSize, onChange: (e) => handlePageSizeChange(parseInt(e.target.value)), disabled: disabled, className: theme.select, children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) }), _jsx("span", { className: theme.paginationText, children: "entries" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: () => handlePageChange(currentPage - 1), disabled: !hasPrevious || disabled, className: theme.paginationButton, children: "Previous" }), _jsxs("span", { className: `${theme.paginationText} px-2`, children: ["Page ", currentPage, " ", totalPages > 0 && `of ${totalPages}`] }), _jsx("button", { onClick: () => handlePageChange(currentPage + 1), disabled: !hasNext || disabled, className: theme.paginationButton, children: "Next" })] })] })] }));
12
14
  };
@@ -1,10 +1,12 @@
1
1
  import React from 'react';
2
+ import { Theme } from '../../themes';
2
3
  interface SearchInputProps {
3
4
  value: string;
4
5
  onChange: (value: string) => void;
5
6
  placeholder?: string;
6
7
  disabled?: boolean;
7
8
  className?: string;
9
+ theme?: Theme;
8
10
  }
9
11
  export declare const SearchInput: React.FC<SearchInputProps>;
10
12
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../src/components/Search/SearchInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuClD,CAAC"}
1
+ {"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../src/components/Search/SearchInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA0ClD,CAAC"}
@@ -1,9 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- export const SearchInput = ({ value, onChange, placeholder = 'Search...', disabled = false, className = '', }) => {
3
- return (_jsxs("div", { className: "relative", children: [_jsx("input", { type: "text", value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, disabled: disabled, className: `
4
- w-full px-3 py-2 pl-10 border border-gray-300 rounded text-sm
5
- focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
6
- disabled:bg-gray-50 disabled:text-gray-500
7
- ${className}
8
- ` }), _jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: _jsx("svg", { className: "h-4 w-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) })] }));
2
+ export const SearchInput = ({ value, onChange, placeholder = 'Search...', disabled = false, className = '', theme, }) => {
3
+ // Fallback styles if no theme provided (backward compatibility)
4
+ const inputStyles = theme?.searchInput ??
5
+ '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';
6
+ const iconStyles = theme?.textMuted ?? 'text-gray-400 dark:text-gray-500';
7
+ return (_jsxs("div", { className: "relative", children: [_jsx("input", { type: "text", value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, disabled: disabled, className: `w-full pl-10 ${inputStyles} disabled:opacity-50 disabled:cursor-not-allowed ${className}` }), _jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: _jsx("svg", { className: `h-4 w-4 ${iconStyles}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) })] }));
9
8
  };
@@ -5,7 +5,7 @@ interface TableBodyProps<T> {
5
5
  columns: Column<T>[];
6
6
  data: T[];
7
7
  selectedRows: Set<string>;
8
- onSelectRow?: (rowId: string, selected: boolean) => void;
8
+ onSelectRow?: (row: T, selected: boolean) => void;
9
9
  onRowClick?: (row: T, event: React.MouseEvent) => void;
10
10
  onRowDoubleClick?: (row: T, event: React.MouseEvent) => void;
11
11
  onRowHover?: (row: T | null, event: React.MouseEvent) => void;
@@ -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,4CAwKnB,CAAC"}
1
+ {"version":3,"file":"TableBody.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableBody.tsx"],"names":[],"mappings":"AAEA,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,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,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,4CAuLnB,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // File: src/components/Table/TableBody.tsx
2
3
  import React from 'react';
3
4
  export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick, onRowDoubleClick, onRowHover, onCellClick, enableSelection, loading, emptyMessage = 'No data available', theme, getRowId, }) => {
4
- // Generate stable row IDs - always generate, never use existing fields
5
+ // Generate stable row IDs
5
6
  const rowIdMap = React.useMemo(() => {
6
7
  const map = new Map();
7
8
  data.forEach((row, index) => {
8
- // Always generate based on index and content hash
9
9
  const contentHash = JSON.stringify(row)
10
10
  .slice(0, 50)
11
11
  .replace(/[^a-zA-Z0-9]/g, '');
@@ -40,7 +40,7 @@ export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick
40
40
  if (enableSelection && onSelectRow) {
41
41
  const rowId = getStableRowId(row);
42
42
  const isSelected = selectedRows.has(rowId);
43
- onSelectRow(rowId, !isSelected);
43
+ onSelectRow(row, !isSelected);
44
44
  }
45
45
  };
46
46
  const handleCellClick = (row, column, event) => {
@@ -49,19 +49,32 @@ export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick
49
49
  onCellClick(value, row, column, event);
50
50
  }
51
51
  };
52
+ // Extract background from theme.table for tbody
53
+ const tbodyBg = theme.table.includes('bg-')
54
+ ? theme.table
55
+ .split(' ')
56
+ .filter((c) => c.startsWith('bg-') || c.startsWith('dark:bg-'))
57
+ .join(' ')
58
+ : '';
52
59
  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: "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..." })] }) }) }) }));
60
+ return (_jsx("tbody", { className: tbodyBg, children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: `px-4 py-12 text-center ${theme.textMuted}`, 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
61
  }
55
62
  if (data.length === 0) {
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 }) }) }));
63
+ return (_jsx("tbody", { className: tbodyBg, children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: `px-4 py-8 text-center ${theme.emptyState} ${tbodyBg}`, children: emptyMessage }) }) }));
57
64
  }
58
- return (_jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: data.map((row, index) => {
65
+ // Extract border color from theme for dividers
66
+ const borderColor = theme.cell
67
+ .match(/border-\S+/g)
68
+ ?.filter((c) => !c.includes('border-b') && !c.includes('border-r'))?.[0] ||
69
+ 'border-gray-200 dark:border-gray-600';
70
+ const divideBorder = borderColor.replace('border-', 'divide-');
71
+ return (_jsx("tbody", { className: `divide-y ${divideBorder}`, children: data.map((row) => {
59
72
  const rowId = getStableRowId(row);
60
73
  const isSelected = selectedRows.has(rowId);
61
74
  return (_jsxs("tr", { className: `cursor-pointer ${isSelected ? theme.selectedRow : theme.row}`, onClick: (e) => handleRowClick(row, e), onDoubleClick: (e) => onRowDoubleClick?.(row, e), onMouseEnter: (e) => onRowHover?.(row, e), onMouseLeave: (e) => onRowHover?.(null, e), children: [enableSelection && (_jsx("td", { className: theme.cell, children: _jsx("input", { type: "checkbox", checked: isSelected, onChange: (e) => {
62
75
  e.stopPropagation();
63
- onSelectRow?.(rowId, e.target.checked);
64
- }, className: "w-4 h-4 text-blue-600 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 dark:focus:ring-blue-400" }) })), columns.map((column) => (_jsx("td", { className: theme.cell, style: {
76
+ onSelectRow?.(row, e.target.checked);
77
+ }, className: `w-4 h-4 text-blue-600 rounded focus:ring-blue-500 dark:focus:ring-blue-400 ${tbodyBg} ${borderColor}` }) })), columns.map((column) => (_jsx("td", { className: theme.cell, style: {
65
78
  width: column.width,
66
79
  minWidth: column.minWidth,
67
80
  maxWidth: column.maxWidth,
@@ -1 +1 @@
1
- {"version":3,"file":"TableHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableHeader.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,gBAAgB,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,EAAG,0GAU7B,gBAAgB,CAAC,CAAC,CAAC,4CAyGrB,CAAC"}
1
+ {"version":3,"file":"TableHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableHeader.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,gBAAgB,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,EAAG,0GAU7B,gBAAgB,CAAC,CAAC,CAAC,4CAgJrB,CAAC"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  export const TableHeader = ({ columns, sortConfig, onSort, enableSelection, selectedCount, totalCount, onSelectAll, theme, sticky = false, }) => {
3
3
  const getSortIcon = (columnKey) => {
4
4
  if (sortConfig.column !== columnKey) {
5
- return (_jsx("svg", { className: "w-4 h-4 text-gray-400 dark:text-gray-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }));
5
+ return (_jsx("svg", { className: `w-4 h-4 ${theme.textMuted}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }));
6
6
  }
7
7
  if (sortConfig.direction === 'asc') {
8
8
  return (_jsx("svg", { className: "w-4 h-4 text-blue-500 dark:text-blue-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) }));
@@ -11,12 +11,46 @@ export const TableHeader = ({ columns, sortConfig, onSort, enableSelection, sele
11
11
  };
12
12
  // Sticky styles
13
13
  const stickyClass = sticky ? 'sticky top-0 z-10' : '';
14
+ // Extract background from header theme for hover
15
+ const headerBg = theme.header.match(/(?:dark:)?bg-\S+/g) || [];
16
+ const hoverBg = headerBg.length > 0
17
+ ? headerBg
18
+ .map((bg) => {
19
+ // Convert bg-gray-50 -> hover:bg-gray-100, dark:bg-gray-700 -> dark:hover:bg-gray-600
20
+ if (bg.startsWith('dark:')) {
21
+ const color = bg.replace('dark:bg-', '');
22
+ const parts = color.match(/(\w+)-(\d+)/);
23
+ if (parts) {
24
+ const newShade = Math.max(parseInt(parts[2]) - 100, 600);
25
+ return `dark:hover:bg-${parts[1]}-${newShade}`;
26
+ }
27
+ return `dark:hover:bg-${color}`;
28
+ }
29
+ else {
30
+ const color = bg.replace('bg-', '');
31
+ const parts = color.match(/(\w+)-(\d+)/);
32
+ if (parts) {
33
+ const newShade = Math.min(parseInt(parts[2]) + 50, 200);
34
+ return `hover:bg-${parts[1]}-${newShade}`;
35
+ }
36
+ return `hover:bg-${color}`;
37
+ }
38
+ })
39
+ .join(' ')
40
+ : 'hover:bg-gray-100 dark:hover:bg-gray-600';
41
+ // Extract border from theme for checkbox
42
+ const borderColor = theme.headerCell
43
+ .match(/(?:dark:)?border-\S+/g)
44
+ ?.filter((c) => !c.includes('border-r') && !c.includes('border-b'))?.[0] ||
45
+ 'border-gray-300 dark:border-gray-600';
46
+ // Extract background for checkbox
47
+ const checkboxBg = theme.table.match(/(?:dark:)?bg-\S+/g)?.join(' ') || 'bg-white dark:bg-gray-800';
14
48
  return (_jsx("thead", { className: `${theme.header} ${stickyClass}`, children: _jsxs("tr", { children: [enableSelection && (_jsx("th", { className: `w-12 ${theme.headerCell}`, role: "columnheader", "aria-label": "Select all rows", children: _jsx("input", { type: "checkbox", checked: selectedCount > 0 && selectedCount === totalCount, ref: (el) => {
15
49
  if (el) {
16
50
  el.indeterminate = selectedCount > 0 && selectedCount < totalCount;
17
51
  }
18
- }, onChange: (e) => onSelectAll?.(e.target.checked), className: "w-4 h-4 text-blue-600 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 dark:focus:ring-blue-400", "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx("th", { role: "columnheader", className: `${theme.headerCell} ${column.sortable && onSort
19
- ? 'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 select-none'
52
+ }, onChange: (e) => onSelectAll?.(e.target.checked), className: `w-4 h-4 text-blue-600 ${checkboxBg} ${borderColor} rounded focus:ring-blue-500 dark:focus:ring-blue-400`, "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx("th", { role: "columnheader", className: `${theme.headerCell} ${column.sortable && onSort
53
+ ? `cursor-pointer ${hoverBg} select-none transition-colors duration-150`
20
54
  : ''}`, onClick: () => column.sortable && onSort && onSort(String(column.key)), style: {
21
55
  width: column.width,
22
56
  minWidth: column.minWidth,
@@ -7,8 +7,22 @@ export interface Theme {
7
7
  cell: string;
8
8
  selectedRow: string;
9
9
  searchInput: string;
10
+ select: string;
10
11
  button: string;
12
+ buttonSecondary: string;
13
+ buttonDanger: string;
14
+ text: string;
15
+ textMuted: string;
16
+ textError: string;
11
17
  pagination: string;
18
+ paginationButton: string;
19
+ paginationText: string;
20
+ loadingSkeleton: string;
21
+ emptyState: string;
22
+ errorState: string;
23
+ filterDropdown: string;
24
+ filterTag: string;
25
+ filterTagRemove: string;
12
26
  }
13
27
  export declare const defaultTheme: Theme;
14
28
  export declare const stripedTheme: Theme;
@@ -18,5 +32,13 @@ export declare const themes: {
18
32
  striped: Theme;
19
33
  bordered: Theme;
20
34
  };
21
- export declare const getTheme: (variant?: keyof typeof themes) => Theme;
35
+ export type ThemeVariant = keyof typeof themes;
36
+ /**
37
+ * Get a theme by variant name, optionally merged with custom overrides
38
+ */
39
+ export declare const getTheme: (variant?: ThemeVariant, customTheme?: Partial<Theme>) => Theme;
40
+ /**
41
+ * Create a theme with zinc palette for dark mode (matches Smithers ThemeStyles)
42
+ */
43
+ export declare const createZincTheme: (variant?: ThemeVariant) => Theme;
22
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,KAgB1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAS3B,CAAC;AAEF,eAAO,MAAM,MAAM;;;;CAIlB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,UAAS,MAAM,OAAO,MAAkB,KAAG,KAEnE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,KAAK;IAEpB,SAAS,EAAE,MAAM,CAAC;IAGlB,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;IAGpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IAGrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAGlB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IAGvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IAGnB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,YAAY,EAAE,KAiD1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAS3B,CAAC;AAEF,eAAO,MAAM,MAAM;;;;CAIlB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,MAAM,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,QAAQ,GACnB,UAAS,YAAwB,EACjC,cAAc,OAAO,CAAC,KAAK,CAAC,KAC3B,KAUF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,UAAS,YAAwB,KAAG,KAoDnE,CAAC"}
@@ -1,14 +1,36 @@
1
+ // File: src/themes/index.ts
1
2
  export const defaultTheme = {
3
+ // Container
2
4
  container: 'bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700',
5
+ // Table
3
6
  table: 'w-full bg-white dark:bg-gray-800',
4
7
  header: 'bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600',
5
8
  headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider bg-gray-50 dark:bg-gray-700',
6
9
  row: 'bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-150',
7
10
  cell: 'px-4 py-3 text-sm text-gray-900 dark:text-gray-100 border-b border-gray-200 dark:border-gray-600',
8
11
  selectedRow: 'bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30',
12
+ // Controls
9
13
  searchInput: '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',
14
+ select: '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',
10
15
  button: 'px-3 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:opacity-50 disabled:cursor-not-allowed',
16
+ buttonSecondary: 'px-3 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-blue-500 dark:focus:ring-blue-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150',
17
+ buttonDanger: 'px-3 py-2 bg-red-600 dark:bg-red-700 text-white text-sm rounded-md hover:bg-red-700 dark:hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 dark:focus:ring-red-400 disabled:opacity-50 disabled:cursor-not-allowed',
18
+ // Text
19
+ text: 'text-gray-700 dark:text-gray-300',
20
+ textMuted: 'text-gray-500 dark:text-gray-400',
21
+ textError: 'text-red-600 dark:text-red-400',
22
+ // Pagination
11
23
  pagination: 'flex items-center justify-between px-4 py-3 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-600',
24
+ paginationButton: 'px-3 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 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',
25
+ paginationText: 'text-sm text-gray-700 dark:text-gray-300',
26
+ // States
27
+ loadingSkeleton: 'animate-pulse bg-gray-200 dark:bg-gray-700 rounded',
28
+ emptyState: 'text-gray-500 dark:text-gray-400',
29
+ errorState: 'text-red-600 dark:text-red-400',
30
+ // Filter
31
+ filterDropdown: 'absolute z-50 mt-2 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-lg shadow-lg',
32
+ filterTag: 'inline-flex items-center gap-1 px-2 py-1 text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded-md',
33
+ filterTagRemove: 'hover:bg-blue-200 dark:hover:bg-blue-800 rounded p-0.5 transition-colors',
12
34
  };
13
35
  export const stripedTheme = {
14
36
  ...defaultTheme,
@@ -26,6 +48,71 @@ export const themes = {
26
48
  striped: stripedTheme,
27
49
  bordered: borderedTheme,
28
50
  };
29
- export const getTheme = (variant = 'default') => {
30
- return themes[variant] || themes.default;
51
+ /**
52
+ * Get a theme by variant name, optionally merged with custom overrides
53
+ */
54
+ export const getTheme = (variant = 'default', customTheme) => {
55
+ const baseTheme = themes[variant] || themes.default;
56
+ if (!customTheme)
57
+ return baseTheme;
58
+ // Deep merge custom theme with base theme
59
+ return {
60
+ ...baseTheme,
61
+ ...customTheme,
62
+ };
63
+ };
64
+ /**
65
+ * Create a theme with zinc palette for dark mode (matches Smithers ThemeStyles)
66
+ */
67
+ export const createZincTheme = (variant = 'default') => {
68
+ const base = themes[variant] || themes.default;
69
+ return {
70
+ ...base,
71
+ container: base.container
72
+ .replace(/dark:bg-gray-900/g, 'dark:bg-zinc-900')
73
+ .replace(/dark:border-gray-700/g, 'dark:border-zinc-700'),
74
+ table: base.table.replace(/dark:bg-gray-800/g, 'dark:bg-zinc-900'),
75
+ header: base.header
76
+ .replace(/dark:bg-gray-700/g, 'dark:bg-zinc-800')
77
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700'),
78
+ headerCell: base.headerCell
79
+ .replace(/dark:text-gray-400/g, 'dark:text-zinc-400')
80
+ .replace(/dark:bg-gray-700/g, 'dark:bg-zinc-800'),
81
+ row: base.row
82
+ .replace(/dark:bg-gray-800/g, 'dark:bg-zinc-900')
83
+ .replace(/dark:hover:bg-gray-700/g, 'dark:hover:bg-zinc-800'),
84
+ cell: base.cell
85
+ .replace(/dark:text-gray-100/g, 'dark:text-zinc-100')
86
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700'),
87
+ selectedRow: base.selectedRow.replace(/dark:bg-blue-900\/20/g, 'dark:bg-blue-900/20'),
88
+ searchInput: base.searchInput
89
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700')
90
+ .replace(/dark:bg-gray-800/g, 'dark:bg-zinc-800')
91
+ .replace(/dark:text-gray-100/g, 'dark:text-zinc-100')
92
+ .replace(/dark:placeholder-gray-400/g, 'dark:placeholder-zinc-500'),
93
+ select: base.select
94
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700')
95
+ .replace(/dark:bg-gray-800/g, 'dark:bg-zinc-800')
96
+ .replace(/dark:text-gray-100/g, 'dark:text-zinc-100'),
97
+ buttonSecondary: base.buttonSecondary
98
+ .replace(/dark:bg-gray-700/g, 'dark:bg-zinc-800')
99
+ .replace(/dark:text-gray-300/g, 'dark:text-zinc-300')
100
+ .replace(/dark:hover:bg-gray-600/g, 'dark:hover:bg-zinc-700'),
101
+ text: 'text-gray-700 dark:text-zinc-300',
102
+ textMuted: 'text-gray-500 dark:text-zinc-500',
103
+ pagination: base.pagination
104
+ .replace(/dark:bg-gray-900/g, 'dark:bg-zinc-900')
105
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700'),
106
+ paginationButton: base.paginationButton
107
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700')
108
+ .replace(/dark:bg-gray-800/g, 'dark:bg-zinc-800')
109
+ .replace(/dark:text-gray-300/g, 'dark:text-zinc-300')
110
+ .replace(/dark:hover:bg-gray-700/g, 'dark:hover:bg-zinc-700'),
111
+ paginationText: 'text-sm text-gray-700 dark:text-zinc-300',
112
+ loadingSkeleton: 'animate-pulse bg-gray-200 dark:bg-zinc-700 rounded',
113
+ emptyState: 'text-gray-500 dark:text-zinc-400',
114
+ filterDropdown: base.filterDropdown
115
+ .replace(/dark:bg-gray-800/g, 'dark:bg-zinc-800')
116
+ .replace(/dark:border-gray-600/g, 'dark:border-zinc-700'),
117
+ };
31
118
  };
@@ -1,4 +1,5 @@
1
1
  import { ReactNode, HTMLAttributes } from 'react';
2
+ import { Theme } from '../themes';
2
3
  export interface BaseRowData {
3
4
  id?: string | number;
4
5
  [key: string]: any;
@@ -162,6 +163,26 @@ export interface DataGridProps<T = BaseRowData> extends Omit<HTMLAttributes<HTML
162
163
  className?: string;
163
164
  variant?: 'default' | 'striped' | 'bordered';
164
165
  size?: 'sm' | 'md' | 'lg';
166
+ /**
167
+ * Custom theme overrides. Merges with the variant theme.
168
+ * Use to customize colors, borders, backgrounds, etc.
169
+ *
170
+ * @example
171
+ * // Override specific properties
172
+ * <DataGrid
173
+ * data={data}
174
+ * theme={{
175
+ * container: 'bg-white dark:bg-zinc-900 rounded-lg border border-zinc-700',
176
+ * row: 'bg-white dark:bg-zinc-900 hover:bg-zinc-50 dark:hover:bg-zinc-800',
177
+ * }}
178
+ * />
179
+ *
180
+ * @example
181
+ * // Use createZincTheme for full dark mode compatibility
182
+ * import { createZincTheme } from '@reactorui/datagrid';
183
+ * <DataGrid data={data} theme={createZincTheme('default')} />
184
+ */
185
+ theme?: Partial<Theme>;
165
186
  onPageChange?: OnPageChangeCallback;
166
187
  onPageSizeChange?: OnPageSizeChangeCallback;
167
188
  onSortChange?: OnSortChangeCallback;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactorui/datagrid",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
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",