AI Dropdown Menu Generator.

Describe your items and MeDo generates the full menu — trigger, panel, grouped sections with separators, submenus, arrow-key and type-ahead navigation, Escape and click-outside dismissal, and focus that returns to the trigger on close.

Dropdown Menu
Dropdown Menu

A Menu Is a Single Tab Stop, and That Is the Part People Get Wrong

The instinct is to make every item focusable, so Tab walks through them one by one. The ARIA menu pattern does the opposite: the whole menu is one tab stop, and arrow keys move a roving tabindex between items while Tab closes the menu and leaves it. That is what makes a 12-item account menu cost one keystroke to skip instead of twelve. It also explains why menus need explicit focus restoration: since focus was moved into the panel programmatically, closing without sending it back to the trigger drops the keyboard user at the top of the document. Generating the trigger and panel as one component keeps that round trip intact, because the two halves are written against the same focus contract.

6 templates

Dropdown Menu 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.

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.

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

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

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

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

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

Try in MeDo

How to Customize Your Dropdown Menu

Say it is a menu of actions, not a select

role="menu" tells assistive tech that every item runs a command. If the items instead set a form value, ask for a listbox or a native select. Using a menu for a form field makes screen readers announce commands where the user expects options.

Name the hover intent delay for submenus

Ask for roughly a 150ms delay before a submenu opens and a similar grace period before it closes. Without it, dragging the pointer diagonally across the parent list opens and closes three submenus on the way to the one you wanted.

Ask for collision-aware positioning explicitly

Say the panel should flip above the trigger near the bottom edge and shift horizontally to stay in view. A menu anchored to an avatar in a top-right corner is the most common case where a fixed offset renders half the items off screen.

Separate the destructive item

Put actions like Sign out, Delete, or Revoke access in their own group below a divider and ask for the destructive color treatment. Physical distance from routine items is what prevents the misclick, not the red text.

Who Uses the Dropdown Menu Component

SaaS product

An avatar menu in the top-right with the account email as a static header row, then profile and billing links, a team submenu, a theme toggle, and Sign out isolated below a divider.

Dashboard or admin tool

A row-level overflow menu behind a three-dot icon button, holding Edit, Duplicate, Export, and a destructive Delete, with the trigger labeled by the row it belongs to so screen readers announce which record is being acted on.

Content editor

A block insert menu with grouped item types, a submenu of embed providers, and type-ahead letter jumping so someone who knows the list can reach an item without arrowing through it.

Marketing site navigation

A products dropdown in the navbar built from a plain list of links rather than role="menu", so the panel behaves like the navigation it is and links stay individually focusable and openable in a new tab.

Dropdown Menu Patterns for Different Websites

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

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.

Dropdown Menu Styles and Variants

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

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.

Dropdown Menu in React, Next.js, Vue and Svelte

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

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>

How to Add Your Dropdown Menu to a Project

Four steps, from picking a dropdown menu template to shipping it in production.

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.

Common Questions About Dropdown Menu

How do I generate a dropdown menu with AI?

List the items you want, note which ones open submenus, and say where the dividers go. MeDo generates the trigger, the anchored panel, the grouped items, and the keyboard handling as one component, so arrow keys, Escape, click-outside, and focus restoration are wired before you ever open it.

What is the difference between a dropdown menu and a select?

A menu invokes actions, so choosing an item does something immediately and nothing is stored. A select holds a form value, so choosing an option changes state that is submitted later. They use different roles and different keyboard contracts, and swapping one for the other is the most common accessibility defect in custom dropdowns.

Should a navigation dropdown use role="menu"?

No. role="menu" is for application-style command menus, and applying it to a list of links makes each link announce as a menuitem while collapsing them into a single tab stop. A navigation dropdown should be a plain list of anchors inside a disclosure that the trigger toggles with aria-expanded. Tell MeDo the panel is navigation and it will generate links rather than menu items.

How should keyboard navigation work in a dropdown menu?

Enter, Space, or Arrow Down opens the menu and focuses the first item. Arrow Up and Down move between items and wrap at the ends, Home and End jump to the first and last, and typing a letter moves to the next item starting with that character. Arrow Right opens a submenu, Arrow Left closes it, and Escape or Tab closes the whole menu with focus returning to the trigger.

Can AI generate a dropdown menu with submenus?

Yes. Describe the nesting and MeDo generates the parent item with aria-haspopup, the child panel, the hover intent delay, and the Arrow Right and Arrow Left bindings. Keep nesting to one level where you can, since a second level is hard to hit with a pointer and hard to describe to a screen reader user.

Does a dropdown menu need to close on click outside?

Yes, and it should also close on Escape, on scroll of an ancestor container, and when the trigger is clicked again. Attach the outside listener on pointerdown rather than click so a drag that starts outside the panel dismisses it, and always return focus to the trigger so keyboard users are not dropped at the top of the page.