ARTIFACT_DISPLAY_COMPONENT.md
Component documentation for the ArtifactDisplay artifact rendering system.
Overview
The ArtifactDisplay component provides a comprehensive interface for viewing, copying, and downloading AI-generated artifacts. It supports multiple content types with syntax highlighting and interactive previews.
Component Location
- File:
src/components/ArtifactDisplay.tsx - Type: Content Display Component
- Framework: React with TypeScript
Features
- Multi-Format Support: Handles code, markdown, HTML, and various document types
- Syntax Highlighting: Automatic code highlighting based on artifact type
- Copy to Clipboard: One-click content copying functionality
- File Download: Export artifacts with appropriate file extensions
- Interactive Preview: Live preview for HTML/React/JavaScript artifacts
- Markdown Rendering: Rich markdown display with math and GFM support
- Context Integration: Works with ArtifactContext for state management
Props Interface
interface ArtifactDisplayProps {
className?: string; // Optional CSS classes for styling
}
Usage Examples
Basic Implementation
import { ArtifactDisplay } from '@/components/ArtifactDisplay';
import { ArtifactProvider } from '@/contexts/ArtifactContext';
function ChatInterface() {
return (
<ArtifactProvider>
<div className="chat-container">
{/* Other chat components */}
<ArtifactDisplay className="artifact-panel" />
</div>
</ArtifactProvider>
);
}
With Custom Styling
<ArtifactDisplay className="fixed right-0 top-0 w-96 h-full border-l" />
Context Integration
The component relies on the ArtifactContext for state management:
const { artifacts, activeArtifactId, setActiveArtifactId } = useArtifacts();
// Get current artifact
const currentArtifact = activeArtifactId ? artifacts.get(activeArtifactId) : null;
if (!currentArtifact) {
return null; // Component renders nothing when no artifact is active
}
File Type Support
Code Types
Supports syntax highlighting for multiple programming languages:
const codeTypes = [
'javascript', 'typescript', 'python', 'html', 'css', 'json',
'yaml', 'sql', 'bash', 'jsx', 'tsx', 'js', 'ts', 'py',
'sh', 'shell', 'xml', 'java', 'c', 'cpp', 'go', 'rust',
'php', 'ruby', 'swift'
];
// Wrap in markdown code block for syntax highlighting
if (codeTypes.includes(currentArtifact.type.toLowerCase())) {
return `\`\`\`${currentArtifact.type.toLowerCase()}\n${currentArtifact.content}\n\`\`\``;
}
File Extension Mapping
const getFileExtension = (type: string): string => {
switch (type.toLowerCase()) {
case 'markdown': case 'md': return 'md';
case 'html': return 'html';
case 'javascript': case 'js': return 'js';
case 'typescript': case 'ts': return 'ts';
case 'python': case 'py': return 'py';
case 'json': return 'json';
case 'yaml': case 'yml': return 'yml';
case 'css': return 'css';
case 'svg': return 'svg';
default: return 'txt';
}
};
Actions
Copy Functionality
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(currentArtifact.content);
} catch (err) {
console.error('Failed to copy artifact content:', err);
}
};
Download Functionality
const handleDownload = () => {
const blob = new Blob([currentArtifact.content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${currentArtifact.title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.${getFileExtension(currentArtifact.type)}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
Component Structure
Header Section
<div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2 flex-1 min-w-0">
<h4 className="font-medium text-sm truncate">{currentArtifact.title}</h4>
<Badge variant="outline" className="text-xs">
{currentArtifact.type}
</Badge>
</div>
<div className="flex items-center gap-1">
{/* Copy, Download, Close buttons */}
</div>
</div>
Content Section
<div className="max-h-[calc(100vh-200px)] overflow-y-auto border rounded bg-gray-50">
<div className="p-3">
<div className="prose prose-sm max-w-none">
<Markdown
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeRaw, rehypeKatex]}
components={artifactMarkdownComponents}
skipHtml={false}
>
{processedContent}
</Markdown>
</div>
{/* Interactive preview for HTML/React/JS artifacts */}
<ArtifactPreview
content={currentArtifact.content}
type={currentArtifact.type}
title={currentArtifact.title}
/>
</div>
</div>
Markdown Configuration
The component uses advanced markdown rendering:
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import rehypeRaw from 'rehype-raw';
import rehypeKatex from 'rehype-katex';
import { artifactMarkdownComponents } from '@/components/markdown/artifactComponents';
// Plugins for enhanced markdown support:
// - remarkGfm: GitHub Flavored Markdown
// - remarkMath: Mathematical expressions
// - rehypeRaw: Raw HTML support
// - rehypeKatex: LaTeX math rendering
Interactive Preview
For supported artifact types, the component includes live previews:
<ArtifactPreview
content={currentArtifact.content}
type={currentArtifact.type}
title={currentArtifact.title}
/>
Styling Classes
Container Styling
.bg-white border rounded-lg p-4 mb-4
Content Area
.max-h-[calc(100vh-200px)] overflow-y-auto border rounded bg-gray-50
Button Styling
.h-8 w-8 p-0 /* Icon buttons */
Dependencies
Core Libraries
- React for component structure
- Markdown rendering with
react-markdown - Math support with KaTeX
Context
ArtifactContextfor artifact state management
UI Components
@/components/ui/badgefor type labels@/components/ui/buttonfor actions- Lucide icons for UI elements
Related Components
ArtifactPreviewfor interactive previewsartifactMarkdownComponentsfor custom markdown rendering
Accessibility
- Semantic HTML structure
- ARIA labels for icon buttons
- Keyboard navigation support
- Screen reader friendly content
Performance Considerations
- Efficient re-rendering only when artifacts change
- Proper cleanup of blob URLs after download
- Optimized markdown rendering with custom components
- Lazy loading for large content
Error Handling
- Graceful fallback when clipboard API fails
- Safe file extension detection
- Proper error boundaries for markdown rendering
- Fallback content for unsupported types
Related Components
ArtifactPreview- Interactive preview componentArtifactContext- State management contextartifactMarkdownComponents- Custom markdown components- Various UI primitives from
@/components/ui/