generative-ui について
Claude内蔵のshow_widgetツールでインタラクティブなHTML・SVGウィジェットを作成するためのデザインスキルです。Claudeや他のホスト環境で使える視覚形式の選び方、スタイル規則、テンプレートを示し、ツール非対応時の単独HTML出力にも対応します。
主な機能
- 01視覚形式の選択ガイド
- 02HTML・SVGウィジェットのパターン
- 03ライト・ダークモードのデザイン規則
- 04Chart.jsの設定ガイド
- 05ホスト別のレンダリング手順
活用シーン
- 01会話内のインタラクティブな説明の作成
- 02比較内容のビジュアルグリッド化
- 03会話内でのチャートや図の表示
- 04show_widget非対応環境での単独ウィジェット保存
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ himself65/ finance-skills --skill generative-uiインストール後、Claude Code で/generative-uiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/chart_js.mddesign_system.mdsvg_and_diagrams.md詳細
生成 UI スキル
このスキルには、Claude に組み込まれた show_widget ツールのデザインシステムがすべて含まれています。これは、claude.ai の会話内にインタラクティブな HTML/SVG ウィジェットをインラインで表示する生成 UI 機能です。以下のガイドラインは、実際の Anthropic「Imagine — Visual Creation Suite」のデザインルールを抽出したものです。read_me のセットアップ呼び出しを行わずに、高品質なウィジェットを直接作成できます。
仕組み:claude.ai では、Claude は会話内に HTML/SVG の断片をそのまま表示する show_widget ツールを利用できます。このスキルでは、適切に使うためのデザインシステム、テンプレート、パターンを提供します。
Codex やその他のホストの場合:まず、利用可能なツールを確認してください。ホストにドキュメント化された可視化インターフェースが用意されている場合はそれを使用し、ない場合は完全な HTML ドキュメントをワークスペースに保存して、クリック可能なファイルリンクを返してください。単独で出力する場合は、以下の断片のみというルールは適用されません。ドキュメントのラッパーとビューポートのメタデータを含め、テンプレートで使用する CSS 変数と SVG クラス(ダークモードの色を含む)を定義し、チャートの依存関係を明示的に読み込んでください。以下に記載されているホスト固有の CDN 許可リストと注入されるスタイルは、Claude のレンダラーについての説明であり、Codex の機能ではありません。ブリッジを利用できない場合は、チャットのフォローアップボタンと sendPrompt ハンドラーを削除してください。ローカルのスライダーと計算は引き続き機能するようにしてください。可能な場合は、保存した出力をブラウザーで確認してください。
ステップ 1:適切なビジュアル形式を選ぶ
名詞ではなく、動詞を基準に振り分けます。同じ題材でも、依頼された内容によってビジュアルは異なります。
| ユーザーの依頼 | 種類 | 形式 |
|---|---|---|
| 「X はどのように動作しますか」 | 説明図 | SVG |
| 「X のアーキテクチャ」 | 構造図 | SVG |
| 「手順は何ですか」 | フローチャート | SVG |
| 「複利について説明してください」 | インタラクティブな解説 | HTML |
| 「これらの選択肢を比較してください」 | 比較グリッド | HTML |
| 「売上のグラフを表示してください」 | Chart.js のチャート | HTML |
| 「連絡先カードを作成してください」 | データレコード | HTML |
| 「夕日を描いてください」 | アート/イラスト | SVG |
ステップ 2:ウィジェットを作成する
構造(順序厳守)
<style> → HTML content → <script>
出力はトークンごとにストリーミングされます。スタイルは対象の要素より前に記述し、スクリプトは DOM の準備が整ってから実行してください。
基本方針
- シームレス:ホスト UI の終わりとウィジェットの始まりをユーザーに意識させないようにします
- フラット:グラデーション、メッシュ背景、ノイズテクスチャ、装飾効果は使用しません。すっきりとしたフラットな面にします
- コンパクト:重要な情報はインラインで表示し、残りはテキストで説明します
- ありきたりな「AI デザイン」の初期設定は避ける:クリーム色やオフホワイトのパネル、見出し内の斜体のアクセント語、「01 / 02 / 03」の番号付きセクションラベル、コード以外での等幅フォントのラベル、ピル型ボタンは避けます。汎用的に見え、ホスト UI と調和しないためです
- テキストは応答に、ビジュアルはツールに — 説明文、記述、要約は通常の応答テキストとしてツール呼び出しの外に書き、ウィジェットにはビジュアル要素だけを含めます
基本ルール
- `` または
/* comments */は使用しないでください(トークンを浪費し、ストリーミングを妨げます) - 11px 未満のフォントサイズは使用しないでください
- 絵文字は使用せず、CSS の図形または SVG パスを使用してください
- グラデーション、ドロップシャドウ、ぼかし、グロー、ネオン効果は使用しないでください
- 外側のコンテナに暗色や色付きの背景を設定しないでください(透明のみ。背景色はホストが指定します)
- タイポグラフィ:使用できるウェイトは 400(レギュラー)と 500(ミディアム)の 2 種類のみです。600 と 700 は使用しないでください。見出しは h1=22px、h2=18px、h3=16px とし、すべて font-weight 500 にします。本文は 16px、ウェイト 400、line-height 1.7 にします
- 常に文頭のみ大文字にしてください。タイトルケースやすべて大文字の表記は使用しないでください
- 文中で太字にしないでください。エンティティ名は 太字 ではなく
コードスタイルで表記してください <!DOCTYPE>、<html>、<head>、<body>は使用せず、コンテンツの断片だけを記述してくださいposition: fixedは使用せず、通常のフローに沿ったレイアウトを使用してください- ストリーミング中にタブ、カルーセル、
display: noneのセクションを使用しないでください - 入れ子のスクロールは使用せず、高さを自動調整してください
- 角の丸み:カードには
border-radius: var(--border-radius-lg)、要素にはvar(--border-radius-md)を使用してください - 片側だけの境界線(border-left、border-top)に角の丸みを設定しないでください
- 表示する数値はすべて丸めてください。
Math.round()、.toFixed(n)、またはIntl.NumberFormatを使用してください
CDN の許可リスト(CSP による適用)
外部リソースの読み込みは、次のドメインからのみ許可されています。
cdnjs.cloudflare.comcdn.jsdelivr.netunpkg.comesm.sh
それ以外のオリジンはすべてブロックされ、リクエストはエラーを表示せずに失敗します。
CSS 変数
背景:--color-background-primary(白)、-secondary(サーフェス)、-tertiary(ページ背景)、-info、-danger、-success、-warning
テキスト:--color-text-primary(黒)、-secondary(控えめな色)、-tertiary(ヒント)、-info、-danger、-success、-warning
境界線:--color-border-tertiary(0.15α、デフォルト)、-secondary(0.3α、ホバー時)、-primary(0.4α)、セマンティックカラーの -info/-danger/-success/-warning
タイポグラフィ:--font-sans、--font-serif、--font-mono
レイアウト:--border-radius-md(8px)、--border-radius-lg(12px)、--border-radius-xl(16px)
すべてライトモードとダークモードに自動で適応します。
ダークモードへの対応は必須です。すべての色が両方のモードで機能する必要があります。
- HTML では、テキストに常に CSS 変数を使用してください。
color: #333のように色を直接指定しないでください - SVG では、あらかじめ定義された色クラス(
c-blue、c-tealなど)を使用してください。ライトモードとダークモードに自動で対応します - 確認方法:背景がほぼ黒の場合でも、すべてのテキスト要素が読みやすいか確認してください
sendPrompt(text)
ユーザーが入力したかのように、チャットにメッセージを送信するグローバル関数です。ユーザーの次のステップで Claude の思考が役立つ場合に使用してください。フィルタリング、並べ替え、切り替え、計算は、代わりに JavaScript で処理してください。
ステップ 3:利用可能なホストでレンダリングする
ホストで show_widget が利用できる場合は、以下のようにウィジェットコードを直接渡してください。Codex でこのツールを利用できない場合は、上記のスタンドアロン HTML の方法に従い、show_widget の呼び出しを作り出さないでください。
{
"title": "snake_case_widget_name",
"widget_code": "<style>...</style>\n<div>...</div>\n<script>...</script>"
}
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
title | string | はい | ウィジェットの snake_case 識別子 |
widget_code | string | はい | HTML または SVG コード。SVG の場合は <svg> で始めます。HTML の場合はコンテンツの断片です |
SVG を出力する場合は、widget_code を <svg で始めてください。自動的に検出され、適切にラップされます。
ステップ 4:Chart.js のテンプレート
チャートでは、スクリプトの読み込み順序に対応するため、onload コールバックのパターンを使用してください。
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;">
<div style="background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 1rem;">
<div style="font-size: 13px; color: var(--color-text-secondary);">Label</div>
<div style="font-size: 24px; font-weight: 500;" id="stat1">—</div>
</div>
</div>
<div style="position: relative; width: 100%; height: 300px; margin-top: 1rem;">
<canvas id="myChart"></canvas>
</div>
<div style="display: flex; align-items: center; gap: 12px; margin-top: 1rem;">
<label style="font-size: 14px; color: var(--color-text-secondary);">Parameter</label>
<input type="range" min="0" max="100" value="50" id="param" step="1" style="flex: 1;" />
<span style="font-size: 14px; font-weight: 500; min-width: 32px;" id="param-out">50</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.js" onload="initChart()"></script>
<script>
function initChart() {
const slider = document.getElementById('param');
const out = document.getElementById('param-out');
let chart = null;
function update() {
const val = parseFloat(slider.value);
out.textContent = val;
document.getElementById('stat1').textContent = val.toFixed(1);
const labels = [], data = [];
for (let x = 0; x <= 100; x++) {
labels.push(x);
data.push(x * val / 100);
}
if (chart) chart.destroy();
chart = new Chart(document.getElementById('myChart'), {
type: 'line',
data: { labels, datasets: [{ data, borderColor: '#7F77DD', borderWidth: 2, pointRadius: 0, fill: false }] },
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: { x: { grid: { display: false } } }
}
});
}
slider.addEventListener('input', update);
update();
}
if (window.Chart) initChart();
</script>
Chart.js のルール:
- Canvas では CSS 変数を解決できないため、16 進数の色を直接指定してください
- 高さを設定するのはラッパーの div のみとし、canvas 自体には設定しないでください
- 常に
responsive: true, maintainAspectRatio: falseを指定してください - デフォルトの凡例は常に無効にし、HTML で独自の凡例を作成してください
- 数値の表記:
$-5Mではなく-$5M(通貨記号の前に負号を付けます) - CDN の script タグでは
onload="initChart()"を使用し、フォールバックとしてif (window.Chart) initChart();を指定してください
ステップ 5:SVG 図のテンプレート
フローチャートや図には、あらかじめ定義されたクラスを使った SVG を使用します。
<svg width="100%" viewBox="0 0 680 H">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<g class="node c-blue" onclick="sendPrompt('Tell me more about this')">
<rect x="250" y="40" width="180" height="44" rx="8" stroke-width="0.5"/>
<text class="th" x="340" y="62" text-anchor="middle" dominant-baseline="central">Step one</text>
</g>
<line x1="340" y1="84" x2="340" y2="120" class="arr" marker-end="url(#arrow)"/>
<g class="node c-teal" onclick="sendPrompt('Explain this step')">
<rect x="230" y="120" width="220" height="56" rx="8" stroke-width="0.5"/>
<text class="th" x="340" y="140" text-anchor="middle" dominant-baseline="central">Step two</text>
<text class="ts" x="340" y="158" text-anchor="middle" dominant-baseline="central">Processes the input</text>
</g>
</svg>
SVG のルール:
- viewBox の幅は常に 680px にします(
viewBox="0 0 680 H")。コンテンツに上下 40px の余白を加えた高さに H を設定します。 - セーフエリア:x=40〜x=640、y=40〜y=(H-40)
- あらかじめ定義されたクラス:
t(14px)、ts(12px、補助テキスト)、th(14px、中太字 500)、box、node、arr、c-{color} - すべての
<text>要素にクラス(t、ts、th)を指定します。 - ボックス内でテキストを垂直方向に中央揃えするには、
dominant-baseline="central"を使用します。 - コネクタのパスには
fill="none"を指定します(SVG のデフォルトはfill: blackです)。 - 線の幅:境界線とエッジは 0.5px
- すべてのノードをクリック可能にします:
onclick="sendPrompt('...')"
ステップ 6:インタラクティブな解説テンプレート
インタラクティブな解説(スライダー、リアルタイム計算、インライン SVG)には、次のテンプレートを使用します。
<div style="display: flex; align-items: center; gap: 12px; margin: 0 0 1.5rem;">
<label style="font-size: 14px; color: var(--color-text-secondary);">Years</label>
<input type="range" min="1" max="40" value="20" id="years" style="flex: 1;" />
<span style="font-size: 14px; font-weight: 500; min-width: 24px;" id="years-out">20</span>
</div>
<div style="display: flex; align-items: baseline; gap: 8px; margin: 0 0 1.5rem;">
<span style="font-size: 14px; color: var(--color-text-secondary);">$1,000 →</span>
<span style="font-size: 24px; font-weight: 500;" id="result">$3,870</span>
</div>
<div style="margin: 2rem 0; position: relative; height: 240px;">
<canvas id="chart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.js" onload="initChart()"></script>
<script>
function initChart() {
// slider logic, chart rendering, sendPrompt() for follow-ups
}
if (window.Chart) initChart();
</script>
sendPrompt() を使うと、ユーザーが追加の質問をできます:sendPrompt('What if I increase the rate to 10%?')
ステップ 7:ユーザーに応答する
ウィジェットを表示した後、次の点を簡潔に説明します。
- ウィジェットが何を示しているか
- 操作方法(各コントロールの機能)
- データから得られる重要な洞察を 1 つ
簡潔にまとめます。ウィジェット自体が多くを伝えてくれます。
参考ファイル
references/design_system.md— 9 段階の色調 × 7 段階からなる完全なカラーパレット、CSS 変数、UI コンポーネントのパターン、メトリックカード、レイアウトのルールreferences/svg_and_diagrams.md— SVG の viewBox 設定、フォントの調整、あらかじめ定義されたクラス、フローチャート/構造図/説明図のパターンと例references/chart_js.md— Chart.js の設定、スクリプトの読み込み順、キャンバスのサイズ設定、凡例のパターン、ダッシュボードのレイアウト
デザインのトークン、SVG の座標計算、または Chart.js の設定について詳しく確認する必要がある場合は、関連する参考ファイルを読みます。