File: D:/web/matomo.vdk/plugins/CoreHome/vue/src/ExpandOnHover/ExpandOnHover.ts
/*!
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
import { DirectiveBinding } from 'vue';
import Matomo from '../Matomo/Matomo';
import DirectiveUtilities from '../directiveUtilities';
interface ExpandOnHoverArgs {
// input (provided by user)
expander: string | HTMLElement,
// event handlers
onMouseEnter?: () => void;
onMouseLeave?: () => void;
onClickOutsideElement?: (event: MouseEvent) => void;
onEscapeHandler?: (event: KeyboardEvent) => void;
}
function onMouseEnter(element: HTMLElement) {
element.classList.add('expanded');
const positionElement = element.querySelector('.dropdown.positionInViewport');
if (positionElement) {
Matomo.helper.setMarginLeftToBeInViewport(positionElement);
}
}
function onMouseLeave(element: HTMLElement) {
element.classList.remove('expanded');
}
function onClickOutsideElement(element: HTMLElement, event: MouseEvent) {
if (!element.contains(event.target as HTMLElement)) {
element.classList.remove('expanded');
}
}
function onEscapeHandler(element: HTMLElement, event: KeyboardEvent) {
if (event.which === 27) {
element.classList.remove('expanded');
}
}
const doc = document.documentElement;
/**
* Usage (in a component):
*
* directives: {
* ExpandOnHover: ExpandOnHover(), // function call is important since we store state
* // in this directive
* }
*/
export default {
mounted(el: HTMLElement, binding: DirectiveBinding<ExpandOnHoverArgs>): void {
binding.value.onMouseEnter = onMouseEnter.bind(null, el);
binding.value.onMouseLeave = onMouseLeave.bind(null, el);
binding.value.onClickOutsideElement = onClickOutsideElement.bind(null, el);
binding.value.onEscapeHandler = onEscapeHandler.bind(null, el);
setTimeout(() => {
const expander = DirectiveUtilities.getRef(binding.value.expander, binding);
if (expander) {
expander.addEventListener('mouseenter', binding.value.onMouseEnter!);
}
});
el.addEventListener('mouseleave', binding.value.onMouseLeave);
doc.addEventListener('keyup', binding.value.onEscapeHandler);
doc.addEventListener('mouseup', binding.value.onClickOutsideElement);
},
unmounted(el: HTMLElement, binding: DirectiveBinding<ExpandOnHoverArgs>): void {
const expander = DirectiveUtilities.getRef(binding.value.expander, binding);
if (expander) {
expander.removeEventListener('mouseenter', binding.value.onMouseEnter!);
}
el.removeEventListener('mouseleave', binding.value.onMouseLeave!);
document.removeEventListener('keyup', binding.value.onEscapeHandler!);
document.removeEventListener('mouseup', binding.value.onClickOutsideElement!);
},
};