Skip to content

Commit 31bcd08

Browse files
committed
feat: 코드블럭 복사 버튼 추가
1 parent 33f124a commit 31bcd08

2 files changed

Lines changed: 65 additions & 15 deletions

File tree

src/app/layout.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { Metadata } from 'next'
33
import { Noto_Sans_KR, Poppins } from 'next/font/google'
44
import { GoogleAnalytics } from '@next/third-parties/google'
55

6-
import { AutoScroll } from '@/components/layout/AutoScroll'
76
import { OutLineMenu } from '@/components/layout/OutLineMenu'
87

98
import './globals.css'
@@ -64,7 +63,6 @@ export default function RootLayout({
6463
>
6564
{children}
6665
</div>
67-
<AutoScroll />
6866
</OutLineMenu>
6967
<GoogleAnalytics gaId={GA_TRACKING_ID} />
7068
</body>
Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
2-
import React from 'react'
2+
'use client'
3+
4+
import React, { useState } from 'react'
35
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
46
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'
57

@@ -9,18 +11,68 @@ interface PostCodeBlockProps {
911
}
1012

1113
export const PostCodeBlock = ({ children, language }: PostCodeBlockProps) => {
14+
const [copied, setCopied] = useState(false)
15+
16+
const handleCopy = () => {
17+
void navigator.clipboard.writeText(children).then(() => {
18+
setCopied(true)
19+
setTimeout(() => setCopied(false), 2000)
20+
})
21+
}
22+
1223
return (
13-
<SyntaxHighlighter
14-
language={language}
15-
style={vscDarkPlus}
16-
PreTag="div"
17-
showLineNumbers
18-
customStyle={{
19-
borderRadius: '1rem',
20-
marginBottom: '3rem',
21-
}}
22-
>
23-
{children}
24-
</SyntaxHighlighter>
24+
<div className="relative mb-12">
25+
<button
26+
onClick={handleCopy}
27+
className="absolute right-3 top-3 z-10 rounded-md bg-gray-700 p-1.5 text-gray-300 transition-colors hover:bg-gray-600 hover:text-white"
28+
aria-label="Copy code"
29+
>
30+
{copied ? (
31+
<span className="flex items-center gap-1.5 text-sm text-gray-300">
32+
<svg
33+
xmlns="http://www.w3.org/2000/svg"
34+
width="18"
35+
height="18"
36+
viewBox="0 0 24 24"
37+
fill="none"
38+
stroke="currentColor"
39+
strokeWidth="2.5"
40+
strokeLinecap="round"
41+
strokeLinejoin="round"
42+
>
43+
<polyline points="20 6 9 17 4 12" />
44+
</svg>
45+
Copied
46+
</span>
47+
) : (
48+
<svg
49+
xmlns="http://www.w3.org/2000/svg"
50+
width="18"
51+
height="18"
52+
viewBox="0 0 24 24"
53+
fill="none"
54+
stroke="currentColor"
55+
strokeWidth="2"
56+
strokeLinecap="round"
57+
strokeLinejoin="round"
58+
>
59+
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
60+
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
61+
</svg>
62+
)}
63+
</button>
64+
<SyntaxHighlighter
65+
language={language}
66+
style={vscDarkPlus}
67+
wrapLongLines
68+
PreTag="div"
69+
customStyle={{
70+
borderRadius: '1rem',
71+
marginBottom: '0',
72+
}}
73+
>
74+
{children}
75+
</SyntaxHighlighter>
76+
</div>
2577
)
2678
}

0 commit comments

Comments
 (0)