mirror of
https://github.com/element-plus/element-plus.git
synced 2025-08-18 14:12:56 +08:00
fix(components): [input] lose focus when click suffix icon (#13264)
* feat(hooks): add useFocusController * fix(components): [input] lose focus when click suffix icon closed #13153, #13159 * refactor(hooks): use-focus-controller * test: fix test * test: update * fix(theme-chalk): [input] add cursor style to the wrapper
This commit is contained in:
@ -15,10 +15,10 @@
|
||||
<slot name="prepend" />
|
||||
</div>
|
||||
|
||||
<div :class="wrapperKls">
|
||||
<div ref="wrapperRef" :class="wrapperKls">
|
||||
<!-- prefix slot -->
|
||||
<span v-if="$slots.prefix || prefixIcon" :class="nsInput.e('prefix')">
|
||||
<span :class="nsInput.e('prefix-inner')" @click="focus">
|
||||
<span :class="nsInput.e('prefix-inner')">
|
||||
<slot name="prefix" />
|
||||
<el-icon v-if="prefixIcon" :class="nsInput.e('icon')">
|
||||
<component :is="prefixIcon" />
|
||||
@ -54,7 +54,7 @@
|
||||
|
||||
<!-- suffix slot -->
|
||||
<span v-if="suffixVisible" :class="nsInput.e('suffix')">
|
||||
<span :class="nsInput.e('suffix-inner')" @click="focus">
|
||||
<span :class="nsInput.e('suffix-inner')">
|
||||
<template
|
||||
v-if="!showClear || !showPwdVisible || !isWordLimitVisible"
|
||||
>
|
||||
@ -172,7 +172,12 @@ import {
|
||||
isKorean,
|
||||
isObject,
|
||||
} from '@element-plus/utils'
|
||||
import { useAttrs, useCursor, useNamespace } from '@element-plus/hooks'
|
||||
import {
|
||||
useAttrs,
|
||||
useCursor,
|
||||
useFocusController,
|
||||
useNamespace,
|
||||
} from '@element-plus/hooks'
|
||||
import { UPDATE_MODEL_EVENT } from '@element-plus/constants'
|
||||
import { calcTextareaHeight } from './utils'
|
||||
import { inputEmits, inputProps } from './input'
|
||||
@ -220,7 +225,7 @@ const containerKls = computed(() => [
|
||||
|
||||
const wrapperKls = computed(() => [
|
||||
nsInput.e('wrapper'),
|
||||
nsInput.is('focus', focused.value),
|
||||
nsInput.is('focus', isFocused.value),
|
||||
])
|
||||
|
||||
const attrs = useAttrs({
|
||||
@ -240,7 +245,6 @@ const nsTextarea = useNamespace('textarea')
|
||||
const input = shallowRef<HTMLInputElement>()
|
||||
const textarea = shallowRef<HTMLTextAreaElement>()
|
||||
|
||||
const focused = ref(false)
|
||||
const hovering = ref(false)
|
||||
const isComposing = ref(false)
|
||||
const passwordVisible = ref(false)
|
||||
@ -249,6 +253,17 @@ const textareaCalcStyle = shallowRef(props.inputStyle)
|
||||
|
||||
const _ref = computed(() => input.value || textarea.value)
|
||||
|
||||
const { wrapperRef, isFocused, handleFocus, handleBlur } = useFocusController(
|
||||
_ref,
|
||||
{
|
||||
afterBlur() {
|
||||
if (props.validateEvent) {
|
||||
formItem?.validate?.('blur').catch((err) => debugWarn(err))
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const needStatusIcon = computed(() => form?.statusIcon ?? false)
|
||||
const validateState = computed(() => formItem?.validateState || '')
|
||||
const validateIcon = computed(
|
||||
@ -275,7 +290,7 @@ const showClear = computed(
|
||||
!inputDisabled.value &&
|
||||
!props.readonly &&
|
||||
!!nativeInputValue.value &&
|
||||
(focused.value || hovering.value)
|
||||
(isFocused.value || hovering.value)
|
||||
)
|
||||
const showPwdVisible = computed(
|
||||
() =>
|
||||
@ -283,7 +298,7 @@ const showPwdVisible = computed(
|
||||
!inputDisabled.value &&
|
||||
!props.readonly &&
|
||||
!!nativeInputValue.value &&
|
||||
(!!nativeInputValue.value || focused.value)
|
||||
(!!nativeInputValue.value || isFocused.value)
|
||||
)
|
||||
const isWordLimitVisible = computed(
|
||||
() =>
|
||||
@ -445,19 +460,6 @@ const focus = async () => {
|
||||
|
||||
const blur = () => _ref.value?.blur()
|
||||
|
||||
const handleFocus = (event: FocusEvent) => {
|
||||
focused.value = true
|
||||
emit('focus', event)
|
||||
}
|
||||
|
||||
const handleBlur = (event: FocusEvent) => {
|
||||
focused.value = false
|
||||
emit('blur', event)
|
||||
if (props.validateEvent) {
|
||||
formItem?.validate?.('blur').catch((err) => debugWarn(err))
|
||||
}
|
||||
}
|
||||
|
||||
const handleMouseLeave = (evt: MouseEvent) => {
|
||||
hovering.value = false
|
||||
emit('mouseleave', evt)
|
||||
|
Reference in New Issue
Block a user