Question presented to candidate: "We need a reusable modal for confirmations. Build a 'Delete project?' dialog: a button opens it over the page, it has Cancel and Delete buttons and a close icon, and it can be dismissed with Escape or by clicking the dark overlay. The page should know how the dialog was closed."
Requirements:
- A reusable modal component with a title, a description and caller-supplied action buttons (children, slot or projected content).
- Rendered outside the app's DOM tree, directly under
body(portal / Teleport), above everything else, with a full-screen overlay. - Closes on Escape, on the close icon, on Cancel, and on a click on the overlay, but not on clicks inside the panel, and not when a text selection is dragged from the panel onto the overlay.
- Reports the reason it closed; the page shows the result.
role="dialog",aria-modal="true",aria-labelledbyandaria-describedby; focus moves into the dialog on open and returns to the trigger on close.
What a strong answer should cover:
- Why a portal: escaping
overflow: hidden,z-indexstacking contexts and transforms of ancestor elements. - Overlay click detection with
event.target === event.currentTarget, and the press-started-on-the-overlay check. - A document-level Escape listener added only while open, with cleanup.
- A controlled API: the parent owns
openand receives a close reason. - Knowing what this version does not do yet (focus trap, inert background, scroll lock) and where that is handled.
Clarifying questions expected:
- "Is this a confirmation (must answer) or an informational dialog (easy to dismiss)?"
- "Can dialogs stack, one on top of another?"
- "Should the page behind stop scrolling?"
Code / implementation expected: Yes. A reusable modal plus a demo page; around 100 to 150 lines.