Skip to content

Commit

Permalink
feat(radio): Add name and value required props
Browse files Browse the repository at this point in the history
  • Loading branch information
lzcabrera committed Nov 30, 2017
1 parent d7d77c3 commit 81c9f97
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 26 deletions.
24 changes: 20 additions & 4 deletions src/components/Radio/Radio.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,28 @@ class Radio extends React.Component {
}

render() {
const { label, feedback, ...rest } = this.props
const radioId = generateId(rest.id, rest.name, label)
const { label, name, value, feedback, ...rest } = this.props

let radioId
if (rest.id) {
radioId = generateId(rest.id).identity()
} else {
radioId = generateId(name).postfix(value)
}

return (
<label data-no-global-styles htmlFor={radioId.identity()}>
<label data-no-global-styles htmlFor={radioId}>
<Box inline between={3} dangerouslyAddClassName={styles.alignCenter}>
<span
className={getClassNames(this.state.checked, this.state.focus, feedback, rest.disabled)}
data-testid="fake-radio"
>
<input
{...safeRest(rest)}
id={radioId.identity()}
id={radioId}
type="radio"
name={name}
value={value}
checked={this.state.checked}
className={displayStyles.hide}
onChange={this.onChange}
Expand Down Expand Up @@ -140,6 +148,14 @@ Radio.propTypes = {
* The label.
*/
label: PropTypes.string.isRequired,
/**
* Associate this radio with a group. Set as the HTML name attribute.
*/
name: PropTypes.string.isRequired,
/**
* The value. Must be unique within the group.
*/
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
/**
* The checked state
*/
Expand Down
18 changes: 12 additions & 6 deletions src/components/Radio/Radio.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
```
initialState = {
choice: undefined
};
const setChoice = (value) => setState({choice: value});
<Box tag="fieldset" between={2}>
<Radio label="Choice A" name="choice" />
<Radio label="Choice F" name="choice" />
<Radio label="Choice A" name="group1" value="a" checked={state.choice === "a"} onChange={e => setChoice(e.target.value)} />
<Radio label="Choice F" name="group2" value="f" checked={state.choice === "f"} onChange={e => setChoice(e.target.value)} />
</Box>
```

```
<Radio label="Choice B" feedback="error" />
<Radio label="Choice B" name="group3" value="b" feedback="error" />
```


```
<Radio label="Choice C" checked />
<Radio label="Choice C" name="group4" value="c" checked />
```

```
<Radio label="Choice D" disabled />
<Radio label="Choice D" name="group5" value="d" disabled />
```


```
<Radio label="Choice E" disabled checked />
<Radio label="Choice E" name="group6" value="e" disabled checked />
```
30 changes: 16 additions & 14 deletions src/components/Radio/__tests__/Radio.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import ColoredTextProvider from '../../Typography/ColoredTextProvider/ColoredTex
describe('Radio', () => {
const defaultProps = {
label: 'The radio',
name: 'radio_group',
value: 'the-value',
}
const doMount = (overrides = {}) => {
const radio = mount(<Radio {...defaultProps} {...overrides} />)
Expand All @@ -30,7 +32,7 @@ describe('Radio', () => {
}

it('renders', () => {
const radio = render(<Radio label="A label" />)
const radio = render(<Radio label="A label" name="the-group" value="the-value" />)

expect(radio).toMatchSnapshot()
})
Expand All @@ -41,6 +43,13 @@ describe('Radio', () => {
expect(label).toContainReact(<Text size="medium">Some label</Text>)
})

it('must have a name and a value', () => {
const { findRadioElement } = doMount({ name: 'some-radio-group', value: 'some-value' })

expect(findRadioElement()).toHaveProp('name', 'some-radio-group')
expect(findRadioElement()).toHaveProp('value', 'some-value')
})

describe('connecting the label to the radio', () => {
it('connects the label to the radio', () => {
const { label, findRadioElement } = doMount()
Expand All @@ -51,26 +60,19 @@ describe('Radio', () => {
it('uses the id when provided', () => {
const { label, findRadioElement } = doMount({
id: 'the-id',
name: 'the-name',
label: 'The label',
name: 'the-radio-group',
value: 'the-value',
})

expect(label).toHaveProp('htmlFor', 'the-id')
expect(findRadioElement()).toHaveProp('id', 'the-id')
})

it('uses the name when no id is provided', () => {
const { label, findRadioElement } = doMount({ name: 'the-name', label: 'The label' })

expect(label).toHaveProp('htmlFor', 'the-name')
expect(findRadioElement()).toHaveProp('id', 'the-name')
})

it('generates an id from the label when no id or name is provided', () => {
const { label, findRadioElement } = doMount({ label: 'The label' })
it('uses the name and the value when no id is provided', () => {
const { label, findRadioElement } = doMount({ name: 'the-radio-group', value: 'the-value' })

expect(label).toHaveProp('htmlFor', 'the-label')
expect(findRadioElement()).toHaveProp('id', 'the-label')
expect(label).toHaveProp('htmlFor', 'the-radio-group_the-value')
expect(findRadioElement()).toHaveProp('id', 'the-radio-group_the-value')
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`Radio renders 1`] = `
<label
data-no-global-styles="true"
for="a-label"
for="the-group_the-value"
>
<div
class="betweenRightMarginDesktop-3 inline alignCenter"
Expand All @@ -14,8 +14,10 @@ exports[`Radio renders 1`] = `
>
<input
class="hide"
id="a-label"
id="the-group_the-value"
name="the-group"
type="radio"
value="the-value"
/>
</span>
<span
Expand Down

0 comments on commit 81c9f97

Please sign in to comment.