Build Six Hold-to-Play Piano Keys with Vanilla Web APIs
Company: Roblox
Role: Frontend Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
## Prompt
Build a six-key piano interface for notes `C`, `D`, `E`, `F`, `G`, and `A` using only vanilla HTML, CSS, and JavaScript. The stylesheet already defines the visual class `.key.active`.
The interaction requirements are:
- Holding the primary mouse button down on a piano key adds `active`; releasing the button removes it immediately, including when release occurs outside the original element.
- Holding the physical keyboard letters `c`, `d`, `e`, `f`, `g`, or `a` activates the corresponding keys until each matching keyup.
- Several physical keys may be held at once and remain active independently.
- Any other keyboard input is ignored.
- Repeated `keydown` events generated while a key is held must not corrupt state.
Explain the event model, state representation, cleanup, and accessibility behavior. Provide one compact, complete executable-style vanilla HTML/JavaScript example containing all six labeled controls and all required listeners.
### Constraints & Assumptions
- Each note element has a stable `data-note` value and the shared `key` class.
- Mouse and keyboard can refer to the same note at the same time; releasing one source must not deactivate a note still held by the other source.
- The page can lose focus while keys are held, so state needs a blur or visibility cleanup path.
- Audio playback is outside this exercise; only visual pressed state is required.
- Key matching is case-insensitive and based on the typed letter, not a locale-specific label.
- Piano shortcuts do not activate from an input, textarea, select, or editable target. A matching `keyup` still performs release cleanup even if focus moved into such a target after `keydown`.
### Clarifying Questions to Ask
- Should mouse dragging between keys activate new notes? No; only the key on which the press began is associated with that press.
- Must mouse and keyboard sources compose? Yes.
- Should keyboard auto-repeat retrigger state? No.
- What accessible roles, labels, focus behavior, and reduced-motion considerations apply?
- Is touch support required now or an extension?
```hint Track sources rather than one Boolean
For each note, retain the set of active input sources. The element is visually active while that set is nonempty.
```
### What a Strong Answer Covers
- Six semantic, labeled buttons with data-driven note lookup and `aria-pressed` synchronized with `.active`.
- Delegated or per-key mouse handlers plus document-level release handling so release outside cannot stick a key.
- Independent keyboard-held state, explicit editable-target policy, repeat-safe source tokens, normalization, and invalid-key filtering.
- Correct composition when mouse and keyboard simultaneously hold the same note.
- Cleanup on blur, visibility loss, element removal, and ordinary release.
- Minimal DOM writes through one render helper and tests for simultaneous and interleaved inputs.
- Accessibility that does not hijack unrelated typing contexts without a stated focus policy.
### Follow-up Questions
1. What bug appears if state is only one Boolean per note?
2. How would pointer events and pointer capture add touch and stylus support?
3. Should global keyboard shortcuts fire while a user types in an input field?
4. How would you test a mouse release outside the piano?
5. What cleanup is needed when the browser tab becomes hidden?
Quick Answer: Build six accessible hold-to-play piano keys with vanilla HTML, CSS, and JavaScript. Mouse and keyboard presses must compose correctly across simultaneous inputs, auto-repeat, outside release, editable targets, focus loss, and cleanup.