feat(site): copy PR branch name from git panel (#25589)

This commit is contained in:
McKayla はな
2026-06-08 13:21:18 -06:00
committed by GitHub
parent 18919425f9
commit f242ef0799
2 changed files with 52 additions and 1 deletions
@@ -1,5 +1,6 @@
import {
ArrowLeftIcon,
CopyIcon,
ExternalLinkIcon,
GitBranchIcon,
GitMergeIcon,
@@ -11,6 +12,13 @@ import { type FC, type RefObject, useEffect, useState } from "react";
import { useQuery } from "react-query";
import { chatDiffContents } from "#/api/queries/chats";
import type * as TypesGen from "#/api/typesGenerated";
import { CheckIcon } from "#/components/AnimatedIcons/Check";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "#/components/Tooltip/Tooltip";
import { useClipboard } from "#/hooks/useClipboard";
import { cn } from "#/utils/cn";
import { parsePullRequestUrl } from "../../utils/pullRequest";
import type { ChatMessageInputRef } from "../AgentChatInput";
@@ -22,6 +30,35 @@ import { useParsedDiff } from "../DiffViewer/useParsedDiff";
export { InlinePromptInput } from "../DiffViewer/CommentableDiffViewer";
// -------------------------------------------------------------------
// Branch copy button
// -------------------------------------------------------------------
const BranchCopyButton: FC<{ branch: string }> = ({ branch }) => {
const { copyToClipboard, showCopiedSuccess } = useClipboard();
return (
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
onClick={() => copyToClipboard(branch)}
aria-label={`Copy branch name: ${branch}`}
className="inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0.5 text-content-secondary transition-colors hover:bg-surface-secondary hover:text-content-primary"
>
{showCopiedSuccess ? (
<CheckIcon className="size-3" />
) : (
<CopyIcon className="size-3" />
)}
</button>
</TooltipTrigger>
<TooltipContent side="bottom">
{showCopiedSuccess ? "Copied" : "Copy branch name"}
</TooltipContent>
</Tooltip>
);
};
// -------------------------------------------------------------------
// PR state badge
// -------------------------------------------------------------------
@@ -146,7 +183,12 @@ export const RemoteDiffPanel: FC<RemoteDiffPanelProps> = ({
{headBranch && baseBranch && (
<ArrowLeftIcon className="size-3 shrink-0 opacity-50" />
)}
{headBranch && <span className="truncate"> {headBranch}</span>}
{headBranch && (
<>
<span className="truncate"> {headBranch}</span>
<BranchCopyButton branch={headBranch} />
</>
)}
</>
) : parsedPr ? (
<span className="truncate">
@@ -138,6 +138,15 @@ export const PullRequestAndWorkingChanges: Story = {
diff: sampleDiff,
});
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// The branch row exposes a button that copies the PR head
// branch name. The aria-label embeds the branch so a single
// query is enough to assert both presence and target.
await expect(
canvas.getByLabelText("Copy branch name: feat/add-mcp-config"),
).toBeVisible();
},
};
/** Draft PR with head/base branches. */