poe-custom-elements
Version:
Path of Exile custom elements
153 lines (150 loc) • 5.55 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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { html, css, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { Directive, directive } from 'lit/directive.js';
import { render } from 'lit';
// Positioning library
import { computePosition, autoPlacement, offset, shift } from '@floating-ui/dom';
// Events to turn on/off the tooltip
const enterEvents = ['pointerenter', 'focus', 'click'];
const leaveEvents = ['pointerleave', 'blur'];
let SimpleTooltip = class SimpleTooltip extends LitElement {
// Lazy creation
static lazy(target, callback) {
const createTooltip = () => {
const tooltip = document.createElement('simple-tooltip');
callback(tooltip);
target.parentNode.insertBefore(tooltip, target.nextSibling);
tooltip.show();
// We only need to create the tooltip once, so ignore all future events.
enterEvents.forEach(eventName => target.removeEventListener(eventName, createTooltip));
};
enterEvents.forEach(eventName => target.addEventListener(eventName, createTooltip));
}
static { this.styles = css `
:host {
/* Position fixed to help ensure the tooltip is "on top" */
position: fixed;
/*border: 1px solid darkgray;
background-color: rgba(0, 0, 0, 0.8);
*/
padding: 4px;
border-radius: 4px;
display: inline-block;
pointer-events: none;
z-index: 900;
opacity: 0;
}
:host([showing]) {
opacity: 1;
}
`; }
constructor() {
super();
// Attribute for styling "showing"
this.showing = false;
// Position offset
this.offset = 4;
// Target for which to show tooltip
this._target = null;
this.show = async () => {
await new Promise(resolve => setTimeout(resolve));
this.style.cssText = '';
computePosition(this.target, this, {
strategy: 'fixed',
middleware: [offset(this.offset), shift(), autoPlacement({ allowedPlacements: ['top', 'bottom'] })],
}).then(({ x, y }) => {
this.style.left = `${x}px`;
this.style.top = `${y}px`;
});
this.showing = true;
};
this.hide = async () => {
await new Promise(resolve => setTimeout(resolve));
this.showing = false;
};
this.finishHide = () => {
if (!this.showing) {
this.style.display = 'none';
}
};
// Finish hiding at end of animation
this.addEventListener('transitionend', this.finishHide);
}
connectedCallback() {
super.connectedCallback();
// Setup target if needed
this.target ??= this.previousElementSibling;
// Ensure hidden at start
this.finishHide();
}
get target() {
return this._target;
}
set target(target) {
// Remove events from existing target
if (this.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;
}
render() {
return html `<slot></slot>`;
}
};
__decorate([
property({ reflect: true, type: Boolean }),
__metadata("design:type", Object)
], SimpleTooltip.prototype, "showing", void 0);
__decorate([
property({ type: Number }),
__metadata("design:type", Object)
], SimpleTooltip.prototype, "offset", void 0);
SimpleTooltip = __decorate([
customElement('simple-tooltip'),
__metadata("design:paramtypes", [])
], SimpleTooltip);
export { SimpleTooltip };
class TooltipDirective extends Directive {
constructor() {
super(...arguments);
this.didSetupLazy = false;
}
render(_ = '') { }
update(part, [tooltipContent]) {
this.tooltipContent = tooltipContent;
this.part = part;
if (!this.didSetupLazy) {
this.setupLazy();
}
if (this.tooltip) {
this.renderTooltipContent();
}
}
setupLazy() {
this.didSetupLazy = true;
SimpleTooltip.lazy(this.part.element, (tooltip) => {
this.tooltip = tooltip;
this.renderTooltipContent();
});
}
renderTooltipContent() {
render(this.tooltipContent, this.tooltip, this.part.options);
}
}
export const tooltip = directive(TooltipDirective);
//# sourceMappingURL=simple-tooltip.js.map