Design a Reusable Dropdown Menu Component
Company: Roblox
Role: Frontend Engineer
Category: System Design
Difficulty: medium
Interview Round: Onsite
# Design a Reusable Dropdown Menu Component
You are building a UI component library used across a large web application. Design a reusable **dropdown menu / select** component: the kind that shows a trigger button and, when activated, reveals a floating list of options the user can choose from.
The component must be production-quality — usable by other engineers on many different screens, accessible to keyboard and screen-reader users, and robust when the option list is long or loaded asynchronously. Walk through the component's public API, its interaction and accessibility model, and how it renders and positions the floating list.
### Constraints & Assumptions
- Framework: a modern declarative component framework (e.g., React); the design should translate to any such framework.
- The component renders a **trigger** (button) and a **popup list** of options shown on open.
- Single-select is the baseline; multi-select is a likely future extension.
- Option lists may range from a handful of items to several thousand (async / searchable).
- Must work with mouse, touch, and keyboard, and meet WAI-ARIA expectations.
- The library has a theming system (design tokens / CSS variables) the component must respect.
### Clarifying Questions to Ask
- Is this a **menu** (a list of actions) or a **select / listbox** (value selection)? The ARIA pattern and semantics differ.
- Single-select or multi-select? Is a searchable / typeahead variant required?
- Controlled vs. uncontrolled — do consumers own the open state and selected value, or should the component manage it internally?
- How large can the option list get, and are options static or fetched asynchronously?
- What are the positioning constraints — can the popup overflow scroll containers, and should it flip when near a viewport edge?
- What browser / accessibility support matrix and i18n (RTL) requirements apply?
### Part 1 — Component API and state model
Design the **public API**: the props / inputs the component exposes, how consumers supply and render options, and how open / selected state is managed. Decide what to expose for both simple use and advanced customization.
```hint Where to start
Separate "data in" (options, value) from "events out" (onChange, onOpenChange). Pick a default — uncontrolled with internal state — but allow a fully controlled mode by accepting both `value` and `onChange`.
```
```hint Customization without prop-explosion
Instead of one prop per feature, consider a render-prop / slot / compound-component approach (`<Select.Trigger>`, `<Select.Option>`) so consumers can customize option rendering and the trigger without you anticipating every case.
```
#### What This Part Should Cover
```premium-lock What This Part Should Cover
```
### Part 2 — Accessibility and keyboard interaction
Specify the **accessibility model** and the full keyboard behavior so the component is usable without a mouse and announces correctly to screen readers.
```hint ARIA pattern
Map to the WAI-ARIA combobox / listbox pattern: the trigger carries `aria-haspopup` / `aria-expanded`, the list is `role="listbox"`, options are `role="option"` with `aria-selected`, and `aria-activedescendant` tracks the focused option.
```
#### Clarifying Questions for this Part
- Should DOM focus move into the list, or stay on the trigger using `aria-activedescendant`?
- Is typeahead (jump to an option by typing its first letters) required?
#### What This Part Should Cover
```premium-lock What This Part Should Cover
```
### Part 3 — Rendering, positioning, and performance
Describe how the popup is **rendered and positioned**, and how the component stays performant with large or asynchronously-loaded option lists.
```hint Escaping overflow
Render the popup in a portal at the document root so it is not clipped by an `overflow: hidden` ancestor; compute its position relative to the trigger and reposition on scroll / resize.
```
```hint Big lists
For thousands of options, virtualize the list (render only visible rows) and debounce async search; show explicit loading and empty states.
```
#### What This Part Should Cover
```premium-lock What This Part Should Cover
```
### What a Strong Answer Covers
```premium-lock What a Strong Answer Covers
```
### Follow-up Questions
- How would you extend the single-select design to **multi-select** with checkboxes and a summarized trigger label?
- A consumer reports the dropdown is clipped inside a scrollable modal. Walk through how your positioning approach prevents or fixes this.
- How would you make the option list **searchable** with server-side filtering, and what would you debounce or cache?
- How would you unit / integration test the keyboard and screen-reader behavior in CI?
Quick Answer: This question assesses a candidate's ability to design a reusable, production-grade UI component, covering public API design, controlled versus uncontrolled state, and accessibility semantics. It is commonly used in frontend system design interviews to evaluate architectural judgment around component libraries, keyboard interaction, and performance with large or asynchronous data sets, testing practical application rather than pure theory.