export default class BaseComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this._state = {};
this._unsubscribers = [];
}
connectedCallback() {
this.render();
this._setupListeners();
this._subscribe();
}
disconnectedCallback() {
this._unsubscribers.forEach(unsubscribe => unsubscribe?.());
this._cleanup();
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
this.render();
}
}
render() {
if (!this.shadowRoot) return;
const style = this._getStyles();
const template = this._getTemplate();
this.shadowRoot.innerHTML = `${style}${template}`;
}
_getStyles() {
return '<style>:host { display: block; }</style>';
}
_getTemplate() {
return '';
}
_setupListeners() {
}
_subscribe() {
}
_cleanup() {
}
emit(eventName, detail = {}) {
this.dispatchEvent(
new CustomEvent(eventName, {
detail,
bubbles: true,
composed: true
})
);
}
setState(updates) {
this._state = { ...this._state, ...updates };
this.render();
}
getState() {
return { ...this._state };
}
querySelector(selector) {
return this.shadowRoot?.querySelector(selector);
}
querySelectorAll(selector) {
return this.shadowRoot?.querySelectorAll(selector) || [];
}
}