Refactor #3965 - For Tooltip

pull/3999/head
Tuğçe Küçükoğlu 2023-06-21 16:58:32 +03:00
parent b273dbbcc9
commit 77074e623f
2 changed files with 136 additions and 62 deletions

View File

@ -9,6 +9,89 @@
*/ */
import { DirectiveBinding, ObjectDirective } from 'vue'; import { DirectiveBinding, ObjectDirective } from 'vue';
/**
* Custom passthrough(pt) hooks options.
*/
export interface TooltipPassThroughHooksOptions {
/**
* Called before bound element's attributes or event listeners are applied.
*/
created?: DirectiveBinding;
/**
* Called right before the element is inserted into the DOM.
*/
beforeMount?: DirectiveBinding;
/**
* Called when the bound element's parent component and all its children are mounted.
*/
mounted?: DirectiveBinding;
/**
* Called before the parent component is updated.
*/
beforeUpdate?: DirectiveBinding;
/**
* Called after the parent component and all of its children have updated all of its children have updated.
*/
updated?: DirectiveBinding;
/**
* Called before the parent component is unmounted.
*/
beforeUnmount?: DirectiveBinding;
/**
* Called when the parent component is unmounted.
*/
unmounted?: DirectiveBinding;
}
/**
* Custom passthrough(pt) css options.
*/
export interface TooltipPassThroughCSSOptions {
/**
* Style class of the element.
*/
class?: any;
/**
* Inline style of the element.
*/
style?: any;
}
export interface TooltipPassThroughDirectiveOptions {
/**
* Uses to pass attributes to the life cycle hooks.
* @see {@link TooltipPassThroughHooksOptions}
*/
hooks?: TooltipPassThroughHooksOptions;
/**
* Uses to pass attributes to the styles.
* @see {@link TooltipPassThroughCSSOptions}
*/
css?: TooltipPassThroughCSSOptions;
}
/**
* Custom passthrough(pt) options.
* @see {@link TooltipOptions.pt}
*/
export interface TooltipPassThroughOptions {
/**
* Uses to pass attributes to the root's DOM element.
* @see {@link TooltipPassThroughDirectiveOptions}
*/
root?: TooltipPassThroughDirectiveOptions;
/**
* Uses to pass attributes to the text's DOM element.
* @see {@link TooltipPassThroughDirectiveOptions}
*/
text?: TooltipPassThroughDirectiveOptions;
/**
* Uses to pass attributes to the arrow's DOM element.
* @see {@link TooltipPassThroughDirectiveOptions}
*/
arrow?: TooltipPassThroughDirectiveOptions;
}
/** /**
* Defines options of Tooltip. * Defines options of Tooltip.
*/ */
@ -50,6 +133,11 @@ export interface TooltipOptions {
* @defaultValue 0 * @defaultValue 0
*/ */
hideDelay?: number | undefined; hideDelay?: number | undefined;
/**
* Uses to pass attributes to DOM elements inside the component.
* @type {TooltipPassThroughOptions}
*/
pt?: TooltipPassThroughOptions;
} }
/** /**

View File

@ -1,15 +1,20 @@
import { BaseDirective } from 'primevue/basedirective';
import { ConnectedOverlayScrollHandler, DomHandler, ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primevue/utils'; import { ConnectedOverlayScrollHandler, DomHandler, ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primevue/utils';
let timer; let timer;
function bindEvents(el) { function bindEvents(el, options) {
const modifiers = el.$_ptooltipModifiers; const modifiers = el.$_ptooltipModifiers;
if (modifiers.focus) { if (modifiers.focus) {
el.addEventListener('focus', onFocus); el.$_focusevent = (event) => onFocus(event, options);
el.addEventListener('focus', el.$_focusevent);
el.addEventListener('blur', onBlur); el.addEventListener('blur', onBlur);
} else { } else {
el.addEventListener('mouseenter', onMouseEnter); el.$_mouseenterevent = (event) => onMouseEnter(event, options);
el.addEventListener('mouseenter', el.$_mouseenterevent);
el.addEventListener('mouseleave', onMouseLeave); el.addEventListener('mouseleave', onMouseLeave);
el.addEventListener('click', onClick); el.addEventListener('click', onClick);
} }
@ -21,10 +26,14 @@ function unbindEvents(el) {
const modifiers = el.$_ptooltipModifiers; const modifiers = el.$_ptooltipModifiers;
if (modifiers.focus) { if (modifiers.focus) {
el.removeEventListener('focus', onFocus); el.removeEventListener('focus', el.$_focusevent);
el.$_focusevent = null;
el.removeEventListener('blur', onBlur); el.removeEventListener('blur', onBlur);
} else { } else {
el.removeEventListener('mouseenter', onMouseEnter); el.removeEventListener('mouseenter', el.$_mouseenterevent);
el.$_mouseenterevent = null;
el.removeEventListener('mouseleave', onMouseLeave); el.removeEventListener('mouseleave', onMouseLeave);
el.removeEventListener('click', onClick); el.removeEventListener('click', onClick);
} }
@ -48,11 +57,11 @@ function unbindScrollListener(el) {
} }
} }
function onMouseEnter(event) { function onMouseEnter(event, options) {
const el = event.currentTarget; const el = event.currentTarget;
const showDelay = el.$_ptooltipShowDelay; const showDelay = el.$_ptooltipShowDelay;
show(el, showDelay); show(el, options, showDelay);
} }
function onMouseLeave(event) { function onMouseLeave(event) {
@ -62,11 +71,11 @@ function onMouseLeave(event) {
hide(el, hideDelay); hide(el, hideDelay);
} }
function onFocus(event) { function onFocus(event, options) {
const el = event.currentTarget; const el = event.currentTarget;
const showDelay = el.$_ptooltipShowDelay; const showDelay = el.$_ptooltipShowDelay;
show(el, showDelay); show(el, options, showDelay);
} }
function onBlur(event) { function onBlur(event) {
@ -90,15 +99,15 @@ function onKeydown(event) {
event.code === 'Escape' && hide(event.currentTarget, hideDelay); event.code === 'Escape' && hide(event.currentTarget, hideDelay);
} }
function tooltipActions(el) { function tooltipActions(el, options) {
if (el.$_ptooltipDisabled || !DomHandler.isExist(el)) { if (el.$_ptooltipDisabled || !DomHandler.isExist(el)) {
return; return;
} }
let tooltipElement = create(el); let tooltipElement = create(el, options);
align(el); align(el);
DomHandler.fadeIn(tooltipElement, 250); !el.$_ptooltipUnstyled && DomHandler.fadeIn(tooltipElement, 250);
window.addEventListener('resize', function onWindowResize() { window.addEventListener('resize', function onWindowResize() {
if (!DomHandler.isTouchDevice()) { if (!DomHandler.isTouchDevice()) {
@ -112,11 +121,11 @@ function tooltipActions(el) {
ZIndexUtils.set('tooltip', tooltipElement, el.$_ptooltipZIndex); ZIndexUtils.set('tooltip', tooltipElement, el.$_ptooltipZIndex);
} }
function show(el, showDelay) { function show(el, options, showDelay) {
if (showDelay !== undefined) { if (showDelay !== undefined) {
timer = setTimeout(() => tooltipActions(el), showDelay); timer = setTimeout(() => tooltipActions(el, options), showDelay);
} else { } else {
tooltipActions(el); tooltipActions(el, options);
} }
} }
@ -139,24 +148,7 @@ function getTooltipElement(el) {
return document.getElementById(el.$_ptooltipId); return document.getElementById(el.$_ptooltipId);
} }
function setGlobalPTOptions(el, container) { function create(el, options) {
const addCSS = (element, section) => {
section.class && DomHandler.addMultipleClasses(element, section.class);
section.style && DomHandler.addStyles(element, section.style);
};
el.$_ptooltipPTOptions.css && addCSS(container, el.$_ptooltipPTOptions.css.root);
el.$_ptooltipPTCss && addCSS(container, el.$_ptooltipPTCss.root);
for (let section of ['arrow', 'text']) {
const element = DomHandler.findSingle(container, `[data-pc-section="${section}"]`);
el.$_ptooltipPTOptions.css[section] && addCSS(element, el.$_ptooltipPTOptions.css[section]);
el.$_ptooltipPTCss[section] && addCSS(element, el.$_ptooltipPTCss[section]);
}
}
function create(el) {
const id = el.$_ptooltipIdAttr !== '' ? el.$_ptooltipIdAttr : UniqueComponentId() + '_tooltip'; const id = el.$_ptooltipIdAttr !== '' ? el.$_ptooltipIdAttr : UniqueComponentId() + '_tooltip';
el.$_ptooltipId = id; el.$_ptooltipId = id;
@ -198,7 +190,9 @@ function create(el) {
container.style.width = 'fit-content'; container.style.width = 'fit-content';
} }
setGlobalPTOptions(el, container); el.$_pDirectiveElement = container;
BaseDirective.directiveElement = container;
BaseDirective.handleCSS('tooltip', container, options);
return container; return container;
} }
@ -372,7 +366,7 @@ function getModifiers(options) {
return {}; return {};
} }
const Tooltip = { const Tooltip = BaseDirective.extend('tooltip', {
beforeMount(el, options) { beforeMount(el, options) {
let target = getTarget(el); let target = getTarget(el);
@ -388,7 +382,6 @@ const Tooltip = {
target.$_ptooltipIdAttr = ''; target.$_ptooltipIdAttr = '';
target.$_ptooltipShowDelay = 0; target.$_ptooltipShowDelay = 0;
target.$_ptooltipHideDelay = 0; target.$_ptooltipHideDelay = 0;
target.$_ptooltipPTCss = '';
} 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 {
@ -400,37 +393,25 @@ const Tooltip = {
target.$_ptooltipIdAttr = options.value.id || ''; target.$_ptooltipIdAttr = options.value.id || '';
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.$_ptooltipPTCss = options.value.pt && options.value.pt.css;
} }
} }
if (options.instance.$primevue && options.instance.$primevue.config) { if (options.instance.$primevue && options.instance.$primevue.config) {
target.$_ptooltipZIndex = options.instance.$primevue.config.zIndex.tooltip; let _config = options.instance.$primevue && options.instance.$primevue.config;
target.$_ptooltipUnstyled = options.instance.$primevue.config.unstyled || false;
target.$_ptooltipPTOptions = options.instance.$primevue.config.pt && options.instance.$primevue.config.pt.directives && options.instance.$primevue.config.pt.directives.tooltip; target.$_ptooltipZIndex = _config.zIndex.tooltip;
target.$_ptooltipUnstyled = _config.unstyled || false;
} }
bindEvents(target); bindEvents(target, options);
},
unmounted(el) {
let target = getTarget(el);
remove(target);
unbindEvents(target);
if (target.$_ptooltipScrollHandler) {
target.$_ptooltipScrollHandler.destroy();
target.$_ptooltipScrollHandler = null;
}
}, },
updated(el, options) { updated(el, options) {
let target = getTarget(el); let target = getTarget(el);
target.$_ptooltipModifiers = getModifiers(options); target.$_ptooltipModifiers = getModifiers(options);
unbindEvents(target);
if (!options.value) { if (!options.value) {
unbindEvents(target);
return; return;
} }
@ -442,12 +423,11 @@ const Tooltip = {
target.$_ptooltipIdAttr = ''; target.$_ptooltipIdAttr = '';
target.$_ptooltipShowDelay = 0; target.$_ptooltipShowDelay = 0;
target.$_ptooltipHideDelay = 0; target.$_ptooltipHideDelay = 0;
target.$_ptooltipPTCss = '';
bindEvents(target); bindEvents(target, options);
} 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() === '') { if (ObjectUtils.isEmpty(options.value.value) || options.value.value.trim() === '') {
unbindEvents(target); unbindEvents(target, options);
return; return;
} else { } else {
@ -459,16 +439,22 @@ const Tooltip = {
target.$_ptooltipIdAttr = options.value.id || ''; target.$_ptooltipIdAttr = options.value.id || '';
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.$_ptooltipPTCss = options.value.pt && options.value.pt.css;
bindEvents(target); bindEvents(target, options);
} }
} }
},
unmounted(el, options) {
let target = getTarget(el);
if (options.instance.$primevue && options.instance.$primevue.config) { remove(target);
target.$_ptooltipPTOptions = options.instance.$primevue.config.pt && options.instance.$primevue.config.pt.directives && options.instance.$primevue.config.pt.directives.tooltip; unbindEvents(target, options);
if (target.$_ptooltipScrollHandler) {
target.$_ptooltipScrollHandler.destroy();
target.$_ptooltipScrollHandler = null;
} }
} }
}; });
export default Tooltip; export default Tooltip;