summaryrefslogblamecommitdiffstatshomepage
path: root/frontend/src/lib/pagination/Pagination.svelte
blob: 51612f41364a2a78ca2f334aa585808a1b7c2fc0 (plain) (tree)












































                                                                                                       
<script lang="ts">
	import { getPaginationContext } from '$lib/Pagination';
	import Target from './Target.svelte';

	const pagination = getPaginationContext();
	export let context = 2;

	$: totalPages = Math.ceil($pagination.total / $pagination.items);
	$: rightBoundary = $pagination.page - context;
	$: leftBoundary = $pagination.page + context;

	$: shiftRight = leftBoundary - totalPages;
	$: shiftLeft = 1 - rightBoundary;

	$: containedLeft = leftBoundary <= totalPages;
	$: containedRight = rightBoundary > 0;

	$: start = Math.max(1, containedLeft ? rightBoundary : rightBoundary - shiftRight);
	$: end = Math.min(totalPages, containedRight ? leftBoundary : leftBoundary + shiftLeft);

	$: leftmost = $pagination.page <= 1;
	$: rightmost = $pagination.page >= totalPages;
</script>

{#if totalPages > 1}
	<div class="flex justify-center gap-2">
		<Target disabled={leftmost} page={1}>
			<span class="icon-base icon-[material-symbols--keyboard-double-arrow-left]" />
		</Target>
		<Target disabled={leftmost} page={$pagination.page - 1}>
			<span class="icon-base icon-[material-symbols--keyboard-arrow-left]" />
		</Target>
		{#each Array.from({ length: end + 1 - start }, (_, i) => i + start) as page}
			<Target active={$pagination.page === page} {page}>
				<p>{page.toString()}</p>
			</Target>
		{/each}
		<Target disabled={rightmost} page={$pagination.page + 1}>
			<span class="icon-base icon-[material-symbols--keyboard-arrow-right]" />
		</Target>
		<Target disabled={rightmost} page={totalPages}>
			<span class="icon-base icon-[material-symbols--keyboard-double-arrow-right]" />
		</Target>
	</div>
{/if}