48 lines
1.2 KiB
React
48 lines
1.2 KiB
React
|
|
import { useState, useEffect } from 'react'
|
||
|
|
import { Sun, Moon, Monitor } from 'lucide-react'
|
||
|
|
import { getTheme, setTheme, THEMES } from '../utils/theme'
|
||
|
|
import { hapticFeedback } from '../utils/telegram'
|
||
|
|
import './ThemeToggle.css'
|
||
|
|
|
||
|
|
const THEME_ICONS = {
|
||
|
|
[THEMES.LIGHT]: Sun,
|
||
|
|
[THEMES.DARK]: Moon,
|
||
|
|
[THEMES.AUTO]: Monitor
|
||
|
|
}
|
||
|
|
|
||
|
|
const THEME_LABELS = {
|
||
|
|
[THEMES.LIGHT]: 'Светлая',
|
||
|
|
[THEMES.DARK]: 'Тёмная',
|
||
|
|
[THEMES.AUTO]: 'Авто'
|
||
|
|
}
|
||
|
|
|
||
|
|
export default function ThemeToggle({ showLabel = false }) {
|
||
|
|
const [currentTheme, setCurrentTheme] = useState(getTheme())
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const theme = getTheme()
|
||
|
|
setCurrentTheme(theme)
|
||
|
|
}, [])
|
||
|
|
|
||
|
|
const handleToggle = () => {
|
||
|
|
hapticFeedback('light')
|
||
|
|
|
||
|
|
const themes = [THEMES.LIGHT, THEMES.DARK, THEMES.AUTO]
|
||
|
|
const currentIndex = themes.indexOf(currentTheme)
|
||
|
|
const nextTheme = themes[(currentIndex + 1) % themes.length]
|
||
|
|
|
||
|
|
setTheme(nextTheme)
|
||
|
|
setCurrentTheme(nextTheme)
|
||
|
|
}
|
||
|
|
|
||
|
|
const Icon = THEME_ICONS[currentTheme]
|
||
|
|
|
||
|
|
return (
|
||
|
|
<button className="theme-toggle" onClick={handleToggle} title={THEME_LABELS[currentTheme]}>
|
||
|
|
<Icon size={20} />
|
||
|
|
{showLabel && <span>{THEME_LABELS[currentTheme]}</span>}
|
||
|
|
</button>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|