mirror of
https://gitbruv.vercel.app/api/git/bruv/gitbruv.git
synced 2025-12-20 23:24:09 +01:00
mvp
This commit is contained in:
parent
8f672d012c
commit
46cab693db
49 changed files with 4725 additions and 118 deletions
88
components/code-viewer.tsx
Normal file
88
components/code-viewer.tsx
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"use client";
|
||||
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { useEffect, useState } from "react";
|
||||
import { codeToHtml } from "shiki";
|
||||
|
||||
export function CodeViewer({
|
||||
content,
|
||||
language,
|
||||
showLineNumbers = false,
|
||||
}: {
|
||||
content: string;
|
||||
language: string;
|
||||
showLineNumbers?: boolean;
|
||||
}) {
|
||||
const [highlightedCode, setHighlightedCode] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (language === "markdown" || language === "md") return;
|
||||
|
||||
async function highlight() {
|
||||
try {
|
||||
const html = await codeToHtml(content, {
|
||||
lang: language === "text" ? "plaintext" : language,
|
||||
theme: "github-dark-default",
|
||||
});
|
||||
setHighlightedCode(html);
|
||||
} catch {
|
||||
setHighlightedCode(null);
|
||||
}
|
||||
}
|
||||
|
||||
highlight();
|
||||
}, [content, language]);
|
||||
|
||||
if (language === "markdown" || language === "md") {
|
||||
return (
|
||||
<div className="prose prose-invert prose-sm max-w-none prose-headings:border-b prose-headings:border-border prose-headings:pb-2 prose-a:text-accent prose-code:bg-muted prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-pre:bg-muted">
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (highlightedCode) {
|
||||
const lines = content.split("\n");
|
||||
return (
|
||||
<div className="overflow-x-auto">
|
||||
<div className="flex font-mono text-sm">
|
||||
{showLineNumbers && (
|
||||
<div className="text-right text-muted-foreground select-none pr-4 pl-4 py-2 border-r border-border bg-muted/30 shrink-0">
|
||||
{lines.map((_, i) => (
|
||||
<div key={i} className="leading-6">
|
||||
{i + 1}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="flex-1 pl-4 py-2 [&>pre]:!bg-transparent [&>pre]:!m-0 [&>pre]:!p-0 [&_code]:leading-6"
|
||||
dangerouslySetInnerHTML={{ __html: highlightedCode }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const lines = content.split("\n");
|
||||
|
||||
return (
|
||||
<div className="font-mono text-sm overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<tbody>
|
||||
{lines.map((line, i) => (
|
||||
<tr key={i} className="hover:bg-muted/30">
|
||||
{showLineNumbers && (
|
||||
<td className="text-right text-muted-foreground select-none pr-4 pl-4 py-0.5 w-12 align-top border-r border-border">
|
||||
{i + 1}
|
||||
</td>
|
||||
)}
|
||||
<td className="pl-4 py-0.5 whitespace-pre">{line || " "}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue