-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPagination.svelte
More file actions
87 lines (82 loc) · 3.66 KB
/
Copy pathPagination.svelte
File metadata and controls
87 lines (82 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<!--
Pagination
- Visual rhythm: prev/next anchored by mono arrows; current page lifted with subtle ring + shadow
- Page number cells are square-ish for typographic rhythm; mono numerals reinforce data feel
- Touch targets ≥ 44px via min-h-11 on all interactive cells
-->
<script lang="ts">
interface Props {
currentPage: number;
totalPages: number;
pageUrl: (page: number) => string;
}
const { currentPage, totalPages, pageUrl }: Props = $props();
</script>
{#if totalPages > 1}
<nav
aria-label="ページネーション"
class="mt-12 flex flex-col items-center justify-center gap-3 sm:flex-row sm:gap-2"
>
{#if currentPage > 1}
<a
href={pageUrl(currentPage - 1)}
class="group inline-flex min-h-11 w-full items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white px-4 py-2 text-sm font-medium transition-all hover:bg-primary/5 hover:border-primary/30 hover:text-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 sm:w-auto"
rel="prev"
>
<span aria-hidden="true" class="font-[JetBrains_Mono,monospace] transition-transform group-hover:-translate-x-0.5">←</span>
前へ
</a>
{:else}
<span
class="inline-flex min-h-11 w-full cursor-not-allowed items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white px-4 py-2 text-sm font-medium opacity-40 sm:w-auto"
aria-hidden="true"
>
<span class="font-[JetBrains_Mono,monospace]">←</span>
前へ
</span>
{/if}
<div class="flex flex-1 flex-wrap items-center justify-center gap-1 sm:mx-2 sm:flex-initial">
{#each Array.from({ length: totalPages }, (_, i) => i + 1) as pageNum (pageNum)}
{#if totalPages <= 7 || pageNum === 1 || pageNum === totalPages || Math.abs(pageNum - currentPage) <= 1}
<a
href={pageUrl(pageNum)}
aria-current={currentPage === pageNum ? "page" : undefined}
aria-label="ページ {pageNum}"
class="flex min-h-11 min-w-11 items-center justify-center rounded-lg border px-3 py-2 text-center font-[JetBrains_Mono,monospace] text-sm font-medium transition-all focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 {currentPage ===
pageNum
? 'border-primary bg-primary text-white shadow-md shadow-primary/20'
: 'border-zinc-200 bg-white text-zinc-700 hover:bg-primary/5 hover:border-primary/30 hover:text-primary hover:-translate-y-px'}"
>
{pageNum}
</a>
{:else if pageNum === currentPage - 2 || pageNum === currentPage + 2}
<span
class="flex min-h-11 w-6 items-center justify-center font-[JetBrains_Mono,monospace] text-zinc-400"
aria-hidden="true">···</span
>
{/if}
{/each}
</div>
{#if currentPage < totalPages}
<a
href={pageUrl(currentPage + 1)}
class="group inline-flex min-h-11 w-full items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white px-4 py-2 text-sm font-medium transition-all hover:bg-primary/5 hover:border-primary/30 hover:text-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 sm:w-auto"
rel="next"
>
次へ
<span aria-hidden="true" class="font-[JetBrains_Mono,monospace] transition-transform group-hover:translate-x-0.5">→</span>
</a>
{:else}
<span
class="inline-flex min-h-11 w-full cursor-not-allowed items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white px-4 py-2 text-sm font-medium opacity-40 sm:w-auto"
aria-hidden="true"
>
次へ
<span class="font-[JetBrains_Mono,monospace]">→</span>
</span>
{/if}
</nav>
<p class="mt-3 text-center font-[JetBrains_Mono,monospace] text-[11px] text-zinc-400">
page {currentPage} / {totalPages}
</p>
{/if}