Ver código fonte

lightdarkmode stable

Ian Pomeroy 3 anos atrás
pai
commit
f7733ab2f0
3 arquivos alterados com 65 adições e 86 exclusões
  1. 3 0
      components/Layout.js
  2. 60 82
      components/light_dark.js
  3. 2 4
      pages/_app.js

+ 3 - 0
components/Layout.js

@@ -3,15 +3,18 @@ import styles from '../styles/Layout.module.css'
 import Header from './Header'
 import ResponsiveAppBar from '../components/Nav'
 
+
 const Layout = ({ children }) => {
   return (
       <>
         <ResponsiveAppBar />
         <div className={styles.container}>
+
           <main className={styles.main}>
             <Header />
             {children}
           </main>
+
         </div>
       </>
   )

+ 60 - 82
components/light_dark.js

@@ -1,86 +1,64 @@
-import React, { useState,useEffect  } from 'react';
-import { createTheme } from '@material-ui/core/styles';
-import { ThemeProvider } from '@material-ui/styles';
+import * as React from 'react';
+import IconButton from '@mui/material/IconButton';
+import Box from '@mui/material/Box';
+import { useTheme, ThemeProvider, createTheme } from '@mui/material/styles';
+import Brightness4Icon from '@mui/icons-material/Brightness4';
+import Brightness7Icon from '@mui/icons-material/Brightness7';
+import { CssBaseline } from '@mui/material';
+import { useEffect } from 'react';
 
-const ToggleButton = styled.button`
-  --toggle-width: 80px;
-  --toggle-height: 38px;
-  --toggle-padding: 4px;
-  position: relative;
-  display: flex;
-  align-items: center;
-  justify-content: space-around;
-  font-size: 1.5rem;
-  line-height: 1;
-  width: var(--toggle-width);
-  height: var(--toggle-height);
-  padding: var(--toggle-padding);
-  border: 0;
-  border-radius: calc(var(--toggle-width) / 2);
-  cursor: pointer;
-  background: var(--color-bg-toggle);
-  transition: background 0.25s ease-in-out, box-shadow 0.25s ease-in-out;
-  &:focus {
-    outline-offset: 5px;
-  }
-  &:focus:not(:focus-visible) {
-    outline: none;
-  }
-  &:hover {
-    box-shadow: 0 0 5px 2px var(--color-bg-toggle);
-  },
-`;
+const ColorModeContext = React.createContext({ toggleColorMode: () => {} });
 
-const ToggleThumb = styled.span`
-  position: absolute;
-  top: var(--toggle-padding);
-  left: var(--toggle-padding);
-  width: calc(var(--toggle-height) - (var(--toggle-padding) * 2));
-  height: calc(var(--toggle-height) - (var(--toggle-padding) * 2));
-  border-radius: 50%;
-  background: white;
-  transition: transform 0.25s ease-in-out;
-  transform: ${(p) =>
-    p.activeTheme === "dark"
-      ? "translate3d(calc(var(--toggle-width) - var(--toggle-height)), 0, 0)"
-      : "none"};
-`;
-const light = createTheme({
-  palette: {
-    mode: 'light',
-  },
-});
-
-const dark = createTheme({
-  palette: {
-    mode: 'dark',
-  },
-});
-function activeTheme(themeMode){
-  return themeMode === 'light'? light : dark;
+function MyApp() {
+  const theme = useTheme();
+  const colorMode = React.useContext(ColorModeContext);
+  return (
+    //Give value and area to the dark mode 
+    <CssBaseline 
+      sx={{
+        display: 'flex',
+        width: '100%',
+        alignItems: 'center',
+        justifyContent: 'center',
+        bgcolor: 'background.default',
+        color: 'text.primary',
+        borderRadius: 1,
+        p: 3,
+      }}
+    >
+      {theme.palette.mode} mode
+      <IconButton sx={{ ml: 1 }} onClick={colorMode.toggleColorMode} color="inherit">
+        {theme.palette.mode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />}
+      </IconButton>
+    </CssBaseline >
+  );
 }
-export const toggleTheme = () => { 
-      const [activeTheme, setTheme] = useState("light");
-      const altheme = activeTheme === "light" ? "dark" : "light";
-    useEffect(() => {
-      const savedTheme = window.localStorage.getItem("theme");
-      savedTheme && setActiveTheme(savedTheme);
-    }, []);
-    useEffect(() => {
-      document.body.dataset.theme = activeTheme;
-      window.localStorage.setItem("theme", activeTheme);
-    }, [activeTheme]);
 
-    return (
-      <ToggleButton
-        aria-label={`Change to ${altheme} mode`}
-        title={`Change to ${altheme} mode`}
-        type="button"
-        onClick={() => setActiveTheme(altheme)}
-      >
-        <ToggleThumb activeTheme={activeTheme} />
-        <span>🌙</span>
-      <span>☀️</span>
-      </ToggleButton>
-    );
-  };
+export default function ToggleColorMode(Component) {
+  const [mode, setMode] = React.useState('light');
+  const colorMode = React.useMemo(
+    () => ({
+      toggleColorMode: () => {
+        setMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
+      },
+    }),
+    [],
+  );
+  const theme = React.useMemo(
+    () =>
+      createTheme({
+        palette: {
+          mode,
+        },
+      }),
+    [mode],
+  );
+
+  return (
+    <ColorModeContext.Provider value={colorMode}>
+      <ThemeProvider theme={theme}>
+        <MyApp/>
+      </ThemeProvider>
+    </ColorModeContext.Provider>
+  );
+}

+ 2 - 4
pages/_app.js

@@ -19,9 +19,7 @@ import { useTheme } from "@material-ui/core/styles";
 import useMediaQuery from "@material-ui/core/useMediaQuery";
 import dynamic from 'next/dynamic';
 import styled from '@emotion/styled';
-const toggleTheme = dynamic(() => import("../components/light_dark"),{
-  ssr:false
-});
+import  ToggleColorMode from "../components/light_dark";
 
 const useStyles = makeStyles((theme) => ({
   root: {
@@ -59,7 +57,7 @@ return (
           {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
          <CssBaseline />
           <Component {...pageProps} />
-          <toggleTheme/>
+          <ToggleColorMode/>
         </ThemeProvider>
       </Layout> 
     </CacheProvider>