AI Modal Generator.

Describe the dialog you need and MeDo generates the whole thing — header, scrollable body, and action footer, plus focus trapping, focus restore on close, body scroll lock, and a mobile bottom sheet variant.

Modal
Modal

The Hard Part of a Modal Is the Page Behind It

A modal looks like a centered box with a shadow, which is why it gets rebuilt badly so often. The visual layer is trivial; the difficult part lives entirely outside the component. Opening a dialog has to freeze the document beneath it, capture keyboard focus so Tab cannot wander into hidden content, hide the rest of the page from assistive technology, and then put focus back on the exact element that opened it. Miss the last step and a keyboard user is silently returned to the top of the document with no idea where they are. Generating the dialog and its focus contract together means that state machine is correct on the first render rather than patched in after a QA pass.

6 templates

Modal Templates You Can Generate

Every template is a real prompt, not a screenshot. Copy it into any AI editor, or run it in MeDo and get React + Tailwind code back.

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.

Try in 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.

Try in 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.

Try in 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.

Try in 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.

Try in 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.

Try in MeDo

How to Customize Your Modal

Say which dialogs must not be dismissible

Escape and backdrop clicks are the right default for informational dialogs, but they are a liability on destructive confirmations and multi-step forms with unsaved input. Name the variants that should ignore both, so a stray click outside the box cannot delete an account.

Ask for focus restore, not just focus trapping

Most prompts get the trap and forget the return trip. Specify that focus moves back to the triggering element on close, and that the dialog stores that reference on open, so keyboard users resume exactly where they left off.

Pick centered or bottom sheet per breakpoint

A centered dialog on a phone leaves the action buttons floating mid-screen, far from the thumb. Ask for a bottom sheet under 640px with the primary action within reach, and keep the centered layout for wider viewports.

Never open a modal from inside a modal

A second dialog stacked on the first breaks the focus trap, doubles the backdrop, and leaves Escape ambiguous about which layer it closes. Ask for step-based content inside one dialog instead, so the overlay stays a single layer with one owner of focus.

Who Uses the Modal Component

SaaS product

A non-dismissible confirmation dialog for canceling a subscription, with the plan name repeated in the body and a red Confirm button, alongside a lighter dismissible dialog for inviting a teammate.

E-commerce store

A quick-view dialog holding product images, a size selector, and an Add to cart button, rendered as a bottom sheet on phones so the size options and the cart button both stay within thumb reach.

Dashboard or admin tool

A bulk-delete confirmation that states the exact record count and requires typing the resource name before Confirm enables, paired with an edit dialog whose long form scrolls inside a fixed header and footer.

Content or media site

A lightbox dialog for full-size images with arrow-key navigation, Escape to close, and focus returning to the thumbnail that opened it so the reading position in the gallery is never lost.

Modal Patterns for Different Websites

The same modal component, tuned to the kind of site it ships on.

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.

Modal Styles and Variants

Pick the variant that matches the rest of the page, then generate it.

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.

Modal in React, Next.js, Vue and Svelte

React, Next.js, Vue 3, SvelteKit, Astro or plain HTML — the same modal, six ways to drop it in.

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
  )
}

How to Add Your Modal to a Project

Four steps, from picking a modal template to shipping it in 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.

Common Questions About Modal

How do I generate a modal component with AI?

Describe the layout, sizes, and dismissal rules in one prompt — for example "a 560px centered dialog with a scrollable body, Cancel and Confirm actions, and a destructive variant that ignores Escape". MeDo generates the component with focus trapping, focus restore, scroll lock, and dialog semantics included, so you get a working overlay rather than a styled div.

What is focus trapping and why does a modal need it?

Focus trapping keeps Tab and Shift+Tab cycling through the interactive elements inside the dialog instead of escaping into the page underneath. Without it, a keyboard user tabs past the Confirm button into links they cannot see, which is both confusing and a WCAG failure. The trap should be paired with focus restore, returning focus to the trigger element when the dialog closes.

Should a modal close when you click the backdrop?

For informational and low-stakes dialogs, yes — backdrop click and Escape are the dismissal patterns people expect. For destructive confirmations and forms with unsaved input, no: an accidental click outside the box should not delete data or discard typing. Require an explicit button press for anything irreversible.

Can I use the native HTML dialog element instead of a custom modal?

Often yes. The native dialog element with showModal() gives you focus trapping, Escape handling, top-layer stacking, and a ::backdrop pseudo-element for free, with no z-index management. You still have to lock body scroll and animate it yourself, and older browsers need a fallback. Tell MeDo you want the native element and it will build on top of it instead of reimplementing the behavior.

How should a modal behave on mobile?

Below roughly 640px, a bottom sheet usually beats a centered card: it anchors the primary action near the thumb, uses the full width for form fields, and matches the platform convention users already know. MeDo can generate both layouts in one component and switch between them at a breakpoint you name.

Does a modal need role dialog and aria-modal?

Yes, unless you are using the native dialog element, which supplies the semantics itself. A custom overlay needs role="dialog", aria-modal="true", and either aria-labelledby pointing at the visible title or aria-label when there is no visible heading. Without aria-modal, screen readers continue to expose the page behind the overlay as browsable content.