@legba-core/ui
@legba-core/ui
Ce que ça fait
Base Lit et système de thème par variables CSS pour les Web Components @legba-core/ui, plus les composants atomiques média (LGB-031), texte (LGB-032) et composés (LGB-033). Média : deux boutons bascule contrôlés (micro/caméra), une piste vidéo, un mètre de niveau audio, un avatar et un nom. Texte : <legba-message>/<legba-message-input>/<legba-transcript-line> pour un fil de discussion et une transcription live. Composés : <legba-call> (grille d’appel connectée à @legba-core/realtime/client), <legba-call-button> (déclencheur), <legba-chat> (discussion réutilisant la connexion d’un <legba-call>). Un seul jeu de jetons --legba-*, un système de thème clair/sombre/marque à 3 états, et une isolation Shadow DOM héritée directement de Lit.
Symboles publics
| Symbole | Rôle |
|---|---|
CONTRAST_THRESHOLDS | Les trois seuils de contraste WCAG niveau AA |
LEGBA_NAME_FALLBACK | Texte de repli affiché par <legba-name> quand value est vide/blanc |
LegbaAudioLevel | <legba-audio-level> — mètre visuel de niveau audio |
LegbaAvatar | <legba-avatar> — avatar avec repli initiales/icône générique |
LegbaCall | <legba-call> — grille d’appel composée, connectée à @legba-core/realtime/client |
LegbaCallButton | <legba-call-button for="id"> — déclenche connect() sur un <legba-call> référencé |
LegbaCameraButton | <legba-camera-button> — bouton bascule contrôlé pour la caméra |
LegbaChat | <legba-chat for="id"> — discussion réutilisant la connexion d’un <legba-call> référencé |
LegbaElement | Classe de base de tout Web Component @legba-core/ui |
LegbaMessage | <legba-message> — un message de discussion |
LegbaMessageInput | <legba-message-input> — composeur de message |
LegbaMicButton | <legba-mic-button> — bouton bascule contrôlé pour le microphone |
LegbaName | <legba-name> — affiche un nom avec repli documenté si vide |
LegbaTranscriptLine | <legba-transcript-line> — une ligne de transcription live |
LegbaVideoTrack | <legba-video-track> — rendu d’une MediaStreamTrack vidéo |
LegbaAudioTrack | <legba-audio-track> — lecture d’une MediaStreamTrack audio distante |
THEME_TOKENS | Feuille de styles Lit posant les jetons --legba-*-default |
contrastRatio | Rapport de contraste WCAG 2.x entre deux couleurs |
meetsContrastAA | Dit si un rapport atteint le seuil WCAG AA d’une nature de contenu |
Installation
pnpm add @legba-core/ui lit
Depuis LGB-033, @legba-core/ui dépend de @legba-core/realtime (les
composants composés <legba-call>/<legba-chat> importent
createLegbaRoom depuis @legba-core/realtime/client) — installé
automatiquement, aucune étape supplémentaire pour un consommateur npm.
Pièges
- Un jeton public (
--legba-color-primary, etc.) n’est jamais déclaré directement parLegbaElement/THEME_TOKENS— une déclaration directe sur:hostgagnerait toujours contre une valeur posée par un ancêtre en light DOM (une propriété posée directement sur un élément prime sur l’héritage). Chaque composant doit consommer un jeton avec un repli explicite vers sa variable-default:var(--legba-color-primary, var(--legba-color-primary-default)), jamaisvar(--legba-color-primary)seul. - La technique « auto-référence pour hériter ou retomber sur un défaut »
(
--x: var(--x, défaut);) ne fonctionne PAS dans les navigateurs actuels — c’est toujours invalide, vérifié directement, quel que soit ce qu’un ancêtre pose. Ne jamais l’utiliser dans ce paquet ni dans les composants qui en dérivent. - Un jeton CSS explicitement vide (
--legba-radius: ;) n’est pas équivalent à « non posé » : c’est une déclaration valide mais vide, qui ne déclenche jamais le repli-default— c’est la propriété CSS qui le consomme qui devient invalide et retombe sur sa propre valeur initiale. src/internal/reste réservé aux composants de démonstration jamais exportés (utilisés uniquement par les tests de composant de LGB-030) — les composants atomiques de LGB-031/032 vivent, eux, soussrc/atoms/et sont bien exportés.- Les boutons bascule (
LegbaMicButton/LegbaCameraButton) sont entièrement contrôlés : un clic ne mute jamaisactivelui-même, seulementlegba-toggle(l’appelant doit rappeleractive = ...) — voir leurs pièges respectifs. <legba-message>masque tout le composant quandtextest vide ;<legba-transcript-line>fait l’inverse (indicateur explicite « … ») — choix délibérément différents, documentés sur chaque symbole, pas une incohérence.- Accessibilité (LGB-035). Trois faits qu’un intégrateur doit
connaître avant de thématiser. (1)
--legba-color-primarydu thème clair vaut#8a4e12depuis LGB-035, et non plus#b3661a: l’ancienne valeur ne donnait que 3,88:1 sur le fond clair, sous le seuil AA de 4,5:1. Redéfinir ce jeton, c’est reprendre à sa charge la conformité du couple ainsi créé —contrastRatioetmeetsContrastAAsont exportés pour permettre de le vérifier. (2)--legba-target-min(2,75rem) donne leur taille minimale à toutes les cibles : le remplacer par une valeur enpxfigerait les cibles et les empêcherait de suivre le réglage « taille de police » du navigateur. (3)--legba-color-focuspilote l’anneau de focus, indicateur non textuel dont le seuil est 3:1 — c’est un jeton distinct deprimaryprécisément pour qu’une marque puisse changer son accent sans dégrader la visibilité du focus. "sideEffects": false(package.json) et les imports d’enregistrement de tag. Vérifié en construisant LGB-033 : un import « nu » (import "../atoms/legba-avatar.js";, sans liaison, utilisé pour garantir qu’un tag custom element est enregistré) posé DANS un composant composé (ex.legba-call.ts) est éliminé par tsup/esbuild lors de la construction de ce paquet, à cause desideEffects: false— un avertissement de build le signale. Sans conséquence ici :src/index.tsré-exporte déjà CHAQUE atome par son nom (export { LegbaAvatar } from "./atoms/legba-avatar.js"), ce qui force son inclusion dansdist/index.jsindépendamment de cet import nu — vérifié en grepant le bundle publié. Risque réel pour un futur composant composé : s’il consomme un atome qui n’est PAS (ou plus) ré-exporté individuellement parsrc/index.ts, son enregistrement de tag pourrait être silencieusement absent du bundle publié. Règle à respecter : tout atome consommé par un composant composé doit rester exporté par son nom danssrc/index.ts.