Cours JavaScript et React · Module 7: Styles et animations
Frameworks de composants - Construire des interfaces galactiques avec shadcn/ui, Material-UI et Chakra UI
Dans cette leçon7
Lors de notre voyage à travers le cosmos des technologies frontend, les frameworks de composants sont comme des stations spatiales avancées : des structures complètes et prêtes à l'emploi que nous pouvons peupler de notre propre logique et adapter à nos besoins. Dans ce module, nous explorerons trois frameworks de composants populaires : shadcn/ui, Material-UI et Chakra UI, qui te permettent de créer des interfaces utilisateur cohérentes, élégantes et fonctionnelles.
Pourquoi utiliser des frameworks de composants ?
Imagine que tu dois construire un vaisseau avancé. Tu peux soit fabriquer chaque pièce à partir de zéro, soit utiliser des composants tout prêts, testés et optimisés. Les frameworks de composants t'offrent cette seconde option, avec :
- Des composants UI prêts à l'emploi - boutons, formulaires, cartes, modales, tableaux, et bien plus
- Un design cohérent - tous les éléments s'accordent visuellement et fonctionnellement
- L'accessibilité - les composants sont conçus en pensant à l'accessibilité pour tous les utilisateurs
- Un gain de temps - tu n'as pas besoin de réinventer la roue à chaque fois
- Une maintenance facile - mises à jour, corrections de bugs et nouvelles fonctionnalités sont fournies par la communauté
shadcn/ui - Une approche moderne et non conventionnelle des bibliothèques de composants
Qu'est-ce que shadcn/ui ?
shadcn/ui propose une approche unique des bibliothèques de composants. Contrairement aux frameworks traditionnels, shadcn/ui n'est pas une bibliothèque que tu installes comme dépendance. C'est plutôt une collection de composants que tu copies directement dans ton projet. Cela te donne un contrôle total sur le code et la possibilité de modifier les composants sans restriction.
Installer et configurer shadcn/ui
Pour commencer ton aventure avec shadcn/ui, suis ces étapes :
1# Initialiser shadcn/ui dans le projet
2npx shadcn-ui@latest initPendant l'initialisation, tu répondras à quelques questions sur la configuration (styles, couleurs, etc.). Tu pourras ensuite ajouter les composants choisis :
1# Ajout du composant bouton
2npx shadcn-ui@latest add button
3
4# Ajout d'autres composants
5npx shadcn-ui@latest add card
6npx shadcn-ui@latest add dialogExemple d'utilisation des composants shadcn/ui
1import { Button } from "@/components/ui/button";
2import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
3
4function MissionControl() {
5 return (
6 <Card>
7 <CardHeader>
8 <CardTitle>Panneau de contrôle de mission</CardTitle>
9 <CardDescription>Gère ton expédition cosmique</CardDescription>
10 </CardHeader>
11 <CardContent>
12 <p>État du système : tous les systèmes fonctionnent correctement</p>
13 </CardContent>
14 <CardFooter>
15 <Button variant="outline" className="mr-2">Annuler</Button>
16 <Button>Démarrer la mission</Button>
17 </CardFooter>
18 </Card>
19 );
20}Avantages de shadcn/ui
- Contrôle total - les composants sont dans ton code, tu peux les modifier librement
- Pas de dépendances - pas besoin de s'inquiéter des conflits de versions ou des problèmes de mise à jour
- Design minimaliste - une apparence moderne et épurée des composants
- Personnalisation facile - basé sur Tailwind CSS pour ajuster facilement l'apparence
- Prise en charge du mode sombre - support intégré du mode sombre
Material-UI - Des interfaces à la Google
Qu'est-ce que Material-UI ?
Material-UI (MUI) est une bibliothèque de composants React populaire qui implémente les principes du Material Design créés par Google. C'est comme construire un vaisseau d'après des plans éprouvés de la NASA : tu obtiens une interface intuitive, cohérente et familière pour les utilisateurs du monde entier.
Installer Material-UI
1# Installation des paquets MUI de base
2npm install @mui/material @emotion/react @emotion/styled
3
4# En option, pour les icônes
5npm install @mui/icons-materialExemple d'utilisation de Material-UI
1import { Button, Card, CardActions, CardContent, Typography } from '@mui/material';
2import RocketLaunchIcon from '@mui/icons-material/RocketLaunch';
3
4function SpaceMission() {
5 return (
6 <Card sx={{ maxWidth: 345, m: 2 }}>
7 <CardContent>
8 <Typography gutterBottom variant="h5" component="div">
9 Mission vers Mars
10 </Typography>
11 <Typography variant="body2" color="text.secondary">
12 Prépare-toi à une aventure cosmique. La mission vers Mars exige du courage,
13 des connaissances et une préparation à l'inconnu.
14 </Typography>
15 </CardContent>
16 <CardActions>
17 <Button size="small" color="primary">Détails</Button>
18 <Button
19 size="small"
20 variant="contained"
21 color="primary"
22 startIcon={<RocketLaunchIcon />}
23 >
24 Démarrer
25 </Button>
26 </CardActions>
27 </Card>
28 );
29}Theming dans Material-UI
Material-UI propose un système de thèmes avancé qui te permet de personnaliser les couleurs, la typographie, l'arrondi des bordures et bien d'autres aspects :
1import { createTheme, ThemeProvider } from '@mui/material/styles';
2
3// Création d'un thème personnalisé
4const theme = createTheme({
5 palette: {
6 primary: {
7 main: '#2196f3', // bleu cosmique
8 },
9 secondary: {
10 main: '#f50057', // rose stellaire
11 },
12 },
13 typography: {
14 fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
15 h1: {
16 fontSize: '2.5rem',
17 fontWeight: 500,
18 },
19 },
20 shape: {
21 borderRadius: 8,
22 },
23});
24
25// Application du thème
26function App() {
27 return (
28 <ThemeProvider theme={theme}>
29 {/* Place tes composants ici */}
30 </ThemeProvider>
31 );
32}Avantages de Material-UI
- Bibliothèque de composants riche - des simples boutons aux composants de tableaux avancés
- Design éprouvé - implémentation des principes du Material Design
- Système de thèmes avancé - personnalisation facile de toute l'apparence de l'application
- Excellente documentation - exemples détaillés et explications
- Grande communauté - facile de trouver de l'aide et des solutions aux problèmes
Chakra UI - Simplicité et accessibilité
Qu'est-ce que Chakra UI ?
Chakra UI est une bibliothèque de composants moderne qui privilégie la simplicité, la modularité et l'accessibilité. C'est comme construire un véhicule spatial léger et agile, à la fois sûr et facile à piloter pour chaque membre d'équipage, quelles que soient ses capacités.
Installer Chakra UI
1# Installation de Chakra UI
2npm i @chakra-ui/react @emotion/react @emotion/styled framer-motionConfigurer Chakra UI
1// Dans le fichier principal de l'application
2import { ChakraProvider } from '@chakra-ui/react';
3
4function App() {
5 return (
6 <ChakraProvider>
7 {/* Place tes composants ici */}
8 </ChakraProvider>
9 );
10}Exemple d'utilisation de Chakra UI
1import { Box, Button, Heading, Stack, Text, useColorModeValue } from '@chakra-ui/react';
2
3function SpaceStation() {
4 // Couleurs dynamiques selon le mode (clair/sombre)
5 const bgColor = useColorModeValue('blue.50', 'blue.900');
6 const textColor = useColorModeValue('gray.800', 'white');
7
8 return (
9 <Box
10 p={5}
11 shadow="md"
12 borderWidth="1px"
13 borderRadius="md"
14 bg={bgColor}
15 color={textColor}
16 >
17 <Heading size="md" mb={2}>Station spatiale internationale</Heading>
18 <Text mb={4}>
19 La maison orbitale des astronautes et scientifiques du monde entier.
20 </Text>
21 <Stack direction="row" spacing={4}>
22 <Button colorScheme="blue" variant="outline">
23 Informations
24 </Button>
25 <Button colorScheme="blue">
26 Visiter
27 </Button>
28 </Stack>
29 </Box>
30 );
31}Styles et responsivité dans Chakra UI
Chakra UI offre une manière intuitive de définir des styles responsives :
1<Stack
2 direction={["column", "row"]} // colonne sur petits écrans, ligne sur écrans plus grands
3 spacing={[2, 4, 6]} // espacement différent selon les breakpoints
4>
5 <Box
6 p={[2, 4, 6]} // padding qui augmente avec la taille de l'écran
7 width={["100%", "50%", "33%"]} // largeur selon la taille de l'écran
8 bg="blue.500"
9 >
10 Panel 1
11 </Box>
12 <Box
13 p={[2, 4, 6]}
14 width={["100%", "50%", "33%"]}
15 bg="green.500"
16 >
17 Panel 2
18 </Box>
19 <Box
20 p={[2, 4, 6]}
21 width={["100%", "50%", "33%"]}
22 bg="purple.500"
23 display={["none", "block"]} // masqué sur les plus petits écrans
24 >
25 Panel 3
26 </Box>
27</Stack>Avantages de Chakra UI
- Facilité d'utilisation - API intuitive et structure de composants cohérente
- Accessibilité - composants conformes aux normes WCAG et WAI-ARIA
- Responsivité - définition facile des styles pour différents breakpoints
- Mode sombre/clair - prise en charge intégrée du changement de thème
- Personnalisation - adaptation facile du système de design aux besoins du projet
Comparer les frameworks - Lequel choisir pour ta mission cosmique ?
shadcn/ui
Idéal pour :
- Les projets où tu veux un contrôle total sur le code des composants
- Les développeurs qui utilisent Tailwind CSS
- Les applications nécessitant un design unique mais reposant sur des fondations solides
Inconvénients potentiels :
- Copier le code peut conduire à une base de code plus volumineuse
- Bibliothèque de composants plus restreinte que MUI et Chakra
Material-UI
Idéal pour :
- Les projets d'entreprise et corporatifs
- Les applications devant rester cohérentes avec le design Google
- Les situations nécessitant une riche bibliothèque de composants avancés
Inconvénients potentiels :
- API plus complexe dans certains cas
- La stylisation nécessite de connaître le système de thèmes MUI
- Taille de paquet plus importante
Chakra UI
Idéal pour :
- Les projets où l'accessibilité est une priorité
- Les développeurs qui apprécient la simplicité et une API intuitive
- Les applications nécessitant un prototypage rapide et une personnalisation facile
Inconvénients potentiels :
- Moins de composants avancés que MUI
- Communauté plus petite que celle de MUI
Intégrer les frameworks de composants avec d'autres technologies
Tous les frameworks abordés peuvent être combinés avec d'autres technologies :
- Formulaires - intégration avec React Hook Form ou Formik
- Gestion d'état - coopération avec Redux, MobX ou React Query
- Routing - compatibilité avec React Router ou Next.js
- Animations - extension avec Framer Motion ou React Spring
Exercice pratique : Crée un tableau de bord de mission spatiale
Choisis l'un des frameworks abordés (shadcn/ui, Material-UI ou Chakra UI) et crée un tableau de bord de contrôle de mission spatiale contenant :
- Une navigation principale (par exemple un menu latéral ou une barre supérieure)
- Des cartes de statut des systèmes du vaisseau
- Un graphique de consommation de carburant (tu peux utiliser une bibliothèque de graphiques compatible avec le framework choisi)
- Un formulaire de paramètres de mission avec différents types de champs
Remember about:
- La responsivité (le tableau de bord doit fonctionner sur différents appareils)
- L'accessibilité (les composants doivent être utilisés selon les recommandations d'accessibilité)
- Un design cohérent (utilise le système de thèmes du framework choisi)
Cet exercice t'aidera à comprendre comment les frameworks de composants peuvent accélérer la création d'interfaces complexes et à décider lequel correspond le mieux à ton style de travail et aux besoins de ton projet.
Code de cette leçon : App.jsx
1import React, { useState } from 'react';
2
3// Démonstration des styles en ligne dans React
4function InlineStylesDemo() {
5 const [isHovered, setIsHovered] = useState(null);
6 const [theme, setTheme] = useState('dark');
7
8 // Styles sous forme d'objets JavaScript
9 const themes = {
10 dark: {
11 background: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)',
12 text: '#ffffff',
13 accent: '#00d4ff',
14 card: 'rgba(255, 255, 255, 0.05)',
15 },
16 light: {
17 background: 'linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%)',
18 text: '#1a1a2e',
19 accent: '#667eea',
20 card: 'rgba(0, 0, 0, 0.05)',
21 },
22 };
23
24 const currentTheme = themes[theme];
25
26 // Styles du conteneur
27 const containerStyle = {
28 minHeight: '100vh',
29 background: currentTheme.background,
30 padding: '30px',
31 fontFamily: "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif",
32 color: currentTheme.text,
33 transition: 'all 0.5s ease',
34 };
35
36 const headerStyle = {
37 textAlign: 'center',
38 marginBottom: '40px',
39 };
40
41 const titleStyle = {
42 fontSize: '2.5em',
43 color: currentTheme.accent,
44 marginBottom: '10px',
45 };
46
47 // Fonction générant des styles dynamiques pour la carte
48 const getCardStyle = (index) => ({
49 background: currentTheme.card,
50 borderRadius: '15px',
51 padding: '25px',
52 marginBottom: '20px',
53 border: `2px solid ${isHovered === index ? currentTheme.accent : 'transparent'}`,
54 transform: isHovered === index ? 'translateY(-5px)' : 'translateY(0)',
55 boxShadow: isHovered === index
56 ? `0 10px 30px ${currentTheme.accent}40`
57 : 'none',
58 transition: 'all 0.3s ease',
59 cursor: 'pointer',
60 });
61
62 const buttonStyle = (isActive) => ({
63 padding: '12px 24px',
64 margin: '0 10px',
65 border: `2px solid ${currentTheme.accent}`,
66 borderRadius: '8px',
67 background: isActive ? currentTheme.accent : 'transparent',
68 color: isActive ? '#000' : currentTheme.accent,
69 fontWeight: 'bold',
70 cursor: 'pointer',
71 transition: 'all 0.3s ease',
72 });
73
74 const features = [
75 {
76 title: 'Valeurs dynamiques',
77 description: "Les styles peuvent être calculés à partir des props, du state ou d'autres données",
78 },
79 {
80 title: 'Aucun conflit',
81 description: 'Les styles en ligne sont automatiquement limités au composant',
82 },
83 {
84 title: 'Calculs au runtime',
85 description: "Possibilité d'utiliser des expressions JavaScript pour générer des styles",
86 },
87 {
88 title: 'Conditions simples',
89 description: 'Ajout simple de styles conditionnels sans classes supplémentaires',
90 },
91 ];
92
93 return (
94 <div style={containerStyle}>
95 <header style={headerStyle}>
96 <h1 style={titleStyle}>Inline Styles w React</h1>
97 <p style={{ color: currentTheme.text, opacity: 0.7 }}>
98 Stylisation dynamique avec des objets JavaScript
99 </p>
100 </header>
101
102 {/* Sélecteur de thème */}
103 <div style={{ textAlign: 'center', marginBottom: '40px' }}>
104 <button
105 style={buttonStyle(theme === 'dark')}
106 onClick={() => setTheme('dark')}
107 >
108 Dark
109 </button>
110 <button
111 style={buttonStyle(theme === 'light')}
112 onClick={() => setTheme('light')}
113 >
114 Light
115 </button>
116 </div>
117
118 {/* Cartes avec des styles dynamiques */}
119 <div style={{ maxWidth: '800px', margin: '0 auto' }}>
120 {features.map((feature, index) => (
121 <div
122 key={index}
123 style={getCardStyle(index)}
124 onMouseEnter={() => setIsHovered(index)}
125 onMouseLeave={() => setIsHovered(null)}
126 >
127 <h3 style={{
128 color: currentTheme.accent,
129 marginBottom: '10px',
130 fontSize: '1.3em'
131 }}>
132 {feature.title}
133 </h3>
134 <p style={{
135 lineHeight: 1.6,
136 opacity: 0.9
137 }}>
138 {feature.description}
139 </p>
140 </div>
141 ))}
142 </div>
143
144 {/* Exemple de code */}
145 <div style={{
146 maxWidth: '800px',
147 margin: '40px auto',
148 background: currentTheme.card,
149 borderRadius: '15px',
150 padding: '25px',
151 border: `1px solid ${currentTheme.accent}30`,
152 }}>
153 <h3 style={{ color: currentTheme.accent, marginBottom: '15px' }}>
154 Exemple de syntaxe :
155 </h3>
156 <pre style={{
157 background: 'rgba(0,0,0,0.3)',
158 padding: '15px',
159 borderRadius: '8px',
160 overflow: 'auto',
161 fontSize: '14px',
162 }}>
163{`const style = {
164 backgroundColor: isActive ? 'blue' : 'gray',
165 padding: \`\${spacing}px\`,
166 transform: \`scale(\${scale})\`
167};
168
169<div style={style}>...</div>`}
170 </pre>
171 </div>
172
173 <footer style={{
174 textAlign: 'center',
175 marginTop: '40px',
176 opacity: 0.7
177 }}>
178 <p>Les styles en ligne sont parfaits pour les styles dynamiques et calculés</p>
179 </footer>
180 </div>
181 );
182}
183
184export default InlineStylesDemo;Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quelle est la meilleure façon de surcharger les styles d'une bibliothèque CSS dans React sans utiliser !important ?
Tâches pratiques dans le jeu
- Tri vertical
Ordonne les sélecteurs CSS de la spécificité la plus faible à la plus forte :