1 | import React from "react";
|
2 | import PropTypes from "prop-types";
|
3 | import cls from "classnames";
|
4 | class MiniPager extends React.Component {
|
5 | constructor(props) {
|
6 | super(props);
|
7 | this.state = { currentPage: 0 };
|
8 | this.onPreBtnClick = this.onPreBtnClick.bind(this);
|
9 | this.onNextBtnClick = this.onNextBtnClick.bind(this);
|
10 | }
|
11 |
|
12 | static getDerivedStateFromProps(props, state) {
|
13 | if ("currentPage" in props) {
|
14 | return {
|
15 | currentPage: props.currentPage - 1,
|
16 | };
|
17 | }
|
18 | return null;
|
19 | }
|
20 | componentDidUpdate(preProps, preState) {
|
21 | if (preState.currentPage !== this.state.currentPage) {
|
22 | this.setScrollTop();
|
23 | }
|
24 | }
|
25 |
|
26 | setScrollTop() {
|
27 | let anchorDom = null;
|
28 | let top = 0;
|
29 | const anchor = this.props.anchor;
|
30 | const anchorType = typeof anchor;
|
31 | if (anchorType === "object") {
|
32 | anchorDom = anchor;
|
33 | } else if (anchorType === "string") {
|
34 | anchorDom = document.querySelector(anchor);
|
35 | } else if (anchorType === "number") {
|
36 | top = anchor;
|
37 | }
|
38 |
|
39 | if (anchorDom !== null) {
|
40 | top = anchorDom.getBoundingClientRect().top + window.scrollY;
|
41 | }
|
42 | window.scrollTo(0, top);
|
43 | }
|
44 |
|
45 | onPreBtnClick() {
|
46 | this.setState(preState => {
|
47 | this.props.onPageChange(preState.currentPage - 1 + 1);
|
48 | return {
|
49 | currentPage: preState.currentPage - 1,
|
50 | };
|
51 | });
|
52 | }
|
53 | onNextBtnClick() {
|
54 | this.setState(preState => {
|
55 | this.props.onPageChange(preState.currentPage + 1 + 1);
|
56 | return {
|
57 | currentPage: preState.currentPage + 1,
|
58 | };
|
59 | });
|
60 | }
|
61 | onFirstPageClick = () => {
|
62 | this.setState(preState => {
|
63 | this.props.onPageChange(1);
|
64 | return {
|
65 | currentPage: 0,
|
66 | };
|
67 | });
|
68 | };
|
69 | onLastPageClick = () => {
|
70 | this.setState(preState => {
|
71 | this.props.onPageChange(this.props.pageCount);
|
72 | return {
|
73 | currentPage: this.props.pageCount - 1,
|
74 | };
|
75 | });
|
76 | };
|
77 | render() {
|
78 | const { currentPage } = this.state;
|
79 | const {
|
80 | pageCount,
|
81 | preLabel,
|
82 | nextLabel,
|
83 | clsFix,
|
84 | autoHide,
|
85 | firstLabel,
|
86 | lastLabel,
|
87 | } = this.props;
|
88 | if (autoHide && pageCount <= 1) {
|
89 | return null;
|
90 | }
|
91 | return (
|
92 | <div className={clsFix}>
|
93 | <span
|
94 | onClick={this.onFirstPageClick}
|
95 | title={firstLabel}
|
96 | className={cls({ disable: currentPage === 0 })}
|
97 | >
|
98 | {firstLabel}
|
99 | </span>
|
100 | <span
|
101 | onClick={currentPage === 0 ? null : this.onPreBtnClick}
|
102 | title="上一页"
|
103 | className={cls({ disable: currentPage === 0 })}
|
104 | name={preLabel}
|
105 | >
|
106 | {preLabel}
|
107 | </span>
|
108 | <span>
|
109 | {currentPage + 1}/{pageCount}
|
110 | </span>
|
111 | <span
|
112 | onClick={currentPage === pageCount - 1 ? null : this.onNextBtnClick}
|
113 | title="下一页"
|
114 | className={cls({ disable: currentPage === pageCount - 1 })}
|
115 | name={nextLabel}
|
116 | >
|
117 | {nextLabel}
|
118 | </span>
|
119 | <span
|
120 | onClick={this.onLastPageClick}
|
121 | className={cls({ disable: currentPage === pageCount - 1 })}
|
122 | title={lastLabel}
|
123 | >
|
124 | {lastLabel}
|
125 | </span>
|
126 | </div>
|
127 | );
|
128 | }
|
129 | }
|
130 |
|
131 | function noop() {}
|
132 | MiniPager.defaultProps = {
|
133 | onPageChange: noop,
|
134 | preLabel: "上一页",
|
135 | nextLabel: "下一页",
|
136 | firstLabel: "首页",
|
137 | lastLabel: "末页",
|
138 | clsFix: "sw-minipager",
|
139 | anchor: 0,
|
140 | autoHide: false,
|
141 | };
|
142 | MiniPager.propTypes = {
|
143 | onPageChange: PropTypes.func,
|
144 | pageCount: PropTypes.number.isRequired,
|
145 | preLabel: PropTypes.string,
|
146 | nextLabel: PropTypes.string,
|
147 | firstLabel: PropTypes.string,
|
148 | lastLabel: PropTypes.string,
|
149 | clsFix: PropTypes.string,
|
150 | anchor: PropTypes.oneOfType([
|
151 | PropTypes.string,
|
152 | PropTypes.number,
|
153 | PropTypes.instanceOf(Element),
|
154 | ]),
|
155 | autoHide: PropTypes.bool,
|
156 | };
|
157 | export default MiniPager;
|