Atomic Design na prática com React em um projeto real da RD Station
No meu artigo anterior eu falei sobre como utilizar o Atomic Design para criar arquiteturas escaláveis, neste artigo irei demonstrar um caso real onde utilizamos o modelo mental do Atomic Design para construir componentes React.
Usarei como exemplo o redesign da página inicial do RD Station Marketing. Como envolvia também uma mudança de linguagem e arquitetura, o front-end da página foi reescrito por inteiro, então foi como fazer uma tela nova.
A arquitetura front-end deste produto é distribuída em micro frontends, com diferentes projetos, em vários diferentes times, então o modelo que utilizamos para construir essa página foi para um projeto específico. As decisões aqui apresentadas não são regras, foram decisões dentro de um contexto, com o objetivo de compartilhar lições aprendidas.
Primeiros passos
Com o design da página em mãos, começamos a analisar e planejar como ela seria construída. Contando comigo, eram 3 desenvolvedores que iriam atuar no front-end, então paralelizar o trabalho era importante para atendermos o prazo da entrega.
Como cada seção da página era uma funcionalidade específica, dividimos cada uma em uma unidade própria que iria se unir no componente da página, assim cada um poderia avançar em uma parte da tela sem nenhum conflito.
De forma resumida, conforme demonstrado na imagem acima, a página ficaria conforme o código abaixo:
Essa divisão foi suficiente para distribuir as tarefas e iniciar o desenvolvimento. Como mencionei no artigo anterior, é importante não tentar adivinhar o futuro e tomar grandes decisões no começo, a estrutura vai emergindo conforme a necessidade.
A comunicação foi a peça fundamental para o projeto crescer de forma organizado, já no início do desenvolvimento criamos um grupo entre nós 3 (desenvolvedores front-end) para tomadas de decisões rápidas, enquanto as demais decisões eram sempre tomadas no canal do time. Utilizamos o Slack como meio de comunicação.
Implementação do Design System
Como a empresa estava passando por um redesign e um rebrand, tivemos que reconstruir nosso Design System. No momento que iniciamos a construção dessa página, já tínhamos uma biblioteca com alguns componentes primários, mas ainda teríamos que fazer grande parte direto na página.
Por exemplo, para a construção de um filtro simples para o gráfico que iria aparecer na página, passou por muito estudo e pesquisa para chegar a um padrão no nosso sistema de design (Design System).
Esse mesmo esforço é feito na implementação do Design System, ao construir componentes que padronizam o design, seja flexível para atender todos os cenários e ainda seja fácil de utilizar.
Essa página seria a primeira página com elementos de análise (analytics) a ser desenvolvida, então optamos por desenvolver os componentes novos direto no projeto e posteriormente transferi-los para uma biblioteca a fim de ser reutilizado em outros projetos.
Começamos então a criar componentes que representavam cada bloco na construção de cada seção e, quando o acúmulo de componentes começou a incomodar, decidimos parar e pensar em uma melhor estrutura de diretórios e componentes, foi quando a ideia de usar o Atomic Design surgiu.
Reestruturação com Atomic Design
Quando paramos para estruturar os arquivos e diretórios, notamos que o Atomic Design se encaixava com a forma que já estávamos organizando os componentes, então resolvemos criar diretórios com as camadas do Atomic Design:
- pages (Páginas) — Contém o componente raiz da página, que atualmente só tínhamos essa única página no projeto, mas já ficaria aberto para receber mais páginas.
- Ignoramos a camada Modelo por não fazer sentido no momento.
- organisms (Organismos) — Diretório com os componentes das seções da página.
- molecules (Moléculas) — Subdivisão dos organismos, com componentes mais especializados e reutilizáveis.
- atoms (Átomos) — A maioria dos átomos já vinham da biblioteca de componentes do Design System (UI Library), mas precisamos fazer pequenas customizações em alguns e criar outros.
Como a intenção era criar os componentes de análise neste projeto, depois exportar para uma biblioteca, essa divisão de camadas favorece essa abordagem, pois poderíamos começar exportando os átomos e moléculas.
Criação do componente de carrossel
A segunda seção da página possui um carrossel com os últimos leads convertidos da conta. Construir um carrossel não é nenhuma ciência de foguete, mas essa seção trouxe alguns desafios que exemplificam muito bem os benefícios da estrutura que definimos, então vou usá-la como exemplo.
Começamos então pelo mais simples, criando o átomo que representa cada item do carrossel, chamamos de ConversionCard. Para facilitar o desenvolvimento e fazer testes visuais do componente, instalamos e configuramos o Storybook.
Até aqui nenhuma novidade, o próximo passo seria construir o carrossel em si. Decidimos economizar tempo e usar o React Slick como motor do carrossel, então só teríamos que adequar o layout para o nosso Design System. O item já estava criado, falta customizar a paginação, então criamos o átomo CarouselPagination.
Os dois átomos poderiam ter sido construídos junto com o componente de carrossel, pois não tínhamos a intenção de reutilizá-los, mas o desenvolvimento isolado nos permitiu explorar suas diferentes aplicações e particularidades, tanto visualmente quanto nos testes de unidade.
Com as peças prontas, seria só montar tudo, certo? Só que não!
O carrossel só fica ativo se tiver mais de 6 itens, de 6 a 1 item será só uma lista horizontal simples, essa lista ainda irá preencher o espaço sem item com uma mensagem personalizada diferente para cada quantidade.
O primeiro pensamento a surgir é: “simples, é só personalizar o carrossel para tratar as diferentes quantidades”. Porém, não faz muito sentido um carrossel tratar um comportamento em que ele não existe, fora que podemos evitar o carregamento da biblioteca React Slick se não vamos usá-la.
Sendo assim, seguimos com a construção do carrossel partindo do princípio que ele só será usado sempre com mais de 6 itens. Como esse componente é uma junção de átomos, construímos como uma molécula chamada ConversionCarousel.
Ficou tão simples que precisou só de um exemplo para explorar toda sua funcionalidade. Foi só juntar os átomos com o React Slick, fazer sua configuração e pequenos ajustes de layout.
Para 6 itens ou menos tivemos que criar mais um átomo para exibir as mensagens dos itens restantes, demos o nome de ConversionEmptyCard.
Com isso criamos outro componente chamado ConversionGrid, que também foi classificado como molécula. Nele tratamos os casos de 1 a 6 itens, com suas respectivas mensagens.
Com as moléculas e átomos prontos, a construção do organismo LastConversions ficou mais simples, só tivemos que tomar a decisão de qual molécula carregar de acordo com o tamanho da lista retornada pelo back-end.
O código acima está simplificado, temos tratamento de erro, de carregamento dos dados (loading), um estado vazio para quando a lista tiver zero itens, etc. Nós também envolvemos os componentes com o React Suspense, para que somente o código utilizado fosse carregado.
Se olharmos para a quantidade de arquivos e componentes criados, dá a impressão de que fizemos trabalho extra, mais do que o necessário, mas nós isolamos a complexidade em componentes distintos, assim ficou bem mais simples de testar e manter cada caso de uso.
Considerações finais
O modelo mental do Atomic Design influenciou positivamente as decisões de arquitetura do projeto, conseguimos dividir a complexidade da tela em camadas, facilitando o desenvolvimento rápido, mas mantendo a qualidade.
Todas estas decisões apresentadas aqui foram tomadas no calor do dia a dia, com a pressão do prazo e com outras responsabilidades em paralelo, e conseguimos atingir o resultado esperado com muita qualidade devido a senioridade de todos os profissionais que trabalharam juntos, que são: João Balestrin (dev), Sergio Fiorotti (dev), Wesley Rocha (Designer/UX), Fábio Resner (Product Manager) e Leonardo Lazarini (Team Leader).
Caso tenha interesse em participar de desafios como este, com pessoas super talentosas e experientes, temos vagas!