UNPKG

@6thquake/react-material

Version:

React components that implement Google's Material Design.

433 lines (387 loc) 10.2 kB
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));