MeDo

Générateur de Modale IA.

Décrivez le dialogue dont vous avez besoin et MeDo génère l'ensemble — en-tête, corps défilant et pied d'actions, plus la capture du focus, la restauration du focus à la fermeture, le blocage du scroll du body et une variante bottom sheet pour mobile.

Modale
Modale

Le plus dur dans une modale, c'est la page derrière

Une modale ressemble à une boîte centrée avec une ombre, et c'est précisément pour cela qu'elle est si souvent mal reconstruite. La couche visuelle est triviale ; la partie difficile vit entièrement en dehors du composant. Ouvrir un dialogue doit figer le document en dessous, capturer le focus clavier pour que Tab ne s'échappe pas vers du contenu masqué, masquer le reste de la page aux technologies d'assistance, puis remettre le focus exactement sur l'élément qui l'a ouvert. Oubliez cette dernière étape et l'utilisateur au clavier se retrouve silencieusement en haut du document sans savoir où il est. Générer le dialogue et son contrat de focus ensemble signifie que cette machine à états est correcte au premier rendu, plutôt que rafistolée après une passe de QA.

6 modèles

Modèles de Modale que vous pouvez générer

Chaque modèle est un vrai prompt, pas une capture d'écran. Copiez-le dans n'importe quel éditeur IA, ou exécutez-le dans MeDo pour récupérer du code React + Tailwind.

BasicHeader + Footer

Composable Dialog With Focus Management

The base every other dialog extends. The visual layer takes minutes; the focus contract is the part worth generating rather than hand-writing.

Create a modal dialog with three sizes — sm 400px, md 560px, lg 760px — centered over a black backdrop at 50 percent opacity, 16px radius, soft shadow. Compose it from Header, Body and Footer slots: the header holds a title and an icon-only close button with an aria-label, the body scrolls independently at max-height 70vh, and the footer right-aligns Cancel next to a primary action. On open, move focus to the first interactive element, trap Tab and Shift+Tab inside the dialog, and lock body scroll by compensating for the scrollbar width so the page does not shift. Set role="dialog", aria-modal="true" and aria-labelledby pointing at the title, and restore focus to the trigger on close.

Tester dans MeDo
ConfirmationDestructive Confirm

Non-Dismissible Delete Dialog

The one dialog that must ignore Escape and backdrop clicks. A stray click outside the box should never be the gesture that deletes an account.

Create a destructive confirmation dialog: a warning icon, a heading naming the exact resource, a body stating what will be lost and whether it is recoverable, and a footer with Cancel on the left and a red Confirm on the right. Ignore both Escape and backdrop clicks so the action requires a deliberate button press. Move initial focus to Cancel rather than Confirm, so a stray Enter keypress cancels instead of destroying. Use role="alertdialog" with aria-describedby on the body text. Add an optional type-to-confirm mode requiring the resource name to be typed before Confirm enables, with the comparison case-sensitive and trimmed.

Tester dans MeDo
FormForm Dialog

Scrolling Form With Sticky Actions

A long form in a dialog needs a body that scrolls under a fixed header and footer, plus an unsaved-changes guard. Losing typed input to a misclick is unforgivable.

Create a form dialog with a fixed header, a scrolling body and a sticky footer holding Cancel and Save. Keep the header and footer outside the scroll container so the actions stay reachable in a long form. Add a dirty-state guard: when any field has changed, intercept Escape and backdrop clicks and show a nested confirm-discard step inside the same dialog rather than opening a second overlay. On validation failure, move focus to the first invalid field and scroll it into view inside the body. Set aria-busy while saving, disable Save without removing it from the tab order, and close only after the request resolves.

Tester dans MeDo
MobileBottom Sheet

Sheet That Slides Up on Phones

A centered card on a phone leaves the buttons floating mid-screen, away from the thumb. Same component, different layout under 640px.

Create a dialog that renders as a centered card above 640px and as a bottom sheet below it: full width, rounded top corners only, sliding up from the bottom edge with a 250ms ease-out transform. Add a drag handle at the top and support swipe-to-dismiss with a velocity threshold, falling back to the close button for keyboard and assistive technology. Cap the sheet height at 90vh with the body scrolling inside, and use dynamic viewport units so the mobile browser chrome does not clip the footer. Keep focus trapping and scroll lock identical in both layouts, and disable the slide animation under prefers-reduced-motion.

Tester dans MeDo
PlatformNative Dialog

HTML dialog With showModal

The browser already ships focus trapping, top-layer stacking and Escape handling. Choose this and you delete most of the code the custom overlay needed.

Create a modal built on the native HTML dialog element opened with showModal(), so the browser supplies focus trapping, Escape handling and top-layer stacking with no z-index management. Style the backdrop through the ::backdrop pseudo-element. Add the parts the platform does not give you: body scroll lock on open, an entry and exit animation using allow-discrete and the transition-behavior property, and a close-on-backdrop handler that compares the click target to the dialog element rather than its children. Listen for the close event to restore focus and read returnValue, and use autofocus on the element that should receive focus first.

Tester dans MeDo
OverlayCommand Palette

Cmd+K Search Dialog

A modal whose focus stays in the input while arrow keys drive a list elsewhere. Roving focus would break typing, so this one runs on aria-activedescendant.

Create a command palette dialog opened by Cmd+K or Ctrl+K: a search input at the top with results grouped by section below, positioned near the top of the viewport rather than vertically centered. Keep DOM focus in the input at all times and move the visual selection with aria-activedescendant so arrow keys navigate the list without stealing focus from typing. Support Enter to run the highlighted command, Escape to close with focus restored to the previously active element, and a scroll-into-view on the highlighted row. Debounce the query, render an empty state naming what was searched for, and announce the result count through a polite live region.

Tester dans MeDo

Comment personnaliser votre Modale

Précisez quels dialogues ne doivent pas être fermables

Escape et les clics sur le backdrop sont le bon comportement par défaut pour les dialogues informatifs, mais un risque pour les confirmations destructives et les formulaires multi-étapes avec des saisies non enregistrées. Nommez les variantes qui doivent ignorer les deux, pour qu'un clic malencontreux hors de la boîte ne supprime pas un compte.

Demandez la restauration du focus, pas seulement sa capture

La plupart des prompts obtiennent la capture et oublient le trajet retour. Précisez que le focus revient à l'élément déclencheur à la fermeture, et que le dialogue stocke cette référence à l'ouverture, pour que les utilisateurs au clavier reprennent exactement là où ils s'étaient arrêtés.

Choisissez centré ou bottom sheet selon le breakpoint

Un dialogue centré sur un téléphone laisse les boutons d'action flotter au milieu de l'écran, loin du pouce. Demandez un bottom sheet en dessous de 640px avec l'action principale à portée, et conservez la mise en page centrée pour les viewports plus larges.

N'ouvrez jamais une modale depuis une modale

Un second dialogue empilé sur le premier casse la capture du focus, double le backdrop et rend ambigu la couche que ferme Escape. Demandez plutôt un contenu par étapes dans un seul dialogue, afin que l'overlay reste une couche unique avec un seul propriétaire du focus.

Qui utilise le composant Modale

Produit SaaS

Un dialogue de confirmation non fermable pour annuler un abonnement, avec le nom de la formule répété dans le corps et un bouton Confirmer rouge, aux côtés d'un dialogue plus léger et fermable pour inviter un coéquipier.

Boutique e-commerce

Un dialogue d'aperçu rapide contenant les images du produit, un sélecteur de taille et un bouton Ajouter au panier, rendu en bottom sheet sur téléphone pour que les tailles et le bouton panier restent à portée du pouce.

Tableau de bord ou outil d'administration

Une confirmation de suppression en masse qui indique le nombre exact d'enregistrements et exige de saisir le nom de la ressource avant d'activer Confirmer, associée à un dialogue d'édition dont le formulaire long défile entre un en-tête et un pied fixes.

Site de contenu ou de médias

Un dialogue lightbox pour les images en pleine taille avec navigation aux flèches, Escape pour fermer et retour du focus sur la vignette qui l'a ouvert, afin que la position de lecture dans la galerie ne soit jamais perdue.

Modèles de Modale pour différents sites web

Le même composant modale, adapté au type de site sur lequel il est publié.

01 / 06

SaaS Product Dialogs

Two classes of dialog with opposite dismissal rules: invite-a-teammate should close on Escape and backdrop click, cancel-my-subscription should close on neither. Decide that per variant rather than globally, because a single dismissal policy across a product means either annoying dialogs or destroyed data.

Styles et variantes de Modale

Choisissez la variante qui correspond au reste de la page, puis générez-la.

01 / 06

Centered Dialog

The default above 640px: a fixed-width card centered over a dimmed backdrop. Cap the height at around 70vh with the body scrolling internally, because a dialog taller than the viewport pushes its own footer out of reach and there is no page scroll left to recover it.

Modale en React, Next.js, Vue et Svelte

React, Next.js, Vue 3, SvelteKit, Astro ou HTML simple — le même modale, six façons de l'intégrer.

01 / 06

React Modal

Render through a portal so the dialog escapes any ancestor with overflow hidden or a transform, both of which would clip it. Store the trigger element on open and focus it again in the cleanup, which is the step most hand-rolled modals skip.

src/components/Modal.tsx

export function Modal({ open, onClose, children }) {
  const trigger = useRef(null)

  useEffect(() => {
    if (!open) return
    trigger.current = document.activeElement
    return () => trigger.current?.focus()
  }, [open])

  if (!open) return null
  return createPortal(
    <div role="dialog" aria-modal="true">{children}</div>,
    document.body
  )
}

Comment ajouter votre Modale à un projet

Quatre étapes, du choix d'un modèle de modale à sa mise en production.

01~30s

Pick a Dialog Template

Scan the six templates and start from the interaction — a destructive confirm, a scrolling form, a mobile bottom sheet, or a Cmd+K palette.

02~10s

Copy the Prompt

Take the prompt into MeDo, Lovable, Bolt, v0 or Cursor. State whether this dialog may be dismissed by Escape and backdrop click before you run it, since that single decision separates a helpful overlay from one that deletes data on a misclick.

03~1min

Generate and Refine

You get React + Tailwind back with a live preview. Follow up in plain English — "make it a bottom sheet under 640px", "focus Cancel first", "build it on the native dialog element" — rather than rewiring the focus trap yourself.

04~2min

Test It With the Keyboard Only

Open it, Tab to the end and confirm focus cycles instead of escaping into the page, then close it and check focus returned to the trigger. Those two checks catch nearly every modal defect that ships.

Questions fréquentes à propos de Modale

Comment générer un composant modale avec l'IA ?

Décrivez la mise en page, les tailles et les règles de fermeture dans un seul prompt — par exemple « un dialogue centré de 560px avec un corps défilant, des actions Annuler et Confirmer, et une variante destructive qui ignore Escape ». MeDo génère le composant avec capture du focus, restauration du focus, blocage du scroll et sémantique de dialogue incluses : vous obtenez un overlay fonctionnel, pas un div stylisé.

Qu'est-ce que la capture du focus et pourquoi une modale en a-t-elle besoin ?

La capture du focus fait circuler Tab et Shift+Tab entre les éléments interactifs du dialogue au lieu de s'échapper vers la page en dessous. Sans elle, un utilisateur au clavier passe du bouton Confirmer à des liens qu'il ne peut pas voir, ce qui est déroutant et constitue un échec WCAG. La capture doit être associée à la restauration du focus, qui le ramène sur l'élément déclencheur à la fermeture du dialogue.

Une modale doit-elle se fermer au clic sur le backdrop ?

Pour les dialogues informatifs et à faible enjeu, oui — le clic sur le backdrop et Escape sont les schémas de fermeture attendus. Pour les confirmations destructives et les formulaires avec saisie non enregistrée, non : un clic accidentel hors de la boîte ne doit pas supprimer des données ni effacer ce qui a été tapé. Exigez un appui explicite sur un bouton pour tout ce qui est irréversible.

Puis-je utiliser l'élément HTML natif <dialog> au lieu d'une modale personnalisée ?

Souvent oui. L'élément natif <dialog> avec showModal() vous offre gratuitement la capture du focus, la gestion d'Escape, l'empilement dans la top layer et un pseudo-élément ::backdrop, sans gestion du z-index. Vous devez toujours bloquer le scroll du body et gérer vous-même l'animation, et les anciens navigateurs nécessitent un fallback. Dites à MeDo que vous voulez l'élément natif et il construira dessus plutôt que de réimplémenter le comportement.

Comment une modale doit-elle se comporter sur mobile ?

En dessous de 640px environ, un bottom sheet surpasse généralement la carte centrée : il ancre l'action principale près du pouce, utilise toute la largeur pour les champs de formulaire et respecte la convention de plateforme que les utilisateurs connaissent déjà. MeDo peut générer les deux mises en page dans un seul composant et basculer entre elles au breakpoint que vous indiquez.

Une modale a-t-elle besoin de role="dialog" et d'aria-modal ?

Oui, sauf si vous utilisez l'élément natif <dialog>, qui fournit lui-même la sémantique. Un overlay personnalisé a besoin de role="dialog", aria-modal="true" et soit d'aria-labelledby pointant vers le titre visible, soit d'aria-label lorsqu'il n'y a pas de titre visible. Sans aria-modal, les lecteurs d'écran continuent d'exposer la page derrière l'overlay comme du contenu parcourable.