Build Accessible Data-Loading Popovers for Multiple Buttons
AmazonFrontend Engineer · OnsiteLast updated
This problem tests the ability to build a robust, accessible UI component that manages asynchronous data fetching, state synchronization, and DOM-level focus management.
The Task
Create a reusable Popover component in React that triggers a data fetch upon opening and displays the result. Multiple buttons on the page may trigger different popovers, but only one should be open at a time.
Requirements
- Accessibility: Use appropriate ARIA roles (
aria-expanded,aria-describedby,aria-busy) and ensure keyboard focus is trapped or correctly managed when the popover opens. - State Management: Show a loading state while fetching, and handle the content display upon success.
- Race Condition Protection: If a user clicks a button, clicks another quickly, then clicks the first again, ensure the popover shows the result of the latest request triggered for that specific instance.
- Adaptive Positioning: The popover must appear anchored to the triggering button. You can assume a basic absolute positioning logic or describe how you would use a library like Floating UI.
- Cleanup: Close the popover when the user presses
Escor clicks outside.
Interface
function Popover({ triggerId, fetchData }) {
// fetchData is a function returning a Promise
// triggerId is a unique identifier
}
Examples
- Triggering: Clicking "Load User A" renders a popover at the button's coordinates, displays a spinner, and eventually renders the user profile.
- Keyboard: Pressing
Tabmoves focus to the button; pressingEnteropens the popover. PressingEsccloses it and returns focus to the button.
Constraints
- Assume standard browser support.
- Handle errors gracefully if
fetchDatafails.
Hints
Hint 1
Use a unique `id` for the popover content and link it to the button using `aria-controls` for screen reader navigation.
Hint 2
Implement a 'request ID' or an abort controller within the hook to ignore stale responses that resolve after a newer request has started.
Hint 3
Use a React Portal to render the popover in the document body to prevent z-index and overflow clipping issues.
Follow-up questions
- How would you optimize performance if you have 1,000 buttons on the page, each needing this functionality?
- How would you handle focus restoration if the button that triggered the popover is removed from the DOM while the popover is still open?
- Describe how you would unit test the 'stale-response' scenario using a testing library like Jest or Vitest.
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.