2021-07-13 17:30:41 +08:00
|
|
|
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,
|
2021-09-04 19:29:28 +08:00
|
|
|
onToggle: Handler
|
2021-07-13 17:30:41 +08:00
|
|
|
) => {
|
2021-10-28 04:44:27 +08:00
|
|
|
const { props } = getCurrentInstance()!
|
2021-07-13 17:30:41 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-04 19:29:28 +08:00
|
|
|
const triggerEventsMap: Partial<Record<TriggerType, (keyof PopperEvents)[]>> =
|
|
|
|
{
|
|
|
|
click: ['onClick'],
|
|
|
|
hover: ['onMouseenter', 'onMouseleave'],
|
|
|
|
focus: ['onFocus', 'onBlur'],
|
|
|
|
}
|
2021-07-13 17:30:41 +08:00
|
|
|
|
|
|
|
const mapEvents = (t: TriggerType) => {
|
|
|
|
const events = {} as PopperEvents
|
2021-10-28 04:44:27 +08:00
|
|
|
triggerEventsMap[t]?.forEach((event) => {
|
2021-07-13 17:30:41 +08:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|