Styled Components - 7 truques para trabalhar com eles
Tags: javascript, tips, styledcomponents, webdev
Published: 2021-11-09 01:53:19

![Logo do Styled Components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/08pqtlocgmv1e5375oit.png)
 
Para aqueles que não conhecem o Styled Components, ao utiliza-lo criando componentes estilizados, faz com que permita traduzir a definição dos estilos de nosso aplicativo para componentes em vez de trabalhar em folhas de estilo CSS. Portanto, eles fornecem uma nova maneira de abordar a arquitetura de nosso aplicativo, com a qual me sinto muito confortável em trabalhar, então encorajo a todos experimentar, se ainda não utilizou. No final deste artigo, deixarei uma lista de links que você pode acessar se quiser se aprofundar nesta library incrível 

###Então sem distrações, vamos ver esses truques!

**1º) Uso da Context API** - Uma das vantagens dos componentes estilizados é a possibilidade de definir um tema para nossa aplicação, de forma que, utilizando a [React Context API](https://pt-br.reactjs.org/docs/context.html), todos os componentes que definimos possam acessar as variáveis que definimos.

Para fazer isso, devemos agrupar com o rótulo `ThemeProvider` todos aqueles componentes que desejamos receber as variáveis de nosso tema da mesma forma que faríamos com os outros contextos que definimos para nossa aplicação.

Por exemplo, se nosso tema consiste nas seguintes variáveis definidas no arquivo `theme.js`

````javascript
const theme = {
  color: {
    gray: {
      100: '#f6f9fc',
      200: '#e9ecef',
      300: '#dee2e6',
      400: '#ced4da',
      500: '#adb5bd',
      600: '#8898aa',
      700: '#525f7f',
      800: '#32325d',
      900: '#212529',
    },
  },
  font: {
    body: 'Open Sans, sans-serif',
  },
  fontSize: {
    h3: {
      fontSize: '2.25rem',
      lineHeight: '2.25rem',
    }
    },
    dimension: {
      maxWidth: '1200px',
    },
    zIndex: {
      stepProgress: '100',
      bottomBar: '550',
      backdrop: '990',
      modal: '1000'
    }
  },

  export default theme;

```
Podemos escrever o seguinte:

````javascript
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import theme from "config/theme";
import { ThemeProvider } from "styled-components";

ReactDOM.render(
  <ThemeProvider theme={theme}>
    <App />
  </ThemeProvider>,
  document.getElementById("root")
);

```

Para que qualquer componente estilizado que usarmos no componente `App` possa acessar as variáveis definidas no `theme.js` acessando a propriedade `theme` da variável `props`:

````javascript
import styled from 'styled-components';

export default styled.div`
  font-family: ${props => props.theme.font.body};
  color: ${props => props.color || props.theme.body}
`;

```

**2º) Alterar um tipo de componente estilizado** - 

Esse é o truque típico que parece bobo até um dia por algum motivo que você precise. Basicamente, o que ele nos permite é modificar o rótulo que renderizará um componente estilizado sem adicionar código extra ao nosso aplicativo.
Suponha que temos o seguinte componente estilizado definido:

````javascript
import styled from "styled-components";

export default styled.div`
  font-family: ${(props) => props.theme.font.body};
  font-size: ${(props) => (props.large ? "1.5rem" : "1rem")};
  line-height: ${(props) => (props.large ? "145%" : "110%")};
  color: ${(props) => props.color || props.theme.body};
  margin-bottom: ${(props) => props.marginBottom || "0"};
`;

```

Quando o usarmos em nosso aplicativo, o que veremos na DOM será uma tag `div`, pois a estamos definindo como `styled.div`. No entanto, é possível modificar esse rótulo usando o atributo `as` em nosso componente estilizado, por exemplo:

````javascript
import 'TextWrapper' from 'styled/TextWrapper';

export default ({text}) => (
  <TextWrapper as="p">
    {text}
  </TextWrapper>
);

```

Nesse caso, o que obteríamos na DOM seria o texto contido dentro de uma tag `<p>`.

**3º) Elementos de referência dentro do componente estilizado** - 

Claro, com os componentes estilizados podemos fazer referência a outros elementos da DOM usando uma sintaxe semelhante à que estamos acostumados em CSS ou Sass. Por exemplo, se quisermos definir um `div` cujos filhos tenham 50% de largura, podemos escrever o seguinte:

````javascript
import styled from 'styled-components';

export default styled.div`
  display: flex;
  
  & > div {
    flex-grow: 0 0 50%;
    max-width: 50%;
  }

  `;
```

Isso também nos ajuda a usar os pseudo seletores `::before` e `::after` :

````javascript
import styled from 'styled-components';

export default styled.div`
  display: flex;
  position: relative;

  & > div {
    flex-grow: 0 0 50%;
    max-width: 50%;
  }

  &:before {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    content: '';
    background: rgba(0, 0, 0, 0.5);
  }
`;
```

Portanto, além do fato de que os Styled Components suponham uma nova forma de pensar a respeito da organização de nossa aplicação, não será necessário que aprendamos uma sintaxe especial para trabalhar com eles, pois nosso conhecimento de CSS nos ajudará.

**4º) Referencie outros componentes estilizados**

Outro truque muito útil ao qual podemos recorrer quando precisamos, é aquele que nos permite fazer referência a um componente estilizado dentro de outro. Por exemplo, um caso de uso típico para esse truque é ter um botão composto de texto e ícone que deve mudar durante um foco. Podemos conseguir isso da seguinte maneira:

````javascript
import styled from "styled-components";

const Button = styled.button`
  background: blue;
  color: white;

  &:hover {
    background: gray;
    color: black;
  }
`;

const Icon = styled.i`
  color: white;
  font-size: 1.5em;

  ${Button}:hover & {
    color: black;
  }
`;

```

Como você pode ver, dentro do ícone do componente estilizado, estamos nos referindo ao componente Botão usando a sintaxe `$ {Botão}`. Isso é possível porque os Styled Components atribuem classes específicas a cada componente criado por meio da expressão estilizada. então, mais tarde, podemos usá-los para referenciá-los. Claro, isso só funcionará se fizermos referência a um componente estilizado, não se o usarmos para fazer referência a qualquer outro tipo de componente. 

**5º) Estenda componentes estilizados** - Outro truque muito útil para não sobrecarregar excessivamente seus componentes estilizados é poder estender os componentes estilizados que definimos, para que, por exemplo, definamos o seguinte:

````javascript
import styled from "styled-components";

const DefaultA = styled.button`
  color: ${(props) => props.theme.colors.primary};
`;
```

Posteriormente, podemos fazer o seguinte:

````javascript
import styled from "styled-components";
import DefaultA from "styled/DefaultA";

const CustomA = styled(DefaultA)`
  font-size: 1.5rem;
`;
```

Portanto, o que obteremos quando usarmos `<CustomA>` será um componente com a `color` de estilos (vindo do componente `DefaultA`) e o `font-size` (vindo do próprio `<CustomA>`).

Claro, também podemos substituir estilos:

````javascript
import styled from "styled-components";
import DefaultA from "styled/DefaultA";

const RedA = styled(DefaultA)`
  font-size: 2rem;
  color: red;
`;
```

**6º) Definir propriedades dinâmicas** 
Outra coisa que nos permite fazer componentes estilizados é tirar proveito do poder dos `tagged templates` para definir propriedades CSS dinamicamente. Por exemplo, podemos definir um botão que é pintado de forma diferente dependendo do valor da propriedade `type` que ele recebe:

````javascript
import styled from "styled-components";

export default styled.button`
  background: ${(props) => {
    switch (props.type) {
      case "blue":
        return props.theme.color.blue;
      case "lightGray":
        return props.theme.color.gray200;
      default:
        return props.theme.color.primary;
    }
  }};
  width: ${(props) => props.width || "auto"};
  height: ${(props) => props.height || "auto"};
  border: none;
  -webkit-appearance: none;
  padding: ${(props) =>
    props.width && props.height ? "25%" : "1rem 1.375rem"};
  border-radius: 0.5rem;
  text-align: ${(props) => props.align || "left"};
  outline: 0;
  color: ${props => {
    switch (props.type) {
      case 'blue':
        return 'white';
      case 'lightGray':
        return props.theme.color.body;
      default:
        return 'white';
    }
  }};
  font-family: ${props => props.theme.font.title};
  font-size: ${props => props.fontSize || '1.375rem'};
`;
```
O que é muito útil para encapsular os elementos de nossa IU modificando apenas alguns aspectos deles.

**7º) Atributos de passagem** 

Finalmente, é importante lembrar que também é possível passar atributos para nossos componentes estilizados usando `attrs` ao defini-los. Por exemplo, se tivermos integrado o Bootstrap em nosso aplicativo, podemos definir um botão com a propriedade `type` (como fizemos no exemplo anterior), mas desta vez pintar a classe apropriada com base no valor dessa propriedade:

````javascript
const Button = styled.button.attrs({
  className: `btn btn-${(props) => props.type || "primary"}`,
})``;

<Button type="primary" />;
```

Como você pode ver, os componentes estilizados nos fornecem uma forma diferente de trabalhar com os estilos de nossa aplicação, favorecendo tanto sua “componentização” quanto seu reaproveitamento. Para aprofundá-los, recomendo dois artigos bastante interessantes onde são expostas algumas maneiras recomendadas de integrá-los em nossa aplicação que foi também onde utilizei como fonte de pesquisa:

- https://www.elpassion.com/blog/styled-components-nitty-gritty-2d74b8690ef8
- https://itnext.io/thinking-in-styled-components-e230ea37c52c
- https://styled-components.com/docs