Styled Components

npm i styled-components

Usaremos el siguiente plugin de visual studio code: vscode-styled-components from Julien Poissonnier

Cuando usamos JSX sin styled-components, los atributos son pasados al DOM obligatoriamente como texto.

Como estructurar un componente que utiliza styled-components

Styled Components 1
./src/App.js
import Box from './components/box';
export default () => <Box/>;
./src/components/Box/index.js
import Box from './Box';
export default Box;
./src/components/Box/Box.js
import { Btn } from './Box.styled';
export default () => <Btn onClick="alert('hola)">hola</Btn>;
./src/components/Box/Box.styles.js
import styled from 'styled-components';

export const Btn = styled.button`
    width: 70px;
    height: 70px;
    background-color: pink;
    color: pink;
`;

Etiquetas anidadas

import { Box } from './styled';
export default () => <Box><div></div></Box>;
import styled from 'styled-components';

export const Box = styled.div`
    background-color: salmon;
    padding: 30px;

    div{
        background-color: palegreen;
        width: 100px;
        height: 100px;
    }
`;

Usando props

Para personalizar el comportamiento de los styled componentes, usaremos siempre props con valores booleanos, con el propósito de no complicar la lógica que va dentro de la definición del styled component.

Estilos en función de props

export const Component = styled.div`
  background-color: ${({ isRight}) => isRight ? 'green' : 'red'};
`;

Atributos en función de props

<Input myMaxLength={2}/>
export const Box = styled.div.attrs({ className: 'pt-3' })``;
export const Input = styled.input.attrs(props => ({
    type: "password",
    maxLength: props.myMaxLength || 5,
    }))`
  color: blue;
`;

Ejercicio

1. Crear un styled-component (no un componente funcional de React, bastará con un styled-component )y cuando pulsemos sobre un botón, que cambie de color. Para ello, usaremos un código similar a este:

App.js

<button onClick={ () => setColor('red')}>Cambiar color</button>
<MiStyledComponent color={color}/>

Por tanto, tendremos que modificar el código de dos ficheros: App.js y styles.js (que contendrá el styled-component).

2. Crear un componente que usará styled-components y que mostrará un popup cuando reciba una prop isVisible con el valor true.

Crearemos un componente llamado Popup que recibirá como props isVisible y setVisible.

export default ({setVisible, isVisible}) => <Back isVisible={isVisible}><div></Back>;

En dicho componente, utilizaremos styled componentes para que el componente Back sea visible en función de si su propiedad isVisible es true o false.

Llamando al método setVisible dentro del componente PopUp, nos comunicaremos con el componente App para ocultar el componente.

<button onClick={ () => setVisible(true)}>Mostrar popup</button>
<Popup visible={visible}/>

Hacer hover

export const Panel = styled.div`
  background-color: salmon;
  &:hover {
	  background-color: paleGreen
  }
`;

Heredar de otro componente

export const Rectangulo = styled(Cuadrado)`
  width: 200px;
`;

Incrustar código

// El código de BigText debe estar definido antes de ser usado

import styled, { css } from 'styled-components';

const BigText = css`
	font-size: 3rem;
`;

export const RedText = styled.p`
	background: red;
	${BigText};
`;

export const BlueText = styled.p`
	background: blue;
	${BigText}
`;

Añadir animaciones

import styled, { keyframes } from 'styled-components';

const showIt = keyframes`
    to{ opacity: 1}
`;

export const TextPanel = styled.div`
    animation: 5s ${showIt} forwards;
`;

Animaciones con parámetro

En este caso, trataremos la animación como una función:

const statusBarAnimation = (level) => keyframes`
    to{   width: ${level+ '%'}; }
`;

export const StatusBarContainer = styled.div`
        width:0;
        animation: ${({ level }) => statusBarAnimation(level)} 1s forwards;
`;

Para hacer media queries

const desktopStartWidth = 996;

const desktop = `@media (min-width: ${desktopStartWidth}px)`;
const mobile = `@media (max-width: ${desktopStartWidth}px)`;

const Cuadrado = styled.div`
	...
	${mobile} {
		width:100%;
	}
`;

Para maquetar el body

import styled, { createGlobalStyle } from 'styled-components';

export const GlobalStyle = createGlobalStyle`
	body {
		background-color: salmon;
	}
`;
./src/App.js
import { GlobalStyle } from './styles';

export default () => (
    <div>
      <GlobalStyle />
      <App/> 
    </div>
);

Cargar una tipografía:

Lo haremos usando GlobalStyle:

export const GlobalStyle = createGlobalStyle`
	@font-face {
        font-family: myFont;
        src: url(${font});
    }
`;
← Estilos en React
Valores por defecto →