@coreui/vue
Version:
UI Components Library for Vue.js
213 lines (210 loc) • 7.93 kB
JavaScript
import { defineComponent, ref, useId, h, Transition } from 'vue';
import { CConditionalTeleport } from '../conditional-teleport/CConditionalTeleport.js';
import { usePopper } from '../../composables/usePopper.js';
import { executeAfterTransition } from '../../utils/transition.js';
import getRTLPlacement from '../../utils/getRTLPlacement.js';
const CTooltip = 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 = ref();
const tooltipRef = ref();
const visible = ref(props.visible);
const { initPopper, destroyPopper } = usePopper();
const uniqueId = `tooltip-${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(props.placement, togglerRef.value),
};
const handleEnter = (el, done) => {
emit('show');
initPopper(togglerRef.value, tooltipRef.value, popperConfig);
el.classList.add('show');
executeAfterTransition(() => done(), el);
};
const handleLeave = (el, done) => {
emit('hide');
el.classList.remove('show');
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 () => [
h(CConditionalTeleport, {
container: props.container,
teleport: true,
}, {
default: () => h(Transition, {
onEnter: (el, done) => handleEnter(el, done),
onLeave: (el, done) => handleLeave(el, done),
}, () => visible.value &&
h('div', {
...attrs,
class: [
'tooltip',
'bs-tooltip-auto',
{
fade: props.animation,
},
attrs.class,
],
id: uniqueId,
ref: tooltipRef,
role: 'tooltip',
}, [
h('div', { class: 'tooltip-arrow' }),
(props.content || slots.content) &&
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),
},
}),
];
},
});
export { CTooltip };
//# sourceMappingURL=CTooltip.js.map