File size: 3,703 Bytes
96dd062 | 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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | ---
import type { Page } from "astro";
import { Icon } from "astro-icon/components";
import I18nKey from "@/i18n/i18nKey";
import { i18n } from "@/i18n/translation";
import { url } from "@/utils/url-utils";
interface Props {
page: Page;
class?: string;
style?: string;
}
const { page, style } = Astro.props;
const HIDDEN = -1;
const className = Astro.props.class;
const ADJ_DIST = 2;
const VISIBLE = ADJ_DIST * 2 + 1;
// for test
let count = 1;
let l = page.currentPage;
let r = page.currentPage;
while (0 < l - 1 && r + 1 <= page.lastPage && count + 2 <= VISIBLE) {
count += 2;
l--;
r++;
}
while (0 < l - 1 && count < VISIBLE) {
count++;
l--;
}
while (r + 1 <= page.lastPage && count < VISIBLE) {
count++;
r++;
}
let pages: number[] = [];
if (l > 1) pages.push(1);
if (l === 3) pages.push(2);
if (l > 3) pages.push(HIDDEN);
for (let i = l; i <= r; i++) pages.push(i);
if (r < page.lastPage - 2) pages.push(HIDDEN);
if (r === page.lastPage - 2) pages.push(page.lastPage - 1);
if (r < page.lastPage) pages.push(page.lastPage);
const getPageUrl = (p: number) => {
if (p === 1) return "/";
return `/${p}/`;
};
---
<div class:list={[className, "flex flex-col gap-4 items-center"]} style={style}>
<!-- 分页信息 - 已禁用 -->
<!--
{
page.lastPage > 1 && (
<div class="text-sm text-(--text-secondary) text-center">
第 {page.currentPage} 页,共 {page.lastPage} 页
</div>
)
}
-->
<!-- 分页控件 -->
<div class="flex flex-row gap-3 justify-center" role="navigation" aria-label={i18n(I18nKey.postList)}>
<a
href={page.url.prev || "#"}
aria-label={i18n(I18nKey.paginationPrev)}
aria-disabled={page.url.prev === undefined ? "true" : "false"}
tabindex={page.url.prev === undefined ? "-1" : "0"}
class:list={[
"btn-card overflow-hidden rounded-lg text-(--primary) w-11 h-11",
{ disabled: page.url.prev == undefined },
]}
>
<Icon
name="material-symbols:chevron-left-rounded"
class="text-[1.75rem]"
aria-hidden="true"
/>
</a>
<div
class="bg-(--card-bg) flex flex-row rounded-lg items-center text-neutral-700 dark:text-neutral-300 font-bold"
>
{
pages.map((p) => {
if (p == HIDDEN)
return <Icon name="material-symbols:more-horiz" class="mx-1" aria-hidden="true" />;
if (p == page.currentPage)
return (
<div
class="h-11 w-11 rounded-lg bg-(--primary) flex items-center justify-center
font-bold text-white dark:text-black/70"
aria-current="page"
>
{p}
</div>
);
return (
<a
href={url(getPageUrl(p))}
aria-label={`${i18n(I18nKey.paginationPage)} ${p}`}
class="btn-card w-11 h-11 rounded-lg overflow-hidden active:scale-[0.85]"
>
{p}
</a>
);
})
}
</div>
<a
href={page.url.next || "#"}
aria-label={i18n(I18nKey.paginationNext)}
aria-disabled={page.url.next === undefined ? "true" : "false"}
tabindex={page.url.next === undefined ? "-1" : "0"}
class:list={[
"btn-card overflow-hidden rounded-lg text-(--primary) w-11 h-11",
{ disabled: page.url.next == undefined },
]}
>
<Icon
name="material-symbols:chevron-right-rounded"
class="text-[1.75rem]"
aria-hidden="true"
/>
</a>
</div>
</div>
|