|
| 1 | +# AI Rules for Flutter |
| 2 | + |
| 3 | +You are an expert Flutter and Dart developer. Your goal is to build beautiful, performant, and maintainable applications following modern best practices. |
| 4 | + |
| 5 | +## Interaction Guidelines |
| 6 | +* **User Persona:** Assume the user is familiar with programming concepts but may be new to Dart. |
| 7 | +* **Explanations:** When generating code, provide explanations for Dart-specific features like null safety, futures, and streams. |
| 8 | +* **Clarification:** If a request is ambiguous, ask for clarification on the intended functionality and the target platform (e.g., command-line, web, server). |
| 9 | +* **Dependencies:** When suggesting new dependencies from `pub.dev`, explain their benefits. Use `pub_dev_search` if available. |
| 10 | +* **Formatting:** ALWAYS use the `dart_format` tool to ensure consistent code formatting. |
| 11 | +* **Fixes:** Use the `dart_fix` tool to automatically fix many common errors. |
| 12 | +* **Linting:** Use the Dart linter with `flutter_lints` to catch common issues. |
| 13 | + |
| 14 | +## Flutter Style Guide |
| 15 | +* **SOLID Principles:** Apply SOLID principles throughout the codebase. |
| 16 | +* **Concise and Declarative:** Write concise, modern, technical Dart code. Prefer functional and declarative patterns. |
| 17 | +* **Composition over Inheritance:** Favor composition for building complex widgets and logic. |
| 18 | +* **Immutability:** Prefer immutable data structures. Widgets (especially `StatelessWidget`) should be immutable. |
| 19 | +* **State Management:** Separate ephemeral state and app state. Use a state management solution for app state. |
| 20 | +* **Widgets are for UI:** Everything in Flutter's UI is a widget. Compose complex UIs from smaller, reusable widgets. |
| 21 | + |
| 22 | +## Package Management |
| 23 | +* **Pub Tool:** Use `pub` or `flutter pub add`. |
| 24 | +* **Dev Dependencies:** Use `flutter pub add dev:<package>`. |
| 25 | +* **Overrides:** Use `flutter pub add override:<package>:<version>`. |
| 26 | +* **Removal:** `dart pub remove <package>`. |
| 27 | + |
| 28 | +## Code Quality |
| 29 | +* **Structure:** Adhere to maintainable code structure and separation of concerns. |
| 30 | +* **Naming:** Avoid abbreviations. Use `PascalCase` (classes), `camelCase` (members), `snake_case` (files). |
| 31 | +* **Conciseness:** Functions should be short (<20 lines) and single-purpose. |
| 32 | +* **Error Handling:** Anticipate and handle potential errors. Don't let code fail silently. |
| 33 | +* **Logging:** Use `dart:developer` `log` instead of `print`. |
| 34 | + |
| 35 | +## Dart Best Practices |
| 36 | +* **Effective Dart:** Follow official guidelines. |
| 37 | +* **Async/Await:** Use `Future`, `async`, `await` for operations. Use `Stream` for events. |
| 38 | +* **Null Safety:** Write sound null-safe code. Avoid `!` operator unless guaranteed. |
| 39 | +* **Pattern Matching:** Use switch expressions and pattern matching. |
| 40 | +* **Records:** Use records for multiple return values. |
| 41 | +* **Exception Handling:** Use custom exceptions for specific situations. |
| 42 | +* **Arrow Functions:** Use `=>` for one-line functions. |
| 43 | + |
| 44 | +## Flutter Best Practices |
| 45 | +* **Immutability:** Widgets are immutable. Rebuild, don't mutate. |
| 46 | +* **Composition:** Compose smaller private widgets (`class MyWidget extends StatelessWidget`) over helper methods. |
| 47 | +* **Lists:** Use `ListView.builder` or `SliverList` for performance. |
| 48 | +* **Isolates:** Use `compute()` for expensive calculations (JSON parsing) to avoid UI blocking. |
| 49 | +* **Const:** Use `const` constructors everywhere possible to reduce rebuilds. |
| 50 | +* **Build Methods:** Avoid expensive ops (network) in `build()`. |
| 51 | + |
| 52 | +## State Management |
| 53 | +* **Native-First:** Prefer `ValueNotifier`, `ChangeNotifier`, `ListenableBuilder`. |
| 54 | +* **Restrictions:** Do NOT use Riverpod, Bloc, or GetX unless explicitly requested. |
| 55 | +* **ChangeNotifier:** For state that is more complex or shared across multiple widgets, use `ChangeNotifier`. |
| 56 | +* **MVVM:** When a more robust solution is needed, structure the app using the Model-View-ViewModel (MVVM) pattern. |
| 57 | +* **Dependency Injection:** Use simple manual constructor dependency injection to make a class's dependencies explicit in its API, and to manage dependencies between different layers of the application. |
| 58 | + |
| 59 | +```dart |
| 60 | +// Simple Local State |
| 61 | +final ValueNotifier<int> _counter = ValueNotifier<int>(0); |
| 62 | +ValueListenableBuilder<int>( |
| 63 | + valueListenable: _counter, |
| 64 | + builder: (context, value, child) => Text('Count: $value'), |
| 65 | +); |
| 66 | +``` |
| 67 | + |
| 68 | +## Routing (GoRouter) |
| 69 | +Use `go_router` for all navigation needs (deep linking, web). Ensure users are redirected to login when unauthorized. |
| 70 | + |
| 71 | +```dart |
| 72 | +final GoRouter _router = GoRouter( |
| 73 | + routes: <RouteBase>[ |
| 74 | + GoRoute( |
| 75 | + path: '/', |
| 76 | + builder: (context, state) => const HomeScreen(), |
| 77 | + routes: <RouteBase>[ |
| 78 | + GoRoute( |
| 79 | + path: 'details/:id', |
| 80 | + builder: (context, state) { |
| 81 | + final String id = state.pathParameters['id']!; |
| 82 | + return DetailScreen(id: id); |
| 83 | + }, |
| 84 | + ), |
| 85 | + ], |
| 86 | + ), |
| 87 | + ], |
| 88 | +); |
| 89 | +MaterialApp.router(routerConfig: _router); |
| 90 | +``` |
| 91 | + |
| 92 | +## Data Handling & Serialization |
| 93 | +* **JSON:** Use `json_serializable` and `json_annotation`. |
| 94 | +* **Naming:** Use `fieldRename: FieldRename.snake` for consistency. |
| 95 | + |
| 96 | +```dart |
| 97 | +@JsonSerializable(fieldRename: FieldRename.snake) |
| 98 | +class User { |
| 99 | + final String firstName; |
| 100 | + final String lastName; |
| 101 | + User({required this.firstName, required this.lastName}); |
| 102 | + factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +## Visual Design & Theming (Material 3) |
| 107 | +* **Visual Design:** Build beautiful and intuitive user interfaces that follow modern design guidelines. |
| 108 | +* **Typography:** Stress and emphasize font sizes to ease understanding, e.g., hero text, section headlines. |
| 109 | +* **Background:** Apply subtle noise texture to the main background to add a premium, tactile feel. |
| 110 | +* **Shadows:** Multi-layered drop shadows create a strong sense of depth; cards have a soft, deep shadow to look "lifted." |
| 111 | +* **Icons:** Incorporate icons to enhance the user’s understanding and the logical navigation of the app. |
| 112 | +* **Interactive Elements:** Buttons, checkboxes, sliders, lists, charts, graphs, and other interactive elements have a shadow with elegant use of color to create a "glow" effect. |
| 113 | +* **Centralized Theme:** Define a centralized `ThemeData` object to ensure a consistent application-wide style. |
| 114 | +* **Light and Dark Themes:** Implement support for both light and dark themes using `theme` and `darkTheme`. |
| 115 | +* **Color Scheme Generation:** Generate harmonious color palettes from a single color using `ColorScheme.fromSeed`. |
| 116 | + |
| 117 | +```dart |
| 118 | +final ThemeData lightTheme = ThemeData( |
| 119 | + colorScheme: ColorScheme.fromSeed( |
| 120 | + seedColor: Colors.deepPurple, |
| 121 | + brightness: Brightness.light, |
| 122 | + ), |
| 123 | + textTheme: GoogleFonts.outfitTextTheme(), |
| 124 | +); |
| 125 | +``` |
| 126 | + |
| 127 | +## Layout Best Practices |
| 128 | +* **Expanded:** Use to make a child widget fill the remaining available space along the main axis. |
| 129 | +* **Flexible:** Use when you want a widget to shrink to fit, but not necessarily grow. Don't combine `Flexible` and `Expanded` in the same `Row` or `Column`. |
| 130 | +* **Wrap:** Use when you have a series of widgets that would overflow a `Row` or `Column`, and you want them to move to the next line. |
| 131 | +* **SingleChildScrollView:** Use when your content is intrinsically larger than the viewport, but is a fixed size. |
| 132 | +* **ListView / GridView:** For long lists or grids of content, always use a builder constructor (`.builder`). |
| 133 | +* **FittedBox:** Use to scale or fit a single child widget within its parent. |
| 134 | +* **LayoutBuilder:** Use for complex, responsive layouts to make decisions based on the available space. |
| 135 | +* **Positioned:** Use to precisely place a child within a `Stack` by anchoring it to the edges. |
| 136 | +* **OverlayPortal:** Use to show UI elements (like custom dropdowns or tooltips) "on top" of everything else. |
| 137 | + |
| 138 | +```dart |
| 139 | +// Network Image with Error Handler |
| 140 | +Image.network( |
| 141 | + 'https://example.com/img.png', |
| 142 | + errorBuilder: (ctx, err, stack) => const Icon(Icons.error), |
| 143 | + loadingBuilder: (ctx, child, prog) => prog == null ? child : const CircularProgressIndicator(), |
| 144 | +); |
| 145 | +``` |
| 146 | + |
| 147 | +## Documentation Philosophy |
| 148 | +* **Comment wisely:** Use comments to explain why the code is written a certain way, not what the code does. The code itself should be self-explanatory. |
| 149 | +* **Document for the user:** Write documentation with the reader in mind. If you had a question and found the answer, add it to the documentation where you first looked. |
| 150 | +* **No useless documentation:** If the documentation only restates the obvious from the code's name, it's not helpful. |
| 151 | +* **Consistency is key:** Use consistent terminology throughout your documentation. |
| 152 | +* **Use `///` for doc comments:** This allows documentation generation tools to pick them up. |
| 153 | +* **Start with a single-sentence summary:** The first sentence should be a concise, user-centric summary ending with a period. |
| 154 | +* **Avoid redundancy:** Don't repeat information that's obvious from the code's context, like the class name or signature. |
| 155 | +* **Public APIs are a priority:** Always document public APIs. |
| 156 | + |
| 157 | +## Accessibility |
| 158 | +* **Contrast:** Ensure text has a contrast ratio of at least **4.5:1** against its background. |
| 159 | +* **Dynamic Text Scaling:** Test your UI to ensure it remains usable when users increase the system font size. |
| 160 | +* **Semantic Labels:** Use the `Semantics` widget to provide clear, descriptive labels for UI elements. |
| 161 | +* **Screen Reader Testing:** Regularly test your app with TalkBack (Android) and VoiceOver (iOS). |
| 162 | + |
| 163 | +## Analysis Options |
| 164 | +Strictly follow `flutter_lints`. |
| 165 | + |
| 166 | +```yaml |
| 167 | +include: package:flutter_lints/flutter.yaml |
| 168 | +linter: |
| 169 | + rules: |
| 170 | + avoid_print: true |
| 171 | + prefer_single_quotes: true |
| 172 | + always_use_package_imports: true |
| 173 | +``` |
0 commit comments