Mode sombre facile avec NextJS 13 et Tailwind
Published: 2023-04-14 20:34:28

## 🚀 Mode sombre facile avec NextJS 13 et Tailwind 🌗


`NextJS - TailwindCSS - ModeSombre - React - TypeScript - next-themes`

On suppose que vous maîtrisez déjà les bases de NextJS, React et Tailwind.

### Récap'
 Nous utilisons TypeScript dans cet exemple. Si vous n'êtes pas familier avec TypeScript, considérez ces explications sur le typage :

```tsx
// Exemple de typage de variables : 
let myString: string = 'Hello, world!'; // sera toujours une variable de type string
let myNumber: number = 42; // sera toujours un nombre
let myBoolean: boolean = true; // sera true ou false

// Définition d'un schéma grâce à `type`
type Person = {
  nom: string;
  age: number;
  estSympa?: boolean; // `?` indique que ce n'est pas obligatoire
};

// Utilisation de mon schema Person pour typer un objet
const Marie: Person = {
  nom: 'marie',
  age: 47,
 estSympa: true, // Sympa la Marie
};
const Johny: Person = {
  nom: 'johny',
  age: 25,
estSympa: false // désolé Johny
};
```


### Installation 

... 🐑 Revenons-en à nos moutons...

**Commencez par créer votre projet en utilisant** 

```bash
create-next-app@13 --tailwind NOM-DU-PROJET
```

Dans cet exemple, on n'utilise pas `src` ni `pages`, mais `app` pour notre router.

**On a installer  [Next Themes](https://github.com/pacocoursey/next-themes):** 

```bash
npm install next-themes
```


## 🎨 Configurer Tailwind avec next-theme 🎨


### Comment ça fonctionne ? 


Next-themes va ajouter` [data-theme="dark"]` / `[data-theme="light"] `au `documentElement` aka `html` tag.

 Il faut indiquer à **Tailwind d'observer cette donnée**.


### Configurer Tailwind

Dans `tailwind.config.js`, ajoutez darkMode:` ['class', '[data-theme="dark"]']`.

Le fichier de configuration devrait ressembler à quelque chose comme ça :

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ['class', '[data-theme="dark"]'],
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
    './app/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      backgroundImage: {
        'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
        'gradient-conic':
          'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
      },
    },
  },
  plugins: [],
}

```

## 🌐 Ajouter le Provider 🌐

On va devoir créer un provider pour englober tous notre code. Next-themes va automatiquement gérer tout le code contenu dans ce provider.
 
Comme NextJs13 est **server-first**, on va extraire un composant Provider qui servira de provider côté client.

Créez un  fichier`Providers.tsx`, on le crée dans `components` mais vous pouvez le mettree où bon vous semble.

Tout d'abord, ajoutez 'use client' **tout en haut** du fichier,

Puis importez le ThemeProvider de 'next-themes'


```tsx
'use client'

import React from "react"
import { ThemeProvider } from 'next-themes' // importer le provider


//{ children } : {children: React.ReactNode}
// on destructure props pour extraire children, puis indique le typage de props
function Providers({ children } : {children: React.ReactNode}) {
    return <ThemeProvider>{children}</ThemeProvider>
}

export default Providers
```

On n'a plus qu'à *wrapper* les children de notre `RootLayout` avec ce provider.

On ajoute quelques classes Tailwind pour s'assurer d'avoir du style à tester.

```tsx
import "./globals.css"
import React from "react"
import Providers from "@/components/Providers"

export const metadata = {
	title: "Create Next App",
	description: "Generated by create next app",
} // les Metadatas sont ajoutés ainsi depuis NextJS 13

export default function RootLayout({children}: {children: React.ReactNode}) {
	return (
		<html lang="en">
			<body className="bg-gray-100 dark:bg-slate-800">
				<Providers>{children}</Providers>
			</body>
		</html>
	)
}

```

Il faut maintenant que l'on ajoute un bouton pour switcher de thème

## 🔘 Toggle theme 🔘

Dans `@app/page`, soit notre *home page*, on va importer le hook de next-themes, et créer notre bouton qui aura une methode pour *switcher*   l'état de `theme`.
On peut également ajouter un titre pour s'assurer du changement de couleur :

```tsx
import { useTheme } from 'next-themes'

export default () => {
const { theme, setTheme } = useTheme()
return (
	<main>>
			<header className="fixed top-0 right-0 p-6">
				  <button
				    className="text-amber-500 dark:text-sky-200 text-4xl"
				    onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
				    {theme === "light" ? <ReactIcons.Sun /> : <ReactIcons.Moon />}
				  </button>
		</header>
		<h1 className="text-4xl text-dark dark:text-white">Ma couleur change</h1>
	</main>
	)
}

```


À ce point, le bouton devrait fonctionner et permettre de basculer entre les thèmes clair et sombre. 🌞🌚

Et voilà ! Vous avez maintenant implémenté un mode sombre avec NextJS 13 et Tailwind en utilisant next-themes. 
Vous pouvez maintenant explorer d'autres options de personnalisation et adapter le thème à vos préférences. 
N'hésitez pas à expérimenter avec différentes couleurs et styles pour créer une expérience utilisateur unique et agréable. 🎉🚀
N'hésitez pas non plus à partager votre expérience ou vos astuces en commentaire 👇.