summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/pagination
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/lib/pagination')
-rw-r--r--frontend/src/lib/pagination/Pagination.svelte45
-rw-r--r--frontend/src/lib/pagination/Target.svelte21
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>