@exmg/exm-tooltip 1.1.8 → 1.1.10-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
2
|
+
type TooltipPositions = 'top' | 'right' | 'bottom' | 'left' | 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left';
|
|
2
3
|
export declare class ExmTooltipBase extends ExmgElement {
|
|
3
4
|
/**
|
|
4
5
|
* The id of the element that the tooltip is anchored to. This element
|
|
@@ -8,7 +9,7 @@ export declare class ExmTooltipBase extends ExmgElement {
|
|
|
8
9
|
/**
|
|
9
10
|
* Positions the tooltip to the top, right, bottom, left of its content.
|
|
10
11
|
*/
|
|
11
|
-
position:
|
|
12
|
+
position: TooltipPositions;
|
|
12
13
|
/**
|
|
13
14
|
* If true, no parts of the tooltip will ever be shown offscreen.
|
|
14
15
|
*/
|
|
@@ -16,16 +17,19 @@ export declare class ExmTooltipBase extends ExmgElement {
|
|
|
16
17
|
/**
|
|
17
18
|
* X axis offset from the parent's center
|
|
18
19
|
*/
|
|
19
|
-
xOffset
|
|
20
|
+
xOffset: number;
|
|
20
21
|
/**
|
|
21
22
|
* Y axis offset from the parent's center
|
|
22
23
|
*/
|
|
23
|
-
yOffset
|
|
24
|
-
|
|
24
|
+
yOffset: number;
|
|
25
|
+
private showing;
|
|
25
26
|
tooltip?: HTMLElement;
|
|
26
27
|
private _target?;
|
|
27
|
-
private
|
|
28
|
-
private
|
|
28
|
+
private _parent?;
|
|
29
|
+
private boundShow;
|
|
30
|
+
private boundHide;
|
|
31
|
+
private boundMouseMove;
|
|
32
|
+
private boundMouseLeave;
|
|
29
33
|
/**
|
|
30
34
|
* Returns the target element that this tooltip is anchored to. It is
|
|
31
35
|
* either the element given by the `for` attribute, or the immediate parent
|
|
@@ -34,15 +38,19 @@ export declare class ExmTooltipBase extends ExmgElement {
|
|
|
34
38
|
get target(): any;
|
|
35
39
|
connectedCallback(): void;
|
|
36
40
|
disconnectedCallback(): void;
|
|
37
|
-
|
|
41
|
+
protected firstUpdated(): void;
|
|
42
|
+
private handleMousemove;
|
|
43
|
+
private handleMouseleave;
|
|
44
|
+
private show;
|
|
38
45
|
/**
|
|
39
46
|
* Toggles a CSS class on or off.
|
|
40
47
|
*/
|
|
41
|
-
toggleClass
|
|
42
|
-
hide
|
|
43
|
-
updatePosition
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
private toggleClass;
|
|
49
|
+
private hide;
|
|
50
|
+
private updatePosition;
|
|
51
|
+
private addListeners;
|
|
52
|
+
private findTarget;
|
|
53
|
+
private removeListeners;
|
|
47
54
|
protected render(): import("lit-html").TemplateResult<1>;
|
|
48
55
|
}
|
|
56
|
+
export {};
|
package/dist/exm-tooltip-base.js
CHANGED
|
@@ -15,7 +15,15 @@ export class ExmTooltipBase extends ExmgElement {
|
|
|
15
15
|
* If true, no parts of the tooltip will ever be shown offscreen.
|
|
16
16
|
*/
|
|
17
17
|
this.fitToVisibleBounds = false;
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* X axis offset from the parent's center
|
|
20
|
+
*/
|
|
21
|
+
this.xOffset = 0;
|
|
22
|
+
/**
|
|
23
|
+
* Y axis offset from the parent's center
|
|
24
|
+
*/
|
|
25
|
+
this.yOffset = 0;
|
|
26
|
+
this.showing = false;
|
|
19
27
|
}
|
|
20
28
|
/**
|
|
21
29
|
* Returns the target element that this tooltip is anchored to. It is
|
|
@@ -26,39 +34,72 @@ export class ExmTooltipBase extends ExmgElement {
|
|
|
26
34
|
const parentNode = this.parentNode;
|
|
27
35
|
// If the parentNode is a document fragment, then we need to use the host.
|
|
28
36
|
const ownerRoot = parentNode.getRootNode();
|
|
29
|
-
let target;
|
|
30
37
|
if (this.for) {
|
|
31
|
-
|
|
38
|
+
return ownerRoot.querySelector('#' + this.for);
|
|
32
39
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
target = parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? ownerRoot.host : parentNode;
|
|
36
|
-
}
|
|
37
|
-
return target;
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
return parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? ownerRoot.host : parentNode;
|
|
38
42
|
}
|
|
39
43
|
connectedCallback() {
|
|
40
44
|
super.connectedCallback();
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
45
|
+
this.boundShow = this.show.bind(this);
|
|
46
|
+
this.boundHide = this.hide.bind(this);
|
|
47
|
+
this.boundMouseMove = this.handleMousemove.bind(this);
|
|
48
|
+
this.boundMouseLeave = this.handleMouseleave.bind(this);
|
|
43
49
|
this.setAttribute('role', 'tooltip');
|
|
44
50
|
this.setAttribute('tabindex', '-1');
|
|
45
|
-
this.
|
|
51
|
+
this.findTarget();
|
|
46
52
|
}
|
|
47
53
|
disconnectedCallback() {
|
|
48
|
-
this.
|
|
54
|
+
this.removeListeners();
|
|
49
55
|
super.disconnectedCallback();
|
|
50
56
|
}
|
|
51
|
-
|
|
57
|
+
firstUpdated() {
|
|
58
|
+
this.findTarget();
|
|
59
|
+
this.updatePosition();
|
|
60
|
+
}
|
|
61
|
+
handleMousemove(event) {
|
|
62
|
+
if (!this._target || !this._parent) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const mousePosition = {
|
|
66
|
+
x: event.clientX,
|
|
67
|
+
y: event.clientY,
|
|
68
|
+
};
|
|
69
|
+
const targetRect = this._target.getBoundingClientRect();
|
|
70
|
+
if (mousePosition.x < targetRect.left - 1 || mousePosition.x > targetRect.right + 1) {
|
|
71
|
+
this._parent.removeEventListener('mousemove', this.boundMouseMove);
|
|
72
|
+
this.hide();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (mousePosition.y < targetRect.top - 1 || mousePosition.y > targetRect.bottom + 1) {
|
|
76
|
+
this._parent.removeEventListener('mousemove', this.boundMouseMove);
|
|
77
|
+
this.hide();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
handleMouseleave() {
|
|
82
|
+
if (!this._target || !this._parent) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.hide();
|
|
86
|
+
this._parent.removeEventListener('mouseout', this.boundMouseLeave);
|
|
87
|
+
this._parent.removeEventListener('mousemove', this.boundMouseMove);
|
|
88
|
+
}
|
|
89
|
+
show(event) {
|
|
90
|
+
event.stopPropagation();
|
|
52
91
|
// If the tooltip is already showing, there's nothing to do.
|
|
53
|
-
if (this.
|
|
92
|
+
if (this.showing || !this._parent) {
|
|
54
93
|
return;
|
|
55
94
|
}
|
|
95
|
+
this._parent.addEventListener('mousemove', this.boundMouseMove);
|
|
96
|
+
this._parent.addEventListener('mouseout', this.boundMouseLeave);
|
|
56
97
|
if (this.textContent.trim() === '') {
|
|
57
98
|
// Check if effective children are also empty
|
|
58
99
|
let allChildrenEmpty = true;
|
|
59
100
|
const effectiveChildren = this.childNodes;
|
|
60
|
-
for (
|
|
61
|
-
if (
|
|
101
|
+
for (const child of effectiveChildren) {
|
|
102
|
+
if (child.textContent.trim() !== '') {
|
|
62
103
|
allChildrenEmpty = false;
|
|
63
104
|
break;
|
|
64
105
|
}
|
|
@@ -67,7 +108,7 @@ export class ExmTooltipBase extends ExmgElement {
|
|
|
67
108
|
return;
|
|
68
109
|
}
|
|
69
110
|
}
|
|
70
|
-
this.
|
|
111
|
+
this.showing = true;
|
|
71
112
|
this.toggleClass('hidden', false, this.tooltip);
|
|
72
113
|
this.updatePosition();
|
|
73
114
|
}
|
|
@@ -88,19 +129,19 @@ export class ExmTooltipBase extends ExmgElement {
|
|
|
88
129
|
}
|
|
89
130
|
hide() {
|
|
90
131
|
// If the tooltip is already hidden, there's nothing to do.
|
|
91
|
-
if (!this.
|
|
132
|
+
if (!this.showing) {
|
|
92
133
|
return;
|
|
93
134
|
}
|
|
94
|
-
this.
|
|
135
|
+
this.showing = false;
|
|
95
136
|
this.toggleClass('hidden', true, this.tooltip);
|
|
96
137
|
}
|
|
97
138
|
updatePosition() {
|
|
98
|
-
if (!this._target || !this.offsetParent) {
|
|
139
|
+
if (!this._target || !this.offsetParent || !this.tooltip) {
|
|
99
140
|
return;
|
|
100
141
|
}
|
|
101
142
|
const parentRect = this.offsetParent.getBoundingClientRect();
|
|
102
143
|
const targetRect = this._target.getBoundingClientRect();
|
|
103
|
-
const thisRect = this.getBoundingClientRect();
|
|
144
|
+
const thisRect = this.tooltip.getBoundingClientRect();
|
|
104
145
|
const horizontalCenterOffset = (targetRect.width - thisRect.width) / 2;
|
|
105
146
|
const verticalCenterOffset = (targetRect.height - thisRect.height) / 2;
|
|
106
147
|
const targetLeft = targetRect.left - parentRect.left;
|
|
@@ -124,13 +165,25 @@ export class ExmTooltipBase extends ExmgElement {
|
|
|
124
165
|
tooltipLeft = targetLeft + targetRect.width;
|
|
125
166
|
tooltipTop = targetTop + verticalCenterOffset;
|
|
126
167
|
break;
|
|
168
|
+
case 'top-left':
|
|
169
|
+
tooltipLeft = targetLeft;
|
|
170
|
+
tooltipTop = targetTop - thisRect.height;
|
|
171
|
+
break;
|
|
172
|
+
case 'bottom-left':
|
|
173
|
+
tooltipLeft = targetLeft;
|
|
174
|
+
tooltipTop = targetTop + targetRect.height;
|
|
175
|
+
break;
|
|
176
|
+
case 'top-right':
|
|
177
|
+
tooltipLeft = targetLeft - thisRect.width + targetRect.width;
|
|
178
|
+
tooltipTop = targetTop - thisRect.height;
|
|
179
|
+
break;
|
|
180
|
+
case 'bottom-right':
|
|
181
|
+
tooltipLeft = targetLeft - thisRect.width + targetRect.width;
|
|
182
|
+
tooltipTop = targetTop + targetRect.height;
|
|
183
|
+
break;
|
|
127
184
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
if (this.yOffset !== undefined) {
|
|
132
|
-
tooltipTop += this.yOffset;
|
|
133
|
-
}
|
|
185
|
+
tooltipLeft += this.xOffset;
|
|
186
|
+
tooltipTop += this.yOffset;
|
|
134
187
|
if (this.fitToVisibleBounds) {
|
|
135
188
|
// Clip the left/right side
|
|
136
189
|
if (parentRect.left + tooltipLeft + thisRect.width > window.innerWidth) {
|
|
@@ -156,47 +209,46 @@ export class ExmTooltipBase extends ExmgElement {
|
|
|
156
209
|
this.style.top = tooltipTop + 'px';
|
|
157
210
|
}
|
|
158
211
|
}
|
|
159
|
-
|
|
212
|
+
addListeners() {
|
|
160
213
|
if (this._target) {
|
|
161
|
-
this._target.addEventListener('mouseenter', this.
|
|
162
|
-
this._target.addEventListener('focus', this.
|
|
163
|
-
this._target.addEventListener('
|
|
164
|
-
this._target.addEventListener('
|
|
165
|
-
this._target.addEventListener('tap', this._boundHide);
|
|
214
|
+
this._target.addEventListener('mouseenter', this.boundShow);
|
|
215
|
+
this._target.addEventListener('focus', this.boundShow);
|
|
216
|
+
this._target.addEventListener('blur', this.boundHide);
|
|
217
|
+
this._target.addEventListener('tap', this.boundHide);
|
|
166
218
|
}
|
|
167
|
-
this.addEventListener('mouseenter', this.
|
|
219
|
+
this.addEventListener('mouseenter', this.boundShow);
|
|
168
220
|
}
|
|
169
|
-
|
|
170
|
-
this.
|
|
221
|
+
findTarget() {
|
|
222
|
+
this.removeListeners();
|
|
171
223
|
this._target = this.target;
|
|
172
|
-
this.
|
|
224
|
+
this._parent = this.parentNode;
|
|
225
|
+
this.addListeners();
|
|
173
226
|
}
|
|
174
|
-
|
|
227
|
+
removeListeners() {
|
|
175
228
|
if (this._target) {
|
|
176
|
-
this._target.removeEventListener('mouseenter', this.
|
|
177
|
-
this._target.removeEventListener('focus', this.
|
|
178
|
-
this._target.removeEventListener('
|
|
179
|
-
this._target.removeEventListener('
|
|
180
|
-
this._target.removeEventListener('tap', this._boundHide);
|
|
229
|
+
this._target.removeEventListener('mouseenter', this.boundShow);
|
|
230
|
+
this._target.removeEventListener('focus', this.boundShow);
|
|
231
|
+
this._target.removeEventListener('blur', this.boundHide);
|
|
232
|
+
this._target.removeEventListener('tap', this.boundHide);
|
|
181
233
|
}
|
|
182
|
-
this.removeEventListener('mouseenter', this.
|
|
234
|
+
this.removeEventListener('mouseenter', this.boundShow);
|
|
183
235
|
}
|
|
184
236
|
render() {
|
|
185
237
|
return html `
|
|
186
|
-
<
|
|
238
|
+
<section id="tooltip" class="hidden">
|
|
187
239
|
<slot></slot>
|
|
188
|
-
</
|
|
240
|
+
</section>
|
|
189
241
|
`;
|
|
190
242
|
}
|
|
191
243
|
}
|
|
192
244
|
__decorate([
|
|
193
245
|
property({ type: String }),
|
|
194
246
|
observer(function () {
|
|
195
|
-
this.
|
|
247
|
+
this.findTarget();
|
|
196
248
|
})
|
|
197
249
|
], ExmTooltipBase.prototype, "for", void 0);
|
|
198
250
|
__decorate([
|
|
199
|
-
property(
|
|
251
|
+
property()
|
|
200
252
|
], ExmTooltipBase.prototype, "position", void 0);
|
|
201
253
|
__decorate([
|
|
202
254
|
property({ type: Boolean })
|
|
@@ -209,7 +261,7 @@ __decorate([
|
|
|
209
261
|
], ExmTooltipBase.prototype, "yOffset", void 0);
|
|
210
262
|
__decorate([
|
|
211
263
|
state()
|
|
212
|
-
], ExmTooltipBase.prototype, "
|
|
264
|
+
], ExmTooltipBase.prototype, "showing", void 0);
|
|
213
265
|
__decorate([
|
|
214
266
|
query('#tooltip')
|
|
215
267
|
], ExmTooltipBase.prototype, "tooltip", void 0);
|
|
@@ -22,7 +22,9 @@ export const style = css `
|
|
|
22
22
|
padding: var(--exm-tooltip-padding, 8px);
|
|
23
23
|
border-radius: var(--exm-tooltip-border-radius, 2px);
|
|
24
24
|
min-width: var(--exm-tooltip-min-width, initial);
|
|
25
|
+
width: max-content;
|
|
25
26
|
transition: opacity 0.5s;
|
|
27
|
+
z-index: 10;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
#tooltip.hidden {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exmg/exm-tooltip",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10-alpha.19+20be399",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
".": "./dist/index.js",
|
|
10
10
|
"./exm-tooltip.js": "./dist/exm-tooltip.js"
|
|
11
11
|
},
|
|
12
|
-
"
|
|
13
|
-
"@exmg/lit-base": "^3.0.
|
|
14
|
-
"
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@exmg/lit-base": "^3.0.3",
|
|
14
|
+
"@material/web": "^2.2.0",
|
|
15
|
+
"lit": "^3.2.1",
|
|
15
16
|
"tslib": "^2.6.2"
|
|
16
17
|
},
|
|
17
18
|
"files": [
|
|
@@ -31,12 +32,9 @@
|
|
|
31
32
|
"directory": "packages/exm-tooltip"
|
|
32
33
|
},
|
|
33
34
|
"license": "MIT",
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@exmg/lit-cli": "1.1.13"
|
|
36
|
-
},
|
|
37
35
|
"scripts": {},
|
|
38
36
|
"publishConfig": {
|
|
39
37
|
"access": "public"
|
|
40
38
|
},
|
|
41
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "20be399892ecc54f71f080f17a677a370d9f2b9c"
|
|
42
40
|
}
|