/** * json-render 组件测试页面 * * 测试所有 15 个 json-render 组件的渲染效果 */ 'use client'; import { useState } from 'react'; import JsonRenderer from '@/components/JsonRenderer'; import type { ComponentSpec } from '@/lib/json-render-catalog'; // ============ 基础组件示例数据 ============ const cardSpec: ComponentSpec = { type: 'card', title: '卡片标题', children: [ { type: 'text', content: '这是一个卡片组件示例,用于包装和展示相关内容。', variant: 'body', }, ], }; const stackSpec: ComponentSpec = { type: 'stack', direction: 'row', spacing: 4, align: 'center', children: [ { type: 'badge', text: '项目 A', variant: 'info', }, { type: 'badge', text: '项目 B', variant: 'success', }, { type: 'badge', text: '项目 C', variant: 'warning', }, ], }; const headingSpecs: ComponentSpec[] = [ { type: 'heading', level: 'h1', text: 'Heading Level 1' }, { type: 'heading', level: 'h2', text: 'Heading Level 2' }, { type: 'heading', level: 'h3', text: 'Heading Level 3' }, { type: 'heading', level: 'h4', text: 'Heading Level 4' }, { type: 'heading', level: 'h5', text: 'Heading Level 5' }, { type: 'heading', level: 'h6', text: 'Heading Level 6' }, ]; const textSpecs: ComponentSpec[] = [ { type: 'text', content: '这是默认样式的正文文本,用于主要内容展示。', variant: 'body' }, { type: 'text', content: '这是静音样式的文本,用于次要信息。', variant: 'muted' }, { type: 'text', content: 'const code = "这是代码样式的文本";', variant: 'code' }, ]; const buttonSpecs: ComponentSpec[] = [ { type: 'button', label: 'Default Button', variant: 'default' }, { type: 'button', label: 'Primary Button', variant: 'primary' }, { type: 'button', label: 'Secondary Button', variant: 'secondary' }, { type: 'button', label: 'Ghost Button', variant: 'ghost' }, { type: 'button', label: 'Danger Button', variant: 'danger' }, { type: 'button', label: 'Disabled Button', variant: 'default', disabled: true }, ]; const inputSpecs: ComponentSpec[] = [ { type: 'input', placeholder: '请输入用户名...' }, { type: 'input', placeholder: '禁用状态', value: '固定值', disabled: true }, ]; const badgeSpecs: ComponentSpec[] = [ { type: 'badge', text: 'Default', variant: 'default' }, { type: 'badge', text: 'Success', variant: 'success' }, { type: 'badge', text: 'Warning', variant: 'warning' }, { type: 'badge', text: 'Error', variant: 'error' }, { type: 'badge', text: 'Info', variant: 'info' }, ]; const separatorSpecs: ComponentSpec[] = [ { type: 'separator', orientation: 'horizontal' }, { type: 'separator', orientation: 'vertical' }, ]; // ============ MCP 组件示例数据 ============ const translationResultSpec: ComponentSpec = { type: 'translation-result', translated: 'Lin Feng is an outer disciple of the Spirit Sect, possessing a mysterious cultivation technique that allows him to absorb the energy of heaven and earth.', termsUsed: ['Lin Feng', 'outer disciple', 'Spirit Sect', 'cultivation technique'], }; const novelListSpec: ComponentSpec = { type: 'novel-list', novels: [ { id: '1', title: '修仙之王', author: '张三', description: '一个凡人逆天改命,最终成就仙道的故事。', chapterCount: 1500, tags: ['修仙', '热血', '爽文'], }, { id: '2', title: '都市医仙', author: '李四', description: '一代医仙重回都市,悬壶济世。', chapterCount: 800, tags: ['都市', '医术', '重生'], }, { id: '3', title: '星际霸主', author: '王五', description: '银河系战神,征服星辰大海。', chapterCount: 2000, tags: ['科幻', '星际', '战争'], }, ], }; const chapterReaderSpec: ComponentSpec = { type: 'chapter-reader', novelTitle: '修仙之王', chapterTitle: '第一章: 重生', content: `林峰睁开眼睛,发现自己躺在一张简陋的木床上。 周围是熟悉的茅草屋,空气中弥漫着淡淡的药草味。他猛地坐起身来,看着自己瘦弱的手臂,难以置信地喃喃自语:"我...我竟然重生了?" 上一世,他是修仙界赫赫有名的丹尊,却因渡劫失败而陨落。没想到,竟然回到了少年时期,那个他还只是外门弟子的时候。 "既然上天给我重来的机会,这一世,我定要登临仙道巅峰!"`, chapterNumber: 1, totalChapters: 1500, }; const mcpToolCallSpecs: ComponentSpec[] = [ { type: 'mcp-tool-call', tool: 'translate_text', status: 'pending', args: { text: 'Hello, world!', target_lang: 'zh' }, timestamp: new Date().toISOString(), }, { type: 'mcp-tool-call', tool: 'get_novels', status: 'running', args: { page: 1, limit: 10 }, timestamp: new Date().toISOString(), }, { type: 'mcp-tool-call', tool: 'translate_text', status: 'success', args: { text: 'Hello' }, result: { translated: '你好' }, timestamp: new Date().toISOString(), }, { type: 'mcp-tool-call', tool: 'get_chapter', status: 'error', error: 'Chapter not found', timestamp: new Date().toISOString(), }, ]; const loginPanelSpec: ComponentSpec = { type: 'login-panel', server: 'novel-platform-user', }; const codeBlockSpecs: ComponentSpec[] = [ { type: 'code-block', code: 'function greet(name: string) {\n return `Hello, ${name}!`;\n}', language: 'typescript', }, { type: 'code-block', code: 'SELECT * FROM users WHERE active = true;', language: 'sql', }, { type: 'code-block', code: 'const inline = true;', language: 'javascript', inline: true, }, ]; const dataTableSpec: ComponentSpec = { type: 'data-table', columns: [ { key: 'id', label: 'ID', sortable: true }, { key: 'name', label: '名称', sortable: true }, { key: 'status', label: '状态', sortable: true }, { key: 'updated', label: '更新时间', sortable: true }, ], rows: [ { id: '1', name: '小说 A', status: '已完结', updated: '2026-03-15' }, { id: '2', name: '小说 B', status: '连载中', updated: '2026-03-16' }, { id: '3', name: '小说 C', status: '已完结', updated: '2026-03-17' }, { id: '4', name: '小说 D', status: '连载中', updated: '2026-03-18' }, ], sortable: true, }; // ============ 测试页面组件 ============ export default function TestPage() { const [selectedTab, setSelectedTab] = useState<'basic' | 'mcp'>('basic'); return (
{/* 页面头部 */}

json-render 组件测试页面

测试所有 15 个 json-render 组件的渲染效果

{/* Tab 导航 */}
{/* 内容区域 */}
{selectedTab === 'basic' ? (
{/* Card 组件 */}

1 Card - 卡片容器

{/* Stack 组件 */}

2 Stack - 弹性布局容器

{/* Heading 组件 */}

3 Heading - 标题 (h1-h6)

{/* Text 组件 */}

4 Text - 文本内容

{/* Button 组件 */}

5 Button - 按钮

{/* Input 组件 */}

6 Input - 输入框

{/* Badge 组件 */}

7 Badge - 徽章标签

{/* Separator 组件 */}

8 Separator - 分隔线

左侧内容 右侧内容
) : (
{/* TranslationResult 组件 */}

1 TranslationResult - 翻译结果展示

{/* NovelList 组件 */}

2 NovelList - 小说列表

{/* ChapterReader 组件 */}

3 ChapterReader - 章节阅读器

{/* McpToolCall 组件 */}

4 McpToolCall - 工具调用可视化

{/* LoginPanel 组件 */}

5 LoginPanel - 登录面板

{/* CodeBlock 组件 */}

6 CodeBlock - 代码块

{/* DataTable 组件 */}

7 DataTable - 数据表格

)}
{/* 页脚 */}
); }