Skip to content

Commit

Permalink
Ignore blur on menu enter/leave instead of the individual items react…
Browse files Browse the repository at this point in the history
…js#211 reactjs#222

IE11 (and probably older versions) trigger a click event when you grab the
scrollbar thumb. Since the scrollbar isn't part of any individual item within
the menu, we promptly closed it, thinking the click happened outside
the dropdown. This commit changes the logic to instead capture focus while the
user is hovering over the menu, keeping the input focused until the user either
clicks outside or selects an item.
  • Loading branch information
CMTegner committed May 14, 2017
1 parent a4688d9 commit 53f229a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
15 changes: 10 additions & 5 deletions lib/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,12 @@ let Autocomplete = React.createClass({

selectItemFromMouse(item) {
const value = this.props.getItemValue(item)
this.setIgnoreBlur(false)
this.setState({
isOpen: false,
highlightedIndex: null
}, () => {
this.props.onSelect(value, item)
this.refs.input.focus()
})
},

Expand All @@ -390,7 +390,6 @@ let Autocomplete = React.createClass({
{ cursor: 'default' }
)
return React.cloneElement(element, {
onMouseDown: () => this.setIgnoreBlur(true), // Ignore blur to prevent menu from de-rendering before we can process click
onMouseEnter: () => this.highlightItemFromMouse(index),
onClick: () => this.selectItemFromMouse(item),
ref: e => this.refs[`item-${index}`] = e,
Expand All @@ -402,12 +401,19 @@ let Autocomplete = React.createClass({
minWidth: this.state.menuWidth,
}
const menu = this.props.renderMenu(items, this.props.value, style)
return React.cloneElement(menu, { ref: e => this.refs.menu = e })
return React.cloneElement(menu, {
ref: e => this.refs.menu = e,
// Ignore blur to prevent menu from de-rendering before we can process click
onMouseEnter: () => this.setIgnoreBlur(true),
onMouseLeave: () => this.setIgnoreBlur(false),
})
},

handleInputBlur(event) {
if (this._ignoreBlur)
if (this._ignoreBlur) {
this.refs.input.focus()
return
}
this.setState({
isOpen: false,
highlightedIndex: null
Expand All @@ -420,7 +426,6 @@ let Autocomplete = React.createClass({

handleInputFocus(event) {
if (this._ignoreBlur) {
this.setIgnoreBlur(false)
return
}
this.setState({ isOpen: true })
Expand Down
2 changes: 1 addition & 1 deletion lib/__tests__/Autocomplete-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe('Autocomplete acceptance tests', () => {
onSelect: onSelectSpy,
open: true,
}))
tree.find('div > div > div').at(0).simulate('mouseDown')
tree.find('div > div').at(0).simulate('mouseEnter')
tree.find('input').at(0).simulate('blur')
tree.find('div > div > div').at(0).simulate('click')
expect(onBlurSpy.mock.calls.length).toBe(0)
Expand Down

0 comments on commit 53f229a

Please sign in to comment.