UNPKG

7.22 kBJavaScriptView Raw
1import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
2import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
3import _inherits from 'babel-runtime/helpers/inherits';
4
5var _class, _temp;
6
7import React, { Component } from 'react';
8import PropTypes from 'prop-types';
9import { polyfill } from 'react-lifecycles-compat';
10import classNames from 'classnames';
11import Animate from '../animate';
12import { support, dom } from '../util';
13
14/**
15 * badge sup component
16 */
17
18// util::getDigitArray
19var getDigitArray = function getDigitArray(num) {
20 return num.toString().split('').reverse().map(function (i) {
21 return parseInt(i, 10);
22 });
23};
24
25var Sup = (_temp = _class = function (_Component) {
26 _inherits(Sup, _Component);
27
28 // 单排可滚动的数字列表
29 Sup.renderDigit = function renderDigit(prefix, digit, key) {
30 var children = [];
31 for (var i = 0; i < 30; i++) {
32 children.push(React.createElement(
33 'span',
34 { key: i },
35 i % 10
36 ));
37 }
38
39 return React.createElement(
40 'span',
41 { className: prefix + 'badge-scroll-number-only', key: key },
42 children
43 );
44 };
45
46 // 可滚动数字组
47
48
49 Sup.renderNumber = function renderNumber(prefix, count) {
50 return getDigitArray(count).map(function (digit, i) {
51 return Sup.renderDigit(prefix, digit, i);
52 }).reverse();
53 };
54
55 function Sup(props) {
56 _classCallCheck(this, Sup);
57
58 // render 时, 上一次的渲染数字 和 当前渲染的数字
59 var _this = _possibleConstructorReturn(this, _Component.call(this, props));
60
61 _this.saveRef = function (ref) {
62 _this.supEl = ref;
63 };
64
65 _this.state = {
66 lastCount: 0,
67 currentCount: props.count
68 };
69 return _this;
70 }
71
72 Sup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
73 if ('count' in nextProps) {
74 return {
75 lastCount: prevState.currentCount,
76 currentCount: nextProps.count
77 };
78 }
79
80 return null;
81 };
82
83 Sup.prototype.componentDidMount = function componentDidMount() {
84 this.computeStyle(true);
85 };
86
87 Sup.prototype.componentDidUpdate = function componentDidUpdate(prevProps) {
88 var _this2 = this;
89
90 if (prevProps.count !== this.props.count) {
91 this.computeStyle(false);
92
93 // NOTE why called `computeStyle` again after 300ms ?
94 setTimeout(function () {
95 _this2.computeStyle(true, true);
96 }, 300);
97 }
98 };
99
100 Sup.prototype.computeStyle = function computeStyle(removeTransition, revert) {
101 var _this3 = this;
102
103 var _props = this.props,
104 prefix = _props.prefix,
105 count = _props.count,
106 overflowCount = _props.overflowCount;
107 var lastCount = this.state.lastCount;
108
109
110 if (count < 0) {
111 return;
112 }
113 var supNode = this.supEl;
114
115 if (supNode && dom.hasClass(supNode, prefix + 'badge-count')) {
116 var scrollNums = supNode.querySelectorAll('.' + prefix + 'badge-scroll-number-only');
117
118 if (scrollNums.length) {
119 var height = window.getComputedStyle(supNode).height;
120
121 scrollNums = [].slice.call(scrollNums, 0).reverse();
122
123 getDigitArray(count).forEach(function (digit, i) {
124 var position = _this3.getPositionByDigit(digit, i, revert);
125 var transformTo = -position * parseFloat(height);
126
127 removeTransition = removeTransition || typeof getDigitArray(lastCount)[i] === 'undefined' || lastCount > overflowCount || lastCount <= 0;
128
129 var scrollStyle = support.animation ? {
130 transition: removeTransition ? 'none' : 'transform .3s cubic-bezier(.645, .045, .355, 1), -webkit-transform .3s cubic-bezier(.645, .045, .355, 1)',
131 WebkitTransform: 'translateY(' + transformTo + 'px)',
132 transform: 'translateY(' + transformTo + 'px)',
133 height: height,
134 lineHeight: height
135 } : {
136 top: transformTo + 'px',
137 height: height,
138 lineHeight: height
139 };
140
141 Object.keys(scrollStyle).forEach(function (key) {
142 scrollNums[i].style[key] = scrollStyle[key];
143 });
144 });
145 }
146 }
147 };
148
149 Sup.prototype.getPositionByDigit = function getPositionByDigit(digit, i, revert) {
150 var lastCount = this.state.lastCount;
151
152 if (revert) {
153 return 10 + digit;
154 }
155 var lastDigit = getDigitArray(lastCount)[i] || 0;
156
157 if (this.props.count > lastCount) {
158 return (digit >= lastDigit ? 10 : 20) + digit;
159 }
160
161 if (digit <= lastDigit) {
162 return 10 + digit;
163 }
164
165 return digit;
166 };
167
168 Sup.prototype.render = function render() {
169 var _classNames;
170
171 var _props2 = this.props,
172 prefix = _props2.prefix,
173 count = _props2.count,
174 showZero = _props2.showZero,
175 overflowCount = _props2.overflowCount,
176 dot = _props2.dot,
177 style = _props2.style,
178 content = _props2.content;
179
180
181 var supClasses = classNames(prefix + 'badge-scroll-number', (_classNames = {}, _classNames[prefix + 'badge-count'] = !!count || count === 0 && showZero, _classNames[prefix + 'badge-dot'] = dot, _classNames[prefix + 'badge-custom'] = !!content, _classNames));
182
183 var children = null;
184 var show = dot || count > 0 || count === 0 && showZero || content;
185
186 if (count > 0 || count === 0 && showZero) {
187 var realCount = overflowCount > 0 && count > overflowCount ? overflowCount + '+' : count;
188
189 children = isNaN(realCount) ? realCount : Sup.renderNumber(prefix, count);
190 } else if (content) {
191 children = content;
192 }
193
194 var animation = {
195 appear: 'zoomIn',
196 enter: 'zoomIn',
197 leave: 'zoomOut'
198 };
199
200 var wrapper = support.animation ? React.createElement(Animate, { animation: animation }) : React.createElement('span', null);
201 var element = show ? React.createElement(
202 'sup',
203 { ref: this.saveRef, className: supClasses, style: style },
204 children
205 ) : null;
206
207 return React.cloneElement(wrapper, {}, element);
208 };
209
210 return Sup;
211}(Component), _class.propTypes = {
212 prefix: PropTypes.string,
213 count: PropTypes.number,
214 showZero: PropTypes.bool,
215 overflowCount: PropTypes.number,
216 content: PropTypes.node,
217 dot: PropTypes.bool,
218 style: PropTypes.object
219}, _class.defaultProps = {
220 prefix: 'next-',
221 count: 0,
222 showZero: false,
223 overflowCount: 99,
224 dot: false
225}, _temp);
226Sup.displayName = 'Sup';
227
228
229export default polyfill(Sup);
\No newline at end of file