fix(webui): normalize action tooltips

This commit is contained in:
Xubin Ren 2026-06-10 04:10:24 +08:00
parent 1432094bb5
commit fd947a1fd8
2 changed files with 60 additions and 45 deletions

View File

@ -22,6 +22,12 @@ import { AttachmentTile } from "@/components/AttachmentTile";
import { CliAppMentionText } from "@/components/CliAppMentionText"; import { CliAppMentionText } from "@/components/CliAppMentionText";
import { ImageLightbox } from "@/components/ImageLightbox"; import { ImageLightbox } from "@/components/ImageLightbox";
import { MarkdownText, preloadMarkdownText } from "@/components/MarkdownText"; import { MarkdownText, preloadMarkdownText } from "@/components/MarkdownText";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { copyTextToClipboard } from "@/lib/clipboard"; import { copyTextToClipboard } from "@/lib/clipboard";
import { formatTurnLatency } from "@/lib/format"; import { formatTurnLatency } from "@/lib/format";
@ -187,50 +193,60 @@ export function MessageBubble({
</MarkdownText> </MarkdownText>
{media.length > 0 ? <MessageMedia media={media} align="left" /> : null} {media.length > 0 ? <MessageMedia media={media} align="left" /> : null}
{showAssistantFooterRow ? ( {showAssistantFooterRow ? (
<div className="mt-2 flex min-h-8 flex-wrap items-center gap-x-2 gap-y-1 text-muted-foreground"> <TooltipProvider delayDuration={220} skipDelayDuration={80}>
{showCopyButton ? ( <div className="mt-2 flex min-h-8 flex-wrap items-center gap-x-2 gap-y-1 text-muted-foreground">
<button {showCopyButton ? (
type="button" <Tooltip>
onClick={onCopyAssistantReply} <TooltipTrigger asChild>
aria-label={copyReplyLabel} <button
title={copyReplyLabel} type="button"
className={cn( onClick={onCopyAssistantReply}
"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full", aria-label={copyReplyLabel}
"transition-colors hover:bg-muted/55 hover:text-foreground", className={cn(
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full",
)} "transition-colors hover:bg-muted/55 hover:text-foreground",
> "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
{copied ? ( )}
<Check className="h-4 w-4" aria-hidden /> >
) : ( {copied ? (
<Copy className="h-4 w-4" aria-hidden /> <Check className="h-4 w-4" aria-hidden />
)} ) : (
</button> <Copy className="h-4 w-4" aria-hidden />
) : null} )}
{showForkButton ? ( </button>
<button </TooltipTrigger>
type="button" <TooltipContent side="top" align="center">{copyReplyLabel}</TooltipContent>
onClick={onForkFromHere} </Tooltip>
aria-label={forkLabel} ) : null}
title={forkLabel} {showForkButton ? (
className={cn( <Tooltip>
"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full", <TooltipTrigger asChild>
"transition-colors hover:bg-muted/55 hover:text-foreground", <button
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", type="button"
)} onClick={onForkFromHere}
> aria-label={forkLabel}
<GitFork className="h-4 w-4" aria-hidden /> className={cn(
</button> "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full",
) : null} "transition-colors hover:bg-muted/55 hover:text-foreground",
{showLatencyFooter ? ( "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
<span )}
className="text-[11px] leading-none text-muted-foreground/70 tabular-nums" >
title={t("message.turnLatencyTitle")} <GitFork className="h-4 w-4" aria-hidden />
> </button>
{formatTurnLatency(latencyMs)} </TooltipTrigger>
</span> <TooltipContent side="top" align="center">{forkLabel}</TooltipContent>
) : null} </Tooltip>
</div> ) : null}
{showLatencyFooter ? (
<span
className="text-[11px] leading-none text-muted-foreground/70 tabular-nums"
title={t("message.turnLatencyTitle")}
>
{formatTurnLatency(latencyMs)}
</span>
) : null}
</div>
</TooltipProvider>
) : null} ) : null}
</> </>
)} )}

View File

@ -1768,7 +1768,6 @@ export function ThreadComposer({
disabled={voiceRecorder.buttonDisabled} disabled={voiceRecorder.buttonDisabled}
aria-label={voiceButtonLabel} aria-label={voiceButtonLabel}
aria-keyshortcuts={VOICE_SHORTCUT_ARIA} aria-keyshortcuts={VOICE_SHORTCUT_ARIA}
title={voiceButtonTooltip}
onPointerDown={voiceRecorder.beginPress} onPointerDown={voiceRecorder.beginPress}
onPointerUp={voiceRecorder.endPress} onPointerUp={voiceRecorder.endPress}
onPointerCancel={voiceRecorder.endPress} onPointerCancel={voiceRecorder.endPress}