mcpField
W
wireframe-generator

wireframe-generator

github.com/wire-dslデザイン・UI1848 回インストール31 週間前に更新
リポジトリ

wireframe-generator について

wireframe-generatorは、ワイヤーフレームやインタラクティブなUIプロトタイプ向けに、LLMへWire DSLの構文とコンポーネント情報を提供するスキルです。レイアウト、イベント、検証規則を扱い、UI要件から完全な.wireファイルを生成できます。

主な機能

  1. 01Wire DSLの構文と文法
  2. 0230種類のコンポーネント一覧
  3. 03レイアウトコンテナのパターン
  4. 04イベントとアクションの規則
  5. 05コード生成の検証チェックリスト

活用シーン

  1. 01ワイヤーフレームの.wireファイル生成
  2. 02UI要件からDSLコードへの変換
  3. 03クリック操作を含むフローの作成
  4. 04複数画面のフォームやダッシュボード構築

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wire-dsl/wire-dsl --skill wireframe-generator

インストール後、Claude Code で/wireframe-generatorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
best-practices.md
common-patterns.md
components-catalog.md
core-syntax.md
layouts-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ダッシュボード、製品グリッド、レスポンシブレイアウト
split2 列領域ちょうど 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、Radio
  • onItemsClick:SidebarMenu
  • onItemClick:List
  • onRowClick:Table
  • onClose: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 コードを生成する際は、次の点に従ってください。

  1. 出力前に必ず構文を検証してください
  2. 不完全なスニペットではなく、完全で実行可能な .wire ファイルを返してください
  3. 現実的な名前とデータを使用してください
  4. コンポーネント名とプロパティ名は正確に維持してください
  5. レイアウトの間隔(gap、padding)を明示的に指定してください
  6. インタラクティブなフローでは、ID とイベントを一貫して接続してください
  7. コメントは、分かりにくい構造を明確にする場合にのみ使用してください

インタラクティブなサンプルスニペット

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)
      }
    }
  }
}

コメント