Add pagination to ISAC registries
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { page as currentPage } from '$app/state';
|
||||
let { pagination }: { pagination: { page: number; perPage: number; total: number; pageCount: number } } = $props();
|
||||
const href = (targetPage: number, perPage = pagination.perPage) => {
|
||||
const params = new URLSearchParams(currentPage.url.searchParams);
|
||||
params.set('page', String(targetPage));
|
||||
params.set('perPage', String(perPage));
|
||||
return `${currentPage.url.pathname}?${params}`;
|
||||
};
|
||||
const visiblePages = $derived(
|
||||
Array.from({ length: pagination.pageCount }, (_, index) => index + 1)
|
||||
.filter((page) => page === 1 || page === pagination.pageCount || Math.abs(page - pagination.page) <= 2)
|
||||
);
|
||||
const start = $derived(pagination.total ? (pagination.page - 1) * pagination.perPage + 1 : 0);
|
||||
const end = $derived(Math.min(pagination.total, pagination.page * pagination.perPage));
|
||||
</script>
|
||||
|
||||
<nav class="registry-pagination" aria-label="Registry pagination">
|
||||
<div class="pagination-range"><span>DISPLAYING</span><b>{start}–{end}</b><span>OF {pagination.total}</span></div>
|
||||
<div class="pagination-pages">
|
||||
<a class:disabled={pagination.page === 1} aria-disabled={pagination.page === 1} href={href(Math.max(1, pagination.page - 1))}>← PREV</a>
|
||||
{#each visiblePages as page, index}
|
||||
{#if index > 0 && page - visiblePages[index - 1] > 1}<span class="pagination-gap">···</span>{/if}
|
||||
<a class:active={page === pagination.page} aria-current={page === pagination.page ? 'page' : undefined} href={href(page)}>{page}</a>
|
||||
{/each}
|
||||
<a class:disabled={pagination.page === pagination.pageCount} aria-disabled={pagination.page === pagination.pageCount} href={href(Math.min(pagination.pageCount, pagination.page + 1))}>NEXT →</a>
|
||||
</div>
|
||||
<div class="pagination-sizes"><span>ROWS</span>{#each [10, 25, 50, 100] as size}<a class:active={size === pagination.perPage} href={href(1, size)}>{size}</a>{/each}</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { URL } from 'node:url';
|
||||
|
||||
export const PAGE_SIZE_PRESETS = [10, 25, 50, 100] as const;
|
||||
|
||||
export function getPagination(url: URL, total: number) {
|
||||
const requestedSize = Number(url.searchParams.get('perPage'));
|
||||
const perPage = PAGE_SIZE_PRESETS.includes(requestedSize as (typeof PAGE_SIZE_PRESETS)[number]) ? requestedSize : 25;
|
||||
const pageCount = Math.max(1, Math.ceil(total / perPage));
|
||||
const requestedPage = Number(url.searchParams.get('page'));
|
||||
const page = Math.min(pageCount, Math.max(1, Number.isInteger(requestedPage) ? requestedPage : 1));
|
||||
return {
|
||||
page,
|
||||
perPage,
|
||||
total,
|
||||
pageCount,
|
||||
offset: (page - 1) * perPage
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user