{"id":19472364,"url":"https://github.com/aboutbits/react-pagination","last_synced_at":"2025-04-07T00:48:14.368Z","repository":{"id":41191460,"uuid":"387408341","full_name":"aboutbits/react-pagination","owner":"aboutbits","description":null,"archived":false,"fork":false,"pushed_at":"2025-01-29T14:44:43.000Z","size":530,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-14T02:04:20.998Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aboutbits.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-19T09:23:48.000Z","updated_at":"2024-08-08T07:56:26.000Z","dependencies_parsed_at":"2024-08-09T00:33:25.950Z","dependency_job_id":null,"html_url":"https://github.com/aboutbits/react-pagination","commit_stats":{"total_commits":53,"total_committers":4,"mean_commits":13.25,"dds":"0.24528301886792447","last_synced_commit":"a60766354a5b9e25b004464180bf4d09b102bb87"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Freact-pagination","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Freact-pagination/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Freact-pagination/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Freact-pagination/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aboutbits","download_url":"https://codeload.github.com/aboutbits/react-pagination/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247574096,"owners_count":20960495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T19:14:13.029Z","updated_at":"2025-04-07T00:48:13.081Z","avatar_url":"https://github.com/aboutbits.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Pagination\n\n[![npm package](https://badge.fury.io/js/%40aboutbits%2Freact-pagination.svg)](https://badge.fury.io/js/%40aboutbits%2Freact-pagination)\n[![license](https://img.shields.io/github/license/aboutbits/react-pagination)](https://github.com/aboutbits/react-pagination/blob/main/license.md)\n\nQuery hooks for React with first-class support for TypeScript! Writing and reading the query, attached to the browser URL or in-memory, made easy!\n\n## Table of content\n\n- [Usage](#usage)\n  - [Example usage with Next.js](#example-usage-with-nextjs)\n  - [Example usage with React Router and zod](#example-usage-with-react-router-and-zod)\n- [Build \u0026 Publish](#build--publish)\n- [About](#about)\n\n## Usage\n\nInstall the package:\n\n```sh\nnpm install @aboutbits/react-pagination\n```\n\nThere are a variety of entry points from which to import the hooks `useQuery`, `usePagination` and `useQueryAndPagination`:\n\n- For the [Next.js](https://nextjs.org/) router:\n  - `@aboutbits/react-pagination/next-router`\n  - `@aboutbits/react-pagination/next-router/zod`\n- For [React Router](https://reactrouter.com):\n  - `@aboutbits/react-pagination/react-router`\n  - `@aboutbits/react-pagination/react-router/zod`\n- For an in-memory router that does not modify the browser history:\n  - `@aboutbits/react-pagination/in-memory`\n  - `@aboutbits/react-pagination/in-memory/zod`\n\nThe hooks exported from `@aboutbits/react-pagination/*/zod` are more convenient when using [zod](https://github.com/colinhacks/zod) for the validation of the query.\n\n`useQueryAndPagination` merges the functionality of `useQuery` and `usePagination`. Changing the query resets the page, but changing the page does not reset the query.\n\nSome examples follow, but we recommend having a look at the type definitions for more details about the API.\n\n### Example usage with Next.js\n\n```tsx\nimport { Query } from '@aboutbits/react-pagination/dist/engine'\nimport { useQueryAndPagination } from '@aboutbits/react-pagination/dist/routers/nextRouter'\n\nconst users = ['Alex', 'Simon', 'Natan', 'Nadia', 'Moritz', 'Marie']\n\nconst parseSearch = (query: Query) =\u003e {\n  for (const [key, value] of Object.entries(query)) {\n    if (key === 'search' \u0026\u0026 !Array.isArray(value)) {\n      return { search: value }\n    }\n  }\n  return {}\n}\n\nexport function UserList() {\n  const { page, size, query, setQuery, setPage, resetQuery } =\n    useQueryAndPagination(parseSearch, { search: '' })\n\n  return (\n    \u003cdiv\u003e\n      \u003cinput\n        value={query.search}\n        onChange={(event) =\u003e setQuery({ search: event.target.value })}\n      /\u003e\n      \u003cbutton onClick={() =\u003e resetQuery()}\u003eClear Input\u003c/button\u003e\n      \u003cselect\n        value={page}\n        onChange={(event) =\u003e setPage(parseInt(event.target.value))}\n      \u003e\n        \u003coption value=\"0\"\u003eFirst Page\u003c/option\u003e\n        \u003coption value=\"1\"\u003eSecond Page\u003c/option\u003e\n      \u003c/select\u003e\n      \u003cul\u003e\n        {users\n          .filter((user) =\u003e\n            user.toLowerCase().startsWith(query.search.toLowerCase()),\n          )\n          .slice(page * size, (page + 1) * size)\n          .map((user) =\u003e (\n            \u003cli key={user}\u003e{user}\u003c/li\u003e\n          ))}\n      \u003c/ul\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n### Example usage with Next.js, zod and no default query\n\nNotice 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`.\nThis allows us to still use `departmentId` if it is defined while `userId` is not and vice versa.\n\n```tsx\nimport { useQueryAndPagination } from '@aboutbits/react-pagination/dist/zod/routers/nextRouter'\nimport { z } from 'zod'\n\nexport function Component() {\n  const { page, size, query, setQuery, setPage, resetQuery } =\n    useQueryAndPagination(\n      z.object({\n        departmentId: z\n          .string()\n          .pipe(z.coerce.number().optional())\n          .catch(undefined),\n        userId: z.string().pipe(z.coerce.number().optional()).catch(undefined),\n      }),\n    )\n\n  // ... do something\n}\n```\n\n### Example usage with React Router and zod\n\n```tsx\nimport { useQueryAndPagination } from '@aboutbits/react-pagination/dist/zod/routers/reactRouter'\nimport { z } from 'zod'\n\nconst userSchema = z.object({\n  name: z.string(),\n  // The input to the parser is going to be a string.\n  // We try to convert it to a number and default to undefined if the parsing fails.\n  // This continues the parsing of the remaining query.\n  // Another possibility would be to not catch errors, which would cancel the entire parsing\n  // if \"age\" cannot be converted to a number.\n  age: z.string().pipe(z.coerce.number().optional()).catch(undefined),\n})\n\nconst users = [\n  { name: 'Alex', age: 10 },\n  { name: 'Simon', age: 24 },\n  { name: 'Natan', age: 88 },\n  { name: 'Nadia', age: 42 },\n  { name: 'Moritz', age: 35 },\n  { name: 'Marie', age: 17 },\n]\n\nexport function UserList() {\n  const { page, size, query, setQuery, setPage, resetQuery } =\n    useQueryAndPagination:\n      userSchema,\n      { name: '', age: 0 },\n      {\n        page: 0,\n        size: 4,\n      },\n    )\n\n  return (\n    \u003cdiv\u003e\n      \u003cdiv\u003e\n        Name:\n        \u003cinput\n          value={query.name}\n          onChange={(event) =\u003e setQuery({ name: event.target.value })}\n        /\u003e\n      \u003c/div\u003e\n      \u003cdiv\u003e\n        Minimum age:\n        \u003cinput\n          value={query.age}\n          onChange={(event) =\u003e {\n            const value = event.target.value\n            const parsed = parseInt(value)\n            if (!isNaN(parsed)) {\n              setQuery({ age: parsed })\n            }\n          }}\n        /\u003e\n      \u003c/div\u003e\n      \u003cbutton onClick={() =\u003e resetQuery()}\u003eClear Input\u003c/button\u003e\n      \u003cselect\n        value={page}\n        onChange={(event) =\u003e setPage(parseInt(event.target.value))}\n      \u003e\n        \u003coption value=\"0\"\u003eFirst Page\u003c/option\u003e\n        \u003coption value=\"1\"\u003eSecond Page\u003c/option\u003e\n      \u003c/select\u003e\n      \u003cul\u003e\n        {users\n          .filter(\n            (user) =\u003e\n              user.name.toLowerCase().startsWith(query.name.toLowerCase()) \u0026\u0026\n              user.age \u003e= query.age,\n          )\n          .slice(page * size, (page + 1) * size)\n          .map((user) =\u003e (\n            \u003cli key={user.name}\u003e{user.name}\u003c/li\u003e\n          ))}\n      \u003c/ul\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n## Build \u0026 Publish\n\nTo publish the package commit all changes and push them to main. Then run one of the following commands locally:\n\n```sh\nnpm version patch\nnpm version minor\nnpm version major\n```\n\n## Information\n\nAboutBits is a company based in South Tyrol, Italy. You can find more information about us\non [our website](https://aboutbits.it).\n\n### Support\n\nFor support, please contact [info@aboutbits.it](mailto:info@aboutbits.it).\n\n### Credits\n\n- [All Contributors](../../contributors)\n\n### License\n\nThe MIT License (MIT). Please see the [license file](license.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboutbits%2Freact-pagination","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faboutbits%2Freact-pagination","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboutbits%2Freact-pagination/lists"}