summaryrefslogblamecommitdiffstatshomepage
path: root/frontend/src/lib/pagination/Pagination.svelte
blob: fc2935c6f9137fdb8b3a1c8291553d002c9a75e1 (plain) (tree)
1
2
3
4
5
6
7
8
9
                  
                                                              

                                             




                                           
 
                                                                 
 


                                                                       
 

                                                             
 

                                                                 
 






                                                                                                      



                                               

                                                                                                           
                         

                                                                                                    
                         


                                                                                              

                                 

                                                                                                     
                         

                                                                                                            


                         
<script lang="ts">
	import type { PaginationData } from '$lib/Navigation';
	import Target from './Target.svelte';

	interface Props {
		context?: number;
		pagination: PaginationData;
		total: number;
	}

	let { context = 2, pagination, total }: Props = $props();

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

	let shiftRight = $derived(leftBoundary - totalPages);
	let shiftLeft = $derived(1 - rightBoundary);

	let containedLeft = $derived(leftBoundary <= totalPages);
	let containedRight = $derived(rightBoundary > 0);

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

	let leftmost = $derived(pagination.page <= 1);
	let rightmost = $derived(pagination.page >= totalPages);
</script>

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