UNPKG

equal-vue

Version:

Equal is a Vue 3 hackable UI library empowered by tailwindcss

104 lines (89 loc) 2.95 kB
import TooltipBody from '@/components/tooltip/TooltipBody.vue' import { usePopover } from '@/hooks/usePopover' import { Positions } from '@/models/enums/Positions' import { EqualUIConfiguration } from '@/types/variant' import { autoUpdate } from '@floating-ui/dom' import { createApp, Directive, h, reactive, ref, unref, watch } from 'vue' export const tooltip = (theme: EqualUIConfiguration): Directive => ({ mounted(elem, binding) { const { show, popover, trigger, placement, handleMouseEnter, handleMouseLeave, setPopoverPosition, permanent, disabled, } = usePopover({}) const mountEl = document.createElement('div') // https://github.com/vuejs/core/issues/4874#issuecomment-959008724 const myTooltip = createApp({ render: () => h( TooltipBody, reactive({ placement, show, content: binding.value.content, }), () => binding.value.children, ), }) myTooltip.provide('config', theme) placement.value = unref(binding.value.position) || placement.value watch( ref(binding.value.disabled), (val) => { disabled.value = unref(val) }, { immediate: true }, ) watch( ref(binding.value.permanent), (val) => { permanent.value = !!unref(val) }, { immediate: true }, ) watch(ref(binding.value.content), setPopoverPosition) watch(ref(binding.value.position), (val: Positions) => { if (!val) { return } placement.value = unref(val) setPopoverPosition() }) // mount tooltip El const comp = myTooltip.mount(mountEl) document.body.appendChild(mountEl) // set $refs trigger.value = elem popover.value = comp.$el elem.myTooltip = myTooltip elem.mountEl = mountEl elem.handleMouseEnter = handleMouseEnter elem.handleMouseLeave = handleMouseLeave if (binding.value.autoUpdate) { const cleanup = autoUpdate(trigger.value, popover.value, () => { setPopoverPosition() }) elem.cleanup = cleanup || (() => {}) } elem.addEventListener('mouseenter', elem.handleMouseEnter) elem.addEventListener('mouseleave', elem.handleMouseLeave) elem.addEventListener('focus', elem.handleMouseEnter) elem.addEventListener('blur', elem.handleMouseLeave) }, updated(elem) {}, unmounted(elem) { elem.removeEventListener('mouseenter', elem.handleMouseEnter) elem.removeEventListener('mouseleave', elem.handleMouseLeave) elem.removeEventListener('focus', elem.handleMouseEnter) elem.removeEventListener('blur', elem.handleMouseLeave) elem.cleanup && elem.cleanup() elem.myTooltip.unmount() elem.mountEl.parentNode.removeChild(elem.mountEl) }, })