reis-mobile 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.claude-plugin/marketplace.json +24 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/CHANGELOG.md +103 -0
  4. package/LICENSE +21 -0
  5. package/README.md +631 -0
  6. package/THIRD_PARTY_NOTICES.md +105 -0
  7. package/agents/flutter-architect.md +92 -0
  8. package/agents/flutter-performance-engineer.md +103 -0
  9. package/agents/flutter-test-engineer.md +100 -0
  10. package/agents/lead-mobile.md +107 -0
  11. package/agents/mobile-code-reviewer.md +66 -0
  12. package/agents/mobile-staff-engineer.md +85 -0
  13. package/agents/plugin-native-expert.md +97 -0
  14. package/bin/reis-mobile.mjs +256 -0
  15. package/commands/debate.md +135 -0
  16. package/commands/doctor.md +23 -0
  17. package/commands/reis-mobile.md +50 -0
  18. package/commands/review.md +53 -0
  19. package/core/config/language.mjs +83 -0
  20. package/core/context/context-engine.mjs +113 -0
  21. package/core/detection/project-probe.mjs +104 -0
  22. package/core/detection/stack-detector.mjs +204 -0
  23. package/core/diagnostics/doctor.mjs +181 -0
  24. package/core/install/claude-plugin.mjs +76 -0
  25. package/core/paths.mjs +4 -0
  26. package/core/registry/frontmatter.mjs +81 -0
  27. package/core/registry/registry.mjs +140 -0
  28. package/core/router/intent-detector.mjs +75 -0
  29. package/core/router/intents.mjs +91 -0
  30. package/core/router/router.mjs +83 -0
  31. package/core/security/redact.mjs +24 -0
  32. package/package.json +35 -0
  33. package/skills/architecture-feature-first/SKILL.md +116 -0
  34. package/skills/bloc/SKILL.md +354 -0
  35. package/skills/code-review/SKILL.md +89 -0
  36. package/skills/dart-3-updates/SKILL.md +223 -0
  37. package/skills/dart-add-unit-test/SKILL.md +126 -0
  38. package/skills/dart-collect-coverage/SKILL.md +145 -0
  39. package/skills/dart-fix-runtime-errors/SKILL.md +170 -0
  40. package/skills/dart-generate-test-mocks/SKILL.md +159 -0
  41. package/skills/dart-migrate-to-checks-package/SKILL.md +532 -0
  42. package/skills/dart-resolve-package-conflicts/SKILL.md +120 -0
  43. package/skills/dart-run-static-analysis/SKILL.md +108 -0
  44. package/skills/dart-use-pattern-matching/SKILL.md +240 -0
  45. package/skills/dart-use-pattern-matching/examples/json_patterns.dart +85 -0
  46. package/skills/detect-mobile-stack/SKILL.md +33 -0
  47. package/skills/effective-dart/SKILL.md +187 -0
  48. package/skills/firebase-ai/SKILL.md +93 -0
  49. package/skills/firebase-analytics/SKILL.md +129 -0
  50. package/skills/firebase-app-check/SKILL.md +124 -0
  51. package/skills/firebase-auth/SKILL.md +224 -0
  52. package/skills/firebase-cloud-firestore/SKILL.md +165 -0
  53. package/skills/firebase-cloud-functions/SKILL.md +148 -0
  54. package/skills/firebase-crashlytics/SKILL.md +182 -0
  55. package/skills/firebase-data-connect/SKILL.md +80 -0
  56. package/skills/firebase-database/SKILL.md +224 -0
  57. package/skills/firebase-in-app-messaging/SKILL.md +111 -0
  58. package/skills/firebase-messaging/SKILL.md +201 -0
  59. package/skills/firebase-remote-config/SKILL.md +131 -0
  60. package/skills/firebase-storage/SKILL.md +158 -0
  61. package/skills/flutter-add-integration-test/SKILL.md +167 -0
  62. package/skills/flutter-add-widget-preview/SKILL.md +149 -0
  63. package/skills/flutter-add-widget-test/SKILL.md +158 -0
  64. package/skills/flutter-adding-home-screen-widgets/SKILL.md +205 -0
  65. package/skills/flutter-animating-apps/SKILL.md +185 -0
  66. package/skills/flutter-app-architecture/SKILL.md +80 -0
  67. package/skills/flutter-apply-architecture-best-practices/SKILL.md +166 -0
  68. package/skills/flutter-build-responsive-layout/SKILL.md +143 -0
  69. package/skills/flutter-building-forms/SKILL.md +125 -0
  70. package/skills/flutter-building-layouts/SKILL.md +131 -0
  71. package/skills/flutter-building-plugins/SKILL.md +209 -0
  72. package/skills/flutter-caching-data/SKILL.md +171 -0
  73. package/skills/flutter-change-notifier/SKILL.md +138 -0
  74. package/skills/flutter-embedding-native-views/SKILL.md +200 -0
  75. package/skills/flutter-errors/SKILL.md +126 -0
  76. package/skills/flutter-fix-layout-issues/SKILL.md +134 -0
  77. package/skills/flutter-handling-concurrency/SKILL.md +182 -0
  78. package/skills/flutter-implement-json-serialization/SKILL.md +157 -0
  79. package/skills/flutter-improving-accessibility/SKILL.md +113 -0
  80. package/skills/flutter-interoperating-with-native-apis/SKILL.md +130 -0
  81. package/skills/flutter-login-usecase/SKILL.md +38 -0
  82. package/skills/flutter-managing-state/SKILL.md +206 -0
  83. package/skills/flutter-project-audit/SKILL.md +66 -0
  84. package/skills/flutter-reducing-app-size/SKILL.md +103 -0
  85. package/skills/flutter-secure-token-store/SKILL.md +35 -0
  86. package/skills/flutter-setting-up-on-macos/SKILL.md +78 -0
  87. package/skills/flutter-setup-declarative-routing/SKILL.md +259 -0
  88. package/skills/flutter-setup-localization/SKILL.md +214 -0
  89. package/skills/flutter-theming-apps/SKILL.md +163 -0
  90. package/skills/flutter-use-http-package/SKILL.md +178 -0
  91. package/skills/flutter-widget-review/SKILL.md +54 -0
  92. package/skills/flutter-working-with-databases/SKILL.md +203 -0
  93. package/skills/flutterfire-configure/SKILL.md +143 -0
  94. package/skills/mobile-security-audit/SKILL.md +101 -0
  95. package/skills/mockito/SKILL.md +149 -0
  96. package/skills/mocktail/SKILL.md +122 -0
  97. package/skills/patrol-e2e-testing/SKILL.md +224 -0
  98. package/skills/provider/SKILL.md +139 -0
  99. package/skills/riverpod/SKILL.md +246 -0
  100. package/skills/testing/SKILL.md +50 -0
  101. package/stacks/android/stack.json +8 -0
  102. package/stacks/flutter/stack.json +8 -0
  103. package/stacks/ios/stack.json +8 -0
  104. package/stacks/kotlin-multiplatform/stack.json +8 -0
  105. package/stacks/react-native/stack.json +8 -0
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: flutter-change-notifier
3
+ description: Implements state management with ChangeNotifier and Provider in Flutter. Use when setting up ChangeNotifier models, providing them to the widget tree, consuming state with Consumer or Provider.of, or optimizing rebuilds.
4
+ routing: manual
5
+ stacks: [flutter]
6
+ source: https://github.com/evanca/flutter-ai-rules
7
+ license: MIT
8
+ ---
9
+
10
+ # Flutter ChangeNotifier Skill
11
+
12
+ This skill defines how to correctly use `ChangeNotifier` with the `provider` package for state management in Flutter.
13
+
14
+ ---
15
+
16
+ ## 1. Model
17
+
18
+ Extend `ChangeNotifier` to manage state. Keep internal state **private** and expose **unmodifiable views**. Call `notifyListeners()` on every state change.
19
+
20
+ ```dart
21
+ class CartModel extends ChangeNotifier {
22
+ final List<Item> _items = [];
23
+
24
+ UnmodifiableListView<Item> get items => UnmodifiableListView(_items);
25
+
26
+ void add(Item item) {
27
+ _items.add(item);
28
+ notifyListeners();
29
+ }
30
+
31
+ void removeAll() {
32
+ _items.clear();
33
+ notifyListeners();
34
+ }
35
+ }
36
+ ```
37
+
38
+ - Place shared state **above** the widgets that use it in the widget tree.
39
+ - Never directly mutate widgets or call methods on them to change state — rebuild widgets with new data instead.
40
+
41
+ ---
42
+
43
+ ## 2. Providing the Model
44
+
45
+ ```dart
46
+ ChangeNotifierProvider(
47
+ create: (context) => CartModel(),
48
+ child: MyApp(),
49
+ )
50
+ ```
51
+
52
+ - `ChangeNotifierProvider` **automatically disposes** of the model when it is no longer needed.
53
+ - Use `MultiProvider` when you need to provide multiple models:
54
+
55
+ ```dart
56
+ MultiProvider(
57
+ providers: [
58
+ ChangeNotifierProvider(create: (_) => CartModel()),
59
+ ChangeNotifierProvider(create: (_) => UserModel()),
60
+ ],
61
+ child: MyApp(),
62
+ )
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 3. Consuming State
68
+
69
+ ### Consumer
70
+
71
+ ```dart
72
+ Consumer<CartModel>(
73
+ builder: (context, cart, child) => Stack(
74
+ children: [
75
+ if (child != null) child,
76
+ Text('Total price: ${cart.totalPrice}'),
77
+ ],
78
+ ),
79
+ child: const SomeExpensiveWidget(), // rebuilt only once
80
+ )
81
+ ```
82
+
83
+ - Always specify the generic type (`Consumer<CartModel>`, not `Consumer`).
84
+ - Use the `child` parameter to pass **widgets that don't depend on the model** — they are built once and reused.
85
+ - Place `Consumer` widgets **as deep in the widget tree as possible** to minimize the scope of rebuilds:
86
+
87
+ ```dart
88
+ HumongousWidget(
89
+ child: AnotherMonstrousWidget(
90
+ child: Consumer<CartModel>(
91
+ builder: (context, cart, child) {
92
+ return Text('Total price: ${cart.totalPrice}');
93
+ },
94
+ ),
95
+ ),
96
+ )
97
+ ```
98
+
99
+ ### Provider.of with listen: false
100
+
101
+ Use `Provider.of<T>(context, listen: false)` when you only need to **call methods** on the model, not react to state changes:
102
+
103
+ ```dart
104
+ Provider.of<CartModel>(context, listen: false).removeAll();
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 4. Optimization Rules
110
+
111
+ - Do **not** wrap large widget subtrees in a `Consumer` if only a small part depends on the model.
112
+ - Avoid rebuilding widgets unnecessarily — structure your widget tree and provider usage carefully.
113
+ - Use `listen: false` in callbacks (e.g., `onPressed`) where you trigger actions but don't need rebuilds.
114
+
115
+ ---
116
+
117
+ ## 5. Testing
118
+
119
+ Write **unit tests** for your `ChangeNotifier` models to verify state changes and notifications:
120
+
121
+ ```dart
122
+ test('adding item updates total', () {
123
+ final cart = CartModel();
124
+ var notified = false;
125
+ cart.addListener(() => notified = true);
126
+
127
+ cart.add(Item('Book'));
128
+
129
+ expect(cart.items.length, 1);
130
+ expect(notified, isTrue);
131
+ });
132
+ ```
133
+
134
+ ---
135
+
136
+ ## References
137
+
138
+ - [Flutter Website GitHub Repository](https://github.com/flutter/website)
@@ -0,0 +1,200 @@
1
+ ---
2
+ name: flutter-embedding-native-views
3
+ description: Embeds native Android, iOS, or macOS views into a Flutter app. Use when integrating complex native components like maps or web views.
4
+ metadata:
5
+ model: models/gemini-3.1-pro-preview
6
+ last_modified: Thu, 12 Mar 2026 22:20:28 GMT
7
+ routing: manual
8
+ stacks: [flutter]
9
+ source: https://github.com/flutter/skills
10
+ license: BSD-3-Clause
11
+ ---
12
+ # Integrating Platform Views and Web Content
13
+
14
+ ## Contents
15
+ - [Platform Views Architecture](#platform-views-architecture)
16
+ - [Web Embedding Architecture](#web-embedding-architecture)
17
+ - [Workflow: Implementing Android Platform Views](#workflow-implementing-android-platform-views)
18
+ - [Workflow: Implementing iOS Platform Views](#workflow-implementing-ios-platform-views)
19
+ - [Workflow: Embedding Flutter in Web Applications](#workflow-embedding-flutter-in-web-applications)
20
+ - [Examples](#examples)
21
+
22
+ ## Platform Views Architecture
23
+
24
+ Platform Views allow embedding native views (Android, iOS, macOS) directly into a Flutter application, enabling the application of transforms, clips, and opacity from Dart.
25
+
26
+ ### Android Implementations (API 23+)
27
+ Choose the appropriate implementation based on your performance and fidelity requirements:
28
+ * **Hybrid Composition:** Renders Flutter content into a texture and uses `SurfaceFlinger` to compose both.
29
+ * *Pros:* Best performance and fidelity for Android views.
30
+ * *Cons:* Lowers overall application FPS. Certain Flutter widget transformations will not work.
31
+ * **Texture Layer (Texture Layer Hybrid Composition):** Renders Platform Views into a texture. Flutter draws them via the texture and renders its own content directly into a Surface.
32
+ * *Pros:* Best performance for Flutter rendering. All transformations work correctly.
33
+ * *Cons:* Quick scrolling (e.g., WebViews) can be janky. `SurfaceView` is problematic (breaks accessibility). Text magnifiers break unless Flutter is rendered into a `TextureView`.
34
+
35
+ ### iOS & macOS Implementations
36
+ * **iOS:** Uses Hybrid Composition exclusively. The native `UIView` is appended to the view hierarchy.
37
+ * *Limitations:* `ShaderMask` and `ColorFiltered` widgets are not supported. `BackdropFilter` has composition limitations.
38
+ * **macOS:** Uses Hybrid Composition (`NSView`).
39
+ * *Limitations:* Not fully functional in current releases (e.g., gesture support is unavailable).
40
+
41
+ ### Performance Mitigation
42
+ Mitigate performance drops during complex Dart animations by rendering a screenshot of the native view as a placeholder texture while the animation runs.
43
+
44
+ ## Web Embedding Architecture
45
+
46
+ Embed Flutter into existing web applications (Vanilla JS, React, Angular, etc.) using either Full Page mode or Embedded (Multi-view) mode.
47
+
48
+ * **Full Page Mode:** Flutter takes over the entire browser window. Use an `iframe` if you need to constrain the Flutter app without modifying the Flutter bootstrap process.
49
+ * **Embedded Mode (Multi-view):** Render Flutter into specific HTML elements (`div`s). Requires `multiViewEnabled: true` during engine initialization.
50
+ * Manage views from JavaScript using `app.addView()` and `app.removeView()`.
51
+ * In Dart, replace `runApp` with `runWidget`.
52
+ * Manage the dynamic list of views using `WidgetsBinding.instance.platformDispatcher.views` and render them using `ViewCollection` and `View` widgets.
53
+
54
+ ## Workflow: Implementing Android Platform Views
55
+
56
+ Follow this sequential workflow to implement a Platform View on Android.
57
+
58
+ **Task Progress:**
59
+ - [ ] 1. Determine the composition mode (Hybrid vs. Texture Layer).
60
+ - [ ] 2. Implement the Dart widget.
61
+ - [ ] 3. Implement the native Android View and Factory.
62
+ - [ ] 4. Register the Platform View in the Android host.
63
+ - [ ] 5. Run validator -> review rendering -> fix manual invalidation issues.
64
+
65
+ ### 1. Dart Implementation
66
+ If using **Hybrid Composition**, use `PlatformViewLink`, `AndroidViewSurface`, and `PlatformViewsService.initSurfaceAndroidView`.
67
+ If using **Texture Layer**, use the `AndroidView` widget.
68
+
69
+ ### 2. Native Implementation
70
+ Create a class implementing `io.flutter.plugin.platform.PlatformView` that returns your native `android.view.View`.
71
+ Create a factory extending `PlatformViewFactory` to instantiate your view.
72
+
73
+ ### 3. Registration
74
+ Register the factory in your `MainActivity.kt` (or plugin) using `flutterEngine.platformViewsController.registry.registerViewFactory`.
75
+
76
+ *Note: If your native view uses `SurfaceView` or `SurfaceTexture`, manually call `invalidate` on the View or its parent when content changes, as they do not invalidate themselves automatically.*
77
+
78
+ ## Workflow: Implementing iOS Platform Views
79
+
80
+ Follow this sequential workflow to implement a Platform View on iOS.
81
+
82
+ **Task Progress:**
83
+ - [ ] 1. Implement the Dart widget using `UiKitView`.
84
+ - [ ] 2. Implement the native iOS View (`FlutterPlatformView`) and Factory (`FlutterPlatformViewFactory`).
85
+ - [ ] 3. Register the Platform View in `AppDelegate.swift` or the plugin registrar.
86
+ - [ ] 4. Run validator -> review composition limitations -> fix unsupported filters.
87
+
88
+ ## Workflow: Embedding Flutter in Web Applications
89
+
90
+ Follow this sequential workflow to embed Flutter into an existing web DOM.
91
+
92
+ **Task Progress:**
93
+ - [ ] 1. Update `flutter_bootstrap.js` to enable multi-view.
94
+ - [ ] 2. Update `main.dart` to use `runWidget` and `ViewCollection`.
95
+ - [ ] 3. Implement JavaScript logic to add/remove host elements.
96
+ - [ ] 4. Run validator -> review view constraints -> fix CSS conflicts.
97
+
98
+ ### 1. JavaScript Configuration
99
+ In `flutter_bootstrap.js`, initialize the engine with `multiViewEnabled: true`.
100
+ Use the returned `app` object to add views: `app.addView({ hostElement: document.getElementById('my-div') })`.
101
+
102
+ ### 2. Dart Configuration
103
+ Replace `runApp()` with `runWidget()`.
104
+ Create a root widget that listens to `WidgetsBindingObserver.didChangeMetrics`.
105
+ Map over `WidgetsBinding.instance.platformDispatcher.views` to create a `View` widget for each attached `FlutterView`, and wrap them all in a `ViewCollection`.
106
+
107
+ ## Examples
108
+
109
+ ### Example: Android Texture Layer (Dart)
110
+ ```dart
111
+ import 'package:flutter/material.dart';
112
+ import 'package:flutter/services.dart';
113
+
114
+ class NativeAndroidView extends StatelessWidget {
115
+ @override
116
+ Widget build(BuildContext context) {
117
+ const String viewType = 'my_native_view';
118
+ final Map<String, dynamic> creationParams = <String, dynamic>{};
119
+
120
+ return AndroidView(
121
+ viewType: viewType,
122
+ layoutDirection: TextDirection.ltr,
123
+ creationParams: creationParams,
124
+ creationParamsCodec: const StandardMessageCodec(),
125
+ );
126
+ }
127
+ }
128
+ ```
129
+
130
+ ### Example: Web Multi-View Initialization (JavaScript)
131
+ ```javascript
132
+ _flutter.loader.load({
133
+ onEntrypointLoaded: async function(engineInitializer) {
134
+ let engine = await engineInitializer.initializeEngine({
135
+ multiViewEnabled: true,
136
+ });
137
+ let app = await engine.runApp();
138
+
139
+ // Add a view to a specific DOM element
140
+ let viewId = app.addView({
141
+ hostElement: document.querySelector('#flutter-host-container'),
142
+ initialData: { customData: 'Hello from JS' }
143
+ });
144
+ }
145
+ });
146
+ ```
147
+
148
+ ### Example: Web Multi-View Root Widget (Dart)
149
+ ```dart
150
+ import 'dart:ui' show FlutterView;
151
+ import 'package:flutter/widgets.dart';
152
+
153
+ void main() {
154
+ runWidget(MultiViewApp(viewBuilder: (context) => const MyEmbeddedWidget()));
155
+ }
156
+
157
+ class MultiViewApp extends StatefulWidget {
158
+ final WidgetBuilder viewBuilder;
159
+ const MultiViewApp({super.key, required this.viewBuilder});
160
+
161
+ @override
162
+ State<MultiViewApp> createState() => _MultiViewAppState();
163
+ }
164
+
165
+ class _MultiViewAppState extends State<MultiViewApp> with WidgetsBindingObserver {
166
+ Map<Object, Widget> _views = {};
167
+
168
+ @override
169
+ void initState() {
170
+ super.initState();
171
+ WidgetsBinding.instance.addObserver(this);
172
+ _updateViews();
173
+ }
174
+
175
+ @override
176
+ void didChangeMetrics() => _updateViews();
177
+
178
+ void _updateViews() {
179
+ final newViews = <Object, Widget>{};
180
+ for (final FlutterView view in WidgetsBinding.instance.platformDispatcher.views) {
181
+ newViews[view.viewId] = _views[view.viewId] ?? View(
182
+ view: view,
183
+ child: Builder(builder: widget.viewBuilder),
184
+ );
185
+ }
186
+ setState(() => _views = newViews);
187
+ }
188
+
189
+ @override
190
+ void dispose() {
191
+ WidgetsBinding.instance.removeObserver(this);
192
+ super.dispose();
193
+ }
194
+
195
+ @override
196
+ Widget build(BuildContext context) {
197
+ return ViewCollection(views: _views.values.toList(growable: false));
198
+ }
199
+ }
200
+ ```
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: flutter-errors
3
+ description: Diagnoses and fixes common Flutter errors. Use when encountering layout errors (RenderFlex overflow, unbounded constraints, RenderBox not laid out), scroll errors, or setState-during-build errors.
4
+ intents: [debug]
5
+ stacks: [flutter]
6
+ source: https://github.com/evanca/flutter-ai-rules
7
+ license: MIT
8
+ ---
9
+
10
+ # Flutter Errors Skill
11
+
12
+ This skill provides solutions for the most common Flutter runtime and layout errors.
13
+
14
+ ---
15
+
16
+ ## RenderFlex Overflowed
17
+
18
+ **Error:** `A RenderFlex overflowed by X pixels on the right/bottom.`
19
+
20
+ **Cause:** A `Row` or `Column` contains children that are wider/taller than the available space.
21
+
22
+ **Fix:** Wrap the overflowing child in `Flexible` or `Expanded`, or constrain its size:
23
+
24
+ ```dart
25
+ Row(
26
+ children: [
27
+ Expanded(child: Text('Long text that might overflow')),
28
+ Icon(Icons.info),
29
+ ],
30
+ )
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Vertical Viewport Given Unbounded Height
36
+
37
+ **Error:** `Vertical viewport was given unbounded height.`
38
+
39
+ **Cause:** A `ListView` (or other scrollable) is placed inside a `Column` without a bounded height.
40
+
41
+ **Fix:** Wrap the `ListView` in `Expanded` or give it a fixed height with `SizedBox`:
42
+
43
+ ```dart
44
+ Column(
45
+ children: [
46
+ Text('Header'),
47
+ Expanded(
48
+ child: ListView(children: [...]),
49
+ ),
50
+ ],
51
+ )
52
+ ```
53
+
54
+ ---
55
+
56
+ ## InputDecorator Cannot Have Unbounded Width
57
+
58
+ **Error:** `An InputDecorator...cannot have an unbounded width.`
59
+
60
+ **Cause:** A `TextField` or similar widget is placed in a context without width constraints.
61
+
62
+ **Fix:** Wrap it in `Expanded`, `SizedBox`, or any parent that provides width constraints:
63
+
64
+ ```dart
65
+ Row(
66
+ children: [
67
+ Expanded(child: TextField()),
68
+ ],
69
+ )
70
+ ```
71
+
72
+ ---
73
+
74
+ ## setState Called During Build
75
+
76
+ **Error:** `setState() or markNeedsBuild() called during build.`
77
+
78
+ **Cause:** `setState` or `showDialog` is called directly inside the `build` method.
79
+
80
+ **Fix:** Trigger state changes in response to user actions, or defer to after the frame using `addPostFrameCallback`:
81
+
82
+ ```dart
83
+ @override
84
+ void initState() {
85
+ super.initState();
86
+ WidgetsBinding.instance.addPostFrameCallback((_) {
87
+ // Safe to call setState or showDialog here
88
+ });
89
+ }
90
+ ```
91
+
92
+ ---
93
+
94
+ ## ScrollController Attached to Multiple Scroll Views
95
+
96
+ **Error:** `The ScrollController is attached to multiple scroll views.`
97
+
98
+ **Cause:** A single `ScrollController` instance is shared across more than one scrollable widget simultaneously.
99
+
100
+ **Fix:** Ensure each scrollable widget has its own dedicated `ScrollController` instance.
101
+
102
+ ---
103
+
104
+ ## RenderBox Was Not Laid Out
105
+
106
+ **Error:** `RenderBox was not laid out: ...`
107
+
108
+ **Cause:** A widget is missing or has unbounded constraints — commonly `ListView` or `Column` without proper size constraints.
109
+
110
+ **Fix:** Review your widget tree for missing constraints. Common patterns:
111
+
112
+ - Wrap `ListView` in `Expanded` inside a `Column`.
113
+ - Give widgets an explicit `width` or `height` via `SizedBox` or `ConstrainedBox`.
114
+
115
+ ---
116
+
117
+ ## Debugging Layout Issues
118
+
119
+ - Use the **Flutter Inspector** (in DevTools) to visualize widget constraints.
120
+ - Enable **"Show guidelines"** to see layout boundaries.
121
+ - Add `debugPaintSizeEnabled = true;` temporarily in your `main()` to paint layout bounds.
122
+ - Refer to the [Flutter constraints documentation](https://docs.flutter.dev/ui/layout/constraints) for a deeper understanding of how constraints propagate.
123
+
124
+ ## References
125
+
126
+ - [Flutter Website GitHub Repository](https://github.com/flutter/website)
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: flutter-fix-layout-issues
3
+ description: Fixes Flutter layout errors (overflows, unbounded constraints) using Dart and Flutter MCP tools. Use when addressing "RenderFlex overflowed", "Vertical viewport was given unbounded height", or similar layout issues.
4
+ metadata:
5
+ model: models/gemini-3.1-pro-preview
6
+ last_modified: Tue, 21 Apr 2026 19:45:59 GMT
7
+ intents: [debug]
8
+ stacks: [flutter]
9
+ source: https://github.com/flutter/skills
10
+ license: BSD-3-Clause
11
+ ---
12
+ # Resolving Flutter Layout Errors
13
+
14
+ ## Contents
15
+ - [Constraint Violation Diagnostics](#constraint-violation-diagnostics)
16
+ - [Layout Error Resolution Workflow](#layout-error-resolution-workflow)
17
+ - [Examples](#examples)
18
+
19
+ ## Constraint Violation Diagnostics
20
+
21
+ Flutter layout operates on a strict rule: **Constraints go down. Sizes go up. Parent sets position.** Layout errors occur when this negotiation fails, typically due to unbounded constraints or unconstrained children.
22
+
23
+ Diagnose layout failures using the following error signatures:
24
+
25
+ * **"Vertical viewport was given unbounded height"**: Triggered when a scrollable widget (`ListView`, `GridView`) is placed inside an unconstrained vertical parent (`Column`). The parent provides infinite height, and the child attempts to expand infinitely.
26
+ * **"An InputDecorator...cannot have an unbounded width"**: Triggered when a `TextField` or `TextFormField` is placed inside an unconstrained horizontal parent (`Row`). The text field attempts to determine its width based on infinite available space.
27
+ * **"RenderFlex overflowed"**: Triggered when a child of a `Row` or `Column` requests a size larger than the parent's allocated constraints. Visually indicated by yellow and black warning stripes.
28
+ * **"Incorrect use of ParentData widget"**: Triggered when a `ParentDataWidget` is not a direct descendant of its required ancestor. (e.g., `Expanded` outside a `Flex`, `Positioned` outside a `Stack`).
29
+ * **"RenderBox was not laid out"**: A cascading side-effect error. Ignore this and look further up the stack trace for the primary constraint violation (usually an unbounded height/width error).
30
+
31
+ ## Layout Error Resolution Workflow
32
+
33
+ Copy and use this checklist to systematically resolve layout constraint violations.
34
+
35
+ ### Task Progress
36
+ - [ ] Run the application in debug mode to capture the exact layout exception in the console.
37
+ - [ ] Identify the primary error message (ignore cascading "RenderBox was not laid out" errors).
38
+ - [ ] Apply the conditional fix based on the specific error type:
39
+ - **If "Vertical viewport was given unbounded height"**: Wrap the scrollable child (`ListView`, `GridView`) in an `Expanded` widget to consume remaining space, or wrap it in a `SizedBox` to provide an absolute height constraint.
40
+ - **If "An InputDecorator...cannot have an unbounded width"**: Wrap the `TextField` or `TextFormField` in an `Expanded` or `Flexible` widget.
41
+ - **If "RenderFlex overflowed"**: Constrain the overflowing child by wrapping it in an `Expanded` widget (to force it to fit) or a `Flexible` widget (to allow it to be smaller than the allocated space).
42
+ - **If "Incorrect use of ParentData widget"**: Move the `ParentDataWidget` to be a direct child of its required parent. Ensure `Expanded`/`Flexible` are direct children of `Row`/`Column`/`Flex`. Ensure `Positioned` is a direct child of `Stack`.
43
+ - [ ] Execute Flutter hot reload.
44
+ - [ ] Run validator -> review errors -> fix: Inspect the UI to verify the red/grey error screen or yellow/black overflow stripes are resolved. If new layout errors appear, repeat the workflow.
45
+
46
+ ## Examples
47
+
48
+ ### Fixing Unbounded Height (ListView in Column)
49
+
50
+ **Input (Error State):**
51
+ ```dart
52
+ // Throws "Vertical viewport was given unbounded height"
53
+ Column(
54
+ children: <Widget>[
55
+ const Text('Header'),
56
+ ListView(
57
+ children: const <Widget>[
58
+ ListTile(title: Text('Item 1')),
59
+ ListTile(title: Text('Item 2')),
60
+ ],
61
+ ),
62
+ ],
63
+ )
64
+ ```
65
+
66
+ **Output (Resolved State):**
67
+ ```dart
68
+ // Wrap ListView in Expanded to constrain its height to the remaining Column space
69
+ Column(
70
+ children: <Widget>[
71
+ const Text('Header'),
72
+ Expanded(
73
+ child: ListView(
74
+ children: const <Widget>[
75
+ ListTile(title: Text('Item 1')),
76
+ ListTile(title: Text('Item 2')),
77
+ ],
78
+ ),
79
+ ),
80
+ ],
81
+ )
82
+ ```
83
+
84
+ ### Fixing Unbounded Width (TextField in Row)
85
+
86
+ **Input (Error State):**
87
+ ```dart
88
+ // Throws "An InputDecorator...cannot have an unbounded width"
89
+ Row(
90
+ children: [
91
+ const Icon(Icons.search),
92
+ TextField(),
93
+ ],
94
+ )
95
+ ```
96
+
97
+ **Output (Resolved State):**
98
+ ```dart
99
+ // Wrap TextField in Expanded to constrain its width to the remaining Row space
100
+ Row(
101
+ children: [
102
+ const Icon(Icons.search),
103
+ Expanded(
104
+ child: TextField(),
105
+ ),
106
+ ],
107
+ )
108
+ ```
109
+
110
+ ### Fixing RenderFlex Overflow
111
+
112
+ **Input (Error State):**
113
+ ```dart
114
+ // Throws "A RenderFlex overflowed by X pixels on the right"
115
+ Row(
116
+ children: [
117
+ const Icon(Icons.info),
118
+ const Text('This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
119
+ ],
120
+ )
121
+ ```
122
+
123
+ **Output (Resolved State):**
124
+ ```dart
125
+ // Wrap the Text widget in Expanded to force it to wrap within the available constraints
126
+ Row(
127
+ children: [
128
+ const Icon(Icons.info),
129
+ Expanded(
130
+ child: const Text('This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
131
+ ),
132
+ ],
133
+ )
134
+ ```