improvement(docs): added a copy page button to the docs pages (#1743)

* improvement(docs): added a copy page button to the docs pages

* added copy page button & fixed TOC alignment
This commit is contained in:
Waleed
2025-10-27 15:05:27 -07:00
committed by GitHub
parent 47ddfb639e
commit 8620ab255a
4 changed files with 80 additions and 11 deletions

View File

@@ -6,6 +6,7 @@ import Link from 'next/link'
import { notFound } from 'next/navigation'
import { StructuredData } from '@/components/structured-data'
import { CodeBlock } from '@/components/ui/code-block'
import { CopyPageButton } from '@/components/ui/copy-page-button'
import { source } from '@/lib/source'
export const dynamic = 'force-dynamic'
@@ -193,8 +194,19 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
component: <CustomFooter />,
}}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<div className='relative'>
<div className='absolute top-1 right-0'>
<CopyPageButton
content={`# ${page.data.title}
${page.data.description || ''}
${page.data.content || ''}`}
/>
</div>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
</div>
<DocsBody>
<MDX
components={{

View File

@@ -36,7 +36,9 @@
/* Shift the sidebar slightly left from the content edge for extra breathing room */
--sidebar-shift: 90px;
--sidebar-offset: max(0px, calc(var(--edge-gutter) - var(--sidebar-shift)));
--toc-offset: var(--edge-gutter);
/* Shift TOC slightly right to match sidebar spacing for symmetry */
--toc-shift: 90px;
--toc-offset: max(0px, calc(var(--edge-gutter) - var(--toc-shift)));
/* Sidebar and TOC have 20px internal padding - navbar accounts for this directly */
/* Extra gap between sidebar/TOC and the main text content */
--content-gap: 1.75rem;
@@ -107,8 +109,21 @@ aside#nd-sidebar {
aside#nd-sidebar {
left: var(--sidebar-offset) !important;
}
[data-toc] {
margin-right: var(--toc-offset) !important;
/* TOC positioning - target all possible selectors */
[data-toc],
aside[data-toc],
div[data-toc],
.fd-toc,
#nd-toc,
nav[data-toc],
aside:has([role="complementary"]) {
right: var(--toc-offset) !important;
}
/* Alternative TOC container targeting */
[data-docs-page] > aside:last-child,
main ~ aside {
right: var(--toc-offset) !important;
}
}

View File

@@ -19,13 +19,13 @@ export function Navbar() {
{/* Desktop: Single row layout */}
<div className='hidden h-16 w-full items-center lg:flex'>
<div
className='grid w-full grid-cols-[auto_1fr_auto] items-center'
className='relative flex w-full items-center justify-between'
style={{
paddingLeft: 'calc(var(--sidebar-offset) + 20px)',
paddingRight: 'calc(var(--toc-offset) + 20px)',
paddingRight: 'calc(var(--toc-offset) + 60px)',
}}
>
{/* Left cluster: translate by sidebar delta to align with sidebar edge */}
{/* Left cluster: logo */}
<div className='flex items-center'>
<Link href='/' className='flex min-w-[100px] items-center'>
<Image
@@ -38,12 +38,12 @@ export function Navbar() {
</Link>
</div>
{/* Center cluster: search */}
<div className='flex flex-1 items-center justify-center pl-32'>
{/* Center cluster: search - absolutely positioned to center */}
<div className='-translate-x-1/2 absolute left-1/2 flex items-center justify-center'>
<SearchTrigger />
</div>
{/* Right cluster aligns with TOC edge using the same right gutter */}
{/* Right cluster aligns with TOC edge */}
<div className='flex items-center gap-4'>
<Link
href='https://sim.ai'

View File

@@ -0,0 +1,42 @@
'use client'
import { useState } from 'react'
import { Check, Copy } from 'lucide-react'
interface CopyPageButtonProps {
content: string
}
export function CopyPageButton({ content }: CopyPageButtonProps) {
const [copied, setCopied] = useState(false)
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(content)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (err) {
console.error('Failed to copy:', err)
}
}
return (
<button
onClick={handleCopy}
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 transition-all hover:border-border hover:bg-accent/50 hover:text-muted-foreground'
aria-label={copied ? 'Copied to clipboard' : 'Copy page content'}
>
{copied ? (
<>
<Check className='h-4 w-4' />
<span>Copied</span>
</>
) : (
<>
<Copy className='h-4 w-4' />
<span>Copy page</span>
</>
)}
</button>
)
}