@dile/ui 3.0.3 → 3.0.5
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.
|
@@ -17,6 +17,7 @@ export class DileAccordionItem extends DileSlideDown(LitElement) {
|
|
|
17
17
|
width: 100%;
|
|
18
18
|
max-width: var(--dile-accordion-item-max-width, 100%);
|
|
19
19
|
border-radius: var(--dile-accordion-item-border-radius, none);
|
|
20
|
+
margin-bottom: var(--dile-accordion-item-margin-bottom, 1rem);
|
|
20
21
|
|
|
21
22
|
/** Others */
|
|
22
23
|
color: var(--dile-accordion-item-color, var(--dile-on-background-color, white));
|
|
@@ -53,12 +53,18 @@ export class DileChipTooltip extends LitElement {
|
|
|
53
53
|
label: { type: String },
|
|
54
54
|
message: { type: String },
|
|
55
55
|
position: { type: String },
|
|
56
|
+
icon: { type: Object },
|
|
57
|
+
arrow: { type: Boolean },
|
|
58
|
+
fadeIn: { type: Boolean },
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
constructor() {
|
|
60
63
|
super();
|
|
61
64
|
this.position = "bottom";
|
|
65
|
+
this.icon = infoIcon;
|
|
66
|
+
this.arrow = false;
|
|
67
|
+
this.fadeIn = true;
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
render() {
|
|
@@ -67,15 +73,15 @@ export class DileChipTooltip extends LitElement {
|
|
|
67
73
|
<dile-tooltip
|
|
68
74
|
tooltip="${this.message}"
|
|
69
75
|
position="${this.position}"
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
?arrow=${this.arrow}
|
|
77
|
+
?fadeIn=${this.fadeIn}
|
|
72
78
|
>
|
|
73
|
-
<span class="chip">
|
|
79
|
+
<span class="chip" role="button">
|
|
74
80
|
${this.label
|
|
75
81
|
? html`<span class="label">${this.label}</span>`
|
|
76
82
|
: ''
|
|
77
83
|
}
|
|
78
|
-
<dile-icon .icon=${
|
|
84
|
+
<dile-icon .icon=${this.icon} class="info"></dile-icon>
|
|
79
85
|
</span>
|
|
80
86
|
</dile-tooltip>
|
|
81
87
|
</div>
|
|
@@ -15,21 +15,23 @@ export class DileTooltip extends LitElement {
|
|
|
15
15
|
|
|
16
16
|
.tooltiptext {
|
|
17
17
|
visibility: hidden;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
position: fixed;
|
|
19
|
+
max-width: var(--dile-tooltip-width, 120px);
|
|
20
|
+
width: auto;
|
|
21
|
+
background-color: var(--dile-tooltip-background-color, var(--dile-primary-color, #e74c3c));
|
|
22
|
+
color: var(--dile-tooltip-color, var(--dile-on-primary-color, #fff));
|
|
21
23
|
font-size: var(--dile-tooltip-font-size, 16px);
|
|
22
24
|
text-align: var(--dile-tooltip-text-align, center);
|
|
23
25
|
border-radius: var(--dile-tooltip-border-radius, 6px);;
|
|
24
26
|
padding: var(--dile-tooltip-padding, 5px);
|
|
27
|
+
z-index: 10000;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
.tooltip-top
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
margin-left: -60px;
|
|
30
|
+
.tooltip-top,
|
|
31
|
+
.tooltip-bottom,
|
|
32
|
+
.tooltip-left,
|
|
33
|
+
.tooltip-right {
|
|
34
|
+
/* Posicionamiento manejado por JavaScript */
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
.arrow-top::after {
|
|
@@ -37,73 +39,40 @@ export class DileTooltip extends LitElement {
|
|
|
37
39
|
position: absolute;
|
|
38
40
|
top: 100%;
|
|
39
41
|
left: 50%;
|
|
40
|
-
|
|
42
|
+
transform: translateX(-50%);
|
|
41
43
|
border-width: 5px;
|
|
42
44
|
border-style: solid;
|
|
43
45
|
border-color: var(--dile-tooltip-background-color, #e74c3c) transparent transparent transparent;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
.tooltip-left {
|
|
47
|
-
position: absolute;
|
|
48
|
-
z-index: 1;
|
|
49
|
-
top: -5px;
|
|
50
|
-
right: 105%;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
48
|
.arrow-left::after {
|
|
54
49
|
content: " ";
|
|
55
50
|
position: absolute;
|
|
56
51
|
top: 50%;
|
|
57
|
-
left: 100%;
|
|
58
|
-
|
|
52
|
+
left: 100%;
|
|
53
|
+
transform: translateY(-50%);
|
|
59
54
|
border-width: 5px;
|
|
60
55
|
border-style: solid;
|
|
61
56
|
border-color: transparent transparent transparent var(--dile-tooltip-background-color, #e74c3c);
|
|
62
57
|
}
|
|
63
58
|
|
|
64
|
-
.tooltip-right {
|
|
65
|
-
position: absolute;
|
|
66
|
-
z-index: 1;
|
|
67
|
-
top: -5px;
|
|
68
|
-
left: 105%;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.arrow-right::after {
|
|
72
|
-
content: " ";
|
|
73
|
-
position: absolute;
|
|
74
|
-
top: 50%;
|
|
75
|
-
right: 100%; /* To the left of the tooltip */
|
|
76
|
-
margin-top: -5px;
|
|
77
|
-
border-width: 5px;
|
|
78
|
-
border-style: solid;
|
|
79
|
-
border-color: transparent var(--dile-tooltip-background-color, #e74c3c) transparent transparent;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
59
|
.arrow-right::after {
|
|
83
60
|
content: "";
|
|
84
61
|
position: absolute;
|
|
85
62
|
top: 50%;
|
|
86
63
|
right: 100%;
|
|
87
|
-
|
|
64
|
+
transform: translateY(-50%);
|
|
88
65
|
border-width: 5px;
|
|
89
66
|
border-style: solid;
|
|
90
67
|
border-color: transparent var(--dile-tooltip-background-color, #e74c3c) transparent transparent;
|
|
91
68
|
}
|
|
92
69
|
|
|
93
|
-
.tooltip-bottom {
|
|
94
|
-
position: absolute;
|
|
95
|
-
z-index: 1;
|
|
96
|
-
top: 150%;
|
|
97
|
-
left: 50%;
|
|
98
|
-
margin-left: -60px;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
70
|
.arrow-bottom::after {
|
|
102
71
|
content: "";
|
|
103
72
|
position: absolute;
|
|
104
73
|
bottom: 100%;
|
|
105
74
|
left: 50%;
|
|
106
|
-
|
|
75
|
+
transform: translateX(-50%);
|
|
107
76
|
border-width: 5px;
|
|
108
77
|
border-style: solid;
|
|
109
78
|
border-color: transparent transparent var(--dile-tooltip-background-color, #e74c3c) transparent;
|
|
@@ -119,6 +88,16 @@ export class DileTooltip extends LitElement {
|
|
|
119
88
|
opacity: 1;
|
|
120
89
|
}
|
|
121
90
|
|
|
91
|
+
.tooltiptext:focus-visible {
|
|
92
|
+
outline: var(--dile-tooltip-focus-outline-width, 2px) solid var(--dile-tooltip-focus-outline-color, #12c9e9);
|
|
93
|
+
outline-offset: var(--dile-tooltip-focus-outline-offset, 2px);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media (prefers-reduced-motion: reduce) {
|
|
97
|
+
.animation {
|
|
98
|
+
transition: none;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
122
101
|
`;
|
|
123
102
|
}
|
|
124
103
|
|
|
@@ -137,7 +116,10 @@ export class DileTooltip extends LitElement {
|
|
|
137
116
|
fadeIn: { type: Boolean },
|
|
138
117
|
|
|
139
118
|
/** Private property to control mouseovers and mouseouts */
|
|
140
|
-
_isMouseover: { type: Boolean }
|
|
119
|
+
_isMouseover: { type: Boolean },
|
|
120
|
+
|
|
121
|
+
/** Private property to track keyboard focus */
|
|
122
|
+
_isFocused: { type: Boolean }
|
|
141
123
|
};
|
|
142
124
|
}
|
|
143
125
|
|
|
@@ -148,6 +130,24 @@ export class DileTooltip extends LitElement {
|
|
|
148
130
|
this.arrow = false;
|
|
149
131
|
this.fadeIn = false;
|
|
150
132
|
this._isMouseover = false;
|
|
133
|
+
this._isFocused = false;
|
|
134
|
+
this._tooltipId = `dile-tooltip-${Math.random().toString(36).substr(2, 9)}`;
|
|
135
|
+
this._rafId = null;
|
|
136
|
+
// El evento scroll puede dispararse muchas veces por frame (y con
|
|
137
|
+
// capture:true, por cualquier contenedor con scroll interno), así que
|
|
138
|
+
// agrupamos los recálculos con rAF para hacer como mucho uno por frame.
|
|
139
|
+
this._boundUpdateTooltipPosition = () => {
|
|
140
|
+
if (this._rafId) return;
|
|
141
|
+
this._rafId = requestAnimationFrame(() => {
|
|
142
|
+
this._rafId = null;
|
|
143
|
+
this.updateTooltipPosition();
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
disconnectedCallback() {
|
|
149
|
+
super.disconnectedCallback();
|
|
150
|
+
this._removeReflowListeners();
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
classPosition(position) {
|
|
@@ -166,20 +166,27 @@ export class DileTooltip extends LitElement {
|
|
|
166
166
|
return fadeIn ? 'animation' : '';
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
showOrNot(isMouseover) {
|
|
170
|
-
return isMouseover ? 'show' : '';
|
|
169
|
+
showOrNot(isMouseover, isFocused) {
|
|
170
|
+
return isMouseover || isFocused ? 'show' : '';
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
render() {
|
|
174
174
|
return html`
|
|
175
175
|
<div
|
|
176
176
|
class="tooltip"
|
|
177
|
-
|
|
178
|
-
@
|
|
177
|
+
tabindex="0"
|
|
178
|
+
@mouseover=${this.doMouseover}
|
|
179
|
+
@mouseout=${this.doMouseout}
|
|
180
|
+
@focusin=${this.doFocusin}
|
|
181
|
+
@focusout=${this.doFocusout}
|
|
182
|
+
@keydown=${this.doKeydown}
|
|
179
183
|
>
|
|
180
184
|
<slot></slot>
|
|
181
185
|
<span
|
|
182
|
-
|
|
186
|
+
id="${this._tooltipId}"
|
|
187
|
+
role="tooltip"
|
|
188
|
+
?aria-hidden=${!(this._isMouseover || this._isFocused)}
|
|
189
|
+
class="tooltiptext ${this.classPosition(this.position)} ${this.arrowPosition(this.arrow, this.position)} ${this.animation(this.fadeIn)} ${this.showOrNot(this._isMouseover, this._isFocused)}"
|
|
183
190
|
>${this.tooltip}</span>
|
|
184
191
|
</div>
|
|
185
192
|
`;
|
|
@@ -192,4 +199,88 @@ export class DileTooltip extends LitElement {
|
|
|
192
199
|
doMouseout() {
|
|
193
200
|
this._isMouseover = false;
|
|
194
201
|
}
|
|
202
|
+
|
|
203
|
+
doFocusin() {
|
|
204
|
+
this._isFocused = true;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
doFocusout() {
|
|
208
|
+
this._isFocused = false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
doKeydown(event) {
|
|
212
|
+
if (event.key === 'Escape') {
|
|
213
|
+
this._isFocused = false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
updated(changedProperties) {
|
|
218
|
+
super.updated(changedProperties);
|
|
219
|
+
if (changedProperties.has('_isMouseover') || changedProperties.has('_isFocused')) {
|
|
220
|
+
if (this._isMouseover || this._isFocused) {
|
|
221
|
+
this.updateTooltipPosition();
|
|
222
|
+
// position:fixed no sigue al trigger si la página hace scroll
|
|
223
|
+
// mientras el tooltip está abierto, así que hay que recalcular a mano.
|
|
224
|
+
this._addReflowListeners();
|
|
225
|
+
} else {
|
|
226
|
+
this._removeReflowListeners();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
_addReflowListeners() {
|
|
232
|
+
window.addEventListener('scroll', this._boundUpdateTooltipPosition, { capture: true, passive: true });
|
|
233
|
+
window.addEventListener('resize', this._boundUpdateTooltipPosition);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
_removeReflowListeners() {
|
|
237
|
+
window.removeEventListener('scroll', this._boundUpdateTooltipPosition, { capture: true });
|
|
238
|
+
window.removeEventListener('resize', this._boundUpdateTooltipPosition);
|
|
239
|
+
if (this._rafId) {
|
|
240
|
+
cancelAnimationFrame(this._rafId);
|
|
241
|
+
this._rafId = null;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
updateTooltipPosition() {
|
|
246
|
+
// Esperar a que el DOM se actualice antes de calcular posiciones
|
|
247
|
+
this.updateComplete.then(() => {
|
|
248
|
+
const tooltip = this.shadowRoot.querySelector('.tooltiptext');
|
|
249
|
+
const trigger = this.shadowRoot.querySelector('.tooltip');
|
|
250
|
+
|
|
251
|
+
if (!tooltip || !trigger) return;
|
|
252
|
+
|
|
253
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
254
|
+
const gap = 5; // Espacio entre trigger y tooltip
|
|
255
|
+
|
|
256
|
+
let top, left;
|
|
257
|
+
|
|
258
|
+
switch (this.position) {
|
|
259
|
+
case 'top':
|
|
260
|
+
top = triggerRect.top - tooltip.offsetHeight - gap;
|
|
261
|
+
left = triggerRect.left + triggerRect.width / 2 - tooltip.offsetWidth / 2;
|
|
262
|
+
break;
|
|
263
|
+
case 'bottom':
|
|
264
|
+
top = triggerRect.bottom + gap;
|
|
265
|
+
left = triggerRect.left + triggerRect.width / 2 - tooltip.offsetWidth / 2;
|
|
266
|
+
break;
|
|
267
|
+
case 'left':
|
|
268
|
+
top = triggerRect.top + triggerRect.height / 2 - tooltip.offsetHeight / 2;
|
|
269
|
+
left = triggerRect.left - tooltip.offsetWidth - gap;
|
|
270
|
+
break;
|
|
271
|
+
case 'right':
|
|
272
|
+
top = triggerRect.top + triggerRect.height / 2 - tooltip.offsetHeight / 2;
|
|
273
|
+
left = triggerRect.right + gap;
|
|
274
|
+
break;
|
|
275
|
+
default:
|
|
276
|
+
top = triggerRect.top - tooltip.offsetHeight - gap;
|
|
277
|
+
left = triggerRect.left + triggerRect.width / 2 - tooltip.offsetWidth / 2;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Con position:fixed, getBoundingClientRect() ya es relativo al viewport,
|
|
281
|
+
// no hay que sumar el scroll (eso solo aplica a position:absolute).
|
|
282
|
+
tooltip.style.top = top + 'px';
|
|
283
|
+
tooltip.style.left = left + 'px';
|
|
284
|
+
});
|
|
285
|
+
}
|
|
195
286
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dile/ui",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "UI Core components from dile-components.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "6c8ffd76c5596a7fc0759685469af9ec082f412d"
|
|
31
31
|
}
|