@aquera/nile-elements 0.1.34 → 0.1.35-beta-1.0
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.
- package/README.md +22 -8
- package/demo/index.css +7 -4
- package/demo/index.html +20 -36
- package/dist/{fixture-161dee0b.cjs.js → fixture-d5b55278.cjs.js} +3 -3
- package/dist/fixture-d5b55278.cjs.js.map +1 -0
- package/dist/{fixture-372df3b0.esm.js → fixture-df8b52d7.esm.js} +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/internal/animate.cjs.js +1 -1
- package/dist/internal/animate.cjs.js.map +1 -1
- package/dist/internal/animate.esm.js +1 -1
- package/dist/nile-accordion/nile-accordian.test.cjs.js +1 -1
- package/dist/nile-accordion/nile-accordian.test.esm.js +1 -1
- package/dist/nile-auto-complete/nile-auto-complete.test.cjs.js +1 -1
- package/dist/nile-auto-complete/nile-auto-complete.test.esm.js +1 -1
- package/dist/nile-avatar/nile-avatar.test.cjs.js +1 -1
- package/dist/nile-avatar/nile-avatar.test.esm.js +1 -1
- package/dist/nile-badge/nile-badge.test.cjs.js +1 -1
- package/dist/nile-badge/nile-badge.test.esm.js +1 -1
- package/dist/nile-button/nile-button.test.cjs.js +1 -1
- package/dist/nile-button/nile-button.test.esm.js +1 -1
- package/dist/nile-button-toggle-group/nile-button-toggle-group.test.cjs.js +1 -1
- package/dist/nile-button-toggle-group/nile-button-toggle-group.test.esm.js +1 -1
- package/dist/nile-calendar/nile-calendar.test.cjs.js +1 -1
- package/dist/nile-calendar/nile-calendar.test.esm.js +1 -1
- package/dist/nile-card/nile-card.test.cjs.js +1 -1
- package/dist/nile-card/nile-card.test.esm.js +1 -1
- package/dist/nile-checkbox/nile-checkbox.test.cjs.js +1 -1
- package/dist/nile-checkbox/nile-checkbox.test.esm.js +1 -1
- package/dist/nile-chip/nile-chip.test.cjs.js +1 -1
- package/dist/nile-chip/nile-chip.test.esm.js +1 -1
- package/dist/nile-code-editor/extensionSetup.cjs.js +1 -1
- package/dist/nile-code-editor/extensionSetup.cjs.js.map +1 -1
- package/dist/nile-code-editor/extensionSetup.esm.js +1 -1
- package/dist/nile-code-editor/nile-code-editor.cjs.js +1 -1
- package/dist/nile-code-editor/nile-code-editor.cjs.js.map +1 -1
- package/dist/nile-code-editor/nile-code-editor.esm.js +2 -2
- package/dist/nile-dialog/nile-dialog.test.cjs.js +1 -1
- package/dist/nile-dialog/nile-dialog.test.esm.js +1 -1
- package/dist/nile-drawer/nile-drawer.test.cjs.js +1 -1
- package/dist/nile-drawer/nile-drawer.test.esm.js +1 -1
- package/dist/nile-dropdown/nile-dropdown.test.cjs.js +1 -1
- package/dist/nile-dropdown/nile-dropdown.test.esm.js +1 -1
- package/dist/nile-empty-state/nile-empty-state.test.cjs.js +1 -1
- package/dist/nile-empty-state/nile-empty-state.test.esm.js +1 -1
- package/dist/nile-error-message/nile-error-message.cjs.js +1 -1
- package/dist/nile-error-message/nile-error-message.cjs.js.map +1 -1
- package/dist/nile-error-message/nile-error-message.css.cjs.js +1 -1
- package/dist/nile-error-message/nile-error-message.css.cjs.js.map +1 -1
- package/dist/nile-error-message/nile-error-message.css.esm.js +6 -4
- package/dist/nile-error-message/nile-error-message.esm.js +4 -4
- package/dist/nile-error-message/nile-error-message.test.cjs.js +1 -1
- package/dist/nile-error-message/nile-error-message.test.esm.js +1 -1
- package/dist/nile-error-notification/nile-error-notification.css.cjs.js +1 -1
- package/dist/nile-error-notification/nile-error-notification.css.cjs.js.map +1 -1
- package/dist/nile-error-notification/nile-error-notification.css.esm.js +1 -1
- package/dist/nile-form-group/nile-form-group.test.cjs.js +1 -1
- package/dist/nile-form-group/nile-form-group.test.esm.js +1 -1
- package/dist/nile-form-help-text/nile-form-help-text.test.cjs.js +1 -1
- package/dist/nile-form-help-text/nile-form-help-text.test.esm.js +1 -1
- package/dist/nile-hero/nile-hero.test.cjs.js +1 -1
- package/dist/nile-hero/nile-hero.test.esm.js +1 -1
- package/dist/nile-icon/nile-icon.test.cjs.js +1 -1
- package/dist/nile-icon/nile-icon.test.esm.js +1 -1
- package/dist/nile-input/nile-input.test.cjs.js +1 -1
- package/dist/nile-input/nile-input.test.esm.js +1 -1
- package/dist/nile-link/nile-link.test.cjs.js +1 -1
- package/dist/nile-link/nile-link.test.esm.js +1 -1
- package/dist/nile-loader/nile-loader.test.cjs.js +1 -1
- package/dist/nile-loader/nile-loader.test.esm.js +1 -1
- package/dist/nile-popover/nile-popover.test.cjs.js +1 -1
- package/dist/nile-popover/nile-popover.test.esm.js +1 -1
- package/dist/nile-popup/nile-popup.test.cjs.js +1 -1
- package/dist/nile-popup/nile-popup.test.esm.js +1 -1
- package/dist/nile-progress-bar/nile-progress-bar.css.cjs.js +1 -1
- package/dist/nile-progress-bar/nile-progress-bar.css.cjs.js.map +1 -1
- package/dist/nile-progress-bar/nile-progress-bar.css.esm.js +1 -0
- package/dist/nile-progress-bar/nile-progress-bar.test.cjs.js +1 -1
- package/dist/nile-progress-bar/nile-progress-bar.test.esm.js +1 -1
- package/dist/nile-radio/nile-radio.test.cjs.js +1 -1
- package/dist/nile-radio/nile-radio.test.esm.js +1 -1
- package/dist/nile-radio-group/nile-radio-group.test.cjs.js +1 -1
- package/dist/nile-radio-group/nile-radio-group.test.esm.js +1 -1
- package/dist/nile-select/nile-select.test.cjs.js +1 -1
- package/dist/nile-select/nile-select.test.esm.js +1 -1
- package/dist/nile-slide-toggle/nile-slide-toggle.test.cjs.js +1 -1
- package/dist/nile-slide-toggle/nile-slide-toggle.test.esm.js +1 -1
- package/dist/nile-tab-group/nile-tab-group.test.cjs.js +1 -1
- package/dist/nile-tab-group/nile-tab-group.test.esm.js +1 -1
- package/dist/nile-table/nile-table.cjs.js.map +1 -1
- package/dist/nile-textarea/nile-textarea.test.cjs.js +1 -1
- package/dist/nile-textarea/nile-textarea.test.esm.js +1 -1
- package/dist/nile-tooltip/index.cjs.js +1 -1
- package/dist/nile-tooltip/index.esm.js +1 -1
- package/dist/nile-tooltip/nile-tooltip-utils.cjs.js +2 -0
- package/dist/nile-tooltip/nile-tooltip-utils.cjs.js.map +1 -0
- package/dist/nile-tooltip/nile-tooltip-utils.esm.js +1 -0
- package/dist/nile-tooltip/nile-tooltip.cjs.js +1 -1
- package/dist/nile-tooltip/nile-tooltip.cjs.js.map +1 -1
- package/dist/nile-tooltip/nile-tooltip.css.cjs.js +1 -1
- package/dist/nile-tooltip/nile-tooltip.css.cjs.js.map +1 -1
- package/dist/nile-tooltip/nile-tooltip.css.esm.js +78 -45
- package/dist/nile-tooltip/nile-tooltip.esm.js +23 -28
- package/dist/nile-tooltip/nile-tooltip.test.cjs.js +2 -0
- package/dist/nile-tooltip/nile-tooltip.test.cjs.js.map +1 -0
- package/dist/nile-tooltip/nile-tooltip.test.esm.js +47 -0
- package/dist/src/nile-code-editor/extensionSetup.d.ts +2 -1
- package/dist/src/nile-code-editor/extensionSetup.js +8 -0
- package/dist/src/nile-code-editor/extensionSetup.js.map +1 -1
- package/dist/src/nile-code-editor/nile-code-editor.d.ts +2 -0
- package/dist/src/nile-code-editor/nile-code-editor.js +12 -3
- package/dist/src/nile-code-editor/nile-code-editor.js.map +1 -1
- package/dist/src/nile-error-message/nile-error-message.css.js +6 -4
- package/dist/src/nile-error-message/nile-error-message.css.js.map +1 -1
- package/dist/src/nile-error-message/nile-error-message.d.ts +4 -0
- package/dist/src/nile-error-message/nile-error-message.js +20 -0
- package/dist/src/nile-error-message/nile-error-message.js.map +1 -1
- package/dist/src/nile-error-notification/nile-error-notification.css.js +1 -1
- package/dist/src/nile-error-notification/nile-error-notification.css.js.map +1 -1
- package/dist/src/nile-progress-bar/nile-progress-bar.css.js +1 -0
- package/dist/src/nile-progress-bar/nile-progress-bar.css.js.map +1 -1
- package/dist/src/nile-table/nile-table.js.map +1 -1
- package/dist/src/nile-tooltip/nile-tooltip-utils.d.ts +18 -0
- package/dist/src/nile-tooltip/nile-tooltip-utils.js +216 -0
- package/dist/src/nile-tooltip/nile-tooltip-utils.js.map +1 -0
- package/dist/src/nile-tooltip/nile-tooltip.css.js +76 -43
- package/dist/src/nile-tooltip/nile-tooltip.css.js.map +1 -1
- package/dist/src/nile-tooltip/nile-tooltip.d.ts +24 -46
- package/dist/src/nile-tooltip/nile-tooltip.js +235 -232
- package/dist/src/nile-tooltip/nile-tooltip.js.map +1 -1
- package/dist/src/nile-tooltip/nile-tooltip.test.d.ts +1 -0
- package/dist/src/nile-tooltip/nile-tooltip.test.js +148 -0
- package/dist/src/nile-tooltip/nile-tooltip.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/nile-code-editor/extensionSetup.ts +13 -1
- package/src/nile-code-editor/nile-code-editor.ts +9 -4
- package/src/nile-error-message/nile-error-message.css.ts +6 -4
- package/src/nile-error-message/nile-error-message.ts +18 -0
- package/src/nile-error-notification/nile-error-notification.css.ts +1 -1
- package/src/nile-progress-bar/nile-progress-bar.css.ts +1 -0
- package/src/nile-table/nile-table.ts +2 -2
- package/src/nile-tooltip/nile-tooltip-utils.ts +271 -0
- package/src/nile-tooltip/nile-tooltip.css.ts +77 -44
- package/src/nile-tooltip/nile-tooltip.test.ts +168 -0
- package/src/nile-tooltip/nile-tooltip.ts +268 -230
- package/vscode-html-custom-data.json +103 -93
- package/dist/fixture-161dee0b.cjs.js.map +0 -1
@@ -1,61 +1,28 @@
|
|
1
|
+
|
1
2
|
/**
|
2
3
|
* Copyright Aquera Inc 2023
|
3
4
|
*
|
4
5
|
* This source code is licensed under the BSD-3-Clause license found in the
|
5
6
|
* LICENSE file in the root directory of this source tree.
|
6
7
|
*/
|
7
|
-
|
8
|
-
import { LitElement, CSSResultArray, TemplateResult } from 'lit';
|
9
|
-
import { styles } from './nile-tooltip.css';
|
10
|
-
import '../nile-popup/nile-popup';
|
11
|
-
import { animateTo, parseDuration, stopAnimations } from '../internal/animate';
|
12
|
-
import { classMap } from 'lit/directives/class-map.js';
|
8
|
+
import { LitElement, html, css, CSSResultArray } from 'lit';
|
13
9
|
import { customElement, property, query } from 'lit/decorators.js';
|
14
|
-
import {
|
15
|
-
|
16
|
-
setDefaultAnimation,
|
17
|
-
} from '../utilities/animation-registry';
|
18
|
-
import { html } from 'lit';
|
19
|
-
// import { LocalizeController } from '../utilities/localize';
|
20
|
-
import { waitForEvent } from '../internal/event';
|
21
|
-
import { watch } from '../internal/watch';
|
10
|
+
import { classMap } from 'lit/directives/class-map.js';
|
11
|
+
import { styles } from './nile-tooltip.css';
|
22
12
|
import NileElement from '../internal/nile-element';
|
23
|
-
import
|
24
|
-
|
13
|
+
import { isInViewport, getValidTooltipPosition, getCaretPosition } from './nile-tooltip-utils';
|
14
|
+
|
25
15
|
/**
|
26
|
-
* Nile
|
16
|
+
* Nile tooltip component.
|
27
17
|
*
|
28
18
|
* @tag nile-tooltip
|
29
19
|
*
|
30
20
|
*/
|
31
21
|
@customElement('nile-tooltip')
|
32
22
|
export class NileTooltip extends NileElement {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
*/
|
37
|
-
public static get styles(): CSSResultArray {
|
38
|
-
return [styles];
|
39
|
-
}
|
40
|
-
|
41
|
-
private hoverTimeout: number;
|
42
|
-
// private readonly localize = new LocalizeController(this);
|
43
|
-
|
44
|
-
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
45
|
-
@query('.tooltip__body') body: HTMLElement;
|
46
|
-
@query('nile-popup') popup: NilePopup;
|
47
|
-
|
48
|
-
/** The tooltip's content. If you need to display HTML, use the `content` slot instead. */
|
49
|
-
@property({ type: String, reflect: true }) content = '';
|
50
|
-
|
51
|
-
/** Size Property to decide the tool tip size */
|
52
|
-
@property({ reflect: true }) size: 'small' | 'large' = 'small';
|
53
|
-
|
54
|
-
/**
|
55
|
-
* The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip
|
56
|
-
* inside of the viewport.
|
57
|
-
*/
|
58
|
-
@property() placement:
|
23
|
+
@property({ type: String }) content = '';
|
24
|
+
@property({ type: String })
|
25
|
+
placement:
|
59
26
|
| 'top'
|
60
27
|
| 'top-start'
|
61
28
|
| 'top-end'
|
@@ -68,255 +35,326 @@ export class NileTooltip extends NileElement {
|
|
68
35
|
| 'left'
|
69
36
|
| 'left-start'
|
70
37
|
| 'left-end' = 'top';
|
71
|
-
|
72
|
-
/** Disables the tooltip so it won't show when triggered. */
|
73
38
|
@property({ type: Boolean, reflect: true }) disabled = false;
|
74
|
-
|
75
|
-
/** The distance in pixels from which to offset the tooltip away from its target. */
|
76
|
-
@property({ type: Number }) distance = 8;
|
77
|
-
|
78
|
-
/** Indicates whether or not the tooltip is open. You can use this in lieu of the show/hide methods. */
|
79
39
|
@property({ type: Boolean, reflect: true }) open = false;
|
80
|
-
|
81
|
-
/** The distance in pixels from which to offset the tooltip along its target. */
|
82
|
-
@property({ type: Number }) skidding = 0;
|
83
|
-
|
84
40
|
/**
|
85
41
|
* Controls how the tooltip is activated. Possible options include `click`, `hover`, `focus`, and `manual`. Multiple
|
86
42
|
* options can be passed by separating them with a space. When manual is used, the tooltip must be activated
|
87
43
|
* programmatically.
|
88
44
|
*/
|
89
45
|
@property() trigger = 'hover focus';
|
46
|
+
@property({ type: Number }) distance = 8;
|
47
|
+
private readonly SHIFT_OFFSET = 16;
|
48
|
+
/** The distance in pixels from which to offset the tooltip along its target. */
|
49
|
+
@property({ type: Number }) skidding = 0;
|
50
|
+
@property({ type: Boolean, reflect: true }) hoist = false;
|
90
51
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
52
|
+
@query('.tooltip') tooltip!: HTMLElement;
|
53
|
+
@query('.trigger-container') triggerContainer!: HTMLElement;
|
54
|
+
@query('.tooltip-caret') caret!: HTMLElement;
|
55
|
+
@query('slot[name="content"]') tooltipSlot!: HTMLSlotElement;
|
56
|
+
|
57
|
+
private hasTooltipSlot = false;
|
58
|
+
private hoverTimeout: number = 0;
|
59
|
+
private caretSize = 6;
|
60
|
+
private originalPlacement: string = this.placement;
|
61
|
+
|
62
|
+
public static get styles(): CSSResultArray {
|
63
|
+
return [styles];
|
64
|
+
}
|
97
65
|
|
98
66
|
connectedCallback() {
|
99
67
|
super.connectedCallback();
|
100
|
-
this.
|
101
|
-
|
102
|
-
|
103
|
-
this.handleKeyDown = this.handleKeyDown.bind(this);
|
104
|
-
this.handleMouseOver = this.handleMouseOver.bind(this);
|
105
|
-
this.handleMouseOut = this.handleMouseOut.bind(this);
|
106
|
-
|
107
|
-
this.updateComplete.then(() => {
|
108
|
-
this.addEventListener('blur', this.handleBlur, true);
|
109
|
-
this.addEventListener('focus', this.handleFocus, true);
|
110
|
-
this.addEventListener('click', this.handleClick);
|
111
|
-
this.addEventListener('keydown', this.handleKeyDown);
|
112
|
-
this.addEventListener('mouseover', this.handleMouseOver);
|
113
|
-
this.addEventListener('mouseout', this.handleMouseOut);
|
114
|
-
});
|
68
|
+
this.originalPlacement = this.placement;
|
69
|
+
window.addEventListener('resize', this.updateTooltipPosition);
|
70
|
+
window.addEventListener('scroll', this.updateTooltipPosition, true);
|
115
71
|
}
|
116
72
|
|
117
|
-
|
118
|
-
|
73
|
+
updated(changedProps: Map<string, unknown>) {
|
74
|
+
super.updated?.(changedProps);
|
75
|
+
|
76
|
+
const validPlacements = [
|
77
|
+
'top', 'top-start', 'top-end',
|
78
|
+
'right', 'right-start', 'right-end',
|
79
|
+
'bottom', 'bottom-start', 'bottom-end',
|
80
|
+
'left', 'left-start', 'left-end'
|
81
|
+
];
|
82
|
+
|
83
|
+
if (!validPlacements.includes(this.placement)) {
|
84
|
+
console.warn(`[nile-tooltip] Invalid placement "${this.placement}", defaulting to "bottom".`);
|
85
|
+
this.placement = 'top';
|
86
|
+
}
|
119
87
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
88
|
+
if (!validPlacements.includes(this.originalPlacement)) {
|
89
|
+
this.originalPlacement = 'top';
|
90
|
+
}
|
91
|
+
|
92
|
+
if (changedProps.has('open') && this.open) {
|
93
|
+
this.updateComplete.then(() => {
|
94
|
+
requestAnimationFrame(() => {
|
95
|
+
this.updateTooltipPosition();
|
96
|
+
});
|
97
|
+
});
|
124
98
|
}
|
125
99
|
}
|
126
100
|
|
127
101
|
disconnectedCallback() {
|
128
102
|
super.disconnectedCallback();
|
129
|
-
|
130
|
-
|
131
|
-
this.removeEventListener('click', this.handleClick);
|
132
|
-
this.removeEventListener('keydown', this.handleKeyDown);
|
133
|
-
this.removeEventListener('mouseover', this.handleMouseOver);
|
134
|
-
this.removeEventListener('mouseout', this.handleMouseOut);
|
103
|
+
window.removeEventListener('resize', this.updateTooltipPosition);
|
104
|
+
window.removeEventListener('scroll', this.updateTooltipPosition, true);
|
135
105
|
}
|
136
106
|
|
137
|
-
private
|
138
|
-
|
139
|
-
|
140
|
-
|
107
|
+
private handleTooltipSlotChange() {
|
108
|
+
const nodes = this.tooltipSlot.assignedNodes({ flatten: true });
|
109
|
+
this.hasTooltipSlot = nodes.length > 0;
|
110
|
+
this.requestUpdate();
|
141
111
|
}
|
142
112
|
|
143
|
-
private
|
144
|
-
if (this.
|
145
|
-
|
146
|
-
|
147
|
-
} else {
|
148
|
-
this.show();
|
149
|
-
}
|
113
|
+
private updateTooltipPosition = () => {
|
114
|
+
if (!isInViewport(this.triggerContainer)) {
|
115
|
+
this.open = false;
|
116
|
+
return;
|
150
117
|
}
|
151
|
-
}
|
152
118
|
|
153
|
-
|
154
|
-
|
155
|
-
|
119
|
+
const triggerRect = this.triggerContainer.getBoundingClientRect();
|
120
|
+
const tooltipRect = this.tooltip.getBoundingClientRect();
|
121
|
+
const viewportWidth = window.innerWidth;
|
122
|
+
const viewportHeight = window.innerHeight;
|
123
|
+
|
124
|
+
|
125
|
+
let { top, left, placement } = getValidTooltipPosition(
|
126
|
+
triggerRect,
|
127
|
+
tooltipRect,
|
128
|
+
this.originalPlacement,
|
129
|
+
this.distance,
|
130
|
+
this.skidding,
|
131
|
+
this.caretSize,
|
132
|
+
viewportWidth,
|
133
|
+
viewportHeight
|
134
|
+
);
|
135
|
+
|
136
|
+
// FallBack Positions
|
137
|
+
|
138
|
+
// Bottom
|
139
|
+
if (this.originalPlacement.startsWith('bottom')) {
|
140
|
+
const availableSpaceBelow = viewportHeight - triggerRect.bottom;
|
141
|
+
if (availableSpaceBelow < tooltipRect.height + this.distance) {
|
142
|
+
let newPlacement: typeof this.originalPlacement = 'top';
|
143
|
+
if (this.originalPlacement === 'bottom-start') {
|
144
|
+
newPlacement = 'top';
|
145
|
+
} else if (this.originalPlacement === 'bottom-end') {
|
146
|
+
newPlacement = 'top';
|
147
|
+
}
|
148
|
+
|
149
|
+
const newPosition = getValidTooltipPosition(
|
150
|
+
triggerRect,
|
151
|
+
tooltipRect,
|
152
|
+
newPlacement,
|
153
|
+
this.distance,
|
154
|
+
this.skidding,
|
155
|
+
this.caretSize,
|
156
|
+
viewportWidth,
|
157
|
+
viewportHeight
|
158
|
+
);
|
159
|
+
top = newPosition.top;
|
160
|
+
left = newPosition.left;
|
161
|
+
placement = newPosition.placement;
|
162
|
+
}
|
156
163
|
}
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if (this.
|
162
|
-
|
163
|
-
this.
|
164
|
+
// Top
|
165
|
+
if (this.originalPlacement.startsWith('top')) {
|
166
|
+
const availableSpaceAbove = triggerRect.top;
|
167
|
+
const availableSpaceBelow = viewportHeight - triggerRect.bottom;
|
168
|
+
if (availableSpaceAbove < tooltipRect.height + this.distance && availableSpaceBelow >= tooltipRect.height + this.distance) {
|
169
|
+
let newPlacement: typeof this.originalPlacement = 'bottom';
|
170
|
+
if (this.originalPlacement === 'top-start') {
|
171
|
+
newPlacement = 'bottom-start';
|
172
|
+
} else if (this.originalPlacement === 'top-end') {
|
173
|
+
newPlacement = 'bottom-end';
|
174
|
+
}
|
175
|
+
|
176
|
+
const newPosition = getValidTooltipPosition(
|
177
|
+
triggerRect,
|
178
|
+
tooltipRect,
|
179
|
+
newPlacement,
|
180
|
+
this.distance,
|
181
|
+
this.skidding,
|
182
|
+
this.caretSize,
|
183
|
+
viewportWidth,
|
184
|
+
viewportHeight
|
185
|
+
);
|
186
|
+
top = newPosition.top;
|
187
|
+
left = newPosition.left;
|
188
|
+
placement = newPosition.placement;
|
164
189
|
}
|
165
190
|
}
|
166
191
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
192
|
+
// Left
|
193
|
+
if (this.originalPlacement.startsWith('left')) {
|
194
|
+
const availableSpaceLeft = triggerRect.left;
|
195
|
+
const availableSpaceRight = viewportWidth - triggerRect.right;
|
196
|
+
if (availableSpaceLeft < tooltipRect.width + this.distance && availableSpaceRight >= tooltipRect.width + this.distance) {
|
197
|
+
let newPlacement: typeof this.originalPlacement = 'right';
|
198
|
+
if (this.originalPlacement === 'left-start') {
|
199
|
+
newPlacement = 'right-start';
|
200
|
+
} else if (this.originalPlacement === 'left-end') {
|
201
|
+
newPlacement = 'right-end';
|
202
|
+
}
|
203
|
+
|
204
|
+
const newPosition = getValidTooltipPosition(
|
205
|
+
triggerRect,
|
206
|
+
tooltipRect,
|
207
|
+
newPlacement,
|
208
|
+
this.distance,
|
209
|
+
this.skidding,
|
210
|
+
this.caretSize,
|
211
|
+
viewportWidth,
|
212
|
+
viewportHeight
|
171
213
|
);
|
172
|
-
|
173
|
-
|
214
|
+
top = newPosition.top;
|
215
|
+
left = newPosition.left;
|
216
|
+
placement = newPosition.placement;
|
174
217
|
}
|
175
218
|
}
|
176
219
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
220
|
+
// Right
|
221
|
+
if (this.originalPlacement.startsWith('right')) {
|
222
|
+
const availableSpaceRight = viewportWidth - triggerRect.right;
|
223
|
+
const availableSpaceLeft = triggerRect.left;
|
224
|
+
if (availableSpaceRight < tooltipRect.width + this.distance && availableSpaceLeft >= tooltipRect.width + this.distance) {
|
225
|
+
let newPlacement: typeof this.originalPlacement = 'left';
|
226
|
+
if (this.originalPlacement === 'right-start') {
|
227
|
+
newPlacement = 'left-start';
|
228
|
+
} else if (this.originalPlacement === 'right-end') {
|
229
|
+
newPlacement = 'left-end';
|
230
|
+
}
|
231
|
+
|
232
|
+
const newPosition = getValidTooltipPosition(
|
233
|
+
triggerRect,
|
234
|
+
tooltipRect,
|
235
|
+
newPlacement,
|
236
|
+
this.distance,
|
237
|
+
this.skidding,
|
238
|
+
this.caretSize,
|
239
|
+
viewportWidth,
|
240
|
+
viewportHeight
|
181
241
|
);
|
182
|
-
|
183
|
-
|
242
|
+
top = newPosition.top;
|
243
|
+
left = newPosition.left;
|
244
|
+
placement = newPosition.placement;
|
184
245
|
}
|
185
246
|
}
|
186
247
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
248
|
+
this.setAttribute('placement', placement);
|
249
|
+
this.tooltip.style.top = `${top}px`;
|
250
|
+
this.tooltip.style.left = `${left}px`;
|
251
|
+
|
252
|
+
const { caretLeft, caretTop } = getCaretPosition({
|
253
|
+
placement,
|
254
|
+
tooltipRect,
|
255
|
+
triggerRect,
|
256
|
+
caretSize: this.caretSize,
|
257
|
+
left,
|
258
|
+
top
|
259
|
+
});
|
191
260
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
if (this.disabled) {
|
196
|
-
return;
|
197
|
-
}
|
261
|
+
this.caret.style.left = `${caretLeft}px`;
|
262
|
+
this.caret.style.top = `${caretTop}px`;
|
263
|
+
};
|
198
264
|
|
199
|
-
|
265
|
+
private showTooltip = () => {
|
266
|
+
const trimmedContent = this.content.trim();
|
267
|
+
if (!trimmedContent && !this.hasTooltipSlot) {
|
268
|
+
return;
|
269
|
+
}
|
270
|
+
if (!this.disabled && isInViewport(this.triggerContainer)) {
|
200
271
|
this.emit('nile-show');
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
272
|
+
this.open = true;
|
273
|
+
this.updateComplete.then(() => {
|
274
|
+
requestAnimationFrame(() => {
|
275
|
+
this.updateTooltipPosition();
|
276
|
+
this.emit('nile-after-show');
|
277
|
+
});
|
207
278
|
});
|
208
|
-
await animateTo(this.popup.popup, keyframes, options);
|
209
|
-
|
210
|
-
this.emit('nile-after-show');
|
211
279
|
} else {
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
await stopAnimations(this.body);
|
216
|
-
const { keyframes, options } = getAnimation(this, 'tooltip.hide', {
|
217
|
-
dir: '',
|
218
|
-
});
|
219
|
-
await animateTo(this.popup.popup, keyframes, options);
|
220
|
-
this.popup.active = false;
|
221
|
-
this.body.hidden = true;
|
280
|
+
this.open = false;
|
281
|
+
}
|
282
|
+
};
|
222
283
|
|
284
|
+
private hideTooltip = () => {
|
285
|
+
this.emit('nile-hide');
|
286
|
+
this.open = false;
|
287
|
+
setTimeout(() => {
|
223
288
|
this.emit('nile-after-hide');
|
224
|
-
}
|
225
|
-
}
|
289
|
+
}, 200);
|
290
|
+
};
|
226
291
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
this.popup.reposition();
|
292
|
+
private handleMouseOver = () => {
|
293
|
+
if (this.trigger.includes('hover')) {
|
294
|
+
clearTimeout(this.hoverTimeout);
|
295
|
+
this.hoverTimeout = window.setTimeout(() => this.showTooltip(), 300);
|
232
296
|
}
|
233
|
-
}
|
297
|
+
};
|
234
298
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
this.
|
299
|
+
private handleMouseOut = () => {
|
300
|
+
if (this.trigger.includes('hover')) {
|
301
|
+
clearTimeout(this.hoverTimeout);
|
302
|
+
this.hoverTimeout = window.setTimeout(() => this.hideTooltip(), 150);
|
239
303
|
}
|
240
|
-
}
|
304
|
+
};
|
241
305
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
306
|
+
private handleClick = () => {
|
307
|
+
if (this.trigger.includes('click')) {
|
308
|
+
if (!this.open && isInViewport(this.triggerContainer)) {
|
309
|
+
this.showTooltip();
|
310
|
+
} else {
|
311
|
+
this.hideTooltip();
|
312
|
+
}
|
246
313
|
}
|
314
|
+
};
|
247
315
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
/** Hides the tooltip */
|
253
|
-
async hide() {
|
254
|
-
if (!this.open) {
|
255
|
-
return undefined;
|
316
|
+
private handleFocus = () => {
|
317
|
+
if (this.trigger.includes('focus')) {
|
318
|
+
this.showTooltip();
|
256
319
|
}
|
320
|
+
};
|
321
|
+
|
257
322
|
|
258
|
-
|
259
|
-
|
260
|
-
|
323
|
+
private handleBlur = () => {
|
324
|
+
if (this.trigger.includes('focus')) {
|
325
|
+
this.hideTooltip();
|
326
|
+
}
|
327
|
+
};
|
261
328
|
|
262
329
|
render() {
|
263
330
|
return html`
|
264
|
-
<
|
265
|
-
|
266
|
-
|
267
|
-
popup:base__popup,
|
268
|
-
arrow:base__arrow
|
269
|
-
"
|
270
|
-
class=${classMap({
|
271
|
-
tooltip: true,
|
272
|
-
'tooltip--open': this.open,
|
273
|
-
})}
|
274
|
-
placement=${this.placement}
|
275
|
-
distance=${this.distance}
|
276
|
-
skidding=${this.skidding}
|
277
|
-
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
278
|
-
flip
|
279
|
-
shift
|
280
|
-
arrow
|
331
|
+
<div
|
332
|
+
class="tooltip"
|
333
|
+
id="tooltip"
|
281
334
|
>
|
282
|
-
<
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
335
|
+
<div class="tooltip-content" part="content">
|
336
|
+
<slot name="content" @slotchange=${this.handleTooltipSlotChange}></slot>
|
337
|
+
${!this.hasTooltipSlot ? html`${this.content}` : null}
|
338
|
+
</div>
|
339
|
+
<div class="tooltip-caret" style="--caret-size: ${this.caretSize}px;"></div>
|
340
|
+
</div>
|
341
|
+
|
342
|
+
<div
|
343
|
+
class="trigger-container"
|
344
|
+
tabindex="0"
|
345
|
+
@mouseover=${this.handleMouseOver}
|
346
|
+
@mouseout=${this.handleMouseOut}
|
347
|
+
@click=${this.handleClick}
|
348
|
+
@focusin=${this.handleFocus}
|
349
|
+
@focusout=${this.handleBlur}
|
350
|
+
aria-describedby="tooltip"
|
351
|
+
>
|
352
|
+
<slot></slot>
|
353
|
+
</div>
|
298
354
|
`;
|
299
355
|
}
|
300
356
|
}
|
301
357
|
|
302
|
-
setDefaultAnimation('tooltip.show', {
|
303
|
-
keyframes: [
|
304
|
-
{ opacity: 0, scale: 0.8 },
|
305
|
-
{ opacity: 1, scale: 1 },
|
306
|
-
],
|
307
|
-
options: { duration: 150, easing: 'ease' },
|
308
|
-
});
|
309
|
-
|
310
|
-
setDefaultAnimation('tooltip.hide', {
|
311
|
-
keyframes: [
|
312
|
-
{ opacity: 1, scale: 1 },
|
313
|
-
{ opacity: 0, scale: 0.8 },
|
314
|
-
],
|
315
|
-
options: { duration: 150, easing: 'ease' },
|
316
|
-
});
|
317
|
-
|
318
|
-
export default NileTooltip;
|
319
|
-
|
320
358
|
declare global {
|
321
359
|
interface HTMLElementTagNameMap {
|
322
360
|
'nile-tooltip': NileTooltip;
|