Rafael Campos de Bastiani

Componentes com variantes usando styled-system

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>

Exemplo no codesandbox

styled-system