Pagination
Controles de navegação entre páginas com contrato copy-first e composição shadcn.
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination'
export function PaginationExample() {
return (
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="?page=1" aria-disabled="true" className="pointer-events-none opacity-50" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=1">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=2" isActive>2</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=3">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href="?page=3" />
</PaginationItem>
</PaginationContent>
</Pagination>
)
} <script setup lang="ts">
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination'
</script>
<template>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="?page=1" aria-disabled="true" class="pointer-events-none opacity-50" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=1">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=2" is-active>2</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=3">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href="?page=3" />
</PaginationItem>
</PaginationContent>
</Pagination>
</template> <nav class="itps-pagination" aria-label="Paginação">
<button type="button" class="itps-pagination__button" aria-label="Página anterior" disabled>
<i class="ti ti-chevron-left" aria-hidden="true"></i>
</button>
<input type="number" value="1" min="1" max="10" class="itps-pagination__input" aria-label="Número da página atual" />
<span class="itps-pagination__label">de 10</span>
<button type="button" class="itps-pagination__button" aria-label="Próxima página">
<i class="ti ti-chevron-right" aria-hidden="true"></i>
</button>
</nav> Instalação
Instale o Pagination da sua stack e rode o comando individual ITpS em seguida. O comando itps add pagination é theme-only: ele valida o slug e confirma que o contrato visual vem do tema ITpS, das classes copy-first e dos snippets desta página.
terminal · React/Next
pnpm dlx shadcn@latest add pagination
pnpm dlx github:ITPS/sinapse-ui-cli add pagination terminal · Vue3/Nuxt4
pnpm dlx shadcn-vue@latest add pagination
pnpm dlx github:ITPS/sinapse-ui-cli add pagination O comando individual adapta só este componente; não instala o catálogo inteiro.
Uso
Use Pagination quando o usuário precisa navegar por listas, tabelas ou resultados longos mantendo página atual, total e extremos claros.
Em React/Next com shadcn/ui e Vue3/Nuxt4 com shadcn-vue, use os componentes compostos de @/components/ui/pagination. Para HTML ou wrappers finos, use itps-pagination diretamente e conecte os handlers de navegação na sua stack.
Exemplos
Estrutura
| Peça | React/Next e Vue3/Nuxt4 | HTML |
|---|---|---|
| Landmark | Pagination | <nav class="itps-pagination"> |
| Lista e item | PaginationContent, PaginationItem | filhos diretos do nav |
| Página numérica | PaginationLink | itps-pagination__input ou botão local |
| Anterior/próxima | PaginationPrevious, PaginationNext | itps-pagination__button |
| Atalho de extremo | composição do projeto | itps-pagination__button--boundary |
| Total | composição textual | itps-pagination__label |
Extremos e disabled
Use atalhos de primeira/última página em tabelas longas. Nos extremos, desabilite o controle que não pode executar ação. Em anchors shadcn, prefira aria-disabled com estado visual; em botão copy-first, use disabled.
<div class="flex flex-col items-start gap-4">
<nav class="itps-pagination" aria-label="Paginação na primeira página">
<button type="button" class="itps-pagination__button itps-pagination__button--boundary" aria-label="Primeira página" disabled>
<i class="ti ti-chevron-left-pipe" aria-hidden="true"></i>
</button>
<button type="button" class="itps-pagination__button" aria-label="Página anterior" disabled>
<i class="ti ti-chevron-left" aria-hidden="true"></i>
</button>
<input type="number" value="1" min="1" max="5" class="itps-pagination__input" aria-label="Número da página atual" />
<span class="itps-pagination__label">de 5</span>
<button type="button" class="itps-pagination__button" aria-label="Próxima página">
<i class="ti ti-chevron-right" aria-hidden="true"></i>
</button>
<button type="button" class="itps-pagination__button itps-pagination__button--boundary" aria-label="Última página">
<i class="ti ti-chevron-right-pipe" aria-hidden="true"></i>
</button>
</nav>
<nav class="itps-pagination" aria-label="Paginação na última página">
<button type="button" class="itps-pagination__button itps-pagination__button--boundary" aria-label="Primeira página">
<i class="ti ti-chevron-left-pipe" aria-hidden="true"></i>
</button>
<button type="button" class="itps-pagination__button" aria-label="Página anterior">
<i class="ti ti-chevron-left" aria-hidden="true"></i>
</button>
<input type="number" value="5" min="1" max="5" class="itps-pagination__input" aria-label="Número da página atual" />
<span class="itps-pagination__label">de 5</span>
<button type="button" class="itps-pagination__button" aria-label="Próxima página" disabled>
<i class="ti ti-chevron-right" aria-hidden="true"></i>
</button>
<button type="button" class="itps-pagination__button itps-pagination__button--boundary" aria-label="Última página" disabled>
<i class="ti ti-chevron-right-pipe" aria-hidden="true"></i>
</button>
</nav>
</div> API copy-first
| Classe/atributo | Uso |
|---|---|
itps-pagination | Container inline com gap estável para controles de página. |
itps-pagination__button | Botão circular para anterior/próxima ou ações de navegação. |
itps-pagination__button--boundary | Botão de primeira/última página com borda e fundo secundário. |
itps-pagination__input | Campo numérico da página atual, limitado por min e max. |
itps-pagination__label | Texto auxiliar para total de páginas. |
aria-label | Nomeia o nav e os botões apenas com ícone. |
disabled | Bloqueia botões copy-first que não podem navegar. |
aria-disabled="true" | Comunica estado indisponível em links shadcn. |
min / max | Limitam o campo numérico ao intervalo real de páginas. |
aria-hidden="true" | Esconde ícones decorativos de tecnologias assistivas. |
Acessibilidade
Use um <nav> com aria-label específico para diferenciar paginações quando houver mais de uma na tela. Botões apenas com ícone precisam de aria-label; os ícones decorativos ficam com aria-hidden="true". Campos numéricos devem ter min, max e nome acessível. Em links desabilitados, use aria-disabled="true" e remova handlers de ativação.