diff --git a/packages/docs/content/docs/parsers/community/tanstack-table-multiple.generator.tsx b/packages/docs/content/docs/parsers/community/tanstack-table-multiple.generator.tsx new file mode 100644 index 000000000..003a9293f --- /dev/null +++ b/packages/docs/content/docs/parsers/community/tanstack-table-multiple.generator.tsx @@ -0,0 +1,274 @@ +'use client' + +import { CodeBlock } from '@/src/components/code-block.client' +import { Querystring } from '@/src/components/querystring' +import { Label } from '@/src/components/ui/label' +import { + Pagination, + PaginationButton, + PaginationContent, + PaginationItem, + PaginationNext, + PaginationPrevious +} from '@/src/components/ui/pagination' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/src/components/ui/select' +import { Separator } from '@/src/components/ui/separator' +import { + createParser, + parseAsInteger, + useQueryState, + parseAsArrayOf +} from 'nuqs' +import { useDeferredValue, useState } from 'react' + +const NUM_PAGES = 5 + +// The parser is zero-indexed internally, +// but one-indexed when rendered in the URL, +// to align with your UI and what users might expect. +const paginationParser = createParser({ + parse(query) { + const pagination = parseAsArrayOf(parseAsInteger).parse(query); + + if (pagination === null) return null + + const [pageIndex, pageSize] = pagination + + return { pageIndex: pageIndex - 1, pageSize }; + }, + serialize({ pageIndex, pageSize }) { + return parseAsArrayOf(parseAsInteger).serialize([pageIndex + 1, pageSize]); + }, + eq({ pageIndex, pageSize }) { + return pageIndex === 0 && pageSize === 10; + }, +}); + +type Pagination = {pageIndex: number; pageSize: number} + +const PaginationComponent = ({pagination, onPaginationChange}: + {pagination:Pagination ;onPaginationChange: React.Dispatch>}) => { + const { pageIndex: page, pageSize } = pagination + const setPage = (pageIndex: number) => { + onPaginationChange((prev) => ({ + ...prev, pageIndex + })) + } + const setPageSize = (pageSize: number) => { + onPaginationChange((prev) => ({ + ...prev, pageSize + })) + } + + return
+ + + + setPage(Math.max(0, page - 1))} + /> + + {Array.from({ length: NUM_PAGES }, (_, index) => ( + + setPage(index)} + > + {index + 1} + + + ))} + + = NUM_PAGES - 1} + onClick={() => setPage(Math.min(NUM_PAGES - 1, page + 1))} + /> + + + + +
+} + +export function TanStackTableMultiplePagination() { + const [firstPaginationKey, setFirstPaginationKey] = useState('p1') + const [secondPaginationKey, setSecondPaginationKey] = useState('p2') + const [thirdPaginationKey, setThirdPaginationKey] = useState('p3') + + const paginationParserWithDefaults = paginationParser.withDefault({ pageIndex: 0, pageSize: 10 }) + + const [firstPagination, setFirstPagination] = useQueryState( + firstPaginationKey, + paginationParserWithDefaults + ) + const [secondPagination, setSecondPagination] = useQueryState( + secondPaginationKey, + paginationParserWithDefaults + ) + const [thirdPagination, setThirdPagination] = useQueryState( + thirdPaginationKey, + paginationParserWithDefaults + ) + + + const parserCode = useDeferredValue(`import { + createParser, + parseAsInteger, + useQueryState, + parseAsArrayOf +} from 'nuqs' + + // The parser is zero-indexed internally, + // but one-indexed when rendered in the URL, + // to align with your UI and what users might expect. + const paginationParser = createParser({ + parse(query) { + const pagination = parseAsArrayOf(parseAsInteger).parse(query); + + if (pagination === null) return null + + const [pageIndex, pageSize] = pagination + + return { pageIndex: pageIndex - 1, pageSize }; + }, + serialize({ pageIndex, pageSize }) { + return parseAsArrayOf(parseAsInteger).serialize([pageIndex + 1, pageSize]); + }, + eq({ pageIndex, pageSize }) { + return pageIndex === 0 && pageSize === 10; + }, + }); + + const paginationParserWithDefaults = paginationParser.withDefault({pageIndex: 0, pageSize: 10}) + + const [firstPagination, setFirstPagination] = useQueryState( + '${firstPaginationKey}', + paginationParserWithDefaults + ) + const [secondPagination, setSecondPagination] = useQueryState( + '${secondPaginationKey}', + paginationParserWithDefaults + ) + const [thirdPagination, setThirdPagination] = useQueryState( + '${thirdPaginationKey}', + paginationParserWithDefaults + ) +}`) + + const internalState = useDeferredValue(`{ + // zero-indexed + ${firstPaginationKey}: ${JSON.stringify(firstPagination, null, 2)}, + ${secondPaginationKey}: ${JSON.stringify(secondPagination, null, 2)}, + ${thirdPaginationKey}: ${JSON.stringify(thirdPagination, null, 2)} +}`) + + return ( +
+
+ + + +
+

+ Configure and copy-paste this parser into your application: +

+
+ + + + + } + className="flex-grow" + code={parserCode} + /> + +
+
+ ) +} diff --git a/packages/docs/content/docs/parsers/community/tanstack-table.mdx b/packages/docs/content/docs/parsers/community/tanstack-table.mdx index a395551f9..7058e24b1 100644 --- a/packages/docs/content/docs/parsers/community/tanstack-table.mdx +++ b/packages/docs/content/docs/parsers/community/tanstack-table.mdx @@ -20,11 +20,21 @@ TanStack Table stores pagination under two pieces of state: You will likely want the URL to follow your UI and be one-based for the page index: import { TanStackTablePagination } from './tanstack-table.generator' +import { TanStackTableMultiplePagination } from './tanstack-table-multiple.generator' +___________ + +If you’d prefer to handle multiple pagination's under a single URL or view, +a custom array parser could be really helpful (URL keys should be unique in this case): + + + + + ## Filtering