Intermédiaire

Prompter pour le Design Frontend

Vous savez coder en React. Vous savez utiliser l'IA. Mais quand vous demandez "fais-moi un truc pour afficher des données", le résultat est... générique. Pourquoi ? Parce que le vocabulaire manque.

Le principe clé

Nommer le composant, c'est obtenir le bon composant.

L'IA connaît des centaines de patterns UI. Si vous dites "un bouton avec des options", elle devine. Si vous dites "un dropdown menu avec des items cliquables", elle sait exactement quoi générer.

Le modèle de composants React est parfait pour ça : chaque élément d'interface a un nom, des props, un comportement. Apprendre ce vocabulaire, c'est apprendre à parler la même langue que l'IA.

Cette page est un catalogue de référence : pour chaque famille de composants, vous trouverez le nom, un exemple de code, et surtout la différence entre un prompt vague et un prompt précis.


1. Boutons (Buttons)

Les boutons sont le composant d'interaction de base. Mais dire "un bouton" ne suffit pas : il existe de nombreuses variantes, chacune avec un rôle précis.

VarianteUsage
PrimaryAction principale de la page (valider, envoyer)
SecondaryAction secondaire (annuler, retour)
OutlineAction moins importante, style plus léger
GhostAction discrète, sans fond (souvent dans les toolbars)
DestructiveAction dangereuse (supprimer, révoquer)
Icon buttonBouton avec uniquement une icône (fermer, menu)
Loading stateBouton en cours de traitement (spinner + disabled)
tsx
function ButtonShowcase() {
  const [loading, setLoading] = useState(false);

  return (
    <div className="flex gap-3 items-center">
      <button className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
        Primary
      </button>
      <button className="bg-gray-200 text-gray-800 px-4 py-2 rounded-lg hover:bg-gray-300">
        Secondary
      </button>
      <button className="border border-gray-300 px-4 py-2 rounded-lg hover:bg-gray-50">
        Outline
      </button>
      <button className="text-gray-600 px-4 py-2 rounded-lg hover:bg-gray-100">
        Ghost
      </button>
      <button className="bg-red-600 text-white px-4 py-2 rounded-lg hover:bg-red-700">
        Supprimer
      </button>
      <button
        disabled={loading}
        onClick={() => setLoading(true)}
        className="bg-blue-600 text-white px-4 py-2 rounded-lg disabled:opacity-50 flex items-center gap-2"
      >
        {loading && <span className="animate-spin"></span>}
        {loading ? "Envoi..." : "Envoyer"}
      </button>
    </div>
  );
}

Prompt vague vs. précis :

"Fais-moi des boutons pour mon formulaire"

"Génère un composant Button avec les variantes primary, secondary, outline, ghost et destructive. Ajoute un prop loading qui affiche un spinner et désactive le bouton. Utilise Tailwind CSS."

shadcn/ui

La bibliothèque shadcn/ui fournit un composant Button avec toutes ces variantes via un prop variant. C'est un excellent point de départ pour vos projets.


2. Badges & Tags

Les badges affichent un statut ou un compteur. Les tags catégorisent du contenu. Visuellement proches, leur fonction diffère.

tsx
function BadgeExamples() {
  return (
    <div className="flex gap-3 items-center flex-wrap">
      {/* Status badges */}
      <span className="bg-green-100 text-green-800 text-xs font-medium px-2.5 py-0.5 rounded-full">
        Actif
      </span>
      <span className="bg-yellow-100 text-yellow-800 text-xs font-medium px-2.5 py-0.5 rounded-full">
        En attente
      </span>
      <span className="bg-red-100 text-red-800 text-xs font-medium px-2.5 py-0.5 rounded-full">
        Erreur
      </span>

      {/* Category tags */}
      <span className="bg-blue-50 text-blue-700 text-xs px-2 py-1 rounded border border-blue-200">
        React
      </span>
      <span className="bg-purple-50 text-purple-700 text-xs px-2 py-1 rounded border border-purple-200">
        TypeScript
      </span>

      {/* Notification count */}
      <span className="relative">
        🔔
        <span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center">
          3
        </span>
      </span>
    </div>
  );
}

Prompt vague vs. précis :

"Ajoute des labels de couleur pour les statuts"

"Crée un composant Badge avec des variantes de couleur (success, warning, error, info). Ajoute un composant NotificationBadge qui affiche un compteur rouge en position absolute sur une icône."


3. Cards

Les cards (cartes) regroupent des informations liées dans un conteneur visuel. Elles existent en plusieurs formes selon le contenu.

tsx
function StatCard({ title, value, trend }: { title: string; value: string; trend: number }) {
  return (
    <div className="bg-white rounded-xl shadow-sm border p-6">
      <p className="text-sm text-gray-500">{title}</p>
      <p className="text-3xl font-bold mt-1">{value}</p>
      <p className={`text-sm mt-2 ${trend > 0 ? "text-green-600" : "text-red-600"}`}>
        {trend > 0 ? "↑" : "↓"} {Math.abs(trend)}% vs. mois dernier
      </p>
    </div>
  );
}

function ProductCard({ name, price, image }: { name: string; price: number; image: string }) {
  return (
    <div className="bg-white rounded-xl shadow-sm border overflow-hidden hover:shadow-md transition-shadow">
      <img src={image} alt={name} className="w-full h-48 object-cover" />
      <div className="p-4">
        <h3 className="font-semibold">{name}</h3>
        <p className="text-blue-600 font-bold mt-1">{price}</p>
        <button className="mt-3 w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700">
          Ajouter au panier
        </button>
      </div>
    </div>
  );
}

Prompt vague vs. précis :

"Fais-moi un truc pour afficher des produits"

"Crée un composant ProductCard avec image, titre, prix et bouton d'ajout au panier. Ajoute un hover effect avec shadow transition. Crée aussi un composant StatCard avec titre, valeur numérique et indicateur de tendance coloré."

Pour afficher des métriques clés en haut d'un dashboard (nombre d'utilisateurs, revenus...), quel composant demandez-vous à l'IA ?


4. Modals & Dialogs

Les modals (ou dialogs) sont des fenêtres superposées au contenu. Elles captent l'attention de l'utilisateur pour une action importante.

TypeUsage
Confirmation dialogDemander confirmation avant une action destructive
Form modalFormulaire sans quitter la page (création, édition)
Drawer / SheetPanneau latéral glissant (détails, filtres, paramètres)
tsx
function ConfirmDialog({ open, onConfirm, onCancel }: {
  open: boolean;
  onConfirm: () => void;
  onCancel: () => void;
}) {
  if (!open) return null;

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
      <div className="bg-white rounded-xl p-6 max-w-md w-full mx-4 shadow-xl">
        <h2 className="text-lg font-semibold">Confirmer la suppression</h2>
        <p className="text-gray-600 mt-2">
          Cette action est irréversible. Voulez-vous continuer ?
        </p>
        <div className="flex justify-end gap-3 mt-6">
          <button onClick={onCancel} className="px-4 py-2 rounded-lg border hover:bg-gray-50">
            Annuler
          </button>
          <button onClick={onConfirm} className="px-4 py-2 rounded-lg bg-red-600 text-white hover:bg-red-700">
            Supprimer
          </button>
        </div>
      </div>
    </div>
  );
}

Prompt vague vs. précis :

"Fais un popup pour confirmer"

"Crée un composant ConfirmDialog avec overlay sombre, titre, message, et deux boutons (annuler en outline, confirmer en destructive). Ajoute les props open, onConfirm et onCancel. Pour les filtres, crée un Drawer (panneau latéral) qui glisse depuis la droite."

Accessibilité

Les modals doivent gérer le focus trap (le focus clavier reste dans la modal) et la fermeture avec Escape. Mentionnez-le dans votre prompt pour que l'IA génère du code accessible. shadcn/ui gère ça automatiquement avec son composant Dialog.


5. Dropdowns & Menus

Les dropdowns affichent une liste d'options à la demande. Ne confondez pas les trois sous-types :

TypeUsage
Select dropdownChoisir une valeur dans un formulaire
Context menu / Dropdown menuActions sur un élément (clic droit, bouton "...")
Command paletteRecherche + navigation rapide (Ctrl+K)
tsx
function DropdownMenu({ items }: { items: { label: string; onClick: () => void }[] }) {
  const [open, setOpen] = useState(false);

  return (
    <div className="relative">
      <button
        onClick={() => setOpen(!open)}
        className="p-2 rounded-lg hover:bg-gray-100"
      >
      </button>
      {open && (
        <div className="absolute right-0 mt-1 bg-white border rounded-lg shadow-lg py-1 min-w-[160px] z-10">
          {items.map((item) => (
            <button
              key={item.label}
              onClick={() => { item.onClick(); setOpen(false); }}
              className="w-full text-left px-4 py-2 text-sm hover:bg-gray-100"
            >
              {item.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

Prompt vague vs. précis :

"Fais un menu déroulant"

"Crée un DropdownMenu qui s'ouvre au clic sur un bouton '...' (three-dot icon). Affiche une liste d'actions (Modifier, Dupliquer, Supprimer) avec hover effect. Ferme le menu au clic à l'extérieur."


6. Accordions & Collapsibles

Les accordions affichent/masquent du contenu par sections. Idéals pour les FAQ, les paramètres, ou tout contenu que l'utilisateur ne consulte pas systématiquement.

tsx
function Accordion({ items }: { items: { title: string; content: string }[] }) {
  const [openIndex, setOpenIndex] = useState<number | null>(null);

  return (
    <div className="border rounded-lg divide-y">
      {items.map((item, index) => (
        <div key={index}>
          <button
            onClick={() => setOpenIndex(openIndex === index ? null : index)}
            className="w-full flex justify-between items-center p-4 text-left hover:bg-gray-50"
          >
            <span className="font-medium">{item.title}</span>
            <span className={`transition-transform ${openIndex === index ? "rotate-180" : ""}`}>
            </span>
          </button>
          {openIndex === index && (
            <div className="p-4 pt-0 text-gray-600">{item.content}</div>
          )}
        </div>
      ))}
    </div>
  );
}

Prompt vague vs. précis :

"Fais un truc qui se déplie"

"Crée un composant Accordion qui affiche une liste de questions/réponses. Un seul item ouvert à la fois. Ajoute une animation de rotation sur la flèche et une transition smooth sur le contenu."


7. Tabs

Les tabs (onglets) permettent de naviguer entre des vues dans un même contexte. Deux usages principaux : la navigation entre pages et le contenu dans une même page.

tsx
function Tabs({ tabs }: { tabs: { label: string; content: React.ReactNode }[] }) {
  const [activeIndex, setActiveIndex] = useState(0);

  return (
    <div>
      <div className="flex border-b">
        {tabs.map((tab, index) => (
          <button
            key={tab.label}
            onClick={() => setActiveIndex(index)}
            className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
              activeIndex === index
                ? "border-blue-600 text-blue-600"
                : "border-transparent text-gray-500 hover:text-gray-700"
            }`}
          >
            {tab.label}
          </button>
        ))}
      </div>
      <div className="p-4">{tabs[activeIndex].content}</div>
    </div>
  );
}

Prompt vague vs. précis :

"Ajoute des onglets"

"Crée un composant Tabs avec un underline indicator sur l'onglet actif. Accepte un tableau d'objets {label, content}. L'onglet actif est stocké dans un useState. Style avec border-bottom coloré sur l'onglet sélectionné."

Quelle est la différence entre un Accordion et des Tabs ?


8. Tables

Les data tables (tableaux de données) sont bien plus qu'un <table> HTML. Elles incluent tri, pagination, filtres et actions par ligne.

tsx
function DataTable({ data }: { data: { id: number; name: string; email: string; role: string }[] }) {
  const [sortField, setSortField] = useState<string>("name");
  const [page, setPage] = useState(0);
  const perPage = 5;

  const sorted = [...data].sort((a, b) =>
    a[sortField as keyof typeof a] > b[sortField as keyof typeof a] ? 1 : -1
  );
  const paged = sorted.slice(page * perPage, (page + 1) * perPage);

  return (
    <div className="border rounded-lg overflow-hidden">
      <table className="w-full text-sm">
        <thead className="bg-gray-50 border-b">
          <tr>
            {["name", "email", "role"].map((field) => (
              <th
                key={field}
                onClick={() => setSortField(field)}
                className="text-left p-3 font-medium text-gray-600 cursor-pointer hover:text-gray-900"
              >
                {field} {sortField === field && "↑"}
              </th>
            ))}
            <th className="p-3 text-right font-medium text-gray-600">Actions</th>
          </tr>
        </thead>
        <tbody className="divide-y">
          {paged.map((row) => (
            <tr key={row.id} className="hover:bg-gray-50">
              <td className="p-3">{row.name}</td>
              <td className="p-3 text-gray-500">{row.email}</td>
              <td className="p-3"><span className="bg-blue-100 text-blue-800 text-xs px-2 py-0.5 rounded">{row.role}</span></td>
              <td className="p-3 text-right">
                <button className="text-gray-400 hover:text-gray-600"></button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <div className="flex justify-between items-center p-3 border-t bg-gray-50 text-sm">
        <span className="text-gray-500">{data.length} résultats</span>
        <div className="flex gap-2">
          <button onClick={() => setPage(Math.max(0, page - 1))} disabled={page === 0} className="px-3 py-1 border rounded disabled:opacity-50">Précédent</button>
          <button onClick={() => setPage(page + 1)} disabled={(page + 1) * perPage >= data.length} className="px-3 py-1 border rounded disabled:opacity-50">Suivant</button>
        </div>
      </div>
    </div>
  );
}

Prompt vague vs. précis :

"Affiche une liste d'utilisateurs"

"Crée un composant DataTable avec tri par colonne (clic sur le header), pagination (5 éléments par page avec boutons Précédent/Suivant), et une colonne Actions avec un DropdownMenu. Les rôles sont affichés avec des Badge de couleur."


9. Formulaires avancés

Au-delà des <input> classiques, les formulaires modernes utilisent des composants spécialisés.

ComposantUsage
Combobox / AutocompleteInput avec suggestions filtrées en temps réel
Date pickerSélecteur de date avec calendrier
File uploadZone de dépôt de fichiers (drag & drop)
Multi-selectSélectionner plusieurs options (tags)
Toggle / SwitchActiver/désactiver un paramètre (on/off)
SliderChoisir une valeur numérique dans un intervalle
tsx
function Toggle({ checked, onChange, label }: {
  checked: boolean;
  onChange: (value: boolean) => void;
  label: string;
}) {
  return (
    <label className="flex items-center gap-3 cursor-pointer">
      <div
        onClick={() => onChange(!checked)}
        className={`w-11 h-6 rounded-full p-0.5 transition-colors ${
          checked ? "bg-blue-600" : "bg-gray-300"
        }`}
      >
        <div className={`w-5 h-5 bg-white rounded-full shadow transition-transform ${
          checked ? "translate-x-5" : "translate-x-0"
        }`} />
      </div>
      <span className="text-sm">{label}</span>
    </label>
  );
}

function FileUpload() {
  const [dragging, setDragging] = useState(false);

  return (
    <div
      onDragOver={(e) => { e.preventDefault(); setDragging(true); }}
      onDragLeave={() => setDragging(false)}
      onDrop={(e) => { e.preventDefault(); setDragging(false); /* handle files */ }}
      className={`border-2 border-dashed rounded-xl p-8 text-center transition-colors ${
        dragging ? "border-blue-500 bg-blue-50" : "border-gray-300"
      }`}
    >
      <p className="text-gray-500">Glissez vos fichiers ici ou</p>
      <button className="mt-2 text-blue-600 font-medium hover:underline">
        parcourez vos fichiers
      </button>
    </div>
  );
}

Prompt vague vs. précis :

"Ajoute un champ pour chercher dans une liste"

"Crée un Combobox (autocomplete) qui filtre une liste d'options au fur et à mesure de la saisie. Affiche les suggestions dans un dropdown sous l'input. Permet la sélection au clavier (flèches + Entrée)."

"Fais un bouton on/off"

"Crée un composant Toggle (switch) avec animation de transition. Props : checked, onChange, label. Style : pilule arrondie avec cercle blanc qui glisse."


10. Feedback & États

Chaque application a besoin de communiquer son état à l'utilisateur. Voici les composants standards pour chaque situation.

ComposantSituation
Toast / SnackbarNotification temporaire après une action
Progress barProgression d'un téléchargement ou d'un processus
Skeleton loaderPlaceholder animé pendant le chargement des données
Empty stateAucune donnée à afficher (liste vide, aucun résultat)
Error boundary UIQuelque chose s'est cassé, avec option de réessayer
Loading spinnerChargement en cours (petit format)
tsx
function Toast({ message, type = "success" }: { message: string; type?: "success" | "error" }) {
  return (
    <div className={`fixed bottom-4 right-4 px-4 py-3 rounded-lg shadow-lg text-white flex items-center gap-2 ${
      type === "success" ? "bg-green-600" : "bg-red-600"
    }`}>
      <span>{type === "success" ? "✓" : "✕"}</span>
      <span>{message}</span>
    </div>
  );
}

function SkeletonCard() {
  return (
    <div className="bg-white rounded-xl border p-6 animate-pulse">
      <div className="h-4 bg-gray-200 rounded w-1/3 mb-3" />
      <div className="h-8 bg-gray-200 rounded w-1/2 mb-2" />
      <div className="h-3 bg-gray-200 rounded w-1/4" />
    </div>
  );
}

function EmptyState() {
  return (
    <div className="text-center py-12">
      <div className="text-4xl mb-4">📭</div>
      <h3 className="text-lg font-semibold text-gray-900">Aucun résultat</h3>
      <p className="text-gray-500 mt-1">Essayez de modifier vos filtres ou d'ajouter du contenu.</p>
      <button className="mt-4 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
        Créer un élément
      </button>
    </div>
  );
}

Prompt vague vs. précis :

"Affiche un message quand ça charge"

"Pendant le chargement des données, affiche des SkeletonCards (rectangles gris avec animation pulse) qui ont la même forme que les vraies cartes. Quand la liste est vide, affiche un EmptyState avec une icône, un titre, un message explicatif et un bouton d'action. Pour les succès/erreurs, affiche un Toast en bas à droite qui disparaît après 3 secondes."

Votre page charge des données depuis une API. Pendant le chargement, quel composant offre la meilleure expérience utilisateur ?


11. Navigation

Les composants de navigation structurent les déplacements de l'utilisateur dans l'application.

ComposantUsage
NavbarBarre de navigation horizontale en haut de page
SidebarMenu latéral (dashboards, apps complexes)
BreadcrumbsFil d'Ariane montrant le chemin de navigation
PaginationNaviguer entre les pages de résultats
Stepper / WizardProgression dans un processus multi-étapes
tsx
function Breadcrumbs({ items }: { items: { label: string; href?: string }[] }) {
  return (
    <nav className="flex items-center gap-2 text-sm text-gray-500">
      {items.map((item, i) => (
        <span key={i} className="flex items-center gap-2">
          {i > 0 && <span>/</span>}
          {item.href ? (
            <a href={item.href} className="hover:text-gray-900">{item.label}</a>
          ) : (
            <span className="text-gray-900 font-medium">{item.label}</span>
          )}
        </span>
      ))}
    </nav>
  );
}

function Stepper({ steps, currentStep }: { steps: string[]; currentStep: number }) {
  return (
    <div className="flex items-center gap-2">
      {steps.map((step, i) => (
        <div key={i} className="flex items-center gap-2">
          <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${
            i <= currentStep
              ? "bg-blue-600 text-white"
              : "bg-gray-200 text-gray-500"
          }`}>
            {i < currentStep ? "✓" : i + 1}
          </div>
          <span className={`text-sm ${i <= currentStep ? "text-gray-900" : "text-gray-400"}`}>
            {step}
          </span>
          {i < steps.length - 1 && <div className="w-8 h-px bg-gray-300" />}
        </div>
      ))}
    </div>
  );
}

Prompt vague vs. précis :

"Fais un menu"

"Crée une Sidebar de navigation avec des items groupés par section. Chaque item a une icône et un label. L'item actif est mis en surbrillance. La sidebar est collapsible (se réduit à des icônes seules). Ajoute des Breadcrumbs au-dessus du contenu principal."


12. Layouts

Les composants de layout structurent l'agencement global des pages.

tsx
function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div className="flex h-screen">
      {/* Sidebar */}
      <aside className="w-64 bg-gray-900 text-white p-4 flex flex-col">
        <h1 className="text-lg font-bold mb-8">Mon App</h1>
        <nav className="flex-1 space-y-1">
          <a href="#" className="block px-3 py-2 rounded-lg bg-gray-800">Dashboard</a>
          <a href="#" className="block px-3 py-2 rounded-lg hover:bg-gray-800">Utilisateurs</a>
          <a href="#" className="block px-3 py-2 rounded-lg hover:bg-gray-800">Paramètres</a>
        </nav>
      </aside>

      {/* Main content */}
      <div className="flex-1 flex flex-col overflow-hidden">
        {/* Sticky header */}
        <header className="bg-white border-b px-6 py-3 flex items-center justify-between sticky top-0">
          <Breadcrumbs items={[{ label: "Dashboard" }]} />
          <span className="text-sm text-gray-500">Thomas L.</span>
        </header>

        {/* Scrollable content */}
        <main className="flex-1 overflow-y-auto p-6 bg-gray-50">
          {children}
        </main>
      </div>
    </div>
  );
}

Prompt vague vs. précis :

"Fais-moi la mise en page de mon app"

"Crée un DashboardLayout avec : une Sidebar fixe à gauche (w-64, fond sombre), un sticky header avec Breadcrumbs et info utilisateur, et une zone de contenu scrollable avec fond gris. La sidebar et le header restent fixes pendant le scroll."


Assembler des interfaces

La vraie puissance du vocabulaire UI, c'est de pouvoir décrire une interface complète en une seule phrase.

Le vocabulaire comme langage de conception

Quand vous connaissez les noms des composants, vous pouvez décrire une page entière comme une recette avec des ingrédients précis. L'IA comprend immédiatement la structure à générer.

Exemple : un dashboard complet

Au lieu de :

"Fais-moi un dashboard pour gérer des utilisateurs"

Vous pouvez écrire :

"Crée un dashboard avec : - un DashboardLayout (Sidebar + sticky Header avec Breadcrumbs) - en haut : une grille de 4 StatCards (utilisateurs, revenus, commandes, taux de conversion) - en dessous : un DataTable avec les colonnes Nom, Email, Rôle (Badge), Date d'inscription, et une colonne Actions (DropdownMenu avec Modifier / Désactiver / Supprimer) - la suppression ouvre un ConfirmDialog - les succès/erreurs s'affichent en Toast - pendant le chargement, affiche des SkeletonCards puis un Skeleton du tableau"

Ce prompt produit une structure comme :

tsx
function AdminDashboard() {
  return (
    <DashboardLayout>
      {/* KPI Row */}
      <div className="grid grid-cols-4 gap-4 mb-6">
        <StatCard title="Utilisateurs" value="1,234" trend={12} />
        <StatCard title="Revenus" value="45,600 €" trend={8} />
        <StatCard title="Commandes" value="342" trend={-3} />
        <StatCard title="Conversion" value="3.2%" trend={0.5} />
      </div>

      {/* Data Table */}
      <DataTable
        columns={["Nom", "Email", "Role", "Inscription", "Actions"]}
        data={users}
        renderRole={(role) => <Badge variant={role === "admin" ? "info" : "default"}>{role}</Badge>}
        renderActions={(user) => (
          <DropdownMenu items={[
            { label: "Modifier", onClick: () => openEditModal(user) },
            { label: "Supprimer", onClick: () => openConfirmDialog(user) },
          ]} />
        )}
      />

      {/* Dialogs & Feedback */}
      <ConfirmDialog open={showConfirm} onConfirm={handleDelete} onCancel={closeConfirm} />
      {toast && <Toast message={toast.message} type={toast.type} />}
    </DashboardLayout>
  );
}

Remarquez comment chaque composant est nommé et composé : le prompt devient un plan d'architecture, et le code généré est structuré exactement comme on l'a décrit.

Exercice mental : votre Kana App

Pensez à votre projet Kana. Comment décririez-vous ses écrans avec le vocabulaire de cette page ?

"L'écran principal a une Navbar avec le titre et un Toggle pour le mode sombre. Le quiz affiche une Card avec le caractère japonais, un groupe de Buttons pour les réponses, et une ProgressBar pour la progression. Un Toast apparaît pour chaque bonne/mauvaise réponse. L'écran de résultats affiche des StatCards (score, temps, précision) et un bouton primary pour recommencer."


Récapitulatif

La règle d'or

Avant de prompter, nommez le composant. Si vous ne connaissez pas le nom exact, cherchez dans cette page ou demandez à l'IA : "Comment s'appelle le composant UI qui fait [description du comportement] ?"

Voici un aide-mémoire des composants vus dans cette page :

BesoinComposant à demander
Déclencher une actionButton (primary, outline, ghost, destructive...)
Afficher un statutBadge
Grouper des infosCard (StatCard, ProductCard, ProfileCard)
Capturer l'attentionModal / Dialog / Drawer
Choisir parmi des optionsDropdown / Select / Combobox
Montrer/cacher du contenuAccordion
Naviguer entre des vuesTabs
Afficher des données tabulairesDataTable
Saisie avancéeToggle, Slider, DatePicker, FileUpload
Notifier l'utilisateurToast / Snackbar
Indiquer le chargementSkeleton loader, Spinner, ProgressBar
Aucun contenuEmptyState
Navigation globaleNavbar, Sidebar, Breadcrumbs
Processus multi-étapesStepper / Wizard
Structure de pageDashboardLayout, SplitPanel, Grid

Vous voulez que l'IA génère un formulaire d'inscription en 3 étapes (Infos personnelles → Adresse → Confirmation). Quel composant mentionnez-vous dans votre prompt ?