Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions src/Selector/SingleSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,23 @@ const SingleSelector: React.FC<SelectorProps> = 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;

Expand All @@ -67,7 +74,10 @@ const SingleSelector: React.FC<SelectorProps> = props => {
value={inputValue}
onKeyDown={onInputKeyDown}
onMouseDown={onInputMouseDown}
onChange={onInputChange}
onChange={e => {
setInputChanged(true);
onInputChange(e as any);
}}
onPaste={onInputPaste}
onCompositionStart={onInputCompositionStart}
onCompositionEnd={onInputCompositionEnd}
Expand Down
87 changes: 68 additions & 19 deletions tests/Combobox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,25 +213,74 @@ describe('Select.Combobox', () => {
});
});

it('backfill', () => {
const handleChange = jest.fn();
const handleSelect = jest.fn();
const wrapper = mount(
<Select mode="combobox" backfill open onChange={handleChange} onSelect={handleSelect}>
<Option value="One">One</Option>
<Option value="Two">Two</Option>
</Select>,
);
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(
<Select mode="combobox" backfill open onChange={handleChange} onSelect={handleSelect}>
<Option value="One">One</Option>
<Option value="Two">Two</Option>
</Select>,
);
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 (
<Select
backfill
mode="combobox"
onChange={onChange}
onSearch={onSearch}
options={options}
/>
);
};

const wrapper = mount(<Test />);

function input() {
return wrapper.find('input');
}

input().simulate('change', { target: { value: 'light' } });
expectOpen(wrapper);
expect(onChange).toHaveBeenCalledWith('light', expect.anything());
onChange.mockReset();

input().simulate('keyDown', { which: KeyCode.DOWN });
expect(input().props().value).toEqual('light@gmail.com');
expect(onChange).not.toHaveBeenCalled();

input().simulate('keyDown', { which: KeyCode.ENTER });
expect(onChange).toHaveBeenCalledWith('light@gmail.com', expect.anything());
});
});

it("should hide clear icon when value is ''", () => {
Expand Down