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. Accessibility

Chat Scroll

Accessibility

Import ChatScroll from @prepared911/ui/chat-scroll. The scroll root is role="log" with aria-live="polite" and aria-relevant="additions", named by label. A message appended to the list is announced once, in order. additions rather than the default additions text keeps a node and its text from matching twice, which some screen readers speak twice. Edits to the text of an existing message are not announced. Children are in chronological DOM order, so reading order and focus order match what is on screen. Scrollable's reverseOrder seats a short thread at the bottom and puts the loading row at the top without reordering the DOM.
History loads are silent
Adding older messages inserts nodes into a live region, and a polite log would read the whole page as new traffic. While loadingRow or errorRow renders, and for two animation frames after it goes away, the log is aria-live="off". Assistive technology reads a tree change after the frame that painted it, so the second frame is the grace that keeps the prepend quiet. Remove the row in the same update that adds the messages.
Keyboard and focus
When the log overflows and no message holds a focusable descendant, Scrollable makes it a focusable region named by label, so the arrow keys, Page Up and Down, Home and End scroll it. The jump control is an ordinary Button after the log in tab order, and it is outside the live region, so it appearing is not announced. The exiting control is inert. Activating the control with focus on it moves focus to the log (or, when the log is not focusable, to the list, a tabindex="-1" target) so focus never falls to the page. The list draws the shared focus ring, inset, after a keyboard activation; it appears instantly, with no transition. When unreadCount is above zero, jumpUnreadLabel(count) names the control (for example "Jump to latest 3"). Otherwise jumpToLatestLabel names it.
Motion, contrast, direction
  • Reduced motion: the jump scrolls instantly, the control's rise collapses through the glide tokens and its fade stays.
  • Forced colors: ChatScroll paints nothing of its own except the control's shadow, which the platform removes. The Button keeps its system-color edge, and Scrollable keeps the system scrollbar.
  • Right-to-left: the control stays centered and the overlay thumb sits at the inline start.
  • Windows: observers, timers, the reduced-motion query and the focus check use the window and document that own the log, so it works in a detached window.
Screen reader verification (announcing an appended message once, a silent prepend, the control's name) is manual and is an open item in CONTRACT.md.
Overlay
The overlay slot is a sibling of the log, so it is not announced as traffic. The jump control stays above it and out of its way, and the fade is a decorative background. Under forced colors the fade is a system canvas fill.
Previous
Chat Scroll / API and Development
Next
Checkbox / Usage
On this page
History loads are silent
Keyboard and focus
Motion, contrast, direction
Overlay