Skip to content

Commit 1f53297

Browse files
authored
feat(code): add copy source button to markdown viewer (#1948)
1 parent e5fc811 commit 1f53297

1 file changed

Lines changed: 34 additions & 13 deletions

File tree

apps/code/src/renderer/features/code-editor/components/CodeEditorPanel.tsx

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import { usePanelLayoutStore } from "@features/panels";
1313
import { useFileTreeStore } from "@features/right-sidebar/stores/fileTreeStore";
1414
import { useCwd } from "@features/sidebar/hooks/useCwd";
1515
import { useIsWorkspaceCloudRun } from "@features/workspace/hooks/useWorkspace";
16-
import { Code, Eye } from "@phosphor-icons/react";
16+
import { Check, Code, Copy, Eye } from "@phosphor-icons/react";
1717
import { Box, Flex, IconButton, Text } from "@radix-ui/themes";
1818
import { trpcClient, useTRPC } from "@renderer/trpc/client";
1919
import type { Task } from "@shared/types";
2020

2121
import { useQuery } from "@tanstack/react-query";
22-
import { useCallback, useMemo } from "react";
22+
import { useCallback, useMemo, useState } from "react";
2323
import type { Components } from "react-markdown";
2424
import ReactMarkdown from "react-markdown";
2525
import remarkGfm from "remark-gfm";
@@ -47,6 +47,7 @@ export function CodeEditorPanel({
4747
);
4848
const openFileInSplit = usePanelLayoutStore((s) => s.openFileInSplit);
4949
const expandToFile = useFileTreeStore((s) => s.expandToFile);
50+
const [copied, setCopied] = useState(false);
5051

5152
const handleMarkdownLinkClick = useCallback(
5253
(e: React.MouseEvent<HTMLAnchorElement>, href: string) => {
@@ -193,6 +194,12 @@ export function CodeEditorPanel({
193194
}
194195

195196
if (isMarkdown) {
197+
const handleCopySource = () => {
198+
navigator.clipboard.writeText(fileContent);
199+
setCopied(true);
200+
setTimeout(() => setCopied(false), 2000);
201+
};
202+
196203
return (
197204
<Flex direction="column" height="100%" className="overflow-hidden">
198205
<Flex
@@ -208,17 +215,31 @@ export function CodeEditorPanel({
208215
>
209216
{filePath}
210217
</Text>
211-
<Tooltip content={preferRendered ? "View source" : "View rendered"}>
212-
<IconButton
213-
size="1"
214-
variant="ghost"
215-
color="gray"
216-
className="cursor-pointer"
217-
onClick={togglePreferRendered}
218-
>
219-
{preferRendered ? <Code size={14} /> : <Eye size={14} />}
220-
</IconButton>
221-
</Tooltip>
218+
<Flex align="center" gap="1">
219+
<Tooltip content={copied ? "Copied" : "Copy source"}>
220+
<IconButton
221+
size="1"
222+
variant="ghost"
223+
color="gray"
224+
className="cursor-pointer"
225+
onClick={handleCopySource}
226+
aria-label="Copy source"
227+
>
228+
{copied ? <Check size={14} /> : <Copy size={14} />}
229+
</IconButton>
230+
</Tooltip>
231+
<Tooltip content={preferRendered ? "View source" : "View rendered"}>
232+
<IconButton
233+
size="1"
234+
variant="ghost"
235+
color="gray"
236+
className="cursor-pointer"
237+
onClick={togglePreferRendered}
238+
>
239+
{preferRendered ? <Code size={14} /> : <Eye size={14} />}
240+
</IconButton>
241+
</Tooltip>
242+
</Flex>
222243
</Flex>
223244
<Box className="flex-1 overflow-auto">
224245
{preferRendered ? (

0 commit comments

Comments
 (0)