UNPKG

weex-nuke

Version:

基于 Rax 、Weex 的高性能组件体系 ~~

190 lines (177 loc) 4.54 kB
/** @jsx createElement */ 'use strict'; import { createElement, Component, cloneElement, PropTypes } from 'rax'; import View from 'nuke-view'; import Touchable from 'nuke-touchable'; import Text from 'nuke-text'; import { connectStyle } from 'nuke-theme-provider'; import Radio from './radio'; import stylesProvider from '../styles'; /** * Radio.group * @description 单选框group模式 */ class RadioGroup extends Component { constructor(props) { super(props); this.onChange = this.onChange.bind(this); let value; if ('value' in props) { value = props.value; } this.state = { selectedValue: value, }; } getChildContext() { return { __group__: true, onChange: this.onChange, selectedValue: this.state.selectedValue, }; } componentWillReceiveProps(nextProps) { if (nextProps.value !== this.state.selectedValue) { this.setState({ selectedValue: nextProps.value, }); } } onChange(value) { // 同一个group下只能有一个被选中 this.setState({ selectedValue: value, }); this.props.onChange && this.props.onChange(value); } wrapPress(value) { this.onChange(value); } render() { const { dataSource = [], style = {}, size, type, groupItemStyle, themeStyle, touchStyle, labelStyle, reverse, renderItem, } = this.props; let { children } = this.props; const elementGroupStyle = Object.assign({}, themeStyle.group, groupItemStyle); const finalTextStyle = Object.assign( size === 'small' ? themeStyle['group-small-text'] : themeStyle['group-medium-text'], labelStyle ); const current = this.state.selectedValue; if (!children) { children = dataSource.map((item, index) => { if (typeof item !== 'object') { item = { label: item, value: item, index }; } const { label, value, ...others } = item; let checked = false; current === value ? (checked = true) : (checked = false); let labelGroup = [ <Radio t="radioitem" {...others} size={size} value={value} checked={checked} touchStyle={touchStyle} type={type} {...others} />, <Text t="radiotext" style={finalTextStyle}> {label} </Text>, ]; if (reverse) { labelGroup = labelGroup.reverse(); } if (label && !renderItem) { return ( <Touchable t="radio-item-wrap" key={index} style={elementGroupStyle} onPress={() => this.wrapPress(value)}> {labelGroup} </Touchable> ); } else if (label && renderItem) { return typeof renderItem === 'function' ? cloneElement(renderItem(item), { onPress: this.onChange.bind(this, item.value), }) : null; } return ( <View t="radio-item-wrap" style={elementGroupStyle}> <Radio {...others} checked={checked} touchStyle={touchStyle} /> </View> ); }); } return ( <View t="radio-group-wrap" style={style}> {children} </View> ); } } RadioGroup.displayName = 'RadioGroup'; RadioGroup.propTypes = { /** * 单选类型的数据源 */ dataSource: PropTypes.array, /** * 选中回调 callback when select done */ onChange: PropTypes.func, /** * 选中的值,配合dataSource使用 */ value: PropTypes.any, /** * 单选框的尺寸 */ size: PropTypes.oneOf(['small', 'medium']), /** * 单选框的类型 */ type: PropTypes.oneOf(['normal', 'list', 'dark', 'dot']), /** * group 模式下每个item的最外层样式 */ groupItemStyle: PropTypes.object, /** * group 模式下label文案的样式 */ labelStyle: PropTypes.object, /** * 是否翻转文字与radio reverse the label and radio */ reverse: PropTypes.bool, /** * 自定义渲染group item的方法 */ renderItem: PropTypes.func, }; RadioGroup.defaultProps = { dataSource: [], onChange: () => {}, value: '', size: 'small', type: 'normal', groupItemStyle: {}, labelStyle: {}, reverse: false, }; RadioGroup.childContextTypes = { onChange: PropTypes.func, __group__: PropTypes.bool, selectedValue: PropTypes.any, }; export default connectStyle(stylesProvider)(RadioGroup);