@6thquake/react-material
Version:
React components that implement Google's Material Design.
433 lines (387 loc) • 10.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
/**
* @ignore - do not document.
*/
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
import FirstPageIcon from '@material-ui/icons/FirstPage';
import LastPageIcon from '@material-ui/icons/LastPage';
import Input from '../Input';
import MenuItem from '../MenuItem';
import Typography from '../Typography';
import IconButton from '../IconButton';
import Select from '../Select/SelectStandalone';
import { withLocale } from '../LocaleProvider';
import withStyles from '../styles/withStyles';
const styles = theme => ({
root: {
fontSize: theme.typography.pxToRem(12),
'&:last-child': {
padding: 0
}
},
toolbar: {
height: 56,
minHeight: 56,
paddingRight: 2,
position: 'relative',
display: 'flex',
alignItems: 'center'
},
spacer: {
flex: '1 1 100%'
},
menuItem: {},
caption: {
flexShrink: 0
},
firstpage: {
cursor: 'pointer',
marginLeft: 10
},
lastpage: {
cursor: 'pointer',
marginRight: 10
},
input: {
fontSize: 'inherit',
flexShrink: 0
},
pageinput: {
fontSize: 12,
width: 50,
height: 28,
cursor: 'text',
color: '#666',
padding: '0 7px',
border: 'solid 1px #d9d9d9',
borderRadius: 6,
margin: '0 8px',
'&:focus': {
borderColor: 'blue',
transition: 'all 0.3s'
},
'&:hove': {
transition: 'all 0.3s',
borderColor: 'blue'
}
},
selectRoot: {
marginRight: theme.spacing(4),
marginLeft: theme.spacing(1),
color: theme.palette.text.secondary
},
select: {
paddingLeft: theme.spacing(1),
paddingRight: theme.spacing(2)
},
jump: {
lineHeight: '28px'
},
selectIcon: {
top: 1
},
actions: {
flexShrink: 0,
color: theme.palette.text.secondary,
marginLeft: theme.spacing(2.5)
},
textbutton: {
fontSize: '0.75rem',
fontWeight: 400
}
});
var _ref = React.createElement(FirstPageIcon, null);
var _ref2 = React.createElement(KeyboardArrowLeft, null);
var _ref3 = React.createElement(KeyboardArrowRight, null);
var _ref4 = React.createElement(LastPageIcon, null);
class Pagination extends Component {
constructor(props) {
super(props);
this.state = {
minwidth: true,
value: 1
};
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps !== prevState.preProps) {
return {
value: nextProps.page + 1,
preProps: nextProps
};
}
return null;
}
componentDidMount() {
// 分页的宽度小于200px时,只显示前后页按钮
if (this.div.clientWidth < 250) {
this.setState({
minwidth: false
});
}
this.props.onChangePage(this.props.page);
}
componentDidUpdate() {
const {
count,
onChangePage,
page,
rowsPerPage
} = this.props;
const newLastPage = Math.max(0, Math.ceil(count / rowsPerPage) - 1);
if (page > newLastPage) {
onChangePage(newLastPage);
}
}
createPage() {
const {
classes,
page,
rowsPerPage,
count,
backIconButtonProps,
nextIconButtonProps,
labelDisplayedRows,
labelRowsPerPage,
onChangeRowsPerPage,
rowsPerPageOptions,
SelectProps,
showSizeChanger,
showQuickJumper,
showTwoEnds,
homePage,
lastPage,
prePage,
nextPage,
jumpTo,
pageName,
noIcon
} = this.props;
const {
minwidth,
value
} = this.state;
const totalPage = Math.ceil(count / rowsPerPage);
return React.createElement("div", {
className: classes.root,
ref: div => this.div = div
}, React.createElement("div", {
className: classes.toolbar
}, React.createElement("div", {
className: classes.spacer
}), rowsPerPageOptions.length > 1 && showSizeChanger && React.createElement(Typography, {
variant: "caption",
className: classes.caption
}, labelRowsPerPage), rowsPerPageOptions.length > 1 && showSizeChanger && React.createElement(Select, _extends({
classes: {
root: classes.selectRoot,
select: classes.select,
icon: classes.selectIcon
},
input: React.createElement(Input, {
className: classes.input,
disableUnderline: true
}),
value: rowsPerPage,
onChange: onChangeRowsPerPage
}, SelectProps), rowsPerPageOptions.map(rowsPerPageOption => React.createElement(MenuItem, {
className: classes.menuItem,
key: rowsPerPageOption,
value: rowsPerPageOption
}, rowsPerPageOption))), React.createElement(Typography, {
variant: "caption",
className: classes.caption
}, minwidth ? labelDisplayedRows({
from: count === 0 ? 0 : page * rowsPerPage + 1,
to: Math.min(count, (page + 1) * rowsPerPage),
count,
page
}) : null), showTwoEnds ? React.createElement(IconButton, {
onClick: this.goEnd.bind(this, 'first'),
disabled: page === 0,
"aria-label": "Last Page"
}, noIcon ? React.createElement("span", {
className: classes.textbutton
}, homePage) : _ref) : null, React.createElement(IconButton, _extends({
onClick: this.prePageHandeler.bind(this),
disabled: page === 0
}, backIconButtonProps), noIcon ? React.createElement("span", {
className: classes.textbutton
}, prePage) : _ref2), React.createElement(IconButton, _extends({
onClick: this.nextPageHandeler.bind(this),
disabled: page >= totalPage - 1
}, nextIconButtonProps), noIcon ? React.createElement("span", {
className: classes.textbutton
}, nextPage) : _ref3), showTwoEnds ? React.createElement(IconButton, {
onClick: this.goEnd.bind(this, 'last'),
disabled: page >= totalPage - 1,
"aria-label": "Last Page"
}, noIcon ? React.createElement("span", {
className: classes.textbutton
}, lastPage) : _ref4) : null, showQuickJumper ? React.createElement(Typography, {
variant: "caption",
className: `${classes.caption} ${classes.jump}`
}, jumpTo, React.createElement(Input, {
className: classes.pageinput,
disableUnderline: true,
type: "number",
value: value,
onChange: this.jumpTo.bind(this)
}), pageName) : null));
}
pageClick(page) {
const getCurrentPage = this.props.onChangePage; // 将当前页码返回父组件
getCurrentPage(page);
}
prePageHandeler() {
let {
page
} = this.props;
if (--page === -1) {
return false;
}
this.pageClick(page);
}
nextPageHandeler() {
let {
page,
count,
rowsPerPage
} = this.props;
const totalPage = Math.ceil(count / rowsPerPage);
if (++page > totalPage) {
return false;
}
this.pageClick(page);
}
goEnd(param) {
const {
rowsPerPage,
count,
onChangePage
} = this.props;
const totalPage = Math.ceil(count / rowsPerPage);
const getCurrentPage = onChangePage;
if (param === 'first') {
getCurrentPage(0);
}
if (param === 'last') {
getCurrentPage(totalPage - 1);
}
}
jumpTo(e) {
const {
rowsPerPage,
count,
onChangePage
} = this.props;
const totalPage = Math.ceil(count / rowsPerPage);
this.setState({
value: e.target.value
}, () => {
const {
value
} = this.state;
if (value < 1) {
onChangePage(0);
this.setState({
value: 1
});
}
if (value > 0 && value <= totalPage) {
onChangePage(value - 1);
}
if (value > totalPage) {
onChangePage(totalPage - 1);
this.setState({
value: totalPage
});
}
});
}
render() {
return this.createPage();
}
}
process.env.NODE_ENV !== "production" ? Pagination.propTypes = {
/**
* Properties applied to the back arrow `IconButton` component.
*/
backIconButtonProps: PropTypes.object,
/**
* Override or extend the styles applied to the component.
* See [CSS API](#css-api) below for more details.
*/
classes: PropTypes.object.isRequired,
/**
* This is total count of pagination
*/
count: PropTypes.number,
/**
* Useful to customize the rows per page label. Invoked with a { from, to, count, page } object.
*/
labelDisplayedRows: PropTypes.func,
/**
* Customize the displayed rows label.
*/
labelRowsPerPage: PropTypes.node,
/**
* Properties applied to the next arrow `IconButton` element.
*/
nextIconButtonProps: PropTypes.object,
/**
* Customizes the options of the rows per page select field. If less than two options are available, no select field will be displayed.
*/
noIcon: PropTypes.bool,
/**
* This is call current page back to parent component
*/
onChangePage: PropTypes.func.isRequired,
/**
* Callback fired when the number of rows per page is changed.
*/
onChangeRowsPerPage: PropTypes.func,
/**
* The zero-based index of the current page.
*/
page: PropTypes.number,
/**
* This is page size of pagination
*/
rowsPerPage: PropTypes.number,
/**
* Use text alternative icon for next page、pre page、last page and first page
*/
rowsPerPageOptions: PropTypes.array,
/**
* show quick jumper ,jump to xx page.
*/
showQuickJumper: PropTypes.bool,
/**
* show jump to first and last page button.
*/
showSizeChanger: PropTypes.bool,
/**
* Whether to show buttons(first and last page) or not?
*/
showTwoEnds: PropTypes.bool
} : void 0;
Pagination.defaultProps = {
page: 0,
rowsPerPage: 5,
count: 0,
labelRowsPerPage: 'Rows per page:',
rowsPerPageOptions: [5, 10, 25],
labelDisplayedRows: ({
from,
to,
count
}) => `${from}-${to} of ${count}`
};
export default withStyles(styles, {
name: 'RMPagination'
})(withLocale({
name: 'Pagination'
})(Pagination));