fix: doc rendering — markdown prose styling, code blocks with copy button, proper step parsing
- Add @tailwindcss/typography plugin for prose styling - Create CodeBlock component with copy button and language labels - Create Md wrapper component using ReactMarkdown with custom renderers - Replace all plain text renders with Md for proper markdown formatting - Fix parseSteps() in pipeline to group numbered steps with code blocks - Add First Task subtitle explaining its purpose - Add conditional file.purpose render in module key files
This commit is contained in:
55
apps/web/src/components/code-block.tsx
Normal file
55
apps/web/src/components/code-block.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
"use client";
|
||||
|
||||
import { useState, type ReactNode } from "react";
|
||||
import { Check, Copy } from "lucide-react";
|
||||
|
||||
interface CodeBlockProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
inline?: boolean;
|
||||
}
|
||||
|
||||
export function CodeBlock({ children, className, inline }: CodeBlockProps) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
if (inline) {
|
||||
return (
|
||||
<code className="px-1.5 py-0.5 rounded bg-white/10 text-blue-300 text-[0.85em] font-mono border border-white/5">
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
}
|
||||
|
||||
const language = className?.replace("language-", "") || "";
|
||||
const codeString = String(children).replace(/\n$/, "");
|
||||
|
||||
const handleCopy = async () => {
|
||||
await navigator.clipboard.writeText(codeString);
|
||||
setCopied(true);
|
||||
window.setTimeout(() => setCopied(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative group my-4">
|
||||
{language && (
|
||||
<div className="absolute top-0 left-0 px-3 py-1 text-[10px] font-medium uppercase tracking-wider text-zinc-500 bg-black/30 rounded-tl-lg rounded-br-lg border-b border-r border-white/5">
|
||||
{language}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className="absolute top-2 right-2 p-1.5 rounded-md bg-white/5 border border-white/10 text-zinc-500 hover:text-white hover:bg-white/10 transition-all opacity-0 group-hover:opacity-100 z-10"
|
||||
aria-label="Copy code"
|
||||
>
|
||||
{copied ? (
|
||||
<Check className="w-3.5 h-3.5 text-green-400" />
|
||||
) : (
|
||||
<Copy className="w-3.5 h-3.5" />
|
||||
)}
|
||||
</button>
|
||||
<pre className="overflow-x-auto rounded-lg bg-black/50 border border-white/10 p-4 pt-8 text-sm leading-relaxed font-mono scrollbar-thin">
|
||||
<code className={`text-zinc-300 ${className || ""}`}>{codeString}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user