wireframe-generator について
wireframe-generatorは、ワイヤーフレームやインタラクティブなUIプロトタイプ向けに、LLMへWire DSLの構文とコンポーネント情報を提供するスキルです。レイアウト、イベント、検証規則を扱い、UI要件から完全な.wireファイルを生成できます。
主な機能
- 01Wire DSLの構文と文法
- 0230種類のコンポーネント一覧
- 03レイアウトコンテナのパターン
- 04イベントとアクションの規則
- 05コード生成の検証チェックリスト
活用シーン
- 01ワイヤーフレームの.wireファイル生成
- 02UI要件からDSLコードへの変換
- 03クリック操作を含むフローの作成
- 04複数画面のフォームやダッシュボード構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wire-dsl/ wire-dsl --skill wireframe-generatorインストール後、Claude Code で/wireframe-generatorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/best-practices.mdcommon-patterns.mdcomponents-catalog.mdcore-syntax.mdlayouts-guide.md詳細
Wire DSL コードジェネレーター
ワイヤーフレームやインタラクティブな UI プロトタイプ向けに、構文的に正しい Wire DSL コードを生成します。
このスキルでできること
このスキルを使うと、以下の情報に基づいて、LLM が有効かつ最新の Wire DSL を生成できます。
- 完全な構文リファレンスと文法規則
- 利用可能な全 30 コンポーネントのカタログ
- レイアウトコンテナーのパターン(stack、grid、split、panel、card、tabs、modal)
- コード生成のベストプラクティス
- プレイテストで使用するイベントとインタラクティブ性のルール
ブランチに同期した変更
このスキルは feature/add-event-system の変更に対応して更新されており、以下が含まれます。
- コンポーネントとレイアウトのイベントハンドラーを備えたイベントシステム
- 新しいアクション:
enable(id)とdisable(id)(およびnavigate、show、hide、toggle、setTab) - 新しいレイアウト:
layout tabs(...)とlayout modal(...) component Modalをlayout modal(...)に置き換えcomponent TabsがinitialActiveとtabsIdに対応layout card(...)がonClickに対応Checkbox、Radio、Toggleが、インタラクティブではない表示用のclickable: falseに対応
このスキルを使用する場面
以下が必要な場合に、このスキルを使用してください。
- ワイヤーフレームのプロトタイプ用に
.wireファイルを生成する - 宣言的な構文を使って UI モックアップを作成する
- プレイテストのフローにクリック可能なインタラクションを追加する
- 複数画面のアプリケーションのワイヤーフレームを作成する
- フォーム、ダッシュボード、製品カタログ、管理インターフェースを設計する
- UI 要件を Wire DSL コードに変換する
基本概念
構造: すべての Wire DSL ファイルは、次の階層に従います。
project -> [style|colors|mocks|define] -> screen -> layout -> children
構文スタイル: CSS/HCL に似た、波括弧を使うブロック宣言型です。
project "App Name" {
style { ... } // optional
screen ScreenName {
layout <type> { ... }
}
}
主なルール:
- 文字列値は必ず引用符で囲みます:
text: "Hello" - 数値、ブール値、列挙値は引用符で囲みません:
height: 200、checked: true、variant: primary - プロパティの形式:
key: value - コメント:行コメントには
//、ブロックコメントには/* */を使用します
コード生成の手順
ステップ 1:プロジェクト構造から始める
プロジェクトのラッパーから始めます。style ブロックは省略可能です。省略した場合は、デフォルト値(density: "normal"、spacing: "md"、radius: "md"、stroke: "normal"、font: "base")が適用されます。
project "Project Name" {
style {
density: "compact" // compact | normal | comfortable
radius: "lg" // none | sm | md | lg | full
}
// screens go here
}
ステップ 2:画面を作成する
各画面は、アプリケーション内の固有のビューを表します。
screen ScreenName {
layout <type> {
// content
}
}
命名: 画面名には CamelCase を使用します(例:UsersList、ProductDetail、Dashboard)。
ステップ 3:レイアウトコンテナーを選択する
UI の構造に応じて、適切なレイアウトを選択します。
| レイアウト | 用途 | 子要素 | 例 |
|---|---|---|---|
| stack | 線形配置 | 複数 | フォーム、リスト、垂直/水平セクション |
| grid | 複数列(12 列) | cells | ダッシュボード、製品グリッド、レスポンシブレイアウト |
| split | 2 列領域 | ちょうど 2 つ | 管理パネル、ナビゲーション+コンテンツ |
| panel | 枠線付きコンテナー | ちょうど 1 つ | 強調表示されたセクション、フォームグループ |
| card | コンテンツカード | 複数 | 製品カード、ユーザープロフィール、情報ボックス |
| tabs | タブ付きコンテンツパネル | tab ブロック | 設定ページ、プロフィールタブ、ステップフロー |
| modal | オーバーレイダイアログ | 複数(または body / footer) | 確認ダイアログ、フォームダイアログ |
ステップ 4:コンポーネントを追加する
8 つのカテゴリーに分類された、利用可能な 30 個のコンポーネントから選択します。
テキスト: Heading、Text、Label、Paragraph、Code
入力: Input、Textarea、Select、Checkbox、Radio、Toggle
アクション: Button、IconButton、Link
ナビゲーション: Topbar、SidebarMenu、Sidebar、Breadcrumbs、Tabs
データ: Table、List、Stat、Chart
メディア: Image、Icon
レイアウト: Card、Divider、Separate
フィードバック: Badge、Alert
ステップ 5:イベントとアクションを追加する(必要な場合)
イベントは、プレイテストでのインタラクションに関するメタデータです。
サポートされているイベントプロパティ:
onClick:Button、IconButton、Link、layout card(...)onChangeまたはonActive+onInactive:Toggle、Checkbox、RadioonItemsClick:SidebarMenuonItemClick:ListonRowClick:TableonClose:layout modal(...)
サポートされているアクション:
navigate(ScreenName)show(id)/hide(id)/toggle(id)enable(id)/disable(id)setTab(tabsId, index)- 自身を対象にする場合は
selfを使用します:hide(self)、show(self)、toggle(self)、enable(self)、disable(self)
アクションの連鎖:
component Button text: "Delete"
onClick: hide(listModal) & show(confirmModal) & disable(submitBtn)
ステップ 6:出力前に検証する
出力する前に、次の点を確認してください。
- すべての文字列が引用符で囲まれている
- 数値/ブール値/列挙値が引用符で囲まれていない
- すべての波括弧が閉じられている
- 必須プロパティが指定されている
- コンポーネント名が完全に一致している(大文字と小文字を区別)
- Split の子要素が 2 つ、Panel の子要素が 1 つである
- Grid のセルに有効な
span値(1-12)が指定されている tabsIdが同じ画面内にある既存のlayout tabs(id: ...)を参照しているshow/hide/toggle/enable/disableの対象が同じ画面に存在する(またはselfを使用している)onChangeがonActive/onInactiveと併用されていないlayout modal(...)でbody/footerセクションと直接の子要素を混在させていない
参照ファイル
| ファイル | 用途 |
|---|---|
| ../../docs/DSL-SYNTAX.md | 現行の言語構文とイベントのルール |
| ../../docs/COMPONENTS-REFERENCE.md | 現行のコンポーネントプロパティとイベントのサポート状況 |
| ../../docs/CONTAINERS-REFERENCE.md | 現行のレイアウト/コンテナのルール(tabs、modal、card onClick) |
| ../../specs/VALIDATION-RULES.md | イベント、モーダル、セマンティック検証のルール |
| core-syntax.md | スキル内の構文概要 |
| components-catalog.md | スキル内のコンポーネントカタログ |
| layouts-guide.md | スキル内のレイアウトガイド |
| best-practices.md | 検証チェックリスト、よくある間違い、注意点 |
| common-patterns.md | フォーム、ダッシュボード、ナビゲーション、カードで再利用できるパターン |
例
例 1:インタラクティブなモーダル + 有効化/無効化
project "Confirm Action" {
style {
density: "normal"
spacing: "md"
radius: "md"
stroke: "normal"
font: "base"
}
screen Main {
layout stack(direction: vertical, gap: md, padding: lg) {
component Input id: reasonInput label: "Reason" disabled: true
component Checkbox label: "I understand the consequences"
onActive: enable(reasonInput) & enable(deleteBtn)
onInactive: disable(reasonInput) & disable(deleteBtn)
component Button id: deleteBtn text: "Delete Item" variant: danger disabled: true
onClick: show(confirmDelete)
layout modal(id: confirmDelete, title: "Delete item?", visible: false, onClose: hide(self)) {
body {
component Text text: "This action cannot be undone."
}
footer {
component Button text: "Cancel" variant: secondary onClick: hide(self)
component Button text: "Confirm Delete" variant: danger onClick: hide(self)
}
}
}
}
}
例 2:Tabs を Tabs レイアウトにリンクする
project "Profile Settings" {
style {
density: "normal"
spacing: "md"
radius: "md"
stroke: "normal"
font: "base"
}
screen Settings {
layout stack(direction: vertical, gap: md, padding: lg) {
component Tabs items: "Profile,Security,Billing" initialActive: 0 tabsId: settingsTabs
layout tabs(id: settingsTabs) {
tab {
component Heading text: "Profile"
component Input label: "Full name"
component Input label: "Email"
}
tab {
component Heading text: "Security"
component Toggle label: "Two-factor auth"
component Button text: "Go Billing" onClick: setTab(settingsTabs, 2)
}
tab {
component Heading text: "Billing"
component Table columns: "Date,Amount,Status" rows: 4
}
}
}
}
}
例 3:クリック可能なカード + サイドバーナビゲーション
project "Admin" {
style {
density: "normal"
spacing: "md"
radius: "md"
stroke: "normal"
font: "base"
}
define Component "MainMenu" {
layout stack(direction: vertical, gap: md, padding: md) {
component SidebarMenu items: "Dashboard,Users,Settings"
onItemsClick: "DashboardScreen,UsersScreen,SettingsScreen"
active: prop_active
}
}
screen DashboardScreen {
layout split(left: 260, gap: md) {
component MainMenu active: 0
layout grid(columns: 12, gap: md, padding: md) {
cell span: 6 {
layout card(padding: md, gap: md, onClick: navigate(UsersScreen)) {
component Heading text: "Users"
component Text text: "Open users section"
}
}
}
}
}
screen UsersScreen {
layout split(left: 260, gap: md) {
component MainMenu active: 1
layout stack(direction: vertical, gap: md, padding: lg) {
component Heading text: "Users"
}
}
}
screen SettingsScreen {
layout split(left: 260, gap: md) {
component MainMenu active: 2
layout stack(direction: vertical, gap: md, padding: lg) {
component Heading text: "Settings"
}
}
}
}
クイックヒント
パディングのデフォルト値: レイアウトのパディングはデフォルトで 0px です。padding を明示的に追加してください。
グリッドシステム: 12 列グリッドです。cell span は 1-12 にする必要があります。
ID: 有効な識別子を使用してください:[a-zA-Z_][a-zA-Z0-9_]*。
CSV リスト: カンマ区切りの文字列を引用符で囲んで使用してください:items: "Home,Users,Settings"。
Tabs のリンク: component Tabs tabsId: X は同じ画面内の layout tabs(id: X) と一致する必要があります。
モーダルモデル: component Modal ではなく、layout modal(...) を使用してください。
ブール値のコントロール: Checkbox、Radio、Toggle では、必要に応じて clickable: false を指定できます。
よくある間違いと回避方法
- 文字列を引用符で囲み忘れる:
text: Hello->text: "Hello" - 数値/列挙値を引用符で囲む:
rows: "8"->rows: 8 - コンポーネントの大文字と小文字が誤っている:
button->Button component Modalを使用する ->layout modal(...)を使用してくださいtabsIdと一致するlayout tabs(id: ...)がない- Tabs のデザイン時のデフォルト値として
activeを使用する ->initialActiveを優先してください - 同じコントロールで
onChangeとonActive/onInactiveを併用する show/hide/toggle/enable/disableで存在しない ID を参照する- Split の子要素が 3 つある -> 必ず 2 つにしてください
- Panel に複数の子要素がある -> 必ず 1 つにしてください
- 同じモーダル内でモーダルの
body/footerと直接の子要素を混在させる
出力ガイドライン
Wire DSL コードを生成する際は、次の点に従ってください。
- 出力前に必ず構文を検証してください
- 不完全なスニペットではなく、完全で実行可能な
.wireファイルを返してください - 現実的な名前とデータを使用してください
- コンポーネント名とプロパティ名は正確に維持してください
- レイアウトの間隔(
gap、padding)を明示的に指定してください - インタラクティブなフローでは、ID とイベントを一貫して接続してください
- コメントは、分かりにくい構造を明確にする場合にのみ使用してください
インタラクティブなサンプルスニペット
layout stack(direction: vertical, gap: md, padding: md) {
component Input id: nameInput label: "Name" disabled: true
component Button text: "Unlock" onClick: enable(nameInput)
component Button text: "Lock" onClick: disable(nameInput)
component Button text: "Open confirm" onClick: show(confirmModal)
layout modal(id: confirmModal, title: "Confirm?", visible: false, onClose: hide(confirmModal)) {
body {
layout stack(direction: vertical, padding: sm) {
component Text text: "Proceed?"
}
}
footer {
layout stack(direction: vertical, padding: sm) {
component Button text: "Close" onClick: hide(confirmModal)
}
}
}
}