mcpField
F
flutter-native-ui

flutter-native-ui

github.com/thesimpleappデザイン・UI043 回インストール10 週間前に更新
リポジトリ

flutter-native-ui について

flutter-native-ui は、現行の Flutter と Dart のドキュメントに基づいて UI を構築・確認するスキルです。既存のデザインシステムを維持しながら、適切なウィジェットやレイアウトを選べます。

主な機能

  1. 01公式ドキュメントに基づく UI 設計
  2. 02既存テーマとナビゲーションの維持
  3. 03Material と Cupertino のパターン案内
  4. 04レスポンシブなレイアウトとコントロール
  5. 05アナライザーと表示の検証

活用シーン

  1. 01既存 Flutter アプリへの画面追加
  2. 02アダプティブな操作部品とナビの選択
  3. 03空・読み込み・エラー状態の確認

インストール

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

$npx skills add https://github.com/thesimpleapp/flutter-app-skills --skill flutter-native-ui

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

同梱ファイル

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

references/
animations.md
controls.md
icons-and-media.md
layout.md
navigation.md
storage.md
theming.md
visual-effects.md

詳細

Flutter ネイティブ UI

UI の選択はすべて、React Native や Expo のパターンではなく、最新の Flutter と Dart のドキュメントに基づいてください。flutter --version を確認してください。公式情報源:docs.flutter.dev、api.flutter.dev、dart.dev、m3.material.io、および flutter.dev の pub.dev パッケージ。

プロジェクトにすでにデザインシステム、トークン、またはルーターがある場合は、それを拡張してください。2つ目のテーマやナビゲーターを独自に作らないでください。

ウィジェットが独自の ThemeExtension、ブランドトークンのファイル、または Material のインク効果ではなく *Pressable を使っている場合は、そこで作業を止めて flutter-custom-design-system に従ってください。そのアプリを標準の Material 3 に合わせて「修正」しないでください。

参照資料

必要なファイルだけを読んでください。

references/
  navigation.md      go_router, tabs, sheets, dialogs, transitions
  theming.md         ColorScheme, TextTheme, light/dark, Cupertino
  layout.md          SafeArea, MediaQuery.*Of, breakpoints, slivers
  controls.md        Adaptive constructors, buttons, fields, pickers
  animations.md      Implicit first, Hero, M3 motion, lists
  icons-and-media.md Icons.adaptive, images, camera, audio, video
  visual-effects.md  Elevation, blur, gradients
  storage.md         Preferences, secure storage, files, SQL

デザインシステム

アプリの外枠は1つに決め、統一してください。

製品ルート外枠
クロスプラットフォーム(デフォルト)MaterialApp / MaterialApp.routerMaterial 3 + .adaptive() コントロール
iOS 優先CupertinoApp / CupertinoApp.routerCupertino ウィジェット + HIG の間隔
既存アプリすでに使用しているもの方針を示すためにアプリ全体のスタイルを変更しないでください

Flutter はOS の動作(スクロール物理特性、戻るジェスチャー、テキスト編集、触覚フィードバック)を自動的に適応させます。タブバー、アプリバー、情報アーキテクチャは自動で切り替わりません。これらは明示的に選択する必要があります。プラットフォームへの適応を参照してください。

.adaptive() コンストラクターと Icons.adaptive を除き、同じ画面内で Material と Cupertino のウィジェットを混在させないでください。

Material 3 は Flutter 3.16 以降のデフォルトです。useMaterial3: false は決して設定しないでください。オプトイン設定であるかのように useMaterial3: true を渡すことも避けてください。

インポート(Flutter 3.47 以降)

Material と Cupertino は、独立した 1.0 パッケージとして提供されています:material_ui と cupertino_ui。SDK のコピーも 3.47 では引き続き動作しますが、2026年秋の stable で非推奨になる予定です。

  • 既存プロジェクト: ツリー内ですでに使われているインポート形式を維持してください。
  • 新規の 3.47 以降のアプリ、または移行を依頼された場合:
flutter pub add material_ui
# only if you build Cupertino chrome:
flutter pub add cupertino_ui
dart fix --apply --code=migrate_design_widgets

これにより、package:flutter/material.dart → package:material_ui/material_ui.dart と、package:flutter/cupertino.dart → package:cupertino_ui/cupertino_ui.dart が書き換えられます。

pubspec.yaml が更新されない場合は、flutter pub add material_ui(および cupertino_ui)を実行してから、もう一度 dart fix --apply を実行してください。

SDK ライブラリを引き続きインポートしているレガシーパッケージのウィジェットには、ブリッジが必要です。

MaterialApp(
  builder: (context, child) => MaterialUiCompatibilityBridge(child: child!),
)

ローカライズ:material_ui の GlobalMaterialLocalizations.delegates を localizationsDelegates に指定します(Cupertino と Widgets も含まれます)。移行後は flutter_localizations の GlobalMaterialLocalizations / GlobalCupertinoLocalizations を残さないでください。

画面の構築

  1. 既存のテーマ、ルーター、近くの画面を確認してください。それらの規約に合わせてください。
  2. 足場を選びます:Scaffold + AppBar / SliverAppBar(Material)、または CupertinoPageScaffold + CupertinoNavigationBar / CupertinoSliverNavigationBar(Cupertino)。
  3. ページタイトルはアプリバー/ナビゲーションバーに配置し、本文の先頭に独自の Text を置かないでください。
  4. コンテンツは本文の周囲に SafeArea を使ってインセットしてください。Scaffold 全体を囲まないでください(AppBar はすでにステータスバーの下まで描画されます)。入れ子の SafeArea は重複分が折りたたまれるため、MediaQuery.padding を自分で読み取ってパディングを追加しないでください。
  5. スクロール可能なページには CustomScrollView + スライバー、または ListView.builder を使います。フォームには、オーバーフローする装飾のない Column ではなく、ListView / CustomScrollView を使ってください。
  6. 色と文字スタイルは ColorScheme.of(context) と TextTheme.of(context) から取得してください。Colors.blue のような生の色や、個別に指定する fontSize: 13 は使わないでください。
  7. インタラクティブなコントロールには const ValueKey<String>('kebab-name') を設定してください。
  8. 編集後はホットリロードを行い、確認してください(「確認」を参照)。

厳守事項

テーマと色

  • ColorScheme.fromSeed で配色を構築します。theme + darkTheme + themeMode を組み合わせます。
  • ColorScheme.of(context) と TextTheme.of(context) を使ってトークンを読み取ります(Theme.of(context).colorScheme/.textTheme と同じです)。
  • M3 のロールを使います:primary/onPrimary、surface/onSurface、surfaceContainer*、outline、error。primarySwatch や accentColor は使いません。
  • Cupertino の色には CupertinoColors/CupertinoDynamicColor を使い、CupertinoDynamicColor.resolve(color, context) で解決します。

レイアウト

  • MediaQuery.sizeOf/paddingOf/viewInsetsOf/viewPaddingOf/textScalerOf/platformBrightnessOf/highContrastOf/accessibleNavigationOf を使います。MediaQuery.of(context).size は使いません(MediaQuery が変更されるたびに再ビルドされます)。
  • 間隔には Row/Column/Flex の spacing を使います。Wrap では spacing + runSpacing を使います。すべての子ウィジェットの間に SizedBox を追加しないでください。
  • デバイスの種類ではなく、ウィンドウサイズに基づいてレイアウトします。スマートフォンかタブレットかを判定するために Platform.isIOS を使わないでください。アプリのルートで OrientationBuilder を使わないでください。ブレークポイント:compact <600、medium 600–839、expanded ≥840(M3 のウィンドウサイズクラス)。
  • 画面の向きを固定しないでください。flutter_screenutil やデザインピクセル用のスケーラーを使わないでください。

ウィジェット(新規コード)

使用するもの使用しないもの
FilledButton、FilledButton.tonal、OutlinedButton、TextButton主要アクションとしての ElevatedButton、RaisedButton、FlatButton
NavigationBar + NavigationDestinationBottomNavigationBar
幅が広い場合の NavigationRail/NavigationDrawerデスクトップで引き伸ばしたスマートフォン向けナビゲーションバー
SegmentedButtonToggleButtons
DropdownMenuDropdownButton/DropdownButtonFormField
MenuAnchor/MenuBar新しいメニューでの PopupMenuButton
SearchAnchor/SearchBarアプリバーに自作の検索用 TextField を置くこと
Card.filled/Card.outlined場当たり的な Container + BoxShadow のカード
ListView.builder/スライバーListView(children: hugeList)
Switch.adaptive、Slider.adaptive、Checkbox.adaptive、Radio.adaptive、CircularProgressIndicator.adaptive、RefreshIndicator.adaptive、AlertDialog.adaptive、showAdaptiveDialogOS ネイティブの操作要素に対して、プラットフォームを考慮しない Material コントロール

ナビゲーション

  • 新しいマルチスクリーンアプリでは、go_router + MaterialApp.router/CupertinoApp.router を使います。公式ドキュメントでは、MaterialApp.routes による名前付きルートは推奨されていません。
  • 既存アプリで Navigator.push を使っている場合は、移行を依頼されない限り Navigator を使い続けます。
  • タブごとのスタックを維持する必要があるタブには、StatefulShellRoute.indexedStack を使います。
  • シートやダイアログはページレスのままにします(showModalBottomSheet、showAdaptiveDialog)。ディープリンク可能である必要がない限り、すべてのポップアップを GoRoute にしないでください。
  • 全画面モーダルには fullscreenDialog: true(iOS の表示方式)を使うか、そのページフラグを設定した GoRoute を使います。

Dart/ウィジェット

  • const コンストラクターを使います。400 行の build をひとつ書くより、小さなウィジェットに分割します。
  • ファイル名は snake_case.dart、型名は PascalCase にします。インタラクティブなキーには kebab-case の文字列を使います。
  • ユーザーがコピーできる値には SelectableText、または祖先に SelectionArea を使います。
  • 表形式の数字には fontFeatures: const [FontFeature.tabularFigures()] を使います。
  • デバッグ専用のジャンプ用チップや入力済みフィールドは kDebugMode の内側に置き、実際の認証フローを通すようにします。
  • 画面を実装するために GetX、flutter_screenutil、FontAwesome-for-chrome、新しい状態管理パッケージを追加しないでください。

Expo/RN の慣習を持ち込まない

  • StyleSheet、process.env.EXPO_OS、SafeAreaView、CSS の boxShadow、kebab-case のソースファイルは使わないでください。
  • flex: 1 のスタイルマップは使わず、Expanded/Flexible を使います。
  • expo-image で SF Symbols を使わないでください。Icons.adaptive/CupertinoIcons を使います。

検証

UI の作業は、編集内容が適用された時点では完了ではありません。

  1. 変更したファイルでアナライザーの問題がないことを確認します(dart analyze / flutter analyze)。
  2. 実行中のアプリをホットリロードします。main、ルート、またはグローバルテーマを変更した場合は、ホットリスタートします。
  3. 実行中の画面を確認します(スクリーンショット、ウィジェットプレビュー、またはプロジェクトのビジュアルループ)。古い画面表示は証拠になりません。
  4. 分離したウィジェットには、package:flutter/widget_previews.dart の @Preview を使用します(3.47 で安定版)。ウィジェットプレビューアーを参照してください。
  5. 変更した画面の空、読み込み中、エラー、キーボード表示中の状態を確認します。また、同じ状態を読み取る他のルートも確認します。

コメント