O desenvolvimento de interfaces de usuário (UI) para aplicações web e mobile está em constante evolução. Uma das interações mais populares, popularizada por aplicativos como o Tinder, é o "swipe card", onde o usuário arrasta um cartão para a esquerda ou direita para indicar rejeição ou aprovação. Implementar essa funcionalidade com bom desempenho e uma experiência de usuário fluida pode ser um desafio. Este artigo explora como criar um efeito de "swipe card" no estilo Tinder utilizando Next.js 16 (App Router), React 19 e Tailwind CSS, sem a necessidade de bibliotecas externas pesadas como o Framer Motion. Vamos mergulhar no código e entender a lógica por trás dessa implementação.
Construindo um Componente de Swipe Card com Next.js, React e Tailwind CSS
Recentemente, um desenvolvedor compartilhou sua experiência ao criar um aplicativo de busca de colegas de quarto, utilizando o novo App Router do Next.js 16. O maior desafio foi replicar a sensação nativa do "swipe card" sem recorrer a bibliotecas complexas. A solução encontrada envolveu o uso inteligente do estado do React, animações CSS com Tailwind CSS e uma lógica de renderização otimizada. Vamos analisar os principais aspectos dessa implementação.
A Lógica por Trás do Swipe Card
A chave para criar um efeito de "swipe card" eficiente reside na compreensão de que não estamos realmente movendo uma pilha de elementos DOM. Em vez disso, estamos renderizando um único cartão ativo e alterando os dados por trás dele. Para conseguir essa ilusão, precisamos rastrear duas informações principais no estado do nosso componente React:
- O Índice (Index): Qual item do array de dados estamos exibindo atualmente? Este índice nos permite navegar entre os diferentes perfis ou cartões disponíveis.
- A Direção (Direction): O usuário está deslizando o cartão para a esquerda (rejeitar) ou para a direita (aprovar)? Essa informação é crucial para acionar a animação correta.
Com essas duas informações em mãos, podemos manipular o estado do componente para criar a animação de "swipe" e atualizar o cartão exibido.
Implementação do Componente SwipeStack
O código a seguir apresenta uma versão simplificada do componente SwipeStack, que demonstra a lógica central do efeito de "swipe card":
'use client';
import { useState } from 'react';
export default function SwipeStack({ items }) {
// 1. Track which card is active
const [currentIndex, setCurrentIndex] = useState(0);
// 2. Track animation direction ('left' | 'right' | null)
const [swipeDirection, setSwipeDirection] = useState(null);
const handleSwipe = (direction) => {
// Step A: Trigger the animation
setSwipeDirection(direction);
// Step B: Wait for animation to finish, then show next card
setTimeout(() => {
setCurrentIndex((prev) => prev + 1);
setSwipeDirection(null); // Reset animation
}, 300); // Matches CSS transition duration
};
const currentItem = items[currentIndex];
if (!currentItem) return No more profiles!;
return (
{/* Your Card Component */}
{/* Control Buttons */}
);
}
Vamos detalhar o que está acontecendo neste código:
- Gerenciamento de Estado: Utilizamos o hook
useStatedo React para rastrear ocurrentIndex(o índice do cartão atualmente exibido) e oswipeDirection(a direção do "swipe"). - Função
handleSwipe: Esta função é chamada quando o usuário clica nos botões de "rejeitar" ou "aprovar". Ela atualiza o estadoswipeDirectionpara iniciar a animação e, em seguida, utilizasetTimeoutpara aguardar a conclusão da animação antes de atualizar ocurrentIndexe redefinir oswipeDirection. - Animação com Tailwind CSS: As classes CSS do Tailwind CSS são aplicadas dinamicamente com base no valor de
swipeDirection. QuandoswipeDirectioné'left', a classe-translate-x-full -rotate-12 opacity-0é adicionada, movendo o cartão para a esquerda, rotacionando-o e tornando-o transparente. O mesmo acontece para a direita, com classes diferentes. A classetransition-all duration-300 ease-outgarante uma transição suave. - Renderização Condicional: Se não houver mais itens no array
items(ou seja,currentIteménull), uma mensagem indicando que não há mais perfis é exibida.
O Segredo da Animação Fluida
A animação suave e responsiva é crucial para uma boa experiência de usuário. Neste caso, a animação é alcançada utilizando apenas as propriedades translate e opacity do CSS. Essas propriedades são altamente otimizadas pelos navegadores modernos, resultando em animações de 60fps (quadros por segundo) mesmo em dispositivos móveis. Evitar propriedades que causam reflow ou repaints (como width ou height) é essencial para manter o desempenho.
O uso do setTimeout é fundamental. Ele permite que a animação CSS seja concluída antes que o estado do componente seja atualizado. Sem esse atraso, o novo cartão apareceria instantaneamente, sem a animação de transição.
Benefícios da Abordagem
A abordagem descrita oferece diversas vantagens em relação ao uso de bibliotecas externas:
- Menor Tamanho do Bundle: Evitar bibliotecas pesadas reduz o tamanho do bundle da sua aplicação, resultando em tempos de carregamento mais rápidos.
- Maior Controle: Você tem controle total sobre a animação e a lógica do componente, permitindo personalizações mais precisas.
- Dependências Reduzidas: Menos dependências significam menos vulnerabilidades e menos problemas de compatibilidade.
- Aprendizado: Implementar funcionalidades complexas manualmente aprofunda seu conhecimento do React e do CSS.
Recursos Adicionais e Código Aberto
O desenvolvedor por trás dessa implementação disponibilizou o código-fonte completo do UI kit, incluindo a lógica de "swipe", a navegação inferior e a interface de chat, em um repositório GitHub. Você pode acessar o repositório para ver como o filtro de array e as áreas seguras para dispositivos móveis foram tratados:
- Repositório GitHub: Next.js Mobile Marketplace Starter (substitua pelo link real)
- Demo ao Vivo: Link para a Demo (substitua pelo link real)
Conclusão
A criação de um efeito "swipe card" no estilo Tinder utilizando Next.js, React e Tailwind CSS demonstra o poder e a flexibilidade dessas tecnologias. Ao evitar bibliotecas externas e focar em otimizações de desempenho, é possível criar interfaces de usuário fluidas e responsivas, mesmo em dispositivos móveis. A capacidade de manipular o estado do React e aproveitar as animações CSS é fundamental para o desenvolvimento web moderno. O futuro do desenvolvimento web está cada vez mais focado em otimização de performance e em experiências de usuário cada vez mais ricas e interativas. Com o avanço contínuo das ferramentas e frameworks, como Next.js e React, e a crescente importância do CSS para animações e estilos, podemos esperar interfaces ainda mais inovadoras e eficientes no futuro.