deven
deven

Reputation: 1

dark mode toggle in material ui

I am trying to implement a dark toggle in my website. I have gotten the toggle to show up in the correct place. I am using the usestate hook to implement the toggle functionality. However, on clicking the toggle, does not change the theme. I don't understand what is going wrong over here.

Here is the code of the different components.

I have implemented a component for the toggle theme button. Here is the code for togglethemebutton.js

import React, { useState } from "react";
// ----------------------------------------------------------------------
import { Switch } from '@mui/material';
import { createTheme } from '@mui/material/styles';
// ----------------------------------------------------------------------

export default function ToggleThemeButton() {
  const [darkState, setDarkState] = useState(false);
  const palletType = darkState ? "dark" : "light";
  const darkTheme = createTheme({
    palette: {
      type: palletType,
    }
  });
  const handleThemeChange = () => {
    setDarkState(!darkState);
  };

  return (
      <Switch checked={darkState} onChange={handleThemeChange} />
  );
}

I am using this component in the Navbar.js component.

import PropTypes from 'prop-types';
// material
import { alpha, styled } from '@mui/material/styles';
import { Box, Stack, AppBar, Toolbar, IconButton } from '@mui/material';
// components
import Iconify from '../../components/Iconify';
//
import Searchbar from './Searchbar';
import AccountPopover from './AccountPopover';
import LanguagePopover from './LanguagePopover';
import NotificationsPopover from './NotificationsPopover';
import ToggleThemeButton from './ToggleThemeButton';
// ----------------------------------------------------------------------

const DRAWER_WIDTH = 280;
const APPBAR_MOBILE = 64;
const APPBAR_DESKTOP = 92;

const RootStyle = styled(AppBar)(({ theme }) => ({
  boxShadow: 'none',
  backdropFilter: 'blur(6px)',
  WebkitBackdropFilter: 'blur(6px)', // Fix on Mobile
  backgroundColor: alpha(theme.palette.background.default, 0.72),
  [theme.breakpoints.up('lg')]: {
    width: `calc(100% - ${DRAWER_WIDTH + 1}px)`
  }
}));

const ToolbarStyle = styled(Toolbar)(({ theme }) => ({
  minHeight: APPBAR_MOBILE,
  [theme.breakpoints.up('lg')]: {
    minHeight: APPBAR_DESKTOP,
    padding: theme.spacing(0, 5)
  }
}));

// ----------------------------------------------------------------------

DashboardNavbar.propTypes = {
  onOpenSidebar: PropTypes.func
};

export default function DashboardNavbar({ onOpenSidebar }) {
  return (
    <RootStyle>
      <ToolbarStyle>
        <IconButton
          onClick={onOpenSidebar}
          sx={{ mr: 1, color: 'text.primary', display: { lg: 'none' } }}
        >
          <Iconify icon="eva:menu-2-fill" />
        </IconButton>

        <Searchbar />
        <Box sx={{ flexGrow: 1 }} />

        <Stack direction="row" alignItems="center" spacing={{ xs: 0.5, sm: 1.5 }}>

          // here is the toggle button

          <ToggleThemeButton/>
          <LanguagePopover />
          <NotificationsPopover />
          <AccountPopover />
        </Stack>
      </ToolbarStyle>
    </RootStyle>
  );
}

Upvotes: 0

Views: 3637

Answers (1)

noobprogrammer
noobprogrammer

Reputation: 241

A posible solution may be to move the logic to change the theme from the ToggleThemButton component to the NavBar and just pass the values needed like this:

ToggleThemeButton:

export default function ToggleThemeButton({handleThemeChange, darkState}) {
 
  return (
      <Switch checked={darkState} onChange={handleThemeChange} />
  );
}

Then in the NavBar component you could add a theme variable that its updated by the ToggleThemeButton, here i used a new createTheme with the pallete that has a background property just for testing (i don't know much about material ui)

Navbar:

export default function DashboardNavbar({ onOpenSidebar }) {

  const [darkState, setDarkState] = useState(false);     
  const palletType = darkState ? "dark" : "light";
  const darkTheme = createTheme({
    palette: {
      type: palletType,
      background: {
        default: "#fff"
      }
    }
  });

  const [theme, setTheme] = useState(darkTheme);    

  const handleThemeChange = () => {
    setDarkState(!darkState);
  
    setTheme(createTheme({
      palette: {
        type: palletType,
        background: {
          default: !darkState? "#000" : "#fff"
        }
      }
    }))
  };

  return (
    <RootStyle theme={theme}>
      
         ..... <ToggleThemeButton  handleThemeChange={handleThemeChange} darkState={darkState} />  .... 
            
      </ToolbarStyle>
    </RootStyle>
  );
}

Upvotes: 0

Related Questions