📄 TLD - tld_custom_elements - Élément personnalisé
📄 TLD - tld_custom_elements - Élément personnalisé
📝 Introduction
La classe tld_custom_elements est une classe abstraite qui étend HTMLElement pour fournir une base aux éléments personnalisés en TypeScript.
Elle gère automatiquement le rendu et la gestion des attributs, tout en offrant une structure modulaire pour les classes dérivées.
🚀 Utilisation
🔹 Étendre tld_custom_elements
Comme il s'agit d'une classe abstraite, elle ne peut pas être instanciée directement.
Vous devez créer une sous-classe et implémenter la méthode render() :
class MyElement extends tld_custom_elements {
static get observedAttributes() {
return ["color", "size"];
}
constructor() {
super({ color: "red", size: "20px" });
}
render() {
this.innerHTML = `<div style="color: ${this.getAttribute("color")}; font-size: ${this.getAttribute("size")};">
Hello from MyElement!
</div>`;
}
}
// Enregistrement du composant
customElements.define("my-element", MyElement);
🔹 Utilisation dans le HTML
<my-element color="blue" size="25px"></my-element>
📌 Détails du Code
🏗️ Constructeur
Le constructeur :
- Vérifie que la classe abstraite n'est pas instanciée directement.
- Stocke la méthode
appendChildet la propriétéinnerHTMLd'origine. - Applique automatiquement les attributs définis dans
observedAttributes.
constructor(Attributes: { [name: string]: any } = null) {
super();
if (this.constructor === tld_custom_elements) {
throw new Error('Abstract class "tld_custom_elements" cannot be instantiated directly');
}
this._appendChild = this.appendChild;
let innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");
if (innerHTML != undefined) {
Object.defineProperty(this, "_innerHTML", innerHTML);
}
if (Attributes != null) {
setTimeout(() => {
const AttributesKey = (this.constructor as any).observedAttributes as string[];
AttributesKey.forEach((key) => {
if (Attributes[key] !== undefined) {
this.setAttribute(key, Attributes[key]);
}
});
});
}
}
🔄 Cycle de Vie des Éléments
📌 connectedCallback()
S'exécute lorsque l'élément est ajouté au DOM :
async connectedCallback() {
if (this._isConnectedCallback) return;
this._isConnectedCallback = true;
this.dispatchEvent(new CustomEvent("connectedCallback", { bubbles: false }));
if (document.readyState == "complete") {
setTimeout(() => this.__render());
} else {
window.addEventListener("load", () => this.__render());
}
}
📌 __render()
Gère le rendu de l'élément :
__render() {
const EventBeforRender = new CustomEvent("tld:beforRender", { bubbles: false, cancelable: true });
this.dispatchEvent(EventBeforRender);
if (!EventBeforRender.defaultPrevented) {
this.render();
this.dispatchEvent(new CustomEvent("tld:afterRender", { bubbles: false }));
}
}
📌 attributeChangedCallback()
Gère les changements d'attributs :
attributeChangedCallback(name, oldValue, newValue) {
const Object = { oV: this["_" + name], nV: undefined };
switch (newValue?.toLowerCase()) {
case "null":
Object.nV = null;
break;
case "undefined":
Object.nV = undefined;
break;
case "":
case "true":
Object.nV = true;
break;
case "false":
Object.nV = false;
break;
default:
Object.nV = newValue;
break;
}
this["_" + name] = Object.nV;
if (typeof this["_" + name + "Callback"] === "function") {
try {
this["_" + name + "Callback"](Object.oV, Object.nV);
} catch (error) {
console.error(error);
}
}
this.dispatchEvent(new CustomEvent("attribute:" + name, {
detail: { oldValue: Object.oV, newValue: Object.nV, strNewValue: newValue },
bubbles: false,
}));
}
📌 disconnectedCallback()
disconnectedCallback() {
this.dispatchEvent(new CustomEvent("disconnectedCallback", { bubbles: false }));
}
📌 adoptedCallback()
adoptedCallback() {
this.dispatchEvent(new CustomEvent("adoptedCallback", { bubbles: true }));
}
📚 Exemples et Cas Pratiques
Exemple d'Élément Personnalisé
class MyButton extends tld_custom_elements {
static get observedAttributes() {
return ["label"];
}
render() {
this.innerHTML = `<button>${this.getAttribute("label") || "Click me"}</button>`;
}
}
customElements.define("my-button", MyButton);
🔹 Utilisation dans le DOM
<my-button label="Submit"></my-button>
🎯 Conclusion
La classe tld_custom_elements offre une base solide pour créer des Web Components en TypeScript.
Elle facilite la gestion des attributs, du cycle de vie et du rendu, tout en permettant une personnalisation avancée.