From acf493a30c445228c58865962047678e768b1e2a Mon Sep 17 00:00:00 2001 From: Boris <72118807+Curis-lab@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:27:10 +0630 Subject: [PATCH] feat: add copy-to-clipboard functionality to code blocks - Add copy button with visual feedback and clipboard integration - Update styling for proper button positioning and header layering - Improve code formatting consistency --- src/components/code.scss | 25 ++++++++++++++- src/components/code.tsx | 63 ++++++++++++++++++++++++++------------ src/components/header.scss | 1 + 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/components/code.scss b/src/components/code.scss index 7c76470f..38d422d9 100644 --- a/src/components/code.scss +++ b/src/components/code.scss @@ -8,7 +8,8 @@ } .hljs-keyword, - .hljs-built_in {/* stylelint-disable-line */ + .hljs-built_in { + /* stylelint-disable-line */ color: var(--code-keyword); } @@ -20,3 +21,25 @@ color: var(--code-attribute); } } + +.code-container { + position: relative; +} + +.copy-button { + position: absolute; + top: 0; + right: 0; + height: 100%; + padding: 0.5rem; + background: transparent; + border: none; + display: flex; + justify-content: center; + transition: background-color 0.2s ease; + border-radius: 0.25rem; + + &:hover { + cursor: pointer; + } +} diff --git a/src/components/code.tsx b/src/components/code.tsx index 5905ad5c..05a44d1f 100644 --- a/src/components/code.tsx +++ b/src/components/code.tsx @@ -1,28 +1,51 @@ -import React from 'react'; -import { - Light as SyntaxHighlighter, -} from 'react-syntax-highlighter'; -import './code.scss'; -import bash from 'react-syntax-highlighter/dist/esm/languages/hljs/bash'; +import React, { useState } from "react"; +import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; +import "./code.scss"; +import bash from "react-syntax-highlighter/dist/esm/languages/hljs/bash"; // eslint-disable-next-line max-len -import typescript from 'react-syntax-highlighter/dist/esm/languages/hljs/typescript'; +import typescript from "react-syntax-highlighter/dist/esm/languages/hljs/typescript"; // eslint-disable-next-line max-len -import markdown from 'react-syntax-highlighter/dist/esm/languages/hljs/markdown'; - -SyntaxHighlighter.registerLanguage('typescript', typescript,); -SyntaxHighlighter.registerLanguage('bash', bash,); -SyntaxHighlighter.registerLanguage('markdown', markdown,); +import markdown from "react-syntax-highlighter/dist/esm/languages/hljs/markdown"; +import { FaRegCopy } from "react-icons/fa"; +SyntaxHighlighter.registerLanguage("typescript", typescript); +SyntaxHighlighter.registerLanguage("bash", bash); +SyntaxHighlighter.registerLanguage("markdown", markdown); interface CodeType { - language: 'bash'|'typescript'|'markdown', - children: string|string[], + language: "bash" | "typescript" | "markdown"; + children: string | string[]; } -const Code = ({ - language, - children, -}: CodeType,) => {children}; +const Code = ({ language, children }: CodeType) => { + const [copy, setCopy] = useState(false); + + const handleCopy = () => { + const textToCopy = Array.isArray(children) ? children.join("\n") : children; + navigator.clipboard.writeText(textToCopy); + setCopy(true); + setTimeout(() => setCopy(false), 2000); + }; + return ( +
+ + + {children} + +
+ ); +}; export default Code; diff --git a/src/components/header.scss b/src/components/header.scss index 33f282eb..75d0efad 100644 --- a/src/components/header.scss +++ b/src/components/header.scss @@ -76,6 +76,7 @@ header { display: grid; grid-template-columns: repeat(5, 1fr); position: fixed; + z-index: 1; width: 100%; ul {