Tooltip: autoHide (#4126)

* Add autohide to tooltip

* Add missing enter

---------

Co-authored-by: Mikołaj Andrasiak <mikolaj.andrasiak@ncbj.gov.pl>
pull/4649/head
MiAnMy 2023-10-17 09:11:39 +02:00 committed by GitHub
parent 9f4cc77f3a
commit 5b876bebfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 3 deletions

View File

@ -67,7 +67,12 @@ export interface TooltipOptions {
*/ */
hideDelay?: number | undefined; hideDelay?: number | undefined;
/** /**
* Used to pass attributes to DOM elements inside the component. * Whether to hide tooltip when hovering over tooltip content.
* @defaultValue true
*/
autoHide?: boolean | undefined;
/**
* Uses to pass attributes to DOM elements inside the component.
* @type {TooltipDirectivePassThroughOptions} * @type {TooltipDirectivePassThroughOptions}
*/ */
pt?: PassThrough<TooltipDirectivePassThroughOptions>; pt?: PassThrough<TooltipDirectivePassThroughOptions>;

View File

@ -17,6 +17,7 @@ const Tooltip = BaseTooltip.extend('tooltip', {
target.$_ptooltipIdAttr = UniqueComponentId() + '_tooltip'; target.$_ptooltipIdAttr = UniqueComponentId() + '_tooltip';
target.$_ptooltipShowDelay = 0; target.$_ptooltipShowDelay = 0;
target.$_ptooltipHideDelay = 0; target.$_ptooltipHideDelay = 0;
target.$_ptooltipAutoHide = true;
} else if (typeof options.value === 'object' && options.value) { } else if (typeof options.value === 'object' && options.value) {
if (ObjectUtils.isEmpty(options.value.value) || options.value.value.trim() === '') return; if (ObjectUtils.isEmpty(options.value.value) || options.value.value.trim() === '') return;
else { else {
@ -28,6 +29,7 @@ const Tooltip = BaseTooltip.extend('tooltip', {
target.$_ptooltipIdAttr = options.value.id || UniqueComponentId() + '_tooltip'; target.$_ptooltipIdAttr = options.value.id || UniqueComponentId() + '_tooltip';
target.$_ptooltipShowDelay = options.value.showDelay || 0; target.$_ptooltipShowDelay = options.value.showDelay || 0;
target.$_ptooltipHideDelay = options.value.hideDelay || 0; target.$_ptooltipHideDelay = options.value.hideDelay || 0;
target.$_ptooltipAutoHide = !!options.value.autoHide === options.value.autoHide ? options.value.autoHide : true;
} }
} }
@ -55,6 +57,7 @@ const Tooltip = BaseTooltip.extend('tooltip', {
target.$_ptooltipIdAttr = target.$_ptooltipIdAttr || UniqueComponentId() + '_tooltip'; target.$_ptooltipIdAttr = target.$_ptooltipIdAttr || UniqueComponentId() + '_tooltip';
target.$_ptooltipShowDelay = 0; target.$_ptooltipShowDelay = 0;
target.$_ptooltipHideDelay = 0; target.$_ptooltipHideDelay = 0;
target.$_ptooltipAutoHide = true;
this.bindEvents(target, options); this.bindEvents(target, options);
} else if (typeof options.value === 'object' && options.value) { } else if (typeof options.value === 'object' && options.value) {
@ -71,6 +74,7 @@ const Tooltip = BaseTooltip.extend('tooltip', {
target.$_ptooltipIdAttr = options.value.id || target.$_ptooltipIdAttr || UniqueComponentId() + '_tooltip'; target.$_ptooltipIdAttr = options.value.id || target.$_ptooltipIdAttr || UniqueComponentId() + '_tooltip';
target.$_ptooltipShowDelay = options.value.showDelay || 0; target.$_ptooltipShowDelay = options.value.showDelay || 0;
target.$_ptooltipHideDelay = options.value.hideDelay || 0; target.$_ptooltipHideDelay = options.value.hideDelay || 0;
target.$_ptooltipAutoHide = !!options.value.autoHide === options.value.autoHide ? options.value.autoHide : true;
this.bindEvents(target, options); this.bindEvents(target, options);
} }
@ -148,8 +152,21 @@ const Tooltip = BaseTooltip.extend('tooltip', {
onMouseLeave(event) { onMouseLeave(event) {
const el = event.currentTarget; const el = event.currentTarget;
const hideDelay = el.$_ptooltipHideDelay; const hideDelay = el.$_ptooltipHideDelay;
const autoHide = el.$_ptooltipAutoHide;
this.hide(el, hideDelay); if (!autoHide) {
const valid =
DomHandler.hasClass(event.target, 'p-tooltip') ||
DomHandler.hasClass(event.target, 'p-tooltip-arrow') ||
DomHandler.hasClass(event.target, 'p-tooltip-text') ||
DomHandler.hasClass(event.relatedTarget, 'p-tooltip') ||
DomHandler.hasClass(event.relatedTarget, 'p-tooltip-text') ||
DomHandler.hasClass(event.relatedTarget, 'p-tooltip-arrow');
!valid && this.hide(el, hideDelay);
} else {
this.hide(el, hideDelay);
}
}, },
onFocus(event, options) { onFocus(event, options) {
const el = event.currentTarget; const el = event.currentTarget;
@ -195,6 +212,12 @@ const Tooltip = BaseTooltip.extend('tooltip', {
window.removeEventListener('resize', onWindowResize); window.removeEventListener('resize', onWindowResize);
}); });
tooltipElement.addEventListener('mouseleave', function onTooltipLeave() {
$this.hide(el);
tooltipElement.removeEventListener('mouseleave', onTooltipLeave);
});
this.bindScrollListener(el); this.bindScrollListener(el);
ZIndexUtils.set('tooltip', tooltipElement, el.$_ptooltipZIndex); ZIndexUtils.set('tooltip', tooltipElement, el.$_ptooltipZIndex);
}, },

View File

@ -5,7 +5,6 @@ const css = `
.p-tooltip { .p-tooltip {
position:absolute; position:absolute;
display:none; display:none;
pointer-events:none;
padding: .25em .5rem; padding: .25em .5rem;
max-width: 12.5rem; max-width: 12.5rem;
} }

View File

@ -0,0 +1,41 @@
<template>
<DocSectionText v-bind="$attrs">
<p>Tooltip is hidden when mouse leaves the target element, in cases where tooltip needs to be interacted with, set <i>autoHide</i> to false to change the default behavior.</p>
</DocSectionText>
<div class="card flex flex-wrap justify-content-center gap-2">
<InputText v-tooltip="{ value: 'Enter your username', autoHide: false }" type="text" placeholder="autoHide: false" />
<InputText v-tooltip="'Enter your username'" type="text" placeholder="autoHide: true" />
</div>
<DocSectionCode :code="code" />
</template>
<script>
export default {
data() {
return {
code: {
basic: `
<InputText v-tooltip="{ value: 'Enter your username', autoHide: false }" type="text" placeholder="autoHide: false" />
<InputText v-tooltip="'Enter your username'" type="text" placeholder="autoHide: true" />
`,
options: `
<template>
<div class="card flex flex-wrap justify-content-center gap-2">
<InputText v-tooltip="{ value: 'Enter your username', autoHide: false }" type="text" placeholder="autoHide: false" />
<InputText v-tooltip="'Enter your username'" type="text" placeholder="autoHide: true" />
</div>
</template>
`,
composition: `
<template>
<div class="card flex flex-wrap justify-content-center gap-2">
<InputText v-tooltip="{ value: 'Enter your username', autoHide: false }" type="text" placeholder="autoHide: false" />
<InputText v-tooltip="'Enter your username'" type="text" placeholder="autoHide: true" />
</div>
</template>
`
}
};
}
};
</script>

View File

@ -4,6 +4,7 @@
<script> <script>
import AccessibilityDoc from '@/doc/tooltip/AccessibilityDoc.vue'; import AccessibilityDoc from '@/doc/tooltip/AccessibilityDoc.vue';
import AutoHideDoc from '@/doc/tooltip/AutoHideDoc.vue';
import DelayDoc from '@/doc/tooltip/DelayDoc.vue'; import DelayDoc from '@/doc/tooltip/DelayDoc.vue';
import EventDoc from '@/doc/tooltip/EventDoc.vue'; import EventDoc from '@/doc/tooltip/EventDoc.vue';
import ImportDoc from '@/doc/tooltip/ImportDoc.vue'; import ImportDoc from '@/doc/tooltip/ImportDoc.vue';
@ -36,6 +37,11 @@ export default {
label: 'Template', label: 'Template',
component: TemplateDoc component: TemplateDoc
}, },
{
id: 'autohide',
label: 'Auto Hide',
component: AutoHideDoc
},
{ {
id: 'delay', id: 'delay',
label: 'Delay', label: 'Delay',