Skip to content

Navigation Menu

Sign in
Sign up

fix(core): guard TextInput onEnter against IME conversion commits #6083

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ManoharPaturi wants to merge 1 commit into facebook:main
base: main
Choose a base branch
Loading
from ManoharPaturi:fix/textinput-ime-enter
Open
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
6 changes: 6 additions & 0 deletions .changeset/textinput-ime-enter.md
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@astryxdesign/core': patch
---

[fix] TextInput's `onEnter` no longer fires for the Enter that commits an IME conversion (Japanese/Chinese/Korean input); `onKeyDown` still receives the raw event. (#6082)
@ManoharPaturi
3 changes: 2 additions & 1 deletion packages/core/src/TextInput/TextInput.doc.mjs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export const docs = {
{
name: 'onEnter',
type: '() => void',
description: 'Callback fired when the user presses the Enter key.',
description:
'Callback fired when the user presses the Enter key. IME-safe: Enter used to commit a Japanese/Chinese/Korean conversion does not fire it.',
},
{
name: 'onKeyDown',
Expand Down
45 changes: 45 additions & 0 deletions packages/core/src/TextInput/TextInput.test.tsx
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,51 @@ describe('TextInput', () => {
expect(handleEnter).toHaveBeenCalledTimes(1);
});

it('does not call onEnter when Enter commits an IME conversion', () => {
// The browser fires this composing keydown for the Enter that commits an
// IME candidate (isComposing: true, or the legacy keyCode 229) before
// compositionend writes the conversion. It must NOT trigger onEnter —
// submit/save actions would fire before the user intends to submit.
// See utils/ime.ts and #6082.
const handleEnter = vi.fn();
const {container} = render(
<TextInput
label="Name"
value="にほんご"
onChange={() => {}}
onEnter={handleEnter}
/>,
);
const input = container.querySelector('input')!;
fireEvent.keyDown(input, {key: 'Enter', isComposing: true});
expect(handleEnter).not.toHaveBeenCalled();
fireEvent.keyDown(input, {key: 'Enter', keyCode: 229});
expect(handleEnter).not.toHaveBeenCalled();

// A real, non-composing Enter after composition ends still submits.
fireEvent.keyDown(input, {key: 'Enter'});
expect(handleEnter).toHaveBeenCalledTimes(1);
});

it('still calls onKeyDown for composing keydowns', () => {
// onKeyDown is the raw escape hatch: it keeps receiving IME keydowns so
// consumers with custom composition handling are unaffected by the
// onEnter guard.
const handleKeyDown = vi.fn();
const {container} = render(
<TextInput
label="Name"
value="にほんご"
onChange={() => {}}
onKeyDown={handleKeyDown}
onEnter={() => {}}
/>,
);
const input = container.querySelector('input')!;
fireEvent.keyDown(input, {key: 'Enter', isComposing: true});
expect(handleKeyDown).toHaveBeenCalledTimes(1);
});

it('does not call onEnter for other keys', async () => {
const user = userEvent.setup();
const handleEnter = vi.fn();
Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/TextInput/TextInput.tsx
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import {renderIconSlot, type IconType} from '../Icon';
import {Spinner} from '../Spinner';
import {useTooltip} from '../Tooltip';
import {VisuallyHidden} from '../VisuallyHidden';
import {getInputARIA} from '../utils';
import {getInputARIA, isImeKeyEvent} from '../utils';

const styles = stylex.create({
input: {
Expand Down Expand Up @@ -431,7 +431,12 @@ export function TextInput({
onKeyDown={
onEnter || onKeyDown
? e => {
if (e.key === 'Enter') {
// The composing keydown fires before compositionend, so without
// this guard pressing Enter to commit a Japanese/Chinese/Korean
// IME conversion would trigger onEnter (submit/save actions)
// before the user intends to submit. onKeyDown still receives
// the raw event. See utils/ime.ts (#6082).
if (e.key === 'Enter' && !isImeKeyEvent(e.nativeEvent)) {
onEnter?.();
}
onKeyDown?.(e);
Expand Down
Loading

AltStyle によって変換されたページ (->オリジナル) /