UNPKG

4.21 kBJavaScriptView Raw
1import classnames from 'classnames';
2import React from 'react';
3import PropTypes from 'prop-types';
4
5
6const propTypes = {
7 /**
8 * radio 颜色 样式
9 */
10 colors: PropTypes.oneOf(['', 'dark', 'success', 'info', 'warning', 'danger','primary']),
11 /**
12 * radio 大小
13 */
14 size: PropTypes.oneOf(['lg','sm']),
15 /**
16 * radio 是否可用
17 */
18 disabled: PropTypes.bool,
19 /**
20 * radio 样式 是否使用红色填充
21 */
22 inverse: PropTypes.bool,
23 checked:PropTypes.bool,
24 onChange:PropTypes.func
25};
26
27const defaultProps = {
28 inverse: false,
29 disabled: false,
30 clsPrefix: 'u-radio'
31};
32
33/**
34 * 建立与RadioGroup通信
35 */
36const contextTypes = {
37 radioGroup: PropTypes.object
38}
39
40
41class Radio extends React.Component {
42 constructor(props, context) {
43 super(props, context);
44 let initChecked = typeof props.checked !== 'undefined' ? props.checked : props.defaultChecked;
45 this.state = {
46 checked: initChecked,
47 focused: false
48 }
49 }
50 componentWillReceiveProps(nextProps){
51 if('checked' in nextProps){
52 this.setState({
53 checked:nextProps.checked
54 })
55 }
56 }
57
58 handleClick=(event)=> {
59 if (this.props.disabled) {
60 return;
61 }
62 if (this.context.radioGroup && this.context.radioGroup.onChange) {
63 this.context.radioGroup.onChange(this.props.value);
64 }else {
65 if (!('checked' in this.props)) {
66 this.setState({
67 checked: !this.state.checked
68 })
69 }
70 event.target.checked = !this.state.checked;
71 this.props.onChange&&this.props.onChange(event,!this.state.checked)
72 }
73 }
74
75 handleFocus = (e) => {
76 if(e.target && e.target.type == 'radio'){
77 this.setState({
78 focused: true
79 });
80 }
81 }
82
83 handleBlur = (e) => {
84 if(e.target && e.target.type == 'radio'){
85 this.setState({
86 focused: false
87 });
88 }
89 }
90
91 render() {
92 const { state, props, context } = this;
93 let { checked } = state;
94 /**
95 * 自身的属性
96 */
97 const {
98 inverse,
99 disabled,
100 colors,
101 className,
102 children,
103 clsPrefix,
104 style,
105 onChange,
106 ...others
107 } = props;
108 const { radioGroup } = context;
109 const radioProps = { ...others };
110 // 包裹 radioGroup
111 if (radioGroup) {
112 radioProps.name = radioGroup.name;
113 radioProps.selectedValue = radioGroup.selectedValue;
114 radioProps.size = radioGroup.size;
115 radioProps.focusvalue = radioGroup.focusvalue;
116 }
117 const {name, selectedValue,size,focusvalue} = radioProps;
118
119 let optional = {};
120 /**
121 * 若父级selectedValue与本身的value值相同,则改radio被选中
122 */
123 if(selectedValue !== undefined) {
124 optional.checked = (this.props.value === selectedValue);
125 }
126
127 let classes = {
128 [`${clsPrefix}-focused`]: this.state.focused,
129 'is-checked': typeof optional.checked !== 'undefined' ? optional.checked : checked,
130 disabled
131 };
132
133 if (colors) {
134 classes[`${clsPrefix}-${colors}`] = true;
135 }
136 if (size) {
137 classes[`${clsPrefix}-${size}`] = true;
138 }
139 if (inverse) {
140 classes[`${clsPrefix}-inverse`] = true;
141 }
142 if (children == null) {
143 classes[`${clsPrefix}-noContent`] = true;
144 }
145 let classNames = classnames(clsPrefix,classes);
146 let tabIndex=optional.checked?0:-1;
147 if(focusvalue&&focusvalue==this.props.value){
148 tabIndex = 0 ;
149 }
150 const input = (
151 <input
152 {...radioProps}
153 type="radio"
154 name={name}
155 disabled={this.props.disabled}
156 tabIndex={tabIndex}
157 onFocus={this.handleFocus}
158 onBlur={this.handleBlur}
159 />
160 );
161 return (
162 <label style={style} onClick = {this.handleClick} className={classnames(className, classNames)}>
163 {input}
164 <label className={clsPrefix+'-label'}>{children}</label>
165 </label>
166 );
167
168 }
169}
170
171Radio.contextTypes = contextTypes;
172Radio.propTypes = propTypes;
173Radio.defaultProps = defaultProps;
174
175export default Radio;