From da2dccb149d6e37c962c0642baaab8a764e65741 Mon Sep 17 00:00:00 2001 From: Ming Xiao Date: Thu, 9 Aug 2018 12:16:54 -0700 Subject: [PATCH] RadioGroups can hold value and passes and to children [#159416165] Signed-off-by: Reid Mitchell --- .../radio/radio-group_spec.js | 60 ++++++++++++------- src/react/radio/radio-group.js | 22 ++++--- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/spec/pivotal-ui-react/radio/radio-group_spec.js b/spec/pivotal-ui-react/radio/radio-group_spec.js index 71a3afc22..b43e6e352 100644 --- a/spec/pivotal-ui-react/radio/radio-group_spec.js +++ b/spec/pivotal-ui-react/radio/radio-group_spec.js @@ -2,40 +2,56 @@ import '../spec_helper'; import {Radio, RadioGroup} from '../../../src/react/radio'; describe('RadioGroup', () => { + let subject; + const secondRadioSpy = jasmine.createSpy('secondRadio'); - const renderComponent = props => ReactDOM.render( - first - second - third - , root); + beforeEach(() => { + subject = ReactDOM.render( + first + second + third + , root); + }); + + it('renders', () => { + expect('.pui-radio-group input[type="radio"]').toHaveLength(3); + expect('.pui-radio-group input[type="radio"]:eq(0)').toHaveValue('one'); + expect('.pui-radio-group input[type="radio"]:eq(1)').toHaveValue('two'); + expect('.pui-radio-group input[type="radio"]:eq(2)').toHaveValue('three'); + }); - describe('basic RadioGroup', () => { - it('renders', () => { - renderComponent({name: 'radioGroup'}); + describe('when the radio button is changed', () => { + let clickedValue, changeSpy; - expect('.pui-radio-group input[type="radio"]').toHaveLength(3); - expect('.pui-radio-group input[type="radio"]:eq(0)').toHaveValue('one'); - expect('.pui-radio-group input[type="radio"]:eq(1)').toHaveValue('two'); - expect('.pui-radio-group input[type="radio"]:eq(2)').toHaveValue('three'); + beforeEach(() => { + clickedValue = null; + changeSpy = jasmine.createSpy('change').and.callFake(event => clickedValue = event.nativeEvent.target.value); + subject::setProps({onChange: changeSpy, name: 'radioGroup'}); + $('.pui-radio-group input[type="radio"]:eq(0)').simulate('change'); }); - describe('when the radio button is changed', () => { - it('calls the change callback', () => { - let clickedValue = null; - const changeSpy = jasmine.createSpy('change').and.callFake(event => clickedValue = event.nativeEvent.target.value); - renderComponent({onChange: changeSpy, name: 'radioGroup'}); - $('.pui-radio-group input[type="radio"]:eq(0)').simulate('change'); + it('calls the change callback', () => { + expect(changeSpy.calls.count()).toEqual(1); + expect(clickedValue).toEqual('one'); + }); + }); - expect(changeSpy.calls.count()).toEqual(1); - expect(clickedValue).toEqual('one'); - }); + describe('when given a value', () => { + beforeEach(() => { + subject::setProps({value: 'three'}); + }); + + it('checks the corresponding radio', () => { + expect('.pui-radio-group input[type="radio"]:eq(0)').not.toBeChecked(); + expect('.pui-radio-group input[type="radio"]:eq(1)').not.toBeChecked(); + expect('.pui-radio-group input[type="radio"]:eq(2)').toBeChecked(); }); }); describe('other props and no onChange', () => { beforeEach(() => { - renderComponent({id: 'clear-channel', style: {color: 'rgb(255, 0, 0)'}, className: '1234', name: 'radioGroup'}); + subject::setProps({id: 'clear-channel', style: {color: 'rgb(255, 0, 0)'}, className: '1234'}); }); it('passes id, style, and className to radio group', () => { diff --git a/src/react/radio/radio-group.js b/src/react/radio/radio-group.js index 2fdf18674..70cb78da9 100644 --- a/src/react/radio/radio-group.js +++ b/src/react/radio/radio-group.js @@ -5,8 +5,9 @@ import classnames from 'classnames'; export class RadioGroup extends React.Component { static propTypes = { id: PropTypes.string, - name: PropTypes.string.isRequired, - onChange: PropTypes.func + name: PropTypes.string, + onChange: PropTypes.func, + value: PropTypes.any }; componentDidMount() { @@ -14,17 +15,14 @@ export class RadioGroup extends React.Component { } render() { - const {name, children, onChange, className, ...others} = this.props; + const {name, children, onChange, className, value, ...others} = this.props; const radioProps = onChange ? {name, onChange} : {name}; - const renderedChildren = React.Children.map(children, child => - React.cloneElement(child, radioProps)); - - const props = { - ...others, - className: classnames('pui-radio-group', className) - }; - - return
{renderedChildren}
; + return ( +
+ {React.Children.map(children, child => + React.cloneElement(child, {...radioProps, checked: child.props.value === value}))} +
+ ); } }