forked from themesberg/flowbite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tooltip.js
130 lines (113 loc) · 3.76 KB
/
tooltip.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { createPopper } from '@popperjs/core';
const Default = {
placement: 'top',
triggerType: 'hover',
onShow: () => { },
onHide: () => { }
}
class Tooltip {
constructor(targetEl = null, triggerEl = null, options = {}) {
this._targetEl = targetEl
this._triggerEl = triggerEl
this._options = { ...Default, ...options }
this._popperInstance = this._createPopperInstace()
this._init()
}
_init() {
if (this._triggerEl) {
const triggerEvents = this._getTriggerEvents()
triggerEvents.showEvents.forEach(ev => {
this._triggerEl.addEventListener(ev, () => {
this.show()
})
})
triggerEvents.hideEvents.forEach(ev => {
this._triggerEl.addEventListener(ev, () => {
this.hide()
})
})
}
}
_createPopperInstace() {
return createPopper(this._triggerEl, this._targetEl, {
placement: this._options.placement,
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8],
},
},
],
});
}
_getTriggerEvents() {
switch (this._options.triggerType) {
case 'hover':
return {
showEvents: ['mouseenter', 'focus'],
hideEvents: ['mouseleave', 'blur']
}
case 'click':
return {
showEvents: ['click', 'focus'],
hideEvents: ['focusout', 'blur']
}
default:
return {
showEvents: ['mouseenter', 'focus'],
hideEvents: ['mouseleave', 'blur']
}
}
}
show() {
this._targetEl.classList.remove('opacity-0', 'invisible')
this._targetEl.classList.add('opacity-100', 'visible')
// Enable the event listeners
this._popperInstance.setOptions(options => ({
...options,
modifiers: [
...options.modifiers,
{ name: 'eventListeners', enabled: true },
],
}));
// Update its position
this._popperInstance.update()
// callback function
this._options.onShow(this)
}
hide() {
this._targetEl.classList.remove('opacity-100', 'visible')
this._targetEl.classList.add('opacity-0', 'invisible')
// Disable the event listeners
this._popperInstance.setOptions(options => ({
...options,
modifiers: [
...options.modifiers,
{ name: 'eventListeners', enabled: false },
],
}));
// callback function
this._options.onHide(this)
}
}
window.Tooltip = Tooltip;
function initTooltip() {
document.querySelectorAll('[data-tooltip-target]').forEach(triggerEl => {
const targetEl = document.getElementById(triggerEl.getAttribute('data-tooltip-target'))
const triggerType = triggerEl.getAttribute('data-tooltip-trigger');
const placement = triggerEl.getAttribute('data-tooltip-placement');
new Tooltip(targetEl, triggerEl, {
placement: placement ? placement : Default.placement,
triggerType: triggerType ? triggerType : Default.triggerType
})
})
}
if (document.readyState !== 'loading') {
// DOMContentLoaded event were already fired. Perform explicit initialization now
initTooltip()
} else {
// DOMContentLoaded event not yet fired, attach initialization process to it
document.addEventListener('DOMContentLoaded', initTooltip)
}
export default Tooltip