O Symfony UX 3.5 chegou com quase 90 pull requests incorporados desde a versão 3.4. A novidade que mais chama atenção é o UX Pagination, um pacote oficial para paginar consultas do Doctrine, arrays e fontes de dados customizadas sem obrigar a aplicação a transformar uma lista comum em um componente cheio de JavaScript.
A release também mexe em Twig Components, Autocomplete, Dropzone, Icons e no UX Toolkit. É uma atualização grande para o projeto, mas a paginação merece ser entendida separadamente porque tenta reunir três estratégias que normalmente acabam espalhadas entre bibliotecas, código do repositório e helpers próprios.
O que o UX Pagination resolve
O pacote symfony/ux-pagination recebe uma fonte ainda não paginada, resolve os parâmetros da requisição, busca apenas o recorte necessário e devolve um resultado iterável para o controller e o Twig. A instalação é feita com Composer:
composer require symfony/ux-pagination
Ele funciona com queries do Doctrine ORM e DBAL, arrays, callbacks e adapters próprios. A navegação renderizada no servidor usa links reais, então uma paginação básica não depende de Stimulus, Turbo ou outro código no navegador. Existe integração opcional com LiveComponent para atualizar a lista sem recarregar a página, mas os URLs continuam navegáveis e compartilháveis.
Três estratégias para problemas diferentes
O ponto mais interessante da API é não fingir que toda paginação precisa oferecer a mesma promessa. O Symfony UX 3.5 separa três estratégias:
- Páginas numeradas: calcula o total, mostra números e permite saltar diretamente para uma página. É a opção familiar, mas normalmente exige uma consulta de contagem.
- Lookahead: busca um item a mais para descobrir se existe uma próxima página. Evita o
COUNT, mas deixa de oferecer um total exato e o salto para qualquer página. - Cursor bidirecional: continua a partir de uma posição assinada. É mais adequado quando registros podem entrar ou mudar enquanto a pessoa navega pela lista.
Essa divisão ajuda a escolher pelo comportamento necessário. Uma tela administrativa que precisa exibir “página 5 de 27” ainda combina com paginação numerada. Um feed que só mostra “anterior” e “próxima” pode evitar uma contagem cara com lookahead. Já uma lista muito movimentada tende a se beneficiar do cursor para não deslocar resultados entre requisições.
Como fica no controller e no Twig
O fluxo básico injeta PaginatorInterface, entrega a query ao paginador e envia o resultado para a view. Um exemplo reduzido fica assim:
public function __invoke(
ProductRepository $repository,
PaginatorInterface $paginator,
): Response {
$products = $paginator->paginate(
$repository->createListQuery(),
);
return $this->render('product/index.html.twig', [
'products' => $products,
]);
}
No Twig, o mesmo objeto alimenta a lista e os links de navegação:
{% for product in products %}
<article>{{ product.name }}</article>
{% endfor %}
{{ ux_pagination(products) }}
O pacote inclui temas padrão, Bootstrap e Tailwind. Também permite substituir o template sem misturar a lógica de paginação com as classes do projeto. É uma escolha sensata: o backend cuida de limites, posição e URLs, enquanto o tema decide como os controles aparecem.
A release vai além da paginação
O Symfony UX 3.5 também passa a aceitar Twig 4 em vários pacotes, incluindo Autocomplete, Dropzone, Icons, LiveComponent, Map, Turbo e TwigComponent. O Autocomplete deixa de exigir Doctrine e pode buscar opções em APIs, mecanismos de busca ou listas em memória por meio de uma interface própria.
Dropzone ganhou suporte a múltiplos arquivos, o Toolkit recebeu vinte novas receitas inspiradas no Shadcn e a documentação de acessibilidade dessas receitas trouxe correções reais para diálogos e layouts da direita para a esquerda. Houve ainda uma rodada de otimizações em TwigComponent e LiveComponent para evitar trabalho repetido durante a renderização.
Vale atualizar agora?
Para quem já usa Symfony UX, a versão tem melhorias úteis mesmo sem adotar o novo paginador. Ainda assim, vale revisar snapshots e testes que comparam HTML literalmente: a renderização de atributos dos componentes passou a usar a implementação do próprio Twig, e o SVG produzido por UX Icons também pode mudar.
O UX Pagination continua marcado como experimental, portanto sua API pode mudar. Faz sentido testá-lo em uma tela isolada antes de substituir uma solução estável em toda a aplicação. Também é melhor instalar a versão mais recente da linha 3.5, já que a 3.5.1 saiu poucas horas depois para corrigir duas integrações com o AssetMapper do Symfony 8.2.
