Getting the copy button to work well

This commit is contained in:
Matt Aitken
2023-05-10 18:20:30 +01:00
parent 2a93c10828
commit bfac524c75
2 changed files with 61 additions and 9 deletions
+39 -7
View File
@@ -1,10 +1,11 @@
import { ClipboardIcon } from "@heroicons/react/20/solid";
import type { Language, PrismTheme } from "prism-react-renderer";
import Highlight, { defaultProps } from "prism-react-renderer";
import { forwardRef } from "react";
import { forwardRef, useCallback, useState } from "react";
import { cn } from "~/utils/cn";
import {
Tooltip,
TooltipArrow,
TooltipContent,
TooltipProvider,
TooltipTrigger,
@@ -156,16 +157,32 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
}: CodeBlockProps,
ref
) => {
const [copied, setCopied] = useState(false);
const onCopied = useCallback(
(event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
event.stopPropagation();
navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 1500);
},
[code]
);
code = code.trim();
const maxLineSize = code.split("\n").length.toString().length;
return (
<div
className={cn(
"relative overflow-hidden rounded-md border border-slate-800 ",
"relative overflow-hidden rounded-md border border-slate-800",
className
)}
style={{ backgroundColor: theme.plain.backgroundColor }}
style={{
backgroundColor: theme.plain.backgroundColor,
}}
ref={ref}
{...props}
translate="no"
@@ -173,10 +190,20 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
{showCopyButton && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="absolute top-1 right-1 z-50">
<ClipboardIcon className="h-5 w-4 text-slate-500" />
<TooltipTrigger
onClick={onCopied}
className={cn(
"absolute top-3 right-3 z-50 transition-colors duration-500 hover:cursor-pointer",
copied
? "text-emerald-500"
: "text-slate-500 hover:text-slate-300"
)}
>
<ClipboardIcon className="h-5 w-4" />
</TooltipTrigger>
<TooltipContent>Copy</TooltipContent>
<TooltipContent side="left">
{copied ? "Copied" : "Copy"}
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
@@ -196,7 +223,12 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
}) => (
<div
dir="ltr"
className="overflow-auto py-1 px-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700"
className="overflow-auto py-3 px-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700"
style={
{
// maxHeight: "100px",
}
}
>
<pre
className={cn(
@@ -6,7 +6,21 @@ import { cn } from "~/utils/cn";
const TooltipProvider = TooltipPrimitive.Provider;
const Tooltip = TooltipPrimitive.Root;
const TooltipArrow = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Arrow>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>
>(({ ...props }, ref) => (
<TooltipPrimitive.Arrow className="z-50 fill-popover" {...props} />
));
TooltipArrow.displayName = TooltipPrimitive.Arrow.displayName;
const Tooltip = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>
>(({ delayDuration = 0, ...props }, ref) => (
<TooltipPrimitive.Root delayDuration={delayDuration} {...props} />
));
Tooltip.displayName = TooltipPrimitive.Root.displayName;
const TooltipTrigger = TooltipPrimitive.Trigger;
@@ -26,4 +40,10 @@ const TooltipContent = React.forwardRef<
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
export {
Tooltip,
TooltipTrigger,
TooltipContent,
TooltipProvider,
TooltipArrow,
};