How To Add Dark Mode Toggle in ReactJS + TailwindCSS + DaisyUI

Introduction:

It sounds like you are planning to add a dark mode toggle with local storage persistence to a ReactJS + TailwindCSS + DaisyUI project. You can begin by setting up the project and installing the necessary dependencies. Next, you can create a Navbar and Hero component using DaisyUI's pre-built components. Finally, you can implement a dark mode toggle using DaisyUI's help and by updating the custom attribute in the HTML tag to add local storage persistence to it.

Prerequisites:

Before we get started, you need to have the following tools and technologies installed on your machine:

  • NodeJS
  • Code Editor

Initiate ReactJS project

Let's start by creating a new Reactjs project using the create-react-app command.

npx create-react-app dark-mode-toggle
cd dark-mode-toggle

Then remove the unnecessary files and code from the src directory.

Installing and Configuring TailwindCSS

To install TailwindCSS, run the following command:

npm install -D tailwindcss

Then create a new file called tailwind.config.js by running the following command:

npx tailwindcss init

In the tailwind.config.js file, add the following code to it:

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],

  theme: {
    extend: {},
  },
  plugins: [],
}

In your src/index.css file, add the following directives:

@tailwind base;
@tailwind components;
@tailwind utilities;

Installing and Configuring DaisyUI

Now that we've set up TailwindCSS, let's install DaisyUI. DaisyUI is a collection of ready-to-use UI components designed to work seamlessly with TailwindCSS.

To install DaisyUI, run the following command in your project directory:

npm install daisyui

After the installation is complete, we need to configure DaisyUI with TailwindCSS.

Open the tailwind.config.js file and add the following code at the end of the plugins array:

plugins: [require('daisyui')],

Now we also need to add the daisyUI themes so that we can switch between them.

  daisyui: {
    themes: ["light", "dark"],
  },

The whole code in our tailwind.config.js file would look something like this:

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],

  theme: {
    extend: {},
  },
  plugins: [require("daisyui")],
  daisyui: {
    themes: ["light", "dark"],
  },
}

Navbar component

Now create an Navbar.js file inside the src/components folder and add the following code to it:

import { useState, useEffect } from "react";

// assets
import logo from "../assets/om-logo.png";
import sun from "../assets/sun.svg";
import moon from "../assets/moon.svg";

const Navbar = () => {
  return (
    <div className="navbar bg-base-100 shadow-lg px-4 sm:px-8">
      <div className="flex-1">
        <img src={logo} alt="OM" className="btn btn-ghost p-0" />
        <h1 className="text-lg font-bold mx-4">Your Website</h1>
      </div>
      <div className="flex-none">
        {/* Toggle button here */}
        <button className="btn btn-square btn-ghost">
          <label className="swap swap-rotate w-12 h-12">
            <input type="checkbox" />
            {/* light theme sun image */}
            <img src={sun} alt="light" className="w-8 h-8 swap-on" />
            {/* dark theme moon image */}
            <img src={moon} alt="dark" className="w-8 h-8 swap-off" />
          </label>
        </button>
      </div>
    </div>
  );
};
export default Navbar;

Hero component (Optional)

To add some content to our single page, let's create another component called Hero.js inside the src/components folder and add the following code it:


const Hero = () => {
  return (
    <div className="hero min-h-full h-full pt-[20%]">
      <div className="hero-content text-center">
        <div className="max-w-md">
          <h1 className="text-5xl font-bold">Your Awesome Website!</h1>
          <p className="py-6">
            Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.
          </p>
          <button className="btn btn-primary">
            Checkout
          </button>
        </div>
      </div>
    </div>
  );
};
export default Hero;

Adding Navbar and Hero components to App.js

Now we are ready to show our components in our single page by adding them to the App.js component as:

import Navbar from "./components/Navbar";
import Hero from "./components/Hero";

function App() {
  return (
    <div className="h-full min-h-full">
      <Navbar />
      <Hero />
    </div>
  );
}

export default App;

Implementing Dark Mode Toggle functionality

Towards the end, we have to toggle the dark/theme when we click on the toggle button from the Navbar component. So, add the following code to the Navbar.js component:

import { useState, useEffect } from "react";

// assets
import logo from "../assets/om-logo.png";
import sun from "../assets/sun.svg";
import moon from "../assets/moon.svg";

const Navbar = () => {
  // use theme from local storage if available or set light theme
  const [theme, setTheme] = useState(
    localStorage.getItem("theme") ? localStorage.getItem("theme") : "light"
  );

  // update state on toggle
  const handleToggle = (e) => {
    if (e.target.checked) {
      setTheme("dark");
    } else {
      setTheme("light");
    }
  };

  // set theme state in localstorage on mount & also update localstorage on state change
  useEffect(() => {
    localStorage.setItem("theme", theme);
    const localTheme = localStorage.getItem("theme");
    // add custom data-theme attribute to html tag required to update theme using DaisyUI
    document.querySelector("html").setAttribute("data-theme", localTheme);
  }, [theme]);

  return (
    <div className="navbar bg-base-100 shadow-lg px-4 sm:px-8">
      <div className="flex-1">
        <img src={logo} alt="OM" className="btn btn-ghost p-0" />
        <h1 className="text-lg font-bold mx-4">Your Website</h1>
      </div>
      <div className="flex-none">
        {/* Toggle button here */}
        <button className="btn btn-square btn-ghost">
          <label className="swap swap-rotate w-12 h-12">
            <input
              type="checkbox"
              onChange={handleToggle}
              // show toggle image based on localstorage theme
              checked={theme === "light" ? false : true}
            />
            {/* light theme sun image */}
            <img src={sun} alt="light" className="w-8 h-8 swap-on" />
            {/* dark theme moon image */}
            <img src={moon} alt="dark" className="w-8 h-8 swap-off" />
          </label>
        </button>
      </div>
    </div>
  );
};
export default Navbar;

Conclusion:

Congratulations! I'm glad that you were able to add a dark mode toggle to your ReactJS application using Tailwind CSS and DaisyUI. Your users will definitely appreciate the flexibility of choosing their preferred theme for a better user experience.

Thanks for following along, and happy coding!❤️

No comments:

Post a Comment