mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-18 13:10:29 -05:00
* Initial * Progress * Initial UI * Can submit request * Progress * Show text if no scrims * Can cancel request, tabs * Delete post * Popover if can't delete * Request rows * Progress * Scrim page initial * Fix migration order * Progress * Progress * Works again * Make it compile * Make it compile again * Work * Progress * Progress * Progress * Associations initial * Association visibility work * notFoundVisibility form fields initial * Progress * Association leave/join + reset invite code * Progress * Select test * Merge branch 'rewrite' into scrims * Remeda for groupBy * Select with search * Outline styling for select * Select done? * Fix prop names * Paginated badges * Less important * Select no results * Handle limiting select width * UserSearch non-working * Fix problem from merge * Remove UserSearch for now * Remove todo * Flaggable * Remove TODOs * i18n start + styling * Progress * i18n done * Add association e2e test * E2E tests * Done? * Couple leftovers
65 lines
1.6 KiB
TypeScript
65 lines
1.6 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;
|
|
|
|
// if the list changes from externally it might be that we are on a page that doesn't exist anymore
|
|
// setting state inside render looks weird but should be ok
|
|
if (itemsToDisplay.length === 0 && currentPage > 1) {
|
|
setCurrentPage(1);
|
|
}
|
|
|
|
return {
|
|
pagesCount,
|
|
currentPage,
|
|
itemsToDisplay,
|
|
nextPage,
|
|
previousPage,
|
|
setPage,
|
|
thereIsNextPage,
|
|
thereIsPreviousPage,
|
|
everythingVisible: items.length === itemsToDisplay.length,
|
|
};
|
|
}
|