HandleState JS

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;
/sources/components/Counter.js

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:

/sources/components/SaveTextBox.js

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:

/sources/components/Input.js