Skip to content

Conversation

User Message

A sent prompt with attachments, edit-in-place and resend, copy, and a delivery state.

2 variantsMIT

Preview

Translate the onboarding emails into German and keep product names in English.
Sending

Installation

Copies the component into components/ui and installs its dependencies and theme tokens.

pnpm dlx shadcn@latest add https://tuffui.com/r/user-message.json

Usage

Pass your own data and wire the callbacks to your agent runtime.

import { UserMessage } from "@/components/ui/user-message";

export function Prompt({ message }: { message: Message }) {
  return (
    <UserMessage
      data={{
        id: message.id,
        content: message.text,
        attachments: message.files,
        sentAt: formatTime(message.createdAt),
        status: message.status, // "sending" | "sent" | "failed"
        edited: message.edited,
      }}
      onEdit={(text) => chat.editAndResend(message.id, text)}
      onRetry={() => chat.resend(message.id)}
    />
  );
}

Props

PropTypeDefaultDescription
data*UserMessageData—The prompt text, attachments, display time and delivery status.
onEdit(text: string) => void—Save & resend from the inline editor (Enter saves, Shift+Enter adds a line, Esc cancels). The edit action is hidden without it.
onRetry() => void—Shows a Retry button when the status is failed.
onCopy(text: string) => void—Called after the text is copied to the clipboard.
classNamestring—Extra classes for the root.
type UserMessageData = {
  id: string;
  content: string;
  attachments?: { id: string; name: string; kind: "image" | "file"; size?: number; previewUrl?: string }[];
  sentAt?: string;            // display time, e.g. "14:02"
  status?: "sending" | "sent" | "failed";
  edited?: boolean;
};