UNPKG

@gitlab/ui

Version:
120 lines (112 loc) 3.43 kB
import { extend } from '../../../vue'; import { NAME_TOOLTIP_TEMPLATE } from '../../../constants/components'; import { EVENT_NAME_MOUSEENTER, EVENT_NAME_MOUSELEAVE, EVENT_NAME_FOCUSIN, EVENT_NAME_FOCUSOUT } from '../../../constants/events'; import { PROP_TYPE_BOOLEAN, PROP_TYPE_STRING } from '../../../constants/props'; import { isFunction } from '../../../utils/inspect'; import { scopedStyleMixin } from '../../../mixins/scoped-style'; import { BVPopper } from './bv-popper'; // --- Props --- const props = { // Used only by the directive versions html: { type: PROP_TYPE_BOOLEAN, required: false, default: false }, // Other non-reactive (while open) props are pulled in from BVPopper id: { type: PROP_TYPE_STRING, required: false, default: undefined } }; // --- Main component --- // @vue/component const BVTooltipTemplate = /*#__PURE__*/extend({ name: NAME_TOOLTIP_TEMPLATE, extends: BVPopper, mixins: [scopedStyleMixin], props, data() { // We use data, rather than props to ensure reactivity // Parent component will directly set this data return { title: '', content: '', variant: null, customClass: null, interactive: true }; }, computed: { templateType() { return 'tooltip'; }, templateClasses() { const variant = this.variant, attachment = this.attachment, templateType = this.templateType; return [{ // Disables pointer events to hide the tooltip when the user // hovers over its content noninteractive: !this.interactive, [`b-${templateType}-${variant}`]: variant, // `attachment` will come from BVToolpop [`bs-${templateType}-${attachment}`]: attachment }, this.customClass]; }, templateAttributes() { const id = this.id; return { // Apply attributes from root tooltip component ...this.bvParent.bvParent.$attrs, id, role: 'tooltip', tabindex: '-1', // Add the scoped style data attribute to the template root element ...this.scopedStyleAttrs }; }, templateListeners() { // Used for hover/focus trigger listeners return { mouseenter: /* istanbul ignore next */event => { this.$emit(EVENT_NAME_MOUSEENTER, event); }, mouseleave: /* istanbul ignore next */event => { this.$emit(EVENT_NAME_MOUSELEAVE, event); }, focusin: /* istanbul ignore next */event => { this.$emit(EVENT_NAME_FOCUSIN, event); }, focusout: /* istanbul ignore next */event => { this.$emit(EVENT_NAME_FOCUSOUT, event); } }; } }, methods: { renderTemplate(h) { const title = this.title; // Title can be a scoped slot function const $title = isFunction(title) ? title({}) : title; // Directive versions only const domProps = this.html && !isFunction(title) ? { innerHTML: title } : {}; return h('div', { staticClass: 'tooltip b-tooltip', class: this.templateClasses, attrs: this.templateAttributes, on: this.templateListeners }, [h('div', { staticClass: 'arrow', ref: 'arrow' }), h('div', { staticClass: 'tooltip-inner', domProps }, [$title])]); } } }); export { BVTooltipTemplate, props };