import { useRef, useState, Fragment } from "react";
const CodeBlock = (props: {
className: string | undefined;
children: React.ReactChildren;
}): JSX.Element => {
const textInput = useRef(null);
const [hovered, setHovered] = useState(false);
const [copied, setCopied] = useState(false);
const onEnter = () => {
setHovered(true);
};
const onExit = () => {
setHovered(false);
setCopied(false);
};
const onCopy = () => {
setCopied(true);
navigator.clipboard.writeText(textInput.current.textContent);
setTimeout(() => {
setCopied(false);
}, 3000);
};
return (
<div
ref={textInput}
onMouseEnter={onEnter}
onMouseLeave={onExit}
className="relative"
>
{hovered && (
<button
aria-label="Copy code"
type="button"
className={`absolute right-3 top-3 w-7 h-7 p-1 rounded border-2 bg-gray-200 dark:bg-[#282e33] ${
copied
? "focus:outline-none focus:border-green-500 border-green-500 dark:border-green-400 dark:focus:border-green-400"
: "border-gray-100 dark:border-gray-300"
}`}
onClick={onCopy}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
stroke="currentColor"
fill="none"
className={
copied
? "text-green-500 dark:text-green-400"
: "text-gray-700 dark:text-gray-300"
}
>
{copied ? (
<Fragment>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
/>
</Fragment>
) : (
<Fragment>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
/>
</Fragment>
)}
</svg>
</button>
)}
<pre>{props.children}</pre>
</div>
);
};
export default CodeBlock;
import Link from "next/link";
import Image from "next/image";
import ImageWithTheme from "components/ImageWithTheme";
import CodeBlock from "components/CodeBlock";
import { Files } from "components/Files";
const CustomLink = (props) => {
const href = props.href;
const isInternalLink = href && (href.startsWith("/") || href.startsWith("#"));
if (isInternalLink) {
return (
<Link href={href}>
<a {...props}>{props.children}</a>
</Link>
);
}
return <a target="_blank" rel="noopener noreferrer" {...props} />;
};
function RoundedImage(props) {
return <Image alt={props.alt} className="rounded-lg" {...props} />;
}
const MDXComponents = {
ImageWithTheme,
a: CustomLink,
pre: CodeBlock,
Files,
};
export default MDXComponents;