Created
September 29, 2022 12:43
-
-
Save halfbug/f7a9dfda0ea0a37e03b3003b04b8d8a5 to your computer and use it in GitHub Desktop.
usePagination Custom hook to create pagination in any grid.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.... | |
import usePagination from 'hooks/usePagination'; | |
import Pagination from 'react-bootstrap/Pagination'; | |
.... | |
const ProductGrid = ({ | |
...props | |
}: ProductGridProps) => { | |
.... | |
const { | |
screens, breakPoint, pageSize, | |
totalPages, renderItems, currentPage, setCurrentPage, getPageNumbers, | |
} = usePagination<IProduct>({ | |
dimensions, | |
maxrows, | |
screens: { | |
xs, sm, md, lg, xl, xxl, | |
}, | |
items: products || [], | |
siblingCount: 4, | |
id, | |
}); | |
.... | |
return ( | |
.... | |
<Row> | |
<Col> | |
{totalPages > 1 && ( | |
<Pagination className={styles.ghop_pagination}> | |
<Pagination.Prev | |
className={[(currentPage === 1) ? 'd-none' : '', styles.ghop_pagination_prev].join(' ')} | |
onClick={() => { | |
setCurrentPage( | |
(currentPage > 1) ? currentPage - 1 : currentPage, | |
); | |
}} | |
/> | |
{getPageNumbers().map((n, index) => ( | |
<Pagination.Item | |
active={currentPage === n} | |
onClick={() => { | |
setCurrentPage(n); | |
{ (id === 'allproducts') && (paginationScroll()); } | |
}} | |
className={currentPage === n | |
? styles.ghop_pagination_activeItem : styles.ghop_pagination_item} | |
> | |
{n} | |
</Pagination.Item> | |
))} | |
<Pagination.Next | |
className={[(currentPage === totalPages) ? 'd-none' : '', styles.ghop_pagination_next].join(' ')} | |
onClick={() => { | |
setCurrentPage( | |
(currentPage >= 1 && currentPage < totalPages) ? currentPage + 1 : currentPage, | |
); | |
{ (id === 'allproducts') && (paginationScroll()); } | |
}} | |
/> | |
</Pagination> | |
)} | |
</Col> | |
</Row> | |
..): | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect, useCallback, useState } from 'react'; | |
import useDimensions from './useDimentions'; | |
export type ScreensProps= { [key: string]: number } & { | |
xs?: number, | |
sm?: number, | |
md?: number, | |
lg?: number, | |
xl?: number, | |
xxl?: number, | |
} | |
type PaginationProps<T> = { | |
dimensions : any; | |
maxrows: number, | |
screens: ScreensProps | |
items: T[], | |
siblingCount: number, | |
id?: string, | |
// currentPage: number, | |
} | |
const usePagination = <T extends {}>({ | |
maxrows, screens, items, dimensions, siblingCount, id, | |
}:PaginationProps<T>) => { | |
// const [ref, dimensions] = useDimensions(); | |
const [breakPoint, setBreakPoint] = useState<string>('sm'); | |
const [pageSize, setPageSize] = useState<number>(6); | |
const [totalPages, setTotalPages] = useState<number>(1); | |
const [renderItems, setRenderItems] = useState<typeof items | undefined>(undefined); | |
const [currentPage, setCurrentPage] = useState<number>(1); | |
useEffect(() => { | |
if (dimensions.width && items?.length > 0) { | |
setVals(dimensions.width); | |
getPageNumbers(); | |
} | |
}, [dimensions, items, currentPage]); | |
useEffect(() => { | |
if (items?.length > 0 && currentPage !== 1 && id === 'shoppedby') { | |
setCurrentPage(1); | |
} | |
}, [items]); | |
const breakpoints: { [char: string]: number } = { | |
// xs: 0, | |
// sm: 576, | |
md: 768, | |
lg: 992, | |
xl: 1200, | |
xxl: 1400, | |
}; | |
const setVals = (currentWidth: number) => { | |
let bPoint = 'sm'; | |
for (const key in breakpoints) { | |
if (breakpoints[key] < currentWidth) { bPoint = key; } else { break; } | |
} | |
// bPoint = (bPoint === xs ) | |
setBreakPoint(bPoint); | |
const pagesize = (12 / screens[bPoint]) * maxrows; | |
setPageSize(pagesize); | |
const totalpages = Math.ceil((items.length) / pagesize); | |
setTotalPages(totalpages); | |
if (totalpages === 1) { | |
setCurrentPage(1); | |
} | |
const start = (currentPage > 1) | |
? (currentPage - 1) * pagesize : currentPage - 1; | |
const end = (currentPage > 0) | |
? currentPage * pagesize : pagesize; | |
setRenderItems(items.slice(start, end)); | |
}; | |
const range = (start: number, end: number) => Array(end - start + 1) | |
.fill(0).map((_, idx) => start + idx); | |
const getPageNumbers = useCallback(() => { | |
let start : number = 1; | |
let end : number = siblingCount; | |
const pageLeft = totalPages - currentPage; | |
if (currentPage - 1 > 0 && pageLeft >= siblingCount - 2) { | |
start = currentPage - 1 > 0 ? currentPage - 1 : 1; | |
end = start + (siblingCount - 1); | |
} else if (totalPages < siblingCount && totalPages > 1) { | |
end = totalPages; | |
} else if (pageLeft < siblingCount && totalPages > 1) { | |
start = totalPages - (siblingCount - 1); | |
end = totalPages; | |
} | |
return range(start, end); | |
}, [currentPage, totalPages]); | |
return { | |
breakPoint, | |
pageSize, | |
totalPages, | |
renderItems, | |
currentPage, | |
setCurrentPage, | |
getPageNumbers, | |
screens, | |
}; | |
}; | |
export default usePagination; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment