UNPKG

taro-material

Version:

Mini Program components that implement Google's Material Design.

196 lines (178 loc) 5.02 kB
import Taro from '@tarojs/taro' import { View, Input, Text } from '@tarojs/components' import PropTypes from 'prop-types' import classNames from 'classnames' import _toString from 'lodash/toString' import AtComponent from '../../common/component' import { initTestEnv } from '../../common/utils' // 实现两数相加并保留小数点后最短尾数 function addNum (num1, num2) { let sq1, sq2 try { sq1 = _toString(num1).split('.')[1].length } catch (e) { sq1 = 0 } try { sq2 = _toString(num2).split('.')[1].length } catch (e) { sq2 = 0 } const m = Math.pow(10, Math.max(sq1, sq2)) return (Math.round(num1 * m) + Math.round(num2 * m)) / m } // 格式化数字,处理01变成1,并且不处理1. 这种情况 function parseValue (num) { if (num === '') return '0' const numStr = _toString(num) if (numStr.indexOf('0') === 0 && numStr.indexOf('.') === -1) { // 处理01变成1,并且不处理1. return _toString(parseFloat(num)) } return _toString(num) } initTestEnv() class AtInputNumber extends AtComponent { handleClick (clickType) { const { disabled, value, min, max, step } = this.props const lowThanMin = (clickType === 'minus' && value <= min) const overThanMax = (clickType === 'plus' && value >= max) if (lowThanMin || overThanMax || disabled) { const deltaValue = clickType === 'minus' ? -step : step const errorValue = addNum(value, deltaValue) if (disabled) { this.handleError({ type: 'DISABLED', errorValue, }) } else { this.handleError({ type: lowThanMin ? 'LOW' : 'OVER', errorValue, }) } return } const deltaValue = clickType === 'minus' ? -step : step let newValue = addNum(value, deltaValue) newValue = this.handleValue(newValue) this.props.onChange(newValue) } handleValue = value => { const { max, min } = this.props let resultValue = value === '' ? min : value // 此处不能使用 Math.max,会是字符串变数字,并丢失 . if (resultValue > max) { resultValue = max this.handleError({ type: 'OVER', errorValue: resultValue, }) } if (resultValue < min) { resultValue = min this.handleError({ type: 'LOW', errorValue: resultValue, }) } resultValue = parseValue(resultValue) return resultValue } handleInput = (e, ...arg) => { const { value } = e.target const { disabled } = this.props if (disabled) return const newValue = this.handleValue(value) this.props.onChange(newValue, e, ...arg) return newValue } handleBlur = (...arg) => this.props.onBlur(...arg) handleError = errorValue => { if (!this.props.onErrorInput) { return } this.props.onErrorInput(errorValue) } render () { const { customStyle, className, width, disabled, value, type, min, max, size } = this.props const inputStyle = { width: width ? `${Taro.pxTransform(width)}` : '' } const inputValue = this.handleValue(value) const rootCls = classNames('at-input-number', { 'at-input-number--lg': size }, className) const minusBtnCls = classNames('at-input-number__btn', { 'at-input-number--disabled': inputValue <= min || disabled }) const plusBtnCls = classNames('at-input-number__btn', { 'at-input-number--disabled': inputValue >= max || disabled }) return <View className={rootCls} style={customStyle}> <View className={minusBtnCls} onClick={this.handleClick.bind(this, 'minus')}> <Text className='at-icon at-icon-subtract at-input-number__btn-subtract'></Text> </View> <Input className='at-input-number__input' style={inputStyle} type={type} value={inputValue} disabled={disabled} onInput={this.handleInput} onBlur={this.handleBlur} /> <View className={plusBtnCls} onClick={this.handleClick.bind(this, 'plus')}> <Text className='at-icon at-icon-add at-input-number__btn-add'></Text> </View> </View> } } AtInputNumber.defaultProps = { customStyle: '', className: '', disabled: false, value: 1, type: 'number', width: 0, min: 0, max: 100, step: 1, size: '', onChange: () => {}, onBlur: () => {}, } AtInputNumber.propTypes = { customStyle: PropTypes.oneOfType([ PropTypes.object, PropTypes.string ]), className: PropTypes.oneOfType([ PropTypes.array, PropTypes.string ]), value: PropTypes.oneOfType([ PropTypes.number, PropTypes.string ]), type: PropTypes.oneOf(['number', 'digit']), disabled: PropTypes.bool, width: PropTypes.number, min: PropTypes.number, max: PropTypes.number, step: PropTypes.number, size: PropTypes.string, onChange: PropTypes.func, onBlur: PropTypes.func, onErrorInput: PropTypes.func, } export default AtInputNumber