prefer-container
Suggests collapsing compatible nested layout widgets into one Container.
Matches at least three Flutter widgets in Container's outside-in order:
Transform, margin Padding, ConstrainedBox, ColoredBox, inner Padding,
and Align. Stages may be omitted, but not repeated or reordered. Only the
unnamed constructors and their directly equivalent arguments qualify; inner
keys, alignment size factors, transform origins and hit-test overrides are
excluded. Decoration and clipping are excluded because their padding and
clipping behavior cannot generally be reproduced by a Container. The final
child must be provably non-null to preserve Container's empty-child behavior.
Constant contexts are excluded because Container has no const constructor.
A concrete source-widget expected type is also excluded to preserve typing.
Options
min-sequence (integer, default: 3) sets the minimum chain length, with a
minimum effective value of 3 to avoid competing with single-widget rules.
Invalid
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as m;
Widget transformed(Widget child, dynamic matrix) => Transform(transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: Align(alignment: Alignment.center, child: child)));
Widget constrained(Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(alignment: Alignment.topLeft, child: child)));
Widget colored(Widget child) => ColoredBox(color: Colors.red, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));
Widget prefixed(Widget child) => m.Padding(padding: EdgeInsets.all(8), child: m.ConstrainedBox(constraints: BoxConstraints.tightFor(height: 20), child: m.Align(child: child)));
Widget explicitNew(Widget child) => new Padding(padding: EdgeInsets.all(8), child: new ColoredBox(color: Colors.blue, child: new Align(child: child)));
Widget longChain(Widget child, dynamic matrix) => Transform(transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: ColoredBox(color: Colors.red, child: Padding(padding: EdgeInsets.all(4), child: Align(child: child))))));
Widget grouped(Widget child) => (Padding(padding: EdgeInsets.all(8), child: (ConstrainedBox(constraints: BoxConstraints.tightFor(height: 20), child: (Align(child: child))))));
Widget alignedTransform(Widget child, Matrix4 matrix) => Transform(alignment: Alignment.center, transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));
Widget doublePadding(Widget child) => Padding(padding: EdgeInsets.all(8), child: Padding(padding: EdgeInsets.all(4), child: Align(child: child)));
Widget outerKey(Widget child, Key key) => Padding(key: key, padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child))); Widget transformed(Widget child, dynamic matrix) => Transform(transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: Align(alignment: Alignment.center, child: child)));Widget transformed(Widget child, dynamic matrix) => Transform(transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: Align(alignment: Alignment.center, child: child)));Widget constrained(Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(alignment: Alignment.topLeft, child: child)));Widget constrained(Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(alignment: Alignment.topLeft, child: child)));Widget colored(Widget child) => ColoredBox(color: Colors.red, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));Widget colored(Widget child) => ColoredBox(color: Colors.red, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));Widget prefixed(Widget child) => m.Padding(padding: EdgeInsets.all(8), child: m.ConstrainedBox(constraints: BoxConstraints.tightFor(height: 20), child: m.Align(child: child)));Widget prefixed(Widget child) => m.Padding(padding: EdgeInsets.all(8), child: m.ConstrainedBox(constraints: BoxConstraints.tightFor(height: 20), child: m.Align(child: child)));Widget explicitNew(Widget child) => new Padding(padding: EdgeInsets.all(8), child: new ColoredBox(color: Colors.blue, child: new Align(child: child)));Widget explicitNew(Widget child) => new Padding(padding: EdgeInsets.all(8), child: new ColoredBox(color: Colors.blue, child: new Align(child: child)));Widget longChain(Widget child, dynamic matrix) => Transform(transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: ColoredBox(color: Colors.red, child: Padding(padding: EdgeInsets.all(4), child: Align(child: child))))));Widget longChain(Widget child, dynamic matrix) => Transform(transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: ColoredBox(color: Colors.red, child: Padding(padding: EdgeInsets.all(4), child: Align(child: child))))));Widget grouped(Widget child) => (Padding(padding: EdgeInsets.all(8), child: (ConstrainedBox(constraints: BoxConstraints.tightFor(height: 20), child: (Align(child: child))))));Widget grouped(Widget child) => (Padding(padding: EdgeInsets.all(8), child: (ConstrainedBox(constraints: BoxConstraints.tightFor(height: 20), child: (Align(child: child))))));Widget alignedTransform(Widget child, Matrix4 matrix) => Transform(alignment: Alignment.center, transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));Widget alignedTransform(Widget child, Matrix4 matrix) => Transform(alignment: Alignment.center, transform: matrix, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));Widget doublePadding(Widget child) => Padding(padding: EdgeInsets.all(8), child: Padding(padding: EdgeInsets.all(4), child: Align(child: child)));Widget doublePadding(Widget child) => Padding(padding: EdgeInsets.all(8), child: Padding(padding: EdgeInsets.all(4), child: Align(child: child)));Widget outerKey(Widget child, Key key) => Padding(key: key, padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child)));Valid
import 'package:flutter/material.dart';
Widget shortChain(Widget child) => Padding(padding: EdgeInsets.all(8), child: Align(child: child));
Widget wrongOrder(Widget child, dynamic matrix) => Align(child: Padding(padding: EdgeInsets.all(8), child: Transform(transform: matrix, child: child)));
Widget innerKey(Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(key: Key('keep'), constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child)));
Widget sizeFactor(Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(widthFactor: 2, child: child)));
Widget hitTests(Widget child, dynamic matrix) => Transform(transform: matrix, transformHitTests: false, child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));
Widget decorated(Widget child) => DecoratedBox(decoration: BoxDecoration(border: Border.all()), child: Padding(padding: EdgeInsets.all(8), child: Align(child: child)));
Widget shadowed(dynamic Padding, Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child)));
Widget separated(Widget child) => Padding(padding: EdgeInsets.all(8), child: Semantics(child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child))));
Widget nullableChild(Widget? child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child)));
final explicitConst = const Padding(padding: EdgeInsets.all(8), child: ColoredBox(color: Color(0xffff0000), child: Align(child: Text('x'))));
const implicitConst = Center(child: Padding(padding: EdgeInsets.all(8), child: ColoredBox(color: Color(0xffff0000), child: Align(child: Text('x')))));
final constList = const [Padding(padding: EdgeInsets.all(8), child: ColoredBox(color: Color(0xffff0000), child: Align(child: Text('x'))))];
Padding concreteType(Widget child) => Padding(padding: EdgeInsets.all(8), child: ConstrainedBox(constraints: BoxConstraints.tightFor(width: 20), child: Align(child: child)));Configure prefer-container
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"prefer-container": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/prefer-container: <reason>More style rules
- prefer-correct-callback-field-name
Match callback field names to a configured regular expression.
- prefer-correct-error-name
Require configured error parameter names in catches and SDK error callbacks.
- prefer-correct-handler-name
Match callback handler methods to a configured regular expression.
- prefer-correct-identifier-length
prefer-correct-identifier-lengthFlags declared identifiers that are shorter or longer than the allowed range.
- prefer-correct-notifier-file-nameriverpod
Requires
snake_casefile names ending in _notifier.dart for resolved Riverpod notifier classes. - prefer-correct-provider-file-nameriverpod
Requires
snake_casefile names ending in _provider.dart for resolved Riverpod provider declarations, including annotated generator functions. - prefer-correct-test-file-nametest
Requires entry-point files under package-root test/ or
integration_test/ to use the _test.dart suffix. - prefer-correct-type-name
prefer-correct-type-nameFlags type declarations whose name is not well-formed
UpperCamelCase.