@startsimpli/ui 0.1.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/README.md +537 -0
- package/package.json +80 -0
- package/src/components/index.ts +50 -0
- package/src/components/navigation/sidebar.tsx +178 -0
- package/src/components/ui/accordion.tsx +58 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/button.tsx +57 -0
- package/src/components/ui/calendar.tsx +70 -0
- package/src/components/ui/card.tsx +68 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/collapsible.tsx +12 -0
- package/src/components/ui/dialog.tsx +122 -0
- package/src/components/ui/dropdown-menu.tsx +200 -0
- package/src/components/ui/index.ts +24 -0
- package/src/components/ui/input.tsx +25 -0
- package/src/components/ui/label.tsx +26 -0
- package/src/components/ui/popover.tsx +31 -0
- package/src/components/ui/progress.tsx +28 -0
- package/src/components/ui/scroll-area.tsx +48 -0
- package/src/components/ui/select.tsx +160 -0
- package/src/components/ui/separator.tsx +31 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/table.tsx +117 -0
- package/src/components/ui/tabs.tsx +55 -0
- package/src/components/ui/textarea.tsx +24 -0
- package/src/components/ui/tooltip.tsx +30 -0
- package/src/components/unified-table/UnifiedTable.tsx +553 -0
- package/src/components/unified-table/__tests__/components/BulkActionBar.test.tsx +477 -0
- package/src/components/unified-table/__tests__/components/ExportButton.test.tsx +467 -0
- package/src/components/unified-table/__tests__/components/InlineEditCell.test.tsx +159 -0
- package/src/components/unified-table/__tests__/components/SavedViewsDropdown.test.tsx +128 -0
- package/src/components/unified-table/__tests__/components/TablePagination.test.tsx +374 -0
- package/src/components/unified-table/__tests__/hooks/useColumnReorder.test.ts +191 -0
- package/src/components/unified-table/__tests__/hooks/useColumnResize.test.ts +122 -0
- package/src/components/unified-table/__tests__/hooks/useColumnVisibility.test.ts +594 -0
- package/src/components/unified-table/__tests__/hooks/useFilters.test.ts +460 -0
- package/src/components/unified-table/__tests__/hooks/usePagination.test.ts +439 -0
- package/src/components/unified-table/__tests__/hooks/useResponsive.test.ts +421 -0
- package/src/components/unified-table/__tests__/hooks/useSelection.test.ts +367 -0
- package/src/components/unified-table/__tests__/hooks/useTableKeyboard.test.ts +803 -0
- package/src/components/unified-table/__tests__/hooks/useTableState.test.ts +210 -0
- package/src/components/unified-table/__tests__/integration/table-with-selection.test.tsx +624 -0
- package/src/components/unified-table/__tests__/utils/export.test.ts +427 -0
- package/src/components/unified-table/components/BulkActionBar/index.tsx +119 -0
- package/src/components/unified-table/components/DataTableCore/index.tsx +473 -0
- package/src/components/unified-table/components/InlineEditCell/index.tsx +159 -0
- package/src/components/unified-table/components/MobileView/Card.tsx +218 -0
- package/src/components/unified-table/components/MobileView/CardActions.tsx +126 -0
- package/src/components/unified-table/components/MobileView/README.md +411 -0
- package/src/components/unified-table/components/MobileView/index.tsx +77 -0
- package/src/components/unified-table/components/MobileView/types.ts +77 -0
- package/src/components/unified-table/components/TableFilters/index.tsx +298 -0
- package/src/components/unified-table/components/TablePagination/index.tsx +157 -0
- package/src/components/unified-table/components/Toolbar/ExportButton.tsx +229 -0
- package/src/components/unified-table/components/Toolbar/SavedViewsDropdown.tsx +251 -0
- package/src/components/unified-table/components/Toolbar/StandardTableToolbar.tsx +146 -0
- package/src/components/unified-table/components/Toolbar/index.tsx +3 -0
- package/src/components/unified-table/hooks/index.ts +21 -0
- package/src/components/unified-table/hooks/useColumnReorder.ts +90 -0
- package/src/components/unified-table/hooks/useColumnResize.ts +123 -0
- package/src/components/unified-table/hooks/useColumnVisibility.ts +92 -0
- package/src/components/unified-table/hooks/useFilters.ts +53 -0
- package/src/components/unified-table/hooks/usePagination.ts +120 -0
- package/src/components/unified-table/hooks/useResponsive.ts +50 -0
- package/src/components/unified-table/hooks/useSelection.ts +152 -0
- package/src/components/unified-table/hooks/useTableKeyboard.ts +206 -0
- package/src/components/unified-table/hooks/useTablePreferences.ts +198 -0
- package/src/components/unified-table/hooks/useTableState.ts +103 -0
- package/src/components/unified-table/hooks/useTableURL.test.tsx +921 -0
- package/src/components/unified-table/hooks/useTableURL.ts +301 -0
- package/src/components/unified-table/index.ts +16 -0
- package/src/components/unified-table/types.ts +393 -0
- package/src/components/unified-table/utils/export.ts +236 -0
- package/src/components/unified-table/utils/index.ts +4 -0
- package/src/components/unified-table/utils/renderers.ts +105 -0
- package/src/components/unified-table/utils/themes.ts +87 -0
- package/src/components/unified-table/utils/validation.ts +122 -0
- package/src/index.ts +6 -0
- package/src/lib/utils.ts +1 -0
- package/src/theme/contract.ts +46 -0
- package/src/theme/index.ts +9 -0
- package/src/theme/tailwind.config.js +70 -0
- package/src/theme/tailwind.preset.ts +93 -0
- package/src/utils/cn.ts +6 -0
- package/src/utils/index.ts +91 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { renderHook, act } from '@testing-library/react'
|
|
2
|
+
import { usePagination } from '../../hooks/usePagination'
|
|
3
|
+
|
|
4
|
+
describe('usePagination', () => {
|
|
5
|
+
const defaultProps = {
|
|
6
|
+
totalCount: 100,
|
|
7
|
+
initialPageSize: 25,
|
|
8
|
+
initialPage: 1,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('Initialization', () => {
|
|
12
|
+
it('should initialize with default values', () => {
|
|
13
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
14
|
+
|
|
15
|
+
expect(result.current.currentPage).toBe(1)
|
|
16
|
+
expect(result.current.pageSize).toBe(25)
|
|
17
|
+
expect(result.current.totalPages).toBe(4)
|
|
18
|
+
expect(result.current.totalCount).toBe(100)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should initialize with custom page size', () => {
|
|
22
|
+
const { result } = renderHook(() =>
|
|
23
|
+
usePagination({ ...defaultProps, initialPageSize: 50 })
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
expect(result.current.pageSize).toBe(50)
|
|
27
|
+
expect(result.current.totalPages).toBe(2)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should initialize with custom initial page', () => {
|
|
31
|
+
const { result } = renderHook(() =>
|
|
32
|
+
usePagination({ ...defaultProps, initialPage: 2 })
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
expect(result.current.currentPage).toBe(2)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe('Total Pages Calculation', () => {
|
|
40
|
+
it('should calculate total pages correctly', () => {
|
|
41
|
+
const { result } = renderHook(() =>
|
|
42
|
+
usePagination({ ...defaultProps, totalCount: 100, initialPageSize: 25 })
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
expect(result.current.totalPages).toBe(4)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('should round up for partial pages', () => {
|
|
49
|
+
const { result } = renderHook(() =>
|
|
50
|
+
usePagination({ ...defaultProps, totalCount: 101, initialPageSize: 25 })
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
expect(result.current.totalPages).toBe(5)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should return minimum 1 page for empty data', () => {
|
|
57
|
+
const { result } = renderHook(() =>
|
|
58
|
+
usePagination({ ...defaultProps, totalCount: 0 })
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
expect(result.current.totalPages).toBe(1)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should handle single item', () => {
|
|
65
|
+
const { result } = renderHook(() =>
|
|
66
|
+
usePagination({ ...defaultProps, totalCount: 1 })
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
expect(result.current.totalPages).toBe(1)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe('Navigation - Can Go', () => {
|
|
74
|
+
it('should not allow going previous from first page', () => {
|
|
75
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
76
|
+
|
|
77
|
+
expect(result.current.canGoPrevious).toBe(false)
|
|
78
|
+
expect(result.current.canGoNext).toBe(true)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('should not allow going next from last page', () => {
|
|
82
|
+
const { result } = renderHook(() =>
|
|
83
|
+
usePagination({ ...defaultProps, initialPage: 4 })
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
expect(result.current.canGoNext).toBe(false)
|
|
87
|
+
expect(result.current.canGoPrevious).toBe(true)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('should allow going both directions from middle page', () => {
|
|
91
|
+
const { result } = renderHook(() =>
|
|
92
|
+
usePagination({ ...defaultProps, initialPage: 2 })
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
expect(result.current.canGoNext).toBe(true)
|
|
96
|
+
expect(result.current.canGoPrevious).toBe(true)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should update canGo flags when navigating', () => {
|
|
100
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
101
|
+
|
|
102
|
+
expect(result.current.canGoPrevious).toBe(false)
|
|
103
|
+
|
|
104
|
+
act(() => {
|
|
105
|
+
result.current.goToNextPage()
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
expect(result.current.canGoPrevious).toBe(true)
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
describe('Navigation - Go To Page', () => {
|
|
113
|
+
it('should go to specific page', () => {
|
|
114
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
115
|
+
|
|
116
|
+
act(() => {
|
|
117
|
+
result.current.goToPage(3)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
expect(result.current.currentPage).toBe(3)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('should clamp to valid page range', () => {
|
|
124
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
125
|
+
|
|
126
|
+
act(() => {
|
|
127
|
+
result.current.goToPage(10)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
expect(result.current.currentPage).toBe(4) // Max page
|
|
131
|
+
|
|
132
|
+
act(() => {
|
|
133
|
+
result.current.goToPage(-5)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
expect(result.current.currentPage).toBe(1) // Min page
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('should call onPageChange callback', () => {
|
|
140
|
+
const onPageChange = jest.fn()
|
|
141
|
+
const { result } = renderHook(() =>
|
|
142
|
+
usePagination({ ...defaultProps, onPageChange })
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
act(() => {
|
|
146
|
+
result.current.goToPage(2)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
expect(onPageChange).toHaveBeenCalledWith(2)
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
describe('Navigation - First/Last Page', () => {
|
|
154
|
+
it('should go to first page', () => {
|
|
155
|
+
const { result } = renderHook(() =>
|
|
156
|
+
usePagination({ ...defaultProps, initialPage: 3 })
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
act(() => {
|
|
160
|
+
result.current.goToFirstPage()
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
expect(result.current.currentPage).toBe(1)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('should go to last page', () => {
|
|
167
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
168
|
+
|
|
169
|
+
act(() => {
|
|
170
|
+
result.current.goToLastPage()
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
expect(result.current.currentPage).toBe(4)
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('Navigation - Next/Previous Page', () => {
|
|
178
|
+
it('should go to next page', () => {
|
|
179
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
180
|
+
|
|
181
|
+
act(() => {
|
|
182
|
+
result.current.goToNextPage()
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
expect(result.current.currentPage).toBe(2)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('should go to previous page', () => {
|
|
189
|
+
const { result } = renderHook(() =>
|
|
190
|
+
usePagination({ ...defaultProps, initialPage: 2 })
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
act(() => {
|
|
194
|
+
result.current.goToPreviousPage()
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
expect(result.current.currentPage).toBe(1)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('should not go past last page', () => {
|
|
201
|
+
const { result } = renderHook(() =>
|
|
202
|
+
usePagination({ ...defaultProps, initialPage: 4 })
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
act(() => {
|
|
206
|
+
result.current.goToNextPage()
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
expect(result.current.currentPage).toBe(4) // Should stay on last page
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it('should not go before first page', () => {
|
|
213
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
214
|
+
|
|
215
|
+
act(() => {
|
|
216
|
+
result.current.goToPreviousPage()
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
expect(result.current.currentPage).toBe(1) // Should stay on first page
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
describe('Page Numbers Display', () => {
|
|
224
|
+
it('should show all pages when total is small', () => {
|
|
225
|
+
const { result } = renderHook(() =>
|
|
226
|
+
usePagination({ ...defaultProps, totalCount: 50, initialPageSize: 25 })
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
const pageNumbers = result.current.getPageNumbers()
|
|
230
|
+
expect(pageNumbers).toEqual([1, 2])
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
it('should show ellipsis for many pages', () => {
|
|
234
|
+
const { result } = renderHook(() =>
|
|
235
|
+
usePagination({ ...defaultProps, totalCount: 200, initialPageSize: 10 })
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
const pageNumbers = result.current.getPageNumbers()
|
|
239
|
+
expect(pageNumbers).toContain('...')
|
|
240
|
+
expect(pageNumbers[0]).toBe(1)
|
|
241
|
+
expect(pageNumbers[pageNumbers.length - 1]).toBe(20)
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('should show current page and neighbors', () => {
|
|
245
|
+
const { result } = renderHook(() =>
|
|
246
|
+
usePagination({
|
|
247
|
+
...defaultProps,
|
|
248
|
+
totalCount: 200,
|
|
249
|
+
initialPageSize: 10,
|
|
250
|
+
initialPage: 10,
|
|
251
|
+
})
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
const pageNumbers = result.current.getPageNumbers()
|
|
255
|
+
expect(pageNumbers).toContain(9)
|
|
256
|
+
expect(pageNumbers).toContain(10)
|
|
257
|
+
expect(pageNumbers).toContain(11)
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
it('should update page numbers when navigating', () => {
|
|
261
|
+
const { result } = renderHook(() =>
|
|
262
|
+
usePagination({ ...defaultProps, totalCount: 200, initialPageSize: 10 })
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
act(() => {
|
|
266
|
+
result.current.goToPage(15)
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
const pageNumbers = result.current.getPageNumbers()
|
|
270
|
+
expect(pageNumbers).toContain(14)
|
|
271
|
+
expect(pageNumbers).toContain(15)
|
|
272
|
+
expect(pageNumbers).toContain(16)
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it('should handle first page differently', () => {
|
|
276
|
+
const { result } = renderHook(() =>
|
|
277
|
+
usePagination({ ...defaultProps, totalCount: 200, initialPageSize: 10 })
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
const pageNumbers = result.current.getPageNumbers()
|
|
281
|
+
expect(pageNumbers[0]).toBe(1)
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
it('should handle last page differently', () => {
|
|
285
|
+
const { result } = renderHook(() =>
|
|
286
|
+
usePagination({
|
|
287
|
+
...defaultProps,
|
|
288
|
+
totalCount: 200,
|
|
289
|
+
initialPageSize: 10,
|
|
290
|
+
initialPage: 20,
|
|
291
|
+
})
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
const pageNumbers = result.current.getPageNumbers()
|
|
295
|
+
expect(pageNumbers[pageNumbers.length - 1]).toBe(20)
|
|
296
|
+
})
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
describe('Display Range', () => {
|
|
300
|
+
it('should calculate display range for first page', () => {
|
|
301
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
302
|
+
|
|
303
|
+
const range = result.current.getDisplayRange()
|
|
304
|
+
expect(range).toEqual({ start: 1, end: 25 })
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it('should calculate display range for middle page', () => {
|
|
308
|
+
const { result } = renderHook(() =>
|
|
309
|
+
usePagination({ ...defaultProps, initialPage: 2 })
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
const range = result.current.getDisplayRange()
|
|
313
|
+
expect(range).toEqual({ start: 26, end: 50 })
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
it('should calculate display range for last page with partial data', () => {
|
|
317
|
+
const { result } = renderHook(() =>
|
|
318
|
+
usePagination({ ...defaultProps, totalCount: 90, initialPage: 4 })
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
const range = result.current.getDisplayRange()
|
|
322
|
+
expect(range).toEqual({ start: 76, end: 90 })
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
it('should handle single item on last page', () => {
|
|
326
|
+
const { result } = renderHook(() =>
|
|
327
|
+
usePagination({ ...defaultProps, totalCount: 76, initialPage: 4 })
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
const range = result.current.getDisplayRange()
|
|
331
|
+
expect(range).toEqual({ start: 76, end: 76 })
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
it('should update range when navigating', () => {
|
|
335
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
336
|
+
|
|
337
|
+
act(() => {
|
|
338
|
+
result.current.goToPage(3)
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
const range = result.current.getDisplayRange()
|
|
342
|
+
expect(range).toEqual({ start: 51, end: 75 })
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
describe('Server-Side Pagination', () => {
|
|
347
|
+
it('should handle server-side mode', () => {
|
|
348
|
+
const onPageChange = jest.fn()
|
|
349
|
+
const { result } = renderHook(() =>
|
|
350
|
+
usePagination({ ...defaultProps, serverSide: true, onPageChange })
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
act(() => {
|
|
354
|
+
result.current.goToPage(2)
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
expect(onPageChange).toHaveBeenCalledWith(2)
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
it('should work the same as client-side for navigation', () => {
|
|
361
|
+
const { result } = renderHook(() =>
|
|
362
|
+
usePagination({ ...defaultProps, serverSide: true })
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
act(() => {
|
|
366
|
+
result.current.goToNextPage()
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
expect(result.current.currentPage).toBe(2)
|
|
370
|
+
})
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
describe('Edge Cases', () => {
|
|
374
|
+
it('should handle zero total count', () => {
|
|
375
|
+
const { result } = renderHook(() =>
|
|
376
|
+
usePagination({ ...defaultProps, totalCount: 0 })
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
expect(result.current.totalPages).toBe(1)
|
|
380
|
+
expect(result.current.currentPage).toBe(1)
|
|
381
|
+
expect(result.current.canGoNext).toBe(false)
|
|
382
|
+
expect(result.current.canGoPrevious).toBe(false)
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
it('should handle large page sizes', () => {
|
|
386
|
+
const { result } = renderHook(() =>
|
|
387
|
+
usePagination({ ...defaultProps, initialPageSize: 1000 })
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
expect(result.current.totalPages).toBe(1)
|
|
391
|
+
const range = result.current.getDisplayRange()
|
|
392
|
+
expect(range).toEqual({ start: 1, end: 100 })
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
it('should handle page size changes dynamically', () => {
|
|
396
|
+
const { result, rerender } = renderHook(
|
|
397
|
+
({ pageSize }) => usePagination({ ...defaultProps, initialPageSize: pageSize }),
|
|
398
|
+
{ initialProps: { pageSize: 25 } }
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
expect(result.current.totalPages).toBe(4)
|
|
402
|
+
|
|
403
|
+
rerender({ pageSize: 50 })
|
|
404
|
+
|
|
405
|
+
// Note: Since initialPageSize is only used for initialization,
|
|
406
|
+
// the totalPages will stay the same until internal state is updated
|
|
407
|
+
// This test documents current behavior
|
|
408
|
+
expect(result.current.totalPages).toBe(4)
|
|
409
|
+
})
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
describe('Memoization', () => {
|
|
413
|
+
it('should memoize computed values', () => {
|
|
414
|
+
const { result, rerender } = renderHook(() => usePagination(defaultProps))
|
|
415
|
+
|
|
416
|
+
const firstPageNumbers = result.current.getPageNumbers()
|
|
417
|
+
rerender()
|
|
418
|
+
const secondPageNumbers = result.current.getPageNumbers()
|
|
419
|
+
|
|
420
|
+
// Functions should return consistent results
|
|
421
|
+
expect(firstPageNumbers).toEqual(secondPageNumbers)
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
it('should update memoized values when dependencies change', () => {
|
|
425
|
+
const { result } = renderHook(() => usePagination(defaultProps))
|
|
426
|
+
|
|
427
|
+
const firstCanGoNext = result.current.canGoNext
|
|
428
|
+
|
|
429
|
+
act(() => {
|
|
430
|
+
result.current.goToLastPage()
|
|
431
|
+
})
|
|
432
|
+
|
|
433
|
+
const secondCanGoNext = result.current.canGoNext
|
|
434
|
+
|
|
435
|
+
expect(firstCanGoNext).toBe(true)
|
|
436
|
+
expect(secondCanGoNext).toBe(false)
|
|
437
|
+
})
|
|
438
|
+
})
|
|
439
|
+
})
|