1 | import classnames from 'classnames';
|
2 | import React from 'react';
|
3 | import PropTypes from 'prop-types';
|
4 |
|
5 |
|
6 | const propTypes = {
|
7 | |
8 |
|
9 |
|
10 | colors: PropTypes.oneOf(['', 'dark', 'success', 'info', 'warning', 'danger','primary']),
|
11 | |
12 |
|
13 |
|
14 | size: PropTypes.oneOf(['lg','sm']),
|
15 | |
16 |
|
17 |
|
18 | disabled: PropTypes.bool,
|
19 | |
20 |
|
21 |
|
22 | inverse: PropTypes.bool,
|
23 | checked:PropTypes.bool,
|
24 | onChange:PropTypes.func
|
25 | };
|
26 |
|
27 | const defaultProps = {
|
28 | inverse: false,
|
29 | disabled: false,
|
30 | clsPrefix: 'u-radio'
|
31 | };
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | const contextTypes = {
|
37 | radioGroup: PropTypes.object
|
38 | }
|
39 |
|
40 |
|
41 | class 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 |
|
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 |
|
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 |
|
171 | Radio.contextTypes = contextTypes;
|
172 | Radio.propTypes = propTypes;
|
173 | Radio.defaultProps = defaultProps;
|
174 |
|
175 | export default Radio;
|