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 :
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
Système de polices
Système de coins arrondis
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
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 configClasse 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 composants | Caractéristiques | Scénarios d’application |
|---|---|---|
| shadcn/ui | Copiable-collable, entièrement contrôlable, basé sur Radix UI | Projets hautement personnalisés, projets Next.js |
| Material-UI | Composants riches, documentation complète, Material Design | Applications d’entreprise, prototypage rapide |
| Ant Design | Composants de niveau entreprise, applications front-office/back-office, documentation en chinois | Systèmes de back-office, plateformes d’administration |
| Chakra UI | Simple, modulaire, compatible TypeScript | Applications 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
useFieldArrayGérer les champs dynamiques - Utilisation de formulaires volumineux
shouldUnregisterOptimiser 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éeConsidérations de performance
- Utiliser
transformetopacityDéclencher l’accélération GPU - Éviter les animations
width、heightattributs tels que - Utiliser
will-changeConseils 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
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
// 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-actionOptimiser 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
Principes clés (POUR)
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
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
Flux de tests manuels
- Naviguer dans toute l’application en utilisant uniquement le clavier
- Tester à l’aide de lecteurs d’écran (NVDA, JAWS, VoiceOver)
- Vérifier le contraste des couleurs
- Vérifier que toutes les images ont un texte alt
- 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é automatiquementOptimisation 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 responsivesOptimisation 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 charactersPré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 analyzerAnalyser 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
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