DEV Community

Cleyson Leal Braga
Cleyson Leal Braga

Posted on

Criando temas com custom hook + variáveis CSS 👨‍💻

Hoje em dia, uma funcionalidade muito requisitada em sites e apps é a aplicação de temas - normalmente usando o tão aclamado “Dark mode”. Com um clique, podemos mudar toda a cor do app/site para um tema escuro. Seus usuários dizem ser mais agradável aos olhos, e até mesmo trazer mais produtividade.

A aplicação de um tema pode ser algo ainda maior, se pensarmos no estilo do site como um tema, trazendo mais flexibilidade e padronização. Mesmo que ainda não exista um modo escuro, por exemplo. Também podemos aplicar técnicas que estão muito em alta, como o design token.

Iniciando o projeto 🚀

Vamos começar iniciando o projeto instalando e criando nossa aplicação usando o create-react-app

$ npx create-react-app theme-app
$ cd theme-app
$ npm start
Enter fullscreen mode Exit fullscreen mode

Com isso, teremos uma estrutura assim:

Alt Text

Podemos excluir os arquivos logo.svg, App.test.js e o App.css. Não precisaremos deles nesse tutorial.

Criando nosso tema ✨

Vamos criar nosso CSS com o tema primeiro, pois vamos precisar dele dentro do custom hook.
Vamos criar o arquivo theme.module.css no caminho

./src/styles/
Enter fullscreen mode Exit fullscreen mode

Inicialmente, vamos criar somente duas variáveis que serão usadas para aplicar as cores que desejamos.

.defaultTheme {
  /* Format: --theme + type + color + variant */

  /* Colors */
  --theme-background-color-primary: #fff;
  --theme-text-color--primary: #333333;
}

.darkTheme {
  /* Colors */
  --theme-background-color-primary: #333333;
  --theme-text-color--primary: #fff;
}

Enter fullscreen mode Exit fullscreen mode

A lógica aqui, é usar o custom hook para trocar a classe do tema - e com isso, os valores das variáveis, aplicando como um todo na aplicação.

Criando nosso custom hook 👨‍💻

Para criar nosso custom hook, vamos usar as API’s de context e useState, arquitetando todas as funcionalidades dentro dele, e exportando somente o que vamos utilizar para controlar a troca de tema.

Vamos criar o nosso arquivo themeContext.js no caminho

./src/contexts/themeContext
Enter fullscreen mode Exit fullscreen mode

Nosso themeContext.js será assim:

import React, { useState, createContext, useContext } from "react";
import styles from "../../styles/theme.module.css";

const themeContext = createContext();

// exportamos o useTheme com as funções que controlam a troca de tema
export const useTheme = () => {

  const context = useContext(themeContext);

  const [isDarkmode, setIsDarkmode] = context;

  const setDarkmodeOn = () => {
    setIsDarkmode(true);
  };

  const setDarkmodeOff = () => {
    setIsDarkmode(false);
  };

  const toggle = () => {
    setIsDarkmode((prev) => !prev);
  };

  return { isDarkmode, setDarkmodeOn, setDarkmodeOff, toggle };
};

// exportamos o ThemeProvider que aplica a classe do tema na div que vai englobar toda a aplicação
export const ThemeProvider = (props) => {
  const [isDarkmode, setIsDarkmode] = useState(false);
  const theme = isDarkmode ? styles.darkTheme : styles.defaultTheme;

  return (
    <themeContext.Provider value={[isDarkmode, setIsDarkmode]}>
      <div className={theme}>{props.children}</div>
    </themeContext.Provider>
  );
};

Enter fullscreen mode Exit fullscreen mode

Aplicando nosso tema ✅

Para usar nosso useTheme, vamos criar uma funcionalidade básica só para entender o fluxo de como as coisas funcionam.

Vamos criar um arquivo chamado Home.js dentro de ./src e também um arquivo chamado styles.module.css dentro de ./src/styles

No Home.js importamos o useTheme para poder usar nossa função de toggle que troca os temas e nossa variável isDarkMode para saber se o dark mode está ligado ou não.

Home.js

import React from "react";
import { useTheme } from "./contexts/themeContext/themeContext";
import styles from "./styles/styles.module.css";

export const Home = () => {
 const { isDarkmode, toggle } = useTheme();

 return (
   <div className={styles.wrapper}>
     <h1>{`Dark mode on? ${isDarkmode}`}</h1>
     <button onClick={toggle}>Trocar tema</button>
   </div>
 );
};

Enter fullscreen mode Exit fullscreen mode

No styles.module.css aplicamos nossas variáveis (design tokens) que aplicam os valores do tema selecionado.

styles.module.css

.wrapper {
 height: 100vh;
 background-color: var(--theme-background-color-primary);
 color: var(--theme-text-color--primary);
}

h1 {
 margin: 0;
}

Enter fullscreen mode Exit fullscreen mode

Agora podemos usar o provider no nosso App.js e chamar nosso componente Home.js

App.js

import { ThemeProvider } from "./contexts/themeContext/themeContext";
import { Home } from "./Home";
export default function App() {
 return (
   <ThemeProvider>
     <Home />
   </ThemeProvider>
 );
}
Enter fullscreen mode Exit fullscreen mode

Resultado 🤩

Conclusão

Usando o context + custom hook fica simples controlar e compartilhar em todo o nosso app os controles de tema, podemos ir além do dark mode e criar outros temas para personalizar nossas aplicações.
Espero que tenham gostado do post e
até a próxima

Top comments (0)