diff --git a/public/index.html b/public/index.html index 87132de..09d6992 100644 --- a/public/index.html +++ b/public/index.html @@ -6,7 +6,7 @@ diff --git a/src/components/CodeBlock.tsx b/src/components/CodeBlock.tsx new file mode 100644 index 0000000..b9a21e9 --- /dev/null +++ b/src/components/CodeBlock.tsx @@ -0,0 +1,71 @@ +import React, { useState } from 'react' +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' +import { + oneDark, + oneLight, +} from 'react-syntax-highlighter/dist/esm/styles/prism' +import { useThemeValue } from '../hooks/theme' +import { Button } from '@nextui-org/react' +import { ClipboardIcon, CheckIcon } from '@heroicons/react/24/outline' + +export type CodeBlockProps = { + code: string + language: string +} + +const CodeBlock: React.FC = ({ code, language }) => { + const codeStyle = useThemeValue(oneLight, oneDark) + const [isHovering, setIsHovering] = useState(false) + const [showSuccess, setShowSuccess] = useState(false) + + const copyToClipboard = (text: string) => { + const textArea = document.createElement('textarea') + textArea.value = text + + textArea.style.top = '0' + textArea.style.left = '0' + textArea.style.position = 'fixed' + + document.body.appendChild(textArea) + textArea.focus() + textArea.select() + + const success = document.execCommand('copy') + if (success) { + setShowSuccess(true) + setTimeout(() => { + setShowSuccess(false) + }, 2000) + } + document.body.removeChild(textArea) + } + return ( +
setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + > + {isHovering && ( + + )} + + {code} + +
+ ) +} + +export default CodeBlock diff --git a/src/components/Latex.tsx b/src/components/Latex.tsx index e37cef3..ddbc7c7 100644 --- a/src/components/Latex.tsx +++ b/src/components/Latex.tsx @@ -25,7 +25,7 @@ const Latex = ({ useEffect(() => { if (ref && ref.current) { - katex.render(expression, ref.current) + katex.render(expression, ref.current, { displayMode: display }) } }, [expression]) diff --git a/src/pages/Post/PostContent.tsx b/src/pages/Post/PostContent.tsx index 4242ceb..d571577 100644 --- a/src/pages/Post/PostContent.tsx +++ b/src/pages/Post/PostContent.tsx @@ -12,7 +12,6 @@ import { IList, IImage, } from '@ammarahmedca/types' -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { oneDark, oneLight, @@ -31,6 +30,7 @@ import TextSkeleton from '../../components/TextSkeleton' import { extractHeadings, Heading } from '../../utils/content' import PostHeadings from './PostHeadings' import { createHeadingID } from '../../utils/content' +import CodeBlock from '../../components/CodeBlock' export type PostContentProps = { slug: string @@ -173,14 +173,11 @@ const PostContent: React.FC = ({ slug }) => { let code = content[0] as IRichText let language = code.annotations.language as string return ( - - {code.plainText} - + code={code.plainText} + language={language} + /> ) case 'image': let image = content[0] as IImage diff --git a/src/pages/Post/PostMetadata.tsx b/src/pages/Post/PostMetadata.tsx index d1f8465..5f5372e 100644 --- a/src/pages/Post/PostMetadata.tsx +++ b/src/pages/Post/PostMetadata.tsx @@ -2,7 +2,7 @@ import React from 'react' import type { IPostMetadata } from '@ammarahmedca/types' import { useTextGradient } from '../../hooks/styles' import { formatDistance } from 'date-fns' -import { Chip, Skeleton } from '@nextui-org/react' +import { Chip, Skeleton, Image } from '@nextui-org/react' import { useBreakpointValue } from '../../hooks/mediaQuery' import { Helmet } from 'react-helmet' @@ -48,6 +48,7 @@ const PostMetadata: React.FC = ({ metadata }) => { > {metadata.name} + {metadata.image && }

{elapsed}