Styled-system juntamente com styled-components ou emotion nos permite criar componentes completos e configuráveis.
Neste post vou mostrar como criar um componente usando variants do styled-system. Esse recurso nos permite criar componentes para um design system por exemplo, onde os devs apenas informam para o componente o seu tamanho e variante, evitando assim configurações extras que acabariam quebrando o DS ou não mantendo no padrão.
Aqui temos um exemplo de arquivo de tema de um botão, nele temos as variantes e os tamanhos. Obviamente no mundo real os valores estariam vindo de outros arquivos como por exemplo fonts, sizes, colors e etc contendo todos os tokens de um design system.
const variants = {defaultButton: {border: "solid 1px #023e8a",backgroundColor: "#0096c7",borderRadius: "4px",width: "100%",},ghost: {border: "solid 1px #023e8a",backgroundColor: "transparent",borderRadius: "4px",width: "100%","&:hover": {backgroundColor: "#4361ee",},},};
const sizes = {xxx: {height: "60px",},xx: {height: "50px",},medium: {height: "35px",},small: {height: "25px",},};
Agora vamos ver como implementar essas configurações de tema no componente. O código a baixo mostra como fazer.
import styled from "@emotion/styled";import { css } from "@emotion/react";import { variant } from "styled-system";import { theme } from "../theme";export const Button = styled.button`${css({ ...theme.button.variants.defaultButton })}${variant({variants: {...theme.button.variants,},})}${variant({prop: "size",variants: {...theme.button.sizes,},})}`;
No começo do componente informamos as configurações default, que também é uma variante.
Logo a baixo temos então o uso do recurso do styled-system, o variant, passamos na propriedade variants todas as nossas variantes do tema. Quando usarmos o componente, passaremos então a seguinte prop para o botão 'variant="ghost"' por exemplo.
Depois de passar as variantes configuramos então os tamanhos, usando novamente o recurso variant porem com uma configuração a mais, informamos para ele que a prop variant do componente vai se chamar size, ficando assim 'size="xxx"'.
Aqui estão alguns exemplos de uso e o link para a aplicação funcionando.
<Button>ok</Button><Button variant="ghost">ghost</Button><Button size="xxx">xxx</Button><Button size="xx">xx</Button><Button size="medium">medium</Button><Button size="small">small</Button>