UNPKG

hiromi

Version:

React components for Bulma. http://bulma.io/

186 lines (166 loc) 4.43 kB
import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { modifierClassList, defaultReactProps, defaultReactPropsValues } from '../utils'; import Link from '../Link'; const PageItems = ({pagesVisible, onChange, pageCount, currentPage, ...props}) => { let items = []; // compute minLeft and maxRight indeces of page buttons // which exclude first and last pages. let minLeft = currentPage - Math.floor(pagesVisible/2); if (minLeft < 2) minLeft = 2; let maxRight = minLeft + pagesVisible - 1; if (maxRight >= pageCount) { maxRight = pageCount - 1; minLeft = maxRight - pagesVisible + 1; if (minLeft < 2) minLeft = 2; } for (let i = 1; i <= pageCount; i++) { if ( i !== 1 && i !== pageCount && (i < minLeft || i > maxRight) ) { continue; } // If it's the min left visible, and there were skipped items if (i === minLeft && minLeft > 2) { items.push( <li key="min"> ... </li> ); } const active = i === currentPage; const className = classnames({ 'is-active': active }); items.push( <li key={i.toString()}> <Link className={className} onClick={onPaginate(onChange, i)} >{i}</Link> </li> ); // If it's the max right visible, and there will be skipped items if (i === maxRight && maxRight < pageCount - 1) { items.push( <li key="max"> ... </li> ); } } return <ul>{items}</ul>; }; const onPaginate = (onChange, pageIndex) => { return (event) => { let args = [...arguments]; args.splice(0, 0, pageIndex); onChange(...args); }; }; const LeftLevel = ({ hasFirst, hasPrevious, first, previous, onChange, currentPage, ...props }) => { let firstItem = hasFirst ? ( <Link onClick={onPaginate(onChange, 1)}>{first}</Link> ) : null; let previousItem = hasPrevious ? ( <Link onClick={onPaginate(onChange, currentPage - 1)}>{previous}</Link> ) : null; return ( <div className="level-left"> {firstItem} {previousItem} </div> ); }; const RightLevel = ({ hasNext, hasLast, next, last, onChange, pageCount, currentPage, ...props }) => { let lastItem = hasLast ? ( <Link onClick={onPaginate(onChange, pageCount)}>{last}</Link> ) : null; let nextItem = hasNext ? ( <Link onClick={onPaginate(onChange, currentPage + 1)}>{next}</Link> ) : null; return ( <div className="level-right"> {nextItem} {lastItem} </div> ); }; const Pagination = ({ currentPage, pageCount, hasFirst, first, hasPrevious, previous, hasNext, next, hasLast, last, className, onChange, pagesVisible, ...props }) => { let {classList, ...finalProps} = modifierClassList(props); classList = classnames('level', className, classList); const leftLevel = hasFirst || hasPrevious ? ( <LeftLevel hasFirst={hasFirst} hasPrevious={hasPrevious} first={first} previous={previous} onChange={onChange} currentPage={currentPage} /> ) : null; const rightLevel = hasNext || hasLast ? ( <RightLevel hasNext={hasNext} hasLast={hasLast} next={next} last={last} onChange={onChange} pageCount={pageCount} currentPage={currentPage} /> ) : null; return ( <div className={classList} {...finalProps}> {leftLevel} <div className="level-item has-text-centered"> <nav className="pagination" {...finalProps}> <PageItems pageCount={pageCount} currentPage={currentPage} onChange={onChange} pagesVisible={pagesVisible} /> </nav> </div> {rightLevel} </div> ) }; Pagination.propTypes = { currentPage: PropTypes.number, pageCount: PropTypes.number, hasFirst: PropTypes.bool, first: PropTypes.node, hasPrevious: PropTypes.bool, previous: PropTypes.node, hasNext: PropTypes.bool, next: PropTypes.node, hasLast: PropTypes.bool, last: PropTypes.node, pagesVisible: PropTypes.number, onChange: PropTypes.func, ...defaultReactProps }; Pagination.defaultProps = { hasFirst: true, first: "First", hasPrevious: true, previous: "Previous", hasNext: true, next: "Next", hasLast: true, last: "Last", pagesVisible: 2, ...defaultReactPropsValues }; export default Pagination;