https://github.com/aboutbits/react-pagination
https://github.com/aboutbits/react-pagination
Last synced: 10 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/aboutbits/react-pagination
- Owner: aboutbits
- License: mit
- Created: 2021-07-19T09:23:48.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-01-29T14:44:43.000Z (about 1 year ago)
- Last Synced: 2025-03-14T02:04:20.998Z (11 months ago)
- Language: TypeScript
- Homepage:
- Size: 518 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
- License: license.md
Awesome Lists containing this project
README
# React Pagination
[](https://badge.fury.io/js/%40aboutbits%2Freact-pagination)
[](https://github.com/aboutbits/react-pagination/blob/main/license.md)
Query hooks for React with first-class support for TypeScript! Writing and reading the query, attached to the browser URL or in-memory, made easy!
## Table of content
- [Usage](#usage)
- [Example usage with Next.js](#example-usage-with-nextjs)
- [Example usage with React Router and zod](#example-usage-with-react-router-and-zod)
- [Build & Publish](#build--publish)
- [About](#about)
## Usage
Install the package:
```sh
npm install @aboutbits/react-pagination
```
There are a variety of entry points from which to import the hooks `useQuery`, `usePagination` and `useQueryAndPagination`:
- For the [Next.js](https://nextjs.org/) router:
- `@aboutbits/react-pagination/next-router`
- `@aboutbits/react-pagination/next-router/zod`
- For [React Router](https://reactrouter.com):
- `@aboutbits/react-pagination/react-router`
- `@aboutbits/react-pagination/react-router/zod`
- For an in-memory router that does not modify the browser history:
- `@aboutbits/react-pagination/in-memory`
- `@aboutbits/react-pagination/in-memory/zod`
The hooks exported from `@aboutbits/react-pagination/*/zod` are more convenient when using [zod](https://github.com/colinhacks/zod) for the validation of the query.
`useQueryAndPagination` merges the functionality of `useQuery` and `usePagination`. Changing the query resets the page, but changing the page does not reset the query.
Some examples follow, but we recommend having a look at the type definitions for more details about the API.
### Example usage with Next.js
```tsx
import { Query } from '@aboutbits/react-pagination/dist/engine'
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/routers/nextRouter'
const users = ['Alex', 'Simon', 'Natan', 'Nadia', 'Moritz', 'Marie']
const parseSearch = (query: Query) => {
for (const [key, value] of Object.entries(query)) {
if (key === 'search' && !Array.isArray(value)) {
return { search: value }
}
}
return {}
}
export function UserList() {
const { page, size, query, setQuery, setPage, resetQuery } =
useQueryAndPagination(parseSearch, { search: '' })
return (
setQuery({ search: event.target.value })}
/>
resetQuery()}>Clear Input
setPage(parseInt(event.target.value))}
>
First Page
Second Page
{users
.filter((user) =>
user.toLowerCase().startsWith(query.search.toLowerCase()),
)
.slice(page * size, (page + 1) * size)
.map((user) => (
- {user}
))}
)
}
```
### Example usage with Next.js, zod and no default query
Notice that we let zod take a string and then coerce it to a number. If the coercion fails, we do not stop the whole parsing, but default the property to `undefined`.
This allows us to still use `departmentId` if it is defined while `userId` is not and vice versa.
```tsx
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/zod/routers/nextRouter'
import { z } from 'zod'
export function Component() {
const { page, size, query, setQuery, setPage, resetQuery } =
useQueryAndPagination(
z.object({
departmentId: z
.string()
.pipe(z.coerce.number().optional())
.catch(undefined),
userId: z.string().pipe(z.coerce.number().optional()).catch(undefined),
}),
)
// ... do something
}
```
### Example usage with React Router and zod
```tsx
import { useQueryAndPagination } from '@aboutbits/react-pagination/dist/zod/routers/reactRouter'
import { z } from 'zod'
const userSchema = z.object({
name: z.string(),
// The input to the parser is going to be a string.
// We try to convert it to a number and default to undefined if the parsing fails.
// This continues the parsing of the remaining query.
// Another possibility would be to not catch errors, which would cancel the entire parsing
// if "age" cannot be converted to a number.
age: z.string().pipe(z.coerce.number().optional()).catch(undefined),
})
const users = [
{ name: 'Alex', age: 10 },
{ name: 'Simon', age: 24 },
{ name: 'Natan', age: 88 },
{ name: 'Nadia', age: 42 },
{ name: 'Moritz', age: 35 },
{ name: 'Marie', age: 17 },
]
export function UserList() {
const { page, size, query, setQuery, setPage, resetQuery } =
useQueryAndPagination:
userSchema,
{ name: '', age: 0 },
{
page: 0,
size: 4,
},
)
return (
Name:
setQuery({ name: event.target.value })}
/>
Minimum age:
{
const value = event.target.value
const parsed = parseInt(value)
if (!isNaN(parsed)) {
setQuery({ age: parsed })
}
}}
/>
resetQuery()}>Clear Input
setPage(parseInt(event.target.value))}
>
First Page
Second Page
{users
.filter(
(user) =>
user.name.toLowerCase().startsWith(query.name.toLowerCase()) &&
user.age >= query.age,
)
.slice(page * size, (page + 1) * size)
.map((user) => (
- {user.name}
))}
)
}
```
## Build & Publish
To publish the package commit all changes and push them to main. Then run one of the following commands locally:
```sh
npm version patch
npm version minor
npm version major
```
## Information
AboutBits is a company based in South Tyrol, Italy. You can find more information about us
on [our website](https://aboutbits.it).
### Support
For support, please contact [info@aboutbits.it](mailto:info@aboutbits.it).
### Credits
- [All Contributors](../../contributors)
### License
The MIT License (MIT). Please see the [license file](license.md) for more information.