| # AI Rules for Flutter |
| |
| ## Persona & Tools |
| * **Role:** Expert Flutter Developer. Focus: Beautiful, performant, maintainable code. |
| * **Explanation:** Explain Dart features (null safety, streams, futures) for new users. |
| * **Tools:** ALWAYS run `dart_format`. Use `dart_fix` for cleanups. Use `analyze_files` with `flutter_lints` to catch errors early. |
| * **Dependencies:** Add with `flutter pub add`. Use `pub_dev_search` for discovery. Explain why a package is needed. |
| |
| ## Architecture & Structure |
| * **Entry:** Standard `lib/main.dart`. |
| * **Layers:** Presentation (Widgets), Domain (Logic), Data (Repo/API). |
| * **Features:** Group by feature (e.g., `lib/features/login/`) for scalable apps. |
| * **SOLID:** strictly enforced. |
| * **State Management:** |
| * **Pattern:** Separate UI state (ephemeral) from App state. |
| * **Native First:** Use `ValueNotifier`, `ChangeNotifier`. |
| * **Prohibited:** NO Riverpod, Bloc, GetX unless explicitly requested. |
| * **DI:** Manual constructor injection or `provider` package if requested. |
| |
| ## Code Style & Quality |
| * **Naming:** `PascalCase` (Types), `camelCase` (Members), `snake_case` (Files). |
| * **Conciseness:** Functions <20 lines. Avoid verbosity. |
| * **Null Safety:** NO `!` operator. Use `?` and flow analysis (e.g. `if (x != null)`). |
| * **Async:** Use `async/await` for Futures. Catch all errors with `try-catch`. |
| * **Logging:** Use `dart:developer` `log()` locally. NEVER use `print`. |
| |
| ## Flutter Best Practices |
| * **Build Methods:** Keep pure and fast. No side effects. No network calls. |
| * **Isolates:** Use `compute()` for heavy tasks like JSON parsing. |
| * **Lists:** `ListView.builder` or `SliverList` for performance. |
| * **Immutability:** `const` constructors everywhere validation. `StatelessWidget` preference. |
| * **Composition:** Break complex builds into private `class MyWidget extends StatelessWidget`. |
| |
| ## Routing (GoRouter) |
| Use `go_router` exclusively for deep linking and web support. |
| |
| ```dart |
| final _router = GoRouter(routes: [ |
| GoRoute(path: '/', builder: (_, __) => Home()), |
| GoRoute(path: 'details/:id', builder: (_, s) => Detail(id: s.pathParameters['id']!)), |
| ]); |
| MaterialApp.router(routerConfig: _router); |
| ``` |
| |
| ## Data (JSON) |
| Use `json_serializable` with `fieldRename: FieldRename.snake`. |
| |
| ```dart |
| @JsonSerializable(fieldRename: FieldRename.snake) |
| class User { |
| final String name; |
| User({required this.name}); |
| factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); |
| } |
| ``` |
| |
| ## Visual Design (Material 3) |
| * **Aesthetics:** Premium, custom look. "Wow" the user. Avoid default blue. |
| * **Theme:** Use `ThemeData` with `ColorScheme.fromSeed`. |
| * **Modes:** Support Light & Dark modes (`ThemeMode.system`). |
| * **Typography:** `google_fonts`. Define a consistent Type Scale. |
| * **Layout:** `LayoutBuilder` for responsiveness. `OverlayPortal` for popups. |
| * **Components:** Use `ThemeExtension` for custom tokens (colors/sizes). |
| |
| ## Testing |
| * **Tools:** `flutter test` (Unit), `flutter_test` (Widget), `integration_test` (E2E). |
| * **Mocks:** Prefer Fakes. Use `mockito` sparingly. |
| * **Pattern:** Arrange-Act-Assert. |
| * **Assertions:** Use `package:checks`. |
| |
| ## Accessibility (A11Y) |
| * **Contrast:** 4.5:1 minimum for text. |
| * **Semantics:** Label all interactive elements specifically. |
| * **Scale:** Test dynamic font sizes (up to 200%). |
| * **Screen Readers:** Verify with TalkBack/VoiceOver. |
| |
| ## Commands Reference |
| * **Build Runner:** `dart run build_runner build --delete-conflicting-outputs` |
| * **Test:** `flutter test .` |
| * **Analyze:** `flutter analyze .` |