mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-27 21:58:08 -05:00
64 lines
1.5 KiB
TypeScript
64 lines
1.5 KiB
TypeScript
import * as React from "react";
|
|
|
|
export function usePagination<T>({
|
|
items,
|
|
pageSize,
|
|
scrollToTop = true,
|
|
}: {
|
|
items: T[];
|
|
pageSize: number;
|
|
scrollToTop?: boolean;
|
|
}) {
|
|
const [currentPage, setCurrentPage] = React.useState(1);
|
|
const pagesCount = Math.ceil(items.length / pageSize);
|
|
|
|
const itemsToDisplay = React.useMemo(
|
|
() => items.slice((currentPage - 1) * pageSize, currentPage * pageSize),
|
|
[currentPage, items, pageSize],
|
|
);
|
|
|
|
const nextPage = React.useCallback(() => {
|
|
if (currentPage < pagesCount) {
|
|
setCurrentPage((prev) => prev + 1);
|
|
if (scrollToTop) window.scrollTo(0, 0);
|
|
}
|
|
}, [currentPage, pagesCount, scrollToTop]);
|
|
|
|
const previousPage = React.useCallback(() => {
|
|
if (currentPage > 1) {
|
|
setCurrentPage((prev) => prev - 1);
|
|
if (scrollToTop) window.scrollTo(0, 0);
|
|
}
|
|
}, [currentPage, scrollToTop]);
|
|
|
|
const setPage = React.useCallback(
|
|
(page: number) => {
|
|
if (page > 0 && page <= pagesCount) {
|
|
setCurrentPage(page);
|
|
if (scrollToTop) window.scrollTo(0, 0);
|
|
}
|
|
},
|
|
[pagesCount, scrollToTop],
|
|
);
|
|
|
|
const thereIsNextPage = currentPage < pagesCount;
|
|
const thereIsPreviousPage = currentPage > 1;
|
|
|
|
// an external list change can leave us on a page that no longer exists
|
|
if (itemsToDisplay.length === 0 && currentPage > 1) {
|
|
setCurrentPage(1);
|
|
}
|
|
|
|
return {
|
|
pagesCount,
|
|
currentPage,
|
|
itemsToDisplay,
|
|
nextPage,
|
|
previousPage,
|
|
setPage,
|
|
thereIsNextPage,
|
|
thereIsPreviousPage,
|
|
everythingVisible: items.length === itemsToDisplay.length,
|
|
};
|
|
}
|