Files
portfolio/web/src/components/ThemeToggle/ThemeToggle.tsx
2024-10-10 14:09:09 -04:00

50 lines
1.3 KiB
TypeScript

import { useState, useEffect } from 'react'
import { mdiWeatherSunny, mdiWeatherNight } from '@mdi/js'
import Icon from '@mdi/react'
const LIGHT_THEME = 'light'
const DARK_THEME = 'dark'
const ThemeToggle = () => {
const [theme, setTheme] = useState(
(localStorage.getItem('theme') ??
window.matchMedia('(prefers-color-scheme: dark)').matches)
? DARK_THEME
: LIGHT_THEME
)
const handleToggle = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.checked) setTheme(DARK_THEME)
else setTheme(LIGHT_THEME)
}
useEffect(() => {
localStorage.setItem('theme', theme)
document
.querySelector('html')
.setAttribute('data-theme', localStorage.getItem('theme'))
document
.querySelector('html')
.setAttribute('data-uppy-theme', localStorage.getItem('theme'))
}, [theme])
return (
// eslint-disable-next-line jsx-a11y/label-has-associated-control
<label className="btn btn-ghost swap swap-rotate w-12">
<input
type="checkbox"
className="theme-controller"
checked={theme === DARK_THEME}
onChange={handleToggle}
/>
<Icon path={mdiWeatherSunny} className="swap-off size-8 text-warning" />
<Icon path={mdiWeatherNight} className="swap-on size-8 text-primary" />
</label>
)
}
export default ThemeToggle