howdy/ui/chat
Chat: a conversation that keeps to its newest message, messages with an avatar and a header, speech bubbles, reactions and notes.
chat.conversation(words.english(), [attribute.aria_label("Messages")], [
chat.note([text("Today")]),
chat.message(chat.Incoming, avatar: avatar.initials("GH"), header: [text("Grace · 09:41")], content: [
chat.bubble(chat.Incoming, [text("Did the deploy go out?")]),
]),
chat.message(chat.Outgoing, avatar: element.none(), header: [], content: [
chat.bubble(chat.Outgoing, [text("Ten minutes ago.")]),
chat.reactions([chat.reaction("👍", 2, [])]),
]),
])
A conversation stays at its newest message as messages arrive or a reply
streams in, and keeps its place when you scroll back to read. It needs no
script: it is laid out from the bottom, and the browser anchors the
scroll position. It is a log for screen readers, so they announce new
messages. Give each message an id to link to it.
Older history can be added above the first message, such as when
on_older asks for it, and the reader’s place stays put. remember
brings a reader back to where they were after a reload, and
start_at opens the conversation at a message, such as the first
unread one.
Types
Who wrote a message: someone else, or the person reading.
pub type Side {
Incoming
Outgoing
}
Constructors
-
Incoming -
Outgoing
How a note or status line stands out.
pub type Tone {
Neutral
Accent
Critical
}
Constructors
-
Neutral -
AccentThe primary colour, such as for “New messages”.
-
CriticalThe danger colour, such as for “Deploy failed”.
A bubble’s surface.
pub type Variant {
Filled
Muted
Outline
Ghost
Danger
}
Constructors
-
FilledThe primary colour: the reader’s own messages, by default.
-
MutedThe muted colour: everyone else’s messages, by default.
-
Outline -
GhostNo surface, for long replies that read better as plain text.
-
DangerThe danger colour, such as for a message that failed to send.
Values
pub fn bubble(
side: Side,
children: List(element.Element(msg)),
) -> element.Element(msg)
A speech bubble: filled with the primary colour for your own messages, the muted colour for everyone else’s.
pub fn conversation(
words: words.Words,
attributes: List(attribute.Attribute(msg)),
children: List(element.Element(msg)),
) -> element.Element(msg)
The scrolling list of messages. Size it with a height or by placing it
in a flex column; label it with aria-label. When it is scrolled back
from the newest message, a button saying the words’ jump_to_newest
appears.
pub fn footer_class() -> css.Class
pub fn frame_class() -> css.Class
pub fn header_class() -> css.Class
pub fn jump(
id: String,
children: List(element.Element(msg)),
) -> element.Element(msg)
A button that scrolls the conversation to the message with this id and highlights it for a moment, such as a reply’s quote of what it answers.
pub fn jump_class() -> css.Class
pub fn latest_class() -> css.Class
pub fn message(
side: Side,
attributes attributes: List(attribute.Attribute(msg)),
avatar avatar: element.Element(msg),
header header: List(element.Element(msg)),
content content: List(element.Element(msg)),
footer footer: List(element.Element(msg)),
) -> element.Element(msg)
One message, or a run of messages from one person: an avatar beside a
header, the content and a footer. Several bubbles in the content join
into one group. Pass element.none() for no avatar, and [] for no
header or footer. Give it an id in attributes to link to it with
jump.
pub fn note(
children: List(element.Element(msg)),
) -> element.Element(msg)
A line between messages, such as a date or “Grace joined”.
pub fn on_older(message: msg) -> attribute.Attribute(msg)
Hear when the reader has scrolled back near the oldest message shown, to load older ones and add them above it. It is sent once until more messages arrive. Put it in the conversation’s attributes.
pub fn reaction(
emoji: String,
count: Int,
attributes: List(attribute.Attribute(msg)),
) -> element.Element(msg)
A reaction and how many people chose it. Mark the reader’s own with
attribute.aria_pressed("true"), and add a click handler to toggle it.
pub fn reaction_class() -> css.Class
pub fn reactions(
children: List(element.Element(msg)),
) -> element.Element(msg)
A row of reactions under a message.
pub fn reactions_class() -> css.Class
pub fn remember(key: String) -> attribute.Attribute(msg)
Keep the reader’s place in this conversation, named key, for the rest
of the browser session, and go back to it when the page is reloaded.
Put it in the conversation’s attributes.
pub fn scroller_class() -> css.Class
pub fn start_at(id: String) -> attribute.Attribute(msg)
Open the conversation with the message with this id at the top, such as the first unread one, instead of at the newest. A remembered place wins.
pub fn status(
tone: Tone,
icon: element.Element(msg),
children: List(element.Element(msg)),
) -> element.Element(msg)
A line of news from the system rather than a person, with an icon: “Deploy finished”, “Grace changed the topic”.
pub fn status_icon_class() -> css.Class
pub fn styled_bubble(
side: Side,
variant: Variant,
children: List(element.Element(msg)),
) -> element.Element(msg)
A bubble with another surface. side still decides which corner points
at its sender.
pub fn tinted_note(
tone: Tone,
children: List(element.Element(msg)),
) -> element.Element(msg)
A line between messages in a tone, such as “New messages” in the accent colour.