fix: cascader value overwritten when filtering (#26554) (#26569)

* fix: cascader value overwritten when filtering  (#26554)

* test: add onChange test cases (#26554)

* test: add onChange test cases

Co-authored-by: lich(李春翯) <lich@21kunpeng.com>
This commit is contained in:
lich-yoo 2020-09-04 10:59:10 +08:00 committed by GitHub
parent 7e209f0a51
commit f0f22bb726
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 2 deletions

View File

@ -524,4 +524,22 @@ describe('Cascader', () => {
wrapper.find('input').simulate('change', { target: { value: 'jin' } });
expect(wrapper.state('popupVisible')).toBe(true);
});
it('onChange works correctly when the label of fieldNames is the same as value', () => {
const onChange = jest.fn();
const sameNames = { label: 'label', value: 'label', children: 'children' };
const wrapper = mount(
<Cascader options={options} onChange={onChange} showSearch fieldNames={sameNames} />,
);
wrapper.find('input').simulate('click');
wrapper.find('input').simulate('change', { target: { value: 'est' } });
const popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
popupWrapper
.find('.ant-cascader-menu')
.at(0)
.find('.ant-cascader-menu-item')
.at(0)
.simulate('click');
expect(onChange).toHaveBeenCalledWith(['Zhejiang', 'Hangzhou', 'West Lake'], expect.anything());
});
});

View File

@ -128,6 +128,9 @@ interface CascaderLocale {
// We limit the filtered item count by default
const defaultLimit = 50;
// keep value when filtering
const keepFilteredValueField = '__KEEP_FILTERED_OPTION_VALUE';
function highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
return str.split(keyword).map((node: string, index: number) =>
index === 0
@ -308,7 +311,10 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
handleChange = (value: any, selectedOptions: CascaderOptionType[]) => {
this.setState({ inputValue: '' });
if (selectedOptions[0].__IS_FILTERED_OPTION) {
const unwrappedValue = value[0];
const unwrappedValue =
selectedOptions[0][keepFilteredValueField] === undefined
? value[0]
: selectedOptions[0][keepFilteredValueField];
const unwrappedSelectedOptions = selectedOptions[0].path;
this.setValue(unwrappedValue, unwrappedSelectedOptions);
return;
@ -413,11 +419,14 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
filtered = filtered.sort((a, b) => sort(a, b, inputValue, names));
if (filtered.length > 0) {
// Fix issue: https://github.com/ant-design/ant-design/issues/26554
const field = names.value === names.label ? keepFilteredValueField : names.value;
return filtered.map((path: CascaderOptionType[]) => {
return {
__IS_FILTERED_OPTION: true,
path,
[names.value]: path.map((o: CascaderOptionType) => o[names.value]),
[field]: path.map((o: CascaderOptionType) => o[names.value]),
[names.label]: render(inputValue, path, prefixCls, names),
disabled: path.some((o: CascaderOptionType) => !!o.disabled),
isEmptyNode: true,