UNPKG

vuetify

Version:

Vue.js 2 Semantic Component Framework

186 lines (168 loc) 4.56 kB
import '../../stylus/components/_tooltips.styl' // Mixins import Colorable from '../../mixins/colorable' import Delayable from '../../mixins/delayable' import Dependent from '../../mixins/dependent' import Detachable from '../../mixins/detachable' import Menuable from '../../mixins/menuable' import Toggleable from '../../mixins/toggleable' // Helpers import { convertToUnit } from '../../util/helpers' /* @vue/component */ export default { name: 'v-tooltip', mixins: [Colorable, Delayable, Dependent, Detachable, Menuable, Toggleable], props: { closeDelay: { type: [Number, String], default: 200 }, debounce: { type: [Number, String], default: 0 }, disabled: Boolean, fixed: { type: Boolean, default: true }, openDelay: { type: [Number, String], default: 200 }, tag: { type: String, default: 'span' }, transition: String, zIndex: { default: null } }, data: () => ({ calculatedMinWidth: 0, closeDependents: false }), computed: { calculatedLeft () { const { activator, content } = this.dimensions const unknown = !this.bottom && !this.left && !this.top && !this.right let left = 0 if (this.top || this.bottom || unknown) { left = ( activator.left + (activator.width / 2) - (content.width / 2) ) } else if (this.left || this.right) { left = ( activator.left + (this.right ? activator.width : -content.width) + (this.right ? 10 : -10) ) } if (this.nudgeLeft) left -= parseInt(this.nudgeLeft) if (this.nudgeRight) left += parseInt(this.nudgeRight) return `${this.calcXOverflow(left)}px` }, calculatedTop () { const { activator, content } = this.dimensions let top = 0 if (this.top || this.bottom) { top = ( activator.top + (this.bottom ? activator.height : -content.height) + (this.bottom ? 10 : -10) ) } else if (this.left || this.right) { top = ( activator.top + (activator.height / 2) - (content.height / 2) ) } if (this.nudgeTop) top -= parseInt(this.nudgeTop) if (this.nudgeBottom) top += parseInt(this.nudgeBottom) return `${this.calcYOverflow(top + this.pageYOffset)}px` }, classes () { return { 'v-tooltip--top': this.top, 'v-tooltip--right': this.right, 'v-tooltip--bottom': this.bottom, 'v-tooltip--left': this.left } }, computedTransition () { if (this.transition) return this.transition if (this.top) return 'slide-y-reverse-transition' if (this.right) return 'slide-x-transition' if (this.bottom) return 'slide-y-transition' if (this.left) return 'slide-x-reverse-transition' }, offsetY () { return this.top || this.bottom }, offsetX () { return this.left || this.right }, styles () { return { left: this.calculatedLeft, maxWidth: convertToUnit(this.maxWidth), opacity: this.isActive ? 0.9 : 0, top: this.calculatedTop, zIndex: this.zIndex || this.activeZIndex } } }, mounted () { this.value && this.callActivate() }, methods: { activate () { // Update coordinates and dimensions of menu // and its activator this.updateDimensions() // Start the transition requestAnimationFrame(this.startTransition) } }, render (h) { const tooltip = h('div', this.setBackgroundColor(this.color, { staticClass: 'v-tooltip__content', 'class': { [this.contentClass]: true, 'menuable__content__active': this.isActive }, style: this.styles, attrs: this.getScopeIdAttrs(), directives: [{ name: 'show', value: this.isContentActive }], ref: 'content' }), this.showLazyContent(this.$slots.default)) return h(this.tag, { staticClass: 'v-tooltip', 'class': this.classes }, [ h('transition', { props: { name: this.computedTransition } }, [tooltip]), h('span', { on: this.disabled ? {} : { mouseenter: () => { this.runDelay('open') }, mouseleave: () => { this.runDelay('close') } }, ref: 'activator' }, this.$slots.activator) ]) } }