tezvyn:

Headless components and a headless Combobox

AI-drafted, machine-checkedSource: interviewadvanced
WHAT IT TESTS

separating behavior from presentation.

OUTLINE

a headless component owns state, logic, and accessibility but renders no UI, exposing state and prop-getters so consumers supply markup.

WHAT THIS TESTS The interviewer is probing whether you understand the separation of concerns between interaction logic and presentation, and can apply it to a genuinely complex widget where accessibility and keyboard handling are the hard parts.

A GOOD ANSWER COVERS Define headless precisely: the component owns all behavior, state, and accessibility but renders no markup of its own, handing the consumer everything needed to wire up their own UI. This differs from merely unstyled, which still ships specific DOM. The benefit is maximum reuse and flexibility: one tested, accessible core powers many visual designs across products without forking logic, and teams can match any design language. The mechanism is typically a hook or render-prop API that returns state values and prop-getter functions that spread the correct attributes and handlers onto consumer elements.

For a Combobox, the headless core manages the input string, the filtered option list, open and closed state, the highlighted index, selection, and the keyboard model (arrow keys move the active option, Enter selects, Escape closes, typing filters). Crucially it also owns ARIA: roles, aria-expanded, aria-activedescendant, and id wiring between input and listbox. It exposes getInputProps, getMenuProps, getItemProps, and state like isOpen and highlightedIndex. The consumer renders the actual input, list, and items, spreading those prop-getters so behavior and accessibility come for free.

COMMON WRONG ANSWERS Saying headless just means no CSS while still dictating DOM structure. Forgetting accessibility, which is the main value the headless core encapsulates. Leaking internal state management so consumers must reimplement keyboard handling.

LIKELY FOLLOW-UPS How do prop-getters compose with consumer-provided handlers? How do you handle async option loading? Where do controlled versus uncontrolled value semantics live?

ONE CONCRETE EXAMPLE A useCombobox hook returns isOpen, highlightedIndex, and getInputProps, getMenuProps, and getItemProps. One product renders a flat dropdown and another renders grouped cards with avatars; both spread the same prop-getters, so keyboard navigation and screen-reader support are identical while the visuals differ completely.

Read the original → martinfowler.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.