UNPKG

glide-design-system

Version:

Glide design system is an open-source React component library. It offers numerous benefits that make them essential tools for design and development teams.

290 lines (276 loc) 9.27 kB
import React, { useState, useEffect } from "react"; import "./pagination.css"; import PropTypes from "prop-types"; /** * A pagination component * * @param {function} onChange - Callback function when a page is changed. * @param {number} page - Current active page. * @param {number} count - Total number of pages. * @param {string} color - Background color for active page. * @param {string} className - custom class for styles */ export const Pagination = ({ onChange, page, count, color, className, containerClass, style, }) => { const [lastElement, setLastElement] = useState(false); const [more, setMore] = useState(false); const [pages, setPages] = useState(page); const [renderCounter, setRenderCounter] = useState( count > 10 ? [1, 2, 3, 4, 5, 6] : [1, 2, 3] ); useEffect(() => { setRenderCounter(count > 10 ? [1, 2, 3, 4, 5, 6] : [1, 2, 3, 4]); }, [count]); return ( <div className={`paginationParentContainer ${ containerClass ? containerClass : "" }`} > <div id="previous-page" className={`paginationChildContainer ${className ? className : ""}`} style={{ ...style }} onClick={() => { // this if conditions for morethan a 10 pages if (count > 10) { setPages(page - 1); if (page < 7) { setLastElement(false); setMore(false); setRenderCounter([1, 2, 3, 4, 5, 6]); } } onChange && (count || count !== 0) && page - 1 > 0 && onChange(page - 1); }} > <span className="material-symbols-outlined paginationIcon"> chevron_left </span> </div> {count <= 10 && ( <div style={{ display: "flex" }}> {Array.from({ length: count ? count : 0 })?.map((_, i) => { return ( <div key={i} id={`page-${i}`} data-testid={`page-${i}`} onClick={() => onChange && onChange(i + 1)} className={`paginationChildContainer ${ className ? className : "" }`} style={{ backgroundColor: i + 1 === page ? (color ? color : "#0a5b99") : "#ffffff", color: i + 1 === page ? "#ffffff" : "#333333", ...style, }} > <div className="pageCount">{i + 1}</div> </div> ); })} </div> )} {/* if the page has more than a 10 pages it will be nvoke */} {count > 10 && ( <div style={{ display: "flex", }} > <div id={`page-1`} onClick={() => { setMore(false); setRenderCounter([1, 2, 3, 4, 5, 6]); onChange && onChange(1); }} className={`paginationChildContainer ${className ? className : ""}`} style={{ backgroundColor: page === 1 ? "#0a5b99" : "#ffffff", color: page === 1 ? "white" : "", }} > {/* this div contains 1 st page default */} <div className="pageCount">{1}</div> </div> {renderCounter.map((i) => { return ( <div key={i} id={`page-${i}`} data-testid={`page-${i}`} onClick={() => { setRenderCounter(count > 10 ? [1, 2, 3, 4, 5, 6] : [1, 2, 3]); onChange && onChange(i + 1); if (pages >= 4) { setLastElement(false); setMore(false); } }} className={`paginationChildContainer ${ className ? className : "" }`} style={{ backgroundColor: i + 1 === page ? (color ? color : "#0a5b99") : "#ffffff", color: i + 1 === page ? "#ffffff" : "#333333", ...style, }} > <div className="pageCount">{i + 1}</div> </div> ); })} {pages < count - 2 && more && page >= 5 && ( <> {/*This area responsible for If the user reaches a page beyond the seventh, this div invokes, and the closest three pages to the current page will be shows */} <div style={{ marginRight: "5px" }}>....</div> <div id={`page-${page - 2}`} style={{ backgroundColor: page - 2 === pages ? "#0a5b99" : "#ffffff", color: page - 2 === pages ? "white" : "", }} onClick={() => { onChange && onChange(page - 2); }} className={`paginationChildContainer ${ className ? className : "" }`} > <div className="pageCount">{page - 2}</div> </div> <div id={`page-${page - 1}`} style={{ backgroundColor: page - 1 === pages ? "#0a5b99" : "#ffffff", color: page - 1 === pages ? "white" : "", }} onClick={() => { onChange && onChange(page - 1); }} className={`paginationChildContainer ${ className ? className : "" }`} > <div className="pageCount">{page - 1}</div> </div> <div id={`page-${page}`} style={{ backgroundColor: "#0a5b99", color: "white", }} onClick={() => { onChange && onChange(page); }} className={`paginationChildContainer ${ className ? className : "" }`} > <div className="pageCount">{page}</div> </div> </> )} <div style={{ marginRight: "5px" }}>....</div> {/*This area responsible for If the user reaches a last page this div invokes, and the last three pages will be shows */} {pages >= count - 2 && lastElement && ( <div style={{ display: "flex" }}> <div id={`page-${count - 2}`} onClick={() => { setLastElement(true); onChange && onChange(count - 2); }} style={{ backgroundColor: page === count - 2 ? "#0a5b99" : "#ffffff", color: page === count - 2 ? "white" : "", }} className={`paginationChildContainer ${ className ? className : "" }`} > <div className="pageCount">{count - 2}</div> </div> <div id={`page-${count - 1}`} style={{ backgroundColor: page === count - 1 ? "#0a5b99" : "#ffffff", color: page === count - 1 ? "white" : "", }} onClick={() => { onChange && onChange(count - 1); }} className={`paginationChildContainer ${ className ? className : "" }`} > <div className="pageCount">{count - 1}</div> </div> </div> )} {/* this div contains last page by default */} <div id={`page-${count}`} style={{ backgroundColor: page === count ? "#0a5b99" : "#ffffff", color: page === count ? "white" : "", }} onClick={() => { setMore(true); setLastElement(true); setPages(count); setRenderCounter([1]); onChange && onChange(count); }} className={`paginationChildContainer ${className ? className : ""}`} > <div className="pageCount">{count}</div> </div> </div> )} <div id="next-page" className={`paginationChildContainer ${className ? className : ""}`} style={{ ...style }} onClick={() => { if (count > 10) { setPages(page + 1); if (page >= 7) { setLastElement(true); setMore(true); setRenderCounter([1]); } } onChange && (count || count !== 0) && page + 1 <= count && onChange(page + 1); }} > <span className="material-symbols-outlined paginationIcon"> chevron_right </span> </div> </div> ); }; Pagination.propTypes = { onChange: PropTypes.func, count: PropTypes.number, page: PropTypes.number, color: PropTypes.string, };