Quelques exemples
Voici quelques exemples de composants dynamiques que l'on peut créer avec HandleState JS.
Counter
import HandleState from "../handlestate.mjs";
/**
* 1: Counter (component)
*
* @return {HTMLElement}
*/
function Counter() {
// Le status qui contient le nombre
const handleCount = new HandleState(0);
// Compteur (sommet du DOM)
const counter = document.createElement("div");
counter.className = "counter";
// Contient le nombre à incrémenter
const count = document.createElement("div");
// Éléments pour incrémenter
const increment = document.createElement("button");
increment.innerText = "Incrémenter";
increment.addEventListener("click", () => {
handleCount.set(v => ++v);
});
// Éléments pour décrémenter
const decrement = document.createElement("button");
decrement.innerText = "Décrémenter";
decrement.addEventListener("click", () => {
handleCount.set(v => --v);
});
// Ajouter les éléments au DOM
counter.append(count);
counter.append(increment);
counter.append(decrement);
// Le rendu
const render = () => {
if (!count) return;
const value = handleCount.value;
// On met à jour l'affichage
count.innerText = value;
if (value > 0) {
// Vert si positif
count.style.color = "green";
} else if (value < 0) {
// Rouge si négatif
count.style.color = "red";
} else {
// Bleu si nul
count.style.color = "blue";
}
};
// On connecte les rendus aux status
handleCount.connect(render);
// Renvoyer le sommet du DOM
// pour pouvoir le réutiliser
// comme composant
return counter;
};
export default Counter;
Save Text Box
import HandleState from "../handlestate.mjs";
/**
* 2: SaveTextBox (component)
*
* @return {HTMLElement}
*/
function SaveTextBox() {
// Les status
const handleEdit = new HandleState(false);
const handleText = new HandleState("");
// La boîte de sauvegarde (sommet du DOM)
const saveTextBox = document.createElement("div");
saveTextBox.className = "save-text-box";
saveTextBox.style.maxWidth = "180px";
const form = document.createElement("form");
form.style.display = "grid";
const textarea = document.createElement("textarea");
textarea.name = "Save Text Box";
textarea.style.outline = "none";
textarea.style.resize = "vertical";
textarea.style.minHeight = "50px";
// Le bouton Modifier/Enregistrer
const edit = document.createElement("button");
edit.addEventListener("click", () => {
handleText.set(textarea.value.trim());
handleEdit.set(v => !v);
});
// Le bouton Annuler
const cancel = document.createElement("button");
cancel.textContent = "Annuler";
cancel.type = "button";
cancel.addEventListener("click", () => {
handleText.set(v => v);
handleEdit.set(v => !v);
});
// Ajouter les éléments au DOM
saveTextBox.append(form);
form.append(textarea);
form.append(edit);
form.append(cancel);
/**
* Ici les rendus/status sont séparés en deux
* - edit
* - text
* afin de séparer la logique et d'éviter
* les doubles rendus inutiles.
*/
// Les rendus
const renderEdit = () => {
if (!cancel || !edit || !textarea) return;
// Pour voir si on est en train de modifier
const isEdit = handleEdit.value;
// Mettre à jour l'affichage
if (isEdit) {
cancel.removeAttribute("hidden");
edit.textContent = "Enregistrer";
edit.type = "button";
} else {
cancel.setAttribute("hidden", "hidden");
edit.textContent = "Modifier";
edit.type = "submit";
}
textarea.readOnly = !isEdit;
};
const renderText = () => {
if (!textarea || !form) return;
const text = handleText.value;
// On met à jour la valeur du textarea et du form
textarea.value = text;
form.value = text;
};
// On connecte les rendus aux status
handleEdit.connect(renderEdit);
handleText.connect(renderText);
// Renvoyer le sommet du DOM
// pour pouvoir le réutiliser
// comme composant
return saveTextBox;
};
export default SaveTextBox;
Reçu:
Input
import HandleState from "../handlestate.mjs";
/**
* 3: Input (component)
*
* @param {HandleState} handleText
* @param {string} title Pour le label et title
* @param {string} name
*
* @return {HTMLElement}
*/
function Input(handleText, title = null, name = "input") {
// Input (sommet du DOM)
const container = document.createElement("div");
container.className = "input";
// Label du champs
const label = document.createElement("label");
if (title) label.innerText = title;
// Champs de texte
// Ce champs est contrôllé d'une manière
// similaire à React
// (rendu après chaque changement)
const input = document.createElement("input");
input.title = title;
input.name = name;
input.addEventListener("input", (e) => {
handleText.set(e.target.value);
});
// Ajouter les éléments au DOM
container.append(label);
label.append(input);
// Ici le status handleText est passé
// en paramètre donc hérité.
// Les rendus
const render = () => {
if (!input) return;
input.value = handleText.value;
};
// On connecte le rendu aux status
handleText.connect(render);
// Renvoyer le sommet du DOM
// pour pouvoir le réutiliser
// comme composant
return container;
};
export default Input;
Vous êtes: