Skip to content

Commit 7f8ef2d

Browse files
committed
RadioGroup can be an uncontrolled component when not passing the "value" prop
1 parent 3a702b7 commit 7f8ef2d

File tree

10 files changed

+180
-21
lines changed

10 files changed

+180
-21
lines changed

README.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ defaultChecked | Boolean | | The default checked state of the radio button.
144144
disabled | Boolean | false | If true, the radio button will be shown as disabled and cannot be modified.
145145
label | Node or String | | Label for the radio button.
146146
name | String | | Name for the input element.
147-
value | Any | | Value for the radio button.
147+
value | any | | Value for the radio button.
148148
onChange | Function | | Callback function that will be invoked when the value changes.
149149

150150
#### RadioGroup
@@ -154,14 +154,15 @@ Name | Type | Default | Description
154154
children | any | | Children to pass through the component.
155155
disabled | Boolean | false | If true, the radio group will be displayed as disasbled.
156156
name | String | | Name for the input element group.
157-
value | Any | | Default value selected in the radio group.
157+
value | any | | The value of the radio group.
158+
defaultValue | any | | The default value of the radio group.
158159
onChange | Function | | Callback function that will be invoked when the value changes.
159160

160161
### Class Properties
161162

162163
#### RadioButton
163164

164-
Use the ref property to get a reference to the component:
165+
Use the ref property to get a reference to this component:
165166

166167
```jsx
167168
<RadioButton
@@ -178,6 +179,25 @@ Name | Type | Description
178179
:--- | :--- | :----------
179180
checked | Boolean | Get the checked state.
180181

182+
#### RadioGroup
183+
184+
Use the ref property to get a reference to this component:
185+
186+
```jsx
187+
<RadioGroup
188+
ref={node => {
189+
if (node) {
190+
this.radioGroup = node;
191+
console.log(this.radioGroup.value);
192+
}
193+
}}
194+
/>
195+
```
196+
197+
Name | Type | Description
198+
:--- | :--- | :----------
199+
value | Any | Get the value of the radio group.
200+
181201
## License
182202

183203
MIT

dist/react-radio.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/react-radio.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/bundle.js

Lines changed: 17 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
</head>
1212
<body style="background-color: #eee">
1313
<div id="container"></div>
14-
<script type="text/javascript" src="bundle.js?8f86772f41f9fd6b545b"></script></body>
14+
<script type="text/javascript" src="bundle.js?078c050007a7a5b3801c"></script></body>
1515
</html>

examples/RadioGroup.jsx renamed to examples/ControlledRadioGroup.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default class extends PureComponent {
1717
render() {
1818
return (
1919
<Section className="row-sm-11 row-md-6">
20-
<h3>Radio Group</h3>
20+
<h3>Controlled Radio Group</h3>
2121
<h5>Stacked</h5>
2222
<p>{`Selected: "${this.state.ports}"`}</p>
2323
<RadioGroup
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import '@trendmicro/react-tooltip/dist/react-tooltip.css';
2+
import { Tooltip } from '@trendmicro/react-tooltip';
3+
import React, { PureComponent } from 'react';
4+
import Section from './Section';
5+
import { RadioGroup, RadioButton } from '../src';
6+
7+
export default class extends PureComponent {
8+
state = {
9+
ports: '',
10+
comic: ''
11+
};
12+
13+
handleChangeByKey = (key) => (value, event) => {
14+
this.setState({ [key]: value });
15+
};
16+
17+
render() {
18+
return (
19+
<Section className="row-sm-11 row-md-6">
20+
<h3>Uncontrolled Radio Group</h3>
21+
<h5>Stacked</h5>
22+
<p>{`Selected: "${this.state.ports}"`}</p>
23+
<RadioGroup
24+
name="ports"
25+
onChange={this.handleChangeByKey('ports')}
26+
>
27+
<div>
28+
<RadioButton label="All ports" value="all" />
29+
<Tooltip content="All ports">
30+
<i className="fa fa-info-circle" style={{ marginLeft: 8 }} />
31+
</Tooltip>
32+
</div>
33+
<div>
34+
<RadioButton
35+
label="Specified ports"
36+
value="custom"
37+
/>
38+
<Tooltip content="Specified ports">
39+
<i className="fa fa-info-circle" style={{ marginLeft: 8 }} />
40+
</Tooltip>
41+
<div style={{ marginLeft: 22 }}>
42+
<input
43+
type="text"
44+
className="form-control"
45+
placeholder={this.state.ports === 'custom' ? '1-1023, 8000, 8080' : ''}
46+
disabled={this.state.ports !== 'custom'}
47+
onChange={event => {
48+
event.stopPropagation();
49+
}}
50+
/>
51+
<div className="text-muted">
52+
Use a comma to separate multiple ports.
53+
</div>
54+
</div>
55+
</div>
56+
<div>
57+
<RadioButton label="Range" value="range" />
58+
<div style={{ marginLeft: 22 }}>
59+
<div className="row">
60+
<div className="col-xs-6">
61+
<input
62+
type="text"
63+
name="from"
64+
className="form-control"
65+
placeholder={this.state.ports === 'range' ? 'From' : ''}
66+
disabled={this.state.ports !== 'range'}
67+
onChange={event => {
68+
//event.stopPropagation();
69+
}}
70+
/>
71+
</div>
72+
<div className="col-xs-6">
73+
<input
74+
type="text"
75+
name="to"
76+
className="form-control"
77+
placeholder={this.state.ports === 'range' ? 'To' : ''}
78+
disabled={this.state.ports !== 'range'}
79+
onChange={event => {
80+
//event.stopPropagation();
81+
}}
82+
/>
83+
</div>
84+
</div>
85+
</div>
86+
</div>
87+
</RadioGroup>
88+
<h5>Inline</h5>
89+
<p>{`Selected: "${this.state.comic}"`}</p>
90+
<RadioGroup
91+
name="comic"
92+
onChange={this.handleChangeByKey('comic')}
93+
>
94+
<RadioButton label="Batman (DC)" value="dc:batman" />
95+
<RadioButton label="Hulk (Marvel)" value="marvel:hulk" />
96+
<RadioButton label="Superman (DC)" value="dc:superman" />
97+
<RadioButton label="Spider-Man (Marvel)" value="marvel:spiderman" disabled />
98+
</RadioGroup>
99+
</Section>
100+
);
101+
}
102+
}

examples/index.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import ReactDOM from 'react-dom';
55
import Navbar from './Navbar';
66
import UncontrolledRadioButton from './UncontrolledRadioButton';
77
import ControlledRadioButton from './ControlledRadioButton';
8-
import RadioGroup from './RadioGroup';
8+
import UncontrolledRadioGroup from './UncontrolledRadioGroup';
9+
import ControlledRadioGroup from './ControlledRadioGroup';
910

1011
const name = 'React Radio';
1112
const url = 'https://github.com/trendmicro-frontend/react-radio';
@@ -21,7 +22,10 @@ const App = () => (
2122
<ControlledRadioButton />
2223
</div>
2324
<div className="col-lg-6 col-md-12">
24-
<RadioGroup />
25+
<UncontrolledRadioGroup />
26+
</div>
27+
<div className="col-lg-6 col-md-12">
28+
<ControlledRadioGroup />
2529
</div>
2630
</div>
2731
</div>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@trendmicro/react-radio",
3-
"version": "3.1.1",
3+
"version": "3.1.2",
44
"description": "React Radio component",
55
"main": "lib/index.js",
66
"files": [

src/RadioGroup.jsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,31 @@ class RadioGroup extends PureComponent {
77
static propTypes = {
88
disabled: PropTypes.bool,
99
onChange: PropTypes.func,
10-
value: PropTypes.any
10+
value: PropTypes.any,
11+
defaultValue: PropTypes.any
1112
};
1213

1314
static defaultProps = {
1415
disabled: false
1516
};
1617

18+
state = {
19+
value: (this.props.value !== undefined) ? this.props.value : this.props.defaultValue
20+
};
21+
22+
get value() {
23+
return this.state.value;
24+
}
25+
1726
handleChange = (value, event) => {
27+
if (this.props.value !== undefined) {
28+
// Controlled component
29+
this.setState({ value: this.props.value });
30+
} else {
31+
// Uncontrolled component
32+
this.setState({ value: value });
33+
}
34+
1835
if (typeof this.props.onChange === 'function') {
1936
this.props.onChange(value, event);
2037
}
@@ -33,7 +50,7 @@ class RadioGroup extends PureComponent {
3350

3451
if (child.type === RadioButton) {
3552
return cloneElement(child, {
36-
checked: this.props.value === child.props.value,
53+
checked: (this.state.value !== undefined) && (this.state.value === child.props.value),
3754
disabled: this.props.disabled || child.props.disabled,
3855
onChange: chainedFunction(
3956
child.props.onChange,
@@ -60,6 +77,14 @@ class RadioGroup extends PureComponent {
6077
}
6178
};
6279

80+
componentWillReceiveProps(nextProps) {
81+
if (nextProps.value !== undefined) {
82+
this.setState({
83+
value: nextProps.value
84+
});
85+
}
86+
}
87+
6388
render() {
6489
return this.renderChildren(this.props.children);
6590
}

0 commit comments

Comments
 (0)