igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
163 lines • 5.38 kB
JavaScript
import { createAbortHandle } from '../common/abort-handler.js';
import { addWeakEventListener, getElementByIdFromRoot, isString, } from '../common/util.js';
import service from './service.js';
class TooltipController {
get open() {
return this._open;
}
set open(value) {
this._open = value;
if (this._open) {
this._addTooltipListeners();
service.add(this._host, this._options.onEscape);
}
else {
if (this._isTransient) {
this._isTransient = false;
this.setAnchor(this._initialAnchor?.deref());
}
this._hostAbortHandle.abort();
service.remove(this._host);
}
}
get anchor() {
return this._isTransient
? this._anchor?.deref()
: this._initialAnchor?.deref();
}
get hideTriggers() {
return Array.from(this._hideTriggers).join();
}
set hideTriggers(value) {
this._hideTriggers = parseTriggers(value);
this._anchorAbortHandle.abort();
this._addAnchorListeners();
}
get showTriggers() {
return Array.from(this._showTriggers).join();
}
set showTriggers(value) {
this._showTriggers = parseTriggers(value);
this._anchorAbortHandle.abort();
this._addAnchorListeners();
}
constructor(tooltip, options) {
this._hostAbortHandle = createAbortHandle();
this._anchorAbortHandle = createAbortHandle();
this._showTriggers = new Set(['pointerenter']);
this._hideTriggers = new Set(['pointerleave', 'click']);
this._anchor = null;
this._initialAnchor = null;
this._isTransient = false;
this._open = false;
this._host = tooltip;
this._options = options;
this._host.addController(this);
}
_addAnchorListeners() {
const anchor = this.anchor;
if (!anchor) {
return;
}
const { signal } = this._anchorAbortHandle;
for (const each of this._showTriggers) {
addWeakEventListener(anchor, each, this, { passive: true, signal });
}
for (const each of this._hideTriggers) {
addWeakEventListener(anchor, each, this, { passive: true, signal });
}
}
_addTooltipListeners() {
const { signal } = this._hostAbortHandle;
for (const event of TooltipController._listeners) {
this._host.addEventListener(event, this, { passive: true, signal });
}
}
async _handleTooltipEvent(event) {
switch (event.type) {
case 'pointerenter':
await this._options.onShow.call(this._host);
break;
case 'pointerleave':
await this._options.onHide.call(this._host);
break;
default:
return;
}
}
async _handleAnchorEvent(event) {
if (!this._open && this._showTriggers.has(event.type)) {
await this._options.onShow.call(this._host);
}
if (this._open && this._hideTriggers.has(event.type)) {
await this._options.onHide.call(this._host);
}
}
handleEvent(event) {
if (event.target === this._host) {
this._handleTooltipEvent(event);
}
else if (event.target === this._anchor?.deref()) {
this._handleAnchorEvent(event);
}
else if (event.target === this._initialAnchor?.deref()) {
this.open = false;
this._handleAnchorEvent(event);
}
}
_dispose() {
this._anchorAbortHandle.abort();
this._hostAbortHandle.abort();
service.remove(this._host);
this._anchor = null;
this._initialAnchor = null;
}
setAnchor(value, transient = false) {
const newAnchor = isString(value)
? getElementByIdFromRoot(this._host, value)
: value;
if (this._anchor?.deref() === newAnchor) {
return;
}
if (transient && this._open) {
this.open = false;
}
if (this._anchor?.deref() !== this._initialAnchor?.deref()) {
this._anchorAbortHandle.abort();
}
this._anchor = newAnchor ? new WeakRef(newAnchor) : null;
this._isTransient = transient;
this._addAnchorListeners();
}
resolveAnchor(value) {
const resolvedElement = isString(value)
? getElementByIdFromRoot(this._host, value)
: value;
this._initialAnchor = resolvedElement ? new WeakRef(resolvedElement) : null;
this.setAnchor(resolvedElement);
}
hostConnected() {
this.resolveAnchor(this._host.anchor);
}
hostDisconnected() {
this._dispose();
}
}
TooltipController._listeners = [
'pointerenter',
'pointerleave',
];
function parseTriggers(string) {
return new Set((string ?? '').split(TooltipRegexes.triggers).filter((s) => s.trim()));
}
export const TooltipRegexes = Object.freeze({
triggers: /[,\s]+/,
horizontalStart: /^(left|right)-start$/,
horizontalEnd: /^(left|right)-end$/,
start: /start$/,
end: /end$/,
});
export function addTooltipController(host, options) {
return new TooltipController(host, options);
}
//# sourceMappingURL=controller.js.map