@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.
- package/README.md +104 -1
- package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
- package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
- package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
- package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
- package/dist/cjs/components/molecules/index.d.ts +2 -0
- package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/cjs/components/utils/index.d.ts +2 -0
- package/dist/cjs/library.css +13 -0
- package/dist/cjs/library.js +2 -2
- package/dist/cjs/library.js.map +1 -1
- package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
- package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
- package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
- package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/esm/components/molecules/Select/index.d.ts +2 -9
- package/dist/esm/components/molecules/index.d.ts +2 -0
- package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/esm/components/utils/index.d.ts +2 -0
- package/dist/esm/library.css +13 -0
- package/dist/esm/library.js +3 -3
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +156 -12
- package/docs/README.md +264 -0
- package/docs/components/atoms/ActionImage.md +119 -0
- package/docs/components/atoms/Button.md +197 -0
- package/docs/components/atoms/Checkbox.md +299 -0
- package/docs/components/atoms/CheckboxItem.md +314 -0
- package/docs/components/atoms/Chip.md +380 -0
- package/docs/components/atoms/CustomToggle.md +270 -0
- package/docs/components/atoms/Icon.md +365 -0
- package/docs/components/atoms/IconButton.md +407 -0
- package/docs/components/atoms/Image.md +448 -0
- package/docs/components/atoms/Input.md +430 -0
- package/docs/components/atoms/ListItem.md +502 -0
- package/docs/components/atoms/Password.md +472 -0
- package/docs/components/atoms/RadioButton.md +614 -0
- package/docs/components/atoms/RadioButtonItem.md +588 -0
- package/docs/components/atoms/ResponsiveComponent.md +612 -0
- package/docs/components/atoms/SelectListItem.md +609 -0
- package/docs/components/atoms/Slider.md +605 -0
- package/docs/components/atoms/Spinner.md +605 -0
- package/docs/components/atoms/Text.md +463 -0
- package/docs/components/atoms/TextArea.md +670 -0
- package/docs/components/atoms/ToastNotification.md +668 -0
- package/docs/components/atoms/Toggle.md +737 -0
- package/docs/components/atoms/ToggleButton.md +751 -0
- package/docs/components/atoms/Tooltip.md +391 -0
- package/docs/components/molecules/Accordion.md +440 -0
- package/docs/components/molecules/AccordionGroup.md +547 -0
- package/docs/components/molecules/ActionCard.md +546 -0
- package/docs/components/molecules/Breadcrumb.md +403 -0
- package/docs/components/molecules/Breadcrumbs.md +485 -0
- package/docs/components/molecules/ButtonGroup.md +383 -0
- package/docs/components/molecules/Card.md +298 -0
- package/docs/components/molecules/ChipInput.md +646 -0
- package/docs/components/molecules/ContextMenu.md +768 -0
- package/docs/components/molecules/CustomTimeSelector.md +116 -0
- package/docs/components/molecules/DatePicker.md +516 -0
- package/docs/components/molecules/DateTimeSelector.md +166 -0
- package/docs/components/molecules/FormField.md +312 -0
- package/docs/components/molecules/Grid.md +577 -0
- package/docs/components/molecules/GridItem.md +834 -0
- package/docs/components/molecules/GridList.md +244 -0
- package/docs/components/molecules/List.md +485 -0
- package/docs/components/molecules/Modal.md +470 -0
- package/docs/components/molecules/ModalFooter.md +702 -0
- package/docs/components/molecules/ModalHeader.md +756 -0
- package/docs/components/molecules/ModalProvider.md +205 -0
- package/docs/components/molecules/Nav.md +530 -0
- package/docs/components/molecules/NavItem.md +572 -0
- package/docs/components/molecules/NavLink.md +499 -0
- package/docs/components/molecules/Option.md +521 -0
- package/docs/components/molecules/Pagination.md +592 -0
- package/docs/components/molecules/PaginationNumberField.md +722 -0
- package/docs/components/molecules/Popover.md +516 -0
- package/docs/components/molecules/ProgressBar.md +624 -0
- package/docs/components/molecules/RadioGroup.md +831 -0
- package/docs/components/molecules/RepeaterList.md +185 -0
- package/docs/components/molecules/Select.md +402 -0
- package/docs/components/molecules/SortableTrigger.md +82 -0
- package/docs/components/molecules/useModal.md +379 -0
- package/docs/components/organisms/Dropzone.md +346 -0
- package/docs/components/organisms/DropzoneClear.md +135 -0
- package/docs/components/organisms/DropzoneContent.md +216 -0
- package/docs/components/organisms/DropzoneFilename.md +191 -0
- package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
- package/docs/components/organisms/DropzoneTrigger.md +209 -0
- package/docs/components/organisms/Form.md +533 -0
- package/docs/components/organisms/SlideOutPanel.md +662 -0
- package/docs/components/organisms/TabContent.md +902 -0
- package/docs/components/organisms/TabItem.md +1091 -0
- package/docs/components/organisms/Table.md +611 -0
- package/docs/components/organisms/TableBody.md +679 -0
- package/docs/components/organisms/TableCell.md +482 -0
- package/docs/components/organisms/TableHeader.md +513 -0
- package/docs/components/organisms/TableHeaderCell.md +661 -0
- package/docs/components/organisms/TableRow.md +715 -0
- package/docs/components/organisms/Tabs.md +1330 -0
- package/docs/components/utils/ConditionalView.md +568 -0
- package/docs/components/utils/RenderStateView.md +726 -0
- package/docs/components/utils/WrapTextNodes.md +614 -0
- 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
|
+
```
|