导航组件
Pagination 分页
分页导航组件,支持上一页、下一页、页码链接和省略号,适用于长列表数据的翻页场景。
安装
bash
npx polyui add pagination基础
Basic
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
export function PaginationBasic() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Basic</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}带省略
With Ellipsis
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis } from "@polyui/react/pagination"
export function PaginationWithEllipsis() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">With Ellipsis</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">10</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}图标箭头
Icon Arrows
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink } from "@polyui/react/pagination"
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
export function PaginationIconArrows() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Icon Arrows</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to previous page" size="icon">
<ChevronLeftIcon className="size-4" />
</PaginationLink>
</PaginationItem>
{pages.map((page) => (
<PaginationItem key={page}>
<PaginationLink href="#" isActive={page === 2}>
{page}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationLink href="#" aria-label="Go to next page" size="icon">
<ChevronRightIcon className="size-4" />
</PaginationLink>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}主色激活
Primary Active
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
import { buttonVariants } from "@polyui/react/button"
import { cn } from "@polyui/core/lib/utils"
export function PaginationPrimaryActive() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Primary Active</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
{pages.map((page) => (
<PaginationItem key={page}>
<PaginationLink
href="#"
isActive={page === 2}
className={cn(
page === 2 &&
buttonVariants({ variant: "default", size: "icon" }) +
" hover:!text-primary-foreground dark:bg-primary dark:text-primary-foreground"
)}
>
{page}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}次色激活
Secondary Active
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
import { buttonVariants } from "@polyui/react/button"
import { cn } from "@polyui/core/lib/utils"
export function PaginationSecondaryActive() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Secondary Active</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
{pages.map((page) => (
<PaginationItem key={page}>
<PaginationLink
href="#"
isActive={page === 2}
className={cn(
page === 2 &&
"hover:!text-secondary-foreground !border-none !shadow-none " +
buttonVariants({ variant: "secondary", size: "icon" })
)}
>
{page}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}带边框
Bordered
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
import { buttonVariants } from "@polyui/react/button"
import { cn } from "@polyui/core/lib/utils"
export function PaginationBordered() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Bordered</p>
<Pagination>
<PaginationContent className="gap-0 divide-x overflow-hidden rounded-lg border">
<PaginationItem>
<PaginationPrevious href="#" className="rounded-none" />
</PaginationItem>
{pages.map((page) => (
<PaginationItem key={page}>
<PaginationLink
href={`#${page}`}
isActive={page === 2}
className={cn(
"rounded-none border-none",
page === 2 &&
buttonVariants({ variant: "default" }) +
" hover:!text-primary-foreground dark:bg-primary dark:text-primary-foreground"
)}
>
{page}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationNext href="#" className="rounded-none" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}圆角
Rounded
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
export function PaginationRounded() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Rounded</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" className="rounded-full" />
</PaginationItem>
{pages.map((page) => (
<PaginationItem key={page}>
<PaginationLink href={`#${page}`} isActive={page === 2} className="rounded-full">
{page}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationNext href="#" className="rounded-full" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}省略提示
Ellipsis with Tooltip
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis } from "@polyui/react/pagination"
import { Tooltip, TooltipContent, TooltipTrigger } from "@polyui/react/tooltip"
export function PaginationEllipsisTooltip() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Ellipsis with Tooltip</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<Tooltip>
<TooltipTrigger render={<PaginationEllipsis />} />
<TooltipContent>
<p>8 other pages</p>
</TooltipContent>
</Tooltip>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}下划线激活
Underline Active
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
export function PaginationUnderlineActive() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Underline Active</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" className="rounded-none" />
</PaginationItem>
<PaginationItem>
<PaginationLink
href="#"
isActive
className="border-primary! rounded-none border-0 border-b-2 bg-transparent! !shadow-none"
>
1
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" className="rounded-none">
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" className="rounded-none">
3
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" className="rounded-none" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}卡片
Card Pagination
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
export function PaginationCard() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Card Pagination</p>
<Pagination>
<PaginationContent className="rounded-md border p-1 shadow-xs">
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}无编号
Numberless
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
export function PaginationNumberless() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Numberless</p>
<Pagination>
<PaginationContent className="w-full justify-between">
<PaginationItem>
<PaginationPrevious href="#" className="border" />
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" className="border" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}无编号文字
Numberless with Text
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationPrevious, PaginationNext } from "@polyui/react/pagination"
export function PaginationNumberlessText() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Numberless with Text</p>
<Pagination>
<PaginationContent className="w-full justify-between">
<PaginationItem>
<PaginationPrevious href="#" className="border" />
</PaginationItem>
<PaginationItem>
<p className="text-muted-foreground text-sm" aria-live="polite">
Page <span className="text-foreground">2</span> of <span className="text-foreground">5</span>
</p>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" className="border" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}迷你
Mini Pagination
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink } from "@polyui/react/pagination"
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
export function PaginationMini() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Mini Pagination</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to previous page" size="icon">
<ChevronLeftIcon className="size-4" />
</PaginationLink>
</PaginationItem>
<PaginationItem>
<p className="text-muted-foreground text-sm" aria-live="polite">
Page <span className="text-foreground">2</span> of <span className="text-foreground">5</span>
</p>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to next page" size="icon">
<ChevronRightIcon className="size-4" />
</PaginationLink>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}页码选择
With Page Select
tsx
import { Pagination, PaginationContent, PaginationItem, PaginationLink } from "@polyui/react/pagination"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@polyui/react/select"
import { ChevronFirstIcon, ChevronLastIcon, ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
export function PaginationPageSelect() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">With Page Select</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to first page" size="icon" className="rounded-full">
<ChevronFirstIcon className="size-4" />
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to previous page" size="icon" className="rounded-full">
<ChevronLeftIcon className="size-4" />
</PaginationLink>
</PaginationItem>
<PaginationItem>
<Select defaultValue="1" aria-label="Select page">
<SelectTrigger className="w-fit whitespace-nowrap">
<SelectValue placeholder="Select page" />
</SelectTrigger>
<SelectContent>
{Array.from({ length: 10 }, (_, i) => i + 1).map((page) => (
<SelectItem key={page} value={String(page)}>
Page {page}
</SelectItem>
))}
</SelectContent>
</Select>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to next page" size="icon" className="rounded-full">
<ChevronRightIcon className="size-4" />
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" aria-label="Go to last page" size="icon" className="rounded-full">
<ChevronLastIcon className="size-4" />
</PaginationLink>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}表格
Table Pagination
Showing 1 to 10 of 100 products
tsx
import { Pagination } from "@polyui/react/pagination"
export function PaginationTable() {
return (
<div className="space-y-2">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Table Pagination</p>
<TablePagination />
</div>
)
}自定义文本
通过 text prop 自定义上一页和下一页按钮的文字。
tsx
<PaginationPrevious href="#" text="上一页" />
<PaginationNext href="#" text="下一页" />Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
PaginationLink › isActive | boolean | false | 标记当前激活页,使用 outline 变体高亮显示。 |
PaginationLink › size | "default" | "sm" | "lg" | "icon" | "icon" | 页码按钮的尺寸。 |
PaginationPrevious › text | string | "Previous" | 上一页按钮的文字标签。 |
PaginationNext › text | string | "Next" | 下一页按钮的文字标签。 |