diff --git a/src/Selector/MultipleSelector.tsx b/src/Selector/MultipleSelector.tsx index 922392712..476fa427e 100644 --- a/src/Selector/MultipleSelector.tsx +++ b/src/Selector/MultipleSelector.tsx @@ -2,11 +2,7 @@ import React from 'react'; import classNames from 'classnames'; import CSSMotionList from 'rc-animate/lib/CSSMotionList'; import TransBtn from '../TransBtn'; -import { - LabelValueType, - RawValueType, - CustomTagProps, -} from '../interface/generator'; +import { LabelValueType, RawValueType, CustomTagProps } from '../interface/generator'; import { RenderNode } from '../interface'; import { InnerSelectorProps } from '.'; import Input from './Input'; @@ -21,9 +17,7 @@ interface SelectorProps extends InnerSelectorProps { // Tags maxTagCount?: number; maxTagTextLength?: number; - maxTagPlaceholder?: - | React.ReactNode - | ((omittedValues: LabelValueType[]) => React.ReactNode); + maxTagPlaceholder?: React.ReactNode | ((omittedValues: LabelValueType[]) => React.ReactNode); tokenSeparators?: string[]; tagRender?: (props: CustomTagProps) => React.ReactElement; @@ -55,8 +49,7 @@ const SelectSelector: React.FC = ({ maxTagCount, maxTagTextLength, - maxTagPlaceholder = (omittedValues: LabelValueType[]) => - `+ ${omittedValues.length} ...`, + maxTagPlaceholder = (omittedValues: LabelValueType[]) => `+ ${omittedValues.length} ...`, tagRender, onSelect, @@ -74,12 +67,13 @@ const SelectSelector: React.FC = ({ }, []); // ===================== Search ====================== + const inputValue = open ? searchValue : ''; const inputEditable: boolean = mode === 'tags' || (open && showSearch); // We measure width and set to the input immediately useLayoutEffect(() => { setInputWidth(measureRef.current.scrollWidth); - }, [searchValue]); + }, [inputValue]); // ==================== Selection ==================== let displayValues: LabelValueType[] = values; @@ -142,12 +136,7 @@ const SelectSelector: React.FC = ({ }; return typeof tagRender === 'function' ? ( - + {tagRender({ label, value, @@ -164,9 +153,7 @@ const SelectSelector: React.FC = ({ })} style={style} > - - {label} - + {label} {closable && ( = ({ <> {selectionNode} - + = ({ autoFocus={autoFocus} editable={inputEditable} accessibilityIndex={accessibilityIndex} - value={searchValue} + value={inputValue} onKeyDown={onInputKeyDown} onMouseDown={onInputMouseDown} onChange={onInputChange} @@ -209,19 +193,13 @@ const SelectSelector: React.FC = ({ /> {/* Measure Node */} - - {searchValue}  + + {inputValue}  - {!values.length && !searchValue && ( - - {placeholder} - + {!values.length && !inputValue && ( + {placeholder} )} ); diff --git a/src/Selector/SingleSelector.tsx b/src/Selector/SingleSelector.tsx index ad33ae55e..14e587d02 100644 --- a/src/Selector/SingleSelector.tsx +++ b/src/Selector/SingleSelector.tsx @@ -40,7 +40,8 @@ const SingleSelector: React.FC = ({ inputValue = item ? getDisplayValue(item.value) : activeValue || searchValue; } - const hasTextInput = !!inputValue; + // Not show text when closed expect combobox mode + const hasTextInput = mode !== 'combobox' && !open ? false : !!inputValue; return ( <> diff --git a/tests/Multiple.test.tsx b/tests/Multiple.test.tsx index de749349a..988dbfe09 100644 --- a/tests/Multiple.test.tsx +++ b/tests/Multiple.test.tsx @@ -128,10 +128,7 @@ describe('Select.Multiple', () => { expect(handleChange).toHaveBeenCalledWith( [1, 2], - [ - expect.objectContaining({ value: 1 }), - expect.objectContaining({ value: 2, testprop: 2 }), - ], + [expect.objectContaining({ value: 1 }), expect.objectContaining({ value: 2, testprop: 2 })], ); }); @@ -274,4 +271,11 @@ describe('Select.Multiple', () => { jest.useRealTimers(); }); + + it('show placeholder when searchValue is controlled', () => { + const wrapper = mount( + + ); @@ -896,9 +870,7 @@ describe('Select.Basic', () => { it('warns on invalid children', () => { const Foo = value =>
foo{value}
; - const errorSpy = jest - .spyOn(console, 'error') - .mockImplementation(() => null); + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => null); mount( - (option.children as string) - .toUpperCase() - .indexOf(inputValue.toUpperCase()) !== -1 + (option.children as string).toUpperCase().indexOf(inputValue.toUpperCase()) !== -1 } onSelect={handleSelect} showSearch @@ -1132,9 +1100,7 @@ describe('Select.Basic', () => { wrapper.find('input').simulate('change', { target: { value: 'b' } }); expect(wrapper.find('input').props().value).toBe('b'); expect(wrapper.find('List').props().data).toHaveLength(1); - expect(wrapper.find('div.rc-select-item-option-content').text()).toBe( - 'Burns Bay Road', - ); + expect(wrapper.find('div.rc-select-item-option-content').text()).toBe('Burns Bay Road'); wrapper.find('input').simulate('change', { target: { value: 'c' } }); expect(wrapper.find('input').props().value).toBe('c'); @@ -1218,12 +1184,7 @@ describe('Select.Basic', () => { } const wrapper = mount( - , ); toggleOpen(wrapper); expect(wrapper.find('.rc-select-item')).toHaveLength(options.length); @@ -1237,10 +1198,7 @@ describe('Select.Basic', () => { , ); - expect( - wrapper.find('Trigger').props().builtinPlacements.bottomLeft.overflow - .adjustX, - ).toBe(1); + expect(wrapper.find('Trigger').props().builtinPlacements.bottomLeft.overflow.adjustX).toBe(1); }); it('dropdown should not auto-adjust horizontally when dropdownMatchSelectWidth is true', () => { @@ -1250,10 +1208,7 @@ describe('Select.Basic', () => { , ); - expect( - wrapper.find('Trigger').props().builtinPlacements.bottomLeft.overflow - .adjustX, - ).toBe(0); + expect(wrapper.find('Trigger').props().builtinPlacements.bottomLeft.overflow.adjustX).toBe(0); }); it('if loading, arrow should show loading icon', () => { @@ -1298,9 +1253,7 @@ describe('Select.Basic', () => { it('should warning using `onSearch` if not set `showSearch`', () => { resetWarned(); - const errorSpy = jest - .spyOn(console, 'error') - .mockImplementation(() => null); + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => null); mount( - option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= - 0 + option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 } showSearch > @@ -1372,9 +1322,7 @@ describe('Select.Basic', () => { wrapper.find('input').simulate('change', { target: { value: 'l' } }); expect(wrapper.find('List').props().data).toHaveLength(1); - expect(wrapper.find('div.rc-select-item-option-content').text()).toBe( - 'Light', - ); + expect(wrapper.find('div.rc-select-item-option-content').text()).toBe('Light'); expect(errorSpy).toHaveBeenCalledWith( 'Warning: Return type is option instead of Option instance. Please read value directly instead of reading from `props`.', @@ -1384,9 +1332,7 @@ describe('Select.Basic', () => { it('Select & Deselect', () => { resetWarned(); - const errorSpy = jest - .spyOn(console, 'error') - .mockImplementation(() => {}); + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const readPropsFunc = (_, opt) => { expect(opt.props).toBeTruthy(); @@ -1433,9 +1379,7 @@ describe('Select.Basic', () => { it('onChange', () => { resetWarned(); - const errorSpy = jest - .spyOn(console, 'error') - .mockImplementation(() => {}); + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const readPropsFunc = (_, opt) => { expect(opt.props).toBeTruthy(); @@ -1482,9 +1426,7 @@ describe('Select.Basic', () => { }); it('not open when `notFoundCount` is empty & no data', () => { - const wrapper = mount( - ); expect(wrapper.find('SelectTrigger').props().visible).toBeFalsy(); expect(wrapper.find('Input').props().editable).toBeTruthy(); }); @@ -1527,9 +1469,7 @@ describe('Select.Basic', () => { [undefined].forEach(value => { it(`to ${value}`, () => { const wrapper = mount(, ); - [ - [1, '1'], - [null, 'No'], - [0, '0'], - ['', 'Empty'], - ].forEach(([value, showValue], index) => { + [[1, '1'], [null, 'No'], [0, '0'], ['', 'Empty']].forEach(([value, showValue], index) => { toggleOpen(wrapper); selectItem(wrapper, index); expect(onChange).toHaveBeenCalledWith(value, expect.anything()); - expect(wrapper.find('.rc-select-selection-item').text()).toEqual( - showValue, - ); + expect(wrapper.find('.rc-select-selection-item').text()).toEqual(showValue); }); }); + + it('show placeholder when searchValue is controlled', () => { + const wrapper = mount(