export interface UseOffsetPaginationProps { currentPage: number totalPages: number totalItems: number pageSize: number onPageChange: (page: number) => void onPageSizeChange?: (pageSize: number) => void pageSizeOptions?: number[] selectedRows?: number totalRows?: number } export interface UseOffsetPaginationReturn { // Calculated values startItem: number endItem: number pageNumbers: (number | "ellipsis")[] // Handlers handlePageChange: (page: number) => void handlePageSizeChange: (pageSize: number) => void handlePreviousPage: () => void handleNextPage: () => void // State checks isPreviousDisabled: boolean isNextDisabled: boolean hasResults: boolean hasSelection: boolean // Computed values for display resultsText: string selectionText: string | null } export function useOffsetPagination({ currentPage, totalPages, totalItems, pageSize, onPageChange, onPageSizeChange, selectedRows = 0, totalRows = 0, }: UseOffsetPaginationProps): UseOffsetPaginationReturn { // Calculate start and end items const startItem = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1 const endItem = Math.min(currentPage * pageSize, totalItems) // Generate page numbers with ellipsis logic const getPageNumbers = (): (number | "ellipsis")[] => { const pages: (number | "ellipsis")[] = [] if (totalPages <= 7) { // Show all pages if 7 or fewer for (let i = 1; i <= totalPages; i++) { pages.push(i) } } else if (currentPage <= 2) { // Near the beginning: show first 3 pages + ellipsis + last page pages.push(1, 2, 3, "ellipsis", totalPages) } else if (currentPage >= totalPages - 1) { // Near the end: show first page + ellipsis + last 3 pages pages.push(1, "ellipsis", totalPages - 2, totalPages - 1, totalPages) } else { // In the middle: show first page + ellipsis + current ±1 + ellipsis + last page pages.push( 1, "ellipsis", currentPage - 1, currentPage, currentPage + 1, "ellipsis", totalPages, ) } return pages } // Event handlers const handlePageChange = (page: number) => { if (page >= 1 && page <= totalPages && page !== currentPage) { onPageChange(page) } } const handlePageSizeChange = (pageSize: number) => { if (onPageSizeChange) { onPageSizeChange(pageSize) } } const handlePreviousPage = () => { if (currentPage > 1) { onPageChange(currentPage - 1) } } const handleNextPage = () => { if (currentPage < totalPages) { onPageChange(currentPage + 1) } } // State checks const isPreviousDisabled = currentPage <= 1 const isNextDisabled = currentPage >= totalPages const hasResults = totalItems > 0 const hasSelection = totalRows > 0 // Computed display text const resultsText = hasResults ? `Showing ${startItem} to ${endItem} of ${totalItems} results` : "No results" const selectionText = hasSelection ? `${selectedRows} of ${totalRows} row(s) selected.` : null return { startItem, endItem, pageNumbers: getPageNumbers(), handlePageChange, handlePageSizeChange, handlePreviousPage, handleNextPage, isPreviousDisabled, isNextDisabled, hasResults, hasSelection, resultsText, selectionText, } }