Skip to content

Instantly share code, notes, and snippets.

@its-tayo
Created November 2, 2019 21:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save its-tayo/f51f8750ca37688b9fb8d7b389b32614 to your computer and use it in GitHub Desktop.
Save its-tayo/f51f8750ca37688b9fb8d7b389b32614 to your computer and use it in GitHub Desktop.
Typescript React Table Custom Pagination
interface Props {
pages: number
page: number
pageSize: number
onPageChange: Function
previousText: string
nextText: string
data: { [key: string]: any }[]
}
const PaginationButton = (props: any) => (
<button {...props}>{props.children}</button>
)
const Pagination: React.FunctionComponent<Props> = ({
data,
page,
pages,
pageSize,
onPageChange,
previousText,
nextText
}) => {
const [visiblePages, setVisiblePage] = React.useState<number[]>([])
const filterPages = (visiblePages: number[], totalPages: number) => {
return visiblePages.filter(page => page <= totalPages)
}
const getVisiblePages = (page: number, total: number) => {
if (total < 7) {
return filterPages([1, 2, 3, 4, 5, 6], total)
} else {
if (page % 5 >= 0 && page > 4 && page + 2 < total) {
return [1, page - 1, page, page + 1, total]
} else if (page % 5 >= 0 && page > 4 && page + 2 >= total) {
return [1, total - 3, total - 2, total - 1, total]
} else {
return [1, 2, 3, 4, 5, total]
}
}
}
const changePage = (nextPage: number) => {
const activePage = page + 1
if (nextPage === activePage) {
return
}
const visiblePages = getVisiblePages(nextPage, pages)
setVisiblePage(filterPages(visiblePages, pages))
onPageChange(nextPage - 1)
}
React.useEffect(() => {
setVisiblePage(getVisiblePages(1, pages))
changePage(page + 1)
}, [pages])
const activePage: number = page + 1
return (
<PaginationWrapper className="mt-5">
<div className="row">
<div className="lhs-wrapper col-md-6">
{data.length
? `Showing ${page * pageSize + 1} - ${
page + 1 === pages ? data.length : (page + 1) * pageSize
} of ${data.length} results`
: `No results found`}
</div>
<div className="rhs-wraper col-md-6">
<div className="rhs-inner-wrapper d-flex justify-content-end align-items-center">
<div className="previous-wrapper">
<PaginationButton
onClick={() => {
if (activePage === 1) return
changePage(activePage - 1)
}}
disabled={activePage === 1}
>
{previousText}
</PaginationButton>
</div>
<div className="visiblePages-wrapper">
{visiblePages.map((page, index, array) => {
return (
<PaginationButton
key={page}
className={activePage === page ? 'active' : null}
onClick={() => changePage(page)}
>
{array[index - 1] + 2 < page ? `...` : page}
</PaginationButton>
)
})}
</div>
<div className="next-wrapper">
<PaginationButton
onClick={() => {
if (activePage === pages) return
changePage(activePage + 1)
}}
disabled={activePage === pages}
>
{nextText}
</PaginationButton>
</div>
</div>
</div>
</div>
</PaginationWrapper>
)
}
export default Pagination
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment