Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.
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.
En el Visual Studio Code, utilizaría la siguiente extensión para tener autocompletado y coloreado de sintaxis:
Etiquetas anidadas
import { Box } from './styled';
const App = () => <Box><div></div></Box>;
export default App;
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
<Component isRight={true}/>
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;
`;
Error al usar props
Usando camelCase
Al usar props que utilicen camelCase obtendremos un mensaje de error similar a este:
React does not recognize the `isVisible` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `isvisible` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
Usando booleanos en lugar de textos
El siguiente error da cuando renderizado final llega un booleano en lugar de una cadena de texto.
Received `false` for a non-boolean attribute `editmode`.
Ambos errores se evitan poniendo el símbolo de dolar antes del nombre de la prop. De esta forma, evitamos que la prop se propague al DOM. No te olvides de usar la prop con el símbolo de dolar dentro del styled component.
<MyStyledComponent $isVisible={true} />
Ejercicios styled components
Ejercicio 1.
Crear un styled-component (no un componente funcional de React). Cuando pulsemos sobre un botón, haremos que cambie el color del styled-component que acabamos de crear. Para ello, usaremos un código similar a este:
./src/App.jsx
<button onClick={ () => setColor('red')}>Cambiar color</button>
<MyStyledComponent color={color}/>
Por tanto, tendremos que modificar el código de dos ficheros: App.jsx y styles.js (que contendrá el styled-component).
Ejercicio 2
Crear un componente que usará styled-components y que mostrará un popup cuando reciba una prop visible con el valor true.
Pasos en la resolución:
1. Crearemos un componente llamado Popup que recibirá como props visible y setVisible.
./src/components/Popup.jsx
const Popup = ({visible, setVisible}) => (
<Back visible={visible} >
<button onClick={aqui faltan cosas}>Cerrar</button>
</Back>
);
export default Popup;
2. En dicho componente Popup, tenemos un styled-component <Back> que recibirá una prop booleana y en función de ella se hará visible o invisible.
3. Toda la lógica de visibilidad del componente Popup se gestionará desde el componente App, que tendrá un estado llamado visible. Cuando pulsemos un botón, haremos que el estado cambie y se visualice el popup
./src/App
<button onClick={ () => setVisible(!visible)}>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';
const App = () => (
<div>
<GlobalStyle />
<p>App content</p>
</div>
);
export default App;
Cargar una tipografía:
Lo haremos usando GlobalStyle:
import font from './assets/fonts/font.ttf';
export const GlobalStyle = createGlobalStyle`
@font-face {
font-family: myFont;
src: url(${font});
}
`;
Uso de themes
/src/App.jsx
import Theme from "./components/Theme";
import { Box } from "./styles";
const App = () => {
return (
<Theme>
<Box />
</Theme>
)
}
export default App
/src/components/Theme/index.jsx
import { ThemeProvider } from "styled-components";
import { monteserinTheme } from "./themes/monteserinTheme";
import { otroTheme } from "./themes/otroTheme";
const Theme = ({ children }) => {
return (
<ThemeProvider theme={monteserinTheme}>
{children}
</ThemeProvider>
);
};
export default Theme;
/src/components/Theme/themes/monteserinTheme.js
export const monteserinTheme = {
name: "monteserin",
primaryColor: "red",
};
/src/components/Theme/themes/otroTheme.js
export const otroTheme = {
name: "otro",
primaryColor: "blue",
};
/src/styles.js
import styled, { css } from "styled-components";
export const Box = styled.div`
background-color: ${({ theme }) => theme.primaryColor};
width: 100px;
height: 100px;
${({ theme }) =>
theme.name === "monteserin" &&
css`
border-radius: 100%;
`}
`;
Como estructurar un componente que utiliza styled-components
/src/App.js
import Box from './components/box';
const App = () => <Box/>;
export default App;
/src/components/Box/index.js
import Box from './Box';
export default Box;
/src/components/Box/Box.jsx
import { Btn } from './Box.styled';
const Box = () => <Btn onClick="alert('hola)">hola</Btn>;
export default Box;
/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;
`;
Enlace a la extensión de Visual Studio Code para generar los componentes de forma automatizada.
Ejercicio
- Crear un componente funcional que cargue dos styled components que llamaremos : StyledComponent1 y StyledComponent2.
- Debemos usar herencia de styled components. StyledComponent2 debe heredar estilos de StyledComponent1.
- Debemos crear un GlobalStyle para dar estilos al body.
- Cargaremos una fuente y se la aplicaremos a StyledComponent2.
- Debemos tener un efecto hover en StyledComponent2.
- StyledComponent2 debe cambiar de tamaño en función de una prop.
- Debemos usar media queries.