@delightui/components 0.1.105 → 0.1.107

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.
Files changed (102) hide show
  1. package/README.md +104 -1
  2. package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
  3. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  4. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  5. package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  6. package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  7. package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
  8. package/dist/cjs/components/molecules/index.d.ts +2 -0
  9. package/dist/cjs/library.css +19 -6
  10. package/dist/cjs/library.js +3 -3
  11. package/dist/cjs/library.js.map +1 -1
  12. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  13. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  14. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  15. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  16. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  17. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  18. package/dist/esm/components/molecules/index.d.ts +2 -0
  19. package/dist/esm/library.css +19 -6
  20. package/dist/esm/library.js +3 -3
  21. package/dist/esm/library.js.map +1 -1
  22. package/dist/index.d.ts +108 -2
  23. package/docs/README.md +264 -0
  24. package/docs/components/atoms/ActionImage.md +119 -0
  25. package/docs/components/atoms/Button.md +197 -0
  26. package/docs/components/atoms/Checkbox.md +299 -0
  27. package/docs/components/atoms/CheckboxItem.md +314 -0
  28. package/docs/components/atoms/Chip.md +380 -0
  29. package/docs/components/atoms/CustomToggle.md +270 -0
  30. package/docs/components/atoms/Icon.md +365 -0
  31. package/docs/components/atoms/IconButton.md +407 -0
  32. package/docs/components/atoms/Image.md +448 -0
  33. package/docs/components/atoms/Input.md +430 -0
  34. package/docs/components/atoms/ListItem.md +502 -0
  35. package/docs/components/atoms/Password.md +472 -0
  36. package/docs/components/atoms/RadioButton.md +614 -0
  37. package/docs/components/atoms/RadioButtonItem.md +588 -0
  38. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  39. package/docs/components/atoms/SelectListItem.md +609 -0
  40. package/docs/components/atoms/Slider.md +605 -0
  41. package/docs/components/atoms/Spinner.md +605 -0
  42. package/docs/components/atoms/Text.md +463 -0
  43. package/docs/components/atoms/TextArea.md +670 -0
  44. package/docs/components/atoms/ToastNotification.md +668 -0
  45. package/docs/components/atoms/Toggle.md +737 -0
  46. package/docs/components/atoms/ToggleButton.md +751 -0
  47. package/docs/components/atoms/Tooltip.md +391 -0
  48. package/docs/components/molecules/Accordion.md +440 -0
  49. package/docs/components/molecules/AccordionGroup.md +547 -0
  50. package/docs/components/molecules/ActionCard.md +546 -0
  51. package/docs/components/molecules/Breadcrumb.md +403 -0
  52. package/docs/components/molecules/Breadcrumbs.md +485 -0
  53. package/docs/components/molecules/ButtonGroup.md +383 -0
  54. package/docs/components/molecules/Card.md +298 -0
  55. package/docs/components/molecules/ChipInput.md +646 -0
  56. package/docs/components/molecules/ContextMenu.md +768 -0
  57. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  58. package/docs/components/molecules/DatePicker.md +516 -0
  59. package/docs/components/molecules/DateTimeSelector.md +166 -0
  60. package/docs/components/molecules/FormField.md +312 -0
  61. package/docs/components/molecules/Grid.md +577 -0
  62. package/docs/components/molecules/GridItem.md +834 -0
  63. package/docs/components/molecules/GridList.md +244 -0
  64. package/docs/components/molecules/List.md +485 -0
  65. package/docs/components/molecules/Modal.md +470 -0
  66. package/docs/components/molecules/ModalFooter.md +702 -0
  67. package/docs/components/molecules/ModalHeader.md +756 -0
  68. package/docs/components/molecules/ModalProvider.md +205 -0
  69. package/docs/components/molecules/Nav.md +530 -0
  70. package/docs/components/molecules/NavItem.md +572 -0
  71. package/docs/components/molecules/NavLink.md +499 -0
  72. package/docs/components/molecules/Option.md +521 -0
  73. package/docs/components/molecules/Pagination.md +592 -0
  74. package/docs/components/molecules/PaginationNumberField.md +722 -0
  75. package/docs/components/molecules/Popover.md +516 -0
  76. package/docs/components/molecules/ProgressBar.md +624 -0
  77. package/docs/components/molecules/RadioGroup.md +831 -0
  78. package/docs/components/molecules/RepeaterList.md +185 -0
  79. package/docs/components/molecules/Select.md +402 -0
  80. package/docs/components/molecules/SortableTrigger.md +82 -0
  81. package/docs/components/molecules/useModal.md +379 -0
  82. package/docs/components/organisms/Dropzone.md +346 -0
  83. package/docs/components/organisms/DropzoneClear.md +135 -0
  84. package/docs/components/organisms/DropzoneContent.md +216 -0
  85. package/docs/components/organisms/DropzoneFilename.md +191 -0
  86. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  87. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  88. package/docs/components/organisms/Form.md +533 -0
  89. package/docs/components/organisms/SlideOutPanel.md +662 -0
  90. package/docs/components/organisms/TabContent.md +902 -0
  91. package/docs/components/organisms/TabItem.md +1091 -0
  92. package/docs/components/organisms/Table.md +611 -0
  93. package/docs/components/organisms/TableBody.md +679 -0
  94. package/docs/components/organisms/TableCell.md +482 -0
  95. package/docs/components/organisms/TableHeader.md +513 -0
  96. package/docs/components/organisms/TableHeaderCell.md +661 -0
  97. package/docs/components/organisms/TableRow.md +715 -0
  98. package/docs/components/organisms/Tabs.md +1330 -0
  99. package/docs/components/utils/ConditionalView.md +568 -0
  100. package/docs/components/utils/RenderStateView.md +726 -0
  101. package/docs/components/utils/WrapTextNodes.md +614 -0
  102. package/package.json +3 -2
@@ -0,0 +1,592 @@
1
+ # Pagination
2
+
3
+ ## Description
4
+
5
+ A pagination controls component that provides navigation through multiple pages of content. Features customizable page numbers, navigation arrows, current page highlighting, and accessibility support for managing large datasets with efficient user navigation.
6
+
7
+ ## Aliases
8
+
9
+ - Pagination
10
+ - PageNavigation
11
+ - Pager
12
+ - PageControls
13
+ - PageSelector
14
+
15
+ ## Props Breakdown
16
+
17
+ **Extends:** Standalone interface (no HTML element inheritance)
18
+
19
+ | Prop | Type | Default | Required | Description |
20
+ |------|------|---------|----------|-------------|
21
+ | `className` | `string` | - | No | Additional CSS class names for custom styling |
22
+ | `currentPage` | `number` | - | No | The currently active page number |
23
+ | `totalPages` | `number` | - | No | Total number of pages available |
24
+ | `updateCurrentPage` | `(page: number) => void` | - | No | Callback function when page changes |
25
+ | `previousPageIcon` | `ReactNode` | - | No | Custom icon for previous page button |
26
+ | `nextPageIcon` | `ReactNode` | - | No | Custom icon for next page button |
27
+
28
+ ## Examples
29
+
30
+ ### Basic Usage
31
+ ```tsx
32
+ import { Pagination } from '@delightui/components';
33
+
34
+ function BasicExample() {
35
+ const [currentPage, setCurrentPage] = useState(1);
36
+ const totalPages = 10;
37
+
38
+ return (
39
+ <Pagination
40
+ currentPage={currentPage}
41
+ totalPages={totalPages}
42
+ updateCurrentPage={setCurrentPage}
43
+ />
44
+ );
45
+ }
46
+ ```
47
+
48
+ ### Custom Navigation Icons
49
+ ```tsx
50
+ function CustomIconsExample() {
51
+ const [currentPage, setCurrentPage] = useState(1);
52
+ const totalPages = 15;
53
+
54
+ return (
55
+ <Pagination
56
+ currentPage={currentPage}
57
+ totalPages={totalPages}
58
+ updateCurrentPage={setCurrentPage}
59
+ previousPageIcon={<Icon icon="ChevronLeft" />}
60
+ nextPageIcon={<Icon icon="ChevronRight" />}
61
+ />
62
+ );
63
+ }
64
+ ```
65
+
66
+ ### Table Pagination
67
+ ```tsx
68
+ function TablePaginationExample() {
69
+ const [currentPage, setCurrentPage] = useState(1);
70
+ const [itemsPerPage, setItemsPerPage] = useState(10);
71
+
72
+ // Mock data
73
+ const totalItems = 247;
74
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
75
+ const startItem = (currentPage - 1) * itemsPerPage + 1;
76
+ const endItem = Math.min(currentPage * itemsPerPage, totalItems);
77
+
78
+ const mockData = Array.from({ length: itemsPerPage }, (_, index) => ({
79
+ id: startItem + index,
80
+ name: `Item ${startItem + index}`,
81
+ status: ['Active', 'Inactive', 'Pending'][Math.floor(Math.random() * 3)]
82
+ }));
83
+
84
+ return (
85
+ <div className="table-pagination-example">
86
+ <Table>
87
+ <TableHeader>
88
+ <TableHeaderCell>ID</TableHeaderCell>
89
+ <TableHeaderCell>Name</TableHeaderCell>
90
+ <TableHeaderCell>Status</TableHeaderCell>
91
+ </TableHeader>
92
+ <TableBody>
93
+ {mockData.map(item => (
94
+ <TableRow key={item.id}>
95
+ <TableCell>{item.id}</TableCell>
96
+ <TableCell>{item.name}</TableCell>
97
+ <TableCell>
98
+ <Chip size="Small" style={item.status === 'Active' ? 'Success' : 'Default'}>
99
+ {item.status}
100
+ </Chip>
101
+ </TableCell>
102
+ </TableRow>
103
+ ))}
104
+ </TableBody>
105
+ </Table>
106
+
107
+ <div className="pagination-info">
108
+ <Text type="BodySmall">
109
+ Showing {startItem}-{endItem} of {totalItems} items
110
+ </Text>
111
+
112
+ <Select value={itemsPerPage} onValueChange={setItemsPerPage}>
113
+ <Option value={5}>5 per page</Option>
114
+ <Option value={10}>10 per page</Option>
115
+ <Option value={25}>25 per page</Option>
116
+ <Option value={50}>50 per page</Option>
117
+ </Select>
118
+ </div>
119
+
120
+ <Pagination
121
+ currentPage={currentPage}
122
+ totalPages={totalPages}
123
+ updateCurrentPage={setCurrentPage}
124
+ className="table-pagination"
125
+ />
126
+ </div>
127
+ );
128
+ }
129
+ ```
130
+
131
+ ### Search Results Pagination
132
+ ```tsx
133
+ function SearchResultsPaginationExample() {
134
+ const [currentPage, setCurrentPage] = useState(1);
135
+ const [searchTerm, setSearchTerm] = useState('react');
136
+
137
+ // Mock search results
138
+ const resultsPerPage = 8;
139
+ const totalResults = 156;
140
+ const totalPages = Math.ceil(totalResults / resultsPerPage);
141
+
142
+ const mockResults = Array.from({ length: resultsPerPage }, (_, index) => ({
143
+ id: (currentPage - 1) * resultsPerPage + index + 1,
144
+ title: `${searchTerm} Tutorial ${(currentPage - 1) * resultsPerPage + index + 1}`,
145
+ description: 'Learn advanced techniques and best practices...',
146
+ category: ['Tutorial', 'Guide', 'Documentation'][Math.floor(Math.random() * 3)]
147
+ }));
148
+
149
+ return (
150
+ <div className="search-results-pagination">
151
+ <div className="search-header">
152
+ <Input
153
+ placeholder="Search..."
154
+ value={searchTerm}
155
+ onValueChange={setSearchTerm}
156
+ leadingIcon={<Icon icon="Search" />}
157
+ />
158
+
159
+ <Text type="BodySmall">
160
+ {totalResults} results found for "{searchTerm}"
161
+ </Text>
162
+ </div>
163
+
164
+ <div className="search-results">
165
+ {mockResults.map(result => (
166
+ <Card key={result.id} className="search-result-card">
167
+ <div className="result-header">
168
+ <Text type="Heading6">{result.title}</Text>
169
+ <Chip size="Small">{result.category}</Chip>
170
+ </div>
171
+ <Text type="BodyMedium">{result.description}</Text>
172
+ <Button type="Ghost" size="Small">
173
+ Read More
174
+ </Button>
175
+ </Card>
176
+ ))}
177
+ </div>
178
+
179
+ <Pagination
180
+ currentPage={currentPage}
181
+ totalPages={totalPages}
182
+ updateCurrentPage={setCurrentPage}
183
+ className="search-pagination"
184
+ />
185
+ </div>
186
+ );
187
+ }
188
+ ```
189
+
190
+ ### Blog Post Pagination
191
+ ```tsx
192
+ function BlogPaginationExample() {
193
+ const [currentPage, setCurrentPage] = useState(1);
194
+ const postsPerPage = 5;
195
+ const totalPosts = 42;
196
+ const totalPages = Math.ceil(totalPosts / postsPerPage);
197
+
198
+ const mockPosts = Array.from({ length: postsPerPage }, (_, index) => ({
199
+ id: (currentPage - 1) * postsPerPage + index + 1,
200
+ title: `Blog Post Title ${(currentPage - 1) * postsPerPage + index + 1}`,
201
+ excerpt: 'This is a brief excerpt of the blog post content...',
202
+ author: 'John Doe',
203
+ date: '2024-01-15',
204
+ readTime: '5 min read'
205
+ }));
206
+
207
+ return (
208
+ <div className="blog-pagination">
209
+ <div className="blog-posts">
210
+ {mockPosts.map(post => (
211
+ <Card key={post.id} className="blog-post-card">
212
+ <Text type="Heading5">{post.title}</Text>
213
+ <Text type="BodyMedium">{post.excerpt}</Text>
214
+
215
+ <div className="post-meta">
216
+ <div className="author-info">
217
+ <Icon icon="Person" />
218
+ <Text type="BodySmall">{post.author}</Text>
219
+ </div>
220
+
221
+ <div className="post-date">
222
+ <Icon icon="Calendar" />
223
+ <Text type="BodySmall">{post.date}</Text>
224
+ </div>
225
+
226
+ <div className="read-time">
227
+ <Icon icon="Schedule" />
228
+ <Text type="BodySmall">{post.readTime}</Text>
229
+ </div>
230
+ </div>
231
+
232
+ <Button type="Outlined" size="Small">
233
+ Read More
234
+ </Button>
235
+ </Card>
236
+ ))}
237
+ </div>
238
+
239
+ <div className="blog-pagination-controls">
240
+ <Pagination
241
+ currentPage={currentPage}
242
+ totalPages={totalPages}
243
+ updateCurrentPage={setCurrentPage}
244
+ previousPageIcon={<Icon icon="ArrowBack" />}
245
+ nextPageIcon={<Icon icon="ArrowForward" />}
246
+ />
247
+
248
+ <Text type="BodySmall" className="pagination-info">
249
+ Page {currentPage} of {totalPages}
250
+ </Text>
251
+ </div>
252
+ </div>
253
+ );
254
+ }
255
+ ```
256
+
257
+ ### E-commerce Product Pagination
258
+ ```tsx
259
+ function ProductPaginationExample() {
260
+ const [currentPage, setCurrentPage] = useState(1);
261
+ const [sortBy, setSortBy] = useState('name');
262
+ const [filterCategory, setFilterCategory] = useState('all');
263
+
264
+ const productsPerPage = 12;
265
+ const totalProducts = 89;
266
+ const totalPages = Math.ceil(totalProducts / productsPerPage);
267
+
268
+ const mockProducts = Array.from({ length: productsPerPage }, (_, index) => ({
269
+ id: (currentPage - 1) * productsPerPage + index + 1,
270
+ name: `Product ${(currentPage - 1) * productsPerPage + index + 1}`,
271
+ price: (Math.random() * 100 + 10).toFixed(2),
272
+ category: ['Electronics', 'Clothing', 'Books'][Math.floor(Math.random() * 3)],
273
+ rating: (Math.random() * 2 + 3).toFixed(1),
274
+ image: `/product-${(currentPage - 1) * productsPerPage + index + 1}.jpg`
275
+ }));
276
+
277
+ return (
278
+ <div className="product-pagination">
279
+ <div className="product-filters">
280
+ <Select value={filterCategory} onValueChange={setFilterCategory}>
281
+ <Option value="all">All Categories</Option>
282
+ <Option value="electronics">Electronics</Option>
283
+ <Option value="clothing">Clothing</Option>
284
+ <Option value="books">Books</Option>
285
+ </Select>
286
+
287
+ <Select value={sortBy} onValueChange={setSortBy}>
288
+ <Option value="name">Sort by Name</Option>
289
+ <Option value="price">Sort by Price</Option>
290
+ <Option value="rating">Sort by Rating</Option>
291
+ </Select>
292
+
293
+ <Text type="BodySmall">
294
+ {totalProducts} products found
295
+ </Text>
296
+ </div>
297
+
298
+ <div className="product-grid">
299
+ {mockProducts.map(product => (
300
+ <Card key={product.id} className="product-card">
301
+ <Image src={product.image} alt={product.name} />
302
+ <Text type="Heading6">{product.name}</Text>
303
+ <Text type="BodyMedium">${product.price}</Text>
304
+ <div className="product-rating">
305
+ <Icon icon="Star" />
306
+ <Text type="BodySmall">{product.rating}</Text>
307
+ </div>
308
+ <Button type="Filled" size="Small">
309
+ Add to Cart
310
+ </Button>
311
+ </Card>
312
+ ))}
313
+ </div>
314
+
315
+ <Pagination
316
+ currentPage={currentPage}
317
+ totalPages={totalPages}
318
+ updateCurrentPage={setCurrentPage}
319
+ className="product-pagination-controls"
320
+ />
321
+ </div>
322
+ );
323
+ }
324
+ ```
325
+
326
+ ### Advanced Pagination with Jump
327
+ ```tsx
328
+ function AdvancedPaginationExample() {
329
+ const [currentPage, setCurrentPage] = useState(1);
330
+ const [goToPage, setGoToPage] = useState('');
331
+ const totalPages = 25;
332
+
333
+ const handleGoToPage = () => {
334
+ const pageNumber = parseInt(goToPage);
335
+ if (pageNumber >= 1 && pageNumber <= totalPages) {
336
+ setCurrentPage(pageNumber);
337
+ setGoToPage('');
338
+ }
339
+ };
340
+
341
+ const handleKeyPress = (event) => {
342
+ if (event.key === 'Enter') {
343
+ handleGoToPage();
344
+ }
345
+ };
346
+
347
+ return (
348
+ <div className="advanced-pagination">
349
+ <div className="pagination-controls">
350
+ <Pagination
351
+ currentPage={currentPage}
352
+ totalPages={totalPages}
353
+ updateCurrentPage={setCurrentPage}
354
+ previousPageIcon={<Icon icon="SkipPrevious" />}
355
+ nextPageIcon={<Icon icon="SkipNext" />}
356
+ />
357
+ </div>
358
+
359
+ <div className="pagination-extras">
360
+ <div className="page-jump">
361
+ <Text type="BodySmall">Go to page:</Text>
362
+ <Input
363
+ value={goToPage}
364
+ onValueChange={setGoToPage}
365
+ onKeyPress={handleKeyPress}
366
+ placeholder="Page #"
367
+ size="Small"
368
+ style={{ width: '80px' }}
369
+ />
370
+ <Button
371
+ onClick={handleGoToPage}
372
+ disabled={!goToPage}
373
+ size="Small"
374
+ >
375
+ Go
376
+ </Button>
377
+ </div>
378
+
379
+ <div className="pagination-info">
380
+ <Text type="BodySmall">
381
+ Page {currentPage} of {totalPages}
382
+ </Text>
383
+ </div>
384
+ </div>
385
+ </div>
386
+ );
387
+ }
388
+ ```
389
+
390
+ ### Infinite Scroll Alternative
391
+ ```tsx
392
+ function InfiniteScrollExample() {
393
+ const [currentPage, setCurrentPage] = useState(1);
394
+ const [loadingMore, setLoadingMore] = useState(false);
395
+ const [showPagination, setShowPagination] = useState(false);
396
+
397
+ const itemsPerPage = 10;
398
+ const totalPages = 20;
399
+ const [loadedItems, setLoadedItems] = useState([]);
400
+
401
+ const loadMoreItems = async () => {
402
+ setLoadingMore(true);
403
+
404
+ // Simulate API call
405
+ await new Promise(resolve => setTimeout(resolve, 1000));
406
+
407
+ const newItems = Array.from({ length: itemsPerPage }, (_, index) => ({
408
+ id: loadedItems.length + index + 1,
409
+ title: `Item ${loadedItems.length + index + 1}`,
410
+ content: 'This is the content for this item...'
411
+ }));
412
+
413
+ setLoadedItems(prev => [...prev, ...newItems]);
414
+ setCurrentPage(prev => prev + 1);
415
+ setLoadingMore(false);
416
+ };
417
+
418
+ return (
419
+ <div className="infinite-scroll-example">
420
+ <div className="scroll-toggle">
421
+ <Toggle
422
+ checked={showPagination}
423
+ onCheckedChange={setShowPagination}
424
+ label="Use pagination instead of infinite scroll"
425
+ />
426
+ </div>
427
+
428
+ <div className="items-list">
429
+ {loadedItems.map(item => (
430
+ <Card key={item.id} className="list-item">
431
+ <Text type="Heading6">{item.title}</Text>
432
+ <Text type="BodyMedium">{item.content}</Text>
433
+ </Card>
434
+ ))}
435
+ </div>
436
+
437
+ {showPagination ? (
438
+ <Pagination
439
+ currentPage={currentPage}
440
+ totalPages={totalPages}
441
+ updateCurrentPage={setCurrentPage}
442
+ />
443
+ ) : (
444
+ <div className="load-more-section">
445
+ <Button
446
+ onClick={loadMoreItems}
447
+ loading={loadingMore}
448
+ disabled={currentPage >= totalPages}
449
+ type="Outlined"
450
+ >
451
+ {loadingMore ? 'Loading...' : 'Load More Items'}
452
+ </Button>
453
+
454
+ {currentPage >= totalPages && (
455
+ <Text type="BodySmall">
456
+ All items loaded ({loadedItems.length} total)
457
+ </Text>
458
+ )}
459
+ </div>
460
+ )}
461
+ </div>
462
+ );
463
+ }
464
+ ```
465
+
466
+ ### Responsive Pagination
467
+ ```tsx
468
+ function ResponsivePaginationExample() {
469
+ const [currentPage, setCurrentPage] = useState(1);
470
+ const [isMobile, setIsMobile] = useState(false);
471
+ const totalPages = 15;
472
+
473
+ useEffect(() => {
474
+ const checkMobile = () => {
475
+ setIsMobile(window.innerWidth < 768);
476
+ };
477
+
478
+ checkMobile();
479
+ window.addEventListener('resize', checkMobile);
480
+
481
+ return () => window.removeEventListener('resize', checkMobile);
482
+ }, []);
483
+
484
+ return (
485
+ <div className="responsive-pagination">
486
+ <div className="content-area">
487
+ <Text type="Heading4">
488
+ Page {currentPage} Content
489
+ </Text>
490
+ <Text type="BodyMedium">
491
+ This content changes based on the selected page.
492
+ </Text>
493
+ </div>
494
+
495
+ {isMobile ? (
496
+ <div className="mobile-pagination">
497
+ <Button
498
+ disabled={currentPage === 1}
499
+ onClick={() => setCurrentPage(currentPage - 1)}
500
+ leadingIcon={<Icon icon="ChevronLeft" />}
501
+ >
502
+ Previous
503
+ </Button>
504
+
505
+ <Text type="BodyMedium">
506
+ {currentPage} / {totalPages}
507
+ </Text>
508
+
509
+ <Button
510
+ disabled={currentPage === totalPages}
511
+ onClick={() => setCurrentPage(currentPage + 1)}
512
+ trailingIcon={<Icon icon="ChevronRight" />}
513
+ >
514
+ Next
515
+ </Button>
516
+ </div>
517
+ ) : (
518
+ <Pagination
519
+ currentPage={currentPage}
520
+ totalPages={totalPages}
521
+ updateCurrentPage={setCurrentPage}
522
+ className="desktop-pagination"
523
+ />
524
+ )}
525
+ </div>
526
+ );
527
+ }
528
+ ```
529
+
530
+ ### Pagination with Loading States
531
+ ```tsx
532
+ function LoadingPaginationExample() {
533
+ const [currentPage, setCurrentPage] = useState(1);
534
+ const [isLoading, setIsLoading] = useState(false);
535
+ const [data, setData] = useState([]);
536
+ const totalPages = 12;
537
+
538
+ const fetchPageData = async (page) => {
539
+ setIsLoading(true);
540
+
541
+ // Simulate API call
542
+ await new Promise(resolve => setTimeout(resolve, 1500));
543
+
544
+ const pageData = Array.from({ length: 8 }, (_, index) => ({
545
+ id: (page - 1) * 8 + index + 1,
546
+ title: `Page ${page} - Item ${index + 1}`,
547
+ content: 'Loading content from server...'
548
+ }));
549
+
550
+ setData(pageData);
551
+ setIsLoading(false);
552
+ };
553
+
554
+ const handlePageChange = (page) => {
555
+ setCurrentPage(page);
556
+ fetchPageData(page);
557
+ };
558
+
559
+ useEffect(() => {
560
+ fetchPageData(1);
561
+ }, []);
562
+
563
+ return (
564
+ <div className="loading-pagination">
565
+ <div className="data-container">
566
+ {isLoading ? (
567
+ <div className="loading-state">
568
+ <Spinner size="Large" />
569
+ <Text type="BodyMedium">Loading page data...</Text>
570
+ </div>
571
+ ) : (
572
+ <div className="data-grid">
573
+ {data.map(item => (
574
+ <Card key={item.id} className="data-item">
575
+ <Text type="Heading6">{item.title}</Text>
576
+ <Text type="BodyMedium">{item.content}</Text>
577
+ </Card>
578
+ ))}
579
+ </div>
580
+ )}
581
+ </div>
582
+
583
+ <Pagination
584
+ currentPage={currentPage}
585
+ totalPages={totalPages}
586
+ updateCurrentPage={handlePageChange}
587
+ className={isLoading ? 'disabled' : ''}
588
+ />
589
+ </div>
590
+ );
591
+ }
592
+ ```