Skip to content

Commit 381e39f

Browse files
author
waleed
committed
improvement(docs): added a copy page button to the docs pages
1 parent 5d48c27 commit 381e39f

2 files changed

Lines changed: 56 additions & 2 deletions

File tree

apps/docs/app/[lang]/[[...slug]]/page.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Link from 'next/link'
66
import { notFound } from 'next/navigation'
77
import { StructuredData } from '@/components/structured-data'
88
import { CodeBlock } from '@/components/ui/code-block'
9+
import { CopyPageButton } from '@/components/ui/copy-page-button'
910
import { source } from '@/lib/source'
1011

1112
export const dynamic = 'force-dynamic'
@@ -193,8 +194,19 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
193194
component: <CustomFooter />,
194195
}}
195196
>
196-
<DocsTitle>{page.data.title}</DocsTitle>
197-
<DocsDescription>{page.data.description}</DocsDescription>
197+
<div className='relative'>
198+
<div className='absolute top-1 right-0'>
199+
<CopyPageButton
200+
content={`# ${page.data.title}
201+
202+
${page.data.description || ''}
203+
204+
${page.data.content || ''}`}
205+
/>
206+
</div>
207+
<DocsTitle>{page.data.title}</DocsTitle>
208+
<DocsDescription>{page.data.description}</DocsDescription>
209+
</div>
198210
<DocsBody>
199211
<MDX
200212
components={{
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use client'
2+
3+
import { useState } from 'react'
4+
import { Check, Copy } from 'lucide-react'
5+
6+
interface CopyPageButtonProps {
7+
content: string
8+
}
9+
10+
export function CopyPageButton({ content }: CopyPageButtonProps) {
11+
const [copied, setCopied] = useState(false)
12+
13+
const handleCopy = async () => {
14+
try {
15+
await navigator.clipboard.writeText(content)
16+
setCopied(true)
17+
setTimeout(() => setCopied(false), 2000)
18+
} catch (err) {
19+
console.error('Failed to copy:', err)
20+
}
21+
}
22+
23+
return (
24+
<button
25+
onClick={handleCopy}
26+
className='flex items-center gap-1.5 rounded-lg border border-border/40 bg-background px-2.5 py-1.5 text-muted-foreground/60 text-sm shadow-sm transition-all hover:border-border hover:bg-accent/50 hover:text-muted-foreground'
27+
aria-label={copied ? 'Copied to clipboard' : 'Copy page content'}
28+
>
29+
{copied ? (
30+
<>
31+
<Check className='h-4 w-4' />
32+
<span>Copied</span>
33+
</>
34+
) : (
35+
<>
36+
<Copy className='h-4 w-4' />
37+
<span>Copy page</span>
38+
</>
39+
)}
40+
</button>
41+
)
42+
}

0 commit comments

Comments
 (0)