diff options
Diffstat (limited to '')
-rw-r--r-- | frontend/src/lib/pagination/Pagination.svelte | 45 | ||||
-rw-r--r-- | frontend/src/lib/pagination/Target.svelte | 21 |
2 files changed, 66 insertions, 0 deletions
diff --git a/frontend/src/lib/pagination/Pagination.svelte b/frontend/src/lib/pagination/Pagination.svelte new file mode 100644 index 0000000..51612f4 --- /dev/null +++ b/frontend/src/lib/pagination/Pagination.svelte @@ -0,0 +1,45 @@ +<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} diff --git a/frontend/src/lib/pagination/Target.svelte b/frontend/src/lib/pagination/Target.svelte new file mode 100644 index 0000000..9044bb9 --- /dev/null +++ b/frontend/src/lib/pagination/Target.svelte @@ -0,0 +1,21 @@ +<script lang="ts"> + import { page as pageStore } from '$app/stores'; + import { navigate } from '$lib/Navigation'; + + export let active = false; + + export let disabled = false; + export let page: number; +</script> + +<button + on:click={() => { + navigate({ pagination: { page: page } }, $pageStore.url.searchParams); + }} + class:bg-slate-700={active} + class:bg-slate-800={!active} + class="flex h-8 w-8 items-center justify-center rounded-sm p-0 text-base hover:text-white disabled:text-slate-600" + {disabled} +> + <slot /> +</button> |