fix(web): move copy button to inline layout to prevent tool card overlap (#404)

The copy button was absolutely positioned (right-0 top-0) over the
entire message content area. When assistant messages contain both text
and tool calls (e.g. TodoWrite), the button overlapped the tool card UI.

Move the button from absolute positioning inside the content wrapper to
an inline flex layout after the content. This places it at the bottom-
right of the message, below all content (text + tool cards), so it never
overlaps anything. The hover-to-reveal behavior is preserved.

Also restores getAssistantCopyText to its original logic so mixed
text+tool messages remain copyable (the previous fix of suppressing the
button entirely for mixed messages was too aggressive).

via [HAPI](https://hapi.run)

Co-authored-by: HAPI <noreply@hapi.run>
This commit is contained in:
Haoqing Wang
2026-04-06 20:41:59 +08:00
committed by GitHub
co-authored by HAPI
parent c02f392d81
commit 7ba15d1e75
@@ -53,21 +53,23 @@ export function HappyAssistantMessage() {
return (
<MessagePrimitive.Root className={`${rootClass} ${copyText ? 'group/msg' : ''}`}>
<div className={`relative min-w-0 ${copyText ? 'pr-8' : ''}`}>
{copyText && (
<div className="min-w-0">
<MessagePrimitive.Content components={MESSAGE_PART_COMPONENTS} />
</div>
{copyText && (
<div className="flex justify-end mt-1 opacity-60 sm:opacity-0 sm:group-hover/msg:opacity-100 transition-opacity">
<button
type="button"
title="Copy"
className="absolute right-0 top-0 opacity-60 sm:opacity-0 sm:group-hover/msg:opacity-100 transition-[opacity,background-color] p-0.5 rounded hover:bg-[var(--app-subtle-bg)]"
className="p-0.5 rounded hover:bg-[var(--app-subtle-bg)] transition-colors"
onClick={() => copy(copyText)}
>
{copied
? <CheckIcon className="h-3.5 w-3.5 text-green-500" />
: <CopyIcon className="h-3.5 w-3.5 text-[var(--app-hint)]" />}
</button>
)}
<MessagePrimitive.Content components={MESSAGE_PART_COMPONENTS} />
</div>
</div>
)}
</MessagePrimitive.Root>
)
}