fix(components): fix iOS select click event listening (#16393)

iOS Safari does not handle click events when a mouseenter event is registered and a DOM-change
happens in a child. We use a Vue custom event binding to only register the event on non-iOS devices.
The inputHovering state gets updated now on iOS-devices on click. This is needed as the mouseenter
event normally does this.

closed #5210
This commit is contained in:
Raphael Bernhart
2024-06-21 01:34:43 +02:00
committed by GitHub
parent db0fec864a
commit 03e8be2657
2 changed files with 13 additions and 1 deletions

View File

@@ -3,7 +3,7 @@
ref="selectRef"
v-click-outside:[popperRef]="handleClickOutside"
:class="[nsSelect.b(), nsSelect.m(selectSize)]"
@mouseenter="states.inputHovering = true"
@[mouseEnterEventName]="states.inputHovering = true"
@mouseleave="states.inputHovering = false"
@click.prevent.stop="toggleMenu"
>

View File

@@ -27,6 +27,7 @@ import {
debugWarn,
isClient,
isFunction,
isIOS,
isNumber,
isUndefined,
scrollIntoView,
@@ -249,6 +250,12 @@ export const useSelect = (props: ISelectProps, emit) => {
: states.selectedLabel
})
// iOS Safari does not handle click events when a mouseenter event is registered and a DOM-change happens in a child
// We use a Vue custom event binding to only register the event on non-iOS devices
// ref.: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
// Github Issue: https://github.com/vuejs/vue/issues/9859
const mouseEnterEventName = computed(() => (isIOS ? null : 'mouseenter'))
watch(
() => props.modelValue,
(val, oldVal) => {
@@ -671,6 +678,10 @@ export const useSelect = (props: ISelectProps, emit) => {
const toggleMenu = () => {
if (selectDisabled.value) return
// We only set the inputHovering state to true on mouseenter event on iOS devices
// To keep the state updated we set it here to true
if (isIOS) states.inputHovering = true
if (states.menuVisibleOnFocus) {
// controlled by automaticDropdown
states.menuVisibleOnFocus = false
@@ -815,6 +826,7 @@ export const useSelect = (props: ISelectProps, emit) => {
hasModelValue,
shouldShowPlaceholder,
currentPlaceholder,
mouseEnterEventName,
showClose,
iconComponent,
iconReverse,