Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisar el sistema de temas del mapa #195

Open
benjavicente opened this issue Feb 17, 2025 · 0 comments
Open

Revisar el sistema de temas del mapa #195

benjavicente opened this issue Feb 17, 2025 · 0 comments

Comments

@benjavicente
Copy link
Member

benjavicente commented Feb 17, 2025

Me llamó la atención como está implementado los temas.

export const useThemeObserver = (map: mapboxgl.Map | undefined) => {
const [theme, setTheme] = useState(
typeof window !== "undefined" && localStorage?.theme === "dark" ? "dark-v11" : "streets-v12",
);
const observer = useRef<MutationObserver | null>(null);
const onClassChange = useCallback(() => {
if (typeof window !== "undefined") {
const isDark = document.documentElement.classList.contains("dark");
setTheme(isDark ? "dark-v11" : "streets-v12");
map?.setStyle(`mapbox://styles/mapbox/${isDark ? "dark-v11" : "streets-v12"}?optimize=true`);
}
}, [map, setTheme]);
useEffect(() => {
observer.current = new MutationObserver(onClassChange);
observer.current.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
return () => {
observer.current?.disconnect();
};
}, [onClassChange]);
return [theme];
};

¿Por qué es el hook que dicta el estilo del mapa? ¿No debería ser al revés?

export default function DarkModeSelector() {
const [isDark, setIsDark] = useState(false);
const [isButtonDisabled, setIsButtonDisabled] = useState(false);
const switchTheme = () => {
document.documentElement.classList.toggle("dark", !isDark);
setIsDark(!isDark);
localStorage.theme = !isDark ? "dark" : "light";
setIsButtonDisabled(true);
setTimeout(() => setIsButtonDisabled(false), 700);
};
const setSystemTheme = () => {
const savedTheme = localStorage.theme;
if (savedTheme === "dark" || (!savedTheme && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
switchTheme();
}
};
useEffect(() => {
setSystemTheme();
}, []);
return (
<div className="flex items-center ml-auto">
<button
className="rounded-lg hover:bg-sky-700 p-1 text-xl"
onClick={() => switchTheme()}
disabled={isButtonDisabled} // Deshabilitar el botón
>
{isDark ? "🌙" : "🌞"}
</button>
</div>
);
}

Este botón tiene mucha responsabilidad, yo haría que solo cambie le tema y no se preocupe de sincronizarlo.


Yo lo que recomendaría es cambiarlo para que sea como estos selectores de 3 estados: tema del dispositivo, dark mode, light mode.

  1. Crear un contexto global del tema.

Hacer un contexto de theme, donde se exponga el estado del tema actual (que depende de la clase dark o del prefers-color-scheme si es que no está la clase), y una función que cambie el tema a light, dark o reiniciar(null) que permita modificar la clase que modifica el tema.

El botón para cambiar el estilo usuarioa esta función, y cualquier js que requiera el tema actual, lo podría sacar de este hook.

  1. Aprovechar el css para definir cambios de colores (esto no está probado)
:root:not(.dark) {
  --bg-color: white;
  --text-color: black;
}

@media (prefers-color-scheme: dark) {
  :root:not(.light) {
    --bg-color: black;
    --text-color: white;
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant