use-spacer-as-expanded-child

Same as use_spacer_as_expanded_child in Pyramid Lint

Group
Style
Path
lint/style/use-spacer-as-expanded-child
Default
On (recommended)
Origin
Pyramid Lint
Domain
flutter
Rule
504 of 512
recommendedflutter

Flags an Expanded wrapping an empty SizedBox or Container that should be a Spacer.

Flutter's Spacer is exactly an Expanded whose child is an empty box, so Expanded(child: SizedBox()) or Expanded(child: Container()) is a verbose spelling of Spacer(). Using Spacer states the intent — reserve flexible empty space in a Row, Column, or Flex — and drops a layer of nesting. The rule matches an Expanded whose child: constructs a Container or SizedBox with no child: argument of its own; other arguments such as color do not disqualify the match, only a nested child does. Replace it with Spacer(), moving any flex: across. Checks constructions throughout the program, including initializers and closures.

Invalid

example.dartdart
import 'package:flutter/material.dart';

// Bad: Expanded with empty Container or SizedBox

class BadLayout1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Top'),
        Expanded(
          child: Container(),
        ),
        Text('Bottom'),
      ],
    );
  }
}

class BadLayout2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Text('Left'),
        Expanded(
          child: SizedBox(),
        ),
        Text('Right'),
      ],
    );
  }
}

class BadLayout3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Text('A'),
        Expanded(
          child: Container(color: Colors.transparent),
        ),
        Text('B'),
      ],
    );
  }
}

class BadLayout4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Header'),
        Expanded(
          child: SizedBox(width: double.infinity),
        ),
        Text('Footer'),
      ],
    );
  }
}

class BadLayout5 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Icon(Icons.arrow_left),
        Expanded(
          child: Container(decoration: BoxDecoration()),
        ),
        Icon(Icons.arrow_right),
      ],
    );
  }
}
Use `Spacer()` instead of an `Expanded` with an empty `Container` or `SizedBox` child.
10 Text('Top'),
11 Expanded(
Use `Spacer()` instead of an `Expanded` with an empty `Container` or `SizedBox` child.
25 Text('Left'),
26 Expanded(
Use `Spacer()` instead of an `Expanded` with an empty `Container` or `SizedBox` child.
40 Text('A'),
41 Expanded(
Use `Spacer()` instead of an `Expanded` with an empty `Container` or `SizedBox` child.
55 Text('Header'),
56 Expanded(
Use `Spacer()` instead of an `Expanded` with an empty `Container` or `SizedBox` child.
70 Icon(Icons.arrow_left),
71 Expanded(

Valid

example.dartdart
import 'package:flutter/material.dart';

// Good: use Spacer() instead of Expanded with empty container

class GoodLayout1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text('Top'),
        const Spacer(),
        const Text('Bottom'),
      ],
    );
  }
}

class GoodLayout2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        const Text('Left'),
        const Spacer(),
        const Text('Right'),
      ],
    );
  }
}

// Good: Expanded with actual content

class GoodLayout3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        const Text('A'),
        Expanded(
          child: Container(
            color: Colors.blue,
            child: const Center(
              child: Text('Content'),
            ),
          ),
        ),
        const Text('B'),
      ],
    );
  }
}

class GoodLayout4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text('Header'),
        Expanded(
          child: ListView(
            children: const [
              ListTile(title: Text('Item 1')),
              ListTile(title: Text('Item 2')),
            ],
          ),
        ),
        const Text('Footer'),
      ],
    );
  }
}

// Good: use Spacer for spacing in column
class GoodLayout5 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text('Start'),
        const Spacer(),
        const Text('Middle'),
        const Spacer(),
        const Text('End'),
      ],
    );
  }
}

// Good: Expanded with actual widget content
class GoodLayout6 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        const Icon(Icons.arrow_left),
        Expanded(
          child: Container(
            padding: const EdgeInsets.all(8),
            child: const Text('Expanded content area'),
          ),
        ),
        const Icon(Icons.arrow_right),
      ],
    );
  }
}

// Good: use Spacer in row for spacing
class GoodLayout7 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        const Text('Left'),
        const Spacer(),
        const Text('Right'),
        const Spacer(),
        const Text('Far Right'),
      ],
    );
  }
}

final prefixedExpanded = new framework.Expanded(child: Container());
final prefixedChild = Expanded(child: new framework.Container());
final namedExpanded = Expanded.named(child: Container());
final namedChild = Expanded(child: SizedBox.named());
final populated = Expanded(child: Container(child: Text('content')));

Configure use-spacer-as-expanded-child

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "use-spacer-as-expanded-child": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/style/use-spacer-as-expanded-child: <reason>