woocommerce/plugins/woocommerce-admin/client/components/pagination/index.js

199 lines
4.8 KiB
JavaScript
Raw Normal View History

/** @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';
2018-07-31 16:38:24 +00:00
import { isFinite, noop, uniqueId } from 'lodash';
/**
* Internal dependencies
*/
import './style.scss';
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 );
2018-07-31 16:38:24 +00:00
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 ) {
2018-07-30 23:08:13 +00:00
const { onPageChange } = this.props;
2018-07-31 16:38:24 +00:00
const newPage = parseInt( event.target.value, 10 );
2018-08-01 18:51:11 +00:00
if ( isFinite( newPage ) && this.pageCount && this.pageCount >= newPage ) {
2018-07-31 16:38:24 +00:00
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 (
<div className="woocommerce-pagination__page-arrows">
<span
className="woocommerce-pagination__page-arrows-label"
role="status"
aria-live="polite"
>
{ sprintf( __( 'Page %d of %d', 'wc-admin' ), page, this.pageCount ) }
</span>
<div className="woocommerce-pagination__page-arrows-buttons">
<IconButton
className={ previousLinkClass }
disabled={ ! ( page > 1 ) }
onClick={ this.previousPage }
icon="arrow-left-alt2"
label={ __( 'Previous Page', 'wc-admin' ) }
size={ 18 }
/>
<IconButton
className={ nextLinkClass }
disabled={ ! ( page < this.pageCount ) }
onClick={ this.nextPage }
icon="arrow-right-alt2"
label={ __( 'Next Page', 'wc-admin' ) }
size={ 18 }
/>
</div>
</div>
);
}
renderPagePicker() {
2018-07-30 23:08:13 +00:00
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 (
<div className="woocommerce-pagination__page-picker">
<label htmlFor={ instanceId } className="woocommerce-pagination__page-picker-label">
{ __( 'Go to page', 'wc-admin' ) }
<input
id={ instanceId }
className={ inputClass }
aria-invalid={ isError }
type="number"
2018-07-31 16:38:24 +00:00
onClick={ this.selectInputValue }
onChange={ this.onPageValueChange }
2018-07-30 23:08:13 +00:00
value={ page }
min={ 1 }
max={ this.pageCount }
/>
</label>
</div>
);
}
renderPerPagePicker() {
// TODO Replace this with a styleized Select drop-down/control?
return (
<div className="woocommerce-pagination__per-page-picker">
<SelectControl
label={ __( 'Rows per page', 'wc-admin' ) }
value={ this.props.perPage }
onChange={ this.perPageChange }
options={ [
{ value: '25', label: '25' },
{ value: '50', label: '50' },
{ value: '75', label: '75' },
{ value: '100', label: '100' },
{ value: '250', label: '250' },
{ value: '500', label: '500' },
] }
/>
</div>
);
}
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 (
<div className={ classes }>
{ this.renderPageArrows() }
{ this.renderPagePicker() }
{ this.renderPerPagePicker() }
</div>
);
}
}
Pagination.propTypes = {
page: PropTypes.number.isRequired,
onPageChange: PropTypes.func,
perPage: PropTypes.number.isRequired,
onPerPageChange: PropTypes.func,
total: PropTypes.number.isRequired,
className: PropTypes.string,
};
Pagination.defaultProps = {
onPageChange: noop,
onPerPageChange: noop,
};
export default Pagination;