Skip to content

feat: create file list/tab component #66

@nullcoder

Description

@nullcoder

Description

Create a component to display files in view mode using a vertical layout similar to GitHub Gist, with no tabs.

Requirements

  • Vertical file display: All files shown vertically (NO TABS)
  • File name as header for each code block
  • Syntax-highlighted code using CodeEditor in read-only mode
  • Language badge next to filename
  • Copy button for each file's content
  • Download button for each file
  • File size indicator
  • Line count indicator
  • Mobile-friendly responsive design
  • Smooth scroll anchors for each file

Acceptance Criteria

  • All files displayed vertically in order
  • File headers clearly separate each file
  • Language badge shows detected/set language
  • Copy button copies file content to clipboard
  • Download button downloads individual file
  • File size shown in human-readable format
  • Line count displayed for each file
  • Responsive design works on mobile
  • Each file has unique anchor for deep linking
  • Keyboard accessible navigation
  • Screen reader announces file information

UI Layout

┌─ main.js ─ JavaScript ─ 2.3 KB ─ 45 lines ─[📋 Copy][⬇ Download]─┐
│ // Syntax highlighted code here                                   │
│ function hello() {                                                │
│   console.log('Hello World');                                     │
│ }                                                                 │
└───────────────────────────────────────────────────────────────────┘

┌─ styles.css ─ CSS ─ 1.1 KB ─ 30 lines ─[📋 Copy][⬇ Download]─────┐
│ /* Syntax highlighted CSS */                                      │
│ body {                                                            │
│   margin: 0;                                                      │
│   font-family: sans-serif;                                        │
│ }                                                                 │
└───────────────────────────────────────────────────────────────────┘

Props Interface

interface FileListProps {
  files: Array<{
    name: string;
    content: string;
    language?: string;
    size: number; // in bytes
  }>;
  onCopy?: (filename: string) => void;
  onDownload?: (filename: string) => void;
  className?: string;
}

Technical Implementation

  • Reuse CodeEditor component in read-only mode
  • Calculate line count from content
  • Format file size (e.g., "2.3 KB", "156 B")
  • Use shadcn/ui Card component for file containers
  • Implement copy with Clipboard API
  • Generate download with Blob and anchor click
  • Add id attribute to each file for anchor navigation
  • Use semantic HTML for accessibility

File Actions

// Copy to clipboard
async function copyFile(content: string) {
  await navigator.clipboard.writeText(content);
  // Show toast notification
}

// Download file
function downloadFile(filename: string, content: string) {
  const blob = new Blob([content], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

Accessibility

  • Each file section should be a landmark
  • File header should be focusable for keyboard navigation
  • Screen reader should announce: "main.js, JavaScript file, 2.3 kilobytes, 45 lines"
  • Copy/download buttons need clear labels

Performance Considerations

  • Lazy render CodeEditor for files outside viewport
  • Use React.memo to prevent unnecessary re-renders
  • Consider virtual scrolling for 10+ files

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature implementationpriority: mediumNormal priorityuiUser interface and components

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions