import { PopupPagination } from "../map/popup/PopupPagination.js";
import { Window } from "./Window.js";
import "./PopupTour.css";
export { PopupTour };
/**
* Popup tour to explain the Ui
*
* @author rhess <robin.hess@awi.de>
* @memberof vef.ui
*/
class PopupTour extends Window {
constructor(parent, items, useWidget) {
super(parent, {
mode: "slim",
draggable: false,
open: false
});
this.setClass("popup-tour");
this.items_ = [];
this.currentItem_ = null;
// init items
if (Array.isArray(items)) {
items.forEach(item => this.add(item.target, item.content));
if (this.items_.length > 0) this.currentItem_ = this.items_[0];
}
// init pagination
this.pagination_ = new PopupPagination(this.getElement(), {
pageCount: this.items_.length,
page: 1
});
this.pagination_.on("change", () => this.open_());
// globally add the widget
this.widget_ = (useWidget) ? this.initWidget_() : null;
// init with position of first item
this.calculatePosition_();
}
initWidget_() {
const widget = document.createElement("div");
widget.classList.add("vef-ui", "vef-widget-button", "popup-tour-widget");
widget.innerHTML = "<div class='widget-button-icon fas fa-question'></div>";
widget.style.display = "none";
widget.addEventListener("click", () => this.open_())
document.body.appendChild(widget);
return widget;
}
/**
* calculate the position and direction of the window
* @private
* @override
*/
calculatePosition_() {
if (!this.currentItem_) return;
let target = this.currentItem_.target;
let parent = this.getElement().parentElement;
if (parent && (typeof target == "string")) target = parent.querySelector(target);
if (!(target instanceof HTMLElement)) throw new Error("Invalid Target Element");
const rect = target.getBoundingClientRect();
const width = 310;
let left = rect.left + rect.width + 20;
let top = rect.top;
let direction = "left";
if (window.innerWidth <= (left + width)) {
left = rect.left - width - 20;
direction = "right";
}
if (left < 0) left = 0;
if (top < 0) top = 0;
const element = this.getElement();
element.classList.remove("pointer-bottom", "pointer-top", "pointer-left", "pointer-right");
element.classList.add("pointer-" + direction);
this.setOptions({
top: top + "px",
left: left + "px",
width: width + "px"
});
}
/**
*
* @param {HTMLElement} target
* @param {string} content content as string
*/
add(target, content) {
if (!(target instanceof HTMLElement) && (typeof target != "string")) throw new Error("Invalid Target Element");
if (typeof content != "string") throw new Error("Invalid Content");
this.items_.push({
target: target,
content: content
});
}
/**
* @private
*/
open_() {
if (this.widget_) this.widget_.style.display = "none";
this.getElement().style.removeProperty("opacity");
const index = this.pagination_.getPage() - 1;
this.currentItem_ = this.items_[index];
// create content
const content = document.createElement("div");
content.innerHTML = this.currentItem_.content;
super.setContent(content);
super.open();
}
/**
* show next item of the tour
*/
next() {
this.pagination_.next();
}
/**
* show previous item of the tour
*/
previous() {
this.pagination_.previous();
}
/**
* open the popup tour
*
* @param {number} index start index (starts at current index if omitted)
*/
open(index) {
const currentIndex = this.pagination_.getPage() - 1;
if (typeof index != "number") index = currentIndex;
if (currentIndex != index) {
this.pagination_.setPage(index + 1);
} else {
this.open_();
}
}
/**
* Hide the window by removing it from the parent
*/
close() {
if (this.widget_) {
this.widget_.style.removeProperty("display");
const rect = this.widget_.getBoundingClientRect();
this.getElement().style.opacity = 0;
this.getElement().classList.remove("pointer-left", "pointer-right");
this.setOptions({
top: rect.top + "px",
left: rect.left + "px",
width: rect.width + "px",
width: rect.height + "px",
});
setTimeout(() => super.close(), 333);
} else {
super.close();
}
}
/**
* dispose the Tour
* @override
*/
dispose() {
if (this.widget_) this.widget_.remove();
super.dispose();
}
}