chat-message-demo

PreviousNext
Docs
simple-aiexample

Preview

Loading preview…
./src/registry/examples/chat-message-demo.tsx
"use client";

import type { UIMessage } from "@ai-sdk/react";
import { Copy, ThumbsUp } from "lucide-react";
import {
	ChatMessage,
	ChatMessageAction,
	ChatMessageActions,
	ChatMessageAuthor,
	ChatMessageAvatar,
	ChatMessageAvatarFallback,
	ChatMessageAvatarImage,
	ChatMessageContainer,
	ChatMessageContent,
	ChatMessageHeader,
	ChatMessageMarkdown,
	ChatMessageThread,
	ChatMessageThreadAction,
	ChatMessageThreadReplyCount,
	ChatMessageThreadTimestamp,
	ChatMessageTimestamp,
} from "@/registry/ui/chat-message";

const messages: UIMessage<{
	member: {
		image: string;
		name: string;
	};
	threadData?: {
		messageCount: number;
		lastReply: Date;
		member: {
			image: string;
			name: string;
		};
	};
}>[] = [
	{
		id: "1",
		parts: [
			{
				type: "text",
				text: "Can you implement the new user authentication feature?",
			},
		],
		role: "user",
		metadata: {
			member: {
				image: "/avatar-1.png",
				name: "Pedro",
			},
		},
	},
	{
		id: "2",
		parts: [
			{
				type: "text",
				text: "Sure, I'll work on implementing the user authentication feature. I'll respond on the thread with updates as I progress.",
			},
		],
		role: "assistant",
		metadata: {
			member: {
				image: "/avatar-2.png",
				name: "Project Assistant",
			},
			threadData: {
				messageCount: 3,
				lastReply: new Date(),
				member: {
					image: "/avatar-1.png",
					name: "Pedro",
				},
			},
		},
	},
	{
		id: "3",
		parts: [
			{
				type: "text",
				text: "What's the progress on the other task?",
			},
		],
		role: "user",
		metadata: {
			member: {
				image: "/avatar-1.png",
				name: "Pedro",
			},
		},
	},
];

export default function ChatMessageDemo() {
	return (
		<div className="w-full max-h-[400px] overflow-y-auto">
			{messages.map((message) => (
				<ChatMessage key={message.id}>
					<ChatMessageActions>
						<ChatMessageAction label="Copy">
							<Copy className="size-4" />
						</ChatMessageAction>
						<ChatMessageAction label="Like">
							<ThumbsUp className="size-4" />
						</ChatMessageAction>
					</ChatMessageActions>

					<ChatMessageAvatar>
						<ChatMessageAvatarImage
							src={message.metadata?.member.image}
						/>
						<ChatMessageAvatarFallback>
							{message.metadata?.member.name
								.charAt(0)
								.toUpperCase()}
						</ChatMessageAvatarFallback>
					</ChatMessageAvatar>

					<ChatMessageContainer>
						<ChatMessageHeader>
							<ChatMessageAuthor>
								{message.metadata?.member.name}
							</ChatMessageAuthor>
							<ChatMessageTimestamp createdAt={new Date()} />
						</ChatMessageHeader>

						<ChatMessageContent>
							{message.parts
								.filter((part) => part.type === "text")
								.map((part) => (
									<ChatMessageMarkdown
										key={part.type}
										content={part.text}
									/>
								))}
						</ChatMessageContent>

						{message.metadata?.threadData && (
							<ChatMessageThread>
								<ChatMessageAvatar>
									<ChatMessageAvatarImage
										src={
											message.metadata?.threadData.member
												.image
										}
									/>
									<ChatMessageAvatarFallback>
										{message.metadata?.threadData.member.name
											.charAt(0)
											.toUpperCase()}
									</ChatMessageAvatarFallback>
								</ChatMessageAvatar>
								<ChatMessageThreadReplyCount>
									{message.metadata.threadData.messageCount}{" "}
									replies
								</ChatMessageThreadReplyCount>
								<ChatMessageThreadTimestamp
									date={message.metadata.threadData.lastReply}
								/>
								<ChatMessageThreadAction />
							</ChatMessageThread>
						)}
					</ChatMessageContainer>
				</ChatMessage>
			))}
		</div>
	);
}

Installation

npx shadcn@latest add @simple-ai/chat-message-demo

Usage

import { ChatMessageDemo } from "@/components/chat-message-demo"
<ChatMessageDemo />