Skip to content

Commit 5f309da

Browse files
fix(ui5-input): prevent typeahead during IME composition
1 parent 1695eee commit 5f309da

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

packages/main/src/Input.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ type InputSuggestionScrollEventDetail = {
161161
scrollContainer: HTMLElement;
162162
}
163163

164+
type CompositionEventHandler = (e?: CompositionEvent) => void;
165+
164166
/**
165167
* @class
166168
* ### Overview
@@ -566,6 +568,13 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement
566568
@property({ type: Array })
567569
_linksListenersArray: Array<(args: any) => void> = [];
568570

571+
/**
572+
* Indicates whether the input is currently being composed (e.g. during IME input).
573+
* @private
574+
*/
575+
@property({ type: Boolean, noAttribute: true })
576+
_isComposing = false;
577+
569578
/**
570579
* Defines the suggestion items.
571580
*
@@ -606,6 +615,8 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement
606615
})
607616
valueStateMessage!: Array<HTMLElement>;
608617

618+
_onCompositionStartBound: CompositionEventHandler;
619+
_onCompositionEndBound: CompositionEventHandler;
609620
hasSuggestionItemSelected: boolean;
610621
valueBeforeItemSelection: string;
611622
valueBeforeSelectionStart: string;
@@ -702,17 +713,42 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement
702713
this._keepInnerValue = false;
703714
this._focusedAfterClear = false;
704715
this._valueStateLinks = [];
716+
717+
this._onCompositionStartBound = this._onCompositionStart.bind(this);
718+
this._onCompositionEndBound = this._onCompositionEnd.bind(this);
705719
}
706720

707721
onEnterDOM() {
708722
ResizeHandler.register(this, this._handleResizeBound);
709723
registerUI5Element(this, this._updateAssociatedLabelsTexts.bind(this));
724+
const input = this.nativeInput;
725+
if (input) {
726+
// Update to JSX bindings when Preact resolves bug with:
727+
// https://github.com/preactjs/preact/issues/1978
728+
input.addEventListener("compositionstart", this._onCompositionStartBound);
729+
input.addEventListener("compositionend", this._onCompositionEndBound);
730+
}
710731
}
711732

712733
onExitDOM() {
713734
ResizeHandler.deregister(this, this._handleResizeBound);
714735
deregisterUI5Element(this);
715736
this._removeLinksEventListeners();
737+
const input = this.nativeInput;
738+
if (input) {
739+
input.removeEventListener("compositionstart", this._onCompositionStartBound);
740+
input.removeEventListener("compositionend", this._onCompositionEndBound);
741+
}
742+
}
743+
744+
_onCompositionStart() {
745+
this._isComposing = true;
746+
}
747+
748+
_onCompositionEnd() {
749+
requestAnimationFrame(() => {
750+
this._isComposing = false;
751+
});
716752
}
717753

718754
_highlightSuggestionItem(item: SuggestionItem) {
@@ -773,7 +809,7 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement
773809

774810
// Typehead causes issues on Android devices, so we disable it for now
775811
// If there is already a selection the autocomplete has already been performed
776-
if (this._shouldAutocomplete && !isAndroid() && !autoCompletedChars && !this._isKeyNavigation) {
812+
if (this._shouldAutocomplete && !isAndroid() && !autoCompletedChars && !this._isKeyNavigation && !this._isComposing) {
777813
const item = this._getFirstMatchingItem(value);
778814
if (item) {
779815
this._handleTypeAhead(item);

0 commit comments

Comments
 (0)