HextaUI

Pagination

Navegación de páginas que mantiene cada botón en su sitio, se desliza hasta la página actual y salta a cualquier página desde los puntos suspensivos.

Showing 1–10 of 248 results

"use client"

import * as React from "react"

import { Pagination } from "@/components/ui/pagination"

const perPage = 10
const total = 248

export function PaginationDemo() {
  const [page, setPage] = React.useState(1)
  const first = (page - 1) * perPage + 1
  const last = Math.min(page * perPage, total)

  return (
    <div className="flex w-full flex-col items-center gap-4">
      <Pagination
        page={page}
        count={Math.ceil(total / perPage)}
        onPageChange={setPage}
      />
      <p className="text-sm text-muted-foreground tabular-nums">
        Showing {first}–{last} of {total} results
      </p>
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/pagination.json

Añade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.

import { Pagination } from "@/components/ui/pagination"
const [page, setPage] = React.useState(1)

<Pagination page={page} count={25} onPageChange={setPage} />

Dale a Pagination un count y construye toda la barra. Siempre muestra el mismo número de huecos, así que Previous, Next y los números nunca se mueven bajo el cursor mientras pasas de página. Omite count para componer las partes tú mismo.

Pagination
└── PaginationContent
    ├── PaginationItem
    │   └── PaginationPrevious
    ├── PaginationItem
    │   └── PaginationLink
    ├── PaginationItem
    │   └── PaginationEllipsis
    └── PaginationItem
        └── PaginationNext

Saltar a una página

Haz clic en unos puntos suspensivos para escribir un número de página. Enter salta, un número fuera de rango hace vibrar el campo y Esc devuelve los puntos suspensivos. Desactívalo con jump={false}.

"use client"

import * as React from "react"

import { Pagination } from "@/components/ui/pagination"

export function PaginationLong() {
  const [page, setPage] = React.useState(480)

  return <Pagination page={page} count={1000} onPageChange={setPage} />
}

Compacto

Cuando la barra no cabe en su contenedor, cambia a Previous, “Page 4 of 24” y Next, y vuelve cuando hay espacio. La etiqueta también es un campo de salto. Fuerza cualquiera de los dos diseños con compact.

"use client"

import * as React from "react"

import { Pagination } from "@/components/ui/pagination"

export function PaginationCompact() {
  const [page, setPage] = React.useState(4)

  return (
    <div className="w-full max-w-72 rounded-xl border p-2">
      <Pagination page={page} count={24} onPageChange={setPage} />
    </div>
  )
}

Con getPageHref, cada página es un enlace real, por lo que puede abrirse en una pestaña nueva. Los clics normales siguen llamando a onPageChange.

"use client"

import * as React from "react"

import { Pagination } from "@/components/ui/pagination"

export function PaginationLinks() {
  const [page, setPage] = React.useState(3)

  return (
    <Pagination
      page={page}
      count={12}
      getPageHref={(target) => `#page-${target}`}
      onPageChange={setPage}
    />
  )
}

Componible

Sin count, construye la barra con las partes, como en shadcn/ui. Pasa render para usar el enlace de tu router.

"use client"

import * as React from "react"

import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination"

const pages = [1, 2, 3]

export function PaginationComposable() {
  const [page, setPage] = React.useState(2)

  return (
    <Pagination>
      <PaginationContent>
        <PaginationItem>
          <PaginationPrevious
            render={<button type="button" />}
            disabled={page === 1}
            onClick={() => setPage(page - 1)}
          />
        </PaginationItem>
        {pages.map((item) => (
          <PaginationItem key={item}>
            <PaginationLink
              render={<button type="button" />}
              isActive={item === page}
              onClick={() => setPage(item)}
            >
              {item}
            </PaginationLink>
          </PaginationItem>
        ))}
        <PaginationItem>
          <PaginationEllipsis />
        </PaginationItem>
        <PaginationItem>
          <PaginationNext
            render={<button type="button" />}
            disabled={page === pages.length}
            onClick={() => setPage(page + 1)}
          />
        </PaginationItem>
      </PaginationContent>
    </Pagination>
  )
}

De derecha a izquierda

usePagination devuelve los elementos de página y de puntos suspensivos para diseños personalizados. Los chevrons se invierten en texto de derecha a izquierda.

"use client"

import * as React from "react"

import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
  usePagination,
} from "@/components/ui/pagination"

export function PaginationRtl() {
  const [page, setPage] = React.useState(2)
  const { items, hasPrevious, hasNext } = usePagination({ page, count: 3 })

  return (
    <div dir="rtl">
      <Pagination aria-label="التنقل بين الصفحات">
        <PaginationContent>
          <PaginationItem>
            <PaginationPrevious
              text="السابق"
              aria-label="الصفحة السابقة"
              render={<button type="button" />}
              disabled={!hasPrevious}
              onClick={() => setPage(page - 1)}
            />
          </PaginationItem>
          {items.map((item) =>
            item.type === "page" ? (
              <PaginationItem key={item.page}>
                <PaginationLink
                  render={<button type="button" />}
                  isActive={item.page === page}
                  onClick={() => setPage(item.page)}
                >
                  {item.page.toLocaleString("ar-EG")}
                </PaginationLink>
              </PaginationItem>
            ) : null
          )}
          <PaginationItem>
            <PaginationNext
              text="التالي"
              aria-label="الصفحة التالية"
              render={<button type="button" />}
              disabled={!hasNext}
              onClick={() => setPage(page + 1)}
            />
          </PaginationItem>
        </PaginationContent>
      </Pagination>
    </div>
  )
}
KeyAcción
TabEntra y sale de la barra. Previous y Next siguen siendo enfocables en los extremos.
←→Se mueve entre Previous, las páginas y Next. Se invierte en diseños de derecha a izquierda.
HomeEndVa al primer o al último elemento.
EnterAbre la página enfocada o el campo de página. En el campo, salta a esa página y la enfoca.
EscCierra el campo de página y devuelve el foco a los puntos suspensivos.
  • La raíz es un <nav> con la etiqueta “Pagination”, y la página actual tiene aria-current="page".
  • En la primera y la última página, Previous y Next usan aria-disabled en lugar de disabled, así que el foco no se pierde al llegar al final.
  • El indicador deslizante se convierte en un fundido cuando el movimiento reducido está activado.
PropTipoPredeterminado
countTotal de páginas. Si se define, la barra se construye por ti; omítelo para componer las partes.
number–
page
number–
defaultPage
number1
onPageChange
(page: number) => void–
getPageHrefRenderiza las páginas como enlaces en lugar de botones.
(page: number) => string–
siblingsPáginas que se muestran a cada lado de la actual.
number1
boundariesPáginas que se muestran siempre al principio y al final.
number1
compactauto cambia a Previous, “Page x of y” y Next cuando la barra no cabe.
boolean | "auto""auto"
jumpPermite que los puntos suspensivos abran un campo de página.
booleantrue
AtributoDescripción
data-slot="pagination"El nav.
data-slot="pagination-indicator"El fondo que se desliza hasta la página actual.
PropTipoPredeterminado
isActiveMarca la página actual con aria-current="page".
booleanfalse
disabledDefine aria-disabled e ignora los clics.
booleanfalse
render
ReactElement | (props, state) => ReactElement<a>
AtributoDescripción
data-slot="pagination-link"Apunta a los enlaces de página en CSS.
data-activePresente en la página actual.
PropTipoPredeterminado
textPasa null para un botón solo con icono.
ReactNode"Previous" / "Next"
disabled
booleanfalse
PropTipoPredeterminado
onJumpConvierte los puntos suspensivos en un campo de página. Sin él, los puntos suspensivos son decorativos.
(page: number) => void–
countLa página más alta que acepta el campo.
number–
PropTipoPredeterminado
page
number–
count
number–
siblings
number1
boundaries
number1

Devuelve items, la page y el count ajustados, y hasPrevious y hasNext. Consulta la guía de usePagination para construir tu propio paginador.