diff --git a/src/Select.jsx b/src/Select.jsx index 1c85dd63d..bbc5275fb 100644 --- a/src/Select.jsx +++ b/src/Select.jsx @@ -137,6 +137,7 @@ const Select = createClass({ }, componentWillUnmount() { + this.clearFocusTime(); this.clearBlurTime(); this.clearAdjustTimer(); if (this.dropdownContainer) { @@ -170,6 +171,12 @@ const Select = createClass({ }, onDropdownVisibleChange(open) { + if (open && !this._focused) { + this.clearBlurTime(); + this.timeoutFocus(); + this._focused = true; + this.updateFocusClassName(); + } this.setOpenState(open); }, @@ -301,13 +308,16 @@ const Select = createClass({ }, onOuterFocus(e) { + this.clearBlurTime(); if (!isMultipleOrTagsOrCombobox(this.props) && e.target === this.getInputDOMNode()) { return; } - this.clearBlurTime(); + if (this._focused) { + return; + } this._focused = true; this.updateFocusClassName(); - this.props.onFocus(); + this.timeoutFocus(); }, onPopupFocus() { @@ -545,6 +555,22 @@ const Select = createClass({ } } }, + + timeoutFocus() { + if (this.focusTimer) { + this.clearFocusTime(); + } + this.focusTimer = setTimeout(() => { + this.props.onFocus(); + }, 10); + }, + + clearFocusTime() { + if (this.focusTimer) { + clearTimeout(this.focusTimer); + this.focusTimer = null; + } + }, clearBlurTime() { if (this.blurTimer) { clearTimeout(this.blurTimer); @@ -574,11 +600,13 @@ const Select = createClass({ if (input && (open || isMultipleOrTagsOrCombobox(this.props))) { if (activeElement !== input) { input.focus(); + this._focused = true; } } else { const selection = this.refs.selection; if (activeElement !== selection) { selection.focus(); + this._focused = true; } } } diff --git a/tests/Select.spec.js b/tests/Select.spec.js index 9a0cb757d..e1fc92076 100644 --- a/tests/Select.spec.js +++ b/tests/Select.spec.js @@ -256,7 +256,39 @@ describe('Select', () => { ); + jest.useFakeTimers(); wrapper.find('.rc-select').simulate('focus'); + jest.runAllTimers(); + }); + + it('set _focused to true', () => { + expect(wrapper.instance()._focused).toBe(true); + }); + + it('fires focus event', () => { + expect(handleFocus).toBeCalled(); + expect(handleFocus.mock.calls.length).toBe(1); + }); + + it('set className', () => { + expect(wrapper.find('.rc-select').node.className).toContain('-focus'); + }); + }); + + describe('click input will trigger focus', () => { + let handleFocus; + let wrapper; + beforeEach(() => { + handleFocus = jest.fn(); + wrapper = mount( + + ); + jest.useFakeTimers(); + wrapper.find('.rc-select input').simulate('click'); + jest.runAllTimers(); }); it('set _focused to true', () => { @@ -265,6 +297,7 @@ describe('Select', () => { it('fires focus event', () => { expect(handleFocus).toBeCalled(); + expect(handleFocus.mock.calls.length).toBe(1); }); it('set className', () => {