diff --git a/src/hooks/useCombobox/__tests__/getInputProps.test.js b/src/hooks/useCombobox/__tests__/getInputProps.test.js index 3358e45b..98c73caa 100644 --- a/src/hooks/useCombobox/__tests__/getInputProps.test.js +++ b/src/hooks/useCombobox/__tests__/getInputProps.test.js @@ -370,6 +370,41 @@ describe('getInputProps', () => { expect(result.current.inputValue).toBe('lalaland') }) + test('does not update inputValue while an IME composition is in progress', () => { + const userOnChange = jest.fn() + const onInputValueChange = jest.fn() + const {result} = renderUseCombobox({onInputValueChange}) + + act(() => { + const {ref: inputRef, onChange} = result.current.getInputProps({ + onChange: userOnChange, + }) + + inputRef({focus: noop}) + onChange({ + target: {value: 'に'}, + nativeEvent: {isComposing: true}, + }) + }) + + expect(userOnChange).toHaveBeenCalledTimes(1) + expect(onInputValueChange).not.toHaveBeenCalled() + expect(result.current.inputValue).toBe('') + + act(() => { + result.current.getInputProps().onChange({ + target: {value: '日本'}, + nativeEvent: {isComposing: false}, + }) + }) + + expect(onInputValueChange).toHaveBeenCalledTimes(1) + expect(onInputValueChange).toHaveBeenCalledWith( + expect.objectContaining({inputValue: '日本'}), + ) + expect(result.current.inputValue).toBe('日本') + }) + test("event handler onChange is called without downshift handler if 'preventDownshiftDefault' is passed in user event", () => { const userOnChange = jest.fn(event => { event.preventDownshiftDefault = true diff --git a/src/hooks/useCombobox/index.ts b/src/hooks/useCombobox/index.ts index 762eed3e..11b4fc20 100644 --- a/src/hooks/useCombobox/index.ts +++ b/src/hooks/useCombobox/index.ts @@ -454,9 +454,19 @@ function useCombobox( } const inputHandleChange = ( event: - | React.ChangeEvent - | {nativeEvent: {text: string}}, + React.ChangeEvent | {nativeEvent: {text: string}}, ) => { + if ( + !isReactNative && + !isReactNativeWeb && + ( + (event as React.ChangeEvent) + .nativeEvent as InputEvent + )?.isComposing + ) { + return + } + dispatch({ type: stateChangeTypes.InputChange, inputValue: