element-plus/packages/hooks/use-popper/use-target-events.ts
Sanxiaozhizi e9e56d5938
chore: upgrade & improve eslint rule (#3105)
* chore: remove unused ts-node

* chore: upgrade lodash

* chore: upgrade eslint

* perf: remove side effects in computed

* refactor: follow eslint rules

* chore: remove vue-template-compiler

* style: enhance eslint format rule

* style: format code
2021-08-27 17:46:06 +08:00

92 lines
1.9 KiB
TypeScript

import { computed, getCurrentInstance } from 'vue'
import { isArray } from '@element-plus/utils/util'
export type TriggerType = 'click' | 'hover' | 'focus' | 'manual'
export type Trigger = TriggerType | TriggerType[]
export interface PopperEvents {
onClick?: (e: Event) => void
onMouseenter?: (e: Event) => void
onMouseleave?: (e: Event) => void
onFocus?: (e: Event) => void
onBlur?: (e: Event) => void
}
export const DEFAULT_TRIGGER = 'hover'
type Handler = () => void
export const useTargetEvents = (
onShow: Handler,
onHide: Handler,
onToggle: Handler,
) => {
const { props } = getCurrentInstance()
let triggerFocused = false
const popperEventsHandler = (e: Event) => {
e.stopPropagation()
switch (e.type) {
case 'click': {
if (triggerFocused) {
// reset previous focus event
triggerFocused = false
} else {
onToggle()
}
break
}
case 'mouseenter': {
onShow()
break
}
case 'mouseleave': {
onHide()
break
}
case 'focus': {
triggerFocused = true
onShow()
break
}
case 'blur': {
triggerFocused = false
onHide()
break
}
}
}
const triggerEventsMap: Partial<Record<
TriggerType,
(keyof PopperEvents)[]
>> = {
click: ['onClick'],
hover: ['onMouseenter', 'onMouseleave'],
focus: ['onFocus', 'onBlur'],
}
const mapEvents = (t: TriggerType) => {
const events = {} as PopperEvents
triggerEventsMap[t].forEach(event => {
events[event] = popperEventsHandler
})
return events
}
return computed(() => {
if (isArray(props.trigger)) {
return Object.values(props.trigger).reduce((pre, t) => {
return {
...pre,
...mapEvents(t),
}
}, {})
} else {
return mapEvents(props.trigger as TriggerType)
}
})
}