Question presented to candidate: "Build an Actions dropdown: a button that opens a short list of commands like Edit, Duplicate, Share and Delete. It should work with a mouse and with the keyboard alone, close when you click elsewhere or press Escape, and tell the page which item was picked."
Requirements:
- A trigger button toggles a menu of items; choosing an item reports it to the parent and closes the menu.
- Opening moves focus to the first item; ArrowDown and ArrowUp move between items and wrap; Home and End jump to the ends; ArrowUp on the closed trigger opens on the last item.
- Escape closes and returns focus to the trigger; Tab closes and lets focus continue; a pointer press outside the widget closes it.
- Correct ARIA:
aria-haspopup,aria-expandedandaria-controlson the trigger,role="menu"androle="menuitem"on the list.
What a strong answer should cover:
- A tiny state model:
openplus the index of the active item, with DOM focus moved after render, not during it. - Roving tabindex: only the active item has
tabindex="0", the rest-1, so Tab leaves the menu in one step. - Outside-click detection with
contains()on a listener that exists only while the menu is open, and its cleanup. - Why focus must return to the trigger on Escape and on selection, and why Tab should not be trapped in a menu.
- The ARIA menu-button pattern, and when a plain disclosure list is the better choice (site navigation).
Clarifying questions expected:
- "Are the items commands (a menu) or links to pages (navigation)? That changes the roles."
- "Can the list be long enough to need scrolling or type-ahead search?"
- "Does it need to flip upward near the bottom of the viewport?"
Code / implementation expected: Yes. A working component with keyboard support; about 100 lines in any framework.