Question presented to candidate: "Build a segmented control, the pill-shaped row of options you see in a calendar for Day / Week / Month. Exactly one option is selected, a highlight slides to it when the selection changes, and the parent page owns the value. It must work with the keyboard and announce correctly to screen readers."
Requirements:
- Props: an
optionsarray (value,label), the currentvalue, anonChangecallback (or two-way binding in Vue and Angular) and alabelfor the group. - Fully controlled: the component never changes its own selection; when the parent changes
value(for example a "Reset" button), the control follows. - Semantics of a single-choice group:
role="radiogroup"with an accessible name, each optionrole="radio"witharia-checked. - Roving tabindex: only the selected option is in the Tab order. Arrow Right / Down select the next option, Arrow Left / Up the previous, both wrapping; Home and End select the first and last.
- A single indicator element slides under the selected option with a CSS transition, disabled for reduced motion. Several controls on one page work independently.
What a strong answer should cover:
- Controlled versus uncontrolled components, and deriving the selected index from
valueinstead of storing it. - Why this is a radio group (a choice of value), not a tab list (which switches panels), and what that changes in roles.
- Roving tabindex, and moving focus together with selection.
- Animating the indicator: equal-width segments allow a pure
translateX(index * 100%); unequal widths require measuring with layout APIs. - Reduced-motion support and readable behaviour at narrow widths.
Clarifying questions expected:
- "Are all segments the same width, or do they size to their labels?"
- "Can an option be disabled?"
- "Should arrow keys select immediately, or only move focus?"
Code / implementation expected: Yes. A reusable controlled component and a demo with two instances and a parent-side reset.