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

  • ArtifactContext for artifact state management

UI Components

  • @/components/ui/badge for type labels
  • @/components/ui/button for actions
  • Lucide icons for UI elements
  • ArtifactPreview for interactive previews
  • artifactMarkdownComponents for 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
  • ArtifactPreview - Interactive preview component
  • ArtifactContext - State management context
  • artifactMarkdownComponents - Custom markdown components
  • Various UI primitives from @/components/ui/