Chapitre 8

Interaction de l'interface

Maîtrisez la conception de composants UI, les modèles d’interaction, le design responsive et les principes d’expérience utilisateur pour créer d’excellentes interfaces utilisateur.

Utiliser Sequential Thinking pour apprendre les interactions d’interface pilotées par l’IA

L’application de l’IA dans les interactions d’interface implique plusieurs niveaux, en utilisantMéthodes de pensée structuréePeut vous aider à maîtriser systématiquement :

1
Aperçu des bases de la conception d’interface
Comprendre rapidement les Design Tokens, le système de thèmes et l’architecture des composants
2
Développement de composants assisté par IA
Génération de code de composants, optimisation du style, sélection de bibliothèque de composants
3
Implémentation d’interactions assistée par IA
Génération de code de gestion d’état, validation de formulaires, effets d’animation
4
Conception réactive et accessibilité assistées par l’IA
Génération de mises en page responsives, vérifications d’accessibilité, validation de conformité WCAG
5
Optimisation des performances pilotée par l’IA
Analyse des goulots d’étranglement des performances, génération de plans d’optimisation, surveillance des performances

Design System

Un design system est un ensemble de standards de conception réutilisables et de bibliothèques de composants qui garantissent la cohérence et la maintenabilité du produit.

Design Tokens Jetons de conception

Les Design Tokens sont la plus petite unité de décision de design, et les variables CSS permettent de gérer de manière centralisée des éléments de design comme les couleurs, les espacements et les polices.

Système de couleurs (espace colorimétrique OKLCH)

L’utilisation de l’espace colorimétrique OKLCH permet de mieux gérer le contraste des couleurs et le changement de thème. Définitions des couleurs dans le projet :

:root {
  --primary: oklch(0.7 0.15 200);
  --background: oklch(0.09 0 0);
  --foreground: oklch(0.98 0 0);
  --border: oklch(0.25 0 0);
  /* ... plus de variables de couleur */
}

Système d'espacement

Échelle d’espacement par défaut de Tailwind (base 4 px) : 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64

0
0px
1
4px
2
8px
4
16px
8
32px
12
48px
16
64px
24
96px

Système de polices

Famille de polices
--font-sans: 'Geist'
--font-mono: 'Geist Mono'
Rapport de taille de police
xs: 0.75rem, sm: 0.875rem, base: 1rem, lg: 1.125rem, xl: 1.25rem, 2xl: 1.5rem

Système de coins arrondis

--radius-sm: calc(var(--radius) - 4px)
--radius-md: calc(var(--radius) - 2px)
--radius-lg: var(--radius)
--radius-xl: calc(var(--radius) + 4px)

Système de thèmes

Implémentation du mode sombre

Utiliser next-themes Implémenter le changement de thème :

// app/layout.tsx
import { ThemeProvider } from '@/components/theme-provider'

export default function RootLayout({ children }) {
  return (
    <ThemeProvider
      attribute="class"
      defaultTheme="system"
      enableSystem
      disableTransitionOnChange
    >
      {children}
    </ThemeProvider>
  )
}

Changement de thème avec des variables CSS

Réussi .dark Variable de thème de bascule de classe :

.dark {
  --background: oklch(0.09 0 0);
  --foreground: oklch(0.98 0 0);
  /* Toutes les variables de couleur en mode sombre */
}

Architecture des composants

Méthodologie du design atomique

Atome
Boutons, champs de saisie, libellés
Button, Input
Molécule
Champs de recherche, champs de formulaire
SearchBox, FormField
Organisation
Barre de navigation, formulaires, liste de cartes
Header, Form, CardList
Modèle
Structure de la mise en page
DashboardLayout
Page
Interface utilisateur finale
DashboardPage

Système de variantes de composants (CVA)

Utiliser class-variance-authority Gérer les variantes de composants :

import { cva, type VariantProps } from 'class-variance-authority'

const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md',
  {
    variants: {
      variant: {
        default: 'bg-primary text-primary-foreground',
        destructive: 'bg-destructive text-destructive-foreground',
        outline: 'border border-input',
      },
      size: {
        default: 'h-10 px-4 py-2',
        sm: 'h-9 rounded-md px-3',
        lg: 'h-11 rounded-md px-8',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'default',
    },
  }
)

Bonnes pratiques de l’IA dans les interactions d’interface

Utiliser l’IA pour améliorer l’efficacité du développement UI front-end, avec des pratiques d’assistance par IA tout au long du flux de travail, de la conception des composants à l’optimisation des performances.

Développement de composants assisté par IA

Utiliser l’IA pour générer du code de composants

Décrivez les exigences du composant à l'IA et laissez-la générer un composant React/Next.js complet :

Modèle de prompt :

J’ai besoin de créer un composant de carte utilisateur avec les fonctionnalités suivantes :
1. Afficher l’avatar, le nom et l’e-mail de l’utilisateur
2. Prendre en charge le clic pour afficher les détails
3. Utiliser les styles Tailwind CSS
4. Prendre en charge le mode sombre
5. Design adaptatif (mobile et ordinateur)
6. Utiliser TypeScript
7. Suivre les directives de conception shadcn/ui

Veuillez générer le code complet du composant, y compris :
- Définitions de types
- Interface Props
- Noms de classes de style
- Points de rupture responsifs
- Attributs d’accessibilité

Exemple de composant généré par IA

// components/user-card.tsx
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Card, CardContent } from '@/components/ui/card'

interface UserCardProps {
  name: string
  email: string
  avatar?: string
  onClick?: () => void
}

export function UserCard({ name, email, avatar, onClick }: UserCardProps) {
  const initials = name
    .split(' ')
    .map(n => n[0])
    .join('')
    .toUpperCase()
    .slice(0, 2)

  return (
    <Card 
      className="cursor-pointer transition-shadow hover:shadow-md"
      onClick={onClick}
      role="button"
      tabIndex={0}
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') {
          onClick?.()
        }
      }}
    >
      <CardContent className="p-4 flex items-center gap-4">
        <Avatar className="h-12 w-12">
          <AvatarImage src={avatar} alt={name} />
          <AvatarFallback>{initials}</AvatarFallback>
        </Avatar>
        <div className="flex-1 min-w-0">
          <h3 className="font-semibold text-foreground truncate">{name}</h3>
          <p className="text-sm text-muted-foreground truncate">{email}</p>
        </div>
      </CardContent>
    </Card>
  )
}

Optimisation du style assistée par IA

Utilisez l’IA pour optimiser les noms de classes Tailwind CSS et générer des styles plus concis et plus efficaces :

Invite :

Optimisez les noms de classes Tailwind CSS suivants afin de les rendre plus concis et plus efficaces :

Code actuel :
<div className="flex flex-row items-center justify-between p-4 m-2 bg-white dark:bg-gray-800 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200">

Veuillez :
1. Fusionner les classes en double
2. Utiliser une syntaxe plus concise
3. Garantir la prise en charge du responsive et du mode sombre
4. Conserver le même rendu visuel

Sélection d’une bibliothèque de composants assistée par l’IA

Prompt :

Je dois choisir une bibliothèque de composants pour un projet Next.js 16 + TypeScript. Les exigences sont les suivantes :
1. Prise en charge du mode sombre
2. Forte capacité de personnalisation
3. Sécurité typée
4. Excellentes performances
5. Communauté active

Veuillez comparer les bibliothèques de composants suivantes :
- shadcn/ui
- Material-UI (MUI)
- Ant Design
- Chakra UI

Donnez une recommandation et les raisons, puis expliquez comment l’intégrer dans un projet Next.js.

Conception de composants UI

La composantisation est une idée centrale du développement front-end moderne, qui consiste à construire des interfaces utilisateur complexes en combinant des composants réutilisables.

Configuration avancée de Tailwind CSS

Structure du fichier de configuration

// tailwind.config.ts
import type { Config } from 'tailwindcss'

const config: Config = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        background: 'var(--background)',
        foreground: 'var(--foreground)',
        // Utiliser des variables CSS
      },
      borderRadius: {
        lg: 'var(--radius)',
        md: 'calc(var(--radius) - 2px)',
        sm: 'calc(var(--radius) - 4px)',
      },
    },
  },
  plugins: [],
}

export default config

Classe d’outil personnalisée

// Ajouter des classes utilitaires personnalisées dans globals.css
@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
  
  .scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  
  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }
}

Personnalisation des points de rupture responsive

// tailwind.config.ts
theme: {
  screens: {
    'xs': '475px',
    'sm': '640px',
    'md': '768px',
    'lg': '1024px',
    'xl': '1280px',
    '2xl': '1536px',
  },
}

Paramètres du mode sombre

Utiliser dark: Préfixe :

<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
  {/* Contenu */}
</div>

Comparaison et sélection de bibliothèques de composants

Bibliothèque de composantsCaractéristiquesScénarios d’application
shadcn/uiCopiable-collable, entièrement contrôlable, basé sur Radix UIProjets hautement personnalisés, projets Next.js
Material-UIComposants riches, documentation complète, Material DesignApplications d’entreprise, prototypage rapide
Ant DesignComposants de niveau entreprise, applications front-office/back-office, documentation en chinoisSystèmes de back-office, plateformes d’administration
Chakra UISimple, modulaire, compatible TypeScriptApplications Web modernes, projets nécessitant de la flexibilité

Mode interactif

Un bon design d’interaction rend les opérations des utilisateurs plus fluides et plus intuitives. Maîtrisez la gestion d’état, le traitement des formulaires et les techniques d’animation.

Guide détaillé de la gestion d’état

Bonnes pratiques de useState

// Utilisez des mises à jour fonctionnelles pour éviter les problèmes de fermeture
const [count, setCount] = useState(0)

// Correct : utiliser des mises à jour fonctionnelles
setCount(prev => prev + 1)

// À éviter : dépendre directement de l'état
setCount(count + 1) // peut être inexact

// Utiliser useReducer pour un état complexe
const [state, dispatch] = useReducer(reducer, initialState)

Bonnes pratiques de gestion des formulaires

Exemple de validation de formulaire

// Exemple complet de composant de formulaire
'use client'

import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form'

const formSchema = z.object({
  username: z.string().min(2, 'Le nom d’utilisateur doit comporter au moins 2 caractères'),
  email: z.string().email('Adresse e-mail invalide'),
})

export function UserForm() {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      username: '',
      email: '',
    },
  })

  function onSubmit(values: z.infer<typeof formSchema>) {
    console.log(values)
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
        <FormField
          control={form.control}
          name="username"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Nom d’utilisateur</FormLabel>
              <FormControl>
                <Input {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">Envoyer</Button>
      </form>
    </Form>
  )
}

Optimisation des performances des formulaires

  • Utiliser mode: 'onBlur' Réduire le nombre de vérifications
  • Utilisation de formulaires complexes useFieldArray Gérer les champs dynamiques
  • Utilisation de formulaires volumineux shouldUnregister Optimiser la mémoire

Système de retour des utilisateurs

Notifications toast

import { toast } from 'sonner'

toast.success('Opération réussie')
toast.error('Échec de l’opération')
toast.info('Information')

État de chargement

// Chargement du squelette
<Skeleton className="h-4 w-[250px]" />

// Spinner
<Loader2 className="h-4 w-4 animate-spin" />

Animations et transitions

Animations Tailwind

// Utiliser tailwindcss-animate
<div className="animate-in fade-in slide-in-from-top-4">
  {/* Contenu */}
</div>

// Classes d'animation courantes
animate-in          // Animation d'entrée
animate-out         // Animation de sortie
fade-in             // Fondu entrant
slide-in-from-top  // Glisser depuis le haut
duration-300        // Durée

Considérations de performance

  • Utiliser transform et opacity Déclencher l’accélération GPU
  • Éviter les animations widthheight attributs tels que
  • Utiliser will-change Conseils pour optimiser le navigateur

Conception responsive

Veillez à ce que l’interface offre une bonne expérience utilisateur sur différents appareils. Adoptez une stratégie mobile-first et utilisez des techniques de mise en page flexibles.

Stratégie mobile-first

Principes de conception mobile

  • Concevoir d’abord pour le mobile, puis améliorer progressivement l’expérience sur ordinateur
  • Simplifier les interactions mobiles et réduire le nombre d’étapes
  • Optimiser la taille des cibles tactiles (minimum 44x44px)
  • Réduire le contenu mobile et mettre en avant les fonctionnalités principales

Modèles de navigation mobile

Navigation inférieure
Convient au point d’entrée des principales fonctionnalités
Menu hamburger
Convient aux fonctionnalités secondaires
Onglet
Convient à la classification de contenu

Techniques de mise en page

Utilisation avancée de Flexbox

// Flexbox responsive
<div className="flex flex-col md:flex-row gap-4">
  <div className="flex-1">Contenu 1</div>
  <div className="flex-1">Contenu 2</div>
</div>

// Alignement
<div className="flex items-center justify-between">
  {/* Centré verticalement, réparti horizontalement entre les bords */}
</div>

Stratégie de point d’arrêt

sm
≥640px
Appareils à petit écran
md
≥768px
Tablette
lg
≥1024px
Ordinateur portable
xl
≥1280px
Bureau
2xl
≥1536px
Grand écran
// Bonnes pratiques pour les points de rupture
// Mobile first : les styles par défaut s’appliquent au mobile
<div className="text-sm md:text-base lg:text-lg">
  {/* Amélioration progressive des petits écrans aux grands écrans */}
</div>

// À éviter : desktop first (non recommandé)
<div className="text-lg md:text-base sm:text-sm">
  {/* Cela augmente la charge sur les appareils mobiles */}
</div>

Optimisation mobile

Configuration du viewport

// app/layout.tsx
export const metadata = {
  viewport: {
    width: 'device-width',
    initialScale: 1,
    maximumScale: 5,
  },
}

Gestion des événements tactiles

  • Utiliser touch-action Optimiser la réactivité tactile
  • Éviter hover État provoqué par des appuis accidentels sur mobile
  • Utiliser @media (hover: hover) Détecter si l’appareil prend en charge le survol

Accessibilité

L’accessibilité garantit que tous les utilisateurs peuvent utiliser votre application, y compris ceux qui utilisent des technologies d’assistance. Respectez les normes WCAG pour rendre votre produit plus inclusif.

norme WCAG

Niveau WCAG 2.1

Niveau A
Exigences minimales, accessibilité de base
Niveau AA (recommandé)
La norme que la plupart des sites web devraient atteindre
Niveau AAA
Normes les plus élevées, exigences particulières

Principes clés (POUR)

Perceptible
Les informations peuvent être perçues de diverses manières
Actionnable
Les composants d’interface et la navigation sont utilisables
Compréhensible
Les informations et les opérations sont compréhensibles
Peut être robuste
Le contenu peut être interprété par diverses technologies d’assistance

Navigation au clavier

Gestion de l’ordre des onglets

// Utilisez tabIndex pour contrôler l'ordre de tabulation
<button tabIndex={1}>Premier</button>
<button tabIndex={2}>Deuxième</button>

// Ignorer les éléments non interactifs
<div tabIndex={-1}>Ignorer cet élément</div>

// Retirer de l'ordre de tabulation (déconseillé sauf si nécessaire)
<button tabIndex={-1}>Inaccessible via Tab</button>

Gestion du focus

// Piège de focus (Focus Trap) - utilisé dans les modales
import { FocusTrap } from '@radix-ui/react-focus-trap'

<FocusTrap>
  <Dialog>
    {/* Le focus est limité à l'intérieur de la boîte de dialogue */}
  </Dialog>
</FocusTrap>

// Style visible au focus
<button className="focus-visible:ring-2 focus-visible:ring-primary">
  {/* Afficher l’anneau de focus lors de la navigation au clavier */}
</button>

Prise en charge des raccourcis clavier

  • Entrée/Espace : activer un bouton ou un lien
  • Esc : fermer la fenêtre modale ou le menu
  • Arrow Keys : naviguer dans la liste ou les éléments du menu
  • Tab : passer d’un élément focalisable à un autre

Prise en charge des lecteurs d’écran

Utilisation des étiquettes ARIA

// aria-label : fournit une étiquette à un élément
<button aria-label="Fermer la boîte de dialogue">
  <X />
</button>

// aria-labelledby : fait référence à l’ID d’un autre élément
<div aria-labelledby="dialog-title">
  <h2 id="dialog-title">Titre de la boîte de dialogue</h2>
</div>

// aria-describedby : fournit une description supplémentaire
<input 
  aria-describedby="email-help"
  aria-invalid={hasError}
/>
<span id="email-help">Veuillez saisir une adresse e-mail valide</span>

HTML sémantique

// Utiliser des balises sémantiques
<nav>Navigation</nav>
<main>Contenu principal</main>
<article>Article</article>
<section>Section</section>
<aside>Barre latérale</aside>
<header>En-tête</header>
<footer>Pied de page</footer>

// À éviter : utiliser div à la place des balises sémantiques
<div className="nav"> {/* Non recommandé */}
<nav> {/* Recommandé */}

Définition des rôles

// Utilisez l’attribut role (lorsque les balises sémantiques ne sont pas disponibles)
<div role="button" tabIndex={0} onClick={handleClick}>
  Bouton personnalisé
</div>

<div role="alert" aria-live="polite">
  Avis important
</div>

<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  {/* Boîte de dialogue modale */}
</div>

Contraste des couleurs

Norme WCAG AA

Texte normal
Contraste ≥ 4,5:1
Grand texte (18px+ ou 14px+ en gras)
Rapport de contraste ≥ 3:1

Vérification des outils

  • WebAIM Contrast Checker : outil en ligne de vérification du contraste
  • Lighthouse : intégré à Chrome DevTools
  • axe DevTools : extension de navigateur

Ne vous fiez pas à la couleur pour transmettre l’information

// Erreur : utiliser uniquement la couleur pour indiquer l’état
<span className="text-red-500">Erreur</span>

// Correct : couleur + icône/texte
<span className="text-red-500 flex items-center gap-1">
  <AlertCircle />
  Erreur : veuillez saisir une valeur valide
</span>

Tests d’accessibilité

Outils de test automatisés

axe
npm install @axe-core/react
Lighthouse
Chrome DevTools
WAVE
Extension de navigateur

Flux de tests manuels

  1. Naviguer dans toute l’application en utilisant uniquement le clavier
  2. Tester à l’aide de lecteurs d’écran (NVDA, JAWS, VoiceOver)
  3. Vérifier le contraste des couleurs
  4. Vérifier que toutes les images ont un texte alt
  5. Message d’erreur du formulaire de test

Liste de contrôle des tests du clavier

  • Tous les éléments interactifs sont accessibles via Tab
  • La logique de l’ordre de focalisation est cohérente
  • Focus visible (avec anneau de focus)
  • La fenêtre modale peut être fermée avec Esc
  • Le menu peut être parcouru avec les touches fléchées

Optimisation des performances

Les performances ont un impact direct sur l'expérience utilisateur. Optimisez les performances de rendu, le chargement des ressources et les performances d'exécution afin de garantir une réponse rapide de l'application.

Performance de rendu

Optimisation du rendu React

// Utiliser memo pour éviter les re-rendus inutiles
const ExpensiveComponent = React.memo(({ data }) => {
  return <div>{/* rendu complexe */}</div>
})

// Utiliser useMemo pour mettre en cache les résultats calculés
const expensiveValue = useMemo(() => {
  return computeExpensiveValue(a, b)
}, [a, b])

// Utiliser useCallback pour mettre en cache les fonctions
const handleClick = useCallback(() => {
  doSomething(id)
}, [id])

Défilement virtuel

Pour les grandes listes, utilisez le défilement virtuel pour ne rendre que les éléments visibles :

// Utiliser react-window ou react-virtualized
import { FixedSizeList } from 'react-window'

<FixedSizeList
  height={600}
  itemCount={10000}
  itemSize={50}
  width="100%"
>
  {Row}
</FixedSizeList>

Découpage du code

// Importation dynamique du composant
import dynamic from 'next/dynamic'

const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <Skeleton />,
  ssr: false, // si vous devez désactiver le SSR
})

// Découpage du code au niveau des routes (géré automatiquement par Next.js)
// app/dashboard/page.tsx sera découpé automatiquement

Optimisation des ressources

Optimisation des images

// Optimisation automatique par le composant Image de Next.js
import Image from 'next/image'

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority // image au-dessus de la ligne de flottaison
  loading="lazy" // image sous la ligne de flottaison
  placeholder="blur" // espace réservé flouté
/>

// Prend en charge les formats modernes tels que WebP et AVIF
// Génère automatiquement des images responsives

Optimisation des polices

// Use next/font to optimize fonts
import { GeistSans } from 'next/font/google'

const geistSans = GeistSans({
  subsets: ['latin'],
  display: 'swap', // Font loading strategy
  preload: true,
})

// Font subsetting, load only the required characters

Préchargement des ressources

// Préconnecter les domaines tiers
<link rel="preconnect" href="https://fonts.googleapis.com" />

// Précharger les ressources critiques
<link rel="preload" href="/fonts/geist.woff2" as="font" />

// Pré-récupérer les ressources de la page suivante
<link rel="prefetch" href="/dashboard" />

Performance d'exécution

Optimisation de la taille du bundle

  • Utiliser bundle analyzer Analyser la taille du bundle
  • Importer des bibliothèques selon les besoins (import { debounce } from 'lodash-es'
  • Supprimer les dépendances inutilisées

Tree Shaking

Next.js et les outils de bundling modernes effectuent automatiquement le tree shaking pour supprimer le code inutilisé.

Surveillance des performances

Core Web Vitals

LCP
Largest Contentful Paint < 2,5 s
FID
Délai du premier input < 100 ms
CLS
Décalage de mise en page cumulatif < 0.1

Outils d’analyse des performances

  • React DevTools Profiler : analyser les performances de rendu des composants
  • Lighthouse : audit des performances de Chrome DevTools
  • Web Vitals Extension : surveillance en temps réel des Core Web Vitals

Exemples pratiques

Apprenez à construire des composants UI et des interactions de haute qualité à travers des exemples de code réels.

Exemple complet de composant de formulaire

'use client'

import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form'
import { toast } from 'sonner'

const formSchema = z.object({
  name: z.string().min(2, 'Le nom doit comporter au moins 2 caractères'),
  email: z.string().email('Adresse e-mail invalide'),
  age: z.number().min(18, 'L’âge doit être supérieur à 18').max(100),
})

export function UserForm() {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      name: '',
      email: '',
      age: 18,
    },
  })

  async function onSubmit(values: z.infer<typeof formSchema>) {
    try {
      await saveUser(values)
      toast.success('Utilisateur créé avec succès')
      form.reset()
    } catch (error) {
      toast.error('Échec de la création, veuillez réessayer')
    }
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Nom</FormLabel>
              <FormControl>
                <Input placeholder="Veuillez saisir votre nom" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit" disabled={form.formState.isSubmitting}>
          {form.formState.isSubmitting ? 'Envoi...' : 'Envoyer'}
        </Button>
      </form>
    </Form>
  )
}

Résultats d’apprentissage

À la fin de ce chapitre, vous pourrez :

  • 1Comprendre les bases des systèmes de design et maîtriser les Design Tokens, les systèmes de thème et l’architecture des composants
  • 2Maîtrise de Tailwind CSS et shadcn/ui, capable de configurer et de personnaliser des bibliothèques de composants
  • 3Maîtrisez la gestion d’état, le traitement des formulaires et les techniques d’animation pour créer une expérience interactive fluide
  • 4Maîtrisez les méthodes de conception responsive, en utilisant une approche mobile-first et des techniques de mise en page modernes
  • 5Comprendre les normes d’accessibilité (WCAG) et être capable de mettre en œuvre la navigation au clavier et la prise en charge des lecteurs d’écran
  • 6Maîtrisez les techniques d’optimisation des performances, notamment l’optimisation du rendu, le chargement des ressources et le suivi des performances
  • 7Capable de créer des composants de formulaire complets, des mises en page responsives et des fonctionnalités interactives