LegbaMessageInput

expérimentaldepuis 0.1.0@legba-core/ui
Aperçu en direct — vrai composant, pas une image

LegbaMessageInput

Ce que ça fait

<legba-message-input> est le composeur d’un fil de discussion : un champ de saisie multiligne et un bouton d’envoi. Émet legba-submit (valeur nettoyée des espaces superflus) sur Entrée ou clic du bouton, puis se vide. Maj+Entrée insère un saut de ligne (multiligne supporté). disabled représente l’état « envoi en cours » ; errorMessage affiche une erreur accessible sans bloquer la correction.

Signature

class LegbaMessageInput extends LegbaElement {
  value: string;
  placeholder: string;
  disabled: boolean; // réfléchi comme attribut HTML `disabled`
  errorMessage: string | null; // attribut HTML `error-message`
  maxLength?: number; // attribut HTML `max-length`
  focus(options?: FocusOptions): void;
}

Événement émis : legba-submit (CustomEvent<{ value: string }>, bubbles: true, composed: true).

Paramètres

PropriétéTypeRequisDéfautDescription
valuestringnon""Valeur courante — composant entièrement contrôlé
placeholderstringnon""Texte d’aide affiché quand le champ est vide
disabledbooleannonfalsetrue = envoi en cours ; bloque saisie et soumission
errorMessagestring | nullnonnullMessage d’erreur accessible (role="alert") ; la saisie reste possible
maxLengthnumber | undefinednonundefinedLongueur maximale ; non défini = pas de limite

Retour

N/A — un Web Component, pas une fonction.

Erreurs

Aucune : un collage dépassant maxLength est tronqué silencieusement (jamais d’exception), une soumission à vide/blanc est simplement ignorée.

Exemple minimal

import { html } from "lit";
import { customElement } from "lit/decorators.js";
import { LegbaElement, LegbaMessageInput } from "@legba-core/ui";

@customElement("mon-composeur")
class MonComposeur extends LegbaElement {
  render() {
    return html`<legba-message-input placeholder="Écrire un message…"></legba-message-input>`;
  }
}

Exemple complet

import { html } from "lit";
import { customElement } from "lit/decorators.js";
import { LegbaElement, LegbaMessageInput } from "@legba-core/ui";

@customElement("mon-composeur-avance")
class MonComposeurAvance extends LegbaElement {
  envoiEnCours = false;
  erreur: string | null = null;

  private onSubmit(event: CustomEvent<{ value: string }>): void {
    this.envoiEnCours = true;
    this.erreur = null;
    // ex. await this.service.envoyer(event.detail.value) puis
    // this.envoiEnCours = false; en cas d'échec : this.erreur = "...";
  }

  render() {
    return html`
      <legba-message-input
        placeholder="Écrire un message…"
        max-length="500"
        ?disabled=${this.envoiEnCours}
        error-message=${this.erreur ?? ""}
        @legba-submit=${this.onSubmit}
      ></legba-message-input>
    `;
  }
}

Pièges

  • Maj+Entrée insère un saut de ligne, Entrée seule soumet — géré entièrement au niveau JS du composant (jamais en s’appuyant sur l’action par défaut native du navigateur), choix documenté et volontaire, pas un comportement du <textarea> natif.
  • Un texte uniquement composé d’espaces n’est jamais soumis et le champ n’est pas effacé dans ce cas (contrairement à une soumission réussie) — l’utilisateur retrouve ce qu’il a tapé.
  • errorMessage à null (ou chaîne vide) masque le message d’erreur ; le composant ne retient aucun état d’erreur interne au-delà de cette propriété — c’est à l’intégrateur de la remettre à null après correction.
  • disabled bloque la saisie et la soumission au niveau du composant lui-même (pas seulement via l’attribut HTML disabled du <textarea> interne) : robuste même si un intégrateur déclenche legba-submit autrement qu’via l’UI.
  • focus() est surchargée pour déléguer au <textarea> interne (Shadow DOM) — toujours utiliser el.focus(), jamais chercher le <textarea> directement depuis l’extérieur du composant.

Voir aussi