mcpField
U
ui-package

ui-package

github.com/verygoodopensource開発17564 回インストール今日更新
リポジトリ

ui-package について

再利用可能な UI パッケージを作る Flutter 開発者向けガイドです。Material ウィジェット、`ThemeExtension` のデザイントークン、一貫したウィジェット API を軸に構成します。パッケージ構造、公開 API、ウィジェットテスト、Widgetbook カタログも扱います。

主な機能

  1. 01Material ウィジェットによる UI 構成
  2. 02`ThemeExtension` によるテーマトークンの拡張
  3. 03単一のバレルファイルで公開 API を提供
  4. 04各ウィジェットの振る舞いテスト
  5. 05`pumpApp` と Widgetbook のスキャフォールド

活用シーン

  1. 01再利用可能な Flutter UI パッケージの作成
  2. 02間隔やカスタムカラーのトークン定義
  3. 03Material に基づく共有コンポーネントの実装
  4. 04ウィジェット操作のテストとカタログ整理

MCP 対応

UI パッケージのスキャフォールドには、`subcommand` を `app_ui_package` に設定した Very Good CLI MCP の `create` ツールを使うよう定めています。

インストール

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

$npx skills add https://github.com/verygoodopensource/vgv-ai-flutter-plugin --skill ui-package

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

同梱ファイルagents/openai.yamlreference.md

詳細

UI パッケージ

package:flutter/material.dart を基盤とする再利用可能なウィジェットライブラリ、Flutter UI パッケージを作成するためのベストプラクティスです。アプリ固有のコンポーネント、ThemeExtension によるカスタムデザイントークン、一貫した API サーフェスで拡張します。

テーマ設定の基盤: このスキルでは、UI パッケージの構成、ウィジェット API、テストに焦点を当てます。Material 3 の基本的なテーマ設定(ColorScheme、TextTheme、コンポーネントテーマ、スペーシング定数、ライト/ダークモード)については、Material Theming スキル(/material-theming)を参照してください。2 つのスキルは相互に補完するものです。Material Theming では ThemeData の設定方法と使い方を扱い、このスキルでは ThemeExtension トークンを使って拡張し、その周りに再利用可能なウィジェットをパッケージ化する方法を扱います。

基本標準

UI パッケージに関するすべての作業で、次の標準を適用してください。

  • app_ui_package テンプレートから作成する — Very Good CLI MCP ツールの subcommand: 'app_ui_package' を使ってパッケージを作成します。flutter_package、dart_package、flutter create --template=package は使用しないでください。これらでは、以下に示すテーマ、バレル、テストヘルパー、Widgetbook のスキャフォールディングがない、最小限のパッケージが生成されます
  • Material を基盤にする — flutter/material.dart に依存し、Material ウィジェットを組み合わせます。Material がすでに提供しているプリミティブを作り直さないでください
  • 1 ファイルにつき 1 ウィジェット — 各パブリックウィジェットは、ウィジェット名に基づくスネークケースのファイル名(例:app_button.dart)で、独立したファイルに配置します
  • パブリック API 用のバレルファイル — すべてのパブリックウィジェットとテーマクラスを、単一のバレルファイル(例:lib/my_ui.dart)から公開します。このファイルでは material.dart も再エクスポートするため、1 つのインポートで Material のウィジェットとパッケージ独自のウィジェットの両方を利用でき、Material を別途インポートする必要がありません
  • lib/src/ はプライベート — 利用側はバレルのみをインポートし、それ以外はインポートしません。package:my_ui/src/widgets/app_button.dart のようにファイル単位でインポートすると、プライベートな実装にアクセスすることになり、内部の名前変更で壊れます。ツリーシェイキングによって未使用のウィジェットはすでに除外されるため、バレルによるコストはありません
  • ThemeExtension でテーマを拡張する — Material の ThemeData、ColorScheme、TextTheme を基盤として使います(Material Theming スキルを参照)。アプリ固有のトークン(スペーシング、カスタムカラー)は ThemeExtension<T> で追加し、それぞれを ThemeData.extensions に登録して、BuildContext 拡張(context.appColors、context.appSpacing)から読み取ります
  • すべてのウィジェットに対応するウィジェットテストを用意する — 動作テストでインタラクション、コールバック、状態の変化を検証します。インラインの MaterialApp ではなく、パッケージの pumpApp ヘルパーを使ってポンプします
  • アンチパターンには動作するコードで対応する — アンチパターンの表にある内容を求められた場合は、なぜ誤りなのかを説明し、同じ回答内で修正版の実装を提示します。異議を述べるだけで終わらせたり、ドキュメントに記載された方法で進めてよいか尋ねたりしないでください
  • すべてのパブリッククラスにプレフィックスを付ける — Material ウィジェットとの名前の衝突を避けるため、一貫したプレフィックス(例:App、Vg)を使います
  • 可能な限りすべてのコンストラクターを const にする — 可能な場合、すべてのウィジェットコンストラクターを const にします
  • すべてのパブリックメンバーをドキュメント化する — すべてのパブリッククラス、コンストラクターパラメーター、メソッドに dartdoc コメントを付けます

パッケージ構成

my_ui/
├── lib/
│   ├── my_ui.dart              # Barrel file — re-exports material.dart + all public API
│   └── src/
│       ├── theme/
│       │   ├── app_theme.dart        # AppTheme class with light/dark ThemeData builders
│       │   ├── app_colors.dart       # AppColors ThemeExtension for custom color tokens
│       │   ├── app_spacing.dart      # AppSpacing ThemeExtension for spacing tokens
│       │   └── app_text_styles.dart  # Optional: extra text styles beyond Material's TextTheme
│       ├── widgets/
│       │   ├── app_button.dart
│       │   ├── app_text_field.dart
│       │   ├── app_card.dart
│       │   └── ...
│       └── extensions/
│           └── build_context_extensions.dart  # context.appColors, context.appSpacing shortcuts
├── test/
│   ├── src/
│   │   ├── theme/
│   │   │   └── app_theme_test.dart
│   │   └── widgets/
│   │       ├── app_button_test.dart
│   │       └── ...
│   └── helpers/
│       └── pump_app.dart         # Test helper wrapping widgets in MaterialApp + theme
├── widgetbook/                   # Widgetbook catalog submodule (sandbox + showcase)
│   └── ...
└── pubspec.yaml

ウィジェットの作成

ウィジェット API のガイドライン
  • Material ウィジェットを組み合わせる — FilledButton、OutlinedButton、TextField、Card などを構成要素として使います
  • 必要最小限のパラメーターのみを受け付ける — 「何でも入り」のコンストラクターは避けます
  • key と child/children 以外はすべて名前付きパラメーターにします
  • パラメーターが指定されていない場合は、テーマに基づく適切なデフォルト値を設定します
  • コールバックには ValueChanged<T> または VoidCallback を公開します — 生の Function は使わないでください
  • スロットベースの任意の構成(先行アイコン、後続アイコンなど)には Widget? を使います

アンチパターン

アンチパターン正しいアプローチ
Material にすでに用意されているウィジェットを再構築する(例:GestureDetector と DecoratedBox を使ったカスタムボタン)Material ウィジェット(FilledButton、OutlinedButton)を組み合わせてスタイルを設定する
カスタムの InheritedWidget で独自のテーマシステムを作成するMaterial の ThemeData をベースとして使い、カスタムトークンには ThemeExtension を使う
ウィジェットのコードに Color(0xFF...) をハードコードする標準色には Theme.of(context).colorScheme を、カスタムトークンには context.appColors を使う
カスタムクラスで Material の ColorScheme の役割を重複して定義するMaterial でカバーされない値(例:成功、警告、情報)にのみ ThemeExtension トークンを作成する
コールバックの型に dynamic または Object を使うVoidCallback、ValueChanged<T>、または具体的な関数の型定義を使う
内部実装ファイルを直接公開するバレルファイルを使い、src/ 以下のすべてのファイルを非公開にする

パッケージの作成

Very Good CLI MCP の create ツールを使ってひな形を作成します。

パラメーター値
subcommandapp_ui_package — すべての UI パッケージで必ず指定します
nameパッケージ名を snake_case で指定します(例:storefront_ui)
output_directory共有パッケージを格納するモノレポのディレクトリ(例:packages/)

app_ui_package は、lib/src/theme の拡張機能、バレルファイル、pumpApp ヘルパー、Widgetbook カタログを含むテンプレートです。flutter_package は、手作業で再構築するための空のパッケージです。

異なるハーネス環境での代替手段。 このプラグインの Bash フックがなく、Very Good CLI MCP サーバーにも接続されていないホストでは、同等の very_good create app_ui_package <package_name> --output-directory <dir> コマンドを直接実行してください。

ThemeExtension クラスの一覧(AppColors、AppSpacing、AppTheme、BuildContext 拡張機能)、pumpApp テストヘルパー、バレルファイルの例、Widgetbook カタログの概念と build_runner コマンド、ウィジェットまたはカスタムトークンを追加する手順については、reference.md を参照してください。

コメント