@ea-lab/reactive-json-docs 0.8.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -5
- package/public/rjbuild/docs/advanced-concepts/attribute-transformers.md +168 -0
- package/public/rjbuild/docs/advanced-concepts/attribute-transformers.yaml +151 -0
- package/public/rjbuild/docs/advanced-concepts/data-mapping.md +6 -6
- package/public/rjbuild/docs/advanced-concepts/data-mapping.yaml +7 -7
- package/public/rjbuild/docs/advanced-concepts/data-processors.md +7 -7
- package/public/rjbuild/docs/advanced-concepts/data-processors.yaml +7 -7
- package/public/rjbuild/docs/advanced-concepts/forward-update.md +2 -2
- package/public/rjbuild/docs/advanced-concepts/forward-update.yaml +2 -2
- package/public/rjbuild/docs/advanced-concepts/index.md +1 -0
- package/public/rjbuild/docs/advanced-concepts/index.yaml +1 -0
- package/public/rjbuild/docs/advanced-concepts/plugins/component-development.md +1 -1
- package/public/rjbuild/docs/advanced-concepts/plugins/component-development.yaml +1 -1
- package/public/rjbuild/docs/advanced-concepts/plugins/plugin-system.md +48 -2
- package/public/rjbuild/docs/advanced-concepts/plugins/plugin-system.yaml +54 -2
- package/public/rjbuild/docs/core/action/Attribute/SetAttributeValue.md +2 -0
- package/public/rjbuild/docs/core/action/Attribute/SetAttributeValue.yaml +2 -0
- package/public/rjbuild/docs/core/action/Attribute/ToggleAttributeValue.md +2 -0
- package/public/rjbuild/docs/core/action/Attribute/ToggleAttributeValue.yaml +2 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttribute.md +2 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttribute.yaml +2 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttributeValue.md +2 -0
- package/public/rjbuild/docs/core/action/Attribute/UnsetAttributeValue.yaml +2 -0
- package/public/rjbuild/docs/core/action/Attribute/index.md +121 -0
- package/public/rjbuild/docs/core/action/Attribute/index.yaml +77 -0
- package/public/rjbuild/docs/core/attributeTransformer/index.md +17 -0
- package/public/rjbuild/docs/core/attributeTransformer/index.yaml +24 -0
- package/public/rjbuild/docs/core/attributeTransformer/setAttributeValue.md +101 -0
- package/public/rjbuild/docs/core/attributeTransformer/setAttributeValue.yaml +144 -0
- package/public/rjbuild/docs/core/attributeTransformer/toggleAttributeValue.md +269 -0
- package/public/rjbuild/docs/core/attributeTransformer/toggleAttributeValue.yaml +247 -0
- package/public/rjbuild/docs/core/attributeTransformer/unsetAttribute.md +114 -0
- package/public/rjbuild/docs/core/attributeTransformer/unsetAttribute.yaml +138 -0
- package/public/rjbuild/docs/core/attributeTransformer/unsetAttributeValue.md +140 -0
- package/public/rjbuild/docs/core/attributeTransformer/unsetAttributeValue.yaml +187 -0
- package/public/rjbuild/docs/core/dataMapping/simpleMapping.yaml +14 -4
- package/public/rjbuild/docs/core/element/form/Input.md +307 -0
- package/public/rjbuild/docs/core/element/form/Input.yaml +572 -0
- package/public/rjbuild/docs/core/element/special/Count.yaml +99 -31
- package/public/rjbuild/docs/core/element/special/DataFilter.yaml +118 -38
- package/public/rjbuild/docs/core/element/special/ReactiveJsonSubroot.yaml +154 -34
- package/public/rjbuild/docs/core/element/special/Switch.md +5 -5
- package/public/rjbuild/docs/core/element/special/Switch.yaml +9 -18
- package/public/rjbuild/docs/core/example/html.md +2 -2
- package/public/rjbuild/docs/core/example/html.yaml +2 -3
- package/public/rjbuild/docs/core/example/native-html-forms.md +245 -0
- package/public/rjbuild/docs/core/example/native-html-forms.yaml +393 -0
- package/public/rjbuild/docs/core/hook/index.md +38 -0
- package/public/rjbuild/docs/core/hook/index.yaml +44 -0
- package/public/rjbuild/docs/core/hook/usePagination.md +286 -0
- package/public/rjbuild/docs/core/hook/usePagination.yaml +319 -0
- package/public/rjbuild/docs/core/hook/useTransformedAttributes.md +130 -0
- package/public/rjbuild/docs/core/hook/useTransformedAttributes.yaml +164 -0
- package/public/rjbuild/docs/core/reaction/addData.md +17 -3
- package/public/rjbuild/docs/core/reaction/addData.yaml +53 -9
- package/public/rjbuild/docs/core/reaction/fetchData.yaml +44 -8
- package/public/rjbuild/docs/core/reaction/setData.md +18 -4
- package/public/rjbuild/docs/core/reaction/setData.yaml +18 -4
- package/public/rjbuild/docs/docs-components/Mermaid.md +254 -0
- package/public/rjbuild/docs/docs-components/Mermaid.yaml +339 -0
- package/public/rjbuild/docs/docs-components/index.yaml +1 -0
- package/public/rjbuild/docs/getting-started/actions.md +1 -1
- package/public/rjbuild/docs/index.yaml +2 -1
- package/public/rjbuild/docs/install.md +2 -5
- package/public/rjbuild/docs/install.yaml +4 -10
- package/public/rjbuild/docs/{core → integration/bootstrap}/action/Popover.md +1 -1
- package/public/rjbuild/docs/{core → integration/bootstrap}/action/Tooltip.md +1 -1
- package/public/rjbuild/docs/integration/bootstrap/element/html/AccordionItem.md +69 -0
- package/public/rjbuild/docs/integration/bootstrap/element/html/Modal.md +127 -0
- package/public/rjbuild/docs/integration/bootstrap/element/html/Tabs.md +150 -0
- package/public/rjbuild/docs/integration/bootstrap/element/html/index.md +13 -0
- package/public/rjbuild/docs/integration/bootstrap/element/special/index.md +19 -0
- package/public/rjbuild/docs/integration/bootstrap/example/website.md +41 -0
- package/public/rjbuild/docs/integration/bootstrap/overview.md +69 -0
- package/public/rjbuild/docs/integration/bootstrap/overview.yaml +87 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/action/Popover.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/action/Tooltip.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/CheckBoxField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/CheckBoxField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/DateField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/DateField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/NumberField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/NumberField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/SelectField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/SelectField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextAreaField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextAreaField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextField.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/TextField.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/formElementsCommon.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/index.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/form/index.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/AccordionItem.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/Modal.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/html/Tabs.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/special/BootstrapElement.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/element/special/BootstrapElement.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/accordion.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/accordion.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/dynamic-content.md +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/dynamic-content.yaml +0 -0
- /package/public/rjbuild/docs/{core → integration/bootstrap}/example/website.yaml +0 -0
- /package/public/rjbuild/docs/{chartjs → integration/chartjs}/components.yaml +0 -0
- /package/public/rjbuild/docs/{chartjs → integration/chartjs}/overview.yaml +0 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# usePagination
|
|
2
|
+
|
|
3
|
+
Creates customizable pagination systems with configurable components and advanced navigation logic.
|
|
4
|
+
|
|
5
|
+
## Hook Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
const {
|
|
9
|
+
firstShownItemIndex,
|
|
10
|
+
getPageCountForContent,
|
|
11
|
+
maxShownItemIndexExcluded,
|
|
12
|
+
PageControls,
|
|
13
|
+
pageMaxItemCount,
|
|
14
|
+
sliceVisibleContent,
|
|
15
|
+
} = usePagination({
|
|
16
|
+
customComponents = {},
|
|
17
|
+
containerProps = {},
|
|
18
|
+
dataToPaginate = [],
|
|
19
|
+
forcePaginationDisplay = false,
|
|
20
|
+
itemProps = {},
|
|
21
|
+
maxPageButtonsCount = 5,
|
|
22
|
+
pageMaxItemCount = 10,
|
|
23
|
+
})
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Parameters
|
|
27
|
+
|
|
28
|
+
- `customComponents` (object, optional): Custom components to override defaults
|
|
29
|
+
- `Container`: Pagination container component
|
|
30
|
+
- `First`: First page button
|
|
31
|
+
- `Prev`: Previous page button
|
|
32
|
+
- `Item`: Numbered page button
|
|
33
|
+
- `Ellipsis`: Hidden pages indicator ("...")
|
|
34
|
+
- `Next`: Next page button
|
|
35
|
+
- `Last`: Last page button
|
|
36
|
+
- `containerProps` (object, optional): Additional props passed to container component
|
|
37
|
+
- `dataToPaginate` (array, optional): Complete data to paginate (used for page count calculation)
|
|
38
|
+
- `forcePaginationDisplay` (boolean, optional): Force pagination display even with less than 2 pages
|
|
39
|
+
- `itemProps` (object, optional): Additional props passed to page buttons
|
|
40
|
+
- `maxPageButtonsCount` (number, optional): Maximum number of page buttons to display (default: 5)
|
|
41
|
+
- `pageMaxItemCount` (number, optional): Maximum items per page (default: 10)
|
|
42
|
+
|
|
43
|
+
## Return Values
|
|
44
|
+
|
|
45
|
+
- `firstShownItemIndex` (number): Index of first item displayed for active page (for `slice()`)
|
|
46
|
+
- `getPageCountForContent` (function): Function to calculate page count for given content
|
|
47
|
+
- `maxShownItemIndexExcluded` (number): Exclusive index of last displayed item (for `slice()`)
|
|
48
|
+
- `PageControls` (function): React component containing pagination controls
|
|
49
|
+
- `pageMaxItemCount` (number): Maximum items per page (same as parameter)
|
|
50
|
+
- `sliceVisibleContent` (function): Function to slice array according to active page
|
|
51
|
+
|
|
52
|
+
## Component Override System
|
|
53
|
+
|
|
54
|
+
The `usePagination` hook uses a sophisticated component override system that allows you to customize pagination appearance and behavior at three different levels.
|
|
55
|
+
|
|
56
|
+
### Resolution Priority
|
|
57
|
+
|
|
58
|
+
The hook resolves components using this priority order:
|
|
59
|
+
|
|
60
|
+
1. **Custom Components** (highest priority): Components passed via `customComponents` parameter
|
|
61
|
+
2. **Plugin Components** (medium priority): Components from `globalDataContext.plugins.pagination`
|
|
62
|
+
3. **Default Components** (fallback): Built-in components with basic styling
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const PaginationContainer = customComponents.Container ?? pluginComponents.Container ?? DefaultPaginationContainer;
|
|
66
|
+
const PaginationFirst = customComponents.First ?? pluginComponents.First ?? DefaultPaginationFirst;
|
|
67
|
+
const PaginationPrev = customComponents.Prev ?? pluginComponents.Prev ?? DefaultPaginationPrev;
|
|
68
|
+
const PaginationItem = customComponents.Item ?? pluginComponents.Item ?? DefaultPaginationItem;
|
|
69
|
+
const PaginationEllipsis = customComponents.Ellipsis ?? pluginComponents.Ellipsis ?? DefaultPaginationEllipsis;
|
|
70
|
+
const PaginationNext = customComponents.Next ?? pluginComponents.Next ?? DefaultPaginationNext;
|
|
71
|
+
const PaginationLast = customComponents.Last ?? pluginComponents.Last ?? DefaultPaginationLast;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Available Component Slots
|
|
75
|
+
|
|
76
|
+
Each component receives specific props automatically from the hook:
|
|
77
|
+
|
|
78
|
+
#### Container
|
|
79
|
+
```javascript
|
|
80
|
+
// Props: { children, ...containerProps }
|
|
81
|
+
Container: ({ children, ...props }) => <nav {...props}>{children}</nav>
|
|
82
|
+
```
|
|
83
|
+
- **Purpose**: Wraps the entire pagination
|
|
84
|
+
- **Receives**: All children components and `containerProps` from hook parameters
|
|
85
|
+
|
|
86
|
+
#### First & Last
|
|
87
|
+
```javascript
|
|
88
|
+
// Props: { disabled, onClick, children, ...props }
|
|
89
|
+
First: ({ disabled, onClick, children, ...props }) => (
|
|
90
|
+
<button disabled={disabled} onClick={onClick} {...props}>
|
|
91
|
+
{children ?? "«"}
|
|
92
|
+
</button>
|
|
93
|
+
)
|
|
94
|
+
```
|
|
95
|
+
- **Purpose**: Navigate to first/last page
|
|
96
|
+
- **Receives**: `disabled` (boolean), `onClick` handler, optional `children` content
|
|
97
|
+
|
|
98
|
+
#### Prev & Next
|
|
99
|
+
```javascript
|
|
100
|
+
// Props: { disabled, onClick, children, ...props }
|
|
101
|
+
Prev: ({ disabled, onClick, children, ...props }) => (
|
|
102
|
+
<button disabled={disabled} onClick={onClick} {...props}>
|
|
103
|
+
{children ?? "‹"}
|
|
104
|
+
</button>
|
|
105
|
+
)
|
|
106
|
+
```
|
|
107
|
+
- **Purpose**: Navigate to previous/next page
|
|
108
|
+
- **Receives**: `disabled` (boolean), `onClick` handler, optional `children` content
|
|
109
|
+
|
|
110
|
+
#### Item (Page Numbers)
|
|
111
|
+
```javascript
|
|
112
|
+
// Props: { active, disabled, onClick, children, ...itemProps }
|
|
113
|
+
Item: ({ active, disabled, onClick, children, ...props }) => (
|
|
114
|
+
<button
|
|
115
|
+
disabled={disabled}
|
|
116
|
+
onClick={onClick}
|
|
117
|
+
aria-current={active ? "page" : undefined}
|
|
118
|
+
{...props}
|
|
119
|
+
>
|
|
120
|
+
{children} {/* Page number */}
|
|
121
|
+
</button>
|
|
122
|
+
)
|
|
123
|
+
```
|
|
124
|
+
- **Purpose**: Individual page number buttons
|
|
125
|
+
- **Receives**: `active` (boolean), `disabled`, `onClick`, `children` (page number), `itemProps`
|
|
126
|
+
|
|
127
|
+
#### Ellipsis
|
|
128
|
+
```javascript
|
|
129
|
+
// Props: { children, ...props }
|
|
130
|
+
Ellipsis: ({ children, ...props }) => (
|
|
131
|
+
<span {...props}>{children ?? "…"}</span>
|
|
132
|
+
)
|
|
133
|
+
```
|
|
134
|
+
- **Purpose**: Indicates hidden pages
|
|
135
|
+
- **Receives**: Optional `children` content (defaults to "…")
|
|
136
|
+
|
|
137
|
+
### Override Scenarios
|
|
138
|
+
|
|
139
|
+
#### 1. Custom Components (Per-Hook Override)
|
|
140
|
+
```javascript
|
|
141
|
+
const { PageControls } = usePagination({
|
|
142
|
+
customComponents: {
|
|
143
|
+
// Override specific components for this hook instance
|
|
144
|
+
Item: ({ active, disabled, onClick, children, ...props }) => (
|
|
145
|
+
<button
|
|
146
|
+
className={`my-page-btn ${active ? 'active' : ''}`}
|
|
147
|
+
disabled={disabled}
|
|
148
|
+
onClick={onClick}
|
|
149
|
+
{...props}
|
|
150
|
+
>
|
|
151
|
+
Page {children}
|
|
152
|
+
</button>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### 2. Plugin Components (Global Override)
|
|
159
|
+
```javascript
|
|
160
|
+
// In your plugin configuration
|
|
161
|
+
const myPaginationPlugin = {
|
|
162
|
+
pagination: {
|
|
163
|
+
// These components will be used by ALL usePagination hooks
|
|
164
|
+
Container: MyCustomContainer,
|
|
165
|
+
Item: MyCustomPageButton,
|
|
166
|
+
Next: MyCustomNextButton
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const plugins = mergeComponentCollections([myPaginationPlugin]);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### 3. Mixed Override Strategy
|
|
174
|
+
```javascript
|
|
175
|
+
// Plugin provides base customization
|
|
176
|
+
const plugins = mergeComponentCollections([bootstrapPaginationPlugin]);
|
|
177
|
+
|
|
178
|
+
// Specific hook overrides just the container
|
|
179
|
+
const { PageControls } = usePagination({
|
|
180
|
+
customComponents: {
|
|
181
|
+
Container: ({ children, ...props }) => (
|
|
182
|
+
<nav className="special-nav" {...props}>
|
|
183
|
+
<div className="custom-wrapper">{children}</div>
|
|
184
|
+
</nav>
|
|
185
|
+
)
|
|
186
|
+
// Item, Prev, Next, etc. will use plugin components
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Page Button Logic
|
|
192
|
+
|
|
193
|
+
The hook uses intelligent logic for button display:
|
|
194
|
+
|
|
195
|
+
- **Pages 1, 2, 3**: `[1,2,3,4,5]`
|
|
196
|
+
- **Page 4**: `[2,3,4,5,6]`
|
|
197
|
+
- **Page 5**: `[3,4,5,6,7]`
|
|
198
|
+
- **Final pages**: `[6,7,8,9,10]`
|
|
199
|
+
|
|
200
|
+
Smart ellipses (`...`) appear automatically when pages are hidden between visible buttons and extremes.
|
|
201
|
+
|
|
202
|
+
## Example Usage
|
|
203
|
+
|
|
204
|
+
```jsx
|
|
205
|
+
import { usePagination } from '@ea-lab/reactive-json';
|
|
206
|
+
|
|
207
|
+
const MyPaginatedList = ({ items }) => {
|
|
208
|
+
const {
|
|
209
|
+
PageControls,
|
|
210
|
+
sliceVisibleContent,
|
|
211
|
+
} = usePagination({
|
|
212
|
+
dataToPaginate: items,
|
|
213
|
+
pageMaxItemCount: 20,
|
|
214
|
+
maxPageButtonsCount: 7,
|
|
215
|
+
customComponents: {
|
|
216
|
+
Container: ({ children, ...props }) => (
|
|
217
|
+
<nav className="custom-pagination" {...props}>
|
|
218
|
+
<div className="pagination-wrapper">{children}</div>
|
|
219
|
+
</nav>
|
|
220
|
+
),
|
|
221
|
+
Item: ({ active, disabled, onClick, children, ...props }) => (
|
|
222
|
+
<button
|
|
223
|
+
className={`custom-page-btn ${active ? 'active' : ''}`}
|
|
224
|
+
disabled={disabled}
|
|
225
|
+
onClick={onClick}
|
|
226
|
+
{...props}
|
|
227
|
+
>
|
|
228
|
+
{children}
|
|
229
|
+
</button>
|
|
230
|
+
),
|
|
231
|
+
Prev: ({ disabled, onClick, children, ...props }) => (
|
|
232
|
+
<button
|
|
233
|
+
className="custom-prev-btn"
|
|
234
|
+
disabled={disabled}
|
|
235
|
+
onClick={onClick}
|
|
236
|
+
{...props}
|
|
237
|
+
>
|
|
238
|
+
{children ?? 'Previous'}
|
|
239
|
+
</button>
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const visibleItems = sliceVisibleContent(items);
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<div>
|
|
248
|
+
<div className="items-list">
|
|
249
|
+
{visibleItems.map(item => (
|
|
250
|
+
<div key={item.id}>{item.name}</div>
|
|
251
|
+
))}
|
|
252
|
+
</div>
|
|
253
|
+
<PageControls />
|
|
254
|
+
</div>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Plugin Integration
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
// Plugin with custom pagination components
|
|
263
|
+
const paginationPlugin = {
|
|
264
|
+
pagination: {
|
|
265
|
+
Container: BootstrapPaginationContainer,
|
|
266
|
+
Item: BootstrapPaginationItem,
|
|
267
|
+
Next: BootstrapPaginationNext,
|
|
268
|
+
Prev: BootstrapPaginationPrev,
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Hook will automatically use these components
|
|
273
|
+
const plugins = mergeComponentCollections([paginationPlugin]);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Performance Notes
|
|
277
|
+
|
|
278
|
+
- Hook maintains active page state internally
|
|
279
|
+
- Page calculations optimized to avoid unnecessary re-calculations
|
|
280
|
+
- `sliceVisibleContent` useful for complete in-memory collections
|
|
281
|
+
- For very large collections, prefer server-side pagination
|
|
282
|
+
|
|
283
|
+
## Known Limitations
|
|
284
|
+
|
|
285
|
+
- Pagination doesn't automatically update when data filters change (`currentData`)
|
|
286
|
+
- Future version: support for synchronization with external data changes
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
renderView:
|
|
2
|
+
- type: Markdown
|
|
3
|
+
content: |
|
|
4
|
+
# usePagination
|
|
5
|
+
|
|
6
|
+
Creates customizable pagination systems with configurable components and advanced navigation logic.
|
|
7
|
+
|
|
8
|
+
## Hook Signature
|
|
9
|
+
|
|
10
|
+
- type: SyntaxHighlighter
|
|
11
|
+
language: "javascript"
|
|
12
|
+
content: |
|
|
13
|
+
const {
|
|
14
|
+
firstShownItemIndex,
|
|
15
|
+
getPageCountForContent,
|
|
16
|
+
maxShownItemIndexExcluded,
|
|
17
|
+
PageControls,
|
|
18
|
+
pageMaxItemCount,
|
|
19
|
+
sliceVisibleContent,
|
|
20
|
+
} = usePagination({
|
|
21
|
+
customComponents = {},
|
|
22
|
+
containerProps = {},
|
|
23
|
+
dataToPaginate = [],
|
|
24
|
+
forcePaginationDisplay = false,
|
|
25
|
+
itemProps = {},
|
|
26
|
+
maxPageButtonsCount = 5,
|
|
27
|
+
pageMaxItemCount = 10,
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
- type: Markdown
|
|
31
|
+
content: |
|
|
32
|
+
## Parameters
|
|
33
|
+
|
|
34
|
+
- type: DefinitionList
|
|
35
|
+
content:
|
|
36
|
+
- term:
|
|
37
|
+
code: customComponents
|
|
38
|
+
after: "(object, optional)"
|
|
39
|
+
details: "Custom components to override defaults (Container, First, Prev, Item, Ellipsis, Next, Last)"
|
|
40
|
+
- term:
|
|
41
|
+
code: containerProps
|
|
42
|
+
after: "(object, optional)"
|
|
43
|
+
details: "Additional props passed to container component"
|
|
44
|
+
- term:
|
|
45
|
+
code: dataToPaginate
|
|
46
|
+
after: "(array, optional)"
|
|
47
|
+
details: "Complete data to paginate (used for page count calculation)"
|
|
48
|
+
- term:
|
|
49
|
+
code: forcePaginationDisplay
|
|
50
|
+
after: "(boolean, optional)"
|
|
51
|
+
details: "Force pagination display even with less than 2 pages"
|
|
52
|
+
- term:
|
|
53
|
+
code: itemProps
|
|
54
|
+
after: "(object, optional)"
|
|
55
|
+
details: "Additional props passed to page buttons"
|
|
56
|
+
- term:
|
|
57
|
+
code: maxPageButtonsCount
|
|
58
|
+
after: "(number, optional)"
|
|
59
|
+
details: "Maximum number of page buttons to display (default: 5)"
|
|
60
|
+
- term:
|
|
61
|
+
code: pageMaxItemCount
|
|
62
|
+
after: "(number, optional)"
|
|
63
|
+
details: "Maximum items per page (default: 10)"
|
|
64
|
+
|
|
65
|
+
- type: Markdown
|
|
66
|
+
content: |
|
|
67
|
+
## Return Values
|
|
68
|
+
|
|
69
|
+
- type: DefinitionList
|
|
70
|
+
content:
|
|
71
|
+
- term:
|
|
72
|
+
code: firstShownItemIndex
|
|
73
|
+
after: "(number)"
|
|
74
|
+
details: "Index of first item displayed for active page (for slice())"
|
|
75
|
+
- term:
|
|
76
|
+
code: getPageCountForContent
|
|
77
|
+
after: "(function)"
|
|
78
|
+
details: "Function to calculate page count for given content"
|
|
79
|
+
- term:
|
|
80
|
+
code: maxShownItemIndexExcluded
|
|
81
|
+
after: "(number)"
|
|
82
|
+
details: "Exclusive index of last displayed item (for slice())"
|
|
83
|
+
- term:
|
|
84
|
+
code: PageControls
|
|
85
|
+
after: "(function)"
|
|
86
|
+
details: "React component containing pagination controls"
|
|
87
|
+
- term:
|
|
88
|
+
code: pageMaxItemCount
|
|
89
|
+
after: "(number)"
|
|
90
|
+
details: "Maximum items per page (same as parameter)"
|
|
91
|
+
- term:
|
|
92
|
+
code: sliceVisibleContent
|
|
93
|
+
after: "(function)"
|
|
94
|
+
details: "Function to slice array according to active page"
|
|
95
|
+
|
|
96
|
+
- type: Markdown
|
|
97
|
+
content: |
|
|
98
|
+
## Component Override System
|
|
99
|
+
|
|
100
|
+
The `usePagination` hook uses a sophisticated component override system that allows you to customize pagination appearance and behavior at three different levels.
|
|
101
|
+
|
|
102
|
+
### Resolution Priority
|
|
103
|
+
|
|
104
|
+
The hook resolves components using this priority order:
|
|
105
|
+
|
|
106
|
+
1. **Custom Components** (highest priority): Components passed via `customComponents` parameter
|
|
107
|
+
2. **Plugin Components** (medium priority): Components from `globalDataContext.plugins.pagination`
|
|
108
|
+
3. **Default Components** (fallback): Built-in components with basic styling
|
|
109
|
+
|
|
110
|
+
- type: SyntaxHighlighter
|
|
111
|
+
language: "javascript"
|
|
112
|
+
content: |
|
|
113
|
+
const PaginationContainer = customComponents.Container ?? pluginComponents.Container ?? DefaultPaginationContainer;
|
|
114
|
+
const PaginationFirst = customComponents.First ?? pluginComponents.First ?? DefaultPaginationFirst;
|
|
115
|
+
const PaginationPrev = customComponents.Prev ?? pluginComponents.Prev ?? DefaultPaginationPrev;
|
|
116
|
+
const PaginationItem = customComponents.Item ?? pluginComponents.Item ?? DefaultPaginationItem;
|
|
117
|
+
const PaginationEllipsis = customComponents.Ellipsis ?? pluginComponents.Ellipsis ?? DefaultPaginationEllipsis;
|
|
118
|
+
const PaginationNext = customComponents.Next ?? pluginComponents.Next ?? DefaultPaginationNext;
|
|
119
|
+
const PaginationLast = customComponents.Last ?? pluginComponents.Last ?? DefaultPaginationLast;
|
|
120
|
+
|
|
121
|
+
- type: Markdown
|
|
122
|
+
content: |
|
|
123
|
+
### Available Component Slots
|
|
124
|
+
|
|
125
|
+
Each component receives specific props automatically from the hook:
|
|
126
|
+
|
|
127
|
+
#### Container
|
|
128
|
+
- **Purpose**: Wraps the entire pagination
|
|
129
|
+
- **Props**: `{ children, ...containerProps }`
|
|
130
|
+
|
|
131
|
+
#### First & Last
|
|
132
|
+
- **Purpose**: Navigate to first/last page
|
|
133
|
+
- **Props**: `{ disabled, onClick, children, ...props }`
|
|
134
|
+
|
|
135
|
+
#### Prev & Next
|
|
136
|
+
- **Purpose**: Navigate to previous/next page
|
|
137
|
+
- **Props**: `{ disabled, onClick, children, ...props }`
|
|
138
|
+
|
|
139
|
+
#### Item (Page Numbers)
|
|
140
|
+
- **Purpose**: Individual page number buttons
|
|
141
|
+
- **Props**: `{ active, disabled, onClick, children, ...itemProps }`
|
|
142
|
+
|
|
143
|
+
#### Ellipsis
|
|
144
|
+
- **Purpose**: Indicates hidden pages
|
|
145
|
+
- **Props**: `{ children, ...props }`
|
|
146
|
+
|
|
147
|
+
### Override Scenarios
|
|
148
|
+
|
|
149
|
+
#### 1. Custom Components (Per-Hook Override)
|
|
150
|
+
|
|
151
|
+
- type: SyntaxHighlighter
|
|
152
|
+
language: "javascript"
|
|
153
|
+
content: |
|
|
154
|
+
const { PageControls } = usePagination({
|
|
155
|
+
customComponents: {
|
|
156
|
+
// Override specific components for this hook instance
|
|
157
|
+
Item: ({ active, disabled, onClick, children, ...props }) => (
|
|
158
|
+
<button
|
|
159
|
+
className={`my-page-btn ${active ? 'active' : ''}`}
|
|
160
|
+
disabled={disabled}
|
|
161
|
+
onClick={onClick}
|
|
162
|
+
{...props}
|
|
163
|
+
>
|
|
164
|
+
Page {children}
|
|
165
|
+
</button>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
- type: Markdown
|
|
171
|
+
content: |
|
|
172
|
+
#### 2. Plugin Components (Global Override)
|
|
173
|
+
|
|
174
|
+
- type: SyntaxHighlighter
|
|
175
|
+
language: "javascript"
|
|
176
|
+
content: |
|
|
177
|
+
// In your plugin configuration
|
|
178
|
+
const myPaginationPlugin = {
|
|
179
|
+
pagination: {
|
|
180
|
+
// These components will be used by ALL usePagination hooks
|
|
181
|
+
Container: MyCustomContainer,
|
|
182
|
+
Item: MyCustomPageButton,
|
|
183
|
+
Next: MyCustomNextButton
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const plugins = mergeComponentCollections([myPaginationPlugin]);
|
|
188
|
+
|
|
189
|
+
- type: Markdown
|
|
190
|
+
content: |
|
|
191
|
+
#### 3. Mixed Override Strategy
|
|
192
|
+
|
|
193
|
+
- type: SyntaxHighlighter
|
|
194
|
+
language: "javascript"
|
|
195
|
+
content: |
|
|
196
|
+
// Plugin provides base customization
|
|
197
|
+
const plugins = mergeComponentCollections([bootstrapPaginationPlugin]);
|
|
198
|
+
|
|
199
|
+
// Specific hook overrides just the container
|
|
200
|
+
const { PageControls } = usePagination({
|
|
201
|
+
customComponents: {
|
|
202
|
+
Container: ({ children, ...props }) => (
|
|
203
|
+
<nav className="special-nav" {...props}>
|
|
204
|
+
<div className="custom-wrapper">{children}</div>
|
|
205
|
+
</nav>
|
|
206
|
+
)
|
|
207
|
+
// Item, Prev, Next, etc. will use plugin components
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
- type: Markdown
|
|
212
|
+
content: |
|
|
213
|
+
## Page Button Logic
|
|
214
|
+
|
|
215
|
+
The hook uses intelligent logic for button display:
|
|
216
|
+
|
|
217
|
+
- **Pages 1, 2, 3**: `[1,2,3,4,5]`
|
|
218
|
+
- **Page 4**: `[2,3,4,5,6]`
|
|
219
|
+
- **Page 5**: `[3,4,5,6,7]`
|
|
220
|
+
- **Final pages**: `[6,7,8,9,10]`
|
|
221
|
+
|
|
222
|
+
Smart ellipses (`...`) appear automatically when pages are hidden between visible buttons and extremes.
|
|
223
|
+
|
|
224
|
+
- type: Markdown
|
|
225
|
+
content: |
|
|
226
|
+
## Example Usage
|
|
227
|
+
|
|
228
|
+
- type: SyntaxHighlighter
|
|
229
|
+
language: "jsx"
|
|
230
|
+
content: |
|
|
231
|
+
import { usePagination } from '@ea-lab/reactive-json';
|
|
232
|
+
|
|
233
|
+
const MyPaginatedList = ({ items }) => {
|
|
234
|
+
const {
|
|
235
|
+
PageControls,
|
|
236
|
+
sliceVisibleContent,
|
|
237
|
+
} = usePagination({
|
|
238
|
+
dataToPaginate: items,
|
|
239
|
+
pageMaxItemCount: 20,
|
|
240
|
+
maxPageButtonsCount: 7,
|
|
241
|
+
customComponents: {
|
|
242
|
+
Container: ({ children, ...props }) => (
|
|
243
|
+
<nav className="custom-pagination" {...props}>
|
|
244
|
+
<div className="pagination-wrapper">{children}</div>
|
|
245
|
+
</nav>
|
|
246
|
+
),
|
|
247
|
+
Item: ({ active, disabled, onClick, children, ...props }) => (
|
|
248
|
+
<button
|
|
249
|
+
className={`custom-page-btn ${active ? 'active' : ''}`}
|
|
250
|
+
disabled={disabled}
|
|
251
|
+
onClick={onClick}
|
|
252
|
+
{...props}
|
|
253
|
+
>
|
|
254
|
+
{children}
|
|
255
|
+
</button>
|
|
256
|
+
),
|
|
257
|
+
Prev: ({ disabled, onClick, children, ...props }) => (
|
|
258
|
+
<button
|
|
259
|
+
className="custom-prev-btn"
|
|
260
|
+
disabled={disabled}
|
|
261
|
+
onClick={onClick}
|
|
262
|
+
{...props}
|
|
263
|
+
>
|
|
264
|
+
{children ?? 'Previous'}
|
|
265
|
+
</button>
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const visibleItems = sliceVisibleContent(items);
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<div>
|
|
274
|
+
<div className="items-list">
|
|
275
|
+
{visibleItems.map(item => (
|
|
276
|
+
<div key={item.id}>{item.name}</div>
|
|
277
|
+
))}
|
|
278
|
+
</div>
|
|
279
|
+
<PageControls />
|
|
280
|
+
</div>
|
|
281
|
+
);
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
- type: Markdown
|
|
285
|
+
content: |
|
|
286
|
+
## Plugin Integration
|
|
287
|
+
|
|
288
|
+
- type: SyntaxHighlighter
|
|
289
|
+
language: "javascript"
|
|
290
|
+
content: |
|
|
291
|
+
// Plugin with custom pagination components
|
|
292
|
+
const paginationPlugin = {
|
|
293
|
+
pagination: {
|
|
294
|
+
Container: BootstrapPaginationContainer,
|
|
295
|
+
Item: BootstrapPaginationItem,
|
|
296
|
+
Next: BootstrapPaginationNext,
|
|
297
|
+
Prev: BootstrapPaginationPrev,
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// Hook will automatically use these components
|
|
302
|
+
const plugins = mergeComponentCollections([paginationPlugin]);
|
|
303
|
+
|
|
304
|
+
- type: Markdown
|
|
305
|
+
content: |
|
|
306
|
+
## Performance Notes
|
|
307
|
+
|
|
308
|
+
- Hook maintains active page state internally
|
|
309
|
+
- Page calculations optimized to avoid unnecessary re-calculations
|
|
310
|
+
- `sliceVisibleContent` useful for complete in-memory collections
|
|
311
|
+
- For very large collections, prefer server-side pagination
|
|
312
|
+
|
|
313
|
+
## Known Limitations
|
|
314
|
+
|
|
315
|
+
- Pagination doesn't automatically update when data filters change (`currentData`)
|
|
316
|
+
- Future version: support for synchronization with external data changes
|
|
317
|
+
|
|
318
|
+
templates: {}
|
|
319
|
+
data: {}
|