mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
* feat: add mention component * fix: build error * fix: build error * feat: delete as a whole * fix: update docs * fix: update global.d.ts * fix: update * fix: update code * fix: update code * fix: update code * fix: rename * fix: update code * fix: upload code * fix: update code * fix: fixed cursor position abnormality * fix: update code * fix: docs add avatar * fix: tooltip position is wrong when placing on top * feat: add overview icon * fix: overview icon color
68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import { getCurrentInstance, ref, shallowRef, watch } from 'vue'
|
|
import { useEventListener } from '@vueuse/core'
|
|
import { isFunction } from '@element-plus/utils'
|
|
import type { ShallowRef } from 'vue'
|
|
|
|
interface UseFocusControllerOptions {
|
|
afterFocus?: () => void
|
|
/**
|
|
* return true to cancel blur
|
|
* @param event FocusEvent
|
|
*/
|
|
beforeBlur?: (event: FocusEvent) => boolean | undefined
|
|
afterBlur?: () => void
|
|
}
|
|
|
|
export function useFocusController<T extends { focus: () => void }>(
|
|
target: ShallowRef<T | undefined>,
|
|
{ afterFocus, beforeBlur, afterBlur }: UseFocusControllerOptions = {}
|
|
) {
|
|
const instance = getCurrentInstance()!
|
|
const { emit } = instance
|
|
const wrapperRef = shallowRef<HTMLElement>()
|
|
const isFocused = ref(false)
|
|
|
|
const handleFocus = (event: FocusEvent) => {
|
|
if (isFocused.value) return
|
|
isFocused.value = true
|
|
emit('focus', event)
|
|
afterFocus?.()
|
|
}
|
|
|
|
const handleBlur = (event: FocusEvent) => {
|
|
const cancelBlur = isFunction(beforeBlur) ? beforeBlur(event) : false
|
|
if (
|
|
cancelBlur ||
|
|
(event.relatedTarget &&
|
|
wrapperRef.value?.contains(event.relatedTarget as Node))
|
|
)
|
|
return
|
|
|
|
isFocused.value = false
|
|
emit('blur', event)
|
|
afterBlur?.()
|
|
}
|
|
|
|
const handleClick = () => {
|
|
target.value?.focus()
|
|
}
|
|
|
|
watch(wrapperRef, (el) => {
|
|
if (el) {
|
|
el.setAttribute('tabindex', '-1')
|
|
}
|
|
})
|
|
|
|
// TODO: using useEventListener will fail the test
|
|
// useEventListener(target, 'focus', handleFocus)
|
|
// useEventListener(target, 'blur', handleBlur)
|
|
useEventListener(wrapperRef, 'click', handleClick, true)
|
|
|
|
return {
|
|
wrapperRef,
|
|
isFocused,
|
|
handleFocus,
|
|
handleBlur,
|
|
}
|
|
}
|