Skip to content

MessageStream

<caos-message-stream>

the scrolling list of messages, with its days, its unread line and its grouping

May be placed on a record page, an app’s home page and a page inside an app.

Name Attribute Description Type Default Required
key key, markup only Which conversation this is. Changing it is what tells the stream a different conversation is being read, and is the only thing that lets the unread line be placed again. A stream with no key behaves as one conversation that never changes. text none declared Optional
unreadSince unread-since, markup only When the reader last saw this conversation, as an ISO-8601 instant. The first message after it gets a “New messages” line above it. Read ONCE per conversation and then left alone — a line recomputed as messages arrive walks down the page ahead of the reader and marks nothing. text none declared Optional
highlight highlight, markup only The id of the message that was navigated to — from a search result or a link. That message is marked; setting it does not scroll. Use the reveal method to do both. text none declared Optional
emptyLabel empty-label, markup only What a conversation with nothing in it says. Worth setting: the default says a true thing about a list and nothing about what the reader could do next. text No messages yet. Optional

This piece raises no events.

Name What goes in it
pending What sits below the last message and above the composer — a <caos-typing-indicator>, or anything else that says the next message is on its way. Inside the scroller, so it is reached by scrolling to the bottom like a message is.
Design token What it controls
--caos-color-text The message text, and the jump control.
--caos-color-text-subtle A day divider’s words.
--caos-color-text-muted The empty state.
--caos-color-border The rules either side of a divider, and the jump control’s edge.
--caos-color-accent The unread line — its words and its rules, so it reads as different from a day.
--caos-color-surface Behind the jump control, so it stays legible over messages.
--caos-font The typeface of the dividers and the jump control.
--caos-text-label The size of a divider’s words.
--caos-text-body The size of the empty state.
--caos-font-weight-label The weight of a divider’s words.
--caos-space-2 The space above and below the list, and around a divider.
--caos-space-3 The inset of a divider, and where the jump control sits.
--caos-space-4 The padding of the empty state.
--caos-radius-pill The roundness of the jump control.
--caos-shadow-float The lift under the jump control, which floats over the messages.
--caos-focus-ring The ring on the jump control.
Name Description Arguments
scrollToLatest() Take the reader to the newest message, as the jump control does. not stated
isFollowing() Is the reader at the living end of the conversation? The same question the stream asks itself before deciding whether an arriving message should scroll the view. not stated
reveal() Bring one message into view and mark it. False when this stream is not holding that message — which is the answer a search result needs, because the message may be in a conversation that is not open. not stated

Nothing on this piece can be read back.

Part Which piece of it When it is there
::part(scroller) the scrolling region Always
::part(divider) a day divider Always
::part(unread) the new-messages line Always
::part(jump) the control that takes the reader to the latest message Always
::part(empty) the line shown when there are no messages Always

Messages that arrive over time and are read in order, where the reader scrolls back. The day dividers, the unread line and the grouping are all statements about a sequence; content with no sequence gets none of them and wants a list.

  • DataTable — The rows are records to be compared, sorted or selected. A conversation is read downwards and never sorted.
  • Accordion — The entries are sections of a document that open and close, rather than things said in order.
  • Tree — The shape that matters is nesting rather than time.

The stream is a role="log" with aria-live="polite": a region content is APPENDED to, announced as additions rather than as a region that was replaced, and politely — a message arriving must not interrupt a sentence the reader is in the middle of, since what it would interrupt them with is more of the same conversation. Day dividers and the unread line are role="separator" with a name, so the break is announced as a break instead of being read as part of the message under it. Each message is its own article, so a reader can move message by message. Left to the author: naming the stream — set aria-label to say WHICH conversation this is, because “log” on its own says only that it is one.

Two people, with the second message grouped under the first because it is the same person a minute later.

Cannot be shown as a page placement: is given aria-label, which is set on the element rather than declared as an input. A stored placement carries only a component’s own inputs, so a page copying this would place the piece without it.

<caos-message-stream aria-label="Deploys"></caos-message-stream>