@alegendstale/holly-components
Version:
Reusable UI components created using lit
105 lines (102 loc) • 3.67 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { html, css, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { condCustomElement } from '../../decorators/condCustomElement.js';
const enterEvents = ['pointerenter', 'focus'];
const leaveEvents = ['pointerleave', 'blur', 'keydown', 'click'];
let SimpleTooltip = class SimpleTooltip extends LitElement {
static lazy(target, callback) {
const createTooltip = () => {
const tooltip = document.createElement('simple-tooltip');
callback(tooltip);
target.parentNode.insertBefore(tooltip, target.nextSibling);
tooltip.show();
enterEvents.forEach((eventName) => target.removeEventListener(eventName, createTooltip));
};
enterEvents.forEach((eventName) => target.addEventListener(eventName, createTooltip));
}
get target() {
return this._target;
}
set target(target) {
if (this.target) {
// Remove events from current target
enterEvents.forEach(name => this.target.removeEventListener(name, this.show));
leaveEvents.forEach(name => this.target.removeEventListener(name, this.hide));
}
if (target) {
// Add events to new target
enterEvents.forEach(name => target.addEventListener(name, this.show));
leaveEvents.forEach(name => target.addEventListener(name, this.hide));
}
this._target = target;
}
constructor() {
super();
this.offset = 4;
this.showing = false;
// Tooltip target
this._target = null;
this.addEventListener('transitionend', this.finishHide);
}
connectedCallback() {
super.connectedCallback();
this.hide();
// Set target to previous element as backup
this.target ??= this.previousElementSibling;
}
render() {
return html `<slot></slot>`;
}
show() {
this.style.cssText = '';
// Position tooltip near target
const { x, y, height } = this.target.getBoundingClientRect();
this.style.left = `${x}px`;
this.style.top = `${y + height + this.offset}px`;
this.showing = true;
}
hide() {
this.showing = false;
}
finishHide() {
if (!this.showing) {
this.style.display = 'none';
}
}
};
SimpleTooltip.styles = css `
:host {
display: inline-block;
position: fixed;
padding: 4px;
border: 1px solid darkgray;
border-radius: 4px;
background: #ccc;
pointer-events: none;
//Animation
opacity: 0;
transform: scale(0.75);
transition: opacity, transform;
transition-duration: .33s;
}
:host([showing]) {
opacity: 1;
transform: scale(1);
}
`;
__decorate([
property({ type: Number })
], SimpleTooltip.prototype, "offset", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], SimpleTooltip.prototype, "showing", void 0);
SimpleTooltip = __decorate([
condCustomElement('simple-tooltip')
], SimpleTooltip);
export { SimpleTooltip };