feat(components) BaseComponent added
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user