{"version":3,"file":"index.mjs","sources":["../../../../../packages/hooks/use-popper/index.ts"],"sourcesContent":["import {\n  cloneVNode,\n  computed,\n  Fragment,\n  getCurrentInstance,\n  h,\n  nextTick,\n  toDisplayString,\n  toRef,\n  Transition,\n  ref,\n  renderSlot,\n  withDirectives,\n} from 'vue'\nimport { NOOP } from '@vue/shared'\nimport { createPopper } from '@popperjs/core'\nimport { ClickOutside } from '@element-plus/directives'\nimport {\n  generateId,\n  isHTMLElement,\n  isString,\n  refAttacher,\n} from '@element-plus/utils/util'\nimport { getFirstValidNode } from '@element-plus/utils/vnode'\nimport { stop } from '@element-plus/utils/dom'\nimport PopupManager from '@element-plus/utils/popup-manager'\nimport { throwError } from '@element-plus/utils/error'\n\nimport useTeleport from '../use-teleport'\nimport useTimeout from '../use-timeout'\nimport { useModelToggle } from '../use-model-toggle'\nimport { useTransitionFallthrough } from '../use-transition-fallthrough'\nimport { defaultPopperOptions, defaultModifiers } from './use-popper-options'\nimport { useTargetEvents, DEFAULT_TRIGGER } from './use-target-events'\n\nimport type {\n  CSSProperties,\n  ComponentPublicInstance,\n  ExtractPropTypes,\n  PropType,\n} from 'vue'\nimport type {\n  Instance as PopperInstance,\n  StrictModifiers,\n} from '@popperjs/core'\nimport type { RefElement, Nullable } from '@element-plus/utils/types'\nimport type { Trigger } from './use-target-events'\n\nexport type PopperEffect = 'light' | 'dark'\nexport type Offset = [number, number] | number\n\ntype ElementType = ComponentPublicInstance | HTMLElement\n\nexport const DARK_EFFECT = 'dark'\nexport const LIGHT_EFFECT = 'light'\n\nexport const usePopperControlProps = {\n  appendToBody: {\n    type: Boolean,\n    default: true,\n  },\n  arrowOffset: {\n    type: Number,\n  },\n  popperOptions: defaultPopperOptions,\n  popperClass: {\n    type: String,\n    default: '',\n  },\n}\n\nexport const usePopperProps = {\n  ...usePopperControlProps,\n  // the arrow size is an equailateral triangle with 10px side length, the 3rd side length ~ 14.1px\n  // adding a offset to the ceil of 4.1 should be 5 this resolves the problem of arrow overflowing out of popper.\n  autoClose: {\n    type: Number,\n    default: 0,\n  },\n  content: {\n    type: String,\n    default: '',\n  },\n  class: String,\n  style: Object,\n  hideAfter: {\n    type: Number,\n    default: 200,\n  },\n  disabled: {\n    type: Boolean,\n    default: false,\n  },\n  effect: {\n    type: String as PropType<PopperEffect>,\n    default: DARK_EFFECT,\n  },\n  enterable: {\n    type: Boolean,\n    default: true,\n  },\n  manualMode: {\n    type: Boolean,\n    default: false,\n  },\n  showAfter: {\n    type: Number,\n    default: 0,\n  },\n  pure: {\n    type: Boolean,\n    default: false,\n  },\n  showArrow: {\n    type: Boolean,\n    default: true,\n  },\n  transition: {\n    type: String,\n    default: 'el-fade-in-linear',\n  },\n  trigger: {\n    type: [String, Array] as PropType<Trigger>,\n    default: DEFAULT_TRIGGER,\n  },\n  visible: {\n    type: Boolean,\n    default: undefined,\n  },\n  stopPopperMouseEvent: {\n    type: Boolean,\n    default: true,\n  },\n}\n\nexport const usePopperHook = () => {\n  const vm = getCurrentInstance()!\n  const props: ExtractPropTypes<typeof usePopperProps> = vm.proxy?.$props as any\n  const { slots } = vm\n\n  const arrowRef = ref<RefElement>(null)\n  const triggerRef = ref<ElementType>(null)\n  const popperRef = ref<RefElement>(null)\n\n  const popperStyle = ref<CSSProperties>({ zIndex: PopupManager.nextZIndex() })\n  const visible = ref(false)\n  const isManual = computed(\n    () => props.manualMode || props.trigger === 'manual'\n  )\n\n  const popperId = `el-popper-${generateId()}`\n  let popperInstance: Nullable<PopperInstance> = null\n\n  const { renderTeleport, showTeleport, hideTeleport } = useTeleport(\n    popupRenderer,\n    toRef(props, 'appendToBody')\n  )\n\n  const { show, hide } = useModelToggle({\n    indicator: visible,\n    onShow,\n    onHide,\n  })\n\n  const { registerTimeout, cancelTimeout } = useTimeout()\n\n  // event handlers\n\n  function onShow() {\n    popperStyle.value.zIndex = PopupManager.nextZIndex()\n    nextTick(initializePopper)\n  }\n\n  function onHide() {\n    hideTeleport()\n    nextTick(detachPopper)\n  }\n\n  /**\n   * The calling mechanism here is:\n   * when the visibility gets changed, let's say we change it to true\n   * the delayShow gets called which initializes a global root node for the popper content\n   * to insert in, then it register a timer for calling the show method, which changes the flag to\n   * true, then calls onShow method.\n   * So the order of invocation is: delayedShow -> timer(show) -> set the indicator to true -> onShow\n   */\n\n  function delayShow() {\n    if (isManual.value || props.disabled) return\n    // renders out the teleport element root.\n    showTeleport()\n    registerTimeout(show, props.showAfter)\n  }\n\n  function delayHide() {\n    if (isManual.value) return\n    registerTimeout(hide, props.hideAfter)\n  }\n\n  function onToggle() {\n    if (visible.value) {\n      delayShow()\n    } else {\n      delayHide()\n    }\n  }\n\n  function detachPopper() {\n    popperInstance?.destroy?.()\n    popperInstance = null\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      cancelTimeout()\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    if (shouldPrevent) return\n    delayHide()\n  }\n\n  function initializePopper() {\n    if (!visible.value || popperInstance !== null) {\n      return\n    }\n    const unwrappedTrigger = triggerRef.value\n    const $el = isHTMLElement(unwrappedTrigger)\n      ? unwrappedTrigger\n      : (unwrappedTrigger as ComponentPublicInstance).$el\n\n    popperInstance = createPopper($el, popperRef.value, buildPopperOptions())\n    popperInstance.update()\n  }\n\n  function buildPopperOptions() {\n    const modifiers = [...defaultModifiers, ...props.popperOptions.modifiers]\n\n    if (props.showArrow) {\n      modifiers.push({\n        name: 'arrow',\n        options: {\n          padding: props.arrowOffset || 5,\n          element: arrowRef.value,\n        },\n      } as StrictModifiers)\n    }\n\n    return {\n      ...props.popperOptions,\n      modifiers,\n    }\n  }\n\n  const { onAfterEnter, onAfterLeave, onBeforeEnter, onBeforeLeave } =\n    useTransitionFallthrough()\n\n  const events = useTargetEvents(delayShow, delayHide, onToggle)\n\n  const arrowRefAttacher = refAttacher(arrowRef)\n  const popperRefAttacher = refAttacher(popperRef)\n  const triggerRefAttacher = refAttacher(triggerRef)\n\n  // renderers\n  function popupRenderer() {\n    const mouseUpAndDown = props.stopPopperMouseEvent ? stop : NOOP\n    return h(\n      Transition as any,\n      {\n        name: props.transition,\n        onAfterEnter,\n        onAfterLeave,\n        onBeforeEnter,\n        onBeforeLeave,\n      },\n      {\n        default: () => () =>\n          visible.value\n            ? h(\n                'div',\n                {\n                  'aria-hidden': false,\n                  class: [\n                    props.popperClass,\n                    'el-popper',\n                    `is-${props.effect}`,\n                    props.pure ? 'is-pure' : '',\n                  ],\n                  style: popperStyle.value,\n                  id: popperId,\n                  ref: popperRefAttacher,\n                  role: 'tooltip',\n                  onMouseenter: onPopperMouseEnter,\n                  onMouseleave: onPopperMouseLeave,\n                  onClick: stop,\n                  onMousedown: mouseUpAndDown,\n                  onMouseup: mouseUpAndDown,\n                },\n                [\n                  renderSlot(slots, 'default', {}, () => [\n                    toDisplayString(props.content),\n                  ]),\n                  arrowRenderer(),\n                ]\n              )\n            : null,\n      }\n    )\n  }\n\n  function arrowRenderer() {\n    return props.showArrow\n      ? h(\n          'div',\n          {\n            ref: arrowRefAttacher,\n            class: 'el-popper__arrow',\n            'data-popper-arrow': '',\n          },\n          null\n        )\n      : null\n  }\n\n  function triggerRenderer(triggerProps) {\n    const trigger = slots.trigger?.()\n    const firstElement = getFirstValidNode(trigger, 1)\n    if (!firstElement)\n      throwError('renderTrigger', 'trigger expects single rooted node')\n    return cloneVNode(firstElement, triggerProps, true)\n  }\n\n  function render() {\n    const trigger = triggerRenderer({\n      'aria-describedby': popperId,\n      class: props.class,\n      style: props.style,\n      ref: triggerRefAttacher,\n      ...events,\n    })\n    return h(Fragment, null, [\n      isManual.value\n        ? trigger\n        : withDirectives(trigger, [[ClickOutside, delayHide]]),\n      renderTeleport(),\n    ])\n  }\n\n  return {\n    render,\n  }\n}\n"],"names":[],"mappings":"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"}