@farm-investimentos/front-mfe-components 15.14.4 → 15.14.6
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/dist/front-mfe-components.common.js +365 -1042
- package/dist/front-mfe-components.common.js.map +1 -1
- package/dist/front-mfe-components.css +1 -1
- package/dist/front-mfe-components.umd.js +365 -1042
- package/dist/front-mfe-components.umd.js.map +1 -1
- package/dist/front-mfe-components.umd.min.js +1 -1
- package/dist/front-mfe-components.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Modal/Modal.scss +86 -85
- package/src/components/Tooltip/Tooltip.scss +90 -62
- package/src/components/Tooltip/Tooltip.stories.js +322 -158
- package/src/components/Tooltip/Tooltip.vue +265 -302
- package/src/components/Tooltip/docs/README.md +304 -0
- package/src/components/Tooltip/docs/SPECIFICATION.md +374 -0
- package/src/components/Tooltip/index.ts +16 -0
- package/src/components/Tooltip/types/tooltip.types.ts +49 -0
- package/src/components/Tooltip/utils/tooltip.utils.ts +70 -0
|
@@ -1,79 +1,58 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@mouseover="
|
|
7
|
-
@mouseout="
|
|
8
|
-
@mouseleave="
|
|
2
|
+
<div class="tooltip-container" ref="containerRef">
|
|
3
|
+
<div
|
|
4
|
+
ref="activatorRef"
|
|
5
|
+
class="tooltip-activator"
|
|
6
|
+
@mouseover="show"
|
|
7
|
+
@mouseout="hide"
|
|
8
|
+
@mouseleave="hide"
|
|
9
9
|
>
|
|
10
10
|
<slot name="activator" />
|
|
11
|
-
</
|
|
12
|
-
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'farm-tooltip__popup--visible':
|
|
18
|
-
(!externalControl && showOver) || (externalControl && toggleComponent),
|
|
19
|
-
'farm-tooltip__popup--fluid': fluid,
|
|
20
|
-
[`farm-tooltip__popup--${position}`]: position,
|
|
21
|
-
'farm-tooltip__popup--has-title': hasTitle,
|
|
22
|
-
}"
|
|
23
|
-
:style="styles"
|
|
24
|
-
@mouseout="onOut"
|
|
25
|
-
@mouseleave="onOut"
|
|
26
|
-
>
|
|
27
|
-
<div v-if="hasTitle" class="farm-tooltip__header">
|
|
28
|
-
<div class="farm-tooltip__title">
|
|
29
|
-
<slot name="title"></slot>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div v-if="isVisible" ref="tooltipRef" :class="tooltipClasses" :style="tooltipStyles">
|
|
14
|
+
<div v-if="hasTitle || showCloseButton" class="tooltip-header">
|
|
15
|
+
<div v-if="hasTitle" class="tooltip-title">
|
|
16
|
+
<slot name="title" />
|
|
30
17
|
</div>
|
|
31
|
-
<span v-if="
|
|
32
|
-
|
|
33
|
-
</span>
|
|
18
|
+
<span v-if="showCloseButton" class="tooltip-close" @click="close">×</span>
|
|
34
19
|
</div>
|
|
35
|
-
|
|
20
|
+
|
|
21
|
+
<div class="tooltip-content">
|
|
36
22
|
<slot />
|
|
37
23
|
</div>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
|
|
25
|
+
<div class="tooltip-arrow" :style="arrowStyles"></div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
41
28
|
</template>
|
|
29
|
+
|
|
42
30
|
<script lang="ts">
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
31
|
+
import { defineComponent, ref, computed, PropType, onBeforeUnmount, nextTick, watch } from 'vue';
|
|
32
|
+
import {
|
|
33
|
+
TooltipPlacement,
|
|
34
|
+
TooltipTrigger,
|
|
35
|
+
TooltipVariant,
|
|
36
|
+
TooltipSize,
|
|
37
|
+
} from './types/tooltip.types';
|
|
38
|
+
import { calculateTooltipPosition, moveToBody, moveToContainer } from './utils/tooltip.utils';
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
| 'top-left'
|
|
48
|
-
| 'top-center'
|
|
49
|
-
| 'top-right'
|
|
50
|
-
| 'bottom-left'
|
|
51
|
-
| 'bottom-center'
|
|
52
|
-
| 'bottom-right';
|
|
40
|
+
const ARROW_OFFSET = 18;
|
|
53
41
|
|
|
54
42
|
export default defineComponent({
|
|
55
43
|
name: 'farm-tooltip',
|
|
56
44
|
props: {
|
|
57
|
-
/**
|
|
58
|
-
* Control visibility with v-model
|
|
59
|
-
*/
|
|
60
45
|
value: {
|
|
61
46
|
type: Boolean,
|
|
62
47
|
default: undefined,
|
|
63
48
|
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
fluid: {
|
|
68
|
-
type: Boolean,
|
|
69
|
-
default: false,
|
|
49
|
+
trigger: {
|
|
50
|
+
type: String as PropType<TooltipTrigger>,
|
|
51
|
+
default: 'hover',
|
|
70
52
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
position: {
|
|
75
|
-
type: String as PropType<TooltipPosition>,
|
|
76
|
-
default: undefined,
|
|
53
|
+
placement: {
|
|
54
|
+
type: String as PropType<TooltipPlacement>,
|
|
55
|
+
default: 'top-center',
|
|
77
56
|
validator: (value: string) => {
|
|
78
57
|
return [
|
|
79
58
|
'top-left',
|
|
@@ -85,288 +64,272 @@ export default defineComponent({
|
|
|
85
64
|
].includes(value);
|
|
86
65
|
},
|
|
87
66
|
},
|
|
67
|
+
offset: {
|
|
68
|
+
type: Number,
|
|
69
|
+
default: 8,
|
|
70
|
+
},
|
|
71
|
+
variant: {
|
|
72
|
+
type: String as PropType<TooltipVariant>,
|
|
73
|
+
default: 'dark',
|
|
74
|
+
},
|
|
75
|
+
size: {
|
|
76
|
+
type: String as PropType<TooltipSize>,
|
|
77
|
+
default: 'md',
|
|
78
|
+
},
|
|
79
|
+
maxWidth: {
|
|
80
|
+
type: [String, Number],
|
|
81
|
+
default: undefined,
|
|
82
|
+
},
|
|
83
|
+
delay: {
|
|
84
|
+
type: [Number, Array],
|
|
85
|
+
default: () => [100, 50],
|
|
86
|
+
},
|
|
87
|
+
disabled: {
|
|
88
|
+
type: Boolean,
|
|
89
|
+
default: false,
|
|
90
|
+
},
|
|
91
|
+
fluid: {
|
|
92
|
+
type: Boolean,
|
|
93
|
+
default: false,
|
|
94
|
+
},
|
|
95
|
+
position: {
|
|
96
|
+
type: String,
|
|
97
|
+
default: undefined,
|
|
98
|
+
},
|
|
88
99
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
zIndex: 1,
|
|
98
|
-
});
|
|
99
|
-
const slots = useSlots();
|
|
100
|
-
let hideTimeout: number | null = null;
|
|
100
|
+
emits: ['input', 'show', 'hide'],
|
|
101
|
+
setup(props, { emit, slots }) {
|
|
102
|
+
const containerRef = ref<HTMLElement | null>(null);
|
|
103
|
+
const activatorRef = ref<HTMLElement | null>(null);
|
|
104
|
+
const tooltipRef = ref<HTMLElement | null>(null);
|
|
105
|
+
const scrollableElementsRef = ref<Element[] | null>(null);
|
|
106
|
+
|
|
107
|
+
const isVisible = ref(false);
|
|
101
108
|
|
|
102
|
-
const
|
|
103
|
-
const externalControl = computed(() => props.value !== undefined);
|
|
104
|
-
const hasPosition = computed(() => !!props.position);
|
|
109
|
+
const isControlled = computed(() => props.value !== undefined);
|
|
105
110
|
const hasTitle = computed(() => !!slots.title);
|
|
111
|
+
const showCloseButton = computed(() => isControlled.value && hasTitle.value);
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const parentBoundingClientRect = parent.value.getBoundingClientRect();
|
|
114
|
-
const activatorBoundingClientRect = activator.value.getBoundingClientRect();
|
|
115
|
-
const popupBoundingClientRect = popup.value.getBoundingClientRect();
|
|
116
|
-
|
|
117
|
-
const activatorWidth = activatorBoundingClientRect.width;
|
|
118
|
-
const activatorHeight = activatorBoundingClientRect.height;
|
|
119
|
-
const popupWidth = popupBoundingClientRect.width;
|
|
120
|
-
const popupHeight = popupBoundingClientRect.height;
|
|
121
|
-
|
|
122
|
-
let left = 0;
|
|
123
|
-
let top = 0;
|
|
124
|
-
|
|
125
|
-
// Se estiver dentro de um modal, usar coordenadas da viewport (position fixed)
|
|
126
|
-
if (isInsideModal) {
|
|
127
|
-
if (!props.position) {
|
|
128
|
-
left = activatorBoundingClientRect.left + activatorWidth / 2 - popupWidth / 2;
|
|
129
|
-
top = activatorBoundingClientRect.top - popupHeight - 8;
|
|
130
|
-
} else {
|
|
131
|
-
const [verticalPosition, horizontalAlignment] = props.position.split('-');
|
|
132
|
-
|
|
133
|
-
switch (horizontalAlignment) {
|
|
134
|
-
case 'left':
|
|
135
|
-
left = activatorBoundingClientRect.left - 8;
|
|
136
|
-
break;
|
|
137
|
-
case 'right':
|
|
138
|
-
left = activatorBoundingClientRect.left + activatorWidth - popupWidth + 8;
|
|
139
|
-
break;
|
|
140
|
-
case 'center':
|
|
141
|
-
default:
|
|
142
|
-
left = activatorBoundingClientRect.left + activatorWidth / 2 - popupWidth / 2;
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
113
|
+
const normalizedPlacement = computed(() => {
|
|
114
|
+
if (props.position) {
|
|
115
|
+
return props.position as TooltipPlacement;
|
|
116
|
+
}
|
|
117
|
+
return props.placement;
|
|
118
|
+
});
|
|
145
119
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
120
|
+
const normalizedMaxWidth = computed(() => {
|
|
121
|
+
if (props.fluid) {
|
|
122
|
+
return '300px';
|
|
123
|
+
}
|
|
124
|
+
return props.maxWidth;
|
|
125
|
+
});
|
|
152
126
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (!props.position) {
|
|
162
|
-
left =
|
|
163
|
-
parentBoundingClientRect.left +
|
|
164
|
-
window.scrollX +
|
|
165
|
-
activatorWidth / 2 -
|
|
166
|
-
popupWidth / 2;
|
|
167
|
-
|
|
168
|
-
top = parentBoundingClientRect.top + window.scrollY - popupHeight - 8;
|
|
169
|
-
} else {
|
|
170
|
-
const [verticalPosition, horizontalAlignment] = props.position.split('-');
|
|
171
|
-
|
|
172
|
-
switch (horizontalAlignment) {
|
|
173
|
-
case 'left':
|
|
174
|
-
left = parentBoundingClientRect.left + window.scrollX - 8;
|
|
175
|
-
break;
|
|
176
|
-
case 'right':
|
|
177
|
-
left =
|
|
178
|
-
parentBoundingClientRect.left +
|
|
179
|
-
window.scrollX +
|
|
180
|
-
activatorWidth -
|
|
181
|
-
popupWidth +
|
|
182
|
-
8;
|
|
183
|
-
break;
|
|
184
|
-
case 'center':
|
|
185
|
-
default:
|
|
186
|
-
left =
|
|
187
|
-
parentBoundingClientRect.left +
|
|
188
|
-
window.scrollX +
|
|
189
|
-
activatorWidth / 2 -
|
|
190
|
-
popupWidth / 2;
|
|
191
|
-
break;
|
|
192
|
-
}
|
|
127
|
+
const tooltipClasses = computed(() => ({
|
|
128
|
+
'tooltip-popup': true,
|
|
129
|
+
'tooltip-popup--visible': isVisible.value,
|
|
130
|
+
[`tooltip-popup--${props.variant}`]: true,
|
|
131
|
+
[`tooltip-popup--${props.size}`]: true,
|
|
132
|
+
'tooltip-popup--has-title': hasTitle.value,
|
|
133
|
+
[`tooltip-popup--${normalizedPlacement.value}`]: true,
|
|
134
|
+
}));
|
|
193
135
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
136
|
+
const tooltipStyles = computed(() => {
|
|
137
|
+
const styles: Record<string, string> = {
|
|
138
|
+
position: 'fixed',
|
|
139
|
+
zIndex: '9999',
|
|
140
|
+
};
|
|
200
141
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
142
|
+
if (normalizedMaxWidth.value) {
|
|
143
|
+
styles.maxWidth =
|
|
144
|
+
typeof normalizedMaxWidth.value === 'number'
|
|
145
|
+
? `${normalizedMaxWidth.value}px`
|
|
146
|
+
: normalizedMaxWidth.value;
|
|
147
|
+
styles.width = 'auto';
|
|
206
148
|
}
|
|
207
149
|
|
|
208
|
-
return
|
|
209
|
-
};
|
|
150
|
+
return styles;
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const arrowStyles = computed(() => {
|
|
154
|
+
const [verticalPos, horizontalAlign] = normalizedPlacement.value.split('-');
|
|
155
|
+
|
|
156
|
+
const styles: Record<string, string> = {
|
|
157
|
+
position: 'absolute',
|
|
158
|
+
width: '0',
|
|
159
|
+
height: '0',
|
|
160
|
+
borderStyle: 'solid',
|
|
161
|
+
zIndex: '10000',
|
|
162
|
+
};
|
|
210
163
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
164
|
+
if (verticalPos === 'top') {
|
|
165
|
+
styles.bottom = '-6px';
|
|
166
|
+
styles.borderWidth = '6px 6px 0 6px';
|
|
167
|
+
styles.borderColor = '#333333 transparent transparent transparent';
|
|
168
|
+
} else {
|
|
169
|
+
styles.top = '-6px';
|
|
170
|
+
styles.borderWidth = '0 6px 6px 6px';
|
|
171
|
+
styles.borderColor = 'transparent transparent #333333 transparent';
|
|
216
172
|
}
|
|
217
173
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (modalElement) {
|
|
242
|
-
// Função para detectar elementos scrolláveis
|
|
243
|
-
const isScrollable = (element) => {
|
|
244
|
-
const style = window.getComputedStyle(element);
|
|
245
|
-
return (
|
|
246
|
-
style.overflow === 'auto' ||
|
|
247
|
-
style.overflow === 'scroll' ||
|
|
248
|
-
style.overflowY === 'auto' ||
|
|
249
|
-
style.overflowY === 'scroll' ||
|
|
250
|
-
style.overflowX === 'auto' ||
|
|
251
|
-
style.overflowX === 'scroll'
|
|
252
|
-
);
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
// Buscar todos os elementos dentro do modal
|
|
256
|
-
const allElements = modalElement.querySelectorAll('*');
|
|
257
|
-
const scrollableElements = Array.from(allElements).filter(isScrollable);
|
|
258
|
-
|
|
259
|
-
// Adicionar elementos específicos do modal que podem ter scroll
|
|
260
|
-
const modalSpecificElements = modalElement.querySelectorAll(
|
|
261
|
-
'.farm-modal--content, .farm-modal--content > div, [data-simplebar], .simplebar-content-wrapper'
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
// Combinar e remover duplicatas
|
|
265
|
-
const elementsToWatch = [...new Set([...scrollableElements, ...modalSpecificElements, modalElement])];
|
|
266
|
-
|
|
267
|
-
elementsToWatch.forEach(element => {
|
|
268
|
-
element.addEventListener('scroll', scrollListener, true);
|
|
269
|
-
modalScrollElements.push(element);
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
} else {
|
|
273
|
-
// Comportamento original para tooltips fora de modais
|
|
274
|
-
popup.value.style.position = 'absolute';
|
|
174
|
+
if (horizontalAlign === 'left') {
|
|
175
|
+
styles.left = `${ARROW_OFFSET}px`;
|
|
176
|
+
} else if (horizontalAlign === 'right') {
|
|
177
|
+
styles.right = `${ARROW_OFFSET}px`;
|
|
178
|
+
} else {
|
|
179
|
+
styles.left = '50%';
|
|
180
|
+
styles.transform = 'translateX(-50%)';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return styles;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const show = () => {
|
|
187
|
+
if (props.disabled || isControlled.value) return;
|
|
188
|
+
|
|
189
|
+
isVisible.value = true;
|
|
190
|
+
emit('show');
|
|
191
|
+
|
|
192
|
+
nextTick(() => {
|
|
193
|
+
if (tooltipRef.value && activatorRef.value) {
|
|
194
|
+
moveToBody(tooltipRef.value);
|
|
195
|
+
updatePosition();
|
|
196
|
+
addScrollListener();
|
|
275
197
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
styles.left = `${left}px`;
|
|
279
|
-
styles.top = `${top}px`;
|
|
280
|
-
styles.zIndex = calculateMainZindex();
|
|
198
|
+
});
|
|
199
|
+
};
|
|
281
200
|
|
|
282
|
-
|
|
283
|
-
|
|
201
|
+
const hide = () => {
|
|
202
|
+
if (props.disabled || isControlled.value) return;
|
|
203
|
+
|
|
204
|
+
isVisible.value = false;
|
|
205
|
+
emit('hide');
|
|
206
|
+
removeScrollListener();
|
|
284
207
|
};
|
|
285
208
|
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
209
|
+
const close = () => {
|
|
210
|
+
if (isControlled.value) {
|
|
211
|
+
emit('input', false);
|
|
212
|
+
} else {
|
|
213
|
+
hide();
|
|
291
214
|
}
|
|
215
|
+
};
|
|
292
216
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
element.removeEventListener('scroll', scrollListener, true);
|
|
309
|
-
});
|
|
310
|
-
modalScrollElements = [];
|
|
311
|
-
|
|
312
|
-
scrollListener = null;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
hideTimeout = null;
|
|
316
|
-
}, 50);
|
|
217
|
+
const updatePosition = () => {
|
|
218
|
+
if (!activatorRef.value || !tooltipRef.value) return;
|
|
219
|
+
|
|
220
|
+
const activatorRect = activatorRef.value.getBoundingClientRect();
|
|
221
|
+
const tooltipRect = tooltipRef.value.getBoundingClientRect();
|
|
222
|
+
|
|
223
|
+
const isActivatorVisible =
|
|
224
|
+
activatorRect.top < window.innerHeight &&
|
|
225
|
+
activatorRect.bottom > 0 &&
|
|
226
|
+
activatorRect.left < window.innerWidth &&
|
|
227
|
+
activatorRect.right > 0;
|
|
228
|
+
|
|
229
|
+
if (!isActivatorVisible && isVisible.value && !isControlled.value) {
|
|
230
|
+
hide();
|
|
231
|
+
return;
|
|
317
232
|
}
|
|
233
|
+
|
|
234
|
+
const position = calculateTooltipPosition(
|
|
235
|
+
activatorRect,
|
|
236
|
+
tooltipRect,
|
|
237
|
+
normalizedPlacement.value,
|
|
238
|
+
props.offset
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
tooltipRef.value.style.left = `${position.left}px`;
|
|
242
|
+
tooltipRef.value.style.top = `${position.top}px`;
|
|
318
243
|
};
|
|
319
244
|
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
245
|
+
const getScrollableElements = () => {
|
|
246
|
+
if (!scrollableElementsRef.value) {
|
|
247
|
+
const nodeList = document.querySelectorAll(
|
|
248
|
+
'.farm-modal, .modal-content, [style*="overflow-y: auto"], [style*="overflow-y: scroll"]'
|
|
249
|
+
);
|
|
250
|
+
scrollableElementsRef.value = Array.from(nodeList);
|
|
324
251
|
}
|
|
252
|
+
return scrollableElementsRef.value;
|
|
325
253
|
};
|
|
326
254
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
255
|
+
const addScrollListener = () => {
|
|
256
|
+
window.addEventListener('scroll', updatePosition, { passive: true });
|
|
257
|
+
|
|
258
|
+
const scrollableElements = getScrollableElements();
|
|
259
|
+
scrollableElements.forEach(element => {
|
|
260
|
+
element.addEventListener('scroll', updatePosition, { passive: true });
|
|
261
|
+
});
|
|
262
|
+
};
|
|
333
263
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
264
|
+
const removeScrollListener = () => {
|
|
265
|
+
window.removeEventListener('scroll', updatePosition);
|
|
266
|
+
|
|
267
|
+
const scrollableElements = getScrollableElements();
|
|
268
|
+
scrollableElements.forEach(element => {
|
|
269
|
+
element.removeEventListener('scroll', updatePosition);
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
if (isControlled.value) {
|
|
274
|
+
isVisible.value = props.value || false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
watch(
|
|
278
|
+
() => props.value,
|
|
279
|
+
newValue => {
|
|
280
|
+
if (isControlled.value) {
|
|
281
|
+
isVisible.value = newValue || false;
|
|
282
|
+
|
|
283
|
+
if (isVisible.value) {
|
|
284
|
+
nextTick(() => {
|
|
285
|
+
if (tooltipRef.value) {
|
|
286
|
+
moveToBody(tooltipRef.value);
|
|
287
|
+
updatePosition();
|
|
288
|
+
addScrollListener();
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
} else {
|
|
292
|
+
removeScrollListener();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
345
295
|
}
|
|
296
|
+
);
|
|
346
297
|
|
|
347
|
-
|
|
348
|
-
|
|
298
|
+
onBeforeUnmount(() => {
|
|
299
|
+
if (tooltipRef.value && containerRef.value) {
|
|
300
|
+
moveToContainer(tooltipRef.value, containerRef.value);
|
|
349
301
|
}
|
|
302
|
+
removeScrollListener();
|
|
350
303
|
});
|
|
351
304
|
|
|
352
305
|
return {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
externalControl,
|
|
359
|
-
hasPosition,
|
|
306
|
+
containerRef,
|
|
307
|
+
activatorRef,
|
|
308
|
+
tooltipRef,
|
|
309
|
+
isVisible,
|
|
310
|
+
isControlled,
|
|
360
311
|
hasTitle,
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
312
|
+
showCloseButton,
|
|
313
|
+
tooltipClasses,
|
|
314
|
+
tooltipStyles,
|
|
315
|
+
arrowStyles,
|
|
316
|
+
show,
|
|
317
|
+
hide,
|
|
318
|
+
close,
|
|
365
319
|
};
|
|
366
320
|
},
|
|
367
321
|
});
|
|
368
322
|
</script>
|
|
369
323
|
|
|
370
324
|
<style lang="scss" scoped>
|
|
371
|
-
@import './Tooltip';
|
|
325
|
+
@import './Tooltip.scss';
|
|
326
|
+
|
|
327
|
+
.tooltip-container {
|
|
328
|
+
display: inline-block;
|
|
329
|
+
position: relative;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.tooltip-activator {
|
|
333
|
+
display: inline-block;
|
|
334
|
+
}
|
|
372
335
|
</style>
|