MeDo

Generador de Menú Desplegable con IA.

Describe tus elementos y MeDo genera el menú completo — disparador, panel, secciones agrupadas con separadores, submenús, navegación con flechas y type-ahead, cierre con Escape y clic fuera, y foco que vuelve al disparador al cerrar.

Menú desplegable
Menú desplegable

Un menú es una sola parada de tabulación, y ahí está el error más común

El instinto es hacer que cada elemento sea enfocable, para que Tab los recorra uno a uno. El patrón ARIA menu hace lo contrario: todo el menú es una única parada de tabulación, y las flechas mueven un roving tabindex entre los elementos mientras Tab cierra el menú y lo abandona. Eso es lo que hace que saltar un menú de cuenta de 12 elementos cueste una pulsación en lugar de doce. También explica por qué los menús necesitan restauración explícita del foco: como el foco se movió al panel de forma programática, cerrar sin devolverlo al disparador deja al usuario de teclado al principio del documento. Generar el disparador y el panel como un solo componente mantiene ese viaje de ida y vuelta intacto, porque ambas mitades se escriben contra el mismo contrato de foco.

6 plantillas

Plantillas de Menú desplegable que puedes generar

Cada plantilla es un prompt real, no una captura de pantalla. Cópialo en cualquier editor de IA o ejecútalo en MeDo y obtén código React + Tailwind.

BasicAccount Menu

Avatar Trigger With Grouped Actions

The top-right menu every product has. Get the focus round trip right here and the rest of your menus inherit it — closing without returning focus drops keyboard users at the top of the document.

Create an account dropdown menu: a 32px avatar trigger with aria-haspopup="menu" and aria-expanded, and a 240px panel with role="menu" anchored 6px below it. Each row is role="menuitem", 32px tall, with a 16px leading icon. Use a roving tabindex so the whole menu is one tab stop — Tab closes it and leaves rather than walking the items. Enter, Space or Arrow Down opens the menu and focuses the first item; Arrow Up opens it focusing the last. Arrow Down and Up cycle with wrapping, Home and End jump to the ends, typing a letter jumps to the next item starting with it, Escape and outside pointerdown close it, and focus returns to the trigger on every close path. Group items with 1px dividers and style Sign out as a destructive red item in its own group.

Prueba en MeDo
Table rowRow Overflow

Three-Dot Menu on a Table Row

Repeated once per row, which makes the trigger label the real problem: twenty buttons all called "More options" tell a screen reader user nothing about which record they are about to delete.

Create a row-level overflow menu for a data table: a 32px icon-only three-dot trigger with aria-haspopup="menu", aria-expanded, and an accessible name that names its record — "More actions for invoice 1042" — so repeated triggers are distinguishable. The panel is role="menu" with Edit, Duplicate and Export, then a divider and a destructive Delete that opens a confirmation dialog and moves focus into it rather than acting immediately. Roving tabindex, Arrow Up and Down with wrapping, Home and End, single-letter type-ahead, Escape and outside pointerdown to close, focus back to the trigger. Close the menu when its ancestor scroll container scrolls, since an anchored panel detaches from a row that has moved.

Prueba en MeDo
NestedSubmenu

Parent Items With Nested Panels

One level of nesting, with a hover intent delay. Without the delay, dragging the pointer diagonally to the item you wanted opens and closes three submenus on the way there.

Create a dropdown menu with one level of submenus: the parent item carries aria-haspopup="menu", aria-expanded and a trailing chevron, and its child panel is a separate role="menu" anchored to the parent's right edge, flipping to the left when it would leave the viewport. Open the submenu on Arrow Right or Enter with focus on the first child, and on hover after a 150ms intent delay with a similar grace period before closing so a diagonal pointer path does not toggle three panels. Arrow Left closes the submenu and returns focus to the parent item; Escape closes the whole menu and focuses the trigger. Keep type-ahead scoped to the currently open panel, and do not nest a second level.

Prueba en MeDo
TogglesCheckable Items

Menu With Checkbox and Radio Rows

View options and sort order inside a menu. The roles change with the semantics — menuitemcheckbox for independent toggles, menuitemradio in a group for one-of-many — and so does whether the panel closes on select.

Create a view-options dropdown mixing checkable rows: a group of role="menuitemcheckbox" rows with aria-checked for column visibility, and below a divider a group of role="menuitemradio" rows inside role="group" with aria-labelledby a Sort by heading, where exactly one is aria-checked. Keep the panel open when a checkbox row is toggled so several can be set in one pass, and close it after a radio selection since the choice is complete. Reserve the check indicator column at a fixed width so labels do not shift when a state changes. Roving tabindex, Arrow Up and Down with wrapping, Home and End, Space toggles without closing, Enter selects, Escape closes and returns focus to the trigger.

Prueba en MeDo
NavigationNav Disclosure

Header Dropdown of Plain Links

Deliberately not a menu. A products dropdown holds links, so role="menu" would collapse them into one tab stop and stop cmd+click from opening a new tab.

Create a navigation dropdown for a marketing header that is a disclosure, not an ARIA menu: a trigger button with aria-expanded and aria-controls, and a panel containing a plain ul of anchor elements — no role="menu" or role="menuitem", so each link stays individually focusable and openable in a new tab with cmd+click or middle click. Tab moves through the links in order rather than a roving tabindex. Open on click and on Arrow Down, close on Escape with focus returning to the trigger, close on outside pointerdown, and close on focusout when focus leaves the panel entirely. Do not open on hover alone on touch devices. Mark the link matching the current route with aria-current="page".

Prueba en MeDo
FilterableSearch Menu

Long Menu With a Filter Field

Past roughly fifteen items, single-letter type-ahead stops being enough. Adding a text field changes the contract: the field keeps focus and the highlight moves by aria-activedescendant.

Create a filterable dropdown for a long list: a trigger with aria-haspopup and aria-expanded, and a panel whose first element is a search input that receives focus on open. Because a text field now holds focus, switch from a roving tabindex to the combobox approach — role="listbox" on the list, role="option" on rows, and aria-activedescendant on the input so Arrow Up and Down move the highlight while typing keeps working. Filter as the user types with a 150ms debounce, bold the matched substring, cap the list at 280px with internal scroll, and scroll the active option into view with block nearest. Show a no-matches row rather than an empty panel. Escape clears a non-empty filter first, then closes on a second press with focus returning to the trigger.

Prueba en MeDo

Cómo personalizar tu Menú desplegable

Di que es un menú de acciones, no un <select>

role="menu" indica a la tecnología asistiva que cada elemento ejecuta un comando. Si en cambio los elementos establecen un valor de formulario, pide un listbox o un <select> nativo. Usar un menú para un campo de formulario hace que los lectores de pantalla anuncien comandos donde el usuario espera opciones.

Especifica el retardo de intención de hover en los submenús

Pide unos 150ms de retardo antes de que se abra un submenú y un periodo de gracia similar antes de que se cierre. Sin él, arrastrar el puntero en diagonal por la lista padre abre y cierra tres submenús de camino al que querías.

Pide posicionamiento que evite colisiones de forma explícita

Indica que el panel debe voltearse por encima del disparador cerca del borde inferior y desplazarse horizontalmente para seguir visible. Un menú anclado a un avatar en la esquina superior derecha es el caso más común en el que un desplazamiento fijo deja la mitad de los elementos fuera de pantalla.

Separa el elemento destructivo

Coloca acciones como Cerrar sesión, Eliminar o Revocar acceso en su propio grupo debajo de un divisor y pide el tratamiento de color destructivo. Lo que evita el clic accidental es la distancia física respecto a los elementos rutinarios, no el texto rojo.

Quién usa el componente Menú desplegable

Producto SaaS

Un menú de avatar arriba a la derecha con el correo de la cuenta como fila de encabezado estática, luego enlaces de perfil y facturación, un submenú de equipo, un conmutador de tema y Cerrar sesión aislado bajo un divisor.

Panel de control o herramienta de administración

Un menú de desbordamiento a nivel de fila detrás de un botón de tres puntos, con Editar, Duplicar, Exportar y un Eliminar destructivo, con el disparador etiquetado por la fila a la que pertenece para que los lectores de pantalla anuncien sobre qué registro se está actuando.

Editor de contenido

Un menú de inserción de bloques con tipos de elemento agrupados, un submenú de proveedores de embed y salto por letra con type-ahead para que quien conozca la lista llegue a un elemento sin recorrerla con las flechas.

Navegación de sitio de marketing

Un desplegable de productos en la barra de navegación construido a partir de una lista simple de enlaces en lugar de role="menu", para que el panel se comporte como la navegación que es y los enlaces sigan siendo enfocables individualmente y abribles en una pestaña nueva.

Patrones de Menú desplegable para distintos sitios web

El mismo componente menú desplegable, adaptado al tipo de sitio donde se publica.

01 / 06

SaaS Account Menu

Avatar trigger, the account email as a static non-focusable header row, then profile and billing links, a team submenu and Sign out below a divider. Keep the email row out of the roving tabindex — a label that takes an arrow keypress to skip reads as a broken menu item.

Estilos y variantes de Menú desplegable

Elige la variante que encaje con el resto de la página y genérala.

01 / 06

Grouped Action Menu

Rows split into two or three sections by 1px dividers, with the destructive action alone at the bottom. The physical gap is what prevents the misclick on Sign out or Delete — red text alone does not, because the pointer is already moving before the color registers.

Menú desplegable en React, Next.js, Vue y Svelte

React, Next.js, Vue 3, SvelteKit, Astro o HTML puro: el mismo menú desplegable, seis formas de integrarlo.

01 / 06

React Dropdown Menu

Hold the active index in state and derive tabIndex from it — that is the roving tabindex. Keep a ref to the trigger and focus it in the close handler, since the browser will not restore focus for you.

src/components/Menu.tsx

const [open, setOpen] = useState(false)
const [active, setActive] = useState(0)
const triggerRef = useRef(null)

function close() {
  setOpen(false)
  triggerRef.current?.focus()
}

<button ref={triggerRef} aria-haspopup="menu" aria-expanded={open}>
  Account
</button>

Cómo añadir tu Menú desplegable a un proyecto

Cuatro pasos, desde elegir una plantilla de menú desplegable hasta llevarlo a producción.

01~30s

Pick a Menu Template

Answer one question first: do the items run commands or navigate? Actions get the menu templates and their roving tabindex; links get the navigation disclosure, where every anchor stays its own tab stop.

02~10s

Copy the Prompt

Take the prompt into MeDo, Lovable, Bolt, v0 or Cursor and list your real items with the dividers where you want them. Say which item is destructive and which opens a submenu, since both change the generated markup.

03~1min

Generate and Refine

You get React + Tailwind back with a live preview. Follow up in plain English — "add a filter field", "flip above the trigger near the bottom edge", "turn Sort into radio items" — instead of touching the keydown handler.

04~2min

Wire the Actions and Ship

Connect each item to its handler, then verify the focus round trip with the keyboard alone: open, arrow down, Escape, and confirm focus lands back on the trigger rather than the top of the page.

Preguntas frecuentes sobre Menú desplegable

¿Cómo genero un menú desplegable con IA?

Enumera los elementos que quieres, indica cuáles abren submenús y di dónde van los divisores. MeDo genera el disparador, el panel anclado, los elementos agrupados y el manejo del teclado como un solo componente, de modo que las flechas, Escape, el clic fuera y la restauración del foco quedan conectados antes de que lo abras.

¿Cuál es la diferencia entre un menú desplegable y un <select>?

Un menú invoca acciones: elegir un elemento hace algo de inmediato y no se almacena nada. Un <select> guarda un valor de formulario: elegir una opción cambia un estado que se envía después. Usan roles distintos y contratos de teclado distintos, y confundir uno con otro es el defecto de accesibilidad más habitual en los desplegables personalizados.

¿Debe un desplegable de navegación usar role="menu"?

No. role="menu" es para menús de comandos de estilo aplicación, y aplicarlo a una lista de enlaces hace que cada enlace se anuncie como menuitem y los colapsa en una sola parada de tabulación. Un desplegable de navegación debe ser una lista simple de anclas dentro de un disclosure que el disparador alterna con aria-expanded. Dile a MeDo que el panel es navegación y generará enlaces en lugar de elementos de menú.

¿Cómo debe funcionar la navegación por teclado en un menú desplegable?

Enter, Space o Flecha Abajo abren el menú y enfocan el primer elemento. Flecha Arriba y Abajo se mueven entre elementos y dan la vuelta en los extremos, Home y End saltan al primero y al último, y escribir una letra pasa al siguiente elemento que empiece por ese carácter. Flecha Derecha abre un submenú, Flecha Izquierda lo cierra, y Escape o Tab cierran todo el menú devolviendo el foco al disparador.

¿Puede la IA generar un menú desplegable con submenús?

Sí. Describe el anidamiento y MeDo genera el elemento padre con aria-haspopup, el panel hijo, el retardo de intención de hover y los enlaces de teclado de Flecha Derecha y Flecha Izquierda. Mantén el anidamiento en un solo nivel cuando puedas, ya que un segundo nivel es difícil de alcanzar con el puntero y difícil de describir a quien usa un lector de pantalla.

¿Debe un menú desplegable cerrarse al hacer clic fuera?

Sí, y también debería cerrarse con Escape, al hacer scroll en un contenedor ancestro y al volver a pulsar el disparador. Registra el listener externo en pointerdown en lugar de click para que un arrastre que empiece fuera del panel lo cierre, y devuelve siempre el foco al disparador para que los usuarios de teclado no acaben al principio de la página.