I can't seem to find a solution to this on any of the documentation. All I want is have a button toggle to switch between a light and dark mode.
-
Maybe this tutorial is helping? https://levelup.gitconnected.com/dark-mode-in-react-533faaee3c6e – David Jul 10 '22 at 08:43
4 Answers
It's not really necessary to install an additional npm package to achieve theme switching.
If all you want to achieve is having a toggle, you can list the desired themes in your tailwind.config.cjs
file like so:
plugins: [require('daisyui')],
daisyui: {
themes: ['light', 'dark'],
},
And then in your component, have a state, a toggle function and a useEffect that handles attribute injection into the HTML tag of the document (we want to have the global theme as an attribute in the html element as per the daisyUI docs: https://daisyui.com/docs/themes/)
function MyAwesomeThemeComponent() {
const [theme, setTheme] = React.useState('light');
const toggleTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark');
};
// initially set the theme and "listen" for changes to apply them to the HTML tag
React.useEffect(() => {
document.querySelector('html').setAttribute('data-theme', theme);
}, [theme]);
return (
<label className="swap swap-rotate">
<input onClick={toggleTheme} type="checkbox" />
<div className="swap-on">DARKMODE</div>
<div className="swap-off">LIGHTMODE</div>
</label>
);
}

- 358
- 1
- 3
- 10
-
works like a charm. thank you so much, really wasn't so easy to understand from the docs – Anonymous Mar 01 '23 at 17:44
-
1Very inuitive answer! Instead of going for other new package (as daisyUI docs say), using already available things. – Dr. Joy Singhal Jul 27 '23 at 17:25
Install the package called theme-change
https://www.npmjs.com/package/theme-change and then for react
index.tsx
import { themeChange } from 'theme-change';
/*Initialize under useEffect */
useEffect(() => {
themeChange(false);
}, []);
Then on navigation menu or top bar
<select className="gradientselect" data-choose-theme>
<option disabled value="">
Pick a theme
</option>
<option value="">Default</option>
<option value="light">Light</option>
<option value="retro">Retro</option>
<option value="dracula">Dracula</option>
<option value="cyberpunk">Cyberpunk</option>
</select>
Make sure to check the docs for more info on https://github.com/saadeghi/theme-change

- 86
- 1
- 4
Create a state variable to store the selected theme
const [theme, setTheme] = useState(localStorage.getItem("theme") ?? "light");
create function to handle theme toggle
const handleToggle = (e: any) => {
if (e.target.checked) {
setTheme("winter");
} else {
setTheme("night");
}
};
Save the selected theme to localStorage and update the theme attribute on the root element
useEffect(() => {
localStorage.setItem('theme', theme!)
const localTheme = localStorage.getItem('theme')
document.querySelector('html')?.setAttribute('data-theme', localTheme!)
}, [theme]);
And you can use 'handleToggle' at 'Swap' from DaisyUI
<label className="swap swap-rotate">
{/* this hidden checkbox controls the state */}
<input type="checkbox" onChange={handleToggle} />
{/* sun icon */}
<svg className="swap-on fill-current w-10 h-10" 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>
{/* moon icon */}
<svg className="swap-off fill-current w-10 h-10" 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>

- 1,150
- 6
- 18

- 21
- 2
I use the react-daisyui package. It abstracts all of the daisyui components as react components.
It even has a theme component
Example from official documentation:
import { Theme, Button } from 'react-daisyui'
export default (props) => {
return (
<>
<Theme dataTheme="dark">
<Button color="primary">Click me, dark!</Button>
</Theme>
<Theme dataTheme="light">
<Button color="primary">Click me, light!</Button>
</Theme>
</>
)
}

- 480
- 2
- 5
- 10