Message scroller
Une zone de défilement de chat qui suit les nouveaux messages, garde votre position quand vous remontez et compte les messages manqués sur le bouton de retour en bas.
New chat
How can I help you today?
The prompt is read only. Press send to play the next turn.
pnpm dlx shadcn@latest add https://hextaui.com/r/message-scroller.jsonAjoute le composant, les tokens de thème HextaUI et les composants HextaUI dont il dépend.
Ajoutez les tokens de thème à votre CSS global, si ce n’est pas déjà fait.
Installez les dépendances.
pnpm add @shadcn/react @tabler/icons-react cnCopiez et collez le code suivant dans votre projet.
components/ui/message-scroller.tsx components/ui/button.tsx lib/motion.ts Mettez à jour les chemins d’import selon la configuration de votre projet.
Donnez à chaque élément un messageId stable. Le scroller s'en sert pour suivre les nouveaux messages, garder votre position et compter ce que vous n'avez pas vu. Associez-le à <Message /> et <Bubble /> pour les lignes.
Chat de groupe
Les ancres ne sont pas forcément des messages. Ici, un <Marker /> pour une personne qui rejoint démarre le tour. Faites défiler vers le haut, recevez des messages, et le bouton de saut compte ce qui est arrivé pendant votre absence.
Garder le contexte
scrollPreviousItemPeek garde une tranche du tour précédent au-dessus d'un tour nouvellement ancré, pour que le fil reste continu. Essayez chaque valeur, puis posez la question suivante.
Ouverture de fils enregistrés
defaultScrollPosition="last-anchor" rouvre une conversation sur sa dernière question, avec la réponse en dessous, au lieu de déposer le lecteur au milieu d'une réponse, en bas.
Chargement des messages précédents
Les anciens messages ajoutés au-dessus laissent en place ce que vous lisez (preserveScrollOnPrepend, activé par défaut).
Sauter vers des messages
useMessageScroller pilote le fil depuis l'extérieur, et useMessageScrollerVisibility indique le tour en cours, pour que le plan mette en évidence où vous en êtes.
Dans le provider, ces hooks permettent à vos propres contrôles de faire défiler le fil et de réagir à ce qui est à l'écran.
| Touche | Action |
|---|---|
| Tab | Donne le focus à la conversation. Le bouton de saut n'entre dans l'ordre de tabulation que lorsqu'il est affiché. |
| ↑↓ | Fait défiler la conversation. |
| Page UpPage Down | Défile d'un écran. |
| HomeEnd | Saute au premier ou au dernier message. |
- Le viewport est une région focalisable avec un label et le contenu est un
role="log", si bien que les lecteurs d'écran annoncent les nouveaux messages à leur arrivée. Donnez unaria-labelau viewport. - Le label du bouton de saut indique combien de messages sont nouveaux : « 3 nouveaux messages » est lu à voix haute, pas seulement une flèche.
- Suivre les nouveaux messages ne vous déplace jamais quand vous relisez. Le suivi ne reprend que lorsque vous êtes de nouveau en bas.
| Prop | Type | Par défaut |
|---|---|---|
autoScrollSuit les nouveaux messages tant que le lecteur est en bas. | boolean | false |
defaultScrollPositionLà où s'ouvre le fil. | "start" | "end" | "last-anchor" | "end" |
scrollPreviousItemPeekQuelle part de l'élément précédent reste visible au-dessus d'une nouvelle ancre. | number | 64 |
scrollEdgeThresholdPixels à partir d'un bord qui comptent encore comme y étant. | number | – |
scrollMarginEspace conservé au-dessus des messages amenés dans la vue. | number | – |
| Prop | Type | Par défaut |
|---|---|---|
preserveScrollOnPrependConserve la position de lecture quand des messages sont ajoutés au-dessus. | boolean | false |
aria-labelNomme la région de conversation. | string | – |
| Attribut | Description |
|---|---|
data-scrollable="start end" | Quels bords ont encore du contenu à faire défiler. Pilote les fondus aux bords. |
data-autoscrolling | Présent pendant le suivi des nouveaux messages. La barre de défilement se masque. |
--scroller-fade-start / --scroller-fade-end | Taille des fondus aux bords. Ils s'animent à l'entrée et à la sortie. |
| Prop | Type | Par défaut |
|---|---|---|
messageIdId stable pour le suivi, les ancres et les compteurs. | string | – |
scrollAnchorFait défiler cet élément en haut à son arrivée, avec defaultScrollPosition="last-anchor". | boolean | false |
| Prop | Type | Par défaut |
|---|---|---|
direction | "start" | "end" | "end" |
showUnseenSe transforme en pastille qui compte les messages arrivés pendant que vous étiez remonté. | boolean | true |
unseenLabel | (count: number) => ReactNode | "3 new messages" |
variant | Button variant | "outline" |
behavior | ScrollBehavior | "smooth" |
| Attribut | Description |
|---|---|
data-slot="message-scroller-button" | Cible le bouton en CSS. |
data-active | "true" tant qu'il existe une destination où aller. |
data-unseen | Le nombre de messages non vus, tant qu'il est supérieur à zéro. |
- ButtonDes boutons dans toutes les variantes et tailles, avec un flux de chargement, de succès et d’erreur intégré qui évite le spinner pour les requêtes rapides.
- MotionLes courbes d’easing, les durées et la vérification de réduction des animations utilisées par chaque composant, ainsi que des hooks pour les morphs de taille et les surlignages glissants.
- MessageUne ligne de message de chat avec avatar, nom, bulles et statut, où les nouveaux messages remontent depuis le côté de l’expéditeur.
- AttachmentDes cartes de fichiers et d’images pour les uploads, avec progression, états, actions, un déclencheur sur toute la carte et des noms qui conservent leur extension.
- BubbleDes bulles de messages de chat avec variantes, coins groupés, réactions et place pour du contenu interactif.
- MarkerDes notes discrètes entre les contenus, comme les séparateurs de date et les événements système, avec des dates et heures fixes qui se lisent « Aujourd’hui » ou « Hier ».
Utilisé dans les blocks
Des blocks qui s’appuient sur Message scroller.
- Prompt InputUn champ de discussion qui démarre sur une seule ligne sobre, grandit en carte à mesure que vous écrivez et descend une fois la conversation lancée. Entrée envoie, sans risque avec la saisie japonaise et chinoise. Collez, déposez ou choisissez des fichiers avec aperçus, progression et nouvel essai. @ ajoute des fichiers et / lance des commandes depuis un menu au niveau du curseur. Un sélecteur de modèle avec touches numériques, un curseur d’effort qui s’anime à Max, un anneau de contexte, la dictée avec forme d’onde en direct, des chips d’outils, une file pour les messages saisis pendant qu’une réponse arrive en streaming, et des brouillons qui survivent à un rechargement.
- Agent TodosAffichez le plan d’un agent pendant son travail. Chaque étape passe de backlog à à faire, en cours puis terminé, avec des durées en direct, les échecs et les appels d’outils qui les sous-tendent. Une pastille de statut à placer au-dessus du champ de saisie, des changements de plan visibles et une étape de relecture pour modifier le plan avant son exécution.
- Chat ThreadToute la conversation autour du champ de saisie. Votre question reste épinglée en haut pendant que la réponse arrive en streaming, des points de repère sur le côté permettent de sauter d’un message à l’autre, et chaque réponse peut être copiée, modifiée, relancée, notée et basculée entre versions. Les réponses affichent du Markdown avec blocs de code, tableaux et citations, et la réflexion, les appels d’outils et Prompt Input s’y insèrent directement.
- Code BlockDes blocs de code conçus pour les réponses d’IA. Coloration syntaxique qui suit le streaming, copie, téléchargement et retour à la ligne, numéros de ligne et lignes surlignées, diffs avec accepter et rejeter, et un terminal pour les commandes.