diff --git a/packages/patternfly-4/react-core/src/components/Radio/Radio.d.ts b/packages/patternfly-4/react-core/src/components/Radio/Radio.d.ts index 89060fe02c9..c06928f9d97 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/Radio.d.ts +++ b/packages/patternfly-4/react-core/src/components/Radio/Radio.d.ts @@ -1,11 +1,15 @@ -import { HTMLProps, FormEvent } from 'react'; +import { HTMLProps, FormEvent, ReactNode } from 'react'; import { Omit } from '../../typeUtils'; export interface RadioProps extends Omit, 'type' | 'onChange' | 'disabled'> { - isDisabled: boolean; - isValid: boolean; - onChange(checked: boolean, event: FormEvent): void; + isDisabled?: boolean; + isValid?: boolean; + onChange?(checked: boolean, event: FormEvent): void; + id: string; + 'aria-label': string; + label?: ReactNode; + name: string; } declare const Radio: React.SFC; diff --git a/packages/patternfly-4/react-core/src/components/Radio/Radio.docs.js b/packages/patternfly-4/react-core/src/components/Radio/Radio.docs.js index abee8f29be7..9874789cdd2 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/Radio.docs.js +++ b/packages/patternfly-4/react-core/src/components/Radio/Radio.docs.js @@ -1,12 +1,13 @@ -import { Checkbox } from '@patternfly/react-core'; import Controlled from './examples/ControlledRadio'; import Uncontrolled from './examples/UncontrolledRadio'; import Disabled from './examples/DisabledRadio'; +import Custom from './examples/CustomLabelRadio'; +import { Radio } from '@patternfly/react-core'; export default { title: 'Radio', components: { - Checkbox + Radio }, - examples: [Controlled, Uncontrolled, Disabled] + examples: [Controlled, Uncontrolled, Disabled, Custom] }; diff --git a/packages/patternfly-4/react-core/src/components/Radio/Radio.js b/packages/patternfly-4/react-core/src/components/Radio/Radio.js index 71dea42b5d3..b986a4020d1 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/Radio.js +++ b/packages/patternfly-4/react-core/src/components/Radio/Radio.js @@ -1,24 +1,33 @@ import React from 'react'; import styles from '@patternfly/patternfly-next/components/Check/check.css'; -import { css } from '@patternfly/react-styles'; import PropTypes from 'prop-types'; +import { css, getModifier } from '@patternfly/react-styles'; const propTypes = { - /** additional classes added to the Radio */ + /** Additional classes added to the Radio. */ className: PropTypes.string, /** Flag to show if the Radio selection is valid or invalid. */ isValid: PropTypes.bool, /** Flag to show if the Radio is disabled. */ isDisabled: PropTypes.bool, /** A callback for when the Radio selection changes. */ - onChange: PropTypes.func + onChange: PropTypes.func, + /** Label text of the Radio. */ + label: PropTypes.node, + /** Id of the Radio. */ + id: PropTypes.string.isRequired, + /** Aria-label of the Radio. */ + 'aria-label': PropTypes.any.isRequired, + /** Name for group of Radios */ + name: PropTypes.string.isRequired }; const defaultProps = { className: '', isValid: true, isDisabled: false, - onChange: () => undefined + onChange: () => undefined, + label: undefined }; class Radio extends React.Component { @@ -27,16 +36,23 @@ class Radio extends React.Component { }; render() { - const { className, onChange, isValid, isDisabled, ...props } = this.props; + const { className, onChange, isValid, isDisabled, label, ...props } = this.props; return ( - +
+ + {label && ( + + )} +
); } } diff --git a/packages/patternfly-4/react-core/src/components/Radio/Radio.test.js b/packages/patternfly-4/react-core/src/components/Radio/Radio.test.js index b1d525a2336..f92394b2ca9 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/Radio.test.js +++ b/packages/patternfly-4/react-core/src/components/Radio/Radio.test.js @@ -1,33 +1,65 @@ import React from 'react'; -import { shallow } from 'enzyme'; import Radio from './Radio'; +import { shallow } from 'enzyme'; const props = { onChange: jest.fn(), checked: false }; -test('controlled', () => { - const view = shallow(); - expect(view).toMatchSnapshot(); -}); +describe('Radio check component', () => { + test('controlled', () => { + const view = shallow(); + expect(view).toMatchSnapshot(); + }); -test('uncontrolled', () => { - const view = shallow(); - expect(view).toMatchSnapshot(); -}); + test('uncontrolled', () => { + const view = shallow(); + expect(view).toMatchSnapshot(); + }); -test('isDisabled', () => { - const view = shallow(); - expect(view).toMatchSnapshot(); -}); + test('isDisabled', () => { + const view = shallow(); + expect(view).toMatchSnapshot(); + }); + + test('label is string', () => { + const view = shallow(); + expect(view).toMatchSnapshot(); + }); + + test('label is function', () => { + const functionLabel = () =>

Header

; + const view = shallow(); + expect(view).toMatchSnapshot(); + }); + + test('label is node', () => { + const view = shallow(Header} id="check" checked aria-label="check" name="check" />); + expect(view).toMatchSnapshot(); + }); + + test('passing class', () => { + const view = shallow( + + ); + expect(view).toMatchSnapshot(); + }); + + test('passing HTML attribute', () => { + const view = shallow( + + ); + expect(view).toMatchSnapshot(); + }); -test('radio passes value and event to onChange handler', () => { - const newValue = true; - const event = { - currentTarget: { checked: newValue } - }; - const view = shallow(); - view.find('input').simulate('change', event); - expect(props.onChange).toBeCalledWith(newValue, event); + test('Radio passes value and event to onChange handler', () => { + const newValue = true; + const event = { + currentTarget: { checked: newValue } + }; + const view = shallow(); + view.find('input').simulate('change', event); + expect(props.onChange).toBeCalledWith(newValue, event); + }); }); diff --git a/packages/patternfly-4/react-core/src/components/Radio/__snapshots__/Radio.test.js.snap b/packages/patternfly-4/react-core/src/components/Radio/__snapshots__/Radio.test.js.snap index 0e4c1de9ba5..83a0b1c4db6 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/__snapshots__/Radio.test.js.snap +++ b/packages/patternfly-4/react-core/src/components/Radio/__snapshots__/Radio.test.js.snap @@ -1,44 +1,249 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`controlled 1`] = ` +exports[`Radio check component controlled 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check { + display: block; +} + +
+ +
+`; + +exports[`Radio check component isDisabled 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check { + display: block; +} + +
+ +
+`; + +exports[`Radio check component label is function 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check__label { + display: block; +} .pf-c-check { display: block; } - +> + + + `; -exports[`isDisabled 1`] = ` +exports[`Radio check component label is node 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check__label { + display: block; +} .pf-c-check { display: block; } - +> + + + `; -exports[`uncontrolled 1`] = ` +exports[`Radio check component label is string 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check__label { + display: block; +} +.pf-c-check { + display: block; +} + +
+ + +
+`; + +exports[`Radio check component passing HTML attribute 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check__label { + display: block; +} +.pf-c-check { + display: block; +} + +
+ + +
+`; + +exports[`Radio check component passing class 1`] = ` +.pf-c-check__input { + display: block; +} +.pf-c-check__label { + display: block; +} +.pf-c-check.class-123 { + display: block; +} + +
+ + +
+`; + +exports[`Radio check component uncontrolled 1`] = ` +.pf-c-check__input { + display: block; +} .pf-c-check { display: block; } - +> + + `; diff --git a/packages/patternfly-4/react-core/src/components/Radio/examples/ControlledRadio.js b/packages/patternfly-4/react-core/src/components/Radio/examples/ControlledRadio.js index 767c3d458a9..8a70c3e8e92 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/examples/ControlledRadio.js +++ b/packages/patternfly-4/react-core/src/components/Radio/examples/ControlledRadio.js @@ -21,14 +21,18 @@ class ControlledRadio extends React.Component { checked={this.state.value === '3'} name="pf-version" onChange={this.handleChange} - aria-label="Patternfly 3" + aria-label="Controlled radio 1" + label="Controlled radio 1" + id="radio-1" />{' '} ); diff --git a/packages/patternfly-4/react-core/src/components/Radio/examples/CustomLabelRadio.js b/packages/patternfly-4/react-core/src/components/Radio/examples/CustomLabelRadio.js new file mode 100644 index 00000000000..be56ab3a057 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Radio/examples/CustomLabelRadio.js @@ -0,0 +1,24 @@ +import React from 'react'; +import getContainerProps from './common/getContainerProps'; +import { Radio, Badge } from '@patternfly/react-core'; + +class CustomLabelRadio extends React.Component { + static title = 'Custom label Radio'; + static getContainerProps = getContainerProps; + + render() { + return ( + + Badge here!} id="radio-6" name="radios-custom" aria-label="custom-label-1" /> + Different badge!} + id="radio-7" + name="radios-custom" + aria-label="custom-label-2" + /> + + ); + } +} + +export default CustomLabelRadio; diff --git a/packages/patternfly-4/react-core/src/components/Radio/examples/DisabledRadio.js b/packages/patternfly-4/react-core/src/components/Radio/examples/DisabledRadio.js index de917c299d6..aeac3e0944a 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/examples/DisabledRadio.js +++ b/packages/patternfly-4/react-core/src/components/Radio/examples/DisabledRadio.js @@ -7,8 +7,21 @@ class DisabledRadio extends React.Component { render() { return ( - {' '} - + {' '} + ); } diff --git a/packages/patternfly-4/react-core/src/components/Radio/examples/UncontrolledRadio.js b/packages/patternfly-4/react-core/src/components/Radio/examples/UncontrolledRadio.js index dac842a346f..a9d8a1fa312 100644 --- a/packages/patternfly-4/react-core/src/components/Radio/examples/UncontrolledRadio.js +++ b/packages/patternfly-4/react-core/src/components/Radio/examples/UncontrolledRadio.js @@ -5,7 +5,9 @@ class UncontrolledRadio extends React.Component { static title = 'Uncontrolled Radio'; render() { - return ; + return ( + + ); } } diff --git a/packages/patternfly-4/react-core/src/components/Radio/examples/common/getContainerProps.js b/packages/patternfly-4/react-core/src/components/Radio/examples/common/getContainerProps.js new file mode 100644 index 00000000000..b3d2b3d3f90 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Radio/examples/common/getContainerProps.js @@ -0,0 +1,9 @@ +import { css, StyleSheet } from '@patternfly/react-styles'; + +const styles = StyleSheet.create({ + demoLayout: { + backgroundColor: '#fff' + } +}); + +export default () => ({ className: css(styles.demoLayout) });