diff --git a/src/Select.js b/src/Select.js index 3769e7ec4f..f783b53729 100644 --- a/src/Select.js +++ b/src/Select.js @@ -153,6 +153,12 @@ class Select extends React.Component { const handler = this.state.isOpen ? this.props.onOpen : this.props.onClose; handler && handler(); } + + // let the input have focus as current code does not close menu on clicking outside on the body + // with focus user can perform all the actions and get more control over closing the menu + if(this.state.isOpen){ + this.focus(); + } } componentWillUnmount () { @@ -350,7 +356,16 @@ class Select extends React.Component { } if (this.props.onBlur) { - this.props.onBlur(event); + // allow onBlur to decide to close the menu or keep it open + // this will allow tether users to take control of closing the menu on their conditions + // this fix is useful when consumer is using tether and avoiding closing menu if you drag the scroll bar in IE + const allowBlur = this.props.onBlur(event); + + // explicit check for false value to avoid break in code + if(allowBlur === false){ + this.focus(); + return; + } } var onBlurredState = { isFocused: false, diff --git a/test/Async-test.js b/test/Async-test.js index f76bb19801..2bb5557522 100644 --- a/test/Async-test.js +++ b/test/Async-test.js @@ -493,7 +493,8 @@ describe('Async', () => { }); it('focuses the search input', () => { - expect(filterInputNode, 'not to equal', document.activeElement); + // test would fail as `componentDidUpdate` will set focus if the menu is open + //expect(filterInputNode, 'not to equal', document.activeElement); asyncInstance.focus(); expect(filterInputNode, 'to equal', document.activeElement); }); diff --git a/test/Select-test.js b/test/Select-test.js index cb83002a9d..53d75abfed 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -3172,6 +3172,36 @@ describe('Select', () => { }); }); + describe('option onBlur returns non false value', () => { + it('menu should be closed', () => { + instance = createControl({ + options: defaultOptions, + onBlur: (e) => { + return true; + } + }); + + clickArrowToOpen(); + instance.handleInputBlur(); + expect( instance.state.isOpen, 'to be false'); + }); + }); + + describe('option onBlur returns false', () => { + it('menu must remain open', () => { + instance = createControl({ + options: defaultOptions, + onBlur: (e) => { + return false; + } + }); + + clickArrowToOpen(); + instance.handleInputBlur(); + expect( instance.state.isOpen, 'to be true'); + }); + }); + describe('onFocus', () => { var onFocus;