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

Fixing toggle function #43

Open
gabrieldesousah opened this issue Aug 11, 2023 · 5 comments
Open

Fixing toggle function #43

gabrieldesousah opened this issue Aug 11, 2023 · 5 comments

Comments

@gabrieldesousah
Copy link

Hi, the themeToggle() function have some problems. It is creating a new eventlistener each time that the toggle is clicked and in vue isn't working (I'm trying with https://daisyui.com/)

This is a suggestion to fix (this code: https://github.com/saadeghi/theme-change/blob/master/src/toggle.js):

function themeToggle() {
  const toggleEl = document.querySelector("[data-toggle-theme]");
  const dataKey = toggleEl?.getAttribute("data-key") || "theme";
  const currentTheme = localStorage.getItem(dataKey);

  function setTheme(theme) {
    document.documentElement.setAttribute("data-theme", theme);
    document.querySelectorAll("[data-toggle-theme]").forEach((el) => {
      el.classList.toggle(el.getAttribute("data-act-class"), theme !== null);
    });
    if (theme === null) {
      localStorage.removeItem(dataKey);
    } else {
      localStorage.setItem(dataKey, theme);
    }
  }

  if (currentTheme) {
    setTheme(currentTheme);
  }

  if (toggleEl) {
    toggleEl.addEventListener("click", function () {
      const themesList = toggleEl.getAttribute("data-toggle-theme");
      if (themesList) {
        const themesArray = themesList.split(",");
        const currentThemeIndex = themesArray.indexOf(
          document.documentElement.getAttribute("data-theme")
        );
        const newThemeIndex = (currentThemeIndex + 1) % themesArray.length;
        setTheme(themesArray[newThemeIndex]);
      }
    });
  }
}

In vue, I make works with:

<template>
      <input ref="themeToggle" data-toggle-theme="light,dark" data-act-class="ACTIVECLASS" type="checkbox"
        class="toggle" />
</template>

<script setup lang='ts'>
import { onMounted, ref } from 'vue'
import { themeChange } from 'theme-change'

const themeToggle = ref(null);

const setTheme = (theme, dataKey) => {
  document.documentElement.setAttribute('data-theme', theme);
  document.querySelectorAll('[data-toggle-theme]').forEach((el) => {
    el.classList.toggle(el.getAttribute('data-act-class'), theme !== null);
  });
  if (theme === null) {
    localStorage.removeItem(dataKey);
  } else {
    localStorage.setItem(dataKey, theme);
  }
};

onMounted(() => {
  themeChange(false)
  const toggleEl = themeToggle.value;
  const dataKey = toggleEl.getAttribute('data-key') || 'theme';
  const currentTheme = localStorage.getItem(dataKey);

  if (currentTheme) {
    setTheme(currentTheme, dataKey);
  }

  toggleEl.addEventListener('click', () => {
    const themesList = toggleEl.getAttribute('data-toggle-theme');
    if (themesList) {
      const themesArray = themesList.split(',');
      const currentThemeIndex = themesArray.indexOf(
        document.documentElement.getAttribute('data-theme')
      );
      const newThemeIndex = (currentThemeIndex + 1) % themesArray.length;
      setTheme(themesArray[newThemeIndex], dataKey);
    }
  });
});
</script>
@guschiavon
Copy link

guschiavon commented Oct 1, 2023

I also have the issue in React. It works nicely just after set up, but when restarting the local server it fails to update the theme. Here's my code:

tailwind.config.js

module.exports = {
   content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    [...]
  },
  daisyui: {
    themes: [
      "dark",
      "light"      
    ],
  },
  plugins: [require("daisyui")],
}

index.html

<!DOCTYPE html>
<html lang="en" data-theme="light">

   [...]
</html>

Toggle Component

import { useEffect } from "react";
import { themeChange } from "theme-change";

const ThemeSwitch = () => {
    useEffect(() => {
      themeChange(false)      
    }, [])
    
  return (
    <div className="p-2">    
      <label className="swap swap-rotate">          
        <input type="checkbox" data-toggle-theme="light,dark"/>                
        <svg className="swap-on fill-current w-8 h-8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"/></svg>        
        <svg className="swap-off fill-current w-8 h-8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"/></svg>        
      </label>    
    </div>
  );
};

export default ThemeSwitch;

Working with React 18

@Djibdjib
Copy link

I have the same problem that @guschiavon on react...

@universeroc
Copy link

Me too, I use next.js and facing the same issue :(

@wutsqo
Copy link

wutsqo commented Dec 31, 2023

Me too, with Next 14 and React 18

@cph101
Copy link

cph101 commented Apr 7, 2024

Same issue, using Next, React, and DaisyUI

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

6 participants