97 lines
3.0 KiB
JavaScript
Raw Permalink Normal View History

import { IgniteHtml } from '../ignite-html/ignite-html.js';
import { IgniteElement } from "../ignite-html/ignite-element.js";
import { IgniteTemplate, slot } from "../ignite-html/ignite-template.js";
import { IgniteProperty } from "../ignite-html/ignite-html.js";
class Popper extends IgniteElement {
constructor() {
super();
}
get properties() {
return {
position: "bottom",
show: new IgniteProperty(false, () => {
if (this.show) {
this.update();
} else {
if (this.updateTimeout) {
clearTimeout(this.updateTimeout);
}
this.updateTimeout = null;
}
}),
updateTimeout: null,
offset: "0.5em"
}
}
render() {
return this.template
.show(this.show)
.style("position", "absolute")
.style("top", this.position, true, value => value == "bottom" ? "100%" : null)
.style("bottom", this.position, true, value => value == "top" ? "100%" : null)
.style("margin-top", this.position, true, value => this.position == "bottom" ? this.offset : null)
.style("margin-bottom", this.position, true, value => this.position == "top" ? this.offset : null)
.style("left", "0")
.style("width", "100%")
.style("z-index", "99999")
.child(
new slot(this)
);
}
ready() {
this.update();
}
update() {
if (this.show) {
if (this.updateTimeout) {
clearTimeout(this.updateTimeout);
}
this.updateTimeout = setTimeout(() => this.update(), 200);
}
//Only perform the calculation if we are ready.
if (this.offsetParent) {
var bounds = this.getBoundingClientRect();
var parentBounds = this.getBoundingClientRect();
var offset = 0;
if (this.offsetTop < 0) {
offset = Math.abs(this.offsetTop + bounds.height);
} else {
offset = this.offsetTop - parentBounds.height;
}
if (bounds.y < 0 && this.position != "bottom" && (bounds.y + (bounds.height * 2) + (offset * 2) + parentBounds.height) < window.innerHeight) {
this.position = "bottom";
} else if (bounds.y + bounds.height >= window.innerHeight && this.position != "top") {
this.position = "top";
} else if (parentBounds.height + parentBounds.y + bounds.height + offset <= window.innerHeight && this.position != "bottom") {
this.position = "bottom";
}
}
}
cleanup() {
if (this.updateTimeout) {
clearTimeout(this.updateTimeout);
}
}
}
IgniteHtml.register("mt-popper", Popper);
class PopperTemplate extends IgniteTemplate {
constructor(...children) {
super("mt-popper", children);
}
}
export {
PopperTemplate as Popper
}