Question presented to candidate: "Build a reusable pagination control. The parent tells it the current page and the total number of pages, and it tells the parent when the user picks a page. Show the first and last page, a few pages around the current one, ellipses for the rest, and Prev and Next buttons that are disabled at the ends. It should not jump around in width as I click through."
Requirements:
- A controlled component:
pageandtotalPagescome in, a page-change event or callback goes out; it keeps no page state of its own. - A page-window function: always show page 1, the last page, the current page and one sibling on each side; replace hidden runs with
…. - Constant width: once there are more than 7 pages the control always renders exactly 7 items, so buttons do not shift under the pointer.
- Never hide a single page behind
…(an ellipsis that stands for one page is worse than the page itself). - Prev and Next disabled on the first and last page; clicking the current page does nothing; nothing renders for a single page.
- A small demo: 194 results with a per-page selector that keeps the first visible result on screen when the page size changes.
What a strong answer should cover:
- The window algorithm written as a pure function that is easy to unit test, separate from rendering.
- Edge pages: 1, 2, 3, 4 and their mirrors at the end, totals of 1, 7 and 8, and the symmetry between both ends.
- Why ellipsis items need stable, distinct keys (
gap-leftandgap-right), not the index. - The controlled API (value in, event out) and where the page state lives.
- Accessibility: a
navlandmark with a label,aria-current="page", labelled Prev and Next, real buttons and a visible focus ring.
Clarifying questions expected:
- "How many siblings around the current page, and should that be configurable?"
- "Do we know the total, or is this a cursor-based API with only next and previous?"
- "Should First and Last be separate buttons, or is showing page 1 and the last page enough?"
Code / implementation expected: Yes. A pure pageItems(current, total, siblings) function plus a controlled component in React, Vue or Angular, with the edge cases demonstrated.