Skip to content

Commit 803eded

Browse files
committed
feat: added CTooltip component.
1 parent 2f54f1e commit 803eded

File tree

3 files changed

+165
-0
lines changed

3 files changed

+165
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"chart.js": "^2.7.3",
6161
"core-js": "^2.5.7",
6262
"popper.js": "^1.14.6",
63+
"tooltip.js": "^1.3.1",
6364
"vue": "^2.5.17",
6465
"vue-clickaway": "^2.2.2",
6566
"vue-functional-data-merge": "^2.0.7",

src/components/Tooltip/CTooltip.js

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import Tooltip from 'tooltip.js'
2+
export default {
3+
name: 'CTooltip',
4+
props: {
5+
targetId: {
6+
required: true,
7+
type: String,
8+
},
9+
content: {
10+
type: String,
11+
default: 'Hey <b>There</b>'
12+
},
13+
placement: {
14+
type: String,
15+
default: 'top'
16+
},
17+
popover: Boolean,
18+
popoverHeader: String,
19+
triggers: {
20+
type: [String, Array],
21+
default: 'hover focus'
22+
},
23+
delay: {
24+
type: [Number, Object],
25+
default: 0
26+
},
27+
offset: {
28+
type: Number,
29+
default: 0
30+
},
31+
boundaries: {
32+
type: String,
33+
default: 'scrollParent'
34+
},
35+
appendToBody: Boolean,
36+
active: Boolean,
37+
popperOptions: Object
38+
},
39+
data () {
40+
return {
41+
locked: this.active,
42+
el: null
43+
}
44+
},
45+
mounted () {
46+
this.createPopper()
47+
},
48+
computed: {
49+
hoverTrigger () {
50+
return this.triggers.includes('hover')
51+
},
52+
focusTrigger () {
53+
return this.triggers.includes('focus')
54+
},
55+
clickTrigger () {
56+
return this.triggers.includes('click')
57+
},
58+
tooltipTemplate () {
59+
return `<div class="tooltip bs-tooltip-auto fade show" role="tooltip">
60+
<div class="arrow"></div>
61+
<div class="tooltip-inner"></div>
62+
</div>`
63+
},
64+
popoverTemplate () {
65+
return `<div class="popover bs-popover-auto fade show" role="tooltip">
66+
<div class="arrow"></div>
67+
<h3 class="popover-header">${this.popoverHeader}</h3>
68+
<div class="popover-body"></div>
69+
</div>`
70+
},
71+
generatedTooltipConfig () {
72+
return {
73+
title: this.content,
74+
trigger: '',
75+
html: true,
76+
placement: this.placement,
77+
delay: this.delay,
78+
offset: this.offset,
79+
arrowSelector: '.arrow',
80+
innerSelector: this.popover ? '.popover-body' : '.tooltip-inner',
81+
template: this.popover ? this.popoverTemplate : this.tooltipTemplate,
82+
boundariesElement: document.getElementById(this.boundaries) || this.boundaries,
83+
container: this.appendToBody ? document.body : false,
84+
popperOptions: this.popperOptions
85+
}
86+
}
87+
},
88+
methods: {
89+
createPopper () {
90+
this.el = document.getElementById(this.targetId)
91+
this._tooltip = new Tooltip(this.el, this.generatedTooltipConfig)
92+
if (this.hoverTrigger) {
93+
this.el.addEventListener('mouseover', this.show)
94+
this.el.addEventListener('mouseout', this.mouseoutHide)
95+
}
96+
if(this.clickTrigger || this.focusTrigger)
97+
this.el.addEventListener('click', this.open)
98+
if(this.locked) {
99+
this._tooltip.show()
100+
!(this.clickTrigger || this.focusTrigger) ? this.locked = false : this.open()
101+
}
102+
},
103+
open () {
104+
this.locked = true
105+
this.show()
106+
setTimeout(() => {
107+
this.el.removeEventListener('click', this.open)
108+
document.addEventListener('click', this.close)
109+
}, 0)
110+
},
111+
close (e) {
112+
if(this.el.contains(e.target) && this.clickTrigger ||
113+
!this.el.contains(e.target) && !this.clickTrigger && this._tooltip &&
114+
!this._tooltip.popperInstance.popper.contains(e.target)) {
115+
this.locked = false
116+
this.hide()
117+
this.el.addEventListener('click', this.open)
118+
document.removeEventListener('click', this.close)
119+
}
120+
},
121+
show () {
122+
setTimeout(() => this._tooltip && this._tooltip.show(), this.delay.show || this.delay)
123+
},
124+
mouseoutHide () {
125+
if(!this.locked)
126+
this.hide()
127+
},
128+
hide () {
129+
setTimeout(() => this._tooltip && this._tooltip.hide(), this.delay.hide || this.delay)
130+
},
131+
destroyPopper () {
132+
this._tooltip.dispose()
133+
this._tooltip = null
134+
this.el.removeEventListener('mouseover', this.show)
135+
this.el.removeEventListener('mouseout', this.mouseoutHide)
136+
this.el.removeEventListener('click', this.open)
137+
document.removeEventListener('click', this.close)
138+
},
139+
resetPopper () {
140+
this.destroyPopper()
141+
setTimeout(() => this.createPopper(), 0)
142+
}
143+
},
144+
updated () {
145+
this.resetPopper()
146+
},
147+
beforeDestroy () {
148+
this.destroyPopper()
149+
},
150+
//render function is used only for watching props changes
151+
render (h) {
152+
return h('div',
153+
{ style: { display:'none !important'},
154+
value: [this.targetId, this.content, this.placement,
155+
this.popover, this.popoverHeader, this.triggers,
156+
this.delay, this.offset, this.boundaries,
157+
this.appendToBody, this.active, this.popperOptions]})
158+
}
159+
}

src/components/Tooltip/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import CTooltip from './CTooltip'
2+
3+
export {
4+
CTooltip
5+
}

0 commit comments

Comments
 (0)