Cookies
This website uses cookies to improve the user experience, more information on the legal information path.
Notas
0
anos
0
meses
0
días
0
horas
0
minus
0
segus
Sáb.16Mar.20:16
Esta é a imaxe de fondo
2

Tema escuro con Nextjs

ven., 3 de feb. de 2023

Hai moitas formas de facer a xestión de temas de estilos en React e Nextjs, pero todas elas pasan por ter un array/obxeto con todos os estilos de cada un dos distintos temas, tamén outra das formas é usar variables de css ou scss estas últimas están en cada vez en máis deshuso. Eu, en particular vou usar variables de css e fixar un tema por defecto no meu _document . Por que aquí ?

Por que _document execútase en servidor non como _app que o fai en cliente e se usas un useEffect para setear o teu tema por defecto ou detectar o que ten o usuario no seu sistema operativo, no tempo que se tarda en facer esta comprobación e engadilo, pode darse un parpadeo nos estilos da paxina. Iso pode resultar estraño.

Eu fíxeno así:

1 - Variables do css

globals.css

:root {
/* commons */
--white-color: 255, 255, 255;
--color-available-arrow: 95, 91 98;
...;
}
[data-theme='dark'] {
--blog-nav: 48, 41, 51;
--blog-header: 53, 45, 55;
...;
}
[data-theme='light'] {
--blog-nav: 204, 202, 219;
--blog-header: 255, 255, 255;
...;
}

2 - Fixar tema por defecto

_document.tsx

const Document = (props: Props) => {
return (
<Html lang={props.__NEXT_DATA__.locale} data-theme="light">
)
}

3 - Custom hook pra cambiar o tema

useDarkMode.ts

import React from 'react';
const scheme = {
light: 'light' as const,
dark: 'dark' as const,
};
const useDarkMode = (): { theme: null | 'dark' | 'light'; toggleTheme: () => void; scheme: typeof scheme } => {
const [theme, setTheme] = React.useState<null | 'dark' | 'light'>(null);
React.useEffect(() => {
if (typeof window !== 'undefined' && window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handler = (event: MediaQueryListEvent) => {
setTheme(event.matches ? scheme.dark : scheme.light);
};
mediaQuery.addEventListener('change', handler);
return () => mediaQuery.removeEventListener('change', handler);
}
}, []);
React.useEffect(() => {
if (typeof window !== 'undefined' && theme) {
document.documentElement.setAttribute('data-theme', theme);
}
}, [theme]);
const toggleTheme = () => {
setTheme(theme === scheme.dark ? scheme.light : scheme.dark);
};
return { theme, scheme, toggleTheme };
};
export default useDarkMode;

4 - Usar o hook

settings.tsx

const Content = () => {
const { formatMessage: f } = useIntl();
const {
theme,
scheme: { dark },
toggleTheme,
} = useDarkMode();
return (
<div className={styles.container}>
<section className={styles.confg}>
<IconWithName
icon="/theme.png"
alt={f({ id: 'settings.langAlt' })}
name={f({ id: theme === dark ? 'settings.dark' : 'settings.light' })}
onClick={toggleTheme}
/>
</section>
<section className={styles.confg}></section>
</div>
);
};

Para facer a proba en vivo, podes cambiar o tema no teu sistema operativo e verás que o meu sitio web actualízase automaticamente ou tamén podes ir ao meu pagina de configuración e cambiar o tema.

Todo o código no meu repositorio de github, se che gusta este proxecto, ou se o contido axudouche en algo podes recompensarme cunha ⭐️, Grazas!