Last active
December 7, 2020 09:13
-
-
Save Munter/7c6892d950816e049bf2 to your computer and use it in GitHub Desktop.
React radio input group component, giving you a single selected value across a range of radio inputs in its children
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function (require) { | |
var expect = require('unexpected'); | |
var React = require('react'); | |
var ReactTestUtils = React.addons.TestUtils; | |
var RadioGroup = require('jsx!../RadioGroupComponent.jsx'); | |
describe('RadioGroupComponent', function() { | |
it('should render', function() { | |
var instance = ReactTestUtils.renderIntoDocument(<RadioGroup />); | |
expect(instance, 'to be defined'); | |
}); | |
describe('value', function () { | |
it('should not check any radio buttons when there is no value', function () { | |
var instance = ReactTestUtils.renderIntoDocument( | |
<RadioGroup> | |
<input type="radio" value="one" /> | |
<input type="radio" value="two" /> | |
</RadioGroup>); | |
var inputs = Array.prototype.slice.call(instance.getDOMNode().querySelectorAll('input[type="radio"]')); | |
expect(inputs, 'to have length', 2); | |
expect(inputs, 'to be an array whose items satisfy', function (input) { | |
expect(input.checked, 'to be', false); | |
}); | |
}); | |
it('should not check any radio buttons when there is a value, but no input has the value', function () { | |
var instance = ReactTestUtils.renderIntoDocument( | |
<RadioGroup value="foo"> | |
<input type="radio" value="one" /> | |
<input type="radio" value="two" /> | |
</RadioGroup>); | |
var inputs = Array.prototype.slice.call(instance.getDOMNode().querySelectorAll('input[type="radio"]')); | |
expect(inputs, 'to have length', 2); | |
expect(inputs, 'to be an array whose items satisfy', function (input) { | |
expect(input.checked, 'to be', false); | |
}); | |
}); | |
it('should check the radio button with the corresponding value when a value is defined', function () { | |
var instance = ReactTestUtils.renderIntoDocument( | |
<RadioGroup value="two"> | |
<input type="radio" value="one" /> | |
<input type="radio" value="two" /> | |
</RadioGroup>); | |
var inputs = Array.prototype.slice.call(instance.getDOMNode().querySelectorAll('input[type="radio"]')); | |
expect(inputs, 'to have length', 2); | |
expect(inputs[0], 'to satisfy', function (input) { | |
expect(input.checked, 'to be', false); | |
}); | |
// console.log(inputs[1].outerHTML); | |
// expect(inputs[1], 'to satisfy', function (input) { | |
// expect(input.checked, 'to be', true); | |
// }); | |
}); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function(require) { | |
'use strict'; | |
var React = require('react'); | |
var traverseChildren = (children, cb) => { | |
React.Children.forEach(children, (child) => { | |
cb(child); | |
if (child.props && child.props.children) { | |
traverseChildren(child.props.children, cb); | |
} | |
}); | |
}; | |
var RadioGroupComponent = React.createClass({ | |
displayName: 'RadioGroupComponent', | |
propTypes: { | |
name: React.PropTypes.string, | |
value: React.PropTypes.string, | |
onChange: React.PropTypes.func | |
}, | |
componentWillMount() { | |
this._initChildren(this.props); | |
}, | |
componentWillUpdate(nextProps, nextState) { | |
this._initChildren(nextProps); | |
}, | |
_initChildren(nextProps) { | |
var hasChangeHandler = typeof nextProps.onChange === 'function'; | |
traverseChildren(nextProps.children, (child) => { | |
if (child.type === 'input' && child.props.type === 'radio') { | |
if (hasChangeHandler) { | |
child.props.onChange = this._handleChange; | |
} | |
if (nextProps.name && !child.props.name) { | |
child.props.name = nextProps.name; | |
} | |
if (nextProps.value && nextProps.value === child.props.value) { | |
if (hasChangeHandler) { | |
child.props.checked = true; | |
} else { | |
child.props.defaultChecked = true; | |
} | |
} | |
} | |
}); | |
}, | |
_handleChange(e) { | |
if (e.target.checked) { | |
this.props.onChange(e.target.value); | |
} | |
}, | |
render() { | |
return <div>{this.props.children}</div>; | |
} | |
}); | |
return RadioGroupComponent; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment