feat(components) BaseComponent added

This commit is contained in:
gh0sTedBuddy
2024-04-21 14:38:40 +01:00
parent 588f09afff
commit f2b0d07804
3 changed files with 167 additions and 2 deletions

View File

@@ -138,3 +138,127 @@ export default class BaseComponent {
}
}
}
class NewCetra {
constructor(options = {}) {
this.wrapper = options.wrapper || document.body;
this.componentMap = new Map();
this.variableMap = new Map();
this.observer = null;
}
init() {
this.discoverComponents();
this.setupObserver();
this.triggerHook('afterInit');
}
registerComponent(name, component) {
this.componentMap.set(name, component);
}
getComponent(name) {
return this.componentMap.get(name);
}
mountComponent(element) {
const componentName = element.getAttribute('data-ctra');
const component = this.getComponent(componentName) || this.getComponent('BaseComponent');
if (!component) {
console.warn(`Component "${componentName}" not found.`);
return;
}
const instance = new component(element);
element.__ctra_instance = instance;
this.triggerHook('beforeComponentMount', instance);
instance.mount();
this.triggerHook('afterComponentMount', instance);
}
unmountComponent(element) {
const instance = element.__ctra_instance;
if (!instance) {
console.warn('Unmounting a non-mounted component.');
return;
}
this.triggerHook('beforeComponentUnmount', instance);
instance.unmount();
this.triggerHook('afterComponentUnmount', instance);
delete element.__ctra_instance;
}
updateComponent(element) {
const instance = element.__ctra_instance;
if (!instance) {
console.warn('Updating a non-mounted component.');
return;
}
this.triggerHook('beforeComponentUpdate', instance);
instance.update();
this.triggerHook('afterComponentUpdate', instance);
}
getVariable(name) {
return this.variableMap.get(name);
}
setVariable(name, value) {
this.variableMap.set(name, value);
this.updateVariableBindings(name);
}
discoverComponents() {
const elements = this.wrapper.querySelectorAll('[data-ctra]');
elements.forEach(element => this.mountComponent(element));
}
setupObserver() {
this.observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE && node.hasAttribute('data-ctra')) {
this.mountComponent(node);
}
});
mutation.removedNodes.forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE && node.__ctra_instance) {
this.unmountComponent(node);
}
});
} else if (mutation.type === 'attributes' && mutation.attributeName === 'data-ctra') {
this.updateComponent(mutation.target);
}
});
});
this.observer.observe(this.wrapper, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['data-ctra']
});
}
updateVariableBindings(name) {
const elements = this.wrapper.querySelectorAll(`[data-ctra-var="${name}"]`);
elements.forEach(element => {
const value = this.getVariable(name);
element.textContent = value;
});
}
triggerHook(name, ...args) {
// Placeholder for triggering lifecycle hooks
console.log(`Triggering hook: ${name}`, ...args);
}
}