Skip to content

Commit e6632e6

Browse files
committed
feat(permissions): add copy-to-clipboard button for plan content
Generated-By: PostHog Code
1 parent aeacc26 commit e6632e6

1 file changed

Lines changed: 66 additions & 20 deletions

File tree

packages/ui/src/features/permissions/PlanContent.tsx

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { ArrowsIn, ArrowsOut, ListChecks, X } from "@phosphor-icons/react";
1+
import {
2+
ArrowsIn,
3+
ArrowsOut,
4+
Check,
5+
Copy,
6+
ListChecks,
7+
X,
8+
} from "@phosphor-icons/react";
9+
import { Tooltip } from "@posthog/ui/primitives/Tooltip";
210
import { Box, Flex, IconButton, Text } from "@radix-ui/themes";
311
import { useEffect, useRef, useState } from "react";
412
import { createPortal } from "react-dom";
@@ -15,6 +23,13 @@ interface PlanContentProps {
1523
export function PlanContent({ id, plan }: PlanContentProps) {
1624
const scrollRef = useRef<HTMLDivElement>(null);
1725
const [isFullscreen, setIsFullscreen] = useState(false);
26+
const [copied, setCopied] = useState(false);
27+
28+
const handleCopy = () => {
29+
navigator.clipboard.writeText(plan);
30+
setCopied(true);
31+
setTimeout(() => setCopied(false), 1500);
32+
};
1833

1934
useEffect(() => {
2035
const el = scrollRef.current;
@@ -79,15 +94,31 @@ export function PlanContent({ id, plan }: PlanContentProps) {
7994
<ListChecks size={14} className="text-blue-11" />
8095
<Text className="text-blue-11 text-sm">Plan</Text>
8196
</Flex>
82-
<IconButton
83-
size="1"
84-
variant="ghost"
85-
color="gray"
86-
onClick={() => setIsFullscreen(false)}
87-
title="Exit fullscreen (Escape)"
88-
>
89-
<X size={14} />
90-
</IconButton>
97+
<Flex align="center" gap="2">
98+
<Tooltip
99+
content={copied ? "Copied!" : "Copy plan to clipboard"}
100+
side="bottom"
101+
>
102+
<IconButton
103+
size="1"
104+
variant="ghost"
105+
color="gray"
106+
onClick={handleCopy}
107+
>
108+
{copied ? <Check size={12} /> : <Copy size={12} />}
109+
</IconButton>
110+
</Tooltip>
111+
<Tooltip content="Exit fullscreen (Escape)" side="bottom">
112+
<IconButton
113+
size="1"
114+
variant="ghost"
115+
color="gray"
116+
onClick={() => setIsFullscreen(false)}
117+
>
118+
<X size={14} />
119+
</IconButton>
120+
</Tooltip>
121+
</Flex>
91122
</Flex>
92123

93124
<Box
@@ -109,16 +140,31 @@ export function PlanContent({ id, plan }: PlanContentProps) {
109140
ref={scrollRef}
110141
className="relative max-h-[50vh] max-w-[750px] overflow-y-auto rounded-lg border-2 border-blue-6 bg-blue-2 p-4"
111142
>
112-
<IconButton
113-
size="1"
114-
variant="ghost"
115-
color="gray"
116-
className="sticky top-0 z-10 float-right"
117-
onClick={() => setIsFullscreen(true)}
118-
title="Expand to fullscreen"
119-
>
120-
<ArrowsOut size={12} />
121-
</IconButton>
143+
<Flex gap="2" className="sticky top-0 z-10 float-right">
144+
<Tooltip
145+
content={copied ? "Copied!" : "Copy plan to clipboard"}
146+
side="bottom"
147+
>
148+
<IconButton
149+
size="1"
150+
variant="ghost"
151+
color="gray"
152+
onClick={handleCopy}
153+
>
154+
{copied ? <Check size={12} /> : <Copy size={12} />}
155+
</IconButton>
156+
</Tooltip>
157+
<Tooltip content="Expand to fullscreen" side="bottom">
158+
<IconButton
159+
size="1"
160+
variant="ghost"
161+
color="gray"
162+
onClick={() => setIsFullscreen(true)}
163+
>
164+
<ArrowsOut size={12} />
165+
</IconButton>
166+
</Tooltip>
167+
</Flex>
122168

123169
<Box className="plan-markdown text-blue-12">{markdown}</Box>
124170
</Box>

0 commit comments

Comments
 (0)