Skip to content

Commit fe01637

Browse files
authored
Merge pull request #3 from aboutbits/different-starting-pages
Adjustable starting pages
2 parents 8afb94c + 7502663 commit fe01637

4 files changed

Lines changed: 111 additions & 14 deletions

File tree

readme.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ Second, you can call the calculate function by passing the following information
2424
- `page`: The current page
2525
- `size`: The amount of items shown per page
2626
- `total`: The amount of total items in the list/collection
27-
- `maxPages`: The maximum amount of pages that should be shown (default: 5)
27+
- `config`: A configuration object containing the following possible configuration values:
28+
- `firstPage`: The first page of the pagination (default: 1)
29+
- `maxPages`: The maximum amount of pages that should be shown (default: 5)
2830

2931
In return, you receive an object with all relevant information:
3032

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { calculatePagination } from '../index'
2+
3+
it('should return no pagination if not enough items are given', () => {
4+
const page = 0
5+
const size = 5
6+
const total = 2
7+
const pagination = calculatePagination(page, size, total, { firstPage: 0 })
8+
9+
expect(pagination).toBeNull()
10+
})
11+
it('should return only a few pages', () => {
12+
const page = 1
13+
const size = 5
14+
const total = 15
15+
const pagination = calculatePagination(page, size, total, { firstPage: 0 })
16+
17+
expect(pagination).not.toBeNull()
18+
expect(pagination?.pages).toHaveLength(3)
19+
20+
expect(pagination?.pages[0].number).toBe(0)
21+
expect(pagination?.pages[0].isCurrent).toBeFalsy()
22+
expect(pagination?.pages[1].number).toBe(1)
23+
expect(pagination?.pages[1].isCurrent).toBeTruthy()
24+
expect(pagination?.pages[2].number).toBe(2)
25+
expect(pagination?.pages[2].isCurrent).toBeFalsy()
26+
})
27+
it('should return the maximum number of pages', () => {
28+
const page = 4
29+
const size = 5
30+
const total = 50
31+
const maxPages = 5
32+
const pagination = calculatePagination(page, size, total, {
33+
firstPage: 0,
34+
maxPages: maxPages,
35+
})
36+
37+
expect(pagination).not.toBeNull()
38+
expect(pagination?.pages).toHaveLength(5)
39+
40+
expect(pagination?.pages[0].number).toBe(2)
41+
expect(pagination?.pages[0].isCurrent).toBeFalsy()
42+
expect(pagination?.pages[1].number).toBe(3)
43+
expect(pagination?.pages[1].isCurrent).toBeFalsy()
44+
expect(pagination?.pages[2].number).toBe(4)
45+
expect(pagination?.pages[2].isCurrent).toBeTruthy()
46+
expect(pagination?.pages[3].number).toBe(5)
47+
expect(pagination?.pages[3].isCurrent).toBeFalsy()
48+
expect(pagination?.pages[4].number).toBe(6)
49+
expect(pagination?.pages[4].isCurrent).toBeFalsy()
50+
})
51+
it('should disable the previous link', () => {
52+
const page = 0
53+
const size = 5
54+
const total = 10
55+
const pagination = calculatePagination(page, size, total, { firstPage: 0 })
56+
57+
expect(pagination).not.toBeNull()
58+
59+
expect(pagination?.previous.number).toBe(0)
60+
expect(pagination?.previous.isDisabled).toBeTruthy()
61+
62+
expect(pagination?.next.number).toBe(1)
63+
expect(pagination?.next.isDisabled).toBeFalsy()
64+
65+
expect(pagination?.pages[0].isCurrent).toBeTruthy()
66+
expect(pagination?.pages[1].isCurrent).toBeFalsy()
67+
})
68+
it('should disable the next link', () => {
69+
const page = 1
70+
const size = 5
71+
const total = 10
72+
const pagination = calculatePagination(page, size, total, { firstPage: 0 })
73+
74+
expect(pagination).not.toBeNull()
75+
76+
expect(pagination?.previous.number).toBe(0)
77+
expect(pagination?.previous.isDisabled).toBeFalsy()
78+
79+
expect(pagination?.next.number).toBe(1)
80+
expect(pagination?.next.isDisabled).toBeTruthy()
81+
82+
expect(pagination?.pages[0].isCurrent).toBeFalsy()
83+
expect(pagination?.pages[1].isCurrent).toBeTruthy()
84+
})

src/__test__/pagination.test.ts renamed to src/__test__/pagination-with-first-page-1.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ it('should return the maximum number of pages', () => {
2929
const size = 5
3030
const total = 50
3131
const maxPages = 5
32-
const pagination = calculatePagination(page, size, total, maxPages)
32+
const pagination = calculatePagination(page, size, total, {
33+
maxPages: maxPages,
34+
})
3335

3436
expect(pagination).not.toBeNull()
3537
expect(pagination?.pages).toHaveLength(5)

src/index.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const calculateVisiblePages = (
22
page: number,
3-
total: number,
3+
firstPage: number,
4+
lastPage: number,
45
maxPages: number
56
): number[] => {
67
const range = Math.floor(maxPages / 2)
7-
let lowerBound = 1
8+
let lowerBound = firstPage
89
let lowerBoundRest = 0
9-
let upperBound = total
10+
let upperBound = lastPage
1011
let upperBoundRest = 0
1112

1213
if (page - range >= 1) {
@@ -15,20 +16,22 @@ const calculateVisiblePages = (
1516
lowerBoundRest = (page - range - 1) * -1
1617
}
1718

18-
if (page + range <= total) {
19+
if (page + range <= lastPage) {
1920
upperBound = page + range
2021
} else {
21-
upperBoundRest = (total - range - page) * -1
22+
upperBoundRest = (lastPage - range - page) * -1
2223
}
2324

2425
if (upperBoundRest > 0) {
2526
lowerBound =
26-
lowerBound - upperBoundRest > 0 ? lowerBound - upperBoundRest : 1
27+
lowerBound - upperBoundRest > 0 ? lowerBound - upperBoundRest : firstPage
2728
}
2829

2930
if (lowerBoundRest > 0) {
3031
upperBound =
31-
upperBound + lowerBoundRest < total ? upperBound + lowerBoundRest : total
32+
upperBound + lowerBoundRest < lastPage
33+
? upperBound + lowerBoundRest
34+
: lastPage
3235
}
3336

3437
const pages = []
@@ -44,7 +47,10 @@ const calculatePagination = (
4447
page: number,
4548
size: number,
4649
total: number,
47-
maxPages = 5
50+
config?: {
51+
firstPage?: number
52+
maxPages?: number
53+
}
4854
): {
4955
previous: {
5056
number: number
@@ -63,20 +69,23 @@ const calculatePagination = (
6369
return null
6470
}
6571

66-
const lastPage = Math.ceil(total / size)
67-
const isCurrentTheFirstPage = page === 1
72+
const firstPage = config?.firstPage ?? 1
73+
const maxPages = config?.maxPages ?? 5
74+
75+
const lastPage = Math.ceil(total / size) + (firstPage - 1)
76+
const isCurrentTheFirstPage = page === firstPage
6877
const isCurrentTheLastPage = page === lastPage
6978

7079
return {
7180
previous: {
72-
number: isCurrentTheFirstPage ? 1 : page - 1,
81+
number: isCurrentTheFirstPage ? firstPage : page - 1,
7382
isDisabled: isCurrentTheFirstPage,
7483
},
7584
next: {
7685
number: isCurrentTheLastPage ? lastPage : page + 1,
7786
isDisabled: isCurrentTheLastPage,
7887
},
79-
pages: calculateVisiblePages(page, lastPage, maxPages).map(
88+
pages: calculateVisiblePages(page, firstPage, lastPage, maxPages).map(
8089
(visiblePage) => {
8190
return {
8291
number: visiblePage,

0 commit comments

Comments
 (0)