diff --git a/src/App.tsx b/src/App.tsx index 189a990c8..1fa5531a5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,109 +1,57 @@ -import React from 'react'; +import React, { useState } from 'react'; import './App.css'; import { getNumbers } from './utils'; +import { Pagination } from './components/Pagination'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const items = getNumbers(1, 42).map(n => `Item ${n}`); +const TOTAL_ITEMS = 42; +const DEFAULT_PER_PAGE = 5; +const FIRST_PAGE = 1; + +const items = getNumbers(1, TOTAL_ITEMS).map(n => `Item ${n}`); export const App: React.FC = () => { + const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE); + const [currentPage, setCurrentPage] = useState(FIRST_PAGE); + + const fromIndex = (currentPage - 1) * perPage; + const fromItem = fromIndex + 1; + const toItem = Math.min(fromIndex + perPage, TOTAL_ITEMS); + const pageInfo = `Page ${currentPage} (items ${fromItem} - ${toItem} of ${TOTAL_ITEMS})`; + const selectedItems = items.slice(fromIndex, toItem); + + function handlePageChange(page: number) { + if (currentPage !== page) { + setCurrentPage(page); + } + } + + function handleSelectChange(count: number) { + setPerPage(count); + setCurrentPage(1); + } + return (

Items with Pagination

- Page 1 (items 1 - 5 of 42) + {pageInfo}

-
-
- -
- - -
+ - {/* Move this markup to Pagination */} -
    -
  • Item 1
  • -
  • Item 2
  • -
  • Item 3
  • -
  • Item 4
  • -
  • Item 5
  • + {selectedItems.map(item => ( +
  • + {item} +
  • + ))}
); diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx index e417a09fc..e8f41750e 100644 --- a/src/components/Pagination/Pagination.tsx +++ b/src/components/Pagination/Pagination.tsx @@ -1 +1,124 @@ -export const Pagination = () => {}; +import { getNumbers } from '../../utils'; +import classNames from 'classnames'; +import React from 'react'; + +interface PaginationProps { + total: number; + perPage?: number; + currentPage?: number; + onPageChange: (page: number) => void; + onSelectChange: (perPage: number) => void; +} + +const SELECT_OPTIONS = [3, 5, 10, 20]; +const DEFAULT_PER_PAGE = 5; +const FIRST_PAGE = 1; + +export const Pagination = ({ + total, + perPage = DEFAULT_PER_PAGE, + currentPage = FIRST_PAGE, + onPageChange, + onSelectChange, +}: PaginationProps) => { + const pageCount = Math.ceil(total / perPage); + const pageList: number[] = getNumbers(1, pageCount); + + function handlePageChange( + event: React.MouseEvent, + page: number, + ) { + event.preventDefault(); + + if (page === currentPage) { + return; + } + + if (page < 1 || page > pageCount) { + return; + } + + onPageChange(page); + } + + function handleSelectChange(event: React.ChangeEvent) { + const value: string = event.currentTarget.value; + + onSelectChange(Number(value)); + } + + return ( + <> +
+
+ +
+ + +
+ + + ); +};