diff --git a/src/PickerInput/Selector/Input.tsx b/src/PickerInput/Selector/Input.tsx index 9bf9d7edb..34402a54b 100644 --- a/src/PickerInput/Selector/Input.tsx +++ b/src/PickerInput/Selector/Input.tsx @@ -37,6 +37,7 @@ export interface InputProps extends Omit void; onSubmit: VoidFunction; + onClear: VoidFunction; /** Meaning current is from the hover cell getting the placeholder text */ helped?: boolean; /** @@ -62,6 +63,7 @@ const Input = React.forwardRef((props, ref) => { helped, onHelp, onSubmit, + onClear, onKeyDown, preserveInvalidOnBlur = false, invalid, @@ -201,16 +203,28 @@ const Input = React.forwardRef((props, ref) => { // Check if blur need reset input value useLockEffect(active, () => { if (!active && !preserveInvalidOnBlur) { - setInputValue(value); + if (clearIcon && !inputValue) { + onClear(); + } else { + setInputValue(value); + } } }); // ======================= Keyboard ======================= const onSharedKeyDown: React.KeyboardEventHandler = (event) => { - if (event.key === 'Enter' && validateFormat(inputValue)) { - onSubmit(); + const isEnterKeyTriggered = event.key === 'Enter'; + if (isEnterKeyTriggered) { + if (validateFormat(inputValue)) { + onSubmit(); + } } + if (isEnterKeyTriggered || event.key === 'Escape') { + if (clearIcon && !inputValue) { + onClear(); + } + } onKeyDown?.(event); }; diff --git a/src/PickerInput/Selector/SingleSelector/index.tsx b/src/PickerInput/Selector/SingleSelector/index.tsx index 0dbc82e8a..80c493eab 100644 --- a/src/PickerInput/Selector/SingleSelector/index.tsx +++ b/src/PickerInput/Selector/SingleSelector/index.tsx @@ -160,6 +160,7 @@ function SingleSelector( const showClear = !!(clearIcon && value.length && !disabled); // ======================= Multiple ======================= + const clearIconNode = showClear && ; const selectorNode = multiple ? ( <> ( autoFocus={autoFocus} /> - {showClear && } + {clearIconNode} ) : ( ( {...getInputProps()} autoFocus={autoFocus} suffixIcon={suffixIcon} - clearIcon={showClear && } + clearIcon={clearIconNode} showActiveCls={false} /> ); diff --git a/src/PickerInput/Selector/hooks/useInputProps.ts b/src/PickerInput/Selector/hooks/useInputProps.ts index fa7a1c907..c145747d3 100644 --- a/src/PickerInput/Selector/hooks/useInputProps.ts +++ b/src/PickerInput/Selector/hooks/useInputProps.ts @@ -17,6 +17,7 @@ export default function useInputProps( | 'required' | 'aria-required' | 'onSubmit' + | 'onClear' | 'onFocus' | 'onBlur' | 'onInputChange' @@ -53,6 +54,7 @@ export default function useInputProps( required, 'aria-required': ariaRequired, onSubmit, + onClear, onFocus, onBlur, onInputChange, @@ -180,6 +182,7 @@ export default function useInputProps( }, onSubmit, + onClear, // Get validate text value onChange: (text: string) => { diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index d6751c775..71a5d2c96 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -1251,6 +1251,59 @@ describe('Picker.Basic', () => { }); }); + describe('empty input should submit when set allowClear true', () => { + ['ENTER', 'TAB', 'ESC'].forEach(item => { + it(`submit empty through the '${item}' key`, () => { + const onChange = jest.fn(); + const { container } = render( + , + ); + const inputEle = container.querySelector('input'); + + fireEvent.change(inputEle, { + target: { value: '' }, + }); + keyDown(KeyCode.ENTER); + expect(onChange).toHaveBeenCalledWith(null, ''); + }); + }) + + it('submit empty when input blur', async () => { + const onChange = jest.fn(); + const onFocus = jest.fn(); + const onBlur = jest.fn(); + const { container } = render( + , + ); + const inputEle = container.querySelector('input'); + fireEvent.focus(inputEle); + fireEvent.change(inputEle, { target: { value: '' } }); + fireEvent.blur(inputEle); + expect(onBlur).toHaveBeenCalled(); + /** + * wait useLayoutEffect + * code: PickerInput/Selector/Input.tsx + * useLockEffect(active, () => { + * // ... + * }) + * + */ + await waitFakeTimer(); + expect(onChange).toHaveBeenCalledWith(null, ''); + }); + + }) + it('pickerValue change', () => { const onPickerValueChange = jest.fn(); const { container } = render();