Message
A single row in a conversation. The two sides are deliberately asymmetric: the user's words are an embossed key they placed on the surface; the assistant's reply is flat prose — the surface itself speaking.
tsx
import {
Message,
MessageAvatar,
MessageContent,
} from "@/registry/seam/ui/message"
export default function MessageDemo() {
return (
<div className="flex w-full max-w-md flex-col gap-2">
<Message from="user">
<MessageContent>
How do springs differ from durations in seamui?
</MessageContent>
</Message>
<Message from="assistant">
<MessageAvatar name="Seam UI" />
<MessageContent>
Springs are physics-based — they react to velocity, so a press settles
naturally instead of running a fixed clock. Durations are reserved for
opacity fades and layout dimensions that can't spring cleanly.
</MessageContent>
</Message>
</div>
)
}bunx --bun @seamui/cli@latest add messageNotes
- Each row rises off the canvas on
springs.snappyas it enters; under reduced motion it fades in place and the actions appear instantly. - Actions reveal with an opacity-only transition on hover and
:focus-within, so keyboard users can reach them. Each action button requires anaria-label. MessageAvatardogfoods Avatar with an initials fallback derived fromname.- The live region that announces streamed messages lives on
Conversation, not here, to avoid double-announcing.
Press feedback, reduced motion, and haptics follow the global policy — see Motion and Haptics.