Feature: Mejorar UX del tema y persistencia
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 55s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 55s
- Mover botón editar al lado del nombre (siempre visible, sutil) - Quitar efecto hover del header - Detectar tema del sistema operativo automáticamente - Actualizar theme-color dinámicamente (azul cielo día / oscuro noche) - Usar cookies para persistir tema y filtros (1 año) - Sincronizar filtros de apps con cookies
This commit is contained in:
@@ -6,23 +6,43 @@
|
||||
export type Theme = 'day' | 'night'
|
||||
|
||||
export const useTheme = () => {
|
||||
// Estado del tema con persistencia
|
||||
const themeCookie = useCookie<Theme>('theme', {
|
||||
maxAge: 60 * 60 * 24 * 365, // 1 año
|
||||
sameSite: 'lax'
|
||||
})
|
||||
|
||||
// Estado del tema con persistencia en cookies
|
||||
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'
|
||||
// Primero intentar obtener de la cookie
|
||||
if (themeCookie.value) {
|
||||
return themeCookie.value
|
||||
}
|
||||
|
||||
// Si no hay cookie, detectar preferencia del sistema
|
||||
if (import.meta.client && typeof window !== 'undefined') {
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const systemTheme = prefersDark ? 'night' : 'day'
|
||||
themeCookie.value = systemTheme
|
||||
return systemTheme
|
||||
}
|
||||
|
||||
return 'day'
|
||||
})
|
||||
|
||||
// Computed para saber si es modo noche
|
||||
const isNight = computed(() => currentTheme.value === 'night')
|
||||
|
||||
// Función para actualizar theme-color meta tag
|
||||
const updateThemeColor = (theme: Theme) => {
|
||||
if (import.meta.client && typeof window !== 'undefined') {
|
||||
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
|
||||
const color = theme === 'night' ? '#0B1026' : '#87CEEB' // Cielo nocturno / Cielo diurno
|
||||
if (metaThemeColor) {
|
||||
metaThemeColor.setAttribute('content', color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Función para aplicar la clase dark al HTML
|
||||
const applyThemeClass = (theme: Theme) => {
|
||||
if (import.meta.client && typeof window !== 'undefined') {
|
||||
@@ -34,6 +54,7 @@ export const useTheme = () => {
|
||||
html.classList.add('light')
|
||||
html.classList.remove('dark')
|
||||
}
|
||||
updateThemeColor(theme)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,23 +67,18 @@ export const useTheme = () => {
|
||||
// Sincronizar clase cuando cambie el tema
|
||||
watch(currentTheme, (newTheme) => {
|
||||
applyThemeClass(newTheme)
|
||||
themeCookie.value = 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 {
|
||||
|
||||
Reference in New Issue
Block a user