Skip to content

Commit

Permalink
fix(Dropdown): abort handleBlur on click inside (#514)
Browse files Browse the repository at this point in the history
* docs(Dropdown): add uncontrolled example

* test(Dropdown): test handleBlur

* fix(Dropdown): abort handleBlur on click inside
  • Loading branch information
levithomason authored Sep 20, 2016
1 parent 688b6db commit 6c4034b
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 13 deletions.
18 changes: 18 additions & 0 deletions docs/app/Examples/modules/Dropdown/Types/Uncontrolled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { Dropdown } from 'stardust'

const options = [
{ text: 'One', value: 1 },
{ text: 'Two', value: 2 },
{ text: 'Three', value: 3 },
]

const DropdownUncontrolledExample = () => (
<Dropdown
selection
options={options}
placeholder='Choose an option'
/>
)

export default DropdownUncontrolledExample
13 changes: 13 additions & 0 deletions docs/app/Examples/modules/Dropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ const DropdownExamples = () => (
<ComponentExample
examplePath='modules/Dropdown/Types/ImageTrigger'
/>
<ComponentExample
title='Uncontrolled'
description='A dropdown works as an uncontrolled component'
examplePath='modules/Dropdown/Types/Uncontrolled'
>
<Message>
See React form docs for an explanation of
<a href='https://facebook.github.io/react/docs/forms.html' target='_blank'>
&nbsp;controlled and uncontrolled&nbsp;
</a>
component patterns.
</Message>
</ComponentExample>
<ComponentExample
title='Selection'
description='A dropdown can be used to select between choices in a form'
Expand Down
2 changes: 2 additions & 0 deletions src/modules/Dropdown/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ export default class Dropdown extends Component {
handleBlur = (e) => {
debug('handleBlur()')
const { multiple, onBlur, selectOnBlur } = this.props
// do not "blur" when the mouse is down inside of the Dropdown
if (this.isMouseDown) return
if (onBlur) onBlur(e)
if (selectOnBlur && !multiple) this.selectHighlightedItem(e)
this.setState({ focus: false })
Expand Down
85 changes: 72 additions & 13 deletions test/specs/modules/Dropdown/Dropdown-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,82 @@ describe('Dropdown Component', () => {
.simulate('click')

dropdownMenuIsOpen()
wrapper.simulate('blur')
dropdownMenuIsClosed()
})

wrapper
.simulate('blur')
it('opens on focus', () => {
wrapperMount(<Dropdown options={options} />)

dropdownMenuIsClosed()
wrapper.simulate('focus')
dropdownMenuIsOpen()
})

// TODO: see Dropdown.handleFocus() todo
// it('opens on focus', () => {
// wrapperMount(<Dropdown {...requiredProps} />)
//
// dropdownMenuIsClosed()
//
// wrapper
// .simulate('focus')
//
// dropdownMenuIsOpen()
// })
describe('handleBlur', () => {
it('passes the event to the onBlur prop', () => {
const spy = sandbox.spy()
const event = { foo: 'bar' }

wrapperShallow(<Dropdown onBlur={spy} />)
.simulate('blur', event)

spy.should.have.been.calledOnce()
spy.should.have.been.calledWithMatch(event)
})

it('calls selectHighlightedItem', () => {
wrapperShallow(<Dropdown selectOnBlur />)

const instance = wrapper.instance()
sandbox.spy(instance, 'selectHighlightedItem')

wrapper.simulate('blur')

instance.selectHighlightedItem
.should.have.been.calledOnce()
})

it('sets focus state to false', () => {
wrapperShallow(<Dropdown selectOnBlur />)
.simulate('blur')
.should.have.state('focus', false)
})

it('does not call onBlur when the mouse is down', () => {
const spy = sandbox.spy()

wrapperShallow(<Dropdown onBlur={spy} selectOnBlur />)
.simulate('mousedown')
.simulate('blur')

spy.should.not.have.been.called()
})

it('does not call selectHighlightedItem when the mouse is down', () => {
const spy = sandbox.spy()

wrapperShallow(<Dropdown onBlur={spy} selectOnBlur />)

const instance = wrapper.instance()
sandbox.spy(instance, 'selectHighlightedItem')

wrapper
.simulate('mousedown')
.simulate('blur')

instance.selectHighlightedItem
.should.not.have.been.called()
})

it('does not set focus state when the mouse is down', () => {
wrapperShallow(<Dropdown />)
.setState({ focus: 'foo' })
.simulate('mousedown')
.simulate('blur')
.should.have.state('focus', 'foo')
})
})

describe('isMouseDown', () => {
it('tracks when the mouse is down', () => {
Expand Down Expand Up @@ -1537,6 +1595,7 @@ describe('Dropdown Component', () => {
spy.firstCall.args[0].should.equal('boo')
})
})

describe('header', () => {
it('renders a header when present', () => {
const text = faker.hacker.phrase()
Expand Down

0 comments on commit 6c4034b

Please sign in to comment.