Files
element-plus/packages/hooks/use-focus-controller/index.ts
赵添 0456c790db feat: add mention component (#17586)
* 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
2024-08-02 11:00:26 +08:00

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,
}
}