0
votes

I use React with styled-components library to provide light and dark themes for the application. It works properly, but I need to add a font family selection that works independently of the color scheme. But how can I combine two themes (first for color scheme and second for font) and change them?

Here is my code for changing light and dark theme:

import { useEffect, useState } from 'react';

export const useDarkMode = () => {
  const [theme, setTheme] = useState('light');
  const [componentMounted, setComponentMounted] = useState(false);
  const setMode = mode => {
    window.localStorage.setItem('theme', mode)
    setTheme(mode)
  };

  const toggleTheme = () => {
    if (theme === 'light') {
      setMode('dark')
    } else {
      setMode('light')
    }
  };

  useEffect(() => {
    const localTheme = window.localStorage.getItem('theme');
    window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && !localTheme ?
      setMode('dark') :
      localTheme ?
        setTheme(localTheme) :
        setMode('light');
    setComponentMounted(true);
  }, []);

  return [theme, toggleTheme, componentMounted]
};

And this is my App.jsx:

import React from 'react';
import { Switch, Route, withRouter } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import { GlobalStyles } from '../global';
import { lightTheme, darkTheme } from '../theme';
import { useDarkMode } from '../useDarkMode';

import { Home } from '../../pages';

const App = (props) => {

  const [ theme, toggleTheme ] = useDarkMode();
  const themeMode = theme === 'light' ? lightTheme : darkTheme;

  return (
    <ThemeProvider theme={themeMode}>
      <div>
        <GlobalStyles />  
        <Switch>
          <Route exact path='/' component={Home}></Route>
        </Switch>
      </div>
    </ThemeProvider>
  )
}

export default withRouter(App);
1

1 Answers

0
votes

You can update the theme with the font-style you want by just updating the theme itself:

import { useEffect, useState } from 'react';

export const useDarkMode = () => {
  const [theme, setTheme] = useState('light');
  /* ... */
  
  const toggleFontStyle = () => {
    // To toggle between two font styles, or you can pass style as a parameter
    if (theme.fontStyle === 'SomeStyle') {
      setTheme({ ...theme, fontStyle: 'OtherStyle' })
    } else {
      setTheme({ ...theme, fontStyle: 'SomeStyle' })
    }
  }

  /* .... */

  return [theme, toggleTheme, toggleFontStyle, componentMounted]
};

let me know if it helps