Skip to content

Commit dce2a1a

Browse files
ErnestRobinMalfait
andauthored
fix: the order of compositionend events varies by browser (#1890)
* fix: the order of compositionend events varies by browser * apply our style conventions Co-authored-by: Robin Malfait <[email protected]>
1 parent f66f492 commit dce2a1a

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

packages/@headlessui-react/src/components/combobox/combobox.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,16 @@ let Input = forwardRefWithAs(function Input<
717717
[currentValue, data.comboboxState]
718718
)
719719

720+
let isComposing = useRef(false)
721+
let handleCompositionStart = useEvent(() => {
722+
isComposing.current = true
723+
})
724+
let handleCompositionEnd = useEvent(() => {
725+
setTimeout(() => {
726+
isComposing.current = false
727+
})
728+
})
729+
720730
let handleKeyDown = useEvent((event: ReactKeyboardEvent<HTMLInputElement>) => {
721731
switch (event.key) {
722732
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12
@@ -740,7 +750,7 @@ let Input = forwardRefWithAs(function Input<
740750

741751
case Keys.Enter:
742752
if (data.comboboxState !== ComboboxState.Open) return
743-
if (event.nativeEvent.isComposing) return
753+
if (isComposing.current) return
744754

745755
event.preventDefault()
746756
event.stopPropagation()
@@ -844,6 +854,8 @@ let Input = forwardRefWithAs(function Input<
844854
'aria-multiselectable': data.mode === ValueMode.Multi ? true : undefined,
845855
'aria-labelledby': labelledby,
846856
disabled: data.disabled,
857+
onCompositionStart: handleCompositionStart,
858+
onCompositionEnd: handleCompositionEnd,
847859
onKeyDown: handleKeyDown,
848860
onChange: handleChange,
849861
}

packages/@headlessui-vue/src/components/combobox/combobox.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ export let ComboboxInput = defineComponent({
630630
}
631631

632632
// Workaround Vue bug where watching [ref(undefined)] is not fired immediately even when value is true
633-
const __fixVueImmediateWatchBug__ = ref('')
633+
let __fixVueImmediateWatchBug__ = ref('')
634634

635635
let shouldIgnoreOpenOnChange = false
636636
function updateInputAndNotify(currentValue: string) {
@@ -676,6 +676,16 @@ export let ComboboxInput = defineComponent({
676676
)
677677
})
678678

679+
let isComposing = ref(false)
680+
function handleCompositionstart() {
681+
isComposing.value = true
682+
}
683+
function handleCompositionend() {
684+
setTimeout(() => {
685+
isComposing.value = false
686+
})
687+
}
688+
679689
function handleKeyDown(event: KeyboardEvent) {
680690
switch (event.key) {
681691
// Ref: https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-12
@@ -700,7 +710,7 @@ export let ComboboxInput = defineComponent({
700710

701711
case Keys.Enter:
702712
if (api.comboboxState.value !== ComboboxStates.Open) return
703-
if (event.isComposing) return
713+
if (isComposing.value) return
704714

705715
event.preventDefault()
706716
event.stopPropagation()
@@ -793,6 +803,8 @@ export let ComboboxInput = defineComponent({
793803
'aria-multiselectable': api.mode.value === ValueMode.Multi ? true : undefined,
794804
'aria-labelledby': dom(api.labelRef)?.id ?? dom(api.buttonRef)?.id,
795805
id,
806+
onCompositionstart: handleCompositionstart,
807+
onCompositionend: handleCompositionend,
796808
onKeydown: handleKeyDown,
797809
onChange: handleChange,
798810
onInput: handleInput,

0 commit comments

Comments
 (0)