Implementando Dark Mode en Gatsby con Sass (2/2)

jpgallegos1

JPGallegos1

Posted on January 29, 2020

Implementando Dark Mode en Gatsby con Sass (2/2)
Implementando Dark Mode en Gatsby con Sass
1) Integrando Sass en Gatsby
2) Implementando dark mode con un custom hook y Sass

Bienvenides a la segunda parte de la implementación del Dark Mode en Gatsby con Sass. En esta ocasión voy a arrancar definiendo variables y después crearemos un custom hook, el cual su lógica nos permitirá switchear entre fondo light o dark.

Definiendo variables

Dentro de nuestra carpeta sass vamos a crear un archivo que voy a llamar _vars.scss y dentro de éste voy a nombrar cuatro variables:

Background:

  • $bgLight: rgb(243, 241, 241);
  • $bgDark: rgb(32, 30, 30);

Colores:

  • $green: rgb(40, 168, 40);
  • $pink: rgb(243, 131, 237);

A saber: nombrar los archivos con _ al principio es una caracteristica de Sass y es conveniente que todos se nombren de esa forma menos el principal.

Lo siguiente que haremos es integrar nuestras variables al archivo principal layout.scss y para ello escribiremos la siguiente línea de código: @import './vars';. En este caso no hace falta que lleve extensión .scss dado que lo reconoce automáticamente. Para testear que todo funcione, en nuestro layout.scss escribiremos body{ background: $bgDark } y tendríamos que ver nuestro fondo negro en localhost:8000.

Finalmente a layout.scss le haré unas modificaciones, modificaré pages/index.js y agregaré _index.scss a mi carpeta de Sass. Debería quedar de la siguiente manera:

Gatsby-Sass

En caso de tener un proyecto avanzado en Gatsby, asegúrate de que tu body reciba el &.dark{ background: $bgDark }

Creando el Custom Hook o Hook Personalizado

Como sabemos, en React tenemos distintos hooks como useState, useEffect o useContext que permiten distintas funcionalidades, pero algo realmente bueno de React es la posibilidad de crear nuestros propios hooks para que hagan lo que nosotros queremos. Al fin y al cabo son funciones.

"¿Pero será muy difícil?": A un custom hook se le puede agregar toda la lógica y complejidad que se quiera, pero no va a ser este el caso. Crearemos algo sencillo, entendible para todes.

Primeros pasos con nuestro hook

Nos dirigimos a nuestra carpeta src y creamos otra que la llamaré hooks y dentro tendrá un archivo de nombre useTheme.js.

A saber: la recomendación que nos da React es que nuestros hooks personalizados empiecen con use.

Dentro de nuestro hook, debemos importar React y el useState. Crearemos la función useTheme y la exportaremos para hacerla disponible en otros componentes.

Lo siguiente que haremos es crear un state con value y setValue que arrancará en null, junto a un método que voy a llamar handleTheme, el cual voy a retornar y más adelante nos permitirá ejecutar el evento de nuestro botón. En un principio debería quedar así:

React, JavaScript

Nota: pueden obviar el import React... y dejarlo de esta forma import {useState} from 'react'. Eso eliminará una advertencia en la consola pero ambas formas son válidas.

Jugando con el DOM

si recuerdas, yendo a la consola y tipeando document podemos acceder a todo nuestro HTML. Entre todo ese árbol está el body y dentro de éste elemento podemos ver si contiene o no clases. Incluso puedes tipear en la consola document.body y luego intentar document.body.classList para hacer todo más sencillo.

Alt Text

Complemento: la diferencia entre ClassName y ClassList es que el primero nos devuelve todas las clases que contenga un elemento en forma de string y el segundo en un array, lo cual ésta última opción nos permite agregar y quitar clases. Para saber más sobre esta diferencia aconsejo leer el primer comentario de este post.

Como nos interesa acceder a este último elemento, simplemente lo vamos a guardar en una constante así como esta: const body = document.body.classList y debajo vamos a crear otra: const darkTheme = 'dark'. Y estas son las dos únicas variables que vamos a requerir.

Implementando la lógica

Ahora, quizá esta puede ser la parte más confusa para muches. Pero primero lo primero: cuando algo confunde, lo mejor es escribir pseudo-código y plantear el problema en nuestro lenguaje, no en el de las computadoras.

JavaScript

CONSEJO: Lo que también nos permite la consola es ver todos los métodos con los que tenemos permitido interactuar por medio de su prototype:

JavaScript

JavaScript

De todos esos métodos, vamos a utilizar tres: contains(), add() y remove(). Repasando rápidamente en nuestro lenguaje: si body contiene la clase dark if(body.contains()){ ... } quiero que lo remuevas body.remove(), de otra forma, agregala body.add(). De momento nos quedaría algo así:

JavaScript

Hasta ahí perfecto; pero queremos más. Queremos combinarlo con nuestro state y esa clase que se agrega y remueve por medio de un click quede guardada ahí. Vamos a hacer un setValue al momento de agregar y quitar. Finalmente, hacemos un return { value, handleTheme } para tenerlo disponible donde lo vayamos a utilizar.

JavaScript, React

GRAN TRABAJO! Ya tenemos nuestro custom hook finalizado. Ahora será momento de usarlo.

Utilizando nuestro Custom Hook

Ya hicimos la parte más complicada, ahora sólo queda disfrutar de lo logrado hasta aquí.

Como primer paso vamos a nuestro src/pages/index.js e importamos nuestro hook personalizado tipeando import useTheme from '../hooks/useTheme'. La siguiente que haremos es cortar todo el contenido dentro de const IndexPage = () => (...) y reemplazarlo de la siguiente forma:

Gatsby

Lo siguiente es extraer la función de handleTheme que implementamos y retornamos en nuestro useTheme.js. Para eso, arriba del return ( ... ) vamos a escribir const {handleTheme} = useTheme();. Por último, a nuestro botón le vamos a dar la funcionalidad de handleTheme de la siguiente forma: <button onClick={handleTheme}>Moon</button>.

¡Listo! Ya podemos switchear el background de nuestro sitio entre light o dark mode, porque si recuerdas, a nuestro body ya le avisamos que iba a recibir la clase dark y en nuestro hook personalizado hicimos la funcionalidad de agregarla y removerla a través de un evento onClick.

CSS

Pequeño truco en Sass

Lo último que quiero enseñarte es un pequeño truco de Sass. Como sabemos, nosotros en nuestro index.scss tenemos un h1{ color: $green }. En ese mismo h1 y en realidad puede ser en cualquier selector o elemento, vamos a tipear body.dark & { color: $pink }. Y eso cambiará el color de nuestro h1 o elemento con el que quisieramos hacerlo.

CSS

Agradezco inmensamente a aquelles que se tomaron el tiempo de leer estos artículos y ojalá les haya servido. En este link puede acceder al código final del proyecto. Dudas y sugerencias, todo es bienvenido en un comentario o me pueden escribir a mi twitter.

💖 💪 🙅 🚩
jpgallegos1
JPGallegos1

Posted on January 29, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related