Step 26: Dark Theme

Let's add a button to toggle between light and dark theme! Mantine UI makes this easy!!

Add a new file components/Toggle.jsx with the following content:

import { IconSun, IconMoonStars } from "@tabler/icons";
import { ActionIcon, useMantineColorScheme } from "@mantine/core";

function Toggle() {
  const { colorScheme, toggleColorScheme } = useMantineColorScheme();

  return (
    <ActionIcon variant="default" onClick={() => toggleColorScheme()} size={30}>
      {colorScheme === "dark" ? (
        <IconSun size={16} />
      ) : (
        <IconMoonStars size={16} />
      )}
    </ActionIcon>
  );
}

export default Toggle;

Add the toggle button to the app's header right next to the "add note" button:

  import { IconNote } from "@tabler/icons";
- import { Grid, Button } from "@mantine/core";
+ import { Grid, Button, Group } from "@mantine/core";
  import Search from "./Search";
  import PropTypes from "prop-types";
  import { useNavigate } from "react-router-dom";
+ import Toggle from "./Toggle";

  function Header(props) {
    const { query, setQuery, add } = props;
    const navigate = useNavigate();

    const handleOnClick = () => {
      const { id, title, text } = add();
      navigate("/edit", { state: { id, title, text, mode: "remove-on-cancel" } });
    };

    return (
      <Grid>
-       <Grid.Col span={10}>
+       <Grid.Col span={9}>
          <Search query={query} setQuery={setQuery} />
        </Grid.Col>
-       <Grid.Col span={2}>
+       <Grid.Col span={3}>
+         <Group position="right">
            <Button
              onClick={handleOnClick}
              variant="default"
              leftIcon={<IconNote />}
            >
              Add Note
            </Button>
+           <Toggle />
+         </Group>
        </Grid.Col>
      </Grid>
    );
  }

  export default Header;

  Header.propTypes = {
    query: PropTypes.string,
    setQuery: PropTypes.func,
    add: PropTypes.func,
  };

Next update the main.jsx as follows:

  import React from "react";
  import ReactDOM from "react-dom/client";
  import App from "./App";
- import { MantineProvider } from "@mantine/core";
  import { BrowserRouter } from "react-router-dom";

  ReactDOM.createRoot(document.getElementById("root")).render(
-   <MantineProvider withGlobalStyles withNormalizeCSS>
      <BrowserRouter>
        <App />
      </BrowserRouter>
-   </MantineProvider>
  );

Finally, update the App.jsx as follows:

+ import { MantineProvider, ColorSchemeProvider } from "@mantine/core";

  function App() {
    const [notes, setNotes] = useState([]);
    const [query, setQuery] = useState("");
+   const [colorScheme, setColorScheme] = useState("light");
+   const toggleColorScheme = (value) =>
+     setColorScheme(value || (colorScheme === "dark" ? "light" : "dark"));



    return (
+     <ColorSchemeProvider
+       colorScheme={colorScheme}
+       toggleColorScheme={toggleColorScheme}
+     >
+       <MantineProvider
+         theme={{ colorScheme }}
+         withGlobalStyles
+         withNormalizeCSS
+       >
          <Routes>
            <Route
              path="/"
              element={
                <Home
                  notes={notes}
                  query={query}
                  setQuery={setQuery}
                  add={add}
                  remove={remove}
                />
              }
            />
            <Route path="/edit" element={<Edit edit={edit} remove={remove} />} />
          </Routes>
+       </MantineProvider>
+     </ColorSchemeProvider>
    );
  }

Observer the app as you toggle from light to dark theme and back!