UNPKG

element-plus

Version:

A Component Library for Vue 3

232 lines (229 loc) 5.8 kB
import { ref, reactive, computed, unref, watch } from 'vue'; import { createPopper } from '@popperjs/core'; import { generateId, isBool, isHTMLElement } from '../../../../utils/util.mjs'; import PopupManager from '../../../../utils/popup-manager.mjs'; import usePopperOptions from './popper-options.mjs'; export { Effect } from './defaults.mjs'; import { isString, isArray } from '@vue/shared'; const DEFAULT_TRIGGER = ["hover"]; const UPDATE_VISIBLE_EVENT = "update:visible"; function usePopper(props, { emit }) { const arrowRef = ref(null); const triggerRef = ref(null); const popperRef = ref(null); const popperId = `el-popper-${generateId()}`; let popperInstance = null; let showTimer = null; let hideTimer = null; let triggerFocused = false; const isManualMode = () => props.manualMode || props.trigger === "manual"; const popperStyle = ref({ zIndex: PopupManager.nextZIndex() }); const popperOptions = usePopperOptions(props, { arrow: arrowRef }); const state = reactive({ visible: !!props.visible }); const visibility = computed({ get() { if (props.disabled) { return false; } else { return isBool(props.visible) ? props.visible : state.visible; } }, set(val) { if (isManualMode()) return; isBool(props.visible) ? emit(UPDATE_VISIBLE_EVENT, val) : state.visible = val; } }); function _show() { if (props.autoClose > 0) { hideTimer = window.setTimeout(() => { _hide(); }, props.autoClose); } visibility.value = true; } function _hide() { visibility.value = false; } function clearTimers() { clearTimeout(showTimer); clearTimeout(hideTimer); } const show = () => { if (isManualMode() || props.disabled) return; clearTimers(); if (props.showAfter === 0) { _show(); } else { showTimer = window.setTimeout(() => { _show(); }, props.showAfter); } }; const hide = () => { if (isManualMode()) return; clearTimers(); if (props.hideAfter > 0) { hideTimer = window.setTimeout(() => { close(); }, props.hideAfter); } else { close(); } }; const close = () => { _hide(); if (props.disabled) { doDestroy(true); } }; function onPopperMouseEnter() { if (props.enterable && props.trigger !== "click") { clearTimeout(hideTimer); } } function onPopperMouseLeave() { const { trigger } = props; const shouldPrevent = isString(trigger) && (trigger === "click" || trigger === "focus") || trigger.length === 1 && (trigger[0] === "click" || trigger[0] === "focus"); if (shouldPrevent) return; hide(); } function initializePopper() { if (!unref(visibility)) { return; } const unwrappedTrigger = unref(triggerRef); const _trigger = isHTMLElement(unwrappedTrigger) ? unwrappedTrigger : unwrappedTrigger.$el; popperInstance = createPopper(_trigger, unref(popperRef), unref(popperOptions)); popperInstance.update(); } function doDestroy(forceDestroy) { if (!popperInstance || unref(visibility) && !forceDestroy) return; detachPopper(); } function detachPopper() { var _a; (_a = popperInstance == null ? void 0 : popperInstance.destroy) == null ? void 0 : _a.call(popperInstance); popperInstance = null; } const events = {}; function update() { if (!unref(visibility)) { return; } if (popperInstance) { popperInstance.update(); } else { initializePopper(); } } function onVisibilityChange(toState) { if (toState) { popperStyle.value.zIndex = PopupManager.nextZIndex(); initializePopper(); } } if (!isManualMode()) { const toggleState = () => { if (unref(visibility)) { hide(); } else { show(); } }; const popperEventsHandler = (e) => { e.stopPropagation(); switch (e.type) { case "click": { if (triggerFocused) { triggerFocused = false; } else { toggleState(); } break; } case "mouseenter": { show(); break; } case "mouseleave": { hide(); break; } case "focus": { triggerFocused = true; show(); break; } case "blur": { triggerFocused = false; hide(); break; } } }; const triggerEventsMap = { click: ["onClick"], hover: ["onMouseenter", "onMouseleave"], focus: ["onFocus", "onBlur"] }; const mapEvents = (t) => { triggerEventsMap[t].forEach((event) => { events[event] = popperEventsHandler; }); }; if (isArray(props.trigger)) { Object.values(props.trigger).forEach(mapEvents); } else { mapEvents(props.trigger); } } watch(popperOptions, (val) => { if (!popperInstance) return; popperInstance.setOptions(val); popperInstance.update(); }); watch(visibility, onVisibilityChange); return { update, doDestroy, show, hide, onPopperMouseEnter, onPopperMouseLeave, onAfterEnter: () => { emit("after-enter"); }, onAfterLeave: () => { detachPopper(); emit("after-leave"); }, onBeforeEnter: () => { emit("before-enter"); }, onBeforeLeave: () => { emit("before-leave"); }, initializePopper, isManualMode, arrowRef, events, popperId, popperInstance, popperRef, popperStyle, triggerRef, visibility }; } export { DEFAULT_TRIGGER, UPDATE_VISIBLE_EVENT, usePopper as default }; //# sourceMappingURL=index.mjs.map