Hone logo
Hone
Problems

React Pagination Component with TypeScript

Building a pagination component is a common requirement in web applications dealing with large datasets. This challenge asks you to create a reusable React component that efficiently displays data in manageable chunks, allowing users to navigate through pages. A well-implemented pagination component enhances user experience by preventing overwhelming displays and improving performance.

Problem Description

You are tasked with creating a Pagination component in React using TypeScript. This component should take a totalItems (number), itemsPerPage (number), and currentPage (number) as props and render a set of page numbers and navigation buttons (Previous, Next, First, Last). The component should also provide a callback function onPageChange that is called when a user clicks on a page number or navigation button.

Key Requirements:

  • Display Page Numbers: Render page numbers based on totalItems, itemsPerPage, and the current page. The number of visible page numbers should be limited to a reasonable range (e.g., 5-7 pages visible at a time, with ellipses (...) indicating hidden pages).
  • Navigation Buttons: Include "Previous," "Next," "First," and "Last" buttons. These buttons should update the currentPage prop when clicked.
  • Disabled States: Disable the "Previous" button on the first page, the "Next" button on the last page, the "First" button on the first page, and the "Last" button on the last page.
  • Callback Function: Provide an onPageChange prop that accepts a function. This function should be called with the new currentPage value whenever the user navigates to a different page.
  • Typescript: The component must be written in TypeScript with appropriate type definitions for props and state.

Expected Behavior:

  • The component should accurately calculate and display the correct page numbers and navigation buttons based on the provided props.
  • Clicking on a page number should update the currentPage prop and call the onPageChange callback with the new page number.
  • Clicking on navigation buttons should update the currentPage prop and call the onPageChange callback with the new page number.
  • Disabled buttons should not be clickable and should visually indicate their disabled state.

Edge Cases to Consider:

  • totalItems is 0: The component should render nothing or a message indicating no items are available.
  • itemsPerPage is 0: Handle this gracefully, potentially displaying an error message or defaulting to a reasonable value.
  • currentPage is out of bounds (less than 1 or greater than the total number of pages): Clamp the currentPage to the valid range and update the state accordingly.
  • Large totalItems and small itemsPerPage: Ensure the pagination logic handles this efficiently without rendering an excessive number of page numbers.

Examples

Example 1:

Input: totalItems = 100, itemsPerPage = 10, currentPage = 5, onPageChange = (page) => console.log("Page changed to:", page)
Output:  [Page 1] ... [Page 3] [Page 4] [Page 5] [Page 6] [Page 7] ... [Page 10]
Explanation:  The component displays page numbers around the current page (5), with ellipses indicating hidden pages.  Clicking on any page number or navigation button should call the `onPageChange` function with the new page number.

Example 2:

Input: totalItems = 25, itemsPerPage = 5, currentPage = 1, onPageChange = (page) => console.log("Page changed to:", page)
Output: [Page 1] [Page 2] ... [Page 5]
Explanation: The component displays the first few pages, as the total number of pages is 5. The "Previous" and "First" buttons should be disabled.

Example 3:

Input: totalItems = 15, itemsPerPage = 10, currentPage = 2, onPageChange = (page) => console.log("Page changed to:", page)
Output: [Page 1] [Page 2] ... [Page 3]
Explanation: The component displays page numbers around the current page (2), with ellipses indicating hidden pages.

Constraints

  • The component should be reusable and accept props for customization.
  • The component should be visually appealing and user-friendly.
  • The component should handle edge cases gracefully.
  • The component should be performant, even with a large number of items.
  • totalItems, itemsPerPage, and currentPage must be numbers. currentPage must be a positive integer.

Notes

  • Consider using CSS or a CSS-in-JS library for styling.
  • Think about how to handle the display of ellipses (...) to indicate hidden pages.
  • Focus on creating a clean and well-structured component with clear type definitions.
  • You can use any React hooks (e.g., useState, useEffect) to manage the component's state.
  • The number of visible page numbers can be a configurable prop if you want to extend the component further.
Loading editor...
typescript