json-ui
JSON形式のUIコンポーネントを構築・表示するために使用し、多言語対応やレポート作成、各種UI要素のレンダリングを可能にするSkill。
📜 元の英語説明(参考)
CRITICAL: Use for json-ui component rendering and development. Triggers on: json-ui, json render, component catalog, report render, HTML report, I18nString, i18n, bilingual, language switch, dual language, PaperHeader, AuthorList, Abstract, MetricsGrid, Section, Highlight, Zod schema, catalog.ts, cli.ts, components/index.tsx, "how to add a component", "how to render JSON", JSON 渲染, 组件目录, 报告渲染, 多语言, 中英文切换
🇯🇵 日本人クリエイター向け解説
JSON形式のUIコンポーネントを構築・表示するために使用し、多言語対応やレポート作成、各種UI要素のレンダリングを可能にするSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o json-ui.zip https://jpskill.com/download/15682.zip && unzip -o json-ui.zip && rm json-ui.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15682.zip -OutFile "$d\json-ui.zip"; Expand-Archive "$d\json-ui.zip" -DestinationPath $d -Force; ri "$d\json-ui.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
json-ui.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
json-uiフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
json-ui
バージョン: 1.0.0 | 最終更新日: 2026-01-29
あなたは json-ui パッケージのエキスパートです。これは、React コンポーネントのサポート、バイリンガル i18n、および CLI ツールを備えた JSON から HTML へのレポートレンダラーです。以下を行うことでユーザーを支援します。
- コンポーネントの作成: 既存のパターンに従って新しいコンポーネントタイプを追加します
- レポートのレンダリング: JSON レポート定義から HTML を生成します
- デバッグ: レンダリング、ビルド、または i18n の問題を修正します
- 質問への回答: アーキテクチャ、コンポーネントカタログ、データフローについて説明します
クイックリファレンス
| タスク | ファイル | パターン |
|---|---|---|
| コンポーネントスキーマの定義 | src/catalog.ts |
Zod スキーマを追加し、catalog オブジェクトでエクスポートします |
| コンポーネントのレンダリング (HTML) | src/cli.ts |
renderNode() スイッチに case を追加します |
| コンポーネントのレンダリング (React) | src/components/index.tsx |
カタログタイプを使用して React FC をエクスポートします |
| i18n テキストの追加 | 任意の JSON | { "en": "Hello", "zh": "你好" } またはプレーンな "Hello" |
| ビルド | ターミナル | pnpm build (tsup を使用し、ESM + DTS を出力します) |
| レポートのレンダリング | ターミナル | json-ui render report.json [-o out.html] [--no-open] |
ドキュメント
詳細なドキュメントについては、ローカルソースファイルを参照してください。
packages/json-ui/src/catalog.ts- すべての Zod スキーマと型定義packages/json-ui/src/cli.ts- HTML レンダラーと CLI エントリポイントpackages/json-ui/src/components/index.tsx- React コンポーネントの実装
重要: ドキュメントの完全性チェック
質問に答える前に、Claude は以下を行う必要があります。
- 上記の関連するソースファイルを読みます
- ファイルの読み込みに失敗した場合: ユーザーに「本地文档不完整,建议更新」(ローカルドキュメントが不完全です。更新することをお勧めします) と伝えます
- それでも SKILL.md パターン + 組み込みの知識に基づいて回答します
アーキテクチャ
JSON レポート形式
レポートはノードのツリーです。
{
"type": "Report",
"props": { "title": "My Report", "theme": "auto" },
"children": [
{
"type": "Section",
"props": { "title": "Overview", "icon": "bulb" },
"children": [
{ "type": "Abstract", "props": { "text": "..." } }
]
}
]
}
3 つのレンダリングレイヤー
| レイヤー | ファイル | 出力 | ユースケース |
|---|---|---|---|
| Zod スキーマ | catalog.ts |
型定義 | バリデーション、型安全性 |
| HTML レンダラー | cli.ts |
静的な HTML 文字列 | CLI render コマンド |
| React コンポーネント | components/index.tsx |
React 要素 | 埋め込みでの使用 |
データフロー
JSON file → CLI parse → renderNode() recursion → HTML string → file write → browser open
コンポーネントカタログ (38 種類)
レイアウト
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
Report |
title?, theme |
ルートラッパー、最大幅 800px |
Section |
title, icon?, collapsible? |
ヘッダー付きの折りたたみ可能なセクション |
Grid |
cols, gap |
CSS グリッドレイアウト |
Card |
variant, padding, shadow |
カードコンテナ |
論文情報
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
PaperHeader |
title, arxivId, date, categories? |
論文のタイトル + メタデータ |
AuthorList |
authors, layout?, maxVisible? |
著者名 + 所属 |
Abstract |
text, highlights?, maxLength? |
キーワードのハイライト表示付きの要約 |
TagList |
tags, variant |
タグ/カテゴリのピル |
コンテンツ
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
ContributionList |
items, numbered? |
バッジ付きの番号付きの貢献 |
MethodOverview |
steps, showConnectors? |
ステップごとのメソッドパイプライン |
Highlight |
text, type, source? |
ブロック引用 (引用/重要/警告/コード) |
KeyPoint |
icon, title, description |
アイコン + タイトル + 説明 |
CodeBlock |
code, language, showLineNumbers? |
構文が強調表示されたコード |
Prose |
content |
Markdown コンテンツブロック |
Callout |
type, title?, content |
情報/ヒント/警告/重要/メモボックス |
リッチコンテンツ
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
Image |
src, alt?, caption?, width? |
単一の画像 |
Figure |
images, caption?, label? |
複数画像の図 |
Formula |
latex, block?, label? |
LaTeX 数式 |
DefinitionList |
items |
用語と定義のペア |
Theorem |
type, number?, title?, content |
定理/補題/命題 |
Algorithm |
title, steps, caption? |
アルゴリズムの擬似コード |
ResultsTable |
columns, rows, highlights? |
最良セルが強調表示された結果 |
データ表示
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
Metric |
label, value, trend?, icon? |
単一のメトリックカード |
MetricsGrid |
metrics, cols? |
メトリックカードのグリッド |
Table |
columns, rows, striped?, caption? |
データテーブル |
インタラクティブ
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
LinkButton |
href, label, icon?, external? |
スタイル付きのリンクボタン |
LinkGroup |
links, layout? |
リンクボタンのグループ |
ブランド
| コンポーネント | 主要なプロパティ | 説明 |
|---|---|---|
BrandHeader |
badge?, poweredBy?, showBadge? |
AI によって生成されたバッジヘッダー |
BrandFooter |
timestamp, attribution?, disclaimer? |
属性付きのフッター |
I18n システム
下位互換性のあるバイリンガル文字列
I18nString 型は、プレーンな文字列とバイリンガルオブジェクトの両方を受け入れます。
// catalog.ts
export const I18nString = z.union([
z.string(),
z.object({ en: z.string(), zh: z.string() }),
]);
JSON の使用法
// プレーンな文字列 (下位互換性あり)
{ "title": "Hello World" }
// バイリンガルオブジェクト
{ "title": { "en": "Hello World", "zh": "你好世界" } }
HTML レンダリング (cli.ts)
HTML 出力の場合、i18n 文字列はデュアルスパンとしてレンダリングされます。
// renderI18n() の出力:
<span class="i18n-en">Hello</span><span class="i18n-zh">你好</span>
// CSS は可視性を制御します。
html[lang="en"] .i18n-zh { display: none; }
html[lang="zh"] .i18n-en { display: none; }
プレーンな文字列のみが機能する HTML 属性 (alt、title) の場合:
// resolveI18n() は選択します
(原文はここで切り捨てられています) 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
json-ui
Version: 1.0.0 | Last Updated: 2026-01-29
You are an expert at the json-ui package — a JSON-to-HTML report renderer with React component support, bilingual i18n, and a CLI tool. Help users by:
- Writing components: Add new component types following existing patterns
- Rendering reports: Generate HTML from JSON report definitions
- Debugging: Fix rendering, build, or i18n issues
- Answering questions: Explain architecture, component catalog, data flow
Quick Reference
| Task | File | Pattern |
|---|---|---|
| Define component schema | src/catalog.ts |
Add Zod schema + export in catalog object |
| Render component (HTML) | src/cli.ts |
Add case in renderNode() switch |
| Render component (React) | src/components/index.tsx |
Export React FC using catalog types |
| Add i18n text | Any JSON | { "en": "Hello", "zh": "你好" } or plain "Hello" |
| Build | terminal | pnpm build (uses tsup, outputs ESM + DTS) |
| Render report | terminal | json-ui render report.json [-o out.html] [--no-open] |
Documentation
Refer to local source files for detailed documentation:
packages/json-ui/src/catalog.ts- All Zod schemas and type definitionspackages/json-ui/src/cli.ts- HTML renderer and CLI entry pointpackages/json-ui/src/components/index.tsx- React component implementations
IMPORTANT: Documentation Completeness Check
Before answering questions, Claude MUST:
- Read the relevant source file(s) listed above
- If file read fails: Inform user "本地文档不完整,建议更新"
- Still answer based on SKILL.md patterns + built-in knowledge
Architecture
JSON Report Format
Reports are trees of nodes:
{
"type": "Report",
"props": { "title": "My Report", "theme": "auto" },
"children": [
{
"type": "Section",
"props": { "title": "Overview", "icon": "bulb" },
"children": [
{ "type": "Abstract", "props": { "text": "..." } }
]
}
]
}
Three Rendering Layers
| Layer | File | Output | Use Case |
|---|---|---|---|
| Zod Schemas | catalog.ts |
Type definitions | Validation, type safety |
| HTML Renderer | cli.ts |
Static HTML string | CLI render command |
| React Components | components/index.tsx |
React elements | Embedded usage |
Data Flow
JSON file → CLI parse → renderNode() recursion → HTML string → file write → browser open
Component Catalog (38 types)
Layout
| Component | Key Props | Description |
|---|---|---|
Report |
title?, theme |
Root wrapper, 800px max-width |
Section |
title, icon?, collapsible? |
Collapsible section with header |
Grid |
cols, gap |
CSS grid layout |
Card |
variant, padding, shadow |
Card container |
Paper Info
| Component | Key Props | Description |
|---|---|---|
PaperHeader |
title, arxivId, date, categories? |
Paper title + metadata |
AuthorList |
authors, layout?, maxVisible? |
Author names + affiliations |
Abstract |
text, highlights?, maxLength? |
Abstract with keyword highlighting |
TagList |
tags, variant |
Tag/category pills |
Content
| Component | Key Props | Description |
|---|---|---|
ContributionList |
items, numbered? |
Numbered contributions with badges |
MethodOverview |
steps, showConnectors? |
Step-by-step method pipeline |
Highlight |
text, type, source? |
Blockquote (quote/important/warning/code) |
KeyPoint |
icon, title, description |
Icon + title + description |
CodeBlock |
code, language, showLineNumbers? |
Syntax-highlighted code |
Prose |
content |
Markdown content block |
Callout |
type, title?, content |
Info/tip/warning/important/note box |
Rich Content
| Component | Key Props | Description |
|---|---|---|
Image |
src, alt?, caption?, width? |
Single image |
Figure |
images, caption?, label? |
Multi-image figure |
Formula |
latex, block?, label? |
LaTeX formula |
DefinitionList |
items |
Term-definition pairs |
Theorem |
type, number?, title?, content |
Theorem/lemma/proposition |
Algorithm |
title, steps, caption? |
Algorithm pseudocode |
ResultsTable |
columns, rows, highlights? |
Results with best-cell highlighting |
Data Display
| Component | Key Props | Description |
|---|---|---|
Metric |
label, value, trend?, icon? |
Single metric card |
MetricsGrid |
metrics, cols? |
Grid of metric cards |
Table |
columns, rows, striped?, caption? |
Data table |
Interactive
| Component | Key Props | Description |
|---|---|---|
LinkButton |
href, label, icon?, external? |
Styled link button |
LinkGroup |
links, layout? |
Group of link buttons |
Brand
| Component | Key Props | Description |
|---|---|---|
BrandHeader |
badge?, poweredBy?, showBadge? |
AI-generated badge header |
BrandFooter |
timestamp, attribution?, disclaimer? |
Footer with attribution |
I18n System
Backward-Compatible Bilingual Strings
The I18nString type accepts both plain strings and bilingual objects:
// catalog.ts
export const I18nString = z.union([
z.string(),
z.object({ en: z.string(), zh: z.string() }),
]);
JSON Usage
// Plain string (backward compatible)
{ "title": "Hello World" }
// Bilingual object
{ "title": { "en": "Hello World", "zh": "你好世界" } }
HTML Rendering (cli.ts)
For HTML output, i18n strings render as dual spans:
// renderI18n() outputs:
<span class="i18n-en">Hello</span><span class="i18n-zh">你好</span>
// CSS controls visibility:
html[lang="en"] .i18n-zh { display: none; }
html[lang="zh"] .i18n-en { display: none; }
For HTML attributes (alt, title) where only a plain string works:
// resolveI18n() picks one language:
const alt = resolveI18n(props.alt, 'en'); // returns plain string
React Rendering (components/index.tsx)
// Use <I18nText> component for JSX:
<I18nText value={props.title} />
// Use resolveI18nStr() for plain string contexts:
const altText = resolveI18nStr(props.alt, 'en');
Language Switcher
- Fixed top-right button: EN | 中文
- Toggles
<html lang="en|zh">attribute - Persists choice via
localStorage.getItem('json-ui-lang')
Key Patterns
Pattern 1: Adding a New Component
- Define schema in
catalog.ts:export const MyWidgetSchema = z.object({ label: I18nString, // Use I18nString for user-visible text count: z.number(), // Use z.string()/z.number() for data variant: VariantType.default('default'), });
// Add to catalog object: export const catalog = { // ...existing... MyWidget: MyWidgetSchema, } as const;
// Export type: export type MyWidgetProps = z.infer<typeof MyWidgetSchema>;
2. **Add HTML renderer** in `cli.ts` `renderNode()` switch:
```typescript
case 'MyWidget': {
const { label, count, variant } = props;
return `<div class="my-widget ${variant}">
<span>${renderI18n(label)}</span>
<strong>${escapeHtml(String(count))}</strong>
</div>`;
}
- Add React component in
components/index.tsx:export const MyWidget: React.FC<MyWidgetProps> = ({ label, count, variant = 'default' }) => ( <div className={`my-widget ${variant}`}> <span><I18nText value={label} /></span> <strong>{count}</strong> </div> );
Pattern 2: Handling I18n in Special Cases
For text that needs processing (e.g., Abstract highlights):
// HTML (cli.ts) - process each language separately:
if (isI18n(text)) {
return `<span class="i18n-en">${processText(text.en)}</span>
<span class="i18n-zh">${processText(text.zh)}</span>`;
} else {
return processText(String(text));
}
// React (components/index.tsx):
if (typeof text === 'object' && 'en' in text && 'zh' in text) {
return (
<>
<span className="i18n-en" dangerouslySetInnerHTML={{ __html: processText(text.en) }} />
<span className="i18n-zh" dangerouslySetInnerHTML={{ __html: processText(text.zh) }} />
</>
);
}
Common Errors
| Error | Cause | Solution |
|---|---|---|
Type 'I18nStringType' is not assignable to 'ReactNode' |
Passing i18n object directly to JSX | Wrap with <I18nText value={...} /> |
Property 'length' does not exist on type 'I18nStringType' |
Calling string methods on i18n value | Use type guard: typeof text === 'string' ? text : text.en |
| Images not loading from arxiv | crossorigin="anonymous" on <img> |
Remove crossorigin; keep only referrerpolicy="no-referrer" |
| Language switcher not working | Missing CSS rules or JS | Ensure html[lang] .i18n-* CSS rules and toggle JS are in template |
| Build fails with type errors | Schema changed but components not updated | Update all three files: catalog, cli, components |
CRITICAL: Image Handling
Do NOT use crossorigin="anonymous" on <img> tags.
Sites like arxiv.org do not send CORS headers. Adding crossorigin="anonymous" causes the browser to require CORS, which fails and blocks the image.
<!-- WRONG - breaks images from arxiv and similar sites -->
<img src="..." referrerpolicy="no-referrer" crossorigin="anonymous" />
<!-- CORRECT -->
<img src="..." referrerpolicy="no-referrer" />
Chinese Translation Guidelines
When writing Chinese translations for ML/AI papers:
| Wrong | Correct | Reason |
|---|---|---|
| 评论器 | 价值函数(critic) | Standard ML term |
| 运行估计 | 滑动估计 | Running estimate = 滑动估计 |
| 重加权因子 | 加权系数 | More natural Chinese |
| 不断演化的 | 动态更新的 | Clearer meaning |
| 简单修复 | 改动小 | Academic tone |
Build & CLI
# Build (ESM + DTS via tsup)
cd packages/json-ui && pnpm build
# Render report to HTML
node dist/cli.js render example-report-rich.json
# With options
node dist/cli.js render report.json -o output.html --no-open
When Writing Code
- Always use
I18nStringfor user-visible text properties in schemas - Always handle both string and
{en, zh}forms in renderers - Never use
crossorigin="anonymous"on img tags - Keep
referrerpolicy="no-referrer"on img tags for privacy - Test with
pnpm buildafter any schema or component changes - Update all three layers (catalog, cli, components) when adding components