@stainless-code/react-paginate
Version:
Elegantly use custom events in React
98 lines (96 loc) • 2.56 kB
JavaScript
"use client";
// src/index.ts
import { useEffect, useMemo, useState } from "react";
function usePaginate(items, options = {}) {
const { initialPageSize = 25, initialPageIndex = 0, threshold = 0 } = options;
const [pageSize, setPageSize] = useState(initialPageSize);
const [pageIndex, setPageIndex] = useState(initialPageIndex);
const pageCount = getPageCount(items, pageSize);
const shouldPaginate = items.length > threshold;
const pages = useMemo(() => {
const pages2 = [];
if (shouldPaginate) {
for (let index = 0; index < pageCount; index++) {
pages2.push(paginate(items, pageSize, index));
}
}
return pages2;
}, [items, pageCount, pageSize, shouldPaginate]);
const page = shouldPaginate ? pages[pageIndex] ?? [] : items;
const firstPageIndex = 0;
const lastPageIndex = safeIndex(pageCount - 1);
const nextPageIndex = safeIndex(pageIndex + 1);
const prevPageIndex = safeIndex(pageIndex - 1);
const canFirstPage = pageIndex !== 0;
const canLastPage = pageIndex !== lastPageIndex;
const canNextPage = pageIndex < lastPageIndex;
const canPrevPage = pageIndex > 0;
useEffect(() => {
if (pageIndex > lastPageIndex) {
setPageIndex(lastPageIndex);
}
}, [pageIndex, lastPageIndex]);
function safeIndex(index) {
return Math.min(Math.max(index, 0), pageCount - 1);
}
function handleChangePageSize(size) {
if (size !== pageSize) {
setPageSize(size);
resetPage();
}
}
function handleChangePage(index) {
if (index !== pageIndex) {
setPageIndex(safeIndex(index));
}
}
function firstPage() {
setPageIndex(firstPageIndex);
}
function lastPage() {
setPageIndex(lastPageIndex);
}
function nextPage() {
setPageIndex(nextPageIndex);
}
function prevPage() {
setPageIndex(prevPageIndex);
}
function resetPage() {
setPageIndex(firstPageIndex);
}
return {
canFirstPage,
canLastPage,
canNextPage,
canPrevPage,
changePage: handleChangePage,
changePageSize: handleChangePageSize,
firstPage,
firstPageIndex,
lastPage,
lastPageIndex,
nextPage,
nextPageIndex,
page,
pageCount,
pageIndex,
pages,
pageSize,
prevPage,
prevPageIndex,
resetPage,
shouldPaginate
};
}
function paginate(items, pageSize, pageIndex) {
return items.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
}
function getPageCount(items, pageSize) {
return Math.ceil(items.length / pageSize);
}
export {
getPageCount,
paginate,
usePaginate
};