UNPKG

@coreui/vue

Version:

UI Components Library for Vue.js

215 lines (211 loc) 8.01 kB
'use strict'; var vue = require('vue'); var CConditionalTeleport = require('../conditional-teleport/CConditionalTeleport.js'); var usePopper = require('../../composables/usePopper.js'); var transition = require('../../utils/transition.js'); var getRTLPlacement = require('../../utils/getRTLPlacement.js'); const CTooltip = vue.defineComponent({ name: 'CTooltip', inheritAttrs: false, props: { /** * Apply a CSS fade transition to the tooltip. * * @since 4.9.0 */ animation: { type: Boolean, default: true, }, /** * Appends the vue tooltip to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. * * @since 5.0.0 */ container: { type: [Object, String], default: 'body', }, /** * Content for your component. If you want to pass non-string value please use dedicated slot `<template #content>...</template>` */ content: String, /** * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. * * @since 4.9.0 */ delay: { type: [Number, Object], default: 0, }, /** * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. * * @since 4.9.0 */ fallbackPlacements: { type: [String, Array], default: () => ['top', 'right', 'bottom', 'left'], validator: (value) => { if (typeof value === 'string') { return ['top', 'right', 'bottom', 'left'].includes(value); } if (Array.isArray(value)) { return value.every((e) => ['top', 'right', 'bottom', 'left'].includes(e)); } return false; }, }, /** * Offset of the tooltip relative to its target. */ offset: { type: Array, default: () => [0, 6], }, /** * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. */ placement: { type: String, default: 'top', validator: (value) => { return ['top', 'right', 'bottom', 'left'].includes(value); }, }, /** * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. * * @values 'click', 'focus', 'hover' */ trigger: { type: [String, Array], default: () => ['hover', 'focus'], validator: (value) => { if (typeof value === 'string') { return ['click', 'focus', 'hover'].includes(value); } if (Array.isArray(value)) { return value.every((e) => ['click', 'focus', 'hover'].includes(e)); } return false; }, }, /** * Toggle the visibility of tooltip component. */ visible: Boolean, }, emits: [ /** * Callback fired when the component requests to be hidden. */ 'hide', /** * Callback fired when the component requests to be shown. */ 'show', ], setup(props, { attrs, slots, emit }) { const togglerRef = vue.ref(); const tooltipRef = vue.ref(); const visible = vue.ref(props.visible); const { initPopper, destroyPopper } = usePopper.usePopper(); const uniqueId = `tooltip-${vue.useId()}`; const delay = typeof props.delay === 'number' ? { show: props.delay, hide: props.delay } : props.delay; const popperConfig = { modifiers: [ { name: 'arrow', options: { element: '.tooltip-arrow', }, }, { name: 'flip', options: { fallbackPlacements: props.fallbackPlacements, }, }, { name: 'offset', options: { offset: props.offset, }, }, ], placement: getRTLPlacement.default(props.placement, togglerRef.value), }; const handleEnter = (el, done) => { emit('show'); initPopper(togglerRef.value, tooltipRef.value, popperConfig); el.classList.add('show'); transition.executeAfterTransition(() => done(), el); }; const handleLeave = (el, done) => { emit('hide'); el.classList.remove('show'); transition.executeAfterTransition(() => { done(); destroyPopper(); }, el); }; const toggleVisible = (event, _visible) => { togglerRef.value = event.target; if (_visible) { setTimeout(() => { visible.value = true; }, delay.show); return; } setTimeout(() => { visible.value = false; }, delay.hide); }; return () => [ vue.h(CConditionalTeleport.CConditionalTeleport, { container: props.container, teleport: true, }, { default: () => vue.h(vue.Transition, { onEnter: (el, done) => handleEnter(el, done), onLeave: (el, done) => handleLeave(el, done), }, () => visible.value && vue.h('div', { ...attrs, class: [ 'tooltip', 'bs-tooltip-auto', { fade: props.animation, }, attrs.class, ], id: uniqueId, ref: tooltipRef, role: 'tooltip', }, [ vue.h('div', { class: 'tooltip-arrow' }), (props.content || slots.content) && vue.h('div', { class: 'tooltip-inner' }, { default: () => (slots.content && slots.content()) || props.content, }), ])), }), slots.toggler && slots.toggler({ id: visible.value ? uniqueId : null, on: { click: (event) => props.trigger.includes('click') && toggleVisible(event, !visible.value), blur: (event) => props.trigger.includes('focus') && toggleVisible(event, false), focus: (event) => props.trigger.includes('focus') && toggleVisible(event, true), mouseenter: (event) => props.trigger.includes('hover') && toggleVisible(event, true), mouseleave: (event) => props.trigger.includes('hover') && toggleVisible(event, false), }, }), ]; }, }); exports.CTooltip = CTooltip; //# sourceMappingURL=CTooltip.js.map