Universo Styled Components — Parte 1/3
Faaala jovens gafanhotos, como comentei em outro artigo, hoje vou me aprofundar um pouco mais nessa maravilhosa lib que é o Styled Components. Vou dividir esta matéria em três artigos, sendo que neste abordarei um pouco sobre as features do styled, no segundo falarei sobre testes (não leve em conta esta ordem na hora de criar uma aplicação) e no último, explicarei sobre boas práticas de desenvolvimento (voltado pra style componentes, é claro).
Vamos para a primeira parte, Styled Components :)
Round 1 — Fight!
Instalação
npm install --save styled-components
Mais fácil que painel de Jeep.
Styled componentes cria marcadores literais para estilizar o seu componente, isto significa que estamos definindo nosso style e em consequência disso criando nosso componente React, isso é lindo :)
À grosso modo, é uma lib que utiliza o poder do CSS com JS para a criação de componentes primitivos em React!
Elementos primitivos:
</h1>, </span>, </form>, </input>
Exemplo de componente criado:
import styled from 'styled-components'
// Button Create
const Button = style.button`
font-size: 12px;
background: transparent;
border: 1px solid #CCC;
color: #ccc;
`
// Icon Create
const Icon = styled.i`
vertical-align: middle;
color: ${props => props.active ? '#5cb85c' : ''}
`
Depois é só fazer o import e utilizar o component
<Button />, <Icon />, <Modal opened size="500px" />
Simples, não!?
Props
Agora que a “magia” começa… É possível passar todas as props de componentes React para dentro do styled \o/. É JS, lembra!? ;)
Segue um exemplo:
import styled from 'styled-components'
export const StyledButton = styled.button`
height: ${props => props.size};
width: ${props => props.size};
background: ${
(props) =>
props.close ? '#9B9B9B' :
props.draft ? '#F0AD4E' :
props.theme.primary
};
white-space: nowrap;
&:focus {
background: ${props => props.theme.primary};
color: #FFF;
}
&:disabled {
color: #EFEFEF;
background: #CCC;
cursor: not-allowed;
}
`
Qual é a vantagem disso?
Você simplesmente tem todo o poder do JS nas suas mãos, podendo criar funções, condições, realizar merge de propriedades, utilizar defaultProps, propTypes e habilitar o lint do próprio styled :) .Tudo o que o JS oferece em seu CSS, unindo o poder de ambos.
Outra coisa muito boa é a diminuição de código, antes era necessário criar inúmeras classes mudando pouca coisa, isso acontecia muito com variações de cor, era terrível. Um exemplo bem simples é a criação de um botão com variações, se o time de desenvolvimento não estiver bem alinhado podemos ter situações bastante peculiares, como abaixo:
.big-button, .big-button:focus {
height: 259px;
font-size: 55px;
padding: 0 20px;
background: #00afe0;
border: none;
&:hover {
background-color: #00A8D5;
}
}
.button-secondary {
background: #efefef;
}
.button-danger {
background: #aacf3r;
}
.button-primary, .button-primary:focus {
background: #00afe0;
color: #FFF;
border: none;
&:hover {
color: #FFF;
background-color: #00A8D5;
}
}
Isso pode ser evitado, basta passar props, realizando todo o controle e criando as variações necessárias. Com isso temos um bundle menor e uma lógica clara do que o componente faz.
Imagine projetos de médio e grande porte, com equipes multidisciplinares, a criação e manutenção do CSS podem tornar-se bastante complexas.
Co-creator Max Stoiber says:
The basic idea of styled-components is to enforce best practices by removing the mapping between styles and components.**
Criando componentes
Como já citei acima, é possível criar componentes primitivos, informando todas as props do html, como onClick, id, name, etc…
Para criar um componente, basta importar o styled e informar o componente que será criado, exemplo:
-
input
import styled from 'styled-components'
export const Input = styled.input`
// code
` -
div
import styled from 'styled-components'
export const Wrapper = styled.div`
// code
``
Easy ;)
Tema
A criação de tema é uma das coisas que eu acho mais incrível, eu posso passar um tema e todos os elementos filhos vão receber esta propriedade. O styled componente possui full suporte de tema exportando oThemeProvider, permitindo multi levels de profundidade.
Segue abaixo um exemplo que eu tirei do próprio site do styled componente onde está sendo criado um botão com as props de tema vindo do ThemeProvider:
// Define our button, but with the use of props.theme this time
const Button = styled.button`
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
/* Color the border and text with theme.main */
color: ${props => props.theme.main};
border: 2px solid ${props => props.theme.main};
`;
// We're passing a default theme for Buttons that aren't wrapped in the ThemeProvider
Button.defaultProps = {
theme: {
main: 'palevioletred'
}
}
// Define what props.theme will look like
const theme = {
main: 'mediumseagreen'
};
render(
<div>
<Button>Normal</Button>
<ThemeProvider theme={theme}>
<Button>Themed</Button>
</ThemeProvider>
</div>
);
Também é possível passar as propriedades de forma contextual, como funções. Estas funções vão receber o tema pai, um outro ThemeProvider, que está acima no contexto da árvore.
O exemplo abaixo renderiza um botão estilizado e um segundo invertendo as cores. A função inverte o tema recebido, criando um novo botão, o exemplo também é do site oficial:
// Define our button, but with the use of props.theme this time
const Button = styled.button`
color: ${props => props.theme.fg};
border: 2px solid ${props => props.theme.fg};
background: ${props => props.theme.bg};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
`;
// Define our `fg` and `bg` on the theme
const theme = {
fg: 'palevioletred',
bg: 'white'
};
// This theme swaps `fg` and `bg`
const invertTheme = ({ fg, bg }) => ({
fg: bg,
bg: fg
});
render(
<ThemeProvider theme={theme}>
<div>
<Button>Default Theme</Button>
<ThemeProvider theme={invertTheme}>
<Button>Inverted Theme</Button>
</ThemeProvider>
</div>
</ThemeProvider>
);
Tema com HOC
Se necessário, também é possível utilizar o tema com HOC (higher order component), sem a necessidade do styled, exemplo retirado do site:
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
console.log('Current theme: ', this.props.theme);
// ...
}
}
export default withTheme(MyComponent)
Esse é melhor aproveitado em grandes componentes ;). Realmente repense a necessidade desta abordagem.
A props THEME
O tema também pode ser passado utilizando a prop theme
Isto pode ser feito nos casos em que não existir o ThemeProvider, conforme abaixo:
// Define our button
const Button = styled.button`
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
/* Color the border and text with theme.main */
color: ${props => props.theme.main};
border: 2px solid ${props => props.theme.main};
`;
// Define what main theme will look like
const theme = {
main: 'mediumseagreen'
};
render(
<div>
<Button theme={{ main: 'royalblue' }}>Ad hoc theme</Button>
<ThemeProvider theme={theme}>
<div>
<Button>Themed</Button>
<Button theme={{ main: 'darkorange' }}>Overidden</Button>
</div>
</ThemeProvider>
</div>
);
Helpers
Helpers, como o próprio nome diz, são ajudas para melhorar o desenvolvimento do seu CSS, alguns existentes no styled componente:
-
CSS
-
Keyframes
-
injectGlobal
-
witheme
Eles são muito importantes e bastante utilizados, como é o caso do css, onde é possível criar um template literal utilizando interpolação, exemplo:
import styled, { css } from 'styled-components';
const complexMixin = css`
color: ${props => props.whiteColor ? 'white': 'black'}
`;
const StyledComp = styled.div`
/* This is an example of a nested interpolation */
${props => props.complex ? complexMixin : 'color: blue;'}
`;
Para ver os demais, clique aqui ;)
Suporte a CSS
Bom, deixei o suporte para o final porque acredito que muitos que estão iniciando com styled component tem essa dúvida “e o suporte ao css”?
Caaalma jovens gafanhotos, o suporte continua o mesmo, é tudo CSS, bunitin!
Logo, todas as features que possuem no CSS também existem no styled componente, uma vez que é criado uma folha de estilo e não um css inline.
Segue nota da equipe de desenvolvimento quanto a esse assunto:
Within a styled component, we support all of CSS plus nesting. Since we generate an actual stylesheet and not inline styles, whatever works in CSS works in styled-components!
Bom, falei mais um pouco a respeito desta poderosa ferramenta que é o Styled Component, abordando algumas de suas features e criação de componentes, bem como seu comportamento.
Agora, como havia prometido, no próximo artigo da trilha de Styled Component eu irei falar sobre testes!
Ah… Antes de terminar esta parte, eu só quero deixar uma *dica, *é possível criar e utilizar os mesmos componentes no REACT NATIVE! Mas esse é assunto para outro artigo…
Fontes: