Tudo que sei sobre Style Guides, Design Systems, e Biblioteca de Componentes
Published: 2023-07-27 18:46:08

Esse artigo é uma tradução do artigo original [Everything I Know About Style Guides, Design Systems, and Component Libraries](https://leerob.io/blog/style-guides-component-libraries-design-systems#what-is-a-style-guide) criado por [Lee Robinson](https://leerob.io/).

Durante a maior parte do ano passado, investi arduamente em desenvolvimento front-end e design. Quando iniciei minha nova função, identifiquei a necessidade de uma biblioteca de componentes e a criei. Desde então, aprendi muito sobre style guides, design systems, biblioteca de componentes(component libraries) e suas melhores práticas. Este post será um mergulho profundo em tudo o que aprendi no ano passado.

# Por que você deveria se importar?

Todo site começa simples. Talvez exista uma página com algumas coisas diferentes, mas ele começará de forma humilde.

![Site Mockup](https://miro.medium.com/v2/resize:fit:720/format:webp/0*dBT4SaUssQT_7Irc.png)

Então, aos poucos, ele começa a crescer.

Nova páginas são adicionadas e novas funcionalidades são implementadas. Talvez existam vários times focados em partes específicas do site. Você também por estar focado em mobile.

Você começa a notar que os botões em uma parte do site são um pouco diferentes dos outros. Uma equipe decide construir uma funcionalidade que outra equipe já fez (sem saber). Falhas de comunicação acontecem. A consistência é perdida.

Este problema poderia ter sido evitado? Com certeza. No entanto, por que isso sempre acontece? **A menos que você pense em seu processo de design e desenvolvimento de forma atencipada, você terá problemas mais tarde à medida que o projeto aumenta.**

Para evitar que esse problema aconteça ou corrigir a falta de consistência existente em seus produtos, você precisa de três coisas:

- **Style Guide**
- **Biblioteca de componentes**
- **Design System**

Fique tranquilo se você ainda não tem ideia do que estou falando. No final deste artigo você terá consumido quase um ano de tentativa e erro, pesquisa e desenvolvimento.

# O que é Style Guide?

![Style Guide](https://miro.medium.com/v2/resize:fit:720/format:webp/0*TivIo7iCTXDkVV3s.png)

Um **style guide** é um conjunto de regras sobre como sua marca deve ser exibida. Isso é tanto visual (design e imagens) quanto conteúdo escrito (voz e tom).

O objetivo de um style guide é **permitir que vários colaboradores criem conteúdo de forma clara que represente a marca de forma coesa**. Quase todas as grandes marcas têm um style guide, embora nem todas sejam públicas.

# O que é uma biblioteca de componentes?

![Componentes](https://miro.medium.com/v2/resize:fit:720/format:webp/0*YvJm1ngOg1MIH1-U.png)

Uma **biblioteca de componentes** é uma implementação viva do seu  style guide. É um conjunto compartilhado de componentes que os desenvolvedores podem consumir para criar aplicações que reflitam sua marca. Alguns benefícios notáveis:

- Ter uma biblioteca de componentes significa que quem for utilizar acabará codando menos.

- Como há uma centralização, você pode garantir que todos os componentes atendam aos requisitos de acessibilidade.

- Os componentes se tornam mais robustos com vários contribuidores enviando correções de bugs e melhorias em um único local.

- Menos duplicação de código permitirá que você lance novos produtos e reescreva código legado de forma mais rápida.

# O que é Design System?

Um **design system** é um conjunto de padrões, documentação e princípios, juntamente com os componentes para atingir esses padrões. É a **junção de seu style guide e a biblioteca de componentes**. Um dos design systems mais populares é do Google, [Material Design](https://material.io/design/).

![Design System](https://miro.medium.com/v2/resize:fit:720/format:webp/0*ghOv9iNjSOcMGdyA.png)

Um design system deve conter:

- **Conteúdo**: A linguagem para projetar uma experiência de produto mais ponderada.

- **Design**: Os elementos visuais do design system.

- **Componentes**: Os blocos de construção para o desenvolvimento de novos produtos e funcionalidades.

- **Padrões**: As pequenas partes para criar experiências de produto significativas.

# Por onde você deve começar?

Dependendo do estado da sua empresa/produto, você pode ter um ponto de partida diferente. Este é o esboço antes de entrarmos em detalhes:

- Crie um inventário de padrões de design existentes.
- Estabeleça princípios de design e comece um style guide.
- Defina seus design tokens.
- Crie ou identifique um conjunto de ícones.
- Escolha linguagens/frameworks para dar suporte.
- Avalie entre monorepo ou um único pacote.
- Avalie entre CSS/Sass e CSS-in-JS.
- Crie uma biblioteca de componentes.
- Escolha uma plataforma de documentação.
- Escreva uma documentação do design system.

# Construindo um Design System

## Crie um inventário de padrões de design existentes

A não ser que você esteja começando do zero, você precisará identificar todos os padrões de design em uso na sua interface e documentar toda inconsistência. O objetivo deve ser permanecer com a mesma experiência do usuário, independentemente da parte do produto em que o usuário está.

Comece a documentar e revisar com sua equipe, e identifique os padrões que mais lhe agradam. Isso fará com que vocês tenham uma ideia do que seu style guide precisará.

## Estabeleça princípios de design e comece um style guide

Chegou a hora de traduzir essas descobertas para um style guide. Você pode usar ferramentas como:

- [Figma](https://www.figma.com/)
- [Sketch](https://www.sketch.com/)
- [Framer](https://www.framer.com/)
- [Abobe XD](https://www.adobe.com/products/xd.html)

Minha recomendação seria o Figma, mas em última análise, depende de sua equipe e empresa. Aqui estão alguns tutoriais úteis do [Figma para iniciantes](https://www.youtube.com/playlist?list=PLXDU_eVOJTx7QHLShNqIXL1Cgbxj7HlN4).

### Defina seus design tokens

![Design Tokens](https://miro.medium.com/v2/resize:fit:720/format:webp/0*R-mdfooYKUj9PEap.png)

> Os design tokens são os átomos do design system - especificamente, são entidades nomeadas que armazenam atributos de design. Nós os usamos nos lugares de valores hard-codados(como valores hexadecimais para cor ou valores de pixel para espaçamento) para manter um sistema visual escalável e consistente para o desenvolvimento da interface.

Isso inclui coisas como:

- [Cores](https://colors.eva.design/)
- [Fontes](https://fonts.google.com/)
- [Tamanhos tipográficos](https://spencermortensen.com/articles/typographic-scale/)
- [Espaçamentos](https://tanzu.vmware.com/content/built-to-adapt/intro-to-the-8-point-grid-system-2)
- [Sombras](https://material.io/design/environment/light-shadows.html)

Por exemplo, vamos dar uma olhada no [Design System da Vercel](https://vercel.com/design):

```css
--geist-foreground: #000;
--geist-background: #fff;
--accents-1: #fafafa;
--accents-2: #eaeaea;
--accents-3: #999999;
--accents-4: #888888;
--accents-5: #666666;
--accents-6: #444444;
--accents-7: #333333;
--accents-8: #111111;
--geist-success: #0070f3;
--geist-error: #ee0000;
--geist-warning: #f5a623;
--dropdown-box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.02);
--dropdown-triangle-stroke: #fff;
--scroller-start: var(--geist-background);
--scroller-end: rgba(255, 255, 255, 0);
--shadow-small: 0 5px 10px rgba(0, 0, 0, 0.12);
--shadow-medium: 0 8px 30px rgba(0, 0, 0, 0.12);
--shadow-large: 0 30px 60px rgba(0, 0, 0, 0.12);
--portal-opacity: 0.25;
```

Agora existe uma linguagem comum entre designers e desenvolvedores.

## Crie ou identifique um conjunto de ícones

![Ícones](https://miro.medium.com/v2/resize:fit:720/format:webp/0*meuL8RurmvyNbfGR.png)

Se você já tem ícones, precisará escolher quais você não jogará fora. Talvez não faça sentido você criar seus próprio ícones dependendo do tamanho da sua empresa. Talvez seja melhor utilizar uma biblioteca de ícones open-source. Alguns exemplos:

- [Font Awesome](https://fontawesome.com/)
- [Icons8](https://icons8.com/)
- [Material UI Icons](https://mui.com/components/icons/)
- [Eva Icons](https://akveo.github.io/eva-icons/#/)
- [Feather Icons](https://feathericons.com/)
- [Styled Icons](https://styled-icons.js.org/)
- [Ikonate](https://ikonate.com/)

Mesmo que você construa o seu próprio pacote ou use uma opção open-source, você deve padornizar e identificar padrões de uso. Também vale a pena considerar quem são os usuários finais do seu conjunto de ícones - designers, desenvolvedores e marketing?

Usando SVGs, você pode tornar a biblioteca de ícones sua única fonte de verdade. Seu processo pode ficar assim:

1. Os designers criam/fornecem SVGs puros.
1. Otimize e comprima os SVGs usando [SVGO](https://github.com/svg/svgo/).
1. Crie automaticamente componentes React automaticamente usando [SVGR](https://github.com/gregberge/svgr) pros desenvolvedores.
1. Gere PNGs e JPEGs em diferentes resoluções para marketing.
1. Gere SVGs em um [bundled de fontes](https://www.npmjs.com/package/icon-font-generator) para ser usada em aplicativos mobile.

## Escolha linguagens/frameworks para dar suporte

Quais linguagens ou frameworks você está mantendo atualmente? Qual deve ser o suporte da biblioteca de componentes? É importante pensar nisso com antecedência para que você possa arquitetar adequadamente sua biblioteca.

Se você tiver uma aplicação que usa script tags em vez de ES Modules, então precisará configurar sua biblioteca de componentes para fazer o bundle em um único arquivo. Por exemplo, uma aplicação com JavaScript puro precisaria de algo assim em um arquivo HTML.

```html
<script src="/js/component-library.min.js"></script>
```

Para fazer isso, você pode usar [Webpack](https://webpack.js.org/) ou [Rollup](https://rollupjs.org/). Eu recomendaria o Webpack, pois é o padrão de mercado. Eu também recomendo o [TSDX](https://github.com/jaredpalmer/tsdx) se você quiser usar o TypeScript.

## Avalie entre monorepo ou um único pacote

Um [monorepo](https://leerob.io/blog/monorepo-lerna-yarn-workspaces) permite que você crie e publique várias bibliotecas de um único repositório. Embora resolva alguns problemas muito reais, também cria outros. É importante entender os prós e os contras.

![Monorepo](https://miro.medium.com/v2/resize:fit:720/format:webp/0*Mq2Fux4t-BUdUWZZ.png)

O monorepo pode ser uma boa pois…

- Pacotes pequenos através da diminuição do escopo dos componentes incluídos em um pacote.
- Processo compartilhado de build, lint, teste e release para vários pacotes versus repositórios separados com código duplicado.
- Controle mais granular do semver(versionamento semântico) pacote por pacote.

O monorepo pode não ser uma boa pois…

- Ferramental e infraestrutura adicionais necessárias.
- Quem estiver desenvolvendo será obrigado a importar uma variedade de pacotes em vez de uma única biblioteca de componentes.
- Está no hype, tecnologia de ponta. O mercado está adotando, mas você pode se deparar com problemas que poucos experimentaram sem um caminho claro para uma solução.

Algumas perguntas que o ajudarão a identificar qual solução é a melhor para sua empresa:

- Você tem múltiplos repositórios sendo publicados via NPM?
- Seu processo de build, test, lint e infraestrutura complexos? Esse processo está duplicado em vários lugares?
- Quantos repositórios você tem (ou planeja ter no próximo ano?)?
- Quão grande é seu time? Quantos farão uso da biblioteca de componentes?
- Será open-source? Você pode aprender com outras pessoas do mercado para ajudar a resolver problemas?
- Você a vê a necessidade de múltiplos pacotes no futuro? (e.g. icons, [codemods](https://github.com/facebook/jscodeshift), etc).

Para empresas bem pequenas, eu diria que monorepos são desnecessários. Implementá-lo tem seu momento e lugar. [Eu já usei]((https://leerob.io/blog/monorepo-lerna-yarn-workspaces)) em um lugar com 150 desenvolvedores para distribuir 10 pacotes diferentes de uma vez, abrangendo aplicativos internos e externos.

## Avalie entre CSS/Sass e CSS-in-JS

CSS-in-JS é forma mais fácil para construir estilos e distribuir através do NPM. Para um bom desempenho, considere usar uma solução de tempo de execução quase zero, como [Stitches](https://stitches.dev/).

Se a sua biblioteca de componentes precisar gerar HTML/CSS puros, eu recomendo ficar com o Sass. Um ótimo exemplo disso é o design system [Carbon da IBM](https://www.carbondesignsystem.com/components/button/code/). Você pode usar [variáveis ​​CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) para conter seus [design tokens](https://www.lightningdesignsystem.com/design-tokens/).

![Botão](https://miro.medium.com/v2/resize:fit:720/format:webp/0*417-DDzFMcuejSol.png)

```html
<button class="bx--btn bx--btn--primary" type="button">Button</button>
```

Se você usa React, confira meu post [Como eu deveria estilizar minha aplicação React?](https://leerob.io/blog/css-with-react)

## Crie uma biblioteca de componentes

Com seus requisitos técnicos definidos e seu style guide iniciado, agora você poderá começar a construir uma biblioteca de componentes. Minha recomendação seria usar o **React juntamente ** do [Storybook](https://storybook.js.org/).

![Component Driven Development](https://miro.medium.com/v2/resize:fit:720/format:webp/0*tCTqFaCjz6vRt06V.jpeg)

Criar uma biblioteca de componentes é muito mais do que apenas traduzir o style guide em código.

Você precisa pensar em como quem utilizará seus componentes irão interagir com eles. Que tipo de API eles esperariam? O que fornece mais clareza e é autodocumentado? Por exemplo, considere botões. Você tem diferentes variações de botões - primário, secundário, etc.

![Botões](https://miro.medium.com/v2/resize:fit:720/format:webp/0*5bKLrRuD-ujw3hCm.png)

Você deve ter um componente separado para cada tipo?

```javascript
<PrimaryButton>Hello World!</PrimaryButton>
<SecondaryButton>Hello World!</SecondaryButton>
```

ou usar uma prop?

```javascript
<Button>Hello World!</Button>
<Button variant="secondary">Hello World!</Button>
```

Continuando, como você deveria chamar essa prop? variant? type? Você chegou a considerar que `type` é uma atributo reservado do elemento HTML `<button>`? Esse é o tipo de decisão que você precisará fazer aos construir sua biblioteca de componentes.

Algumas outras coisas pra você considerar:

- Você deveria permitir a quem usar sua biblioteca de [passar propriedades CSS](https://evergreen.segment.com/components/layout-primitives) pro component React, ou eles deveriam ter que estender/wrappar componentes para alcançar o estilo desejado? Se você escolher o primeiro, considere [styled-system](https://github.com/styled-system/styled-system).

- Você deve construir um comportamento de loading [direto no componente](https://react.carbondesignsystem.com/?path=/story/accordion--skeleton), ou deveria existir um [componente genérico](https://www.npmjs.com/package/react-loading-skeleton) para isso (spinner, skeleton)?

- Como vocoê deve testar de forma pura o visual de componentes? [Teste de Snapshot](https://jestjs.io/docs/snapshot-testing)? [Visual diff testing](https://www.chromatic.com/)?

- Como os desenvolvedores precisarão fazer para integrar sua biblioteca de componentes? Deve haver uma [redefinição de estilo global](https://cssdeck.com/blog/what-is-a-css-reset/)? Eles devem adicionar algum [plugin do Babel](https://github.com/umijs/babel-plugin-import)?

- Você deveria utilizar [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/) para gerar automaticamente um changelog?

- Seus componentes precisarão estar presentes no ambiente web e mobile? Considere usar o [React Native Web](https://github.com/necolas/react-native-web) para compartilhar seus componentes entre as plataformas.

## Escolha uma plataforma de documentação

Você precisa de uma plataforma para exibir seu desygn sistem. Se você está apenas começando, eu recomendaria usar o [Storybook Docs](https://medium.com/storybookjs/storybook-docs-sneak-peak-5be78445094a).

![Storybook Docs](https://miro.medium.com/v2/resize:fit:720/format:webp/0*lHyJCKJ8vsW7r-xP.png)

Essa combinação alcançará o resultado de outras plataformas semelhantes, como [Docz](https://github.com/doczjs/docz), [Styleguidist](https://react-styleguidist.js.org/) e [Docusaurus](https://docusaurus.io/).

- Copie facilmente trechos de código de exemplos de componentes
- Gere automaticamente uma tabela de props com base em prop-types e defaultProps
- Facilmente veja as variações de um componente
- Escreva documentação utilizando MDX

![Storybook Flow](https://miro.medium.com/v2/resize:fit:720/format:webp/0*qJ8P3b8FdiwBhXv_.png)

Se você é inflexível em seu design system refletindo sua marca e sua biblioteca de componentes, eu recomendaria uma solução personalizada usando [MDX](https://mdxjs.com/). Isso permitirá que você insira componentes React dentro de arquivos Markdown. [O blog que você está lendo agora usa isso](https://github.com/leerob/leerob.io).

Ter uma solução verdadeiramente personalizada permite controle total sobre sua documentação. Um exemplo pelo qual estou extremamente impressionado é o [Atomize React](https://atomizecode.com/docs/react/atoms/).

![Atomize React](https://miro.medium.com/v2/resize:fit:720/format:webp/0*FSKvnb06vafZues_.png)

## Escreva uma documentação do design system

Agora que você escolheu uma plataforma para documentar, é a hora de escrever. Você deve incluir:

- Processo de instalação e configuração da biblioteca de componentes
- Definições de props e types para cada componente
- Exemplos de componentes junto com trechos de código copiáveis
- Escolhas de tecnologia e racional das escolhas

Também considere colocar:

- Uma sessão de "Começando" com um tutorial
- Informações sobre como trabalhar com temas
- Um code playground para interagir com os componentes
- Modelos prontos de UI para escolher

# Conclusão

Passei muito tempo no ano passado pensando em design systems. Construir uma biblioteca de componentes do zero me deu uma nova apreciação pela quantidade de trabalho que envolve o desenvolvimento front-end e o design. Abaixo, você encontrará uma lista de design systems que me inspiraram e servem como ótimas referências.

Sinta-se à vontade para [entrar em contato](mailto:me@leerob.io) se quiser conversar sobre a construção de design systems.

# Referências

## Design Systems

- [Shopify's Polaris](https://polaris.shopify.com/)
- [Segment's Evergreen](https://evergreen.segment.com)
- [Eva Design](https://eva.design)
- [Vercel's Design System](https://vercel.com/design)
- [Ant Design](https://ant.design)
- [IBM's Carbon](https://www.carbondesignsystem.com)
- [Storybook's Design System](https://github.com/storybookjs/design-system)
- [Modulz's Radix](https://www.radix-ui.com)
- [GitHub's Primer  ](https://primer.style)
- [Palantir's Blueprint](https://blueprintjs.com)
- [Atlassian's Design System](https://atlassian.design)
- [Chakra UI](https://chakra-ui.com)