element-plus
Version:
A Component Library for Vue 3
1 lines • 10.6 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../../../../packages/components/popper/src/use-popper/index.ts"],"sourcesContent":["import { computed, ref, reactive, watch, unref } from 'vue'\nimport { createPopper } from '@popperjs/core'\nimport {\n generateId,\n isBool,\n isHTMLElement,\n isArray,\n isString,\n} from '@element-plus/utils/util'\nimport PopupManager from '@element-plus/utils/popup-manager'\nimport usePopperOptions from './popper-options'\n\nimport type {\n ComponentPublicInstance,\n CSSProperties,\n SetupContext,\n Ref,\n} from 'vue'\nimport type { TimeoutHandle, Nullable } from '@element-plus/utils/types'\nimport type {\n IPopperOptions,\n TriggerType,\n PopperInstance,\n RefElement,\n} from './defaults'\n\nexport type ElementType = ComponentPublicInstance | HTMLElement\nexport type EmitType =\n | 'update:visible'\n | 'after-enter'\n | 'after-leave'\n | 'before-enter'\n | 'before-leave'\n\nexport interface PopperEvents {\n onClick?: (e: Event) => void\n onMouseenter?: (e: Event) => void\n onMouseleave?: (e: Event) => void\n onFocus?: (e: Event) => void\n onBlur?: (e: Event) => void\n}\n\nexport const DEFAULT_TRIGGER = ['hover']\nexport const UPDATE_VISIBLE_EVENT = 'update:visible'\nexport default function (\n props: IPopperOptions,\n { emit }: SetupContext<EmitType[]>\n) {\n const arrowRef = ref<RefElement>(null)\n const triggerRef = ref(null) as Ref<ElementType>\n const popperRef = ref<RefElement>(null)\n\n const popperId = `el-popper-${generateId()}`\n let popperInstance: Nullable<PopperInstance> = null\n let showTimer: Nullable<TimeoutHandle> = null\n let hideTimer: Nullable<TimeoutHandle> = null\n let triggerFocused = false\n\n const isManualMode = () => props.manualMode || props.trigger === 'manual'\n\n const popperStyle = ref<CSSProperties>({ zIndex: PopupManager.nextZIndex() })\n\n const popperOptions = usePopperOptions(props, {\n arrow: arrowRef,\n })\n\n const state = reactive({\n visible: !!props.visible,\n })\n // visible has been taken by props.visible, avoiding name collision\n // Either marking type here or setter parameter\n const visibility = computed<boolean>({\n get() {\n if (props.disabled) {\n return false\n } else {\n return isBool(props.visible) ? props.visible : state.visible\n }\n },\n set(val) {\n if (isManualMode()) return\n isBool(props.visible)\n ? emit(UPDATE_VISIBLE_EVENT, val)\n : (state.visible = val)\n },\n })\n\n function _show() {\n if (props.autoClose > 0) {\n hideTimer = window.setTimeout(() => {\n _hide()\n }, props.autoClose)\n }\n visibility.value = true\n }\n\n function _hide() {\n visibility.value = false\n }\n\n function clearTimers() {\n clearTimeout(showTimer)\n clearTimeout(hideTimer)\n }\n\n const show = () => {\n if (isManualMode() || props.disabled) return\n clearTimers()\n if (props.showAfter === 0) {\n _show()\n } else {\n showTimer = window.setTimeout(() => {\n _show()\n }, props.showAfter)\n }\n }\n\n const hide = () => {\n if (isManualMode()) return\n clearTimers()\n if (props.hideAfter > 0) {\n hideTimer = window.setTimeout(() => {\n close()\n }, props.hideAfter)\n } else {\n close()\n }\n }\n const close = () => {\n _hide()\n if (props.disabled) {\n doDestroy(true)\n }\n }\n\n function onPopperMouseEnter() {\n // if trigger is click, user won't be able to close popper when\n // user tries to move the mouse over popper contents\n if (props.enterable && props.trigger !== 'click') {\n clearTimeout(hideTimer)\n }\n }\n\n function onPopperMouseLeave() {\n const { trigger } = props\n const shouldPrevent =\n (isString(trigger) && (trigger === 'click' || trigger === 'focus')) ||\n // we'd like to test array type trigger here, but the only case we need to cover is trigger === 'click' or\n // trigger === 'focus', because that when trigger is string\n // trigger.length === 1 and trigger[0] === 5 chars string is mutually exclusive.\n // so there will be no need to test if trigger is array type.\n (trigger.length === 1 &&\n (trigger[0] === 'click' || trigger[0] === 'focus'))\n\n if (shouldPrevent) return\n\n hide()\n }\n\n function initializePopper() {\n if (!unref(visibility)) {\n return\n }\n const unwrappedTrigger = unref(triggerRef)\n const _trigger = isHTMLElement(unwrappedTrigger)\n ? unwrappedTrigger\n : (unwrappedTrigger as ComponentPublicInstance).$el\n popperInstance = createPopper(\n _trigger,\n unref(popperRef),\n unref(popperOptions)\n )\n\n popperInstance.update()\n }\n\n function doDestroy(forceDestroy?: boolean) {\n /* istanbul ignore if */\n if (!popperInstance || (unref(visibility) && !forceDestroy)) return\n detachPopper()\n }\n\n function detachPopper() {\n popperInstance?.destroy?.()\n popperInstance = null\n }\n\n const events = {} as PopperEvents\n\n function update() {\n if (!unref(visibility)) {\n return\n }\n if (popperInstance) {\n popperInstance.update()\n } else {\n initializePopper()\n }\n }\n\n function onVisibilityChange(toState: boolean) {\n if (toState) {\n popperStyle.value.zIndex = PopupManager.nextZIndex()\n initializePopper()\n }\n }\n\n if (!isManualMode()) {\n const toggleState = () => {\n if (unref(visibility)) {\n hide()\n } else {\n show()\n }\n }\n\n const popperEventsHandler = (e: Event) => {\n e.stopPropagation()\n switch (e.type) {\n case 'click': {\n if (triggerFocused) {\n // reset previous focus event\n triggerFocused = false\n } else {\n toggleState()\n }\n break\n }\n case 'mouseenter': {\n show()\n break\n }\n case 'mouseleave': {\n hide()\n break\n }\n case 'focus': {\n triggerFocused = true\n show()\n break\n }\n case 'blur': {\n triggerFocused = false\n hide()\n break\n }\n }\n }\n\n const triggerEventsMap: Partial<\n Record<TriggerType, (keyof PopperEvents)[]>\n > = {\n click: ['onClick'],\n hover: ['onMouseenter', 'onMouseleave'],\n focus: ['onFocus', 'onBlur'],\n }\n\n const mapEvents = (t: TriggerType) => {\n triggerEventsMap[t].forEach((event) => {\n events[event] = popperEventsHandler\n })\n }\n\n if (isArray(props.trigger)) {\n Object.values(props.trigger).forEach(mapEvents)\n } else {\n mapEvents(props.trigger as TriggerType)\n }\n }\n\n watch(popperOptions, (val) => {\n if (!popperInstance) return\n popperInstance.setOptions(val)\n popperInstance.update()\n })\n\n watch(visibility, onVisibilityChange)\n\n return {\n update,\n doDestroy,\n show,\n hide,\n onPopperMouseEnter,\n onPopperMouseLeave,\n onAfterEnter: () => {\n emit('after-enter')\n },\n onAfterLeave: () => {\n detachPopper()\n emit('after-leave')\n },\n onBeforeEnter: () => {\n emit('before-enter')\n },\n onBeforeLeave: () => {\n emit('before-leave')\n },\n initializePopper,\n isManualMode,\n arrowRef,\n events,\n popperId,\n popperInstance,\n popperRef,\n popperStyle,\n triggerRef,\n visibility,\n }\n}\n\nexport * from './defaults'\n"],"names":[],"mappings":"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"}