Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Chat Conversation Skeleton Block for React Aria

A support chat window that loads in place: bars become seven bubbles, names, avatars, times and a drawn receipt, then your typed line joins the log in this tab only.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show a support conversation while its messages load, then swap them in without moving the window, with this chat conversation skeleton for React with React Aria. A fixed-height window holds the top bar of an order chat from Distaff, a support widget (the order number is known from the route, the reply promise is data), the message log and a real composer. The "Today" label and the system line are real from the first paint; each message is a bubble whose text, sender name, avatar and time are Skeleton bars that become the conversation in the same boxes, message by message, and a drawn receipt of the order appears under one reply. Once the messages are in, type a line and press Enter: it joins the log in this tab and the polite line says it was added here only, since nothing is sent and nobody replies. It's built from Skeleton, Message, Bubble, Avatar, Textarea, Shine Button and Guides, with a CSS entrance only. For support widgets, order chats and any thread that waits for its history.

FAQ

What stays local, and how do I wire it to a real conversation?

Nothing is fetched. The seven messages are typed in SEED, Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real messages when they arrive. The bars are derived from the same data as the content, so keep one component for both. Your own lines are only added to the log: send them to your backend in post and append the saved message when it returns.

Does the window keep its height while the messages load?

Each bar and its content sit in one grid cell, so the larger of the two sets the cell's box and the swap changes nothing around it. The window is a fixed height and only the log scrolls; each bubble's text is in the same cell as its bar, so a two-line message is two lines tall in both phases. The chrome is real in both phases and the polite line reserves two lines, so the window is exactly as tall before, during and after loading at every width.

Can I send a message before the history arrives?

No: the composer is real from the first paint, so you can type, but sending is refused until the messages are in and the polite line says to load them first. Enter sends, Shift and Enter add a line, and focus stays in the composer after you send.

What is the receipt under one of the replies?

A drawn figure with the order's lines and total, built from typed amounts in whole cents so the total is exact. It is a box until the messages arrive and sits in the same cell as its bar, so the log does not jump when it appears.

Is it accessible?

The window is marked busy while it loads and carries a screen-reader-only "Loading messages…". The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The message log is a named, focusable region so the keyboard can scroll it, the composer has a label, and the one polite line under it announces what loaded and what you did, once. Under reduced motion there is no pulse, no spinner and no stagger: the swap is instant.

Does it work in right-to-left languages?

Yes. The window mirrors, the send arrow flips, names and messages sit in isolated runs so mixed text keeps its order, and times and amounts keep their digits in order.