Message
A single chat turn with a role avatar and a bubble styled per sender.
Message représente un tour de conversation (chat). Il n'affiche rien par lui-même : c'est un contrôleur d'alignement (align="start" ou "end") qui pose ses enfants côte à côte via flex et inverse l'ordre pour les messages envoyés (align="end" → flex-row-reverse).
Un Message se compose typiquement de deux éléments frères :
- MessageAvatar — l'avatar rond qui identifie l'auteur. Contient un
<Avatar>avecAvatarImage+AvatarFallback. Optionnel : sans avatar, la bulle prend toute la largeur. - MessageContent — la colonne verticale qui empile
MessageHeader(nom / horodatage), laBubbleavec sonBubbleContent, etMessageFooter(statut, actions inline comme "Delivered" ou boutons "Undo"/"Retry").
La Bubble est le rectangle coloré du message. Six variantes sémantiques : default (accent primary, pour l'utilisateur courant), muted (gris neutre, pour les interlocuteurs), tinted (teinté primary léger), outline (fond neutre + bordure), ghost (aucun style — pour les longues notes assistant), destructive (rouge, pour les erreurs / warnings). BubbleContent est le vrai conteneur du texte ; BubbleReactions se pose en absolute par-dessus (émojis / réactions).
Pour empiler plusieurs bulles du même auteur, enveloppez-les dans un BubbleGroup à l'intérieur de MessageContent — un seul avatar est affiché pour tout le groupe.
Pour indiquer un état système (bot qui réfléchit, chargement, note de statut), utilisez Marker à la place de MessageContent — <Marker role="status"><MarkerIcon><Spinner /></MarkerIcon><MarkerContent>Checking the logs...</MarkerContent></Marker>.
Installation
$ bext ui add message
Usage
Anatomy
<Message align="start | end">
├── <MessageAvatar> // optionnel — l'avatar rond
│ └── <Avatar>...</Avatar>
└── <MessageContent> // colonne verticale
├── <MessageHeader>... // nom + horodatage (optionnel)
├── <Bubble variant="..."> // la bulle stylée par variant
│ ├── <BubbleContent> // le texte du message
│ └── <BubbleReactions> // réactions emojis (optionnel)
└── <MessageFooter>... // statut + actions (optionnel)
<MessageGroup> // wrapper pour empiler plusieurs Message du même auteur
├── <Message>...</Message>
└── <Message>...</Message>API Reference
Message
| Prop | Type | Default | Description |
|---|---|---|---|
| align | "start" | "end" | "start" | Alignement du message. "end" déclenche flex-row-reverse (avatar à droite, bulle collée à droite) — typiquement pour les messages envoyés. |
| className | string | — | Classes CSS supplémentaires sur le root . |
| children | ReactNode | — | Enfants : typiquement MessageAvatar + MessageContent. |
MessageGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Wrapper qui empile plusieurs |
MessageAvatar
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Container de l'avatar. min-w-8 shrink-0 self-end + translate-y-8 quand un MessageFooter est présent (pour rester aligné avec la bulle). |
| children | ReactNode | — | Typiquement un |
MessageContent
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Colonne verticale qui empile Header + Bubble + Footer avec gap-2.5. |
MessageHeader
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Ligne au-dessus de la bulle (nom d'auteur, horodatage). text-xs muted-foreground. |
MessageFooter
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Ligne sous la bulle (statut "Delivered", actions "Undo"/"Retry"). Aligné à droite quand align="end". |
Data Attributes
Attributs qu'on peut cibler en CSS custom pour override le style par état.
| Attribute | On | Values | Description |
|---|---|---|---|
| data-slot | chaque sub-composant | "message" | "message-group" | "message-avatar" | "message-content" | "message-header" | "message-footer" | Sélecteur stable pour du styling custom. |
| data-align | Message | "start" | "end" | Reflète la prop align. Utilisé par MessageFooter pour justify-end en align=end. |
Keyboard
| Key | Action |
|---|---|
| Tab | Focus next interactive element (avatar link, footer button). |
| Enter / Space | Activate button/link in header/footer. |
Accessibility
Le composant Message n'a pas de rôle ARIA spécifique — c'est un container visuel. C'est aux enfants (Avatar, buttons de MessageFooter) de porter leurs propres aria-label et rôles quand nécessaire.
Pour un thread de messages, envelopper dans un conteneur avec role="log" et aria-live="polite" permet aux lecteurs d'écran d'annoncer les nouveaux messages sans interruption. Utiliser MessageScroller qui pose déjà les bons attributs.
Les BubbleReactions sont interactives : leur wrapper doit avoir aria-label="Reactions" et chaque bouton un aria-label décrivant la réaction ("Thumbs up", "Copy", ...). L'emoji seul n'est pas suffisant.
Le Marker pour les états système (spinner "Checking...") doit avoir role="status" pour être annoncé aux ATs comme un changement d'état non urgent.
Examples
Avatar
Group
Group Chat
Header and Footer
Actions
Attachment
Attachment Group
On This Page


