UNPKG

3.58 kBJavaScriptView Raw
1import React from 'react';
2import classnames from 'classnames';
3import PropTypes from 'prop-types';
4
5
6const propTypes = {
7 name: PropTypes.string,
8 /**
9 * 默认选中的值
10 */
11 defaultValue: PropTypes.oneOfType([
12 PropTypes.string,
13 PropTypes.number,
14 PropTypes.bool,
15 ]),
16 /**
17 * 选中的值
18 */
19 selectedValue: PropTypes.oneOfType([
20 PropTypes.string,
21 PropTypes.number,
22 PropTypes.bool,
23 ]),
24 /**
25 * 选中的值,作用与selectedValue一致,添加value属性是为了配合form表单校验初始化等一起使用
26 */
27 value: PropTypes.oneOfType([
28 PropTypes.string,
29 PropTypes.number,
30 PropTypes.bool,
31 ]),
32 /**
33 * 暴露给用户,且与子Radio通信的方法
34 */
35 onChange: PropTypes.func,
36 /**
37 * radio 大小
38 */
39 size: PropTypes.oneOf(['lg','sm']),
40
41 children: PropTypes.node.isRequired,
42
43 Component: PropTypes.oneOfType([
44 PropTypes.string,
45 PropTypes.func,
46 PropTypes.object
47 ])
48};
49
50const defaultProps = {
51 Component: 'div',
52 clsPrefix: 'u-radio-group',
53 defaultValue: ''
54};
55
56/**
57 * 与子Radio通信
58 */
59const childContextTypes = {
60 radioGroup: PropTypes.object
61}
62
63class RadioGroup extends React.Component {
64
65 constructor(props, context) {
66 super(props, context);
67
68 this.state={
69 focusvalue:'',
70 selectedValue: props.value?props.value:(props.selectedValue ? props.selectedValue : props.defaultValue)
71 }
72 }
73
74 getValues = ()=>{
75 let array = []
76 let children = this.props.children;
77 if(!children){
78 console.error('RadioGroup must have child nodes');
79 return array;
80 }
81 if(children.length>1){
82 children.map((item)=>{
83 array.push(item.props.value)
84 })
85 }else if(children.length === 1){
86 array.push(children[0].props.value)
87 }else{
88 array.push(children.props.value);
89 }
90 return array;
91 }
92 componentDidMount(){
93 let array = this.getValues();
94 if(array.indexOf(this.props.selectedValue)==-1){
95 this.setState({
96 focusvalue:array[0]
97 })
98 }
99 }
100
101 componentWillReceiveProps(nextProps){
102 let array = this.getValues();
103 if(array.indexOf(this.props.selectedValue)==-1 || array.indexOf(this.props.value)==-1){
104 this.setState({
105 focusvalue:array[0]
106 })
107 }else{
108 this.setState({
109 focusvalue:''
110 })
111 }
112 if('selectedValue' in nextProps || 'value' in nextProps) {
113 this.setState({
114 selectedValue: typeof nextProps.selectedValue !== 'undifined' ? nextProps.selectedValue : nextProps.value
115 })
116 }
117 }
118
119 handleChange = (value) => {
120 let { onChange } = this.props;
121 this.setState({
122 selectedValue: value
123 })
124 onChange && onChange(value);
125 }
126
127 /**
128 * 一旦外层change方法触发本身props发生改变,则调用getChildContext更新与子Radio的通信信息(radioGroup)
129 */
130
131 getChildContext() {
132 const {name, size} = this.props;
133 let { selectedValue } = this.state;
134 let onChange = this.handleChange;
135 return {
136 radioGroup: {
137 name, selectedValue, onChange,size,focusvalue:this.state.focusvalue
138 }
139 }
140 }
141
142 render () {
143 const {Component, name, selectedValue, onChange, children,size, clsPrefix, className, focusvalue,...others} = this.props;
144
145 return <Component className={classnames(clsPrefix,className)} {...others} focusvalue={this.state.focusvalue}>{children}</Component>;
146 }
147}
148
149RadioGroup.childContextTypes = childContextTypes;
150RadioGroup.propTypes = propTypes;
151RadioGroup.defaultProps = defaultProps;
152export default RadioGroup;
\No newline at end of file