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