dh_demo

DreamHanks demo project
git clone git://git.lair.cx/dh_demo
Log | Files | Refs | README

Pagination.tsx (1715B)


      1 import Link from 'next/link'
      2 import { useRouter } from 'next/router'
      3 import { ReactNode, useMemo } from 'react'
      4 import styles from './Pagination.module.css'
      5 
      6 export type PaginationProps = {
      7   page: number
      8 } & ({
      9   totalCount: number
     10   pageSize: number
     11 } | {
     12   pageCount: number
     13 })
     14 
     15 export function Pagination (props: PaginationProps) {
     16   const router = useRouter()
     17 
     18   const [items, pageCount] = useMemo(() => {
     19     const pageCount = 'pageCount' in props
     20       ? props.pageCount
     21       : Math.ceil(props.totalCount / props.pageSize)
     22 
     23     const from = Math.max(1, props.page - 2)
     24     const to = Math.min(pageCount, props.page + 2)
     25 
     26     const items: ReactNode[] = []
     27     for (let i = from; i <= to; i++) {
     28       if (i === props.page) {
     29         items.push(
     30           <span key={`page-${i}`} className={styles.item}>{i}</span>,
     31         )
     32         continue
     33       }
     34 
     35       items.push(
     36         <Link
     37           key={`page-${i}`}
     38           href={{
     39             pathname: router.pathname,
     40             query: {
     41               ...router.query,
     42               page: i,
     43             },
     44           }}
     45           className={styles.item}
     46         >{i}</Link>,
     47       )
     48     }
     49 
     50     return [items, pageCount]
     51   }, [props, router])
     52 
     53   return (
     54     <div className={styles.pagination}>
     55       <Link
     56         href={{
     57           pathname: router.pathname,
     58           query: {
     59             ...router.query,
     60             page: 1,
     61           },
     62         }}
     63         className={styles.item}
     64       >&larr;</Link>
     65 
     66       {items}
     67 
     68       <Link
     69         href={{
     70           pathname: router.pathname,
     71           query: {
     72             ...router.query,
     73             page: pageCount,
     74           },
     75         }}
     76         className={styles.item}
     77       >&rarr;</Link>
     78     </div>
     79   )
     80 }