Skip to content

Commit

Permalink
[RadioGroup] Support uncontrolled mode (#13929)
Browse files Browse the repository at this point in the history
* [RadioGroup] Support uncontrolled mode

* Add unit test

* Integrate PR's feedback
  • Loading branch information
rfbotto authored and oliviertassinari committed Dec 20, 2018
1 parent 7e1eeaa commit 43f93a5
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 18 deletions.
24 changes: 20 additions & 4 deletions packages/material-ui/src/RadioGroup/RadioGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import { createChainedFunction, find } from '../utils/helpers';
class RadioGroup extends React.Component {
radios = [];

state = {
value: null,
};

constructor(props) {
super();
this.isControlled = props.value != null;
}

focus = () => {
if (!this.radios || !this.radios.length) {
return;
Expand All @@ -30,15 +39,22 @@ class RadioGroup extends React.Component {
focusRadios[0].focus();
};

handleRadioChange = (event, checked) => {
if (checked && this.props.onChange) {
handleChange = event => {
if (!this.isControlled) {
this.setState({
value: event.target.value,
});
}

if (this.props.onChange) {
this.props.onChange(event, event.target.value);
}
};

render() {
const { children, name, value, onChange, ...other } = this.props;
const { children, name, value: valueProp, onChange, ...other } = this.props;

const value = this.isControlled ? valueProp : this.state.value;
this.radios = [];

return (
Expand All @@ -64,7 +80,7 @@ class RadioGroup extends React.Component {
}
},
checked: value === child.props.value,
onChange: createChainedFunction(child.props.onChange, this.handleRadioChange),
onChange: createChainedFunction(child.props.onChange, this.handleChange),
});
})}
</FormGroup>
Expand Down
33 changes: 19 additions & 14 deletions packages/material-ui/src/RadioGroup/RadioGroup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ describe('<RadioGroup />', () => {
assert.strictEqual(handleKeyDown.args[0][0], event);
});

it('should support uncontrolled mode', () => {
const wrapper = shallow(
<RadioGroup name="group">
<Radio value="one" />
</RadioGroup>,
);

const radio = wrapper.children().first();
const event = { target: { value: 'one' } };
radio.simulate('change', event, true);
assert.strictEqual(
wrapper
.children()
.first()
.props().checked,
true,
);
});

describe('imperative focus()', () => {
let wrapper;

Expand Down Expand Up @@ -134,20 +153,6 @@ describe('<RadioGroup />', () => {
assert.strictEqual(handleChange.calledWith(event), true);
});

it('should not fire onChange if not checked', () => {
const handleChange = spy();
const wrapper = shallow(
<RadioGroup value="" onChange={handleChange}>
<Radio />
<Radio />
</RadioGroup>,
);

const internalRadio = wrapper.children().first();
internalRadio.simulate('change', { target: { value: 'woofRadioGroup' } }, false);
assert.strictEqual(handleChange.callCount, 0);
});

it('should chain the onChange property', () => {
const handleChange1 = spy();
const handleChange2 = spy();
Expand Down

0 comments on commit 43f93a5

Please sign in to comment.