11import type { Message } from "../types/eval-protocol" ;
22import { useState } from "react" ;
3+ import Button from "./Button" ;
4+ import { Tooltip } from "./Tooltip" ;
35
46export const MessageBubble = ( { message } : { message : Message } ) => {
57 const [ isExpanded , setIsExpanded ] = useState ( false ) ;
8+ const [ copySuccess , setCopySuccess ] = useState ( false ) ;
69 const isUser = message . role === "user" ;
710 const isSystem = message . role === "system" ;
811 const isTool = message . role === "tool" ;
@@ -31,10 +34,20 @@ export const MessageBubble = ({ message }: { message: Message }) => {
3134 ? messageContent . substring ( 0 , 200 ) + "..."
3235 : messageContent ;
3336
37+ const handleCopy = async ( ) => {
38+ try {
39+ await navigator . clipboard . writeText ( messageContent ) ;
40+ setCopySuccess ( true ) ;
41+ setTimeout ( ( ) => setCopySuccess ( false ) , 2000 ) ;
42+ } catch ( err ) {
43+ console . error ( "Failed to copy message:" , err ) ;
44+ }
45+ } ;
46+
3447 return (
3548 < div className = { `flex ${ isUser ? "justify-end" : "justify-start" } mb-1` } >
3649 < div
37- className = { `max-w-sm lg:max-w-md xl:max-w-lg px-2 py-1 border text-xs ${
50+ className = { `max-w-sm lg:max-w-md xl:max-w-lg px-2 py-1 border text-xs relative ${
3851 isUser
3952 ? "bg-blue-50 border-blue-200 text-blue-900"
4053 : isSystem
@@ -44,7 +57,32 @@ export const MessageBubble = ({ message }: { message: Message }) => {
4457 : "bg-yellow-50 border-yellow-200 text-yellow-900"
4558 } `}
4659 >
47- < div className = "font-semibold text-xs mb-0.5 capitalize" >
60+ { /* Copy button positioned in top-right corner */ }
61+ < div className = "absolute top-1 right-1" >
62+ < Tooltip
63+ content = { copySuccess ? "Copied!" : "Copy message to clipboard" }
64+ position = "top"
65+ >
66+ < Button
67+ onClick = { handleCopy }
68+ size = "sm"
69+ variant = "secondary"
70+ className = { `p-0.5 h-5 text-[10px] opacity-60 hover:opacity-100 transition-opacity cursor-pointer ${
71+ isUser
72+ ? "text-blue-600 hover:bg-blue-100"
73+ : isSystem
74+ ? "text-gray-600 hover:bg-gray-100"
75+ : isTool
76+ ? "text-green-600 hover:bg-green-100"
77+ : "text-yellow-600 hover:bg-yellow-100"
78+ } `}
79+ >
80+ Copy
81+ </ Button >
82+ </ Tooltip >
83+ </ div >
84+
85+ < div className = "font-semibold text-xs mb-0.5 capitalize pr-8" >
4886 { message . role }
4987 </ div >
5088 < div className = "whitespace-pre-wrap break-words overflow-hidden text-xs" >
0 commit comments