antd-crud-table 0.0.11 โ†’ 0.0.13

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
@@ -2,24 +2,86 @@
2
2
 
3
3
  # ๐Ÿงฉ `antd-crud-table` โ€“ A Dynamic React Table Generator with Forms ๐Ÿš€
4
4
 
5
- `CrudTable` is a highly flexible and powerful React component built using `antd` and `@ant-design/pro-components`. It provides a declarative way to render editable, paginated tables with form support, data fetching, sorting, filtering, and custom rendering. Perfect for building admin dashboards and data management UIs with minimal boilerplate.
5
+ `antd-crud-table` is a highly flexible and powerful React library built using `antd` and `@ant-design/pro-components`. It provides both a declarative component-based approach and a modern hook-based architecture for creating editable, paginated tables with form support, data fetching, sorting, filtering, and custom rendering. Perfect for building admin dashboards and data management UIs with minimal boilerplate.
6
+
7
+ ## ๐Ÿ†• Enhanced ๐Ÿ“‹ API Reference
8
+
9
+ ### CrudTableExperimental Props (Enhanced)
10
+
11
+ | Prop | Type | Description |
12
+ |------|------|-------------|
13
+ | `title` | `string` | Table header title |
14
+ | `rowKey` | `keyof T` | Unique identifier for each row |
15
+ | `columns` | `CrudColumn<T>[]` | Column definitions with enhanced features |
16
+ | `hookConfig` | `UseCrudTableConfig<T>` | Hook configuration for data operations |
17
+ | `defaultPageSize?` | `number` | Initial page size (default: 10) |
18
+ | `enableBulkOperations?` | `boolean` | Enable bulk select/delete (default: false) |
19
+ | `customActions?` | `(record, actions) => ReactNode[]` | Custom row actions |ased Architecture**
20
+
21
+ The experimental version introduces a powerful hook-based architecture with multiple data source strategies:
22
+ - **Static Data**: Perfect for prototypes and small datasets
23
+ - **API Integration**: REST API support with automatic request handling
24
+ - **Custom Operations**: Full control with GraphQL, IndexedDB, or custom logic
25
+ - **Built-in State Management**: Loading states, error handling, optimistic updates
6
26
 
7
27
  ---
8
28
 
9
29
  ## ๐Ÿ“ฆ Installation
10
30
 
11
- Install dependencies with:
12
-
13
31
  ```bash
14
32
  npm install antd-crud-table
15
33
  ```
16
34
 
35
+ **Peer Dependencies:**
36
+ ```bash
37
+ npm install react react-dom antd @ant-design/pro-components
38
+ ```
39
+
17
40
  ---
18
41
 
19
- ## โš™๏ธ Usage Example
42
+ ## ๐Ÿš€ Quick Start
43
+
44
+ Choose your preferred approach:
45
+
46
+ ### Modern Approach (Experimental) - Hook-Based
20
47
 
21
48
  ```tsx
22
- import CrudTable, { CrudTableConfig } from 'antd-crud-table';
49
+ import { CrudTableExperimental } from 'antd-crud-table';
50
+
51
+ // Static data example
52
+ const UserManagement = () => (
53
+ <CrudTableExperimental<User>
54
+ title="User Management"
55
+ rowKey="id"
56
+ hookConfig={{
57
+ staticData: users, // Your data array
58
+ optimisticUpdates: true,
59
+ }}
60
+ columns={[
61
+ {
62
+ title: 'Name',
63
+ dataIndex: 'name',
64
+ fieldType: 'string',
65
+ formConfig: { required: true },
66
+ },
67
+ {
68
+ title: 'Status',
69
+ dataIndex: 'status',
70
+ fieldType: 'enum',
71
+ enumOptions: {
72
+ active: { text: 'Active', color: 'green' },
73
+ inactive: { text: 'Inactive', color: 'orange' },
74
+ },
75
+ },
76
+ ]}
77
+ />
78
+ );
79
+ ```
80
+
81
+ ### Classic Approach (Original) - Service-Based
82
+
83
+ ```tsx
84
+ import { CrudTable } from 'antd-crud-table';
23
85
 
24
86
  const userService = {
25
87
  getList: async () => ({ data: [], total: 0 }),
@@ -28,73 +90,523 @@ const userService = {
28
90
  delete: async (id) => {},
29
91
  };
30
92
 
31
- const config: CrudTableConfig<any> = {
32
- title: 'User Management',
33
- rowKey: 'id',
34
- service: userService,
35
- columns: [
36
- {
37
- title: 'Name',
38
- dataIndex: 'name',
39
- fieldType: 'string',
40
- fieldEditable: true,
41
- formConfig: { required: true },
93
+ const UserTable = () => (
94
+ <CrudTable
95
+ title="User Management"
96
+ rowKey="id"
97
+ service={userService}
98
+ columns={[
99
+ {
100
+ title: 'Name',
101
+ dataIndex: 'name',
102
+ fieldType: 'string',
103
+ fieldEditable: true,
104
+ formConfig: { required: true },
105
+ },
106
+ ]}
107
+ />
108
+ );
109
+ ```
110
+
111
+ ---
112
+
113
+ ## ๐ŸŽฏ **Enhanced Features (Experimental)**
114
+
115
+ ### 1. **Multiple Data Source Strategies**
116
+
117
+ #### Static Data (Perfect for Prototyping)
118
+ ```tsx
119
+ <CrudTableExperimental
120
+ hookConfig={{
121
+ staticData: mockUsers,
122
+ optimisticUpdates: true,
123
+ }}
124
+ // ... other props
125
+ />
126
+ ```
127
+
128
+ #### API Integration (Production Ready)
129
+ ```tsx
130
+ <CrudTableExperimental
131
+ hookConfig={{
132
+ api: {
133
+ baseUrl: 'https://api.example.com',
134
+ endpoints: {
135
+ list: '/users',
136
+ create: '/users',
137
+ update: '/users',
138
+ delete: '/users',
139
+ },
140
+ headers: {
141
+ 'Authorization': 'Bearer your-token',
142
+ },
143
+ transform: {
144
+ response: (data) => ({
145
+ data: data.users,
146
+ total: data.totalCount,
147
+ }),
148
+ request: (data) => ({
149
+ ...data,
150
+ updatedAt: new Date().toISOString(),
151
+ }),
152
+ },
153
+ },
154
+ onSuccess: (operation, data) => {
155
+ console.log(`${operation} completed`, data);
156
+ },
157
+ onError: (operation, error) => {
158
+ console.error(`${operation} failed`, error);
159
+ },
160
+ }}
161
+ // ... other props
162
+ />
163
+ ```
164
+
165
+ #### Custom Operations (Maximum Flexibility)
166
+ ```tsx
167
+ <CrudTableExperimental
168
+ hookConfig={{
169
+ operations: {
170
+ getList: async (params) => {
171
+ const result = await myGraphQLQuery(params);
172
+ return {
173
+ data: result.users,
174
+ total: result.totalCount,
175
+ success: true,
176
+ };
177
+ },
178
+ create: async (data) => await myCreateMutation(data),
179
+ update: async (id, data) => await myUpdateMutation(id, data),
180
+ delete: async (id) => await myDeleteMutation(id),
181
+ },
182
+ }}
183
+ // ... other props
184
+ />
185
+ ```
186
+
187
+ ### 2. **Advanced Features**
188
+
189
+ #### Bulk Operations
190
+ ```tsx
191
+ <CrudTableExperimental
192
+ enableBulkOperations={true}
193
+ // Automatically adds bulk select and delete functionality
194
+ />
195
+ ```
196
+
197
+ #### Custom Actions
198
+ ```tsx
199
+ <CrudTableExperimental
200
+ customActions={(record, actions) => [
201
+ <Button
202
+ key="export"
203
+ onClick={() => exportUser(record)}
204
+ >
205
+ Export
206
+ </Button>,
207
+ <Button
208
+ key="clone"
209
+ onClick={() => actions.create({...record, id: undefined})}
210
+ >
211
+ Clone
212
+ </Button>
213
+ ]}
214
+ />
215
+ ```
216
+
217
+ #### Enhanced Validation
218
+ ```tsx
219
+ columns={[
220
+ {
221
+ dataIndex: 'email',
222
+ title: 'Email',
223
+ fieldType: 'string',
224
+ formConfig: {
225
+ required: true,
226
+ rules: [
227
+ { required: true, message: 'Email is required' },
228
+ { type: 'email', message: 'Invalid email format' },
229
+ {
230
+ validator: async (_, value) => {
231
+ const exists = await checkEmailExists(value);
232
+ if (exists) throw new Error('Email already exists');
233
+ }
234
+ }
235
+ ],
236
+ },
237
+ },
238
+ ]}
239
+ ```
240
+
241
+ ### 3. **Custom Hooks**
242
+
243
+ Create your own specialized hooks for different use cases:
244
+
245
+ #### Example 1: useUserCrud - Specialized User Management
246
+ ```tsx
247
+ import { useCrudTable, type UseCrudTableConfig } from 'antd-crud-table';
248
+
249
+ #### Example 1: useUserCrud - Specialized User Management
250
+ ```tsx
251
+ import { useCrudTable, type UseCrudTableConfig } from 'antd-crud-table';
252
+
253
+ export const useUserCrud = (baseConfig?: Partial<UseCrudTableConfig<any>['api']>) => {
254
+ const config: UseCrudTableConfig<any> = {
255
+ api: {
256
+ baseUrl: '/api/users',
257
+ headers: {
258
+ 'Authorization': `Bearer ${localStorage.getItem('token')}`,
259
+ },
260
+ transform: {
261
+ request: (data) => ({
262
+ ...data,
263
+ // Add default values or transformations
264
+ updatedAt: new Date().toISOString(),
265
+ }),
266
+ response: (data) => ({
267
+ data: data.users || data.data || [],
268
+ total: data.total || data.count || 0,
269
+ success: true,
270
+ }),
271
+ },
272
+ ...baseConfig,
42
273
  },
43
- {
44
- title: 'Status',
45
- dataIndex: 'status',
46
- fieldType: 'enum',
47
- enumOptions: {
48
- active: { text: 'Active' },
49
- inactive: { text: 'Inactive' },
274
+ defaultPageSize: 10,
275
+ optimisticUpdates: true,
276
+ onSuccess: (operation, data) => {
277
+ console.log(`User ${operation} completed:`, data);
278
+ },
279
+ onError: (operation, error) => {
280
+ console.error(`User ${operation} failed:`, error);
281
+ // Could add toast notifications, error reporting, etc.
282
+ },
283
+ };
284
+
285
+ return useCrudTable('id', config);
286
+ };
287
+ ```
288
+
289
+ #### Example 2: useLocalStorageCrud - Local Storage Persistence
290
+ ```tsx
291
+ export const useLocalStorageCrud = <T extends Record<string, any>>(
292
+ storageKey: string,
293
+ rowKey: keyof T,
294
+ initialData: T[] = []
295
+ ) => {
296
+ const getStoredData = (): T[] => {
297
+ try {
298
+ const stored = localStorage.getItem(storageKey);
299
+ return stored ? JSON.parse(stored) : initialData;
300
+ } catch {
301
+ return initialData;
302
+ }
303
+ };
304
+
305
+ const setStoredData = (data: T[]) => {
306
+ localStorage.setItem(storageKey, JSON.stringify(data));
307
+ };
308
+
309
+ return useCrudTable(rowKey, {
310
+ operations: {
311
+ getList: async (params) => {
312
+ const data = getStoredData();
313
+ const { current = 1, pageSize = 10, ...filters } = params;
314
+
315
+ // Apply filters
316
+ let filteredData = data;
317
+ Object.entries(filters).forEach(([key, value]) => {
318
+ if (value !== undefined && value !== null && value !== '') {
319
+ filteredData = filteredData.filter(item =>
320
+ String(item[key]).toLowerCase().includes(String(value).toLowerCase())
321
+ );
322
+ }
323
+ });
324
+
325
+ // Apply pagination
326
+ const start = (current - 1) * pageSize;
327
+ const paginatedData = filteredData.slice(start, start + pageSize);
328
+
329
+ return {
330
+ data: paginatedData,
331
+ total: filteredData.length,
332
+ success: true,
333
+ };
334
+ },
335
+
336
+ create: async (newItem) => {
337
+ const data = getStoredData();
338
+ const maxId = Math.max(...data.map(item => Number(item[rowKey]) || 0), 0);
339
+ const created = {
340
+ [rowKey]: maxId + 1,
341
+ ...newItem,
342
+ createdAt: new Date().toISOString(),
343
+ } as T;
344
+
345
+ data.push(created);
346
+ setStoredData(data);
347
+ return created;
348
+ },
349
+
350
+ update: async (id, updateData) => {
351
+ const data = getStoredData();
352
+ const index = data.findIndex(item => item[rowKey] === id);
353
+ if (index === -1) throw new Error('Item not found');
354
+
355
+ data[index] = {
356
+ ...data[index],
357
+ ...updateData,
358
+ updatedAt: new Date().toISOString(),
359
+ };
360
+ setStoredData(data);
361
+ return data[index];
362
+ },
363
+
364
+ delete: async (id) => {
365
+ const data = getStoredData();
366
+ const filtered = data.filter(item => item[rowKey] !== id);
367
+ setStoredData(filtered);
50
368
  },
51
- formConfig: { required: true },
52
369
  },
53
- ],
370
+ optimisticUpdates: true,
371
+ });
54
372
  };
373
+ ```
55
374
 
56
- export default function Admin() {
57
- return <CrudTable {...config} />;
58
- }
375
+ #### Example 3: useRealtimeCrud - WebSocket Integration
376
+ ```tsx
377
+ #### Example 3: useRealtimeCrud - WebSocket Integration
378
+ ```tsx
379
+ export const useRealtimeCrud = <T extends Record<string, any>>(
380
+ rowKey: keyof T,
381
+ websocketUrl: string,
382
+ apiConfig: UseCrudTableConfig<T>['api']
383
+ ) => {
384
+ const config: UseCrudTableConfig<T> = {
385
+ api: apiConfig,
386
+ optimisticUpdates: false, // Disable optimistic updates for realtime
387
+ };
388
+
389
+ const crud = useCrudTable(rowKey, config);
390
+
391
+ // In a real implementation, you would set up WebSocket listeners here
392
+ // useEffect(() => {
393
+ // const ws = new WebSocket(websocketUrl);
394
+ //
395
+ // ws.onmessage = (event) => {
396
+ // const { type, data } = JSON.parse(event.data);
397
+ // switch (type) {
398
+ // case 'created':
399
+ // case 'updated':
400
+ // case 'deleted':
401
+ // crud.refresh(); // Refresh data when changes occur
402
+ // break;
403
+ // }
404
+ // };
405
+ //
406
+ // return () => ws.close();
407
+ // }, [websocketUrl]);
408
+
409
+ return crud;
410
+ };
59
411
  ```
60
412
 
61
- ---
413
+ #### Example 4: useInfiniteScrollCrud - Infinite Scrolling
414
+ ```tsx
415
+ #### Example 4: useInfiniteScrollCrud - Infinite Scrolling
416
+ ```tsx
417
+ export const useInfiniteScrollCrud = <T extends Record<string, any>>(
418
+ rowKey: keyof T,
419
+ baseConfig: UseCrudTableConfig<T>
420
+ ) => {
421
+ // This would extend the base hook with infinite scroll capabilities
422
+ // Implementation would handle cursor-based pagination, data accumulation, etc.
423
+
424
+ const config: UseCrudTableConfig<T> = {
425
+ ...baseConfig,
426
+ // Add infinite scroll specific configuration
427
+ };
428
+
429
+ return useCrudTable(rowKey, config);
430
+ };
431
+ ```
62
432
 
63
- ## ๐Ÿ† Features
433
+ #### Example 5: useCachedCrud - Advanced Caching
434
+ ```tsx
435
+ #### Example 5: useCachedCrud - Advanced Caching
436
+ ```tsx
437
+ export const useCachedCrud = <T extends Record<string, any>>(
438
+ rowKey: keyof T,
439
+ cacheKey: string,
440
+ baseConfig: UseCrudTableConfig<T>
441
+ ) => {
442
+ const config: UseCrudTableConfig<T> = {
443
+ ...baseConfig,
444
+ enableCache: true,
445
+ // In a real implementation, you might integrate with:
446
+ // - React Query
447
+ // - SWR
448
+ // - Redux Toolkit Query
449
+ // - Apollo Client
450
+ // etc.
451
+ };
452
+
453
+ return useCrudTable(rowKey, config);
454
+ };
455
+ };
456
+ ```
64
457
 
65
- - ๐ŸŽจ **Customizable Column Types** (`string`, `number`, `boolean`, `date`, `enum`, `custom`)
66
- - โœ… **Integrated Create/Edit Modal Form**
67
- - ๐Ÿš€ **ProTable-based Sorting, Pagination & Filtering**
68
- - ๐Ÿ” **Refetching and Action Toolbar**
69
- - ๐Ÿง  **Custom Transform & Render Logic per Field**
70
- - ๐Ÿ“† **Built-in Date/Time Formatting with `date-fns` + `dayjs`**
71
- - ๐Ÿงฐ **Typesafe Configuration with TypeScript Support**
72
- - ๐Ÿ” **Editable Field Controls (per column)**
73
- - ๐Ÿงผ **Clean, Formatted Layout with Row Differentiation Support**
458
+ #### Usage Examples
459
+ ```tsx
460
+ // Using the specialized hooks
461
+ const UserTable = () => {
462
+ const userCrud = useUserCrud();
463
+
464
+ return (
465
+ <CrudTableExperimental
466
+ title="Users"
467
+ rowKey="id"
468
+ hookConfig={userCrud}
469
+ columns={userColumns}
470
+ />
471
+ );
472
+ };
473
+
474
+ const OfflineTable = () => {
475
+ const offlineCrud = useLocalStorageCrud<User>('users-cache', 'id', mockUsers);
476
+
477
+ return (
478
+ <CrudTableExperimental
479
+ title="Offline Users"
480
+ rowKey="id"
481
+ hookConfig={offlineCrud}
482
+ columns={userColumns}
483
+ />
484
+ );
485
+ };
486
+
487
+ const RealtimeTable = () => {
488
+ const realtimeCrud = useRealtimeCrud<User>(
489
+ 'id',
490
+ 'wss://api.example.com/ws',
491
+ { baseUrl: '/api/users' }
492
+ );
493
+
494
+ return (
495
+ <CrudTableExperimental
496
+ title="Realtime Users"
497
+ rowKey="id"
498
+ hookConfig={realtimeCrud}
499
+ columns={userColumns}
500
+ />
501
+ );
502
+ };
503
+ ```
504
+
505
+ ---
506
+
507
+ ## ๐Ÿ† Complete Feature Set
508
+
509
+ ### Core Features
510
+ - ๐ŸŽจ **Multiple Column Types**: `string`, `number`, `boolean`, `date`, `enum`, `custom`
511
+ - โœ… **Integrated Create/Edit Modal Forms** with validation
512
+ - ๐Ÿš€ **ProTable Integration**: Sorting, pagination & filtering built-in
513
+ - ๐Ÿ” **Real-time Data Operations** with loading states
514
+ - ๐Ÿง  **Custom Transform & Render Logic** per field
515
+ - ๐Ÿ“† **Smart Date/Time Handling** with `date-fns` + `dayjs`
516
+ - ๐Ÿงฐ **Full TypeScript Support** with generics
517
+ - ๐Ÿ” **Field-Level Edit Controls**
518
+ - ๐Ÿงผ **Professional UI** with row differentiation
519
+
520
+ ### Enhanced Features (Experimental)
521
+ - ๐Ÿช **Hook-Based Architecture** with `useCrudTable`
522
+ - ๐Ÿ”Œ **Multiple Data Sources**: Static, API, or custom operations
523
+ - โšก **Built-in State Management**: Loading, error states, optimistic updates
524
+ - ๐Ÿ”ง **Extensible Design**: Create custom hooks for your domain
525
+ - ๐Ÿ“Š **Performance Optimized**: Caching, lazy loading, optimistic updates
526
+ - ๐ŸŽ›๏ธ **Bulk Operations**: Select and delete multiple rows
527
+ - ๐ŸŽฏ **Custom Actions**: Add your own row-level actions
528
+ - ๐Ÿ” **Advanced Search**: Configurable column-level search
529
+ - โœจ **Enhanced Validation**: Complex form validation rules
74
530
 
75
531
  ---
76
532
 
77
- ## ๐Ÿ› ๏ธ Props
533
+ ## API Reference
534
+
535
+ ### CrudTableV2 Props (Enhanced)
78
536
 
79
- ### `CrudTableConfig<T>`
80
537
  | Prop | Type | Description |
81
538
  |------|------|-------------|
82
- | `columns` | `CrudColumn<T>[]` | Column definitions including types and rendering logic |
83
- | `service` | `{ getList, create, update, delete }` | API service methods for data fetching and CRUD |
84
- | `rowKey` | `keyof T` | Unique key for each row |
85
539
  | `title` | `string` | Table header title |
86
- | `defaultPageSize?` | `number` | Optional default page size (default is 5) |
540
+ | `rowKey` | `keyof T` | Unique identifier for each row |
541
+ | `columns` | `CrudColumn<T>[]` | Column definitions with enhanced features |
542
+ | `hookConfig` | `UseCrudTableConfig<T>` | Hook configuration for data operations |
543
+ | `defaultPageSize?` | `number` | Initial page size (default: 10) |
544
+ | `enableBulkOperations?` | `boolean` | Enable bulk select/delete (default: false) |
545
+ | `customActions?` | `(record, actions) => ReactNode[]` | Custom row actions |
87
546
 
88
- ### `CrudColumn<T>`
89
- Extends `ProColumns<T>` with:
547
+ ### CrudColumn<T> (Enhanced)
90
548
 
91
549
  | Prop | Type | Description |
92
550
  |------|------|-------------|
93
- | `fieldType` | `"string" \| "number" \| "boolean" \| "date" \| "enum" \| "custom"` | Field type |
94
- | `enumOptions?` | `Record<string, { text: string }>` | Options for enum dropdown |
95
- | `formConfig?` | `{ required?: boolean, component?: ReactNode, transform?: fn }` | Form field behavior |
96
- | `fieldEditable?` | `boolean` | Whether the field is editable in form |
97
- | `customRender?` | `(value, record) => ReactNode` | Custom render function for custom fields |
551
+ | `dataIndex` | `keyof T` | Field key in your data |
552
+ | `title` | `string` | Column header text |
553
+ | `fieldType` | `FieldType` | `"string" \| "number" \| "boolean" \| "date" \| "enum" \| "custom"` |
554
+ | `fieldEditable?` | `boolean` | Whether field can be edited (default: true) |
555
+ | `searchable?` | `boolean` | Whether field appears in search (default: true) |
556
+ | `enumOptions?` | `Record<string, {text: string, color?: string}>` | Options for enum fields |
557
+ | `customRender?` | `(value, record) => ReactNode` | Custom display renderer |
558
+ | `formConfig?` | `FormConfig` | Form field configuration |
559
+
560
+ ### FormConfig
561
+
562
+ | Prop | Type | Description |
563
+ |------|------|-------------|
564
+ | `required?` | `boolean` | Whether field is required |
565
+ | `rules?` | `FormRule[]` | Ant Design validation rules |
566
+ | `component?` | `ReactNode` | Custom form component |
567
+ | `transform?` | `(value) => any` | Transform value before saving |
568
+
569
+ ### UseCrudTableConfig<T>
570
+
571
+ Choose one approach:
572
+
573
+ ```tsx
574
+ // Static data approach
575
+ {
576
+ staticData: T[];
577
+ optimisticUpdates?: boolean;
578
+ }
579
+
580
+ // API approach
581
+ {
582
+ api: {
583
+ baseUrl: string;
584
+ endpoints?: {...};
585
+ headers?: Record<string, string>;
586
+ transform?: {...};
587
+ };
588
+ }
589
+
590
+ // Custom operations approach
591
+ {
592
+ operations: {
593
+ getList: (params) => Promise<{data: T[], total: number}>;
594
+ create: (data: Partial<T>) => Promise<T>;
595
+ update: (id, data: Partial<T>) => Promise<T>;
596
+ delete: (id) => Promise<void>;
597
+ };
598
+ }
599
+ ```
600
+
601
+ ### Legacy CrudTable Props (Original)
602
+
603
+ | Prop | Type | Description |
604
+ |------|------|-------------|
605
+ | `columns` | `CrudColumn<T>[]` | Column definitions |
606
+ | `service` | `CrudService<T>` | Service object with CRUD methods |
607
+ | `rowKey` | `keyof T` | Unique key for each row |
608
+ | `title` | `string` | Table header title |
609
+ | `defaultPageSize?` | `number` | Optional default page size (default: 5) |
98
610
 
99
611
  ---
100
612
 
@@ -118,6 +630,252 @@ Customize row striping using `.row-differentiator` in `CrudTable.css`:
118
630
 
119
631
  ---
120
632
 
633
+ ## ๐Ÿ”„ Migration Guide
634
+
635
+ ### Upgrading from Original to Experimental
636
+
637
+ **Original (Service-Based):**
638
+ ```tsx
639
+ <CrudTable
640
+ title="Users"
641
+ rowKey="id"
642
+ service={UserService}
643
+ columns={columns}
644
+ />
645
+ ```
646
+
647
+ **Experimental (Hook-Based):**
648
+ ```tsx
649
+ <CrudTableExperimental
650
+ title="Users"
651
+ rowKey="id"
652
+ hookConfig={{
653
+ operations: UserService, // Reuse existing service
654
+ // Or choose new approaches:
655
+ // staticData: users,
656
+ // api: { baseUrl: '/api' },
657
+ }}
658
+ columns={columns}
659
+ />
660
+ ```
661
+
662
+ ### Breaking Changes in Experimental
663
+ - โœ… **Fully backward compatible**: Original components still work
664
+ - ๐Ÿ”„ **New import**: `CrudTableExperimental` for enhanced version
665
+ - ๐ŸŽ›๏ธ **Service โ†’ hookConfig**: More flexible configuration
666
+ - ๐Ÿ“Š **Enhanced props**: Additional optional features
667
+
668
+ ### Lazy Loading Options
669
+
670
+ For better performance with code splitting:
671
+
672
+ ```tsx
673
+ // Standard lazy loading
674
+ import { CrudTableLazy } from 'antd-crud-table';
675
+
676
+ // Experimental lazy loading
677
+ import { CrudTableExperimentalLazy } from 'antd-crud-table';
678
+
679
+ <CrudTableExperimentalLazy
680
+ title="Users"
681
+ rowKey="id"
682
+ hookConfig={hookConfig}
683
+ columns={columns}
684
+ />
685
+ ```
686
+
687
+ ---
688
+
689
+ ## ๐ŸŽจ Column Type Examples
690
+
691
+ ### String Field
692
+ ```tsx
693
+ {
694
+ dataIndex: 'name',
695
+ title: 'Full Name',
696
+ fieldType: 'string',
697
+ formConfig: {
698
+ required: true,
699
+ rules: [
700
+ { min: 2, message: 'Name must be at least 2 characters' }
701
+ ]
702
+ },
703
+ }
704
+ ```
705
+
706
+ ### Number Field
707
+ ```tsx
708
+ {
709
+ dataIndex: 'age',
710
+ title: 'Age',
711
+ fieldType: 'number',
712
+ formConfig: {
713
+ rules: [
714
+ { type: 'number', min: 0, max: 120, message: 'Invalid age' }
715
+ ]
716
+ },
717
+ }
718
+ ```
719
+
720
+ ### Date Field
721
+ ```tsx
722
+ {
723
+ dataIndex: 'createdAt',
724
+ title: 'Created Date',
725
+ fieldType: 'date',
726
+ searchable: false, // Exclude from search
727
+ }
728
+ ```
729
+
730
+ ### Boolean Field
731
+ ```tsx
732
+ {
733
+ dataIndex: 'isActive',
734
+ title: 'Active Status',
735
+ fieldType: 'boolean',
736
+ }
737
+ ```
738
+
739
+ ### Enum Field
740
+ ```tsx
741
+ {
742
+ dataIndex: 'status',
743
+ title: 'Status',
744
+ fieldType: 'enum',
745
+ enumOptions: {
746
+ active: { text: 'Active', color: 'green' },
747
+ pending: { text: 'Pending', color: 'orange' },
748
+ inactive: { text: 'Inactive', color: 'red' },
749
+ },
750
+ }
751
+ ```
752
+
753
+ ### Custom Field
754
+ ```tsx
755
+ {
756
+ dataIndex: 'customField',
757
+ title: 'Custom Display',
758
+ fieldType: 'custom',
759
+ customRender: (value, record) => (
760
+ <div>
761
+ <Avatar src={record.avatar} />
762
+ <span>{record.name}</span>
763
+ </div>
764
+ ),
765
+ formConfig: {
766
+ component: <MyCustomInput />,
767
+ },
768
+ }
769
+ ```
770
+
771
+ ---
772
+
773
+ ## ๐Ÿงช Testing
774
+
775
+ The hook-based architecture enables easy testing:
776
+
777
+ ```tsx
778
+ import { renderHook, act } from '@testing-library/react';
779
+ import { useCrudTable } from 'antd-crud-table';
780
+
781
+ test('should handle CRUD operations', async () => {
782
+ const mockData = [
783
+ { id: 1, name: 'John', age: 30 }
784
+ ];
785
+
786
+ const { result } = renderHook(() =>
787
+ useCrudTable('id', {
788
+ staticData: mockData,
789
+ })
790
+ );
791
+
792
+ await act(async () => {
793
+ const created = await result.current.create({
794
+ name: 'Jane',
795
+ age: 25
796
+ });
797
+ expect(created).toBeTruthy();
798
+ });
799
+
800
+ expect(result.current.state.data).toHaveLength(2);
801
+ });
802
+ ```
803
+
804
+ ---
805
+
806
+ ## ๐Ÿš€ Performance Tips
807
+
808
+ ### 1. **Use Static Data for Prototyping**
809
+ ```tsx
810
+ // Perfect for demos and development
811
+ hookConfig={{ staticData: mockData }}
812
+ ```
813
+
814
+ ### 2. **Enable Optimistic Updates**
815
+ ```tsx
816
+ // For better UX with reliable backends
817
+ hookConfig={{
818
+ api: {...},
819
+ optimisticUpdates: true
820
+ }}
821
+ ```
822
+
823
+ ### 3. **Implement Proper Caching**
824
+ ```tsx
825
+ // Custom hook with caching
826
+ const useUserCrud = () => {
827
+ return useCrudTable('id', {
828
+ enableCache: true,
829
+ // ... other config
830
+ });
831
+ };
832
+ ```
833
+
834
+ ### 4. **Lazy Load Components**
835
+ ```tsx
836
+ import { CrudTableLazy } from 'antd-crud-table';
837
+ // Component will be loaded when needed
838
+ ```
839
+
840
+ ---
841
+
842
+ ## ๐Ÿ”ฎ Roadmap
843
+
844
+ ### Coming Soon
845
+ - ๐ŸŒ **WebSocket Integration**: Real-time updates
846
+ - ๐Ÿ“Š **Virtual Scrolling**: Handle thousands of rows
847
+ - ๐Ÿ“ค **Export Functionality**: CSV/Excel export
848
+ - ๐ŸŽจ **Theme Support**: Multiple UI themes
849
+ - ๐Ÿ” **Advanced Filters**: Complex filtering UI
850
+ - ๐Ÿ“ฑ **Mobile Optimization**: Better mobile experience
851
+
852
+ ### Community Requests
853
+ - ๐Ÿ”ง **Plugin System**: Extensible architecture
854
+ - ๐Ÿ“ˆ **Analytics Integration**: Built-in tracking
855
+ - ๐ŸŒ **i18n Support**: Multi-language support
856
+
857
+ ---
858
+
859
+ ## ๐Ÿค Contributing
860
+
861
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md).
862
+
863
+ ### Development Setup
864
+ ```bash
865
+ git clone https://github.com/maifeeulasad/antd-crud-table
866
+ cd antd-crud-table
867
+ npm install
868
+ npm run dev
869
+ ```
870
+
871
+ ---
872
+
873
+ ## ๐Ÿ“„ License
874
+
875
+ MIT License - feel free to use in personal and commercial projects.
876
+
877
+ ---
878
+
121
879
  ๐ŸŽ‰ Build elegant CRUD interfaces faster than ever with `antd-crud-table`!
122
880
 
123
881