Axon 911 Frontend DocsAxon 911 Frontend Docs
Axon 911 Frontend Docs
    Loading navigation…
U
User
Switch to light mode
  1. Components
  2. Chat Scroll
  3. Usage

Chat Scroll

Usage

Use ChatScroll for the scrolling part of a chat transcript. Give it a frame with a height (a flex item that can shrink, or a box with a block size), the messages as plain children oldest first, a label that names the conversation, and a jumpToLatestLabel. It renders one Scrollable and nothing else scrolls, so a consumer such as MessageList never implements pin-to-bottom itself.
Staying at the latest message
The transcript mounts at its latest message. While the reader is there, a message added at the end keeps them there. Once they scroll up the viewport stays where it is, and a jump to latest control appears at the block end of the transcript. It is a default icon-only Button with a downward arrow. When unreadCount is above zero, pass jumpUnreadLabel so assistive technology hears the count; nothing is shown visually. Activating it scrolls to the latest message, smoothly unless the reader prefers reduced motion. The control lives inside the ChatScroll box, so put the composer outside it, below, and the control can never cover it. unreadCount is a number you own. Count messages that arrive while onAtEndChange last reported false, and reset the count when it reports true. ChatScroll never counts children, because only you know which of them are messages. A short thread sits at the bottom of the frame, and the control never shows while the content fits.
Loading older messages
onReachStart is called when the oldest loaded message scrolls into view. Render a loadingRow while the page loads and an errorRow if it fails. Both appear at the top of the transcript and pause onReachStart while they show. Remove the row in the same update that adds the older messages: the reader's place does not move, whatever the size of the page, and the log stays silent for assistive technology until the row has gone. Older messages are added above the viewport. ChatScroll measures an anchor message after every commit, scroll and resize and corrects the offset by how far it moved, so images that load above the viewport and a page that arrives at the very start both leave the reader where they were. Native scroll anchoring is off inside the list. Avoid position: sticky among the messages' direct children, because a sticky element moves with the scroll and misleads the anchor.
Messages
Children are plain elements in one list. Wrapping messages in groups (one element per day or per sender) is fine. The list has one rhythm and no density option: a --space-24 gutter and a 20px gap between children, added to the children's own spacing. In a MessageList that puts items 28px apart within a sender and 44px apart at a change of sender or around a system line (its 8px and 24px margins plus the gap; the values are owner-confirm 12 in the contract).
A floating composer
Pass the composer as overlay. It takes its own row at the block end, below the transcript, with a fade from the page surface reaching up over the transcript's last few pixels. The transcript ends where the composer starts, so the latest message is never covered, even in the server's markup and while the composer grows, and the jump control sits above it. Nothing is measured. The overlay is outside the log, so it is not announced as transcript. Use a docked composer beside ChatScroll instead when the composer should not overlap messages.
What it does not do
ChatScroll does not scroll when the reader sends a message. Write the offset through ref, which is the log element, or call back from your composer. It does not count unread messages and it does not fetch history.
Previous
Chat Input / Accessibility
Next
Chat Scroll / API and Development
On this page
Staying at the latest message
Loading older messages
Messages
A floating composer
What it does not do