3,200+ hardcoded color values replaced with CSS variable-backed Tailwind classes (bg-card, text-foreground, border-border, etc.). Enables light mode via CSS variable swap. Only syntax highlighting colors and intentional one-offs remain hardcoded (~15 values). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { useMemo } from 'react'
|
|
import { FileText } from 'lucide-react'
|
|
|
|
interface SourcePanelProps {
|
|
sourceText: string
|
|
sourceFormat: string
|
|
highlightExcerpt: string | null
|
|
}
|
|
|
|
export function SourcePanel({ sourceText, sourceFormat, highlightExcerpt }: SourcePanelProps) {
|
|
const renderedText = useMemo(() => {
|
|
if (!highlightExcerpt || !sourceText.includes(highlightExcerpt)) {
|
|
return <span>{sourceText}</span>
|
|
}
|
|
|
|
const idx = sourceText.indexOf(highlightExcerpt)
|
|
return (
|
|
<>
|
|
<span>{sourceText.slice(0, idx)}</span>
|
|
<mark className="bg-primary/20 text-foreground rounded px-0.5">{highlightExcerpt}</mark>
|
|
<span>{sourceText.slice(idx + highlightExcerpt.length)}</span>
|
|
</>
|
|
)
|
|
}, [sourceText, highlightExcerpt])
|
|
|
|
return (
|
|
<div className="card-flat flex flex-col h-full">
|
|
<div className="flex items-center gap-2 px-4 py-3 border-b" style={{ borderColor: 'var(--glass-border)' }}>
|
|
<FileText size={16} className="text-muted-foreground" />
|
|
<span className="text-sm font-medium text-foreground">Source Document</span>
|
|
<span className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground ml-auto">
|
|
{sourceFormat}
|
|
</span>
|
|
</div>
|
|
<div className="flex-1 overflow-y-auto p-4">
|
|
<pre className="text-sm text-muted-foreground whitespace-pre-wrap font-sans leading-relaxed">
|
|
{renderedText}
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|