flutter-custom-design-system について
既存のカスタムデザインシステムを持つプロジェクトで、Flutter開発者が画面を構築するためのスキルです。デフォルトのMaterialスタイルや別のUIパッケージではなく、プロジェクトのトークン、テーマアクセサー、Pressableのパターンを再利用するようエージェントを導きます。
主な機能
- 01既存のデザインシステム規約の検出
- 02トークンの単一ソース管理
- 03ThemeExtensionによるトークンの適用
- 04プロジェクトのPressableへのタップ集約
- 05キー、アナライザー、画面表示の確認
活用シーン
- 01ブランド独自のFlutterアプリでの画面構築
- 02プロジェクトのトークン体系の拡張
- 03デフォルトのMaterialスタイル適用の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thesimpleapp/ flutter-app-skills --skill flutter-custom-design-systemインストール後、Claude Code で/flutter-custom-design-systemを入力して読み込まれたか確認します。
同梱ファイルreferences/pressable.mdreferences/tokens.md
詳細
Flutter カスタムデザインシステム
標準の Material/Cupertino のスキルセットを安易に使うのは適切ではありません。このリポジトリですでに色、書体、角丸、モーション、または押下可能なコンポーネントに名前が付いている場合は、その名前と値を使ってください。ユーザーからシステムを捨てるように求められていない限り、アプリのスタイルを FilledButton / NavigationBar / ColorScheme.fromSeed に寄せて変更しないでください。
関連スキル:flutter-native-ui — 実際に Material 3 または Cupertino の外観を求めるアプリに限って使います。
参考資料
references/
tokens.md ThemeExtension mount, context accessor, 1:1 rule
pressable.md Scale/sink press, NoSplash, focus ring, semantics
まずデザインシステムを確認する
ウィジェットを記述する前に、リポジトリを検索して次の項目を確認してください。
ThemeExtension<- 色やトークンを返す
extension <Name> on BuildContext *tokens*、*semantics*、*theme*、WIDGETS.md、DESIGN-SYSTEM.mdという名前のファイル*Pressableという名前のウィジェットNoSplash.splashFactory/splashFactory: NoSplash
次に、近くにある本番画面を開き、そのアクセサー(context.pt、St6Theme.of(context)、context.colors など)を使ってください。プロダクトコードでは、新しいアクセサーではなく、そのアクセサーを使う必要があります。
まだシステムがなく、ユーザーがシステムを求めている場合は、references/tokens.md と references/pressable.md にあるパターンを導入してください。トークンモジュールは1つ、拡張機能は1つ、押下可能なコンポーネントは1つにします。サードパーティの UI キットは追加しないでください。
厳守事項
トークン
- 値は1つのソース(Dart のトークンファイル、CSS/JSON から生成したもの、または承認済みの
tokens.dart)にまとめます。ウィジェットに生の16進カラー値、場当たり的な角丸、独自に決めた時間を記述してはいけません。 - 実行時には
ThemeData.extensionsのThemeExtension<T>と、単一のコンテキストアクセサーを使って適用します。拡張機能と並べて、無関係なウィジェットからFooColorsクラスをインポートしてはいけません。 - システムファイルと1対1で対応させます。引き継ぎ資料に
#C9A24Bとある場合、トークンも#C9A24Bにします。コントラストを「改善」したり、ライトテーマを考案したり、システムにない役割を追加したりしてはいけません。 - 役割が不足している場合は、トークンソースと拡張機能の両方に追加するか、確認してください。近道としてウィジェットに
#hexを直接記述してはいけません。 - ダークモードを使うのは、システムに含まれている場合だけです。ダークパレットを考案してはいけません。
外観
- アプリが Flutter Material のデフォルトだと、ひと目でわかってしまうような見た目にしてはいけません。システムで指定されている場合を除き、インクリップル、M3 のプライマリコンテナのピル、標準の
NavigationBarインジケーターを使ってはいけません。 - すべてのタップは、アプリ共通の
Pressableを経由させます(リポジトリになければ作成してください)。押下時は、縮小および/または沈み込みの動きを付けます。テーマとPressableの両方でsplashFactory: NoSplash.splashFactoryと透明なオーバーレイを設定します。 - 「アクセシビリティを手軽に得る」ために、ブランド独自のコントロールを
FilledButton/ElevatedButton/InkWellで囲み、後からスプラッシュに対処することは避けてください。セマンティクスはPressableに設定します。 - Material の動作(フォーカス、メディアクエリ、テキストスケーラー、
Shortcuts)は使っても、Material の外観は使いません。
書体と余白
- 書体の役割はシステム(または拡張機能のテキストスタイル)に従います。システムが
TextThemeに対応付けていない限り、TextTheme.of(context).titleLargeを使ってはいけません。 - 余白、角丸、モーションにはトークンの値(
space200、radiusControl、durationPress)を使います。EdgeInsets.all(13)やDuration(milliseconds: 180)のような値を呼び出し側で独自に考案してはいけません。
キーとデバッグ
- インタラクティブなコントロールには
const ValueKey<String>('kebab-name')を使い、テストからfind.byKeyで検索できるようにします。 - 神モード、ギャラリー、事前入力、ジャンプチップは
kDebugModeでのみ有効にし、実際の認証/セッション経路を通します。本番リリースで使える抜け道を作ってはいけません。
禁止事項
- システムにフォントがすでに含まれている場合は、
google_fontsを追加しないでください。ゴールデンテストが重要な場合は、FontLoaderでそのフォントを読み込みます。Roboto のゴールデンテストはプロダクトそのものではありません。 flutter_screenutil、GetX、または2つ目のデザインパッケージを追加しないでください。- ブランド独自のサーフェスに、標準の M3 コンポーネントを「今回だけ」と混在させないでください。
画面を構築する
- トークンファイル、拡張機能、押下可能ウィジェット、既存の画面を1つ確認します。
- 新しい
AppBarとNavigationBarを組み合わせるのではなく、プロジェクトのシェル(カスタムのアプリバー/タブバー)を使って足場を作ります。 - 色、文字、余白、角丸、アニメーションには、拡張機能/トークンだけを使います。
- タップ操作には標準の押下可能ウィジェットを使います。アイコンにはシステムのアイコンセットを使い、システムで採用されていない限り
Icons.favoriteは使いません。 - セーフエリアとキーボードには、コンテンツに
SafeAreaを使い、MediaQuery.sizeOf/viewInsetsOf/textScalerOfを使用します。システムで定義されている場合はウィンドウ幅のブレークポイントを使い、定義されていない場合は既存のシェルのルールに従います。 - プロジェクトのアナライザーと、実行中の画面で検証します。
Material のデフォルト設定を使わない場合
システムのウィジェット一覧に記載されていない場合、ブランドを表す画面では次のものを使わないでください。
FilledButton、NavigationBar、NavigationRail、NavigationDrawer、SnackBar(システムにトーストがある場合)、FloatingActionButton、Chip、エレベーションの色合いを適用した Material、デフォルトのスプラッシュ効果を持つ InkWell。
OS 標準の操作要素で、画面の装飾にあたらないものについては、システムで代替要素が指定されていない場合に .adaptive()(Switch.adaptive、Checkbox.adaptive)を使ってもかまいません。
検証する
- 変更したファイルを
grepで検索し、Color(0x/Color.from/#がないか確認します。該当箇所はウィジェットではなく、トークンファイルに記述します。 - 新しいタップ対象には、すべて標準の押下可能ウィジェットを使います。
- アナライザーの警告がないことを確認します。ホットリロードし、実行中の画面を Material 3 のギャラリーの記憶ではなく、近くにあるブランド画面と照らし合わせて確認します。
- ウィジェットテストでは、キーがある場合は表示テキストではなく
find.byKeyを使います。