@delightui/components 0.1.104 → 0.1.106

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 (120) 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/Popover/Popover.presenter.d.ts +26 -0
  9. package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
  10. package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
  11. package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
  12. package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
  13. package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
  14. package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
  15. package/dist/cjs/components/molecules/index.d.ts +2 -0
  16. package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
  17. package/dist/cjs/components/utils/index.d.ts +2 -0
  18. package/dist/cjs/library.css +13 -0
  19. package/dist/cjs/library.js +2 -2
  20. package/dist/cjs/library.js.map +1 -1
  21. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  22. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  23. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  24. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  25. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  26. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  27. package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  28. package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
  29. package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
  30. package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
  31. package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
  32. package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
  33. package/dist/esm/components/molecules/Select/index.d.ts +2 -9
  34. package/dist/esm/components/molecules/index.d.ts +2 -0
  35. package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
  36. package/dist/esm/components/utils/index.d.ts +2 -0
  37. package/dist/esm/library.css +13 -0
  38. package/dist/esm/library.js +3 -3
  39. package/dist/esm/library.js.map +1 -1
  40. package/dist/index.d.ts +156 -12
  41. package/docs/README.md +264 -0
  42. package/docs/components/atoms/ActionImage.md +119 -0
  43. package/docs/components/atoms/Button.md +197 -0
  44. package/docs/components/atoms/Checkbox.md +299 -0
  45. package/docs/components/atoms/CheckboxItem.md +314 -0
  46. package/docs/components/atoms/Chip.md +380 -0
  47. package/docs/components/atoms/CustomToggle.md +270 -0
  48. package/docs/components/atoms/Icon.md +365 -0
  49. package/docs/components/atoms/IconButton.md +407 -0
  50. package/docs/components/atoms/Image.md +448 -0
  51. package/docs/components/atoms/Input.md +430 -0
  52. package/docs/components/atoms/ListItem.md +502 -0
  53. package/docs/components/atoms/Password.md +472 -0
  54. package/docs/components/atoms/RadioButton.md +614 -0
  55. package/docs/components/atoms/RadioButtonItem.md +588 -0
  56. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  57. package/docs/components/atoms/SelectListItem.md +609 -0
  58. package/docs/components/atoms/Slider.md +605 -0
  59. package/docs/components/atoms/Spinner.md +605 -0
  60. package/docs/components/atoms/Text.md +463 -0
  61. package/docs/components/atoms/TextArea.md +670 -0
  62. package/docs/components/atoms/ToastNotification.md +668 -0
  63. package/docs/components/atoms/Toggle.md +737 -0
  64. package/docs/components/atoms/ToggleButton.md +751 -0
  65. package/docs/components/atoms/Tooltip.md +391 -0
  66. package/docs/components/molecules/Accordion.md +440 -0
  67. package/docs/components/molecules/AccordionGroup.md +547 -0
  68. package/docs/components/molecules/ActionCard.md +546 -0
  69. package/docs/components/molecules/Breadcrumb.md +403 -0
  70. package/docs/components/molecules/Breadcrumbs.md +485 -0
  71. package/docs/components/molecules/ButtonGroup.md +383 -0
  72. package/docs/components/molecules/Card.md +298 -0
  73. package/docs/components/molecules/ChipInput.md +646 -0
  74. package/docs/components/molecules/ContextMenu.md +768 -0
  75. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  76. package/docs/components/molecules/DatePicker.md +516 -0
  77. package/docs/components/molecules/DateTimeSelector.md +166 -0
  78. package/docs/components/molecules/FormField.md +312 -0
  79. package/docs/components/molecules/Grid.md +577 -0
  80. package/docs/components/molecules/GridItem.md +834 -0
  81. package/docs/components/molecules/GridList.md +244 -0
  82. package/docs/components/molecules/List.md +485 -0
  83. package/docs/components/molecules/Modal.md +470 -0
  84. package/docs/components/molecules/ModalFooter.md +702 -0
  85. package/docs/components/molecules/ModalHeader.md +756 -0
  86. package/docs/components/molecules/ModalProvider.md +205 -0
  87. package/docs/components/molecules/Nav.md +530 -0
  88. package/docs/components/molecules/NavItem.md +572 -0
  89. package/docs/components/molecules/NavLink.md +499 -0
  90. package/docs/components/molecules/Option.md +521 -0
  91. package/docs/components/molecules/Pagination.md +592 -0
  92. package/docs/components/molecules/PaginationNumberField.md +722 -0
  93. package/docs/components/molecules/Popover.md +516 -0
  94. package/docs/components/molecules/ProgressBar.md +624 -0
  95. package/docs/components/molecules/RadioGroup.md +831 -0
  96. package/docs/components/molecules/RepeaterList.md +185 -0
  97. package/docs/components/molecules/Select.md +402 -0
  98. package/docs/components/molecules/SortableTrigger.md +82 -0
  99. package/docs/components/molecules/useModal.md +379 -0
  100. package/docs/components/organisms/Dropzone.md +346 -0
  101. package/docs/components/organisms/DropzoneClear.md +135 -0
  102. package/docs/components/organisms/DropzoneContent.md +216 -0
  103. package/docs/components/organisms/DropzoneFilename.md +191 -0
  104. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  105. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  106. package/docs/components/organisms/Form.md +533 -0
  107. package/docs/components/organisms/SlideOutPanel.md +662 -0
  108. package/docs/components/organisms/TabContent.md +902 -0
  109. package/docs/components/organisms/TabItem.md +1091 -0
  110. package/docs/components/organisms/Table.md +611 -0
  111. package/docs/components/organisms/TableBody.md +679 -0
  112. package/docs/components/organisms/TableCell.md +482 -0
  113. package/docs/components/organisms/TableHeader.md +513 -0
  114. package/docs/components/organisms/TableHeaderCell.md +661 -0
  115. package/docs/components/organisms/TableRow.md +715 -0
  116. package/docs/components/organisms/Tabs.md +1330 -0
  117. package/docs/components/utils/ConditionalView.md +568 -0
  118. package/docs/components/utils/RenderStateView.md +726 -0
  119. package/docs/components/utils/WrapTextNodes.md +614 -0
  120. package/package.json +3 -2
@@ -0,0 +1,722 @@
1
+ # PaginationNumberField
2
+
3
+ ## Description
4
+
5
+ A specialized number input component designed for pagination controls. Allows users to directly enter a page number for quick navigation, with built-in validation, bounds checking, and integration with pagination state management.
6
+
7
+ ## Aliases
8
+
9
+ - PaginationNumberField
10
+ - PageNumberInput
11
+ - PageJumpField
12
+ - PageInput
13
+ - NavigationNumberField
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
+ | `page` | `number` | - | No | Current page number value |
23
+ | `totalPages` | `number` | - | No | Maximum page number allowed |
24
+ | `onPageChanged` | `(page: number) => void` | - | No | Callback function when page number changes |
25
+
26
+ ## Examples
27
+
28
+ ### Basic Usage
29
+ ```tsx
30
+ import { PaginationNumberField } from '@delightui/components';
31
+
32
+ function BasicExample() {
33
+ const [currentPage, setCurrentPage] = useState(1);
34
+ const totalPages = 10;
35
+
36
+ return (
37
+ <div className="pagination-controls">
38
+ <Text>Go to page:</Text>
39
+ <PaginationNumberField
40
+ page={currentPage}
41
+ totalPages={totalPages}
42
+ onPageChanged={setCurrentPage}
43
+ />
44
+ <Text>of {totalPages}</Text>
45
+ </div>
46
+ );
47
+ }
48
+ ```
49
+
50
+ ### Integrated with Pagination
51
+ ```tsx
52
+ function IntegratedPaginationExample() {
53
+ const [currentPage, setCurrentPage] = useState(1);
54
+ const totalPages = 25;
55
+ const totalItems = 247;
56
+ const itemsPerPage = 10;
57
+
58
+ const startItem = (currentPage - 1) * itemsPerPage + 1;
59
+ const endItem = Math.min(currentPage * itemsPerPage, totalItems);
60
+
61
+ return (
62
+ <div className="integrated-pagination">
63
+ <div className="content-area">
64
+ <Text type="Heading4">Page {currentPage} Content</Text>
65
+ <Text type="BodyMedium">
66
+ Showing items {startItem}-{endItem} of {totalItems}
67
+ </Text>
68
+ </div>
69
+
70
+ <div className="pagination-bar">
71
+ <Pagination
72
+ currentPage={currentPage}
73
+ totalPages={totalPages}
74
+ updateCurrentPage={setCurrentPage}
75
+ />
76
+
77
+ <div className="page-jump">
78
+ <Text type="BodySmall">Jump to:</Text>
79
+ <PaginationNumberField
80
+ page={currentPage}
81
+ totalPages={totalPages}
82
+ onPageChanged={setCurrentPage}
83
+ />
84
+ </div>
85
+ </div>
86
+ </div>
87
+ );
88
+ }
89
+ ```
90
+
91
+ ### Search Results with Page Jump
92
+ ```tsx
93
+ function SearchResultsExample() {
94
+ const [currentPage, setCurrentPage] = useState(1);
95
+ const [searchTerm, setSearchTerm] = useState('React');
96
+ const [resultsPerPage, setResultsPerPage] = useState(10);
97
+
98
+ const totalResults = 156;
99
+ const totalPages = Math.ceil(totalResults / resultsPerPage);
100
+
101
+ const mockResults = Array.from({ length: resultsPerPage }, (_, index) => ({
102
+ id: (currentPage - 1) * resultsPerPage + index + 1,
103
+ title: `${searchTerm} Tutorial ${(currentPage - 1) * resultsPerPage + index + 1}`,
104
+ description: 'Comprehensive guide to modern development practices...',
105
+ category: 'Tutorial'
106
+ }));
107
+
108
+ return (
109
+ <div className="search-results-example">
110
+ <div className="search-header">
111
+ <Input
112
+ placeholder="Search tutorials..."
113
+ value={searchTerm}
114
+ onValueChange={setSearchTerm}
115
+ leadingIcon={<Icon icon="Search" />}
116
+ />
117
+
118
+ <div className="results-info">
119
+ <Text type="BodySmall">
120
+ {totalResults} results found
121
+ </Text>
122
+
123
+ <Select value={resultsPerPage} onValueChange={setResultsPerPage}>
124
+ <Option value={5}>5 per page</Option>
125
+ <Option value={10}>10 per page</Option>
126
+ <Option value={20}>20 per page</Option>
127
+ </Select>
128
+ </div>
129
+ </div>
130
+
131
+ <div className="search-results">
132
+ {mockResults.map(result => (
133
+ <Card key={result.id} className="result-card">
134
+ <div className="result-header">
135
+ <Text type="Heading6">{result.title}</Text>
136
+ <Chip size="Small">{result.category}</Chip>
137
+ </div>
138
+ <Text type="BodyMedium">{result.description}</Text>
139
+ </Card>
140
+ ))}
141
+ </div>
142
+
143
+ <div className="search-pagination">
144
+ <Pagination
145
+ currentPage={currentPage}
146
+ totalPages={totalPages}
147
+ updateCurrentPage={setCurrentPage}
148
+ />
149
+
150
+ <div className="quick-navigation">
151
+ <Text type="BodySmall">Page:</Text>
152
+ <PaginationNumberField
153
+ page={currentPage}
154
+ totalPages={totalPages}
155
+ onPageChanged={setCurrentPage}
156
+ className="compact-field"
157
+ />
158
+ <Text type="BodySmall">of {totalPages}</Text>
159
+ </div>
160
+ </div>
161
+ </div>
162
+ );
163
+ }
164
+ ```
165
+
166
+ ### Data Table with Page Jump
167
+ ```tsx
168
+ function DataTableExample() {
169
+ const [currentPage, setCurrentPage] = useState(1);
170
+ const [sortBy, setSortBy] = useState('id');
171
+ const [sortOrder, setSortOrder] = useState('asc');
172
+
173
+ const rowsPerPage = 15;
174
+ const totalRows = 342;
175
+ const totalPages = Math.ceil(totalRows / rowsPerPage);
176
+
177
+ const mockData = Array.from({ length: rowsPerPage }, (_, index) => {
178
+ const id = (currentPage - 1) * rowsPerPage + index + 1;
179
+ return {
180
+ id,
181
+ name: `User ${id}`,
182
+ email: `user${id}@example.com`,
183
+ status: ['Active', 'Inactive', 'Pending'][Math.floor(Math.random() * 3)],
184
+ lastLogin: '2024-01-15'
185
+ };
186
+ });
187
+
188
+ return (
189
+ <div className="data-table-example">
190
+ <div className="table-controls">
191
+ <div className="sort-controls">
192
+ <Select value={sortBy} onValueChange={setSortBy}>
193
+ <Option value="id">Sort by ID</Option>
194
+ <Option value="name">Sort by Name</Option>
195
+ <Option value="email">Sort by Email</Option>
196
+ <Option value="status">Sort by Status</Option>
197
+ </Select>
198
+
199
+ <Select value={sortOrder} onValueChange={setSortOrder}>
200
+ <Option value="asc">Ascending</Option>
201
+ <Option value="desc">Descending</Option>
202
+ </Select>
203
+ </div>
204
+
205
+ <Text type="BodySmall">
206
+ {totalRows} total records
207
+ </Text>
208
+ </div>
209
+
210
+ <Table className="data-table">
211
+ <TableHeader>
212
+ <TableHeaderCell>ID</TableHeaderCell>
213
+ <TableHeaderCell>Name</TableHeaderCell>
214
+ <TableHeaderCell>Email</TableHeaderCell>
215
+ <TableHeaderCell>Status</TableHeaderCell>
216
+ <TableHeaderCell>Last Login</TableHeaderCell>
217
+ </TableHeader>
218
+ <TableBody>
219
+ {mockData.map(row => (
220
+ <TableRow key={row.id}>
221
+ <TableCell>{row.id}</TableCell>
222
+ <TableCell>{row.name}</TableCell>
223
+ <TableCell>{row.email}</TableCell>
224
+ <TableCell>
225
+ <Chip
226
+ size="Small"
227
+ style={row.status === 'Active' ? 'Success' : row.status === 'Pending' ? 'Warning' : 'Default'}
228
+ >
229
+ {row.status}
230
+ </Chip>
231
+ </TableCell>
232
+ <TableCell>{row.lastLogin}</TableCell>
233
+ </TableRow>
234
+ ))}
235
+ </TableBody>
236
+ </Table>
237
+
238
+ <div className="table-pagination">
239
+ <div className="pagination-info">
240
+ <Text type="BodySmall">
241
+ Showing {(currentPage - 1) * rowsPerPage + 1}-{Math.min(currentPage * rowsPerPage, totalRows)} of {totalRows}
242
+ </Text>
243
+ </div>
244
+
245
+ <div className="pagination-controls">
246
+ <Pagination
247
+ currentPage={currentPage}
248
+ totalPages={totalPages}
249
+ updateCurrentPage={setCurrentPage}
250
+ />
251
+
252
+ <div className="page-jump-controls">
253
+ <Text type="BodySmall">Go to:</Text>
254
+ <PaginationNumberField
255
+ page={currentPage}
256
+ totalPages={totalPages}
257
+ onPageChanged={setCurrentPage}
258
+ />
259
+ </div>
260
+ </div>
261
+ </div>
262
+ </div>
263
+ );
264
+ }
265
+ ```
266
+
267
+ ### Advanced Navigation Controls
268
+ ```tsx
269
+ function AdvancedNavigationExample() {
270
+ const [currentPage, setCurrentPage] = useState(1);
271
+ const [jumpToPage, setJumpToPage] = useState('');
272
+ const [pageHistory, setPageHistory] = useState([1]);
273
+ const totalPages = 50;
274
+
275
+ const handlePageChange = (newPage) => {
276
+ setCurrentPage(newPage);
277
+ setPageHistory(prev => [...prev.slice(-9), newPage]); // Keep last 10 pages
278
+ };
279
+
280
+ const goToFirstPage = () => handlePageChange(1);
281
+ const goToLastPage = () => handlePageChange(totalPages);
282
+
283
+ const goToRandomPage = () => {
284
+ const randomPage = Math.floor(Math.random() * totalPages) + 1;
285
+ handlePageChange(randomPage);
286
+ };
287
+
288
+ return (
289
+ <div className="advanced-navigation">
290
+ <div className="navigation-controls">
291
+ <div className="quick-actions">
292
+ <Button onClick={goToFirstPage} size="Small">
293
+ First Page
294
+ </Button>
295
+ <Button onClick={goToLastPage} size="Small">
296
+ Last Page
297
+ </Button>
298
+ <Button onClick={goToRandomPage} size="Small" type="Outlined">
299
+ Random Page
300
+ </Button>
301
+ </div>
302
+
303
+ <div className="primary-pagination">
304
+ <Pagination
305
+ currentPage={currentPage}
306
+ totalPages={totalPages}
307
+ updateCurrentPage={handlePageChange}
308
+ />
309
+ </div>
310
+
311
+ <div className="page-jump-section">
312
+ <Text type="BodySmall">Jump to page:</Text>
313
+ <PaginationNumberField
314
+ page={currentPage}
315
+ totalPages={totalPages}
316
+ onPageChanged={handlePageChange}
317
+ className="main-page-field"
318
+ />
319
+ <Text type="BodySmall">of {totalPages}</Text>
320
+ </div>
321
+ </div>
322
+
323
+ <div className="page-history">
324
+ <Text type="BodySmall">Recently visited pages:</Text>
325
+ <div className="history-buttons">
326
+ {pageHistory.slice(-5).reverse().map((page, index) => (
327
+ <Button
328
+ key={`${page}-${index}`}
329
+ size="Small"
330
+ type={page === currentPage ? 'Filled' : 'Ghost'}
331
+ onClick={() => handlePageChange(page)}
332
+ >
333
+ {page}
334
+ </Button>
335
+ ))}
336
+ </div>
337
+ </div>
338
+
339
+ <div className="current-page-info">
340
+ <Text type="Heading5">Page {currentPage}</Text>
341
+ <Text type="BodyMedium">Content for page {currentPage} would be displayed here.</Text>
342
+ </div>
343
+ </div>
344
+ );
345
+ }
346
+ ```
347
+
348
+ ### Form-based Page Navigation
349
+ ```tsx
350
+ function FormPageNavigationExample() {
351
+ const [currentPage, setCurrentPage] = useState(1);
352
+ const [pageInput, setPageInput] = useState('');
353
+ const [isValidPage, setIsValidPage] = useState(true);
354
+ const totalPages = 100;
355
+
356
+ const validateAndNavigate = () => {
357
+ const pageNumber = parseInt(pageInput);
358
+
359
+ if (isNaN(pageNumber) || pageNumber < 1 || pageNumber > totalPages) {
360
+ setIsValidPage(false);
361
+ return;
362
+ }
363
+
364
+ setIsValidPage(true);
365
+ setCurrentPage(pageNumber);
366
+ setPageInput('');
367
+ };
368
+
369
+ const handleKeyPress = (event) => {
370
+ if (event.key === 'Enter') {
371
+ validateAndNavigate();
372
+ }
373
+ };
374
+
375
+ const handleInputChange = (value) => {
376
+ setPageInput(value);
377
+ setIsValidPage(true); // Reset validation state when user types
378
+ };
379
+
380
+ return (
381
+ <div className="form-page-navigation">
382
+ <div className="content-section">
383
+ <Text type="Heading4">Page {currentPage} Content</Text>
384
+ <Text type="BodyMedium">
385
+ This is the content for page {currentPage} of {totalPages}.
386
+ </Text>
387
+ </div>
388
+
389
+ <div className="navigation-form">
390
+ <FormField
391
+ label="Navigate to Page"
392
+ error={!isValidPage ? `Please enter a valid page number (1-${totalPages})` : ''}
393
+ >
394
+ <div className="page-input-group">
395
+ <Input
396
+ value={pageInput}
397
+ onValueChange={handleInputChange}
398
+ onKeyPress={handleKeyPress}
399
+ placeholder={`1-${totalPages}`}
400
+ state={!isValidPage ? 'Error' : 'Default'}
401
+ />
402
+ <Button onClick={validateAndNavigate}>
403
+ Go
404
+ </Button>
405
+ </div>
406
+ </FormField>
407
+
408
+ <div className="current-page-field">
409
+ <Text type="BodySmall">Current page:</Text>
410
+ <PaginationNumberField
411
+ page={currentPage}
412
+ totalPages={totalPages}
413
+ onPageChanged={setCurrentPage}
414
+ />
415
+ </div>
416
+ </div>
417
+
418
+ <div className="standard-pagination">
419
+ <Pagination
420
+ currentPage={currentPage}
421
+ totalPages={totalPages}
422
+ updateCurrentPage={setCurrentPage}
423
+ />
424
+ </div>
425
+ </div>
426
+ );
427
+ }
428
+ ```
429
+
430
+ ### Mobile-Optimized Page Input
431
+ ```tsx
432
+ function MobilePageInputExample() {
433
+ const [currentPage, setCurrentPage] = useState(1);
434
+ const [isMobile, setIsMobile] = useState(false);
435
+ const totalPages = 30;
436
+
437
+ useEffect(() => {
438
+ const checkMobile = () => {
439
+ setIsMobile(window.innerWidth < 768);
440
+ };
441
+
442
+ checkMobile();
443
+ window.addEventListener('resize', checkMobile);
444
+
445
+ return () => window.removeEventListener('resize', checkMobile);
446
+ }, []);
447
+
448
+ return (
449
+ <div className="mobile-page-input">
450
+ <div className="page-content">
451
+ <Text type="Heading4">Page {currentPage}</Text>
452
+ <Text type="BodyMedium">
453
+ Content optimized for {isMobile ? 'mobile' : 'desktop'} viewing.
454
+ </Text>
455
+ </div>
456
+
457
+ {isMobile ? (
458
+ <div className="mobile-navigation">
459
+ <div className="mobile-page-controls">
460
+ <Button
461
+ disabled={currentPage === 1}
462
+ onClick={() => setCurrentPage(currentPage - 1)}
463
+ leadingIcon={<Icon icon="ChevronLeft" />}
464
+ />
465
+
466
+ <div className="mobile-page-display">
467
+ <PaginationNumberField
468
+ page={currentPage}
469
+ totalPages={totalPages}
470
+ onPageChanged={setCurrentPage}
471
+ className="mobile-page-field"
472
+ />
473
+ <Text type="BodySmall">/ {totalPages}</Text>
474
+ </div>
475
+
476
+ <Button
477
+ disabled={currentPage === totalPages}
478
+ onClick={() => setCurrentPage(currentPage + 1)}
479
+ trailingIcon={<Icon icon="ChevronRight" />}
480
+ />
481
+ </div>
482
+ </div>
483
+ ) : (
484
+ <div className="desktop-navigation">
485
+ <Pagination
486
+ currentPage={currentPage}
487
+ totalPages={totalPages}
488
+ updateCurrentPage={setCurrentPage}
489
+ />
490
+
491
+ <div className="desktop-page-jump">
492
+ <Text type="BodySmall">Page:</Text>
493
+ <PaginationNumberField
494
+ page={currentPage}
495
+ totalPages={totalPages}
496
+ onPageChanged={setCurrentPage}
497
+ />
498
+ <Text type="BodySmall">of {totalPages}</Text>
499
+ </div>
500
+ </div>
501
+ )}
502
+ </div>
503
+ );
504
+ }
505
+ ```
506
+
507
+ ### Batch Operations with Page Navigation
508
+ ```tsx
509
+ function BatchOperationsExample() {
510
+ const [currentPage, setCurrentPage] = useState(1);
511
+ const [selectedItems, setSelectedItems] = useState(new Set());
512
+ const [selectAll, setSelectAll] = useState(false);
513
+
514
+ const itemsPerPage = 20;
515
+ const totalItems = 189;
516
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
517
+
518
+ const mockItems = Array.from({ length: itemsPerPage }, (_, index) => {
519
+ const id = (currentPage - 1) * itemsPerPage + index + 1;
520
+ return {
521
+ id,
522
+ name: `Item ${id}`,
523
+ status: 'Active',
524
+ type: ['Document', 'Image', 'Video'][Math.floor(Math.random() * 3)]
525
+ };
526
+ });
527
+
528
+ const handleSelectAll = (checked) => {
529
+ setSelectAll(checked);
530
+ if (checked) {
531
+ const currentPageIds = mockItems.map(item => item.id);
532
+ setSelectedItems(new Set([...selectedItems, ...currentPageIds]));
533
+ } else {
534
+ const currentPageIds = new Set(mockItems.map(item => item.id));
535
+ setSelectedItems(new Set([...selectedItems].filter(id => !currentPageIds.has(id))));
536
+ }
537
+ };
538
+
539
+ const handlePageChange = (newPage) => {
540
+ setCurrentPage(newPage);
541
+ setSelectAll(false); // Reset select all when changing pages
542
+ };
543
+
544
+ return (
545
+ <div className="batch-operations-example">
546
+ <div className="operations-header">
547
+ <div className="selection-controls">
548
+ <Checkbox
549
+ checked={selectAll}
550
+ onCheckedChange={handleSelectAll}
551
+ label={`Select all on page ${currentPage}`}
552
+ />
553
+
554
+ {selectedItems.size > 0 && (
555
+ <div className="batch-actions">
556
+ <Text type="BodySmall">
557
+ {selectedItems.size} items selected
558
+ </Text>
559
+ <Button size="Small" type="Outlined">
560
+ Delete Selected
561
+ </Button>
562
+ <Button size="Small" type="Outlined">
563
+ Export Selected
564
+ </Button>
565
+ </div>
566
+ )}
567
+ </div>
568
+
569
+ <div className="page-navigation">
570
+ <Text type="BodySmall">
571
+ Page {currentPage} of {totalPages} ({totalItems} total items)
572
+ </Text>
573
+ <PaginationNumberField
574
+ page={currentPage}
575
+ totalPages={totalPages}
576
+ onPageChanged={handlePageChange}
577
+ />
578
+ </div>
579
+ </div>
580
+
581
+ <div className="items-list">
582
+ {mockItems.map(item => (
583
+ <Card key={item.id} className="batch-item">
584
+ <Checkbox
585
+ checked={selectedItems.has(item.id)}
586
+ onCheckedChange={(checked) => {
587
+ const newSelected = new Set(selectedItems);
588
+ if (checked) {
589
+ newSelected.add(item.id);
590
+ } else {
591
+ newSelected.delete(item.id);
592
+ }
593
+ setSelectedItems(newSelected);
594
+ }}
595
+ />
596
+
597
+ <div className="item-info">
598
+ <Text type="BodyMedium">{item.name}</Text>
599
+ <Text type="BodySmall">{item.type}</Text>
600
+ </div>
601
+
602
+ <Chip size="Small" style="Success">
603
+ {item.status}
604
+ </Chip>
605
+ </Card>
606
+ ))}
607
+ </div>
608
+
609
+ <div className="pagination-footer">
610
+ <Pagination
611
+ currentPage={currentPage}
612
+ totalPages={totalPages}
613
+ updateCurrentPage={handlePageChange}
614
+ />
615
+ </div>
616
+ </div>
617
+ );
618
+ }
619
+ ```
620
+
621
+ ### Real-time Page Validation
622
+ ```tsx
623
+ function RealTimeValidationExample() {
624
+ const [currentPage, setCurrentPage] = useState(1);
625
+ const [inputValue, setInputValue] = useState('');
626
+ const [validationMessage, setValidationMessage] = useState('');
627
+ const [isValid, setIsValid] = useState(true);
628
+ const totalPages = 75;
629
+
630
+ const validatePageInput = (value) => {
631
+ if (value === '') {
632
+ setValidationMessage('');
633
+ setIsValid(true);
634
+ return;
635
+ }
636
+
637
+ const pageNumber = parseInt(value);
638
+
639
+ if (isNaN(pageNumber)) {
640
+ setValidationMessage('Please enter a valid number');
641
+ setIsValid(false);
642
+ return;
643
+ }
644
+
645
+ if (pageNumber < 1) {
646
+ setValidationMessage('Page number must be at least 1');
647
+ setIsValid(false);
648
+ return;
649
+ }
650
+
651
+ if (pageNumber > totalPages) {
652
+ setValidationMessage(`Page number cannot exceed ${totalPages}`);
653
+ setIsValid(false);
654
+ return;
655
+ }
656
+
657
+ setValidationMessage(`Valid page number (${pageNumber})`);
658
+ setIsValid(true);
659
+ };
660
+
661
+ const handleInputChange = (value) => {
662
+ setInputValue(value);
663
+ validatePageInput(value);
664
+ };
665
+
666
+ const applyPageChange = () => {
667
+ if (isValid && inputValue) {
668
+ setCurrentPage(parseInt(inputValue));
669
+ setInputValue('');
670
+ setValidationMessage('');
671
+ }
672
+ };
673
+
674
+ return (
675
+ <div className="realtime-validation-example">
676
+ <div className="current-page-display">
677
+ <Text type="Heading4">Current Page: {currentPage}</Text>
678
+ <Text type="BodyMedium">Content for page {currentPage} goes here.</Text>
679
+ </div>
680
+
681
+ <div className="validation-section">
682
+ <FormField
683
+ label="Enter Page Number"
684
+ helpText={validationMessage}
685
+ error={!isValid ? validationMessage : ''}
686
+ >
687
+ <div className="validated-input-group">
688
+ <Input
689
+ value={inputValue}
690
+ onValueChange={handleInputChange}
691
+ placeholder={`1-${totalPages}`}
692
+ state={!isValid ? 'Error' : validationMessage ? 'Success' : 'Default'}
693
+ />
694
+ <Button
695
+ onClick={applyPageChange}
696
+ disabled={!isValid || !inputValue}
697
+ >
698
+ Apply
699
+ </Button>
700
+ </div>
701
+ </FormField>
702
+
703
+ <div className="standard-field">
704
+ <Text type="BodySmall">Or use the standard page field:</Text>
705
+ <PaginationNumberField
706
+ page={currentPage}
707
+ totalPages={totalPages}
708
+ onPageChanged={setCurrentPage}
709
+ />
710
+ </div>
711
+ </div>
712
+
713
+ <Pagination
714
+ currentPage={currentPage}
715
+ totalPages={totalPages}
716
+ updateCurrentPage={setCurrentPage}
717
+ className="main-pagination"
718
+ />
719
+ </div>
720
+ );
721
+ }
722
+ ```