ترقيم الصفحات
أرقام صفحات هي روابط حقيقية لا معالجات نقر، فتعمل دون JavaScript ويتبع الزاحف كل صفحة منها.
server - 0 KB
ترقيم الصفحات
server - 0 KBأرقام صفحات هي روابط حقيقية لا معالجات نقر، فتعمل دون JavaScript ويتبع الزاحف كل صفحة منها.
جرّبه
value
pageCount
siblingCount
boundaryCount
size
الشيفرة
pagination.tsx
import { Pagination } from 'topclassui/pagination'
<Pagination value={6} pageCount={12} getHref={(page) => `/blog?page=${String(page)}`} />getHref يبقي كل صفحة قابلة للزحف، وقيم value وsiblingCount وboundaryCount محصورة في مدى آمن.
كل الحالات، بدون تمرير الفأرة
4 حالاتأو استورده من الحزمة
topclassui/pagination
import { Pagination } from 'topclassui/pagination'ثبّت مرة واحدة:npm i topclassui@beta zod
أمثلة
- مرّر
valueوpageCountوgetHref، الدالة التي تحوّل رقم الصفحة إلى عنوانها، مثل /blog?page=3. كل خلية رابط حقيقي. - في Next.js يعيد الرابط العادي تحميل الصفحة. مرّر
link={<Link href="" />}فيصبح كل تغيير صفحة تنقّلًا من جهة المتصفح. - الصفحة الخاطئة في العنوان تُحصر لما يُعرض:
?page=999من 12 تعرض الصفحة 12. استعلم عن الصفحة نفسها بـclampPage(Number(page), pageCount). siblingCountوboundaryCount(من 0 إلى 3، والافتراضي 1) يحددان عدد الصفحات حول الحالية وعند كل طرف.size="md"ارتفاعه 40 px، ارتفاع الزر، وsize="sm"هو خلية 32 px في التصميم.customلا يضيف أصناف حجم.- الصف يلتف بدل أن يمرّر. على الهاتف مرّر
siblingCount={0}وboundaryCount={0}لصف أقصر. paginationVariants({ size, current })يعيد أصناف خلية واحدة، لرابط ترسمه بنفسك.
middle
middle.tsx
import { Pagination } from 'topclassui/pagination'
const blog = (page: number) => `/blog?page=${String(page)}`
/** Away from both ends: one sibling each side, one page at each end and a gap between. */
export default function Demo() {
return <Pagination value={6} pageCount={12} getHref={blog} />
}
first-page
first-page.tsx
import { Pagination } from 'topclassui/pagination'
const blog = (page: number) => `/blog?page=${String(page)}`
/** On page 1 there is nowhere to go back to, so first and previous are spans, not links. */
export default function Demo() {
return <Pagination value={1} pageCount={12} getHref={blog} />
}
last-page
last-page.tsx
import { Pagination } from 'topclassui/pagination'
const blog = (page: number) => `/blog?page=${String(page)}`
/** On the last page next and last are the spans; the row is still seven pages long. */
export default function Demo() {
return <Pagination value={12} pageCount={12} getHref={blog} />
}
sizes
sizes.tsx
import { Pagination } from 'topclassui/pagination'
const blog = (page: number) => `/blog?page=${String(page)}`
/** Two navs on one page need a name each, so every one here passes its own aria-label. */
export default function Demo() {
return (
<div className="flex flex-col gap-4">
<Pagination size="xs" value={3} pageCount={12} getHref={blog} aria-label="Extra small" />
<Pagination size="sm" value={3} pageCount={12} getHref={blog} aria-label="Small" />
<Pagination size="md" value={3} pageCount={12} getHref={blog} aria-label="Medium" />
<Pagination size="lg" value={3} pageCount={12} getHref={blog} aria-label="Large" />
<Pagination size="xl" value={3} pageCount={12} getHref={blog} aria-label="Extra large" />
</div>
)
}
many-pages
many-pages.tsx
import { Pagination } from 'topclassui/pagination'
const orders = (page: number) => `/orders?page=${String(page)}`
/** 500 pages are still eleven cells: two at each end, two each side of 250 and two gaps. */
export default function Demo() {
return <Pagination value={250} pageCount={500} siblingCount={2} boundaryCount={2} getHref={orders} />
}
two-navs
Orders 26 to 50 of 200
two-navs.tsx
import { Pagination } from 'topclassui/pagination'
const orders = (page: number) => `/orders?page=${String(page)}`
/** Above and below one list: two navs on a page need a name each, so each passes aria-label. */
export default function Demo() {
return (
<div className="flex flex-col gap-4">
<Pagination value={2} pageCount={8} getHref={orders} aria-label="Orders pages, top" />
<p className="text-sm text-muted">Orders 26 to 50 of 200</p>
<Pagination value={2} pageCount={8} getHref={orders} aria-label="Orders pages, bottom" />
</div>
)
}
custom-size
custom-size.tsx
import { Pagination } from 'topclassui/pagination'
const blog = (page: number) => `/blog?page=${String(page)}`
/** custom emits no size: a cell falls to the 24 px floor and takes the type size of the nav. */
export default function Demo() {
return (
<div className="flex flex-col gap-4">
<Pagination value={3} pageCount={12} getHref={blog} aria-label="The scale" />
<Pagination size="custom" className="text-xs" value={3} pageCount={12} getHref={blog} aria-label="Your own cells" />
</div>
)
}
wide-numbers
wide-numbers.tsx
import { Pagination } from 'topclassui/pagination'
const orders = (page: number) => `/orders?page=${String(page)}`
/** Page 12,345 of 123,456: a cell grows with its number, so no digit leaves the box. */
export default function Demo() {
return (
<div className="flex flex-col gap-4">
<Pagination size="xs" value={12345} pageCount={123456} getHref={orders} aria-label="Extra small" />
<Pagination size="sm" value={12345} pageCount={123456} getHref={orders} aria-label="Small" />
<Pagination value={12345} pageCount={123456} getHref={orders} aria-label="Medium" />
</div>
)
}
بالعربية، من اليمين إلى اليسار
rtl.tsx
import { ar } from 'topclassui/labels/ar'
import { Pagination } from 'topclassui/pagination'
const blog = (page: number) => `/blog?page=${String(page)}`
/** The row runs from the right and the four carets flip, with no class of its own for it. */
export default function Demo() {
return (
<div dir="rtl" lang="ar">
<Pagination value={3} pageCount={12} getHref={blog} labels={ar} locale="ar" />
</div>
)
}
الخصائص
لوحة المفاتيح وإمكانية الوصول
- الصفحة الحالية عليها
aria-current="page"واسمها «صفحة 3 من 12»، وكل خلية أخرى اسمها «صفحة 4». - السابق والتالي عليهما
rel="prev"وrel="next". في الصفحة الأولى والأخيرة يكون ذلك الزر معطّلًا ودون href. - إن كان في الصفحة عنصرا ترقيم فلكلٍّ منهما
aria-labelخاص به، مثل «صفحات الطلبات، أعلى» و«صفحات الطلبات، أسفل».
من اليمين إلى اليسار
مع dir="rtl" يبدأ الصف من اليمين وتنقلب الأسهم الأربعة. {...getLabels('ar')} يمرّر النصوص العربية واللغة معًا.
الخادم والمتصفح
يُعرض على الخادم ولا يرسل أي JavaScript.
الملفات: index.tsx.
على الشارة: server - 0 KB.