Skip to content

Commit

Permalink
feat(checkbox): Add onFocus and onBlur callbacks and willReceiveProps
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanoglesby08 committed Nov 29, 2017
1 parent 620a3e5 commit 6786a75
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 21 deletions.
38 changes: 31 additions & 7 deletions src/components/Checkbox/Checkbox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ import displayStyles from '../Display.modules.scss'
class Checkbox extends React.Component {
state = {
checked: this.props.checked,
focused: false,
focus: false,
}

componentWillReceiveProps(nextProps) {
if (this.state.checked !== nextProps.checked) {
this.setState({
checked: nextProps.checked,
})
}
}

onChange = event => {
Expand All @@ -30,16 +38,28 @@ class Checkbox extends React.Component {
}
}

onFocus = () => {
this.setState({ focused: true })
onFocus = event => {
const { onFocus } = this.props

this.setState({ focus: true })

if (onFocus) {
onFocus(event)
}
}

onBlur = () => {
this.setState({ focused: false })
onBlur = event => {
const { onBlur } = this.props

this.setState({ focus: false })

if (onBlur) {
onBlur(event)
}
}

render() {
const { label, checked, ...rest } = this.props
const { label, ...rest } = this.props
const checkboxId = generateId(rest.id, rest.name, label)

return (
Expand All @@ -48,7 +68,7 @@ class Checkbox extends React.Component {
<span
className={joinClassNames(
this.state.checked ? styles.checked : styles.unchecked,
this.state.focused && styles.focused
this.state.focus && styles.focused
)}
data-testid="fake-checkbox"
>
Expand Down Expand Up @@ -78,11 +98,15 @@ Checkbox.propTypes = {
label: PropTypes.string.isRequired,
checked: PropTypes.bool,
onChange: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
}

Checkbox.defaultProps = {
checked: false,
onChange: undefined,
onFocus: undefined,
onBlur: undefined,
}

export default Checkbox
42 changes: 35 additions & 7 deletions src/components/Checkbox/__tests__/Checkbox.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe('Checkbox', () => {
findFakeCheckbox: () => checkbox.find('[data-testid="fake-checkbox"]'),
check: () => findCheckboxElement().simulate('change', { target: { checked: true } }),
uncheck: () => findCheckboxElement().simulate('change', { target: { checked: false } }),
focus: () => findCheckboxElement().simulate('focus'),
blur: () => findCheckboxElement().simulate('blur'),
focus: (focusEvent = {}) => findCheckboxElement().simulate('focus', focusEvent),
blur: (blurEvent = {}) => findCheckboxElement().simulate('blur', blurEvent),
}
}

Expand Down Expand Up @@ -109,20 +109,28 @@ describe('Checkbox', () => {
expect(findFakeCheckbox().find(DecorativeIcon)).toBeEmpty()
})

it('triggers a change handler when checked or unchecked', () => {
const onChangeSpy = jest.fn()
const { check, uncheck } = doMount({ onChange: onChangeSpy })
it('notifies when it is checked or unchecked', () => {
const onChangeMock = jest.fn()
const { check, uncheck } = doMount({ onChange: onChangeMock })

check()
expect(onChangeSpy).toHaveBeenCalledWith(
expect(onChangeMock).toHaveBeenCalledWith(
expect.objectContaining({ target: { checked: true } })
)

uncheck()
expect(onChangeSpy).toHaveBeenCalledWith(
expect(onChangeMock).toHaveBeenCalledWith(
expect.objectContaining({ target: { checked: false } })
)
})

it('can receive a new value from a parent component', () => {
const { checkbox, findCheckboxElement } = doMount({ checked: false })

checkbox.setProps({ checked: true })

expect(findCheckboxElement()).toHaveProp('checked', true)
})
})

describe('focusing', () => {
Expand All @@ -136,6 +144,26 @@ describe('Checkbox', () => {
expect(findFakeCheckbox()).not.toHaveClassName('focused')
expect(findFakeCheckbox()).toHaveClassName('unchecked')
})

it('will notify when focus is gained', () => {
const onFocusMock = jest.fn()
const event = { target: { value: 'the value' } }

const { focus } = doMount({ onFocus: onFocusMock })
focus(event)

expect(onFocusMock).toHaveBeenCalledWith(expect.objectContaining(event))
})

it('will notify when focus is lost', () => {
const onBlurMock = jest.fn()
const event = { target: { value: 'the value' } }

const { blur } = doMount({ onBlur: onBlurMock })
blur(event)

expect(onBlurMock).toHaveBeenCalledWith(expect.objectContaining(event))
})
})

//
Expand Down
10 changes: 3 additions & 7 deletions src/components/FormField/FormField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,9 @@ const renderHelper = (helper, helperId, feedback, value) => {
}

class FormField extends React.Component {
constructor(props) {
super(props)

this.state = {
value: props.value,
focus: false,
}
state = {
value: this.props.value,
focus: false,
}

componentWillReceiveProps(nextProps) {
Expand Down

0 comments on commit 6786a75

Please sign in to comment.