/** @format */ /** * External dependencies */ import { __, sprintf } from '@wordpress/i18n'; import { Component } from '@wordpress/element'; import { IconButton, SelectControl } from '@wordpress/components'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import { isFinite, noop, uniqueId } from 'lodash'; /** * Internal dependencies */ import './style.scss'; /** * Use `Pagination` to allow navigation between pages that represent a collection of items. * The component allows for selecting a new page and items per page options. */ class Pagination extends Component { constructor( props ) { super( props ); this.previousPage = this.previousPage.bind( this ); this.nextPage = this.nextPage.bind( this ); this.onPageValueChange = this.onPageValueChange.bind( this ); this.perPageChange = this.perPageChange.bind( this ); this.selectInputValue = this.selectInputValue.bind( this ); } previousPage( event ) { event.stopPropagation(); const { page, onPageChange } = this.props; if ( page - 1 < 1 ) { return; } onPageChange( page - 1 ); } nextPage( event ) { event.stopPropagation(); const { page, onPageChange } = this.props; if ( page + 1 > this.pageCount ) { return; } onPageChange( page + 1 ); } perPageChange( perPage ) { const { onPerPageChange, onPageChange, total, page } = this.props; onPerPageChange( parseInt( perPage ) ); const newMaxPage = Math.ceil( total / parseInt( perPage ) ); if ( page > newMaxPage ) { onPageChange( newMaxPage ); } } onPageValueChange( event ) { const { onPageChange } = this.props; const newPage = parseInt( event.target.value, 10 ); if ( isFinite( newPage ) && this.pageCount && this.pageCount >= newPage ) { onPageChange( newPage ); } } selectInputValue( event ) { event.target.select(); } renderPageArrows() { const { page } = this.props; if ( this.pageCount <= 1 ) { return null; } const previousLinkClass = classNames( 'woocommerce-pagination__link', { 'is-active': page > 1, } ); const nextLinkClass = classNames( 'woocommerce-pagination__link', { 'is-active': page < this.pageCount, } ); return (
{ sprintf( __( 'Page %d of %d', 'wc-admin' ), page, this.pageCount ) }
1 ) } onClick={ this.previousPage } icon="arrow-left-alt2" label={ __( 'Previous Page', 'wc-admin' ) } size={ 18 } />
); } renderPagePicker() { const { page } = this.props; const isError = page < 1 || page > this.pageCount; const inputClass = classNames( 'woocommerce-pagination__page-picker-input', { 'has-error': isError, } ); const instanceId = uniqueId( 'woocommerce-pagination-page-picker-' ); return (
); } renderPerPagePicker() { // TODO Replace this with a styleized Select drop-down/control? return (
); } render() { const { total, perPage, className } = this.props; this.pageCount = Math.ceil( total / perPage ); if ( this.pageCount <= 1 ) { return null; } const classes = classNames( 'woocommerce-pagination', className ); return (
{ this.renderPageArrows() } { this.renderPagePicker() } { this.renderPerPagePicker() }
); } } Pagination.propTypes = { /** * The current page of the collection. */ page: PropTypes.number.isRequired, /** * A function to execute when the page is changed. */ onPageChange: PropTypes.func, /** * The amount of results that are being displayed per page. */ perPage: PropTypes.number.isRequired, /** * A function to execute when the per page option is changed. */ onPerPageChange: PropTypes.func, /** * The total number of results. */ total: PropTypes.number.isRequired, /** * Additional classNames. */ className: PropTypes.string, }; Pagination.defaultProps = { onPageChange: noop, onPerPageChange: noop, }; export default Pagination;