← Back to Kontasks
FileViewer Component Test
Testing the FileViewer component with syntax highlighting, line numbers, and copy functionality
Output
🔍 FileViewer Component Test
Testing the interactive FileViewer with syntax highlighting, line numbers, copy, and collapsible features.
Test 1: TypeScript File with Highlighted Lines
src/example.ts
1
// Example TypeScript file for FileViewer test
2
import { Router } from "./router";
3
4
export interface Config {
5
port: number;
6
host: string;
7
}
8
9
const PORT = 8080;
10
const HOST = "localhost";
11
12
console.log(`Server on ${HOST}:${PORT}`);
Test 2: Collapsible Python File
scripts/process.py
✅ Features to Verify
- Line numbers - Left column shows line numbers
- Syntax highlighting - Keywords purple, strings green, comments gray, numbers orange
- Highlighted lines - Lines 4-6 in Test 1 have gold background
- Click to select - Click any line to toggle blue selection
- Copy button - Click 📋 Copy to copy file contents
- Collapsible - Test 2 starts collapsed, click ▶ to expand
Quick Actions
Original Request
No layout configured
Details
Type
General
Status
Completed
Scope
vibetools
Tags
kontasksuicomponentstest
Created
7 Jan 2026, 4:31 pm
Updated
7 Jan 2026, 4:31 pm
Created By
claude
Raw Data
{
"id": "488b1edf-d38a-457e-9cbf-c7edc4f6bd48",
"type": "general",
"status": "completed",
"title": "FileViewer Component Test",
"description": "Testing the FileViewer component with syntax highlighting, line numbers, and copy functionality",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:sans-serif;\">\n<h2 style=\"margin:0 0 16px 0;color:#fff;\">🔍 FileViewer Component Test</h2>\n<p style=\"color:#9ca3af;margin-bottom:20px;\">Testing the interactive FileViewer with syntax highlighting, line numbers, copy, and collapsible features.</p>\n\n<h3 style=\"color:#c9956a;margin:16px 0 12px 0;\">Test 1: TypeScript File with Highlighted Lines</h3>\n<div class=\"file-viewer\" id=\"test-viewer-1\">\n <div class=\"fv-header\">\n <div class=\"fv-file-info\">\n <span class=\"fv-icon\">📘</span>\n <span class=\"fv-path\">src/example.ts</span>\n <span class=\"fv-meta\">12 lines · TypeScript</span>\n </div>\n <div class=\"fv-actions\">\n <button class=\"fv-btn fv-copy-btn\" onclick=\"copyFileContent_test_viewer_1()\">📋 Copy</button>\n </div>\n </div>\n <div class=\"fv-content\" style=\"max-height: 300px;\">\n <div class=\"fv-lines\">\n <div class=\"fv-line\" data-line=\"1\">\n <span class=\"fv-line-num\">1</span>\n <span class=\"fv-line-content\"><span class=\"fv-comment\">// Example TypeScript file for FileViewer test</span></span>\n </div>\n <div class=\"fv-line\" data-line=\"2\">\n <span class=\"fv-line-num\">2</span>\n <span class=\"fv-line-content\"><span class=\"fv-keyword\">import</span> { Router } <span class=\"fv-keyword\">from</span> <span class=\"fv-string\">"./router"</span>;</span>\n </div>\n <div class=\"fv-line\" data-line=\"3\">\n <span class=\"fv-line-num\">3</span>\n <span class=\"fv-line-content\"> </span>\n </div>\n <div class=\"fv-line highlighted\" data-line=\"4\">\n <span class=\"fv-line-num\">4</span>\n <span class=\"fv-line-content\"><span class=\"fv-keyword\">export</span> <span class=\"fv-keyword\">interface</span> Config {</span>\n </div>\n <div class=\"fv-line highlighted\" data-line=\"5\">\n <span class=\"fv-line-num\">5</span>\n <span class=\"fv-line-content\"> port: <span class=\"fv-type\">number</span>;</span>\n </div>\n <div class=\"fv-line highlighted\" data-line=\"6\">\n <span class=\"fv-line-num\">6</span>\n <span class=\"fv-line-content\"> host: <span class=\"fv-type\">string</span>;</span>\n </div>\n <div class=\"fv-line\" data-line=\"7\">\n <span class=\"fv-line-num\">7</span>\n <span class=\"fv-line-content\">}</span>\n </div>\n <div class=\"fv-line\" data-line=\"8\">\n <span class=\"fv-line-num\">8</span>\n <span class=\"fv-line-content\"> </span>\n </div>\n <div class=\"fv-line\" data-line=\"9\">\n <span class=\"fv-line-num\">9</span>\n <span class=\"fv-line-content\"><span class=\"fv-keyword\">const</span> PORT = <span class=\"fv-number\">8080</span>;</span>\n </div>\n <div class=\"fv-line\" data-line=\"10\">\n <span class=\"fv-line-num\">10</span>\n <span class=\"fv-line-content\"><span class=\"fv-keyword\">const</span> HOST = <span class=\"fv-string\">"localhost"</span>;</span>\n </div>\n <div class=\"fv-line\" data-line=\"11\">\n <span class=\"fv-line-num\">11</span>\n <span class=\"fv-line-content\"> </span>\n </div>\n <div class=\"fv-line\" data-line=\"12\">\n <span class=\"fv-line-num\">12</span>\n <span class=\"fv-line-content\">console.log(<span class=\"fv-string\">`Server on ${HOST}:${PORT}`</span>);</span>\n </div>\n </div>\n </div>\n <div class=\"fv-footer\" style=\"display:none;\">\n <span class=\"fv-scroll-hint\">Scroll to see more ↕</span>\n </div>\n</div>\n<script>\n(function() {\n const viewer = document.getElementById('test-viewer-1');\n if (!viewer) return;\n \n const content = viewer.querySelector('.fv-content');\n const footer = viewer.querySelector('.fv-footer');\n \n function updateScrollHint() {\n if (content && footer) {\n const hasOverflow = content.scrollHeight > content.clientHeight;\n footer.style.display = hasOverflow ? 'block' : 'none';\n }\n }\n updateScrollHint();\n \n if (content) {\n content.addEventListener('scroll', () => {\n const atBottom = content.scrollTop + content.clientHeight >= content.scrollHeight - 10;\n if (footer) footer.style.opacity = atBottom ? '0.3' : '1';\n });\n }\n \n window.copyFileContent_test_viewer_1 = function() {\n const rawContent = '// Example TypeScript file\\nimport { Router } from \"./router\";\\n\\nexport interface Config {\\n port: number;\\n host: string;\\n}\\n\\nconst PORT = 8080;\\nconst HOST = \"localhost\";\\n\\nconsole.log(`Server on ${HOST}:${PORT}`);\n';\n navigator.clipboard.writeText(rawContent).then(() => {\n const btn = viewer.querySelector('.fv-copy-btn');\n if (btn) {\n const orig = btn.textContent;\n btn.textContent = '✓ Copied!';\n setTimeout(() => btn.textContent = orig, 2000);\n }\n });\n };\n \n viewer.querySelectorAll('.fv-line').forEach(line => {\n line.addEventListener('click', () => {\n line.classList.toggle('selected');\n });\n });\n \n console.log('[FileViewer] Test 1 initialized');\n})();\n</script>\n\n<h3 style=\"color:#c9956a;margin:24px 0 12px 0;\">Test 2: Collapsible Python File</h3>\n<div class=\"file-viewer\" id=\"test-viewer-2\" data-collapsed=\"true\">\n <div class=\"fv-header\">\n <div class=\"fv-file-info\">\n <span class=\"fv-icon\">🐍</span>\n <span class=\"fv-path\">scripts/process.py</span>\n <span class=\"fv-meta\">6 lines · Python</span>\n </div>\n <div class=\"fv-actions\">\n <button class=\"fv-btn fv-collapse-btn\" onclick=\"toggleFileViewer_test_viewer_2()\">▶</button>\n <button class=\"fv-btn fv-copy-btn\" onclick=\"copyFileContent_test_viewer_2()\">📋 Copy</button>\n </div>\n </div>\n <div class=\"fv-content\" style=\"max-height: 200px; display: none;\">\n <div class=\"fv-lines\">\n <div class=\"fv-line\" data-line=\"1\">\n <span class=\"fv-line-num\">1</span>\n <span class=\"fv-line-content\"><span class=\"fv-comment\"># Python script example</span></span>\n </div>\n <div class=\"fv-line\" data-line=\"2\">\n <span class=\"fv-line-num\">2</span>\n <span class=\"fv-line-content\"><span class=\"fv-keyword\">def</span> process(data):</span>\n </div>\n <div class=\"fv-line\" data-line=\"3\">\n <span class=\"fv-line-num\">3</span>\n <span class=\"fv-line-content\"> <span class=\"fv-keyword\">for</span> item <span class=\"fv-keyword\">in</span> data:</span>\n </div>\n <div class=\"fv-line\" data-line=\"4\">\n <span class=\"fv-line-num\">4</span>\n <span class=\"fv-line-content\"> print(f<span class=\"fv-string\">"Processing: {item}"</span>)</span>\n </div>\n <div class=\"fv-line\" data-line=\"5\">\n <span class=\"fv-line-num\">5</span>\n <span class=\"fv-line-content\"> <span class=\"fv-keyword\">return</span> <span class=\"fv-keyword\">True</span></span>\n </div>\n <div class=\"fv-line\" data-line=\"6\">\n <span class=\"fv-line-num\">6</span>\n <span class=\"fv-line-content\"> </span>\n </div>\n </div>\n </div>\n <div class=\"fv-footer\" style=\"display:none;\">\n <span class=\"fv-scroll-hint\">Scroll to see more ↕</span>\n </div>\n</div>\n<script>\n(function() {\n const viewer = document.getElementById('test-viewer-2');\n if (!viewer) return;\n \n const content = viewer.querySelector('.fv-content');\n const footer = viewer.querySelector('.fv-footer');\n \n function updateScrollHint() {\n if (content && footer) {\n const hasOverflow = content.scrollHeight > content.clientHeight;\n footer.style.display = hasOverflow ? 'block' : 'none';\n }\n }\n \n window.toggleFileViewer_test_viewer_2 = function() {\n const isCollapsed = viewer.dataset.collapsed === 'true';\n viewer.dataset.collapsed = isCollapsed ? 'false' : 'true';\n content.style.display = isCollapsed ? 'block' : 'none';\n const btn = viewer.querySelector('.fv-collapse-btn');\n if (btn) btn.textContent = isCollapsed ? '▼' : '▶';\n if (isCollapsed) updateScrollHint();\n };\n \n window.copyFileContent_test_viewer_2 = function() {\n const rawContent = '# Python script example\\ndef process(data):\\n for item in data:\\n print(f\"Processing: {item}\")\\n return True\\n';\n navigator.clipboard.writeText(rawContent).then(() => {\n const btn = viewer.querySelector('.fv-copy-btn');\n if (btn) {\n const orig = btn.textContent;\n btn.textContent = '✓ Copied!';\n setTimeout(() => btn.textContent = orig, 2000);\n }\n });\n };\n \n viewer.querySelectorAll('.fv-line').forEach(line => {\n line.addEventListener('click', () => {\n line.classList.toggle('selected');\n });\n });\n \n console.log('[FileViewer] Test 2 initialized (collapsible)');\n})();\n</script>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-top:20px;\">\n<h4 style=\"margin:0 0 12px 0;color:#fff;\">✅ Features to Verify</h4>\n<ul style=\"color:#9ca3af;margin:0;padding-left:20px;line-height:1.8;\">\n<li><strong>Line numbers</strong> - Left column shows line numbers</li>\n<li><strong>Syntax highlighting</strong> - Keywords purple, strings green, comments gray, numbers orange</li>\n<li><strong>Highlighted lines</strong> - Lines 4-6 in Test 1 have gold background</li>\n<li><strong>Click to select</strong> - Click any line to toggle blue selection</li>\n<li><strong>Copy button</strong> - Click 📋 Copy to copy file contents</li>\n<li><strong>Collapsible</strong> - Test 2 starts collapsed, click ▶ to expand</li>\n</ul>\n</div>\n</div>\n<style>\n.file-viewer {\n background: #1e1e1e;\n border-radius: 8px;\n overflow: hidden;\n margin: 12px 0;\n font-family: 'Consolas', 'Monaco', 'Fira Code', monospace;\n font-size: 0.85rem;\n}\n.fv-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: #2d2d2d;\n border-bottom: 1px solid #3d3d3d;\n}\n.fv-file-info {\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n.fv-icon { font-size: 1rem; flex-shrink: 0; }\n.fv-path { color: #e0e0e0; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.fv-meta { color: #7f848e; font-size: 0.8rem; white-space: nowrap; }\n.fv-actions { display: flex; gap: 8px; flex-shrink: 0; }\n.fv-btn {\n background: #3d3d3d;\n border: none;\n color: #e0e0e0;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.8rem;\n transition: background 0.15s;\n}\n.fv-btn:hover { background: #4d4d4d; }\n.fv-collapse-btn { padding: 6px 10px; }\n.fv-content { overflow: auto; background: #1e1e1e; }\n.fv-lines { display: table; width: 100%; padding: 8px 0; }\n.fv-line { display: table-row; line-height: 1.5; }\n.fv-line:hover { background: rgba(255, 255, 255, 0.05); }\n.fv-line.highlighted { background: rgba(201, 149, 66, 0.2); }\n.fv-line.highlighted:hover { background: rgba(201, 149, 66, 0.3); }\n.fv-line.selected { background: rgba(97, 175, 239, 0.2); }\n.fv-line-num {\n display: table-cell;\n width: 50px;\n padding: 0 16px;\n text-align: right;\n color: #5c6370;\n user-select: none;\n border-right: 1px solid #3d3d3d;\n}\n.fv-line-content { display: table-cell; padding: 0 16px; white-space: pre; color: #abb2bf; }\n.fv-footer { padding: 8px 16px; background: #2d2d2d; border-top: 1px solid #3d3d3d; text-align: center; }\n.fv-scroll-hint { color: #7f848e; font-size: 0.75rem; }\n.fv-keyword { color: #c678dd; }\n.fv-string { color: #98c379; }\n.fv-comment { color: #5c6370; font-style: italic; }\n.fv-number { color: #d19a66; }\n.fv-type { color: #e5c07b; }\n</style>",
"choices": [
{
"label": "Test passed",
"value": "FileViewer test passed - all Step 7 components complete",
"primary": true
},
{
"label": "Issue found",
"value": "FileViewer has an issue: "
}
]
},
"createdBy": "claude",
"createdAt": "2026-01-07T06:31:57.826Z",
"updatedAt": "2026-01-07T06:31:58.028Z",
"scope": "vibetools",
"tags": [
"kontasks",
"ui",
"components",
"test"
],
"targetUser": "claude"
}