Skip to content

Commit

Permalink
RadioGroup can be an uncontrolled component when not passing the "val…
Browse files Browse the repository at this point in the history
…ue" prop
  • Loading branch information
cheton committed Feb 13, 2018
1 parent 3a702b7 commit 7f8ef2d
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 21 deletions.
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ defaultChecked | Boolean | | The default checked state of the radio button.
disabled | Boolean | false | If true, the radio button will be shown as disabled and cannot be modified.
label | Node or String | | Label for the radio button.
name | String | | Name for the input element.
value | Any | | Value for the radio button.
value | any | | Value for the radio button.
onChange | Function | | Callback function that will be invoked when the value changes.

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

### Class Properties

#### RadioButton

Use the ref property to get a reference to the component:
Use the ref property to get a reference to this component:

```jsx
<RadioButton
Expand All @@ -178,6 +179,25 @@ Name | Type | Description
:--- | :--- | :----------
checked | Boolean | Get the checked state.

#### RadioGroup

Use the ref property to get a reference to this component:

```jsx
<RadioGroup
ref={node => {
if (node) {
this.radioGroup = node;
console.log(this.radioGroup.value);
}
}}
/>
```

Name | Type | Description
:--- | :--- | :----------
value | Any | Get the value of the radio group.

## License

MIT
2 changes: 1 addition & 1 deletion dist/react-radio.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/react-radio.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 17 additions & 9 deletions docs/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
</head>
<body style="background-color: #eee">
<div id="container"></div>
<script type="text/javascript" src="bundle.js?8f86772f41f9fd6b545b"></script></body>
<script type="text/javascript" src="bundle.js?078c050007a7a5b3801c"></script></body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default class extends PureComponent {
render() {
return (
<Section className="row-sm-11 row-md-6">
<h3>Radio Group</h3>
<h3>Controlled Radio Group</h3>
<h5>Stacked</h5>
<p>{`Selected: "${this.state.ports}"`}</p>
<RadioGroup
Expand Down
102 changes: 102 additions & 0 deletions examples/UncontrolledRadioGroup.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import '@trendmicro/react-tooltip/dist/react-tooltip.css';
import { Tooltip } from '@trendmicro/react-tooltip';
import React, { PureComponent } from 'react';
import Section from './Section';
import { RadioGroup, RadioButton } from '../src';

export default class extends PureComponent {
state = {
ports: '',
comic: ''
};

handleChangeByKey = (key) => (value, event) => {
this.setState({ [key]: value });
};

render() {
return (
<Section className="row-sm-11 row-md-6">
<h3>Uncontrolled Radio Group</h3>
<h5>Stacked</h5>
<p>{`Selected: "${this.state.ports}"`}</p>
<RadioGroup
name="ports"
onChange={this.handleChangeByKey('ports')}
>
<div>
<RadioButton label="All ports" value="all" />
<Tooltip content="All ports">
<i className="fa fa-info-circle" style={{ marginLeft: 8 }} />
</Tooltip>
</div>
<div>
<RadioButton
label="Specified ports"
value="custom"
/>
<Tooltip content="Specified ports">
<i className="fa fa-info-circle" style={{ marginLeft: 8 }} />
</Tooltip>
<div style={{ marginLeft: 22 }}>
<input
type="text"
className="form-control"
placeholder={this.state.ports === 'custom' ? '1-1023, 8000, 8080' : ''}
disabled={this.state.ports !== 'custom'}
onChange={event => {
event.stopPropagation();
}}
/>
<div className="text-muted">
Use a comma to separate multiple ports.
</div>
</div>
</div>
<div>
<RadioButton label="Range" value="range" />
<div style={{ marginLeft: 22 }}>
<div className="row">
<div className="col-xs-6">
<input
type="text"
name="from"
className="form-control"
placeholder={this.state.ports === 'range' ? 'From' : ''}
disabled={this.state.ports !== 'range'}
onChange={event => {
//event.stopPropagation();
}}
/>
</div>
<div className="col-xs-6">
<input
type="text"
name="to"
className="form-control"
placeholder={this.state.ports === 'range' ? 'To' : ''}
disabled={this.state.ports !== 'range'}
onChange={event => {
//event.stopPropagation();
}}
/>
</div>
</div>
</div>
</div>
</RadioGroup>
<h5>Inline</h5>
<p>{`Selected: "${this.state.comic}"`}</p>
<RadioGroup
name="comic"
onChange={this.handleChangeByKey('comic')}
>
<RadioButton label="Batman (DC)" value="dc:batman" />
<RadioButton label="Hulk (Marvel)" value="marvel:hulk" />
<RadioButton label="Superman (DC)" value="dc:superman" />
<RadioButton label="Spider-Man (Marvel)" value="marvel:spiderman" disabled />
</RadioGroup>
</Section>
);
}
}
8 changes: 6 additions & 2 deletions examples/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import ReactDOM from 'react-dom';
import Navbar from './Navbar';
import UncontrolledRadioButton from './UncontrolledRadioButton';
import ControlledRadioButton from './ControlledRadioButton';
import RadioGroup from './RadioGroup';
import UncontrolledRadioGroup from './UncontrolledRadioGroup';
import ControlledRadioGroup from './ControlledRadioGroup';

const name = 'React Radio';
const url = 'https://github.com/trendmicro-frontend/react-radio';
Expand All @@ -21,7 +22,10 @@ const App = () => (
<ControlledRadioButton />
</div>
<div className="col-lg-6 col-md-12">
<RadioGroup />
<UncontrolledRadioGroup />
</div>
<div className="col-lg-6 col-md-12">
<ControlledRadioGroup />
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@trendmicro/react-radio",
"version": "3.1.1",
"version": "3.1.2",
"description": "React Radio component",
"main": "lib/index.js",
"files": [
Expand Down
29 changes: 27 additions & 2 deletions src/RadioGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,31 @@ class RadioGroup extends PureComponent {
static propTypes = {
disabled: PropTypes.bool,
onChange: PropTypes.func,
value: PropTypes.any
value: PropTypes.any,
defaultValue: PropTypes.any
};

static defaultProps = {
disabled: false
};

state = {
value: (this.props.value !== undefined) ? this.props.value : this.props.defaultValue
};

get value() {
return this.state.value;
}

handleChange = (value, event) => {
if (this.props.value !== undefined) {
// Controlled component
this.setState({ value: this.props.value });
} else {
// Uncontrolled component
this.setState({ value: value });
}

if (typeof this.props.onChange === 'function') {
this.props.onChange(value, event);
}
Expand All @@ -33,7 +50,7 @@ class RadioGroup extends PureComponent {

if (child.type === RadioButton) {
return cloneElement(child, {
checked: this.props.value === child.props.value,
checked: (this.state.value !== undefined) && (this.state.value === child.props.value),
disabled: this.props.disabled || child.props.disabled,
onChange: chainedFunction(
child.props.onChange,
Expand All @@ -60,6 +77,14 @@ class RadioGroup extends PureComponent {
}
};

componentWillReceiveProps(nextProps) {
if (nextProps.value !== undefined) {
this.setState({
value: nextProps.value
});
}
}

render() {
return this.renderChildren(this.props.children);
}
Expand Down

0 comments on commit 7f8ef2d

Please sign in to comment.