Files
headquarter/apps/web/src/components/syntax-highlighter.tsx
T
Fusion 6f41fa7cbe feat: implement universal icon system with Phosphor Icons
- Install @phosphor-icons/react package
- Create centralized Icon component with size/weight/color variants
- Create icon registry with 34 icons across 5 categories
- Replace all raw Unicode symbols with proper icon components
- Add icons to navigation, buttons, status indicators, git operations
- Add icon CSS with consistent sizing and spacing
- Fix type definitions for Phosphor icon compatibility

Quality gates: typecheck ✓, lint ✓, build ✓ (375KB bundle)
2026-05-19 19:33:06 +02:00

78 lines
1.9 KiB
TypeScript

import React, { useEffect, useState } from "react";
import { Icon } from "./icon";
import { highlightCode, loadLanguage } from "../utils/language";
interface SyntaxHighlighterProps {
code: string;
language: string;
showLineNumbers?: boolean;
}
export const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({
code,
language,
showLineNumbers = true,
}) => {
const [highlighted, setHighlighted] = useState(">");
const [copied, setCopied] = useState(false);
useEffect(() => {
const highlight = async () => {
await loadLanguage(language);
setHighlighted(highlightCode(code, language));
};
void highlight();
}, [code, language]);
const handleCopy = async () => {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
const lines = code.split("\n");
return (
<div className="syntax-highlighter">
<div className="highlighter-toolbar">
<span className="language-badge">{language}</span>
<button
className="copy-button"
onClick={handleCopy}
type="button"
>
{copied ? (
<>
<Icon name="success" size="sm" />
Copied!
</>
) : (
<>
<Icon name="copy" size="sm" />
Copy
</>
)}
</button>
</div>
<div className="code-container">
{showLineNumbers && (
<div className="line-numbers">
{lines.map((_, i) => (
<div key={i} className="line-number">
{i + 1}
</div>
))}
</div>
)}
<pre className="code-block">
<code
className={`language-${language}`}
dangerouslySetInnerHTML={{ __html: highlighted }}
/>
</pre>
</div>
</div>
);
};