import React, { forwardRef, useEffect, useImperativeHandle, useState, } from 'react'; import styles from './Pagination.scss'; import { STORYBOOK_VALS, transparentizeColour } from '../../utils'; export interface PaginationProps { totalItems: number, itemsPerPage: number, maxPageNumbersDisplayed: number, onPaginate: Function, currentPage?: number, vSize?: number, variant?: 'bordered', mainColor?: string, textColor?: string, backgroundColor?: string, hoverColor?: string, borderColor?: string, className?: string, disableArrows?: boolean, enableStrokeAnimation?: boolean, enableArrowBorder?: boolean, enableArrowBackground?: boolean, enableArrowCheck?: boolean, } const DEFAULT_TEXT_COLOR = '#000000'; export const Pagination = forwardRef((props: PaginationProps, ref) => { const [currentPage, setCurrentPage] = useState(props.currentPage || 1); const setMaxPagesDisplayed = (maxPages: number): number => { let validMaxPages: boolean = false let currentMax: number = maxPages while (!validMaxPages) { currentMax++ if (currentMax > 3 && currentMax % 2 != 0) { validMaxPages = true break } } return currentMax } const setPageNumbers = (totalItems: number, itemsPerPage: number): number[] => { let pageNumbers: number[] = [] for (let i = 1; i <= Math.ceil(totalItems / itemsPerPage); i++) { pageNumbers.push(i) } return pageNumbers } const setPageSlices = (pageNumbers: number[], maxPageNumbersDisplayed: number): number[] => { const pageSliceSize = maxPageNumbersDisplayed - 2 if (pageNumbers.length - maxPageNumbersDisplayed >= 2) { if (currentPage < pageSliceSize + 1) { return pageNumbers.slice(0, pageSliceSize + 1) } else if (pageNumbers.length - currentPage < pageSliceSize) { return pageNumbers.slice( pageNumbers.length - pageSliceSize - 1, pageNumbers.length, ) } else { return pageNumbers.slice( currentPage - (pageSliceSize - 1) / 2 - 1, currentPage + (pageSliceSize - 1) / 2, ) } } else { return pageNumbers } } const paginate = (pageNumber: number) => { pageNumbers.length + 1 > pageNumber && pageNumber > 0 ? setCurrentPage(pageNumber) : null } const setTheme = (): any => { let cssProperties: any = [] cssProperties['--vsize'] = vSize cssProperties['--selected'] = mainColor cssProperties['--text'] = textColor cssProperties['--bg'] = backgroundColor cssProperties['--selected-hover'] = transparentizeColour(hoverColor, 0.6) cssProperties['--border-color'] = transparentizeColour(borderColor, 0.5) return cssProperties } let mainColor = props.mainColor ? props.mainColor : STORYBOOK_VALS.lightGray let backgroundColor = props.backgroundColor ? props.backgroundColor : STORYBOOK_VALS.smokeBg let textColor = props.textColor ? props.textColor : DEFAULT_TEXT_COLOR let borderColor = props.borderColor ? props.borderColor : STORYBOOK_VALS.darkGray let hoverColor = props.hoverColor ? props.hoverColor : mainColor let itemsPerPage = props.itemsPerPage > 1 ? props.itemsPerPage : 1 let totalItems = props.totalItems > 1 ? props.totalItems : 1 let vSize = props.vSize ? props.vSize : 2 let maxPageNumbersDisplayed = props.maxPageNumbersDisplayed > 3 && props.maxPageNumbersDisplayed % 2 != 0 ? props.maxPageNumbersDisplayed : setMaxPagesDisplayed(props.maxPageNumbersDisplayed) const pageNumbers: number[] = setPageNumbers(totalItems, itemsPerPage) let slicedPageNumbers: number[] = setPageSlices(pageNumbers, maxPageNumbersDisplayed) useEffect(() => { props.onPaginate(currentPage) }, [currentPage]) useImperativeHandle(ref, () => { return { paginate: paginate, } }) const renderArrows = (direction: string): any => { let valid = true; if (direction == 'left' && props.enableArrowCheck && currentPage <= 1) { valid = false; } else if (direction == 'right' && props.enableArrowCheck && currentPage >= totalItems) { valid = false; } if (valid) { return (
); } } return ( <> {pageNumbers.length > 1 && ( )} > ) })