Paginator
Componente para navegar entre páginas de listas, tabelas e grids extensos. Suporta modo numerado com ellipsis e modo simples.
O mk-pagination permite navegar entre páginas de listas, tabelas e grids extensos. Ele combina três responsabilidades em um único controle: permitir que o usuário escolha quantos itens quer ver por página, indicar em que ponto do conjunto ele está (por exemplo, "1–20 de 250") e oferecer botões de navegação para a primeira, anterior, próxima e última página — além de acesso rápido a páginas específicas. Suporta modo numerado com ellipsis inteligente, modo simples (apenas Anterior/Próximo), rótulo de intervalo, seletor de tamanho de página e botões de salto para os extremos.
Quando usar
Use o mk-pagination sempre que um conjunto de dados tiver mais registros do que o que pode ser exibido confortavelmente em uma única tela.
- A listagem, tabela ou grid tiver mais registros do que o limite configurado por página.
- O usuário precisar navegar entre blocos de dados de forma previsível e controlada.
- For importante informar ao usuário quantos registros existem no total e em qual fatia ele está.
- O conjunto de dados for pequeno o suficiente para caber em uma tela — listas curtas não precisam de paginação.
- A interface adotar carregamento infinito (scroll infinito) — os dois padrões não convivem bem e criam expectativas opostas no usuário.
Anatomia
O paginador é formado por três áreas funcionais dispostas horizontalmente: o seletor de linhas por página, o contador de registros e a barra de navegação com botões de página.
| # | Parte | Obrigatório? | Função |
|---|---|---|---|
| 1 | Seletor de linhas por página | Sim | Permite ao usuário escolher quantos registros quer visualizar por página. Composto pelo rótulo "Linhas por página" e um seletor dropdown com as opções disponíveis. |
| 2 | Contador de registros | Sim | Texto informativo que indica o intervalo visível e o total de registros (ex.: "1–20 de 250"). Contextualiza o usuário sobre sua posição no conjunto de dados. |
| 3 | Barra de navegação | Sim | Conjunto de controles de navegação: botões de atalho para primeira e última página, botões de página anterior e próxima, e os botões numéricos de página com reticências quando há muitas páginas. |
| 3a | Botão primeira página | Sim | Ícone de chevron duplo para a esquerda. Leva diretamente à página 1. |
| 3b | Botão página anterior | Sim | Ícone de chevron simples para a esquerda. Retrocede uma página. |
| 3c | Botões de página | Sim | Botões numéricos clicáveis. O botão da página ativa é visualmente destacado. Quando há muitas páginas, reticências comprimem o intervalo. |
| 3d | Botão próxima página | Sim | Ícone de chevron simples para a direita. Avança uma página. |
| 3e | Botão última página | Sim | Ícone de chevron duplo para a direita. Leva diretamente à última página. |
| 4 | Menu dropdown de linhas | Não | Lista sobreposta com as opções de quantidade de linhas por página. Aparece quando o usuário aciona o seletor de linhas. |
Estados
Botão numérico de página
| Estado | Quando aparece | O que muda visualmente |
|---|---|---|
| Padrão | Página disponível, mas não é a atual | Fundo transparente, número em cor neutra escura. |
| Hover | Cursor sobre o botão | Fundo preenchido com cinza claro. |
| Pressionado | Clique ou toque em andamento | Fundo com cinza médio, feedback de ativação. |
| Selecionado | Página ativa no momento | Fundo escuro, número em branco — destaque máximo para indicar posição atual. |
Dropdown de linhas por página
| Estado | Quando aparece | O que muda visualmente |
|---|---|---|
| Padrão (fechado) | Tela carregada ou após seleção de opção | Apenas o rótulo e o valor selecionado são visíveis; dropdown não aparece. |
| Aberto | Usuário clica no seletor de linhas | Menu sobreposto aparece com fundo branco, borda cinza e lista de opções. |
Uso básico
import { MkPagination } from '@db1/makuco-ui-react';
import { useState } from 'react';
function MinhaTabela() {
const [pagina, setPagina] = useState(1);
return (
<MkPagination
currentPage={pagina}
totalPages={10}
onMkPageChange={(e) => setPagina(e.detail.page)}
/>
);
}<mk-pagination
[currentPage]="pagina"
[totalPages]="totalPaginas"
(mkPageChange)="pagina = $event.detail.page"
></mk-pagination>Modo simples
Use mode="simple" quando não for necessário exibir números de página — por exemplo, em carrosséis ou fluxos paginados sem contexto numérico. Prefira este modo quando o total de páginas não for relevante para o usuário ou quando o espaço disponível for reduzido.
<MkPagination
mode="simple"
currentPage={pagina}
totalPages={20}
onMkPageChange={(e) => setPagina(e.detail.page)}
/><mk-pagination
mode="simple"
[currentPage]="pagina"
[totalPages]="20"
(mkPageChange)="pagina = $event.detail.page"
></mk-pagination>Variante neutral
Use variant="neutral" para ambientes onde a cor de ação primária não é adequada, como em superfícies com fundo colorido ou em contextos onde o paginador não deve chamar atenção como elemento principal da tela.
<MkPagination
variant="neutral"
currentPage={pagina}
totalPages={10}
onMkPageChange={(e) => setPagina(e.detail.page)}
/><mk-pagination
variant="neutral"
[currentPage]="pagina"
[totalPages]="10"
(mkPageChange)="pagina = $event.detail.page"
></mk-pagination>Ellipsis em muitas páginas
Com totalPages > maxVisible (padrão 7), páginas não contíguas são recolhidas com ..., sempre preservando a primeira, a última e a página atual com suas vizinhas. O número total de itens renderizados nunca ultrapassa maxVisible.
<MkPagination
currentPage={pagina}
totalPages={50}
onMkPageChange={(e) => setPagina(e.detail.page)}
/><mk-pagination
[currentPage]="pagina"
[totalPages]="50"
(mkPageChange)="pagina = $event.detail.page"
></mk-pagination>Rótulo de intervalo
Quando showRangeLabel está ativo, o componente exibe "X–Y de Z" ao fim dos controles. Requer pageSize e totalItems.
<MkPagination
currentPage={pagina}
totalPages={10}
showRangeLabel
pageSize={10}
totalItems={100}
onMkPageChange={(e) => setPagina(e.detail.page)}
/><mk-pagination
[currentPage]="pagina"
[totalPages]="10"
show-range-label
[page-size]="10"
[total-items]="100"
(mkPageChange)="pagina = $event.detail.page"
></mk-pagination>Seletor de tamanho de página
Passe pageSizeOptions com um array de números para exibir um select antes dos controles. O componente emite mkPageSizeChange quando o usuário altera o tamanho — o pai deve atualizar pageSize e resetar currentPage para 1.
const [pagina, setPagina] = useState(1);
const [tamPagina, setTamPagina] = useState(10);
const totalItens = 100;
<MkPagination
currentPage={pagina}
totalPages={Math.ceil(totalItens / tamPagina)}
pageSizeOptions={[10, 25, 50, 100]}
pageSize={tamPagina}
showRangeLabel
totalItems={totalItens}
onMkPageChange={(e) => setPagina(e.detail.page)}
onMkPageSizeChange={(e) => {
setTamPagina(e.detail.pageSize);
setPagina(1);
}}
/><mk-pagination
[currentPage]="pagina"
[totalPages]="totalPaginas"
[pageSizeOptions]="[10, 25, 50, 100]"
[pageSize]="tamPagina"
show-range-label
[totalItems]="totalItens"
(mkPageChange)="pagina = $event.detail.page"
(mkPageSizeChange)="onPageSizeChange($event)"
></mk-pagination>Botões de navegação rápida
Use showBoundaryButtons para exibir botões de salto direto para a primeira e última página ao lado dos botões Anterior e Próximo.
<MkPagination
currentPage={pagina}
totalPages={20}
showBoundaryButtons
onMkPageChange={(e) => setPagina(e.detail.page)}
/><mk-pagination
[currentPage]="pagina"
[totalPages]="20"
show-boundary-buttons
(mkPageChange)="pagina = $event.detail.page"
></mk-pagination>Desabilitado
<MkPagination currentPage={5} totalPages={10} disabled /><mk-pagination current-page="5" total-pages="10" disabled></mk-pagination>Comportamento
O paginador tem dois fluxos de interação principais.
Navegação por página: o usuário clica em um botão numérico para ir diretamente a uma página, ou usa os botões de seta para avançar e recuar uma página por vez. Os botões de dupla seta pulam para a primeira ou última página. A página ativa é sempre visualmente destacada na lista de botões.
Seleção de linhas por página: o usuário clica no seletor de linhas para abrir o menu dropdown com as opções disponíveis. Ao escolher um valor, o dropdown fecha, a listagem é atualizada e o contador reflete o novo intervalo — por exemplo, se o usuário estava em "1–20 de 250" e muda para 50 linhas, o contador passa a exibir "1–50 de 250" e a numeração de páginas se ajusta automaticamente.
Composição
O paginador é projetado para acompanhar tabelas de dados e listagens longas. Ele sempre aparece abaixo do conteúdo que pagina, alinhado à largura total da área de dados.
Não combine paginação com scroll infinito na mesma tela — os padrões criam expectativas opostas no usuário: um sugere que há um fim definido, o outro que o conteúdo continua sem limite.
Props
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
currentPage | number | 1 | Página atual (1-indexed). Totalmente controlado — o consumidor deve atualizar ao receber mkPageChange. |
totalPages | number | — | Total de páginas. Obrigatório quando mode="numbered". |
mode | "numbered" | "simple" | "numbered" | "numbered" exibe botões de página com ellipsis; "simple" exibe apenas Anterior e Próximo. |
variant | "primary" | "neutral" | "primary" | "primary" usa tokens de ação; "neutral" usa tokens de superfície. |
maxVisible | number | 7 | Quantidade máxima de itens visíveis (incluindo ellipsis). O número de botões renderizados nunca ultrapassa esse valor. |
showRangeLabel | boolean | false | Exibe o rótulo "X–Y de Z" ao fim dos controles. Requer pageSize e totalItems. |
pageSize | number | — | Itens por página. Se omitido quando pageSizeOptions está preenchido, usa o primeiro valor do array. |
totalItems | number | — | Total de itens. Necessário para showRangeLabel. |
pageSizeOptions | number[] | [] | Opções de tamanho de página para o select. Quando vazio, o select não é renderizado. |
showBoundaryButtons | boolean | false | Exibe botões de salto para a primeira e última página ao lado de Anterior/Próximo. |
locale | string | — | Tag de locale BCP 47 (ex.: "en", "es", "pt-BR"). Recai para lang do ancestral mais próximo e depois "pt-BR". |
disabled | boolean | false | Desabilita toda a paginação, impedindo interação do usuário. |
Eventos
| Evento | Payload | Descrição |
|---|---|---|
mkPageChange | { page: number } | Emitido ao clicar em um número de página ou nos botões Anterior, Próximo, Primeira e Última. O valor de page é 1-indexed. |
mkPageSizeChange | { pageSize: number } | Emitido quando o usuário seleciona um novo tamanho de página. O consumidor deve atualizar pageSize e resetar currentPage para 1. |
Acessibilidade
- O componente renderiza um
<nav role="navigation" aria-label="Paginação">como container semântico. - A página atual recebe
aria-current="page"e bloqueia cliques no handler. - Cada botão de página tem
aria-label="Ir para página N". - Os botões de navegação têm
aria-labeldescritivo (ex.: "Página anterior", "Próxima página", "Primeira página", "Última página"). - Os elementos de ellipsis têm
aria-hidden="true". - Quando
disabled, o componente bloqueia toda interação mas permanece visível para leitores de tela.
Navegação por teclado: todos os botões do paginador devem ser acessíveis via Tab. A ordem de foco deve seguir a ordem visual: seletor de linhas → botão primeira página → botão anterior → botões numéricos → botão próximo → botão última página.
Indicador de foco: cada botão deve ter um contorno de foco visível ao receber o foco pelo teclado. Sem esse indicador, usuários que navegam sem mouse perdem o rastro de onde estão na interface.
Contador de registros: quando o valor é atualizado após navegação, o leitor de tela precisa ser notificado — use aria-live para que o novo intervalo seja anunciado automaticamente.
Dropdown de linhas por página: ao abrir o menu, o foco deve mover-se para a lista de opções. Ao fechar (por seleção ou Escape), o foco retorna ao botão que abriu o dropdown.
Contraste: todos os textos, números e ícones devem ter contraste suficiente para leitura em condições de baixa luminosidade — incluindo o número branco sobre o fundo escuro do botão de página selecionado.