Skip to content

Commit 183e5ba

Browse files
Merge pull request #3 from aboutbits/support-filter
Support handling multiple fields, not just search
2 parents 4ff54d3 + 3c20f1c commit 183e5ba

11 files changed

Lines changed: 386 additions & 120 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"eslint-plugin-prettier": "^3.3.1",
5555
"jest": "^26.6.3",
5656
"next": "^11.0.1",
57-
"next-router-mock": "^0.1.4",
57+
"next-router-mock": "^0.6.1",
5858
"prettier": "^2.2.1",
5959
"react": "^17.0.2",
6060
"react-dom": "^17.0.2",

readme.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ React Pagination
44
[![npm package](https://badge.fury.io/js/%40aboutbits%2Freact-pagination.svg)](https://badge.fury.io/js/%40aboutbits%2Freact-pagination)
55
[![license](https://img.shields.io/github/license/aboutbits/react-pagination)](https://github.com/aboutbits/react-pagination/blob/main/license.md)
66

7-
This package includes pagination hooks for React. The hooks support saving the search and pagination values in local
7+
This package includes pagination hooks for React. The hooks support saving the query and pagination values in local
88
state or in the browser URL.
99

1010
## Table of content
1111

1212
- [Usage](#usage)
13-
- [useSearchAndPagination](#usesearchandpagination)
13+
- [useQueryAndPagination](#usequeryandpagination)
1414
- [Supported Implementations](#supported-implementations)
1515
- [In Memory Pagination](#in-memory-pagination)
1616
- [React-Router based pagination](#react-router-based-pagination)
@@ -26,17 +26,17 @@ First, you have to install the package:
2626
npm install @aboutbits/react-pagination
2727
```
2828

29-
Second, you can make use of the `useSearchAndPagination` hook. This package implements 3 versions of this hook:
29+
Second, you can make use of the `useQueryAndPagination` hook. This package implements 3 versions of this hook:
3030

3131
- [In Memory](#in-memory-pagination): Use this hook where you don't want to modify browser history. e.g. Dialogs
3232
- [React Router](#react-router-based-pagination): Use this hook if you want to keep track of the state in the URL and
3333
your project is using React Router.
3434
- [NextJS Router](#nextjs-router-based-pagination): Use this hook if you want to keep track of the state in the URL and
3535
your project is using NextJS.
3636

37-
### useSearchAndPagination
37+
### useQueryAndPagination
3838

39-
This hook supports the combination of a search value and pagination and manages the state of the search value, and the
39+
This hook supports the combination of query parameters and pagination and manages the state of the query parameter values and the
4040
pagination values.
4141

4242
#### The hook supports following configuration parameter object:
@@ -45,39 +45,40 @@ pagination values.
4545
|---|---|---|---|
4646
|indexType|IndexType|IndexType.ZERO_BASED|It defines whether the pagination is zero or one based.|
4747
|pageSize|number|15|Page size of the pagination.|
48+
|defaultQueryParameters/Record<string, string>|{}|It defines the default value for each query parameter. This is used to remove a query parameter from the URL and also to clear the query.
4849

4950
#### The hook returns the following object:
5051

5152
|value|type|description|
5253
|---|---|---|
53-
|search|string|value of your search parameter|
54+
|queryParameters|object|values of your query parameters|
5455
|page|number|value of the current page|
5556
|size|number|max elements in a single page|
56-
|actions|object|object with 3 functions: search, setPage, clear|
57+
|actions|object|object with 3 functions: updateQuery, setPage, clear|
5758

5859
#### Example usage with NextJS
5960

6061
```tsx
61-
import { useSearchAndPagination } from '@aboutbits/react-pagination/dist/nextRouterPagination'
62+
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/nextRouterPagination'
6263

6364
const users = [
6465
'Alex', 'Simon', 'Natan', 'Nadia', 'Moritz', 'Marie'
6566
]
6667

6768
function UserList() {
68-
const { page, size, search, actions } = useSearchAndPagination({pageSize: 2})
69+
const { page, size, queryParameters, actions } = useQueryAndPagination({pageSize: 2})
6970

7071
return (
7172
<div>
72-
<input onChange={(value) => actions.search(value)}/>
73+
<input onChange={(value) => actions.updateQuery({search: value})}/>
7374
<button onClick={() => actions.clear()}>Clear Input</button>
7475
<select onSelect={(value) => actions.setPage(value)}>
7576
<option value={0}>First Page</option>
7677
<option value={1}>Second Page</option>
7778
</select>
7879

7980
<ul>
80-
{users.filter(user => user.startsWith(search))
81+
{users.filter(user => user.startsWith(queryParameters.search))
8182
.slice(page, page + size)
8283
.map(user => <li>{user}</li>)}
8384
</ul>
@@ -99,15 +100,15 @@ This package includes 3 different implementations of the above hook.
99100
Use this pagination hook if you want to keep track of the pagination in memory. This is very handy for dialogs.
100101

101102
```tsx
102-
import { useSearchAndPagination } from '@aboutbits/react-pagination/dist/inMemoryPagination'
103+
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/inMemoryPagination'
103104
```
104105

105106
### React-Router based pagination
106107

107108
These are specific hooks for applications that use [React Router](https://reactrouter.com/) for routing.
108109

109110
```tsx
110-
import { useSearchAndPagination } from '@aboutbits/react-pagination/dist/reactRouterPagination'
111+
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/reactRouterPagination'
111112
```
112113

113114
### NextJS Router based pagination
@@ -116,7 +117,7 @@ These are specific hooks for applications that use [NextJS Router](https://nextj
116117
for routing.
117118

118119
```tsx
119-
import { useSearchAndPagination } from '@aboutbits/react-pagination/dist/nextRouterPagination'
120+
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/nextRouterPagination'
120121
```
121122

122123
## Build & Publish
Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import { act, renderHook } from '@testing-library/react-hooks'
2-
import { useSearchAndPagination } from '../inMemoryPagination'
2+
import { useQueryAndPagination } from '../inMemoryPagination'
33
import { IndexType } from '../types'
44

55
test('should initialize pagination', () => {
6-
const { result } = renderHook(() => useSearchAndPagination())
6+
const { result } = renderHook(() => useQueryAndPagination())
77

88
expect(result.current.page).toBe(0)
9-
expect(result.current.search).toBe('')
109
expect(result.current.size).toBe(15)
1110
})
1211

1312
test('should change page', () => {
14-
const { result } = renderHook(() => useSearchAndPagination())
13+
const { result } = renderHook(() => useQueryAndPagination())
1514

1615
act(() => {
1716
result.current.actions.setPage(2)
@@ -21,17 +20,21 @@ test('should change page', () => {
2120
})
2221

2322
test('should change search', () => {
24-
const { result } = renderHook(() => useSearchAndPagination())
23+
const { result } = renderHook(() =>
24+
useQueryAndPagination({ defaultQueryParameters: { search: '' } })
25+
)
2526

2627
act(() => {
27-
result.current.actions.search('Max')
28+
result.current.actions.updateQuery({ search: 'Max' })
2829
})
2930

30-
expect(result.current.search).toBe('Max')
31+
expect(result.current.queryParameters.search).toBe('Max')
3132
})
3233

3334
test('on search change -> page should be reset', () => {
34-
const { result } = renderHook(() => useSearchAndPagination())
35+
const { result } = renderHook(() =>
36+
useQueryAndPagination({ defaultQueryParameters: { search: '' } })
37+
)
3538

3639
act(() => {
3740
result.current.actions.setPage(2)
@@ -40,40 +43,73 @@ test('on search change -> page should be reset', () => {
4043
expect(result.current.page).toBe(2)
4144

4245
act(() => {
43-
result.current.actions.search('Max')
46+
result.current.actions.updateQuery({ search: 'Max' })
4447
})
4548

46-
expect(result.current.search).toBe('Max')
49+
expect(result.current.queryParameters.search).toBe('Max')
4750
expect(result.current.page).toBe(0)
4851
})
4952

5053
test('clear pagination should reset search and page', () => {
51-
const { result } = renderHook(() => useSearchAndPagination())
54+
const { result } = renderHook(() =>
55+
useQueryAndPagination({ defaultQueryParameters: { search: '' } })
56+
)
5257

5358
act(() => {
54-
result.current.actions.search('Max')
59+
result.current.actions.updateQuery({ search: 'Max' })
5560
})
5661

5762
act(() => {
5863
result.current.actions.setPage(2)
5964
})
6065

61-
expect(result.current.search).toBe('Max')
66+
expect(result.current.queryParameters.search).toBe('Max')
6267
expect(result.current.page).toBe(2)
6368

6469
act(() => {
6570
result.current.actions.clear()
6671
})
6772

68-
expect(result.current.search).toBe('')
73+
expect(result.current.queryParameters.search).toBe('')
6974
expect(result.current.page).toBe(0)
7075
})
7176

7277
test('change default parameters', () => {
7378
const { result } = renderHook(() =>
74-
useSearchAndPagination({ indexType: IndexType.ONE_BASED, pageSize: 10 })
79+
useQueryAndPagination({ indexType: IndexType.ONE_BASED, pageSize: 10 })
7580
)
7681

7782
expect(result.current.page).toBe(1)
7883
expect(result.current.size).toBe(10)
7984
})
85+
86+
test('query multiple different properties, should keep them all', () => {
87+
const { result } = renderHook(() =>
88+
useQueryAndPagination({
89+
defaultQueryParameters: { search: '', department: '' },
90+
})
91+
)
92+
93+
act(() => {
94+
result.current.actions.updateQuery({ search: 'Max' })
95+
result.current.actions.updateQuery({ department: 'IT' })
96+
})
97+
98+
expect(result.current.queryParameters.search).toBe('Max')
99+
expect(result.current.queryParameters.department).toBe('IT')
100+
})
101+
102+
test('query a property that is not configured, should do nothing', () => {
103+
const { result } = renderHook(() =>
104+
useQueryAndPagination({
105+
defaultQueryParameters: { search: '' },
106+
})
107+
)
108+
109+
act(() => {
110+
result.current.actions.updateQuery({ department: 'IT' })
111+
})
112+
113+
expect(result.current.queryParameters.search).toBe('')
114+
expect(result.current.queryParameters.department).toBeUndefined()
115+
})

0 commit comments

Comments
 (0)