@exmg/exm-tooltip 1.1.9 → 1.1.10-alpha.26

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.
@@ -0,0 +1,56 @@
1
+ import { ExmgElement } from '@exmg/lit-base/index.js';
2
+ type TooltipPositions = 'top' | 'right' | 'bottom' | 'left' | 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left';
3
+ export declare class ExmTooltipBase extends ExmgElement {
4
+ /**
5
+ * The id of the element that the tooltip is anchored to. This element
6
+ * must be a sibling of the tooltip.
7
+ */
8
+ for?: string;
9
+ /**
10
+ * Positions the tooltip to the top, right, bottom, left of its content.
11
+ */
12
+ position: TooltipPositions;
13
+ /**
14
+ * If true, no parts of the tooltip will ever be shown offscreen.
15
+ */
16
+ fitToVisibleBounds: boolean;
17
+ /**
18
+ * X axis offset from the parent's center
19
+ */
20
+ xOffset: number;
21
+ /**
22
+ * Y axis offset from the parent's center
23
+ */
24
+ yOffset: number;
25
+ private showing;
26
+ tooltip?: HTMLElement;
27
+ private _target?;
28
+ private _parent?;
29
+ private boundShow;
30
+ private boundHide;
31
+ private boundMouseMove;
32
+ private boundMouseLeave;
33
+ /**
34
+ * Returns the target element that this tooltip is anchored to. It is
35
+ * either the element given by the `for` attribute, or the immediate parent
36
+ * of the tooltip.
37
+ */
38
+ get target(): any;
39
+ connectedCallback(): void;
40
+ disconnectedCallback(): void;
41
+ protected firstUpdated(): void;
42
+ private handleMousemove;
43
+ private handleMouseleave;
44
+ private show;
45
+ /**
46
+ * Toggles a CSS class on or off.
47
+ */
48
+ private toggleClass;
49
+ private hide;
50
+ private updatePosition;
51
+ private addListeners;
52
+ private findTarget;
53
+ private removeListeners;
54
+ protected render(): import("lit-html").TemplateResult<1>;
55
+ }
56
+ export {};
@@ -0,0 +1,268 @@
1
+ import { __decorate } from "tslib";
2
+ import { html } from 'lit';
3
+ import { property } from 'lit/decorators/property.js';
4
+ import { state } from 'lit/decorators.js';
5
+ import { query } from 'lit/decorators/query.js';
6
+ import { ExmgElement, observer } from '@exmg/lit-base/index.js';
7
+ export class ExmTooltipBase extends ExmgElement {
8
+ constructor() {
9
+ super(...arguments);
10
+ /**
11
+ * Positions the tooltip to the top, right, bottom, left of its content.
12
+ */
13
+ this.position = 'bottom';
14
+ /**
15
+ * If true, no parts of the tooltip will ever be shown offscreen.
16
+ */
17
+ this.fitToVisibleBounds = false;
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;
27
+ }
28
+ /**
29
+ * Returns the target element that this tooltip is anchored to. It is
30
+ * either the element given by the `for` attribute, or the immediate parent
31
+ * of the tooltip.
32
+ */
33
+ get target() {
34
+ const parentNode = this.parentNode;
35
+ // If the parentNode is a document fragment, then we need to use the host.
36
+ const ownerRoot = parentNode.getRootNode();
37
+ if (this.for) {
38
+ return ownerRoot.querySelector('#' + this.for);
39
+ }
40
+ // @ts-ignore
41
+ return parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? ownerRoot.host : parentNode;
42
+ }
43
+ connectedCallback() {
44
+ super.connectedCallback();
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);
49
+ this.setAttribute('role', 'tooltip');
50
+ this.setAttribute('tabindex', '-1');
51
+ this.findTarget();
52
+ }
53
+ disconnectedCallback() {
54
+ this.removeListeners();
55
+ super.disconnectedCallback();
56
+ }
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();
91
+ // If the tooltip is already showing, there's nothing to do.
92
+ if (this.showing || !this._parent) {
93
+ return;
94
+ }
95
+ this._parent.addEventListener('mousemove', this.boundMouseMove);
96
+ this._parent.addEventListener('mouseout', this.boundMouseLeave);
97
+ if (this.textContent.trim() === '') {
98
+ // Check if effective children are also empty
99
+ let allChildrenEmpty = true;
100
+ const effectiveChildren = this.childNodes;
101
+ for (const child of effectiveChildren) {
102
+ if (child.textContent.trim() !== '') {
103
+ allChildrenEmpty = false;
104
+ break;
105
+ }
106
+ }
107
+ if (allChildrenEmpty) {
108
+ return;
109
+ }
110
+ }
111
+ this.showing = true;
112
+ this.toggleClass('hidden', false, this.tooltip);
113
+ this.updatePosition();
114
+ }
115
+ /**
116
+ * Toggles a CSS class on or off.
117
+ */
118
+ toggleClass(name, bool, node) {
119
+ node = /** @type {Element} */ node || this;
120
+ if (arguments.length == 1) {
121
+ bool = !node.classList.contains(name);
122
+ }
123
+ if (bool) {
124
+ node.classList.add(name);
125
+ }
126
+ else {
127
+ node.classList.remove(name);
128
+ }
129
+ }
130
+ hide() {
131
+ // If the tooltip is already hidden, there's nothing to do.
132
+ if (!this.showing) {
133
+ return;
134
+ }
135
+ this.showing = false;
136
+ this.toggleClass('hidden', true, this.tooltip);
137
+ }
138
+ updatePosition() {
139
+ if (!this._target || !this.offsetParent || !this.tooltip) {
140
+ return;
141
+ }
142
+ const parentRect = this.offsetParent.getBoundingClientRect();
143
+ const targetRect = this._target.getBoundingClientRect();
144
+ const thisRect = this.tooltip.getBoundingClientRect();
145
+ const horizontalCenterOffset = (targetRect.width - thisRect.width) / 2;
146
+ const verticalCenterOffset = (targetRect.height - thisRect.height) / 2;
147
+ const targetLeft = targetRect.left - parentRect.left;
148
+ const targetTop = targetRect.top - parentRect.top;
149
+ let tooltipLeft = 0;
150
+ let tooltipTop = 0;
151
+ switch (this.position) {
152
+ case 'top':
153
+ tooltipLeft = targetLeft + horizontalCenterOffset;
154
+ tooltipTop = targetTop - thisRect.height;
155
+ break;
156
+ case 'bottom':
157
+ tooltipLeft = targetLeft + horizontalCenterOffset;
158
+ tooltipTop = targetTop + targetRect.height;
159
+ break;
160
+ case 'left':
161
+ tooltipLeft = targetLeft - thisRect.width;
162
+ tooltipTop = targetTop + verticalCenterOffset;
163
+ break;
164
+ case 'right':
165
+ tooltipLeft = targetLeft + targetRect.width;
166
+ tooltipTop = targetTop + verticalCenterOffset;
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;
184
+ }
185
+ tooltipLeft += this.xOffset;
186
+ tooltipTop += this.yOffset;
187
+ if (this.fitToVisibleBounds) {
188
+ // Clip the left/right side
189
+ if (parentRect.left + tooltipLeft + thisRect.width > window.innerWidth) {
190
+ this.style.right = '0px';
191
+ this.style.left = 'auto';
192
+ }
193
+ else {
194
+ this.style.left = Math.max(0, tooltipLeft) + 'px';
195
+ this.style.right = 'auto';
196
+ }
197
+ // Clip the top/bottom side.
198
+ if (parentRect.top + tooltipTop + thisRect.height > window.innerHeight) {
199
+ this.style.bottom = parentRect.height + 'px';
200
+ this.style.top = 'auto';
201
+ }
202
+ else {
203
+ this.style.top = Math.max(-parentRect.top, tooltipTop) + 'px';
204
+ this.style.bottom = 'auto';
205
+ }
206
+ }
207
+ else {
208
+ this.style.left = tooltipLeft + 'px';
209
+ this.style.top = tooltipTop + 'px';
210
+ }
211
+ }
212
+ addListeners() {
213
+ if (this._target) {
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);
218
+ }
219
+ this.addEventListener('mouseenter', this.boundShow);
220
+ }
221
+ findTarget() {
222
+ this.removeListeners();
223
+ this._target = this.target;
224
+ this._parent = this.parentNode;
225
+ this.addListeners();
226
+ }
227
+ removeListeners() {
228
+ if (this._target) {
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);
233
+ }
234
+ this.removeEventListener('mouseenter', this.boundShow);
235
+ }
236
+ render() {
237
+ return html `
238
+ <section id="tooltip" class="hidden">
239
+ <slot></slot>
240
+ </section>
241
+ `;
242
+ }
243
+ }
244
+ __decorate([
245
+ property({ type: String }),
246
+ observer(function () {
247
+ this.findTarget();
248
+ })
249
+ ], ExmTooltipBase.prototype, "for", void 0);
250
+ __decorate([
251
+ property()
252
+ ], ExmTooltipBase.prototype, "position", void 0);
253
+ __decorate([
254
+ property({ type: Boolean })
255
+ ], ExmTooltipBase.prototype, "fitToVisibleBounds", void 0);
256
+ __decorate([
257
+ property({ type: Number })
258
+ ], ExmTooltipBase.prototype, "xOffset", void 0);
259
+ __decorate([
260
+ property({ type: Number })
261
+ ], ExmTooltipBase.prototype, "yOffset", void 0);
262
+ __decorate([
263
+ state()
264
+ ], ExmTooltipBase.prototype, "showing", void 0);
265
+ __decorate([
266
+ query('#tooltip')
267
+ ], ExmTooltipBase.prototype, "tooltip", void 0);
268
+ //# sourceMappingURL=exm-tooltip-base.js.map
@@ -0,0 +1,33 @@
1
+ import { ExmTooltipBase } from './exm-tooltip-base.js';
2
+ /**
3
+ * `exm-tooltip`
4
+ * Example:
5
+ * ```html
6
+ * <div style="position:relative;">
7
+ * <button id="styledBtn">Test</button>
8
+ * <exm-tooltip for="styledBtn">the name means "different lizard"</exm-tooltip>
9
+ * </div>
10
+ * ```
11
+ *
12
+ * ### Styling
13
+ * The following custom properties and mixins are available for styling:
14
+ *
15
+ * Custom property | Description | Default
16
+ * ----------------|-------------|----------
17
+ * `--exm-tooltip-font-size` | Font size of tooltip text | 10px
18
+ * `--exm-tooltip-line-height` | Text line height | 1
19
+ * `--exm-tooltip-background` | Background color | #616161
20
+ * `--exm-tooltip-opacity` | Tooltip opacity | 0.9
21
+ * `--exm-tooltip-text-color` | Font color | white
22
+ * `--exm-tooltip-padding` | Container padding | 8px
23
+ * `--exm-tooltip-border-radius` | Container border radius | 2px
24
+ * `--exm-tooltip-min-width` | Breadcrumb container background color | initial
25
+ */
26
+ export declare class ExmTooltip extends ExmTooltipBase {
27
+ static styles: import("lit").CSSResult;
28
+ }
29
+ declare global {
30
+ interface HTMLElementTagNameMap {
31
+ 'exm-tooltip': ExmTooltip;
32
+ }
33
+ }
@@ -0,0 +1,36 @@
1
+ import { __decorate } from "tslib";
2
+ import { customElement } from 'lit/decorators/custom-element.js';
3
+ import { style } from './styles/exm-tooltip-styles-css.js';
4
+ import { ExmTooltipBase } from './exm-tooltip-base.js';
5
+ /**
6
+ * `exm-tooltip`
7
+ * Example:
8
+ * ```html
9
+ * <div style="position:relative;">
10
+ * <button id="styledBtn">Test</button>
11
+ * <exm-tooltip for="styledBtn">the name means "different lizard"</exm-tooltip>
12
+ * </div>
13
+ * ```
14
+ *
15
+ * ### Styling
16
+ * The following custom properties and mixins are available for styling:
17
+ *
18
+ * Custom property | Description | Default
19
+ * ----------------|-------------|----------
20
+ * `--exm-tooltip-font-size` | Font size of tooltip text | 10px
21
+ * `--exm-tooltip-line-height` | Text line height | 1
22
+ * `--exm-tooltip-background` | Background color | #616161
23
+ * `--exm-tooltip-opacity` | Tooltip opacity | 0.9
24
+ * `--exm-tooltip-text-color` | Font color | white
25
+ * `--exm-tooltip-padding` | Container padding | 8px
26
+ * `--exm-tooltip-border-radius` | Container border radius | 2px
27
+ * `--exm-tooltip-min-width` | Breadcrumb container background color | initial
28
+ */
29
+ let ExmTooltip = class ExmTooltip extends ExmTooltipBase {
30
+ };
31
+ ExmTooltip.styles = style;
32
+ ExmTooltip = __decorate([
33
+ customElement('exm-tooltip')
34
+ ], ExmTooltip);
35
+ export { ExmTooltip };
36
+ //# sourceMappingURL=exm-tooltip.js.map
@@ -0,0 +1,3 @@
1
+ export { ExmTooltip } from './exm-tooltip.js';
2
+ export { ExmTooltipBase } from './exm-tooltip-base.js';
3
+ export { style as tooltipStyles } from './styles/exm-tooltip-styles-css.js';
@@ -0,0 +1,4 @@
1
+ export { ExmTooltip } from './exm-tooltip.js';
2
+ export { ExmTooltipBase } from './exm-tooltip-base.js';
3
+ export { style as tooltipStyles } from './styles/exm-tooltip-styles-css.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ export declare const style: import("lit").CSSResult;
@@ -0,0 +1,35 @@
1
+ import { css } from 'lit';
2
+ export const style = css `
3
+ :host {
4
+ display: block;
5
+ position: absolute;
6
+ outline: none;
7
+ z-index: var(--exm-tooltip-z-index, 1002);
8
+ -moz-user-select: none;
9
+ -ms-user-select: none;
10
+ -webkit-user-select: none;
11
+ user-select: none;
12
+ cursor: default;
13
+ }
14
+
15
+ #tooltip {
16
+ display: block;
17
+ outline: none;
18
+ font-size: var(--exm-tooltip-font-size, 12px);
19
+ line-height: var(--exm-tooltip-line-height, 14px);
20
+ background-color: var(--exm-tooltip-background-color, var(--md-sys-color-inverse-surface, #333));
21
+ color: var(--exm-tooltip-color, var(--md-sys-color-inverse-on-surface, white));
22
+ padding: var(--exm-tooltip-padding, 8px);
23
+ border-radius: var(--exm-tooltip-border-radius, 2px);
24
+ min-width: var(--exm-tooltip-min-width, initial);
25
+ width: max-content;
26
+ transition: opacity 0.5s;
27
+ z-index: 10;
28
+ }
29
+
30
+ #tooltip.hidden {
31
+ opacity: 0;
32
+ display: none;
33
+ }
34
+ `;
35
+ //# sourceMappingURL=exm-tooltip-styles-css.js.map
@@ -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: string;
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?: number;
20
+ xOffset: number;
20
21
  /**
21
22
  * Y axis offset from the parent's center
22
23
  */
23
- yOffset?: number;
24
- _showing: boolean;
24
+ yOffset: number;
25
+ private showing;
25
26
  tooltip?: HTMLElement;
26
27
  private _target?;
27
- private _boundShow;
28
- private _boundHide;
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
- show(): void;
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(name: string, bool: boolean, node: HTMLElement): void;
42
- hide(): void;
43
- updatePosition(): void;
44
- _addListeners(): void;
45
- _findTarget(): void;
46
- _removeListeners(): void;
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 {};
@@ -1,10 +1,11 @@
1
- import { __decorate } from "tslib";
1
+ import { __decorate } from 'tslib';
2
2
  import { html } from 'lit';
3
3
  import { property } from 'lit/decorators/property.js';
4
4
  import { state } from 'lit/decorators.js';
5
5
  import { query } from 'lit/decorators/query.js';
6
- import { ExmgElement, observer } from '@exmg/lit-base/index.js';
7
- export class ExmTooltipBase extends ExmgElement {
6
+ import { observer, ExmgElement } from '@exmg/lit-base/index.js';
7
+
8
+ class ExmTooltipBase extends ExmgElement {
8
9
  constructor() {
9
10
  super(...arguments);
10
11
  /**
@@ -15,7 +16,15 @@ export class ExmTooltipBase extends ExmgElement {
15
16
  * If true, no parts of the tooltip will ever be shown offscreen.
16
17
  */
17
18
  this.fitToVisibleBounds = false;
18
- this._showing = false;
19
+ /**
20
+ * X axis offset from the parent's center
21
+ */
22
+ this.xOffset = 0;
23
+ /**
24
+ * Y axis offset from the parent's center
25
+ */
26
+ this.yOffset = 0;
27
+ this.showing = false;
19
28
  }
20
29
  /**
21
30
  * Returns the target element that this tooltip is anchored to. It is
@@ -26,39 +35,72 @@ export class ExmTooltipBase extends ExmgElement {
26
35
  const parentNode = this.parentNode;
27
36
  // If the parentNode is a document fragment, then we need to use the host.
28
37
  const ownerRoot = parentNode.getRootNode();
29
- let target;
30
38
  if (this.for) {
31
- target = ownerRoot.querySelector('#' + this.for);
39
+ return ownerRoot.querySelector('#' + this.for);
32
40
  }
33
- else {
34
- // @ts-ignore
35
- target = parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? ownerRoot.host : parentNode;
36
- }
37
- return target;
41
+ // @ts-ignore
42
+ return parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? ownerRoot.host : parentNode;
38
43
  }
39
44
  connectedCallback() {
40
45
  super.connectedCallback();
41
- this._boundShow = this.show.bind(this);
42
- this._boundHide = this.hide.bind(this);
46
+ this.boundShow = this.show.bind(this);
47
+ this.boundHide = this.hide.bind(this);
48
+ this.boundMouseMove = this.handleMousemove.bind(this);
49
+ this.boundMouseLeave = this.handleMouseleave.bind(this);
43
50
  this.setAttribute('role', 'tooltip');
44
51
  this.setAttribute('tabindex', '-1');
45
- this._findTarget();
52
+ this.findTarget();
46
53
  }
47
54
  disconnectedCallback() {
48
- this._removeListeners();
55
+ this.removeListeners();
49
56
  super.disconnectedCallback();
50
57
  }
51
- show() {
58
+ firstUpdated() {
59
+ this.findTarget();
60
+ this.updatePosition();
61
+ }
62
+ handleMousemove(event) {
63
+ if (!this._target || !this._parent) {
64
+ return;
65
+ }
66
+ const mousePosition = {
67
+ x: event.clientX,
68
+ y: event.clientY,
69
+ };
70
+ const targetRect = this._target.getBoundingClientRect();
71
+ if (mousePosition.x < targetRect.left - 1 || mousePosition.x > targetRect.right + 1) {
72
+ this._parent.removeEventListener('mousemove', this.boundMouseMove);
73
+ this.hide();
74
+ return;
75
+ }
76
+ if (mousePosition.y < targetRect.top - 1 || mousePosition.y > targetRect.bottom + 1) {
77
+ this._parent.removeEventListener('mousemove', this.boundMouseMove);
78
+ this.hide();
79
+ return;
80
+ }
81
+ }
82
+ handleMouseleave() {
83
+ if (!this._target || !this._parent) {
84
+ return;
85
+ }
86
+ this.hide();
87
+ this._parent.removeEventListener('mouseout', this.boundMouseLeave);
88
+ this._parent.removeEventListener('mousemove', this.boundMouseMove);
89
+ }
90
+ show(event) {
91
+ event.stopPropagation();
52
92
  // If the tooltip is already showing, there's nothing to do.
53
- if (this._showing) {
93
+ if (this.showing || !this._parent) {
54
94
  return;
55
95
  }
96
+ this._parent.addEventListener('mousemove', this.boundMouseMove);
97
+ this._parent.addEventListener('mouseout', this.boundMouseLeave);
56
98
  if (this.textContent.trim() === '') {
57
99
  // Check if effective children are also empty
58
100
  let allChildrenEmpty = true;
59
101
  const effectiveChildren = this.childNodes;
60
- for (let i = 0; i < effectiveChildren.length; i++) {
61
- if (effectiveChildren[i].textContent.trim() !== '') {
102
+ for (const child of effectiveChildren) {
103
+ if (child.textContent.trim() !== '') {
62
104
  allChildrenEmpty = false;
63
105
  break;
64
106
  }
@@ -67,7 +109,7 @@ export class ExmTooltipBase extends ExmgElement {
67
109
  return;
68
110
  }
69
111
  }
70
- this._showing = true;
112
+ this.showing = true;
71
113
  this.toggleClass('hidden', false, this.tooltip);
72
114
  this.updatePosition();
73
115
  }
@@ -88,19 +130,19 @@ export class ExmTooltipBase extends ExmgElement {
88
130
  }
89
131
  hide() {
90
132
  // If the tooltip is already hidden, there's nothing to do.
91
- if (!this._showing) {
133
+ if (!this.showing) {
92
134
  return;
93
135
  }
94
- this._showing = false;
136
+ this.showing = false;
95
137
  this.toggleClass('hidden', true, this.tooltip);
96
138
  }
97
139
  updatePosition() {
98
- if (!this._target || !this.offsetParent) {
140
+ if (!this._target || !this.offsetParent || !this.tooltip) {
99
141
  return;
100
142
  }
101
143
  const parentRect = this.offsetParent.getBoundingClientRect();
102
144
  const targetRect = this._target.getBoundingClientRect();
103
- const thisRect = this.getBoundingClientRect();
145
+ const thisRect = this.tooltip.getBoundingClientRect();
104
146
  const horizontalCenterOffset = (targetRect.width - thisRect.width) / 2;
105
147
  const verticalCenterOffset = (targetRect.height - thisRect.height) / 2;
106
148
  const targetLeft = targetRect.left - parentRect.left;
@@ -124,13 +166,25 @@ export class ExmTooltipBase extends ExmgElement {
124
166
  tooltipLeft = targetLeft + targetRect.width;
125
167
  tooltipTop = targetTop + verticalCenterOffset;
126
168
  break;
169
+ case 'top-left':
170
+ tooltipLeft = targetLeft;
171
+ tooltipTop = targetTop - thisRect.height;
172
+ break;
173
+ case 'bottom-left':
174
+ tooltipLeft = targetLeft;
175
+ tooltipTop = targetTop + targetRect.height;
176
+ break;
177
+ case 'top-right':
178
+ tooltipLeft = targetLeft - thisRect.width + targetRect.width;
179
+ tooltipTop = targetTop - thisRect.height;
180
+ break;
181
+ case 'bottom-right':
182
+ tooltipLeft = targetLeft - thisRect.width + targetRect.width;
183
+ tooltipTop = targetTop + targetRect.height;
184
+ break;
127
185
  }
128
- if (this.xOffset !== undefined) {
129
- tooltipLeft += this.xOffset;
130
- }
131
- if (this.yOffset !== undefined) {
132
- tooltipTop += this.yOffset;
133
- }
186
+ tooltipLeft += this.xOffset;
187
+ tooltipTop += this.yOffset;
134
188
  if (this.fitToVisibleBounds) {
135
189
  // Clip the left/right side
136
190
  if (parentRect.left + tooltipLeft + thisRect.width > window.innerWidth) {
@@ -156,47 +210,46 @@ export class ExmTooltipBase extends ExmgElement {
156
210
  this.style.top = tooltipTop + 'px';
157
211
  }
158
212
  }
159
- _addListeners() {
213
+ addListeners() {
160
214
  if (this._target) {
161
- this._target.addEventListener('mouseenter', this._boundShow);
162
- this._target.addEventListener('focus', this._boundShow);
163
- this._target.addEventListener('mouseleave', this._boundHide);
164
- this._target.addEventListener('blur', this._boundHide);
165
- this._target.addEventListener('tap', this._boundHide);
215
+ this._target.addEventListener('mouseenter', this.boundShow);
216
+ this._target.addEventListener('focus', this.boundShow);
217
+ this._target.addEventListener('blur', this.boundHide);
218
+ this._target.addEventListener('tap', this.boundHide);
166
219
  }
167
- this.addEventListener('mouseenter', this._boundHide);
220
+ this.addEventListener('mouseenter', this.boundShow);
168
221
  }
169
- _findTarget() {
170
- this._removeListeners();
222
+ findTarget() {
223
+ this.removeListeners();
171
224
  this._target = this.target;
172
- this._addListeners();
225
+ this._parent = this.parentNode;
226
+ this.addListeners();
173
227
  }
174
- _removeListeners() {
228
+ removeListeners() {
175
229
  if (this._target) {
176
- this._target.removeEventListener('mouseenter', this._boundShow);
177
- this._target.removeEventListener('focus', this._boundShow);
178
- this._target.removeEventListener('mouseleave', this._boundHide);
179
- this._target.removeEventListener('blur', this._boundHide);
180
- this._target.removeEventListener('tap', this._boundHide);
230
+ this._target.removeEventListener('mouseenter', this.boundShow);
231
+ this._target.removeEventListener('focus', this.boundShow);
232
+ this._target.removeEventListener('blur', this.boundHide);
233
+ this._target.removeEventListener('tap', this.boundHide);
181
234
  }
182
- this.removeEventListener('mouseenter', this._boundHide);
235
+ this.removeEventListener('mouseenter', this.boundShow);
183
236
  }
184
237
  render() {
185
238
  return html `
186
- <div id="tooltip" class="hidden">
239
+ <section id="tooltip" class="hidden">
187
240
  <slot></slot>
188
- </div>
241
+ </section>
189
242
  `;
190
243
  }
191
244
  }
192
245
  __decorate([
193
246
  property({ type: String }),
194
247
  observer(function () {
195
- this._findTarget();
248
+ this.findTarget();
196
249
  })
197
250
  ], ExmTooltipBase.prototype, "for", void 0);
198
251
  __decorate([
199
- property({ type: String })
252
+ property()
200
253
  ], ExmTooltipBase.prototype, "position", void 0);
201
254
  __decorate([
202
255
  property({ type: Boolean })
@@ -209,8 +262,10 @@ __decorate([
209
262
  ], ExmTooltipBase.prototype, "yOffset", void 0);
210
263
  __decorate([
211
264
  state()
212
- ], ExmTooltipBase.prototype, "_showing", void 0);
265
+ ], ExmTooltipBase.prototype, "showing", void 0);
213
266
  __decorate([
214
267
  query('#tooltip')
215
268
  ], ExmTooltipBase.prototype, "tooltip", void 0);
216
- //# sourceMappingURL=exm-tooltip-base.js.map
269
+
270
+ export { ExmTooltipBase };
271
+ //# sourceMappingURL=exm-tooltip-base.js.map
@@ -1,7 +1,8 @@
1
- import { __decorate } from "tslib";
1
+ import { __decorate } from 'tslib';
2
2
  import { customElement } from 'lit/decorators/custom-element.js';
3
3
  import { style } from './styles/exm-tooltip-styles-css.js';
4
4
  import { ExmTooltipBase } from './exm-tooltip-base.js';
5
+
5
6
  /**
6
7
  * `exm-tooltip`
7
8
  * Example:
@@ -32,5 +33,6 @@ ExmTooltip.styles = style;
32
33
  ExmTooltip = __decorate([
33
34
  customElement('exm-tooltip')
34
35
  ], ExmTooltip);
36
+
35
37
  export { ExmTooltip };
36
- //# sourceMappingURL=exm-tooltip.js.map
38
+ //# sourceMappingURL=exm-tooltip.js.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { ExmTooltip } from './exm-tooltip.js';
2
2
  export { ExmTooltipBase } from './exm-tooltip-base.js';
3
3
  export { style as tooltipStyles } from './styles/exm-tooltip-styles-css.js';
4
- //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -1,5 +1,6 @@
1
1
  import { css } from 'lit';
2
- export const style = css `
2
+
3
+ const style = css `
3
4
  :host {
4
5
  display: block;
5
6
  position: absolute;
@@ -22,7 +23,9 @@ export const style = css `
22
23
  padding: var(--exm-tooltip-padding, 8px);
23
24
  border-radius: var(--exm-tooltip-border-radius, 2px);
24
25
  min-width: var(--exm-tooltip-min-width, initial);
26
+ width: max-content;
25
27
  transition: opacity 0.5s;
28
+ z-index: 10;
26
29
  }
27
30
 
28
31
  #tooltip.hidden {
@@ -30,4 +33,6 @@ export const style = css `
30
33
  display: none;
31
34
  }
32
35
  `;
33
- //# sourceMappingURL=exm-tooltip-styles-css.js.map
36
+
37
+ export { style };
38
+ //# sourceMappingURL=exm-tooltip-styles-css.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exmg/exm-tooltip",
3
- "version": "1.1.9",
3
+ "version": "1.1.10-alpha.26+dffd4ec",
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
- "dependencies": {
13
- "@exmg/lit-base": "^3.0.0",
14
- "lit": "^3.0.0",
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": "ac876ab3f3d6d83a43a3944c052c8e71de300832"
39
+ "gitHead": "dffd4ecb68fdeb061f4e8ad585af221bfb0f8e8b"
42
40
  }