Component registry
Chat
A conversation: messages as room lines or bubbles, each with its actions in one cluster at its corner, and the box that sends, replies and edits.
Live web demo
Hover a message (on a phone, tap it): reply, edit, translate and copy are one cluster at its corner. Edit puts the words in the box; Enter saves, Esc puts back what was there. The demo keeps its messages on this page.
Web source: openvibe-shared/messages · OVMessages.render(list, { messages, view, me, actions, onAction }); OpenVibeComposer.mount(box, { preset: 'chat' }) with .reply() and .edit()
Anatomy
- messagesroom lines or bubbles, grouped by person, with their time
- actionsreply, edit, translate, copy: one cluster at a message's corner, on hover, focus or a tap
- editedone quiet word after the words, the time as its title
- bar"Replying to …" or "Editing your message" above the box
- composerthe chat preset: attach, emoji, voice and a round send
Props
messages- message[]
view- "room" | "bubbles"
me- id
actions- id[] | (message, { mine }) => id[]
onAction- function
Behavior and accessibility
- States
- default · hover · acting · replying · editing · edited
- Tokens
- color.bg.raised · color.text.muted · color.accent · size.tap
- Keyboard
- Keeps the focused control in view
- Outside tap
- Closes the surface
- Scroll lock
- Page remains scrollable
- Reduced motion
- Remove movement; keep the state change.
- Accessibility
- Chat. Each action is a labelled button reached by Tab; Esc stops a reply or an edit. At least 44 × 44 dp or pt for every touch action.
Android · Jetpack Compose
A LazyColumn of messages; a long press opens the actions as a menu anchored at the message; the composer sits on the bottom bar with a reply or edit strip above it (imePadding).
Material 3 container: SurfaceContainerHigh
iOS · SwiftUI
A List of messages with a contextMenu for the actions; the composer above the keyboard with a reply or edit strip.
Example definition
{
"schema": "design.component@1",
"name": "chat",
"props": {
"view": "room",
"actions": [
"reply",
"edit",
"copy"
]
}
}