UNPKG

tuya-panel-kit

Version:

a functional component library for developing tuya device panels!

198 lines (188 loc) 4.63 kB
import PropTypes from 'prop-types'; import React from 'react'; import { StyleSheet, View, ViewPropTypes, I18nManager } from 'react-native'; import IconART from '../iconfont/art'; import TYText from '../TYText'; import svgsART from '../iconfont/art/defaultSvg'; const LetterWidth = 0.37; const LetterPadding = (1 - LetterWidth) / 2; export default class UnitTextART extends React.PureComponent { static propTypes = { /** * 内容样式 */ style: ViewPropTypes.style, /** * 字体尺寸大小,valueSize 或 unitSize 的缩写版 * 其中 valueSize 将会和与 size 相同,unitSize 将会为 size 值的一半。 */ size: PropTypes.number, /** * 单位的大小 */ valueSize: PropTypes.number, /** * 可以用来定制每个值的颜色 */ valueColors: PropTypes.array, /** * 值的颜色 */ valueColor: PropTypes.string, /** * 单位,字符串为内置的 svg name */ unit: PropTypes.string, /** * 单位的大小 */ unitSize: PropTypes.number, /** * 单位的颜色 */ unitColor: PropTypes.string, /** * 单位的左边距 */ unitPaddingLeft: PropTypes.number, /** * 单位的上边距 */ unitPaddingTop: PropTypes.number, /** * 单位的类型 */ unitType: PropTypes.oneOf(['icon', 'text']), /** * 值 */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, }; static defaultProps = { style: null, unit: '', valueSize: null, unitSize: null, size: 96, valueColors: [], valueColor: 'white', unitColor: 'white', unitPaddingLeft: 0, unitPaddingTop: 0, unitType: 'icon', }; constructor(props) { super(props); this.state = { value: props.value || '', unit: props.unit, }; } componentWillReceiveProps(nextProps) { if (nextProps.value !== this.state.value || nextProps.unit !== this.state.unit) { this.setState({ value: nextProps.value, unit: nextProps.unit, }); } } // TODO: /* istanbul ignore next */ setValue(value) { if (value !== this.state.value) { this.setState({ value: `${value}` }); } } /* istanbul ignore next */ setUnit(unit) { if (unit !== this.state.unit) { this.setState({ unit: `${unit}` }); } } renderUnit() { const { unitSize, unitType, valueSize, size, unitColor, unitPaddingLeft, unitPaddingTop, } = this.props; const { unit } = this.state; if (!unit) { return null; } const uSize = unitSize || size / 2; const isRtl = I18nManager.isRTL; const marginType = isRtl ? 'marginRight' : 'marginLeft'; const vSize = valueSize || size; const uNeedLeft = (vSize + uSize) * (LetterPadding - 0.025); const unitStyle = [{ marginTop: unitPaddingTop, [marginType]: -uNeedLeft + unitPaddingLeft }]; return unitType === 'icon' ? ( <IconART d={svgsART[unit] || unit} size={uSize} style={unitStyle} color={unitColor} /> ) : ( <TYText style={[ { fontSize: uSize, color: unitColor, }, unitStyle, ]} > {unit} </TYText> ); } render() { const { style, size, valueSize, valueColor, valueColors, unit, unitSize, unitColor, unitPaddingLeft, unitPaddingTop, value, ...rest } = this.props; const isRtl = I18nManager.isRTL; const letter = `${this.state.value}`.split(''); if (!letter || !letter.length) return null; const vSize = valueSize || size; const needLeft = vSize * (LetterPadding * 2 - 0.05); const marginType = isRtl ? 'marginRight' : 'marginLeft'; const wrapperStyle = [ styles.wrapperStyle, { flexDirection: isRtl ? 'row-reverse' : 'row' }, style, ]; return ( <View {...rest} style={wrapperStyle}> {letter.map((l, i) => { const letterStyle = [i !== 0 && { [marginType]: -needLeft }]; const color = valueColors[i] ? valueColors[i] : valueColor; return ( <IconART name={l} size={vSize} style={letterStyle} key={`TYUnitText_${l}_${i + 1}`} color={color} /> ); })} {this.renderUnit()} </View> ); } } const styles = StyleSheet.create({ wrapperStyle: { justifyContent: 'center', }, });