/**
* @fileoverview Base Component Class for Rantii
* @author retoor <retoor@molodetz.nl>
* @description Foundation class for all custom HTML elements
* @keywords component, web component, custom element, base, foundation
*/
class BaseComponent extends HTMLElement {
constructor() {
super();
this.isInitialized = false;
this.eventListeners = [];
}
connectedCallback() {
if (!this.isInitialized) {
this.init();
this.isInitialized = true;
}
this.onConnected();
}
disconnectedCallback() {
this.cleanup();
this.onDisconnected();
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
this.onAttributeChanged(name, oldValue, newValue);
}
}
init() {}
onConnected() {}
onDisconnected() {}
onAttributeChanged(name, oldValue, newValue) {}
render() {}
update(data) {
Object.assign(this, data);
this.render();
}
$(selector) {
return this.querySelector(selector);
}
$$(selector) {
return this.querySelectorAll(selector);
}
on(target, event, handler, options = {}) {
const boundHandler = handler.bind(this);
target.addEventListener(event, boundHandler, options);
this.eventListeners.push({ target, event, handler: boundHandler, options });
return boundHandler;
}
off(target, event, handler) {
target.removeEventListener(event, handler);
this.eventListeners = this.eventListeners.filter(
l => !(l.target === target && l.event === event && l.handler === handler)
);
}
cleanup() {
this.eventListeners.forEach(({ target, event, handler, options }) => {
target.removeEventListener(event, handler, options);
});
this.eventListeners = [];
}
emit(eventName, detail = {}) {
const event = new CustomEvent(eventName, {
bubbles: true,
composed: true,
detail
});
this.dispatchEvent(event);
}
setHtml(html) {
this.innerHTML = html;
}
setText(text) {
this.textContent = text;
}
show() {
this.style.display = '';
this.removeAttribute('hidden');
}
hide() {
this.style.display = 'none';
}
toggle(visible) {
if (visible !== undefined) {
visible ? this.show() : this.hide();
} else {
this.style.display === 'none' ? this.show() : this.hide();
}
}
addClass(...classNames) {
this.classList.add(...classNames);
}
removeClass(...classNames) {
this.classList.remove(...classNames);
}
toggleClass(className, force) {
this.classList.toggle(className, force);
}
hasClass(className) {
return this.classList.contains(className);
}
setData(key, value) {
this.dataset[key] = value;
}
getData(key) {
return this.dataset[key];
}
getAttr(name) {
return this.getAttribute(name);
}
setAttr(name, value) {
if (value === null || value === undefined) {
this.removeAttribute(name);
} else {
this.setAttribute(name, value);
}
}
hasAttr(name) {
return this.hasAttribute(name);
}
async waitForInit() {
return new Promise(resolve => {
if (this.isInitialized) {
resolve();
} else {
const observer = new MutationObserver(() => {
if (this.isInitialized) {
observer.disconnect();
resolve();
}
});
observer.observe(this, { childList: true, subtree: true });
}
});
}
debounce(func, wait) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
throttle(func, limit) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
getApp() {
return window.app;
}
getApi() {
return window.app?.api;
}
getAuth() {
return window.app?.auth;
}
getRouter() {
return window.app?.router;
}
getStorage() {
return window.app?.storage;
}
getTheme() {
return window.app?.theme;
}
isLoggedIn() {
return window.app?.auth?.isLoggedIn() || false;
}
getCurrentUser() {
return window.app?.auth?.getUser() || null;
}
}
export { BaseComponent };