consul/ui/packages/consul-ui/app/modifiers/with-overlay.js

76 lines
2.0 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { modifier } from 'ember-modifier';
import tippy, { followCursor } from 'tippy.js';
/**
* Overlay modifier using Tippy.js
* https://atomiks.github.io/tippyjs
*
* {{tooltip 'Text' options=(hash )}}
*/
export default modifier(($element, [content], hash = {}) => {
const options = hash.options || {};
let $anchor = $element;
// make it easy to specify the modified element as the actual tooltip
if (typeof options.triggerTarget === 'string') {
const $el = $anchor;
switch (options.triggerTarget) {
case 'parentNode':
$anchor = $anchor.parentNode;
break;
default:
$anchor = $anchor.querySelectorAll(options.triggerTarget);
}
content = $anchor.cloneNode(true);
$el.remove();
hash.options.triggerTarget = undefined;
}
// {{tooltip}} will just use the HTML content
if (typeof content === 'undefined') {
content = $anchor.innerHTML;
$anchor.innerHTML = '';
}
if (hash.returns) {
options.trigger = 'manual';
}
let interval;
if (options.trigger === 'manual') {
// if we are manually triggering, a out delay means only show for the
// amount of time specified by the delay
const delay = options.delay || [];
if (typeof delay[1] !== 'undefined') {
options.onShown = (popover) => {
clearInterval(interval);
interval = setTimeout(() => {
popover.hide();
}, delay[1]);
};
}
}
let $trigger = $anchor;
const popover = tippy($anchor, {
triggerTarget: $trigger,
content: ($anchor) => content,
// showOnCreate: true,
// hideOnClick: false,
interactive: true,
plugins: [typeof options.followCursor !== 'undefined' ? followCursor : undefined].filter(
(item) => Boolean(item)
),
...options,
});
if (hash.returns) {
hash.returns(popover);
}
return () => {
clearInterval(interval);
popover.destroy();
};
});