diff --git a/src/Selector/SingleSelector.tsx b/src/Selector/SingleSelector.tsx index 729d2887a..1fa72e477 100644 --- a/src/Selector/SingleSelector.tsx +++ b/src/Selector/SingleSelector.tsx @@ -37,16 +37,23 @@ const SingleSelector: React.FC = props => { onInputCompositionEnd, } = props; + const [inputChanged, setInputChanged] = React.useState(false); + const combobox = mode === 'combobox'; const inputEditable = combobox || (showSearch && open); const item = values[0]; - const getDisplayValue = (value: React.ReactText): string => (value === null ? '' : String(value)); - let inputValue: string = searchValue; - if (combobox) { - inputValue = item ? getDisplayValue(item.value) : activeValue || searchValue; + let inputValue: string = searchValue || ''; + if (combobox && activeValue && !inputChanged) { + inputValue = activeValue; } + React.useEffect(() => { + if (combobox) { + setInputChanged(false); + } + }, [combobox, activeValue]); + // Not show text when closed expect combobox mode const hasTextInput = mode !== 'combobox' && !open ? false : !!inputValue; @@ -67,7 +74,10 @@ const SingleSelector: React.FC = props => { value={inputValue} onKeyDown={onInputKeyDown} onMouseDown={onInputMouseDown} - onChange={onInputChange} + onChange={e => { + setInputChanged(true); + onInputChange(e as any); + }} onPaste={onInputPaste} onCompositionStart={onInputCompositionStart} onCompositionEnd={onInputCompositionEnd} diff --git a/tests/Combobox.test.tsx b/tests/Combobox.test.tsx index dd7982647..ad4fba4e7 100644 --- a/tests/Combobox.test.tsx +++ b/tests/Combobox.test.tsx @@ -213,25 +213,74 @@ describe('Select.Combobox', () => { }); }); - it('backfill', () => { - const handleChange = jest.fn(); - const handleSelect = jest.fn(); - const wrapper = mount( - , - ); - const input = wrapper.find('input'); - input.simulate('keyDown', { which: KeyCode.DOWN }); - expect(wrapper.find('input').props().value).toEqual('One'); - expect(handleChange).not.toHaveBeenCalled(); - expect(handleSelect).not.toHaveBeenCalled(); - - input.simulate('keyDown', { which: KeyCode.ENTER }); - expect(wrapper.find('input').props().value).toEqual('One'); - expect(handleChange).toHaveBeenCalledWith('One', expect.objectContaining({ value: 'One' })); - expect(handleSelect).toHaveBeenCalledWith('One', expect.objectContaining({ value: 'One' })); + describe('backfill', () => { + it('basic', () => { + const handleChange = jest.fn(); + const handleSelect = jest.fn(); + const wrapper = mount( + , + ); + const input = wrapper.find('input'); + input.simulate('keyDown', { which: KeyCode.DOWN }); + expect(wrapper.find('input').props().value).toEqual('One'); + expect(handleChange).not.toHaveBeenCalled(); + expect(handleSelect).not.toHaveBeenCalled(); + + input.simulate('keyDown', { which: KeyCode.ENTER }); + expect(wrapper.find('input').props().value).toEqual('One'); + expect(handleChange).toHaveBeenCalledWith('One', expect.objectContaining({ value: 'One' })); + expect(handleSelect).toHaveBeenCalledWith('One', expect.objectContaining({ value: 'One' })); + }); + + // https://github.com/ant-design/ant-design/issues/25345 + it('dynamic options', () => { + const onChange = jest.fn(); + + const Test = () => { + const [options, setOptions] = React.useState([]); + const onSearch = (value: string) => { + let res = []; + + if (!value || value.indexOf('@') >= 0) { + res = []; + } else { + const email = `${value}@gmail.com`; + res = [{ value: email, label: email }]; + } + setOptions(res); + }; + return ( +