@snowpact/react-tanstack-query-table 1.3.0 → 1.4.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 +183 -224
- package/dist/index.cjs +14 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -14
- package/dist/index.js +1999 -1981
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,49 +8,84 @@ Ultra-light, registry-based data table for React + TanStack Table + TanStack Que
|
|
|
8
8
|
- **Registry-based**: Inject your own i18n, Link component, confirmation dialogs
|
|
9
9
|
- **TypeScript**: Full type support with generics
|
|
10
10
|
- **Two modes**: Client-side and Server-side pagination/filtering/sorting
|
|
11
|
-
- **Customizable**: Override styles via registry
|
|
11
|
+
- **Customizable**: Override styles via CSS variables or registry
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Quick Setup
|
|
14
|
+
|
|
15
|
+
### 1. Install
|
|
14
16
|
|
|
15
17
|
```bash
|
|
18
|
+
npm install @tanstack/react-query @tanstack/react-table
|
|
16
19
|
npm install @snowpact/react-tanstack-query-table
|
|
17
|
-
# or
|
|
18
|
-
pnpm add @snowpact/react-tanstack-query-table
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
###
|
|
22
|
+
### 2. Import styles
|
|
22
23
|
|
|
23
|
-
```
|
|
24
|
-
|
|
24
|
+
```tsx
|
|
25
|
+
// In your app entry point (main.tsx or App.tsx)
|
|
26
|
+
import '@snowpact/react-tanstack-query-table/styles.css';
|
|
25
27
|
```
|
|
26
28
|
|
|
27
|
-
###
|
|
29
|
+
### 3. Setup once
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { setupSnowTable } from '@snowpact/react-tanstack-query-table';
|
|
33
|
+
import { Link } from 'react-router-dom';
|
|
34
|
+
|
|
35
|
+
// Your translation function (or just return the key)
|
|
36
|
+
const t = (key: string) => translations[key] || key;
|
|
37
|
+
|
|
38
|
+
setupSnowTable({
|
|
39
|
+
t,
|
|
40
|
+
LinkComponent: Link,
|
|
41
|
+
confirm: ({ title }) => window.confirm(title),
|
|
42
|
+
});
|
|
43
|
+
```
|
|
28
44
|
|
|
29
|
-
|
|
45
|
+
### 4. Use the table
|
|
30
46
|
|
|
31
47
|
```tsx
|
|
32
|
-
import '@snowpact/react-tanstack-query-table
|
|
48
|
+
import { SnowClientDataTable, SnowColumnConfig } from '@snowpact/react-tanstack-query-table';
|
|
49
|
+
|
|
50
|
+
type User = { id: string; name: string; email: string; status: string };
|
|
51
|
+
|
|
52
|
+
const columns: SnowColumnConfig<User>[] = [
|
|
53
|
+
{ key: 'name', label: 'Name' },
|
|
54
|
+
{ key: 'email', label: 'Email' },
|
|
55
|
+
{ key: 'status', label: 'Status' },
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
<SnowClientDataTable
|
|
59
|
+
queryKey={['users']}
|
|
60
|
+
fetchAllItemsEndpoint={() => fetchUsers()}
|
|
61
|
+
columnConfig={columns}
|
|
62
|
+
enableGlobalSearch
|
|
63
|
+
enablePagination
|
|
64
|
+
/>
|
|
33
65
|
```
|
|
34
66
|
|
|
35
|
-
|
|
67
|
+
That's it! You have a working data table.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Advanced Configuration
|
|
72
|
+
|
|
73
|
+
### Theme Customization
|
|
36
74
|
|
|
37
|
-
|
|
75
|
+
Override CSS variables to match your design:
|
|
38
76
|
|
|
39
77
|
```css
|
|
40
78
|
:root {
|
|
41
|
-
--snow-background: #ffffff;
|
|
42
|
-
--snow-foreground: #0a0a0a;
|
|
43
|
-
--snow-secondary: #f5f5f5;
|
|
44
|
-
--snow-secondary-foreground: #737373;
|
|
45
|
-
--snow-border: #d4d4d4;
|
|
46
|
-
--snow-ring: #a3a3a3;
|
|
47
|
-
--snow-radius: 0.375rem;
|
|
79
|
+
--snow-background: #ffffff;
|
|
80
|
+
--snow-foreground: #0a0a0a;
|
|
81
|
+
--snow-secondary: #f5f5f5;
|
|
82
|
+
--snow-secondary-foreground: #737373;
|
|
83
|
+
--snow-border: #d4d4d4;
|
|
84
|
+
--snow-ring: #a3a3a3;
|
|
85
|
+
--snow-radius: 0.375rem;
|
|
48
86
|
}
|
|
49
|
-
```
|
|
50
87
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```css
|
|
88
|
+
/* Dark mode */
|
|
54
89
|
.dark {
|
|
55
90
|
--snow-background: #1a1a2e;
|
|
56
91
|
--snow-foreground: #eaeaea;
|
|
@@ -61,73 +96,100 @@ You can customize the library appearance by overriding CSS variables:
|
|
|
61
96
|
}
|
|
62
97
|
```
|
|
63
98
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### 1. Setup (once in your app)
|
|
99
|
+
### Setup with i18n (react-i18next)
|
|
67
100
|
|
|
68
101
|
```tsx
|
|
69
|
-
// Import styles first
|
|
70
|
-
import '@snowpact/react-tanstack-query-table/styles.css';
|
|
71
|
-
|
|
72
|
-
import { setupSnowTable } from '@snowpact/react-tanstack-query-table';
|
|
73
102
|
import { useTranslation } from 'react-i18next';
|
|
74
|
-
|
|
75
|
-
|
|
103
|
+
|
|
104
|
+
// Get t function at module level or use a hook wrapper
|
|
105
|
+
const { t } = i18n;
|
|
76
106
|
|
|
77
107
|
setupSnowTable({
|
|
78
|
-
|
|
108
|
+
t: (key) => t(key),
|
|
79
109
|
LinkComponent: Link,
|
|
80
|
-
|
|
110
|
+
confirm: ({ title, content }) => {
|
|
111
|
+
const message = typeof content === 'string' ? `${title}\n\n${content}` : title;
|
|
112
|
+
return window.confirm(message);
|
|
113
|
+
},
|
|
81
114
|
});
|
|
82
115
|
```
|
|
83
116
|
|
|
84
|
-
|
|
117
|
+
Required translation keys:
|
|
118
|
+
- `dataTable.search` - Search placeholder
|
|
119
|
+
- `dataTable.elements` - "elements" label
|
|
120
|
+
- `dataTable.searchEmpty` - Empty state text
|
|
121
|
+
- `dataTable.resetFilters` - Reset button tooltip
|
|
122
|
+
- `dataTable.columns` - Columns button label
|
|
85
123
|
|
|
86
|
-
###
|
|
124
|
+
### Setup with custom confirm dialog
|
|
87
125
|
|
|
88
126
|
```tsx
|
|
89
|
-
import {
|
|
90
|
-
import { Edit, Trash } from 'lucide-react';
|
|
127
|
+
import { useConfirmDialog } from './your-confirm-hook';
|
|
91
128
|
|
|
92
|
-
|
|
129
|
+
// If you have a hook-based confirm dialog
|
|
130
|
+
const confirmDialog = useConfirmDialog();
|
|
93
131
|
|
|
94
|
-
|
|
132
|
+
setupSnowTable({
|
|
133
|
+
t,
|
|
134
|
+
LinkComponent: Link,
|
|
135
|
+
confirm: async ({ title, content, confirmText, cancelText }) => {
|
|
136
|
+
return confirmDialog.open({
|
|
137
|
+
title,
|
|
138
|
+
description: content,
|
|
139
|
+
confirmLabel: confirmText,
|
|
140
|
+
cancelLabel: cancelText,
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
```
|
|
95
145
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
146
|
+
### Override component styles (rare)
|
|
147
|
+
|
|
148
|
+
For deep customization, override internal Tailwind classes:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
setupSnowTable({
|
|
152
|
+
t,
|
|
153
|
+
LinkComponent: Link,
|
|
154
|
+
confirm: ({ title }) => window.confirm(title),
|
|
155
|
+
styles: {
|
|
156
|
+
button: {
|
|
157
|
+
visual: 'rounded-full bg-primary text-primary-foreground',
|
|
158
|
+
hover: 'hover:bg-primary/90',
|
|
159
|
+
},
|
|
160
|
+
table: {
|
|
161
|
+
header: 'bg-slate-100 dark:bg-slate-800',
|
|
162
|
+
rowHover: 'hover:bg-slate-50',
|
|
163
|
+
},
|
|
164
|
+
input: 'rounded-full border-2 border-primary',
|
|
165
|
+
},
|
|
166
|
+
});
|
|
107
167
|
```
|
|
108
168
|
|
|
169
|
+
---
|
|
170
|
+
|
|
109
171
|
## Client vs Server Mode
|
|
110
172
|
|
|
111
|
-
| Mode | Component
|
|
112
|
-
| ---------- |
|
|
113
|
-
| **Client** | `SnowClientDataTable` | < 5,000 items | All data loaded, filtered/sorted locally
|
|
114
|
-
| **Server** | `SnowServerDataTable` | > 5,000 items |
|
|
173
|
+
| Mode | Component | Use case | Data handling |
|
|
174
|
+
| ---------- | --------------------- | ------------- | ---------------------------------------- |
|
|
175
|
+
| **Client** | `SnowClientDataTable` | < 5,000 items | All data loaded, filtered/sorted locally |
|
|
176
|
+
| **Server** | `SnowServerDataTable` | > 5,000 items | Server handles pagination/filtering |
|
|
115
177
|
|
|
116
178
|
### SnowClientDataTable
|
|
117
179
|
|
|
118
|
-
|
|
180
|
+
Fetches all data once, handles everything in the browser:
|
|
119
181
|
|
|
120
182
|
```tsx
|
|
121
183
|
<SnowClientDataTable
|
|
122
184
|
queryKey={['users']}
|
|
123
|
-
fetchAllItemsEndpoint={() => api.getUsers()}
|
|
185
|
+
fetchAllItemsEndpoint={() => api.getUsers()}
|
|
124
186
|
columnConfig={columns}
|
|
125
187
|
/>
|
|
126
188
|
```
|
|
127
189
|
|
|
128
190
|
### SnowServerDataTable
|
|
129
191
|
|
|
130
|
-
|
|
192
|
+
Server handles pagination, search, filtering, and sorting:
|
|
131
193
|
|
|
132
194
|
```tsx
|
|
133
195
|
import { SnowServerDataTable, ServerFetchParams } from '@snowpact/react-tanstack-query-table';
|
|
@@ -141,21 +203,25 @@ const fetchUsers = async (params: ServerFetchParams) => {
|
|
|
141
203
|
};
|
|
142
204
|
};
|
|
143
205
|
|
|
144
|
-
<SnowServerDataTable
|
|
206
|
+
<SnowServerDataTable
|
|
207
|
+
queryKey={['users']}
|
|
208
|
+
fetchServerEndpoint={fetchUsers}
|
|
209
|
+
columnConfig={columns}
|
|
210
|
+
/>
|
|
145
211
|
```
|
|
146
212
|
|
|
213
|
+
---
|
|
214
|
+
|
|
147
215
|
## Actions
|
|
148
216
|
|
|
149
|
-
Actions appear as buttons in each row
|
|
217
|
+
Actions appear as buttons in each row:
|
|
150
218
|
|
|
151
219
|
### Click Action
|
|
152
220
|
|
|
153
|
-
Simple callback when clicked.
|
|
154
|
-
|
|
155
221
|
```tsx
|
|
156
222
|
{
|
|
157
223
|
type: 'click',
|
|
158
|
-
icon:
|
|
224
|
+
icon: EditIcon,
|
|
159
225
|
label: 'Edit',
|
|
160
226
|
onClick: (item) => openEditModal(item),
|
|
161
227
|
}
|
|
@@ -163,12 +229,10 @@ Simple callback when clicked.
|
|
|
163
229
|
|
|
164
230
|
### Link Action
|
|
165
231
|
|
|
166
|
-
Navigates to a URL. Uses your registered `LinkComponent`.
|
|
167
|
-
|
|
168
232
|
```tsx
|
|
169
233
|
{
|
|
170
234
|
type: 'link',
|
|
171
|
-
icon:
|
|
235
|
+
icon: EyeIcon,
|
|
172
236
|
label: 'View',
|
|
173
237
|
href: (item) => `/users/${item.id}`,
|
|
174
238
|
external: false, // true for target="_blank"
|
|
@@ -177,123 +241,57 @@ Navigates to a URL. Uses your registered `LinkComponent`.
|
|
|
177
241
|
|
|
178
242
|
### Endpoint Action
|
|
179
243
|
|
|
180
|
-
Calls an async endpoint (API mutation). Integrates with React Query invalidation.
|
|
181
|
-
|
|
182
|
-
```tsx
|
|
183
|
-
{
|
|
184
|
-
type: 'endpoint',
|
|
185
|
-
icon: Trash,
|
|
186
|
-
label: 'Delete',
|
|
187
|
-
endpoint: (item) => api.deleteUser(item.id),
|
|
188
|
-
onSuccess: () => queryClient.invalidateQueries(['users']),
|
|
189
|
-
onError: (error) => toast.error(error.message),
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Confirmation Dialog
|
|
194
|
-
|
|
195
|
-
Any action can require confirmation before executing:
|
|
196
|
-
|
|
197
244
|
```tsx
|
|
198
245
|
{
|
|
199
246
|
type: 'endpoint',
|
|
200
|
-
icon:
|
|
247
|
+
icon: TrashIcon,
|
|
201
248
|
label: 'Delete',
|
|
202
249
|
variant: 'danger',
|
|
203
250
|
endpoint: (item) => api.deleteUser(item.id),
|
|
251
|
+
onSuccess: () => queryClient.invalidateQueries(['users']),
|
|
204
252
|
confirm: {
|
|
205
253
|
title: 'Delete user?',
|
|
206
254
|
content: 'This action cannot be undone.',
|
|
207
|
-
confirmText: 'Delete',
|
|
208
|
-
cancelText: 'Cancel',
|
|
209
|
-
},
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
For forms inside confirm dialogs, use a function to access the `close` helper:
|
|
214
|
-
|
|
215
|
-
```tsx
|
|
216
|
-
{
|
|
217
|
-
type: 'click',
|
|
218
|
-
icon: Edit,
|
|
219
|
-
label: 'Change Status',
|
|
220
|
-
onClick: () => {},
|
|
221
|
-
confirm: {
|
|
222
|
-
title: 'Change Status',
|
|
223
|
-
hideButtons: true, // Form handles its own buttons
|
|
224
|
-
content: ({ close }) => (
|
|
225
|
-
<StatusForm
|
|
226
|
-
onSuccess={() => {
|
|
227
|
-
queryClient.invalidateQueries(['users']);
|
|
228
|
-
close();
|
|
229
|
-
}}
|
|
230
|
-
/>
|
|
231
|
-
),
|
|
232
255
|
},
|
|
233
256
|
}
|
|
234
257
|
```
|
|
235
258
|
|
|
236
|
-
### Action Options
|
|
237
|
-
|
|
238
|
-
| Option | Type | Description |
|
|
239
|
-
| ----------- | ----------------------------------------------------------- | ---------------------------------------- |
|
|
240
|
-
| `icon` | `ComponentType<SVGProps>` | Icon component (lucide-react or any SVG) |
|
|
241
|
-
| `label` | `string` | Button label (used for tooltip) |
|
|
242
|
-
| `variant` | `'default' \| 'danger' \| 'warning' \| 'info' \| 'success'` | Button color variant |
|
|
243
|
-
| `display` | `'button' \| 'dropdown'` | Show as button or in dropdown menu |
|
|
244
|
-
| `hidden` | `boolean` | Conditionally hide the action |
|
|
245
|
-
| `disabled` | `boolean` | Disable the action |
|
|
246
|
-
| `showLabel` | `boolean` | Show label text next to icon |
|
|
247
|
-
|
|
248
259
|
### Dynamic Actions
|
|
249
260
|
|
|
250
|
-
Actions can be functions that return the action config, allowing per-row customization:
|
|
251
|
-
|
|
252
261
|
```tsx
|
|
253
262
|
actions={[
|
|
254
263
|
(item) => ({
|
|
255
264
|
type: 'click',
|
|
256
|
-
icon: item.isActive ?
|
|
265
|
+
icon: item.isActive ? PauseIcon : PlayIcon,
|
|
257
266
|
label: item.isActive ? 'Deactivate' : 'Activate',
|
|
258
267
|
onClick: () => toggleStatus(item),
|
|
259
|
-
hidden: item.role === 'admin',
|
|
268
|
+
hidden: item.role === 'admin',
|
|
260
269
|
}),
|
|
261
270
|
]}
|
|
262
271
|
```
|
|
263
272
|
|
|
264
|
-
|
|
273
|
+
---
|
|
265
274
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
Enable fuzzy search across all columns:
|
|
269
|
-
|
|
270
|
-
```tsx
|
|
271
|
-
<SnowClientDataTable enableGlobalSearch texts={{ searchPlaceholder: 'Search users...' }} />
|
|
272
|
-
```
|
|
275
|
+
## Filters
|
|
273
276
|
|
|
274
|
-
|
|
277
|
+
### Global Search
|
|
275
278
|
|
|
276
279
|
```tsx
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
render: item => `${item.firstName} ${item.lastName}`,
|
|
282
|
-
searchableValue: item => `${item.firstName} ${item.lastName}`,
|
|
283
|
-
},
|
|
284
|
-
];
|
|
280
|
+
<SnowClientDataTable
|
|
281
|
+
enableGlobalSearch
|
|
282
|
+
texts={{ searchPlaceholder: 'Search users...' }}
|
|
283
|
+
/>
|
|
285
284
|
```
|
|
286
285
|
|
|
287
286
|
### Column Filters
|
|
288
287
|
|
|
289
|
-
Multi-select dropdown filters:
|
|
290
|
-
|
|
291
288
|
```tsx
|
|
292
289
|
<SnowClientDataTable
|
|
293
290
|
filters={[
|
|
294
291
|
{
|
|
295
292
|
key: 'status',
|
|
296
293
|
label: 'Status',
|
|
294
|
+
multipleSelection: true, // Allow multiple values
|
|
297
295
|
options: [
|
|
298
296
|
{ value: 'active', label: 'Active' },
|
|
299
297
|
{ value: 'inactive', label: 'Inactive' },
|
|
@@ -313,14 +311,11 @@ Multi-select dropdown filters:
|
|
|
313
311
|
|
|
314
312
|
### Prefilters (Tabs)
|
|
315
313
|
|
|
316
|
-
Quick segmentation via tabs:
|
|
317
|
-
|
|
318
314
|
```tsx
|
|
319
315
|
<SnowClientDataTable
|
|
320
316
|
prefilters={[
|
|
321
317
|
{ id: 'all', label: 'All' },
|
|
322
318
|
{ id: 'active', label: 'Active' },
|
|
323
|
-
{ id: 'archived', label: 'Archived' },
|
|
324
319
|
]}
|
|
325
320
|
prefilterFn={(item, prefilterId) => {
|
|
326
321
|
if (prefilterId === 'all') return true;
|
|
@@ -329,72 +324,37 @@ Quick segmentation via tabs:
|
|
|
329
324
|
/>
|
|
330
325
|
```
|
|
331
326
|
|
|
332
|
-
|
|
327
|
+
---
|
|
333
328
|
|
|
334
|
-
##
|
|
329
|
+
## Other Features
|
|
335
330
|
|
|
336
|
-
###
|
|
337
|
-
|
|
338
|
-
Users can show/hide columns via a settings button. Configuration is saved in cookies.
|
|
331
|
+
### URL State Persistence
|
|
339
332
|
|
|
340
333
|
```tsx
|
|
341
|
-
<SnowClientDataTable
|
|
342
|
-
enableColumnConfiguration
|
|
343
|
-
columnConfig={[
|
|
344
|
-
{ key: 'name' }, // Always visible
|
|
345
|
-
{ key: 'email' },
|
|
346
|
-
{ key: 'details', meta: { defaultHidden: true } }, // Hidden by default
|
|
347
|
-
]}
|
|
348
|
-
/>
|
|
334
|
+
<SnowClientDataTable persistState />
|
|
349
335
|
```
|
|
350
336
|
|
|
351
|
-
|
|
337
|
+
Saves pagination, search, filters, and sorting in URL params.
|
|
352
338
|
|
|
353
|
-
|
|
339
|
+
### Column Configuration
|
|
354
340
|
|
|
355
341
|
```tsx
|
|
356
342
|
<SnowClientDataTable
|
|
357
|
-
|
|
343
|
+
enableColumnConfiguration
|
|
344
|
+
columnConfig={[
|
|
345
|
+
{ key: 'name' },
|
|
346
|
+
{ key: 'details', meta: { defaultHidden: true } },
|
|
347
|
+
]}
|
|
358
348
|
/>
|
|
359
349
|
```
|
|
360
350
|
|
|
361
|
-
URL params used:
|
|
362
|
-
|
|
363
|
-
- `dt_page`, `dt_pageSize` - Pagination
|
|
364
|
-
- `dt_search` - Search query
|
|
365
|
-
- `dt_prefilter` - Active prefilter
|
|
366
|
-
- `dt_filters` - Column filters
|
|
367
|
-
- `dt_sortBy`, `dt_sortDesc` - Sorting
|
|
368
|
-
|
|
369
|
-
### Column Meta Properties
|
|
370
|
-
|
|
371
|
-
```tsx
|
|
372
|
-
{
|
|
373
|
-
key: 'actions',
|
|
374
|
-
meta: {
|
|
375
|
-
width: '100px', // Fixed width
|
|
376
|
-
minWidth: '80px', // Minimum width
|
|
377
|
-
center: true, // Center content
|
|
378
|
-
defaultHidden: true, // Hidden by default
|
|
379
|
-
disableColumnClick: true, // Disable row click for this column
|
|
380
|
-
},
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
351
|
### Sorting
|
|
385
352
|
|
|
386
|
-
```tsx
|
|
387
|
-
<SnowClientDataTable enableSorting defaultSortBy="createdAt" defaultSortOrder="desc" />
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### Pagination
|
|
391
|
-
|
|
392
353
|
```tsx
|
|
393
354
|
<SnowClientDataTable
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
enableElementLabel // Show element label
|
|
355
|
+
enableSorting
|
|
356
|
+
defaultSortBy="createdAt"
|
|
357
|
+
defaultSortOrder="desc"
|
|
398
358
|
/>
|
|
399
359
|
```
|
|
400
360
|
|
|
@@ -402,35 +362,35 @@ URL params used:
|
|
|
402
362
|
|
|
403
363
|
```tsx
|
|
404
364
|
<SnowClientDataTable
|
|
405
|
-
onRowClick={item => navigate(`/users/${item.id}`)}
|
|
406
|
-
activeRowId={selectedUserId}
|
|
365
|
+
onRowClick={(item) => navigate(`/users/${item.id}`)}
|
|
366
|
+
activeRowId={selectedUserId}
|
|
407
367
|
/>
|
|
408
368
|
```
|
|
409
369
|
|
|
410
|
-
### Custom
|
|
411
|
-
|
|
412
|
-
Override default Tailwind classes via the registry:
|
|
370
|
+
### Custom Column Rendering
|
|
413
371
|
|
|
414
372
|
```tsx
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
hover: 'hover:bg-blue-600',
|
|
426
|
-
},
|
|
373
|
+
const columns: SnowColumnConfig<User>[] = [
|
|
374
|
+
{ key: 'name', label: 'Name' },
|
|
375
|
+
{
|
|
376
|
+
key: 'status',
|
|
377
|
+
label: 'Status',
|
|
378
|
+
render: (item) => (
|
|
379
|
+
<span className={item.status === 'active' ? 'text-green-500' : 'text-red-500'}>
|
|
380
|
+
{item.status}
|
|
381
|
+
</span>
|
|
382
|
+
),
|
|
427
383
|
},
|
|
428
|
-
|
|
384
|
+
{
|
|
385
|
+
key: '_extra_fullName', // Use _extra_ prefix for computed columns
|
|
386
|
+
label: 'Full Name',
|
|
387
|
+
render: (item) => `${item.firstName} ${item.lastName}`,
|
|
388
|
+
searchableValue: (item) => `${item.firstName} ${item.lastName}`,
|
|
389
|
+
},
|
|
390
|
+
];
|
|
429
391
|
```
|
|
430
392
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
Action buttons automatically display tooltips on hover. The tooltip uses your theme's CSS variables (`--snow-foreground`, `--snow-background`, `--snow-radius`) for consistent styling.
|
|
393
|
+
---
|
|
434
394
|
|
|
435
395
|
## API Reference
|
|
436
396
|
|
|
@@ -441,23 +401,22 @@ Action buttons automatically display tooltips on hover. The tooltip uses your th
|
|
|
441
401
|
| `queryKey` | `string[]` | Required | React Query cache key |
|
|
442
402
|
| `fetchAllItemsEndpoint` | `() => Promise<T[]>` | Required | Data fetching function |
|
|
443
403
|
| `columnConfig` | `SnowColumnConfig<T>[]` | Required | Column definitions |
|
|
444
|
-
| `actions` | `TableAction<T>[]` |
|
|
445
|
-
| `filters` | `FilterConfig<T>[]` |
|
|
446
|
-
| `prefilters` | `PreFilter[]` |
|
|
404
|
+
| `actions` | `TableAction<T>[]` | - | Row actions |
|
|
405
|
+
| `filters` | `FilterConfig<T>[]` | - | Column filters |
|
|
406
|
+
| `prefilters` | `PreFilter[]` | - | Tab filters |
|
|
447
407
|
| `prefilterFn` | `(item, id) => boolean` | - | Client-side prefilter logic |
|
|
448
408
|
| `persistState` | `boolean` | `false` | Persist state in URL |
|
|
449
409
|
| `enableGlobalSearch` | `boolean` | `false` | Enable search bar |
|
|
450
|
-
| `enablePagination` | `boolean` | `
|
|
451
|
-
| `enableSorting` | `boolean` | `
|
|
410
|
+
| `enablePagination` | `boolean` | `true` | Enable pagination |
|
|
411
|
+
| `enableSorting` | `boolean` | `true` | Enable column sorting |
|
|
452
412
|
| `enableColumnConfiguration` | `boolean` | `false` | Enable column visibility toggle |
|
|
453
|
-
| `enableResetFilters` | `boolean` | `false` | Show reset filters button |
|
|
454
413
|
| `defaultPageSize` | `number` | `10` | Initial page size |
|
|
455
414
|
| `defaultSortBy` | `string` | - | Initial sort column |
|
|
456
415
|
| `defaultSortOrder` | `'asc' \| 'desc'` | `'asc'` | Initial sort direction |
|
|
457
416
|
|
|
458
417
|
### SnowServerDataTable Props
|
|
459
418
|
|
|
460
|
-
Same as `SnowClientDataTable`,
|
|
419
|
+
Same as `SnowClientDataTable`, plus:
|
|
461
420
|
|
|
462
421
|
| Prop | Type | Description |
|
|
463
422
|
| --------------------- | -------------------------------------------------------------------- | ------------------------ |
|