|
<script lang="ts"> |
|
import { page } from "$app/stores"; |
|
import { getHref } from "$lib/utils/getHref"; |
|
import PaginationArrow from "./PaginationArrow.svelte"; |
|
|
|
export let classNames = ""; |
|
export let numItemsPerPage: number; |
|
export let numTotalItems: number; |
|
|
|
const ELLIPSIS_IDX = -1 as const; |
|
|
|
$: numTotalPages = Math.ceil(numTotalItems / numItemsPerPage); |
|
$: pageIndex = parseInt($page.url.searchParams.get("p") ?? "0"); |
|
$: pageIndexes = getPageIndexes(pageIndex, numTotalPages); |
|
|
|
function getPageIndexes(pageIdx: number, nTotalPages: number) { |
|
let pageIdxs: number[] = []; |
|
|
|
const NUM_EXTRA_BUTTONS = 2; |
|
|
|
const minIdx = 0; |
|
const maxIdx = nTotalPages - 1; |
|
|
|
pageIdxs = [pageIdx]; |
|
|
|
|
|
for (let i = 1; i < NUM_EXTRA_BUTTONS + 1; i++) { |
|
const newPageIdx = pageIdx + i; |
|
if (newPageIdx > maxIdx) { |
|
continue; |
|
} |
|
pageIdxs.push(newPageIdx); |
|
} |
|
if (maxIdx - pageIdxs[pageIdxs.length - 1] > 1) { |
|
pageIdxs.push(...[ELLIPSIS_IDX, maxIdx]); |
|
} else if (maxIdx - pageIdxs[pageIdxs.length - 1] === 1) { |
|
pageIdxs.push(maxIdx); |
|
} |
|
|
|
|
|
for (let i = 1; i < NUM_EXTRA_BUTTONS + 1; i++) { |
|
const newPageIdx = pageIdx - i; |
|
if (newPageIdx < minIdx) { |
|
continue; |
|
} |
|
pageIdxs.unshift(newPageIdx); |
|
} |
|
if (pageIdxs[0] - minIdx > 1) { |
|
pageIdxs.unshift(...[minIdx, ELLIPSIS_IDX]); |
|
} else if (pageIdxs[0] - minIdx === 1) { |
|
pageIdxs.unshift(minIdx); |
|
} |
|
return pageIdxs; |
|
} |
|
</script> |
|
|
|
{#if numTotalPages > 1} |
|
<nav> |
|
<ul |
|
class="flex select-none items-center justify-between space-x-2 text-gray-700 sm:justify-center dark:text-gray-300 {classNames}" |
|
> |
|
<li> |
|
<PaginationArrow |
|
href={getHref($page.url, { newKeys: { p: (pageIndex - 1).toString() } })} |
|
direction="previous" |
|
isDisabled={pageIndex - 1 < 0} |
|
/> |
|
</li> |
|
{#each pageIndexes as pageIdx} |
|
<li class="hidden sm:block"> |
|
<a |
|
class=" |
|
rounded-lg px-2.5 py-1 |
|
{pageIndex === pageIdx |
|
? 'bg-gray-50 font-semibold ring-1 ring-inset ring-gray-200 dark:bg-gray-800 dark:text-yellow-500 dark:ring-gray-700' |
|
: ''} |
|
" |
|
class:pointer-events-none={pageIdx === ELLIPSIS_IDX || pageIndex === pageIdx} |
|
href={getHref($page.url, { newKeys: { p: pageIdx.toString() } })} |
|
> |
|
{pageIdx === ELLIPSIS_IDX ? "..." : pageIdx + 1} |
|
</a> |
|
</li> |
|
{/each} |
|
<li> |
|
<PaginationArrow |
|
href={getHref($page.url, { newKeys: { p: (pageIndex + 1).toString() } })} |
|
direction="next" |
|
isDisabled={pageIndex + 1 >= numTotalPages} |
|
/> |
|
</li> |
|
</ul> |
|
</nav> |
|
{/if} |
|
|