- 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.
84 lines
2.3 KiB
TypeScript
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 '';
|
|
}
|