UNPKG

react-native-komect-uikit

Version:
177 lines (151 loc) 5.03 kB
/** * @Author: will * @Date: 2017-08-09T23:33:32+08:00 * @Filename: Stepper.js * @Last modified by: will * @Last modified time: 2017-08-12T14:21:40+08:00 */ // Stepper.js 'use strict'; import React, {Component} from 'react'; import PropTypes from 'prop-types'; import {StyleSheet, View, Text, TouchableOpacity} from 'react-native'; import Theme from '../themes/Theme'; export default class Stepper extends Component { static propTypes = { ...View.propTypes, defaultValue: PropTypes.number, value: PropTypes.number, step: PropTypes.number, max: PropTypes.number, min: PropTypes.number, valueStyle: Text.propTypes.style, valueFormat: PropTypes.func, //(value) subButton: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), addButton: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), showSeparator: PropTypes.bool, disabled: PropTypes.bool, editable: PropTypes.bool, onChange: PropTypes.func, //(value) }; static defaultProps = { ...View.defaultProps, defaultValue: 0, step: 1, subButton: '-', addButton: '+', showSeparator: true, disabled: false, editable: true, }; constructor(props) { super(props); this.state = { value: props.value ? props.value : (props.defaultValue ? props.defaultValue : 0), height: null, }; } buildProps() { let {style, valueStyle, subButton, addButton, disabled, editable, pointerEvents, opacity, ...others} = this.props; style = [{ backgroundColor: Theme.stepperColor, borderColor: Theme.stepperBorderColor, borderWidth: Theme.stepperBorderWidth, borderRadius: Theme.stepperBorderRadius, flexDirection: 'row', alignItems: 'center', overflow: 'hidden', }].concat(style); valueStyle = [{ color: Theme.stepperTextColor, fontSize: Theme.stepperFontSize, textAlign: 'center', minWidth: Theme.stepperValueMinWidth, paddingHorizontal: Theme.stepperValuePaddingHorizontal, }].concat(valueStyle); let btnStyle = { width: Theme.stepperButtonWidth, height: Theme.stepperButtonHeight, alignItems: 'center', justifyContent: 'center', }; let btnTextStyle = { color: Theme.stepperBtnTextColor, fontSize: Theme.stepperBtnFontSize, }; if (!React.isValidElement(subButton)) { subButton = ( <View style={btnStyle}> <Text style={btnTextStyle}>{subButton}</Text> </View> ); } if (!React.isValidElement(addButton)) { addButton = ( <View style={btnStyle}> <Text style={btnTextStyle}>{addButton}</Text> </View> ); } if (disabled) { pointerEvents = 'none'; opacity = Theme.stepperDisabledOpacity; } this.props = {style, valueStyle, subButton, addButton, disabled, editable, pointerEvents, opacity, ...others}; } onLayout(e) { if (this.state.height === null) { this.setState({ height: e.nativeEvent.layout.height, }); } this.props.onLayout && this.props.onLayout(e); } onSubButtonPress() { let {value, step, min, onChange} = this.props; if (value === undefined) value = this.state.value; value -= step; if (value < min) value = min; this.setState({value}); onChange && onChange(value); } onAddButtonPress() { let {value, step, max, onChange} = this.props; if (value === undefined) value = this.state.value; value += step; if (value > max) value = max; this.setState({value}); onChange && onChange(value); } render() { this.buildProps(); let {style, subButton, addButton, value, valueStyle, valueFormat, max, min, showSeparator, disabled, editable, onLayout, ...others} = this.props; if (value === undefined) value = this.state.value; let separator; if (showSeparator) { let fs = StyleSheet.flatten(style); separator = <View style={{backgroundColor: fs.borderColor, width: fs.borderWidth, height: this.state.height}} />; } let subDisabled = !editable || value <= min; let addDisabled = !editable || value >= max; let subOpacity = !disabled && subDisabled ? Theme.stepperDisabledOpacity : 1; let addOpacity = !disabled && addDisabled ? Theme.stepperDisabledOpacity : 1; return ( <View style={style} onLayout={e => this.onLayout(e)} {...others}> <TouchableOpacity disabled={subDisabled} onPress={() => this.onSubButtonPress()}> <View style={{opacity: subOpacity}}> {subButton} </View> </TouchableOpacity> {separator} <Text style={valueStyle} numberOfLines={1}>{valueFormat ? valueFormat(value) : value}</Text> {separator} <TouchableOpacity disabled={addDisabled} onPress={() => this.onAddButtonPress()}> <View style={{opacity: addOpacity}}> {addButton} </View> </TouchableOpacity> </View> ); } }