Patterns
Chat kit
Messages, avatars and a streaming scroller.
A composed conversation demo using avatars, message rows, and an accessible follow-aware message scroller. The controls make the scroll and busy states visible without background work.
Conversation
A fixed-height transcript keeps MessageScroller as the inner scroll region; append, stream, and reset are ordinary LiveView events.
<.message_scroller id="chat-kit-demo" label="Chat kit conversation" follow={true} busy={@chat_demo_busy}>
<.message_scroller_item
:for={{message, index} <- Enum.with_index(@chat_demo_messages)}
message_id={message.id}
scroll_anchor={index == length(@chat_demo_messages) - 1 and not @chat_demo_busy}
>
<.message align={message.align} tone={message.tone}>
<:avatar><.avatar initials={message.initials} /></:avatar>
<:header>{message.header}</:header>
{message.body}
<:footer>{message.footer}</:footer>
</.message>
</.message_scroller_item>
<.message_scroller_item :if={@chat_demo_busy} message_id="chat-streaming" scroll_anchor>
<.message align="start" tone="surface">
<:avatar><.avatar initials="LU" /></:avatar>
<:header>Assistant - now</:header>
Assistant is typing...
</.message>
</.message_scroller_item>
</.message_scroller>
API reference
Props and slots, introspected from the component.
avatar/1| Prop | Type | Default | Description |
|---|---|---|---|
class |
any |
nil |
|
initials |
string |
nil |
|
shape |
circle | square |
"circle" |
|
size |
xs | sm | md | lg |
"md" |
|
| Slots | |||
:inner_block |
|||
message/1| Prop | Type | Default | Description |
|---|---|---|---|
align |
start | end |
"start" |
|
class |
any |
nil |
|
tone |
primary | surface |
"surface" |
|
| Slots | |||
:avatar |
|||
:footer |
|||
:header |
|||
:inner_block |
|||
message_scroller/1| Prop | Type | Default | Description |
|---|---|---|---|
busy |
boolean |
false |
|
class |
any |
nil |
|
follow |
boolean |
true |
Follow the latest message and mount at the bottom |
id* |
string |
— |
|
label |
string |
"Messages" |
|
peek |
integer |
40 |
|
| Slots | |||
:inner_block* |
|||
message_scroller_item/1| Prop | Type | Default | Description |
|---|---|---|---|
class |
any |
nil |
|
id |
string |
nil |
|
message_id |
string |
nil |
|
scroll_anchor |
boolean |
false |
|
| Slots | |||
:inner_block* |
|||