All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 53s
- Agregar función applyThemeClass para sincronizar con HTML - Aplicar clase dark/light al elemento HTML - Agregar watcher para actualizar clase en cambios de tema - Inicializar clase correcta en onMounted
75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
/**
|
|
* Composable para manejar el tema día/noche
|
|
* Persiste la preferencia del usuario en localStorage
|
|
*/
|
|
|
|
export type Theme = 'day' | 'night'
|
|
|
|
export const useTheme = () => {
|
|
// Estado del tema con persistencia
|
|
const currentTheme = useState<Theme>('theme', () => {
|
|
if (import.meta.client && typeof window !== 'undefined') {
|
|
const saved = localStorage.getItem('theme')
|
|
if (saved === 'day' || saved === 'night') {
|
|
return saved
|
|
}
|
|
// Detectar preferencia del sistema
|
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
return prefersDark ? 'night' : 'day'
|
|
}
|
|
return 'day'
|
|
})
|
|
|
|
// Computed para saber si es modo noche
|
|
const isNight = computed(() => currentTheme.value === 'night')
|
|
|
|
// Función para aplicar la clase dark al HTML
|
|
const applyThemeClass = (theme: Theme) => {
|
|
if (import.meta.client && typeof window !== 'undefined') {
|
|
const html = document.documentElement
|
|
if (theme === 'night') {
|
|
html.classList.add('dark')
|
|
html.classList.remove('light')
|
|
} else {
|
|
html.classList.add('light')
|
|
html.classList.remove('dark')
|
|
}
|
|
}
|
|
}
|
|
|
|
// Aplicar clase inicial al montar
|
|
if (import.meta.client) {
|
|
onMounted(() => {
|
|
applyThemeClass(currentTheme.value)
|
|
})
|
|
|
|
// Sincronizar clase cuando cambie el tema
|
|
watch(currentTheme, (newTheme) => {
|
|
applyThemeClass(newTheme)
|
|
})
|
|
}
|
|
|
|
// Alternar tema
|
|
const toggleTheme = () => {
|
|
currentTheme.value = currentTheme.value === 'day' ? 'night' : 'day'
|
|
if (import.meta.client && typeof window !== 'undefined') {
|
|
localStorage.setItem('theme', currentTheme.value)
|
|
}
|
|
}
|
|
|
|
// Establecer tema específico
|
|
const setTheme = (theme: Theme) => {
|
|
currentTheme.value = theme
|
|
if (import.meta.client && typeof window !== 'undefined') {
|
|
localStorage.setItem('theme', theme)
|
|
}
|
|
}
|
|
|
|
return {
|
|
currentTheme: readonly(currentTheme),
|
|
isNight,
|
|
toggleTheme,
|
|
setTheme
|
|
}
|
|
}
|