Cours JavaScript et React · Module 7: Styles et animations

Frameworks de composants - Construire des interfaces galactiques avec shadcn/ui, Material-UI et Chakra UI

8 min de lecture
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 :

  1. Des composants UI prêts à l'emploi - boutons, formulaires, cartes, modales, tableaux, et bien plus
  2. Un design cohérent - tous les éléments s'accordent visuellement et fonctionnellement
  3. L'accessibilité - les composants sont conçus en pensant à l'accessibilité pour tous les utilisateurs
  4. Un gain de temps - tu n'as pas besoin de réinventer la roue à chaque fois
  5. 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 init

Pendant 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 dialog

Exemple 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-material

Exemple 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-motion

Configurer 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 :

  1. Une navigation principale (par exemple un menu latéral ou une barre supérieure)
  2. Des cartes de statut des systèmes du vaisseau
  3. Un graphique de consommation de carburant (tu peux utiliser une bibliothèque de graphiques compatible avec le framework choisi)
  4. 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. 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 :

Articles utiles