diff --git a/src/modules/Dropdown/Dropdown.js b/src/modules/Dropdown/Dropdown.js index 6645780d87..cc64823c14 100644 --- a/src/modules/Dropdown/Dropdown.js +++ b/src/modules/Dropdown/Dropdown.js @@ -579,7 +579,7 @@ export default class Dropdown extends Component { makeSelectedItemActive = (e) => { const { open } = this.state - const { multiple, onAddItem } = this.props + const { multiple } = this.props const item = this.getSelectedItem() const value = _.get(item, 'value') @@ -588,9 +588,6 @@ export default class Dropdown extends Component { // prevent selecting duplicate items when the dropdown is closed if (_.isNil(value) || !open) return - // notify the onAddItem prop if this is a new value - if (onAddItem && item['data-additional']) onAddItem(e, { ...this.props, value }) - // state value may be undefined const newValue = multiple ? _.union(this.state.value, [value]) : value @@ -598,11 +595,15 @@ export default class Dropdown extends Component { this.setValue(newValue) this.setSelectedIndex(newValue) this.handleChange(e, newValue) + + // Heads up! This event handler should be called after `onChange` + // Notify the onAddItem prop if this is a new value + if (item['data-additional']) _.invoke(this.props, 'onAddItem', e, { ...this.props, value }) } selectItemOnEnter = (e) => { debug('selectItemOnEnter()', keyboardKey.getName(e)) - const { onAddItem, search } = this.props + const { search } = this.props if (keyboardKey.getCode(e) !== keyboardKey.Enter) return e.preventDefault() @@ -611,7 +612,7 @@ export default class Dropdown extends Component { if (search && optionSize === 0) return const item = this.getSelectedItem() - const isAdditionItem = onAddItem && item['data-additional'] + const isAdditionItem = item['data-additional'] this.makeSelectedItemActive(e) this.closeOnChange(e) @@ -700,7 +701,7 @@ export default class Dropdown extends Component { handleItemClick = (e, item) => { debug('handleItemClick()', item) - const { multiple, onAddItem, search } = this.props + const { multiple, search } = this.props const { value } = item // prevent toggle() in handleClick() @@ -709,10 +710,7 @@ export default class Dropdown extends Component { if (multiple || item.disabled) e.nativeEvent.stopImmediatePropagation() if (item.disabled) return - // notify the onAddItem prop if this is a new value - const isAdditionItem = onAddItem && item['data-additional'] - if (isAdditionItem) onAddItem(e, { ...this.props, value }) - + const isAdditionItem = item['data-additional'] const newValue = multiple ? _.union(this.state.value, [value]) : value // notify the onChange prop that the user is trying to change value @@ -725,6 +723,10 @@ export default class Dropdown extends Component { this.handleChange(e, newValue) this.closeOnChange(e) + // Heads up! This event handler should be called after `onChange` + // Notify the onAddItem prop if this is a new value + if (isAdditionItem) _.invoke(this.props, 'onAddItem', e, { ...this.props, value }) + if (multiple && search && this.searchRef) this.searchRef.focus() } diff --git a/test/specs/modules/Dropdown/Dropdown-test.js b/test/specs/modules/Dropdown/Dropdown-test.js index a44aa4d04f..83cc5d53f9 100644 --- a/test/specs/modules/Dropdown/Dropdown-test.js +++ b/test/specs/modules/Dropdown/Dropdown-test.js @@ -2291,9 +2291,17 @@ describe('Dropdown', () => { }) it('calls onAddItem prop when clicking new value', () => { - const spy = sandbox.spy() + const onAddItem = sandbox.spy() + const onChange = sandbox.spy() const search = wrapperMount( - , + , ) .find('input.search') @@ -2304,22 +2312,34 @@ describe('Dropdown', () => { .first() .simulate('click') - spy.should.have.been.calledOnce() - spy.should.have.been.calledWithMatch({}, { value: 'boo' }) + onChange.should.have.been.calledOnce() + onAddItem.should.have.been.calledOnce() + onAddItem.should.have.been.calledWithMatch({}, { value: 'boo' }) + onAddItem.should.have.been.calledImmediatelyAfter(onChange) }) it('calls onAddItem prop when pressing enter on new value', () => { - const spy = sandbox.spy() + const onAddItem = sandbox.spy() + const onChange = sandbox.spy() const search = wrapperMount( - , + , ) .find('input.search') search.simulate('change', { target: { value: 'boo' } }) domEvent.keyDown(document, { key: 'Enter' }) - spy.should.have.been.calledOnce() - spy.should.have.been.calledWithMatch({}, { value: 'boo' }) + onChange.should.have.been.calledOnce() + onAddItem.should.have.been.calledOnce() + onAddItem.should.have.been.calledWithMatch({}, { value: 'boo' }) + onAddItem.should.have.been.calledImmediatelyAfter(onChange) }) it('clears value of the searchQuery when selection is only option', () => {