diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-07-01 01:10:02 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-07-01 01:18:01 +0900 |
| commit | a7cd871b183679a8fe5287155283d23bff9d5d56 (patch) | |
| tree | baa28b25813131a101fa971220a93a57f8e24332 /services/blog/nuldoc-src/components/Pagination.tsx | |
| parent | 118f8c7969ec9f77f07dd462110ed29318ad2bde (diff) | |
| download | nsfisis.dev-a7cd871b183679a8fe5287155283d23bff9d5d56.tar.gz nsfisis.dev-a7cd871b183679a8fe5287155283d23bff9d5d56.tar.zst nsfisis.dev-a7cd871b183679a8fe5287155283d23bff9d5d56.zip | |
feat(blog/nuldoc): update page navigation
Diffstat (limited to 'services/blog/nuldoc-src/components/Pagination.tsx')
| -rw-r--r-- | services/blog/nuldoc-src/components/Pagination.tsx | 117 |
1 files changed, 67 insertions, 50 deletions
diff --git a/services/blog/nuldoc-src/components/Pagination.tsx b/services/blog/nuldoc-src/components/Pagination.tsx index ab13e361..84752c5e 100644 --- a/services/blog/nuldoc-src/components/Pagination.tsx +++ b/services/blog/nuldoc-src/components/Pagination.tsx @@ -11,68 +11,44 @@ export default function Pagination( return <div></div>; } - const firstPage = 1; - const lastPage = totalPages; - const prevPage = currentPage > 1 ? currentPage - 1 : null; - const nextPage = currentPage < totalPages ? currentPage + 1 : null; - - const firstHref = pageUrlAt(basePath, firstPage); - const lastHref = pageUrlAt(basePath, lastPage); - const prevHref = prevPage ? pageUrlAt(basePath, prevPage) : null; - const nextHref = nextPage ? pageUrlAt(basePath, nextPage) : null; + const pages = generatePageNumbers(currentPage, totalPages); return ( <nav className="pagination"> <div className="pagination-prev"> - {prevHref + {currentPage > 1 ? ( - <a href={prevHref}> + <a href={pageUrlAt(basePath, currentPage - 1)}> 前へ </a> ) : null} </div> - <div - className={"pagination-page" + - (firstPage === currentPage ? " pagination-page-current" : "")} - > - {firstPage === currentPage - ? String(firstPage) - : <a href={firstHref}>{String(firstPage)}</a>} - </div> - {currentPage - firstPage > 1 - ? ( - <div className="pagination-elipsis"> - … - </div> - ) - : null} - {currentPage !== firstPage && currentPage !== lastPage - ? ( - <div className="pagination-page pagination-page-current"> - {String(currentPage)} - </div> - ) - : null} - {lastPage - currentPage > 1 - ? ( - <div className="pagination-elipsis"> - … - </div> - ) - : null} - <div - className={"pagination-page" + - (lastPage === currentPage ? " pagination-page-current" : "")} - > - {lastPage === currentPage - ? String(lastPage) - : <a href={lastHref}>{String(lastPage)}</a>} - </div> + {pages.map((page) => { + if (page === "...") { + return ( + <div className="pagination-elipsis"> + … + </div> + ); + } else if (page === currentPage) { + return ( + <div className="pagination-page pagination-page-current"> + <span>{String(page)}</span> + </div> + ); + } else { + return ( + <div className="pagination-page"> + <a href={pageUrlAt(basePath, page)}>{String(page)}</a> + </div> + ); + } + })} <div className="pagination-next"> - {nextHref + {currentPage < totalPages ? ( - <a href={nextHref}> + <a href={pageUrlAt(basePath, currentPage + 1)}> 次へ </a> ) @@ -82,6 +58,47 @@ export default function Pagination( ); } +type PageItem = number | "..."; + +/** + * Generates page numbers for pagination display. + * + * - Always show the first page + * - Always show the last page + * - Always show the current page + * - Always show the page before and after the current page + * - If there's only one page gap between displayed pages, fill it + * - If there are two or more pages gap between displayed pages, show ellipsis + */ +function generatePageNumbers( + currentPage: number, + totalPages: number, +): PageItem[] { + const pages = new Set<number>(); + pages.add(1); + pages.add(Math.max(1, currentPage - 1)); + pages.add(currentPage); + pages.add(Math.min(totalPages, currentPage + 1)); + pages.add(totalPages); + + const sorted = Array.from(pages).sort((a, b) => a - b); + + const result: PageItem[] = []; + for (let i = 0; i < sorted.length; i++) { + if (i > 0) { + const gap = sorted[i] - sorted[i - 1]; + if (gap === 2) { + result.push(sorted[i - 1] + 1); + } else if (gap > 2) { + result.push("..."); + } + } + result.push(sorted[i]); + } + + return result; +} + function pageUrlAt(basePath: string, page: number): string { return page === 1 ? basePath : `${basePath}${page}/`; } |
