LegbaTranscriptLine

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

LegbaTranscriptLine

Ce que ça fait

<legba-transcript-line> affiche une ligne de transcription/sous-titrage live : locuteur, texte, et un état final distinguant une ligne interimaire (non finalisée, style atténué) d’une ligne finalisée. Un texte vide affiche un indicateur explicite « … » (jamais une ligne totalement vide, trompeuse dans une liste). Un speaker manquant/vide retombe sur "Anonyme". La transition visuelle interimaire → finalisée respecte prefers-reduced-motion.

Signature

class LegbaTranscriptLine extends LegbaElement {
  speaker: string;
  text: string;
  final: boolean; // réfléchi comme attribut HTML `final`, défaut true
  timestamp?: number | Date;
}

Paramètres

PropriétéTypeRequisDéfautDescription
speakerstringnon""Nom du locuteur ; vide/blanc → repli "Anonyme"
textstringnon""Texte transcrit ; vide → indicateur explicite « … »
finalbooleannontruefalse = interimaire (non finalisé), rendu visuellement distinct
timestampnumber | Date | undefinednonundefinedHorodatage optionnel ; omis du rendu si absent

Retour

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

Erreurs

Aucune : un timestamp invalide (ex. NaN) fait simplement omettre l’horodatage rendu.

Exemple minimal

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

@customElement("mon-flux-sous-titres")
class MonFluxSousTitres extends LegbaElement {
  render() {
    return html`<legba-transcript-line speaker="Alice" text="Bonjour à tous" final></legba-transcript-line>`;
  }
}

Exemple complet

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

interface LigneCaptee {
  id: string;
  speaker: string;
  text: string;
  final: boolean;
}

@customElement("mon-panneau-captions")
class MonPanneauCaptions extends LegbaElement {
  // Une ligne interimaire se met à jour en place (même id) jusqu'à
  // finalisation par le service de reconnaissance vocale, puis final=true.
  lignes: LigneCaptee[] = [
    { id: "l1", speaker: "Alice", text: "Bonjour", final: true },
    { id: "l2", speaker: "", text: "en train de parler", final: false },
  ];

  render() {
    return html`${this.lignes.map(
      (l) =>
        html`<legba-transcript-line
          speaker=${l.speaker}
          text=${l.text}
          ?final=${l.final}
        ></legba-transcript-line>`,
    )}`;
  }
}

Pièges

  • État vide affiche un indicateur explicite, à l’inverse de <legba-message> (qui se masque entièrement quand text est vide) : sémantique différente — une ligne de transcription live vide signifie « en attente des premiers mots », un état actif qui doit rester visible dans une liste, pas un contenu absent.
  • Le repli speaker"Anonyme" est pensé pour rester cohérent avec le repli prévu pour <legba-name> (LGB-031) sur un nom vide — les deux composants doivent converger vers le même choix de mot.
  • final doit être posé via ?final=${...} ou l’attribut nu — comme pour own sur <legba-message>, final="false" en chaîne pose quand même l’attribut (donc true).
  • La transition d’opacité entre interimaire et finalisé n’est déclarée que sous @media (prefers-reduced-motion: no-preference) : un intégrateur qui étend les styles ne doit jamais ajouter de transition en dehors de cette même garde, sous peine de réintroduire du mouvement pour les utilisateurs qui l’ont explicitement désactivé.
  • timestamp n’est jamais un attribut HTML (attribute: false) : se règle uniquement via la propriété JS.

Voir aussi