Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue integrating states with theme-change into React + TailwindCSS + DaisyUI FIXED #40

Open
kryptobaseddev opened this issue Jun 8, 2023 · 0 comments

Comments

@kryptobaseddev
Copy link

kryptobaseddev commented Jun 8, 2023

To make this work I had to make a handleThemeChange function to control the use of window.localStoreage.getItem and pass that into a 'if' statement controlling the setTheme. I am adding the toggle option to the Navbar of my app.

I had a bit of a unique scenario I needed to handle with my app. I wanted the logo for our site to change based on the Light or Dark theme. I have 2 variants of our logo that look better in each theme.

Firstly you need to make sure you have your tailwind.config.js file updated with DaisyUI and configured properly. This is where the light and dark theme toggles will come from below and they MUST match:

  plugins: [require("@tailwindcss/typography"), require("daisyui")],
  daisyui: {
    themes: [
      "light", 
      "dark",
    ],
    darkTheme: "dark", 
    base: true,
    styled: true,
    utils: true,
    rtl: false,
    prefix: "",
    logs: true,
  },

Follow like the readme instructions say:
import { themeChange } from 'theme-change';

Additionally, I am using the react-feather icons so I added:
import { Sun, Moon } from 'react-feather';

Just inside the page component I 'InitializeState' of the theme and logo:

const Navbar: React.FC = () => {
  // Initialize state
// First, we try to get the current theme from local storage. If there's no theme
// stored yet, we default to 'light'.
const initialTheme = window.localStorage.getItem('theme') || 'light';
// We then initialize our 'theme' state variable with the initial theme.
const [theme, setTheme] = useState(initialTheme);

// Based on the initial theme, we set the initial logo. If the theme is 'dark',
// we set the light logo, and vice versa.
const initialLogoName = initialTheme === 'dark' ? logoNameLight : logoNameDark;
// We then initialize our 'logoName' state variable with the initial logo name.
const [logoName, setLogoName] = useState(initialLogoName);

Next we have to instantiate the useEffect by doing this:

useEffect(() => {
  // In the 'useEffect' hook that runs on component mount, we get the current theme
  // from local storage again (it might have changed since the component initialized).
  // Again, if there's no theme stored yet, we default to 'light'.
  const currentTheme = window.localStorage.getItem('theme') || 'light';
  // We then update our 'theme' state variable with the current theme.
  setTheme(currentTheme);
  // Finally, we call 'themeChange' to update the actual theme of the app. If the
  // theme is 'dark', we pass 'true' to 'themeChange', and 'false' otherwise.
  themeChange(currentTheme === 'dark');
}, []);

To handle the changing of the theme and logo swap I created the function, here is the snippet of the handleThemeChange:

const handleThemeChange = () => {
  // When the theme change handler is called, we first get the current theme from
  // our 'theme' state variable.
  const currentTheme = theme;
  if (currentTheme === 'dark') {
    // If the current theme is 'dark', we switch to the 'light' theme. We update
    // the theme in local storage, the 'theme' state variable, and call 'themeChange'
    // with 'false' to switch the actual theme of the app. Finally, we switch the
    // logo to the dark version.
    window.localStorage.setItem('theme', 'light');
    setTheme('light');
    themeChange(false);
    setLogoName(logoNameDark);
  } else {
    // If the current theme is not 'dark' (so it's 'light'), we switch to the 'dark'
    // theme. We update the theme in local storage, the 'theme' state variable, and
    // call 'themeChange' with 'true' to switch the actual theme of the app. Finally,
    // we switch the logo to the light version.
    window.localStorage.setItem('theme', 'dark');
    setTheme('dark');
    themeChange(true);
    setLogoName(logoNameLight);
  }
}

In the body of the jsx under the return ( I made my appropriate updates to the correct sections of the Navbar I needed.
You can see here in my section I display the Navbar Logo:

  <div className="navbar-center">
    {/* Logo image works with the themeChange to set correct logo */}
  <img src={logoName} alt="logo" onClick={home} className="w-40" />
  </div>

Here you can see the use of the logoName that comes from the state of the handleThemeChange function.

For the actual Sun/Moon toggle for Light and Dark I implemented like this:

    {/* Dark mode toggle button */}
    <button 
        data-toggle-theme="dark,light" 
        data-act-class="ACTIVECLASS" 
        onClick={handleThemeChange}
        className="text-white btn btn-ghost btn-circle"
      >
          {theme === 'light' ? (
            <Moon className="h-5 w-5" strokeWidth="2" />
          ) : (
            <Sun className="h-5 w-5" strokeWidth="2" />
          )}
      </button>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant