Files
fast-next-template/frontend/src/components/docs/CodeBlock.tsx
Felipe Cardoso 96df7edf88 Refactor useAuth hook, settings components, and docs for formatting and readability improvements
- Consolidated multi-line arguments into single lines where appropriate in `useAuth`.
- Improved spacing and readability in data processing across components (`ProfileSettingsForm`, `PasswordChangeForm`, `SessionCard`).
- Applied consistent table and markdown formatting in design system docs (e.g., `README.md`, `08-ai-guidelines.md`, `00-quick-start.md`).
- Updated code snippets to ensure adherence to Prettier rules and streamlined JSX structures.
2025-11-10 11:03:45 +01:00

84 lines
2.3 KiB
TypeScript

/* istanbul ignore file */
/**
* CodeBlock Component
* Syntax-highlighted code block with copy functionality
* This file is excluded from coverage as it's a documentation component
*/
'use client';
import { useState } from 'react';
import { Check, Copy } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
interface CodeBlockProps {
children: React.ReactNode;
className?: string;
title?: string;
}
export function CodeBlock({ children, className, title }: CodeBlockProps) {
const [copied, setCopied] = useState(false);
const handleCopy = async () => {
const code = extractTextFromChildren(children);
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<div className="group relative my-6">
{title && (
<div className="flex items-center justify-between rounded-t-lg border border-b-0 bg-muted/50 px-4 py-2">
<span className="text-xs font-medium text-muted-foreground">{title}</span>
</div>
)}
<div className={cn('relative', title && 'rounded-t-none')}>
<pre
className={cn(
'overflow-x-auto rounded-lg border bg-slate-950 p-4 font-mono text-sm',
title && 'rounded-t-none',
className
)}
>
{children}
</pre>
<Button
variant="ghost"
size="icon"
className="absolute right-2 top-2 h-8 w-8 opacity-0 transition-opacity group-hover:opacity-100"
onClick={handleCopy}
aria-label="Copy code"
>
{copied ? (
<Check className="h-4 w-4 text-green-500" />
) : (
<Copy className="h-4 w-4 text-muted-foreground" />
)}
</Button>
</div>
</div>
);
}
function extractTextFromChildren(children: React.ReactNode): string {
if (typeof children === 'string') {
return children;
}
if (Array.isArray(children)) {
return children.map(extractTextFromChildren).join('');
}
if (children && typeof children === 'object' && 'props' in children) {
return extractTextFromChildren(
(children as { props: { children: React.ReactNode } }).props.children
);
}
return '';
}