widget_chain 0.1.0

Flutter Android iOS web

Get rid of the nested hell

widget_chain #

Get rid of the nested hell with shiny extensions, now!

Chain programming, not widget nesting constructors.

Container buildItem(String name) {
  return Icon(Icons.phone)
    .addNeighbor(Text(name))
    .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
    .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),);
}

Story #

If you've ever written anything like this:

/// do you love nested hell?
class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo'),),
      body: Container(
        child: Offstage(
          offstage: false,
          child: ListView(
            children: <Widget>[
              Container(
                color: Colors.white,
                padding: EdgeInsets.all(20),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Icon(Icons.phone),
                    Text("amy"),
                  ],
                ),
              ),
              Container(
                color: Colors.white,
                padding: EdgeInsets.all(20),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Icon(Icons.phone),
                    Text("billy"),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

to resolve nested hell, maybe you will extract a build method, then it looks like:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo'),),
      body: Container(
        child: Offstage(
          offstage: false,
          child: ListView(
            children: <Widget>[
              buildItem("amy"),
              buildItem("billy"),
            ],
          ),
        ),
      ),
    );
  }

  Container buildItem(String name) {
    return Container(
      color: Colors.white,
      padding: EdgeInsets.all(20),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Icon(Icons.phone),
          Text(name),
        ],
      ),
    );
  }
}

Use widget_chain can replace constructors by an intoXxx() function calling.

The code looks like:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo'),),
      body: Container(
        child: Offstage(
          offstage: false,
          child: ListView(
            children: <Widget>[
              buildItem("amy"),
              buildItem("billy"),
            ],
          ),
        ),
      ),
    );
  }

  Container buildItem(String name) {
    return Icon(Icons.phone)
        .addNeighbor(Text(name))  //the widget(Icon) add a neighbor (Text) and returns a List<Widget>
        .intoRow(crossAxisAlignment: CrossAxisAlignment.center,) // make the List<Widget> as the children of Row, and then returns the Row widget
        .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),) // make the Row as the child of Container, and then returns the Container widget
        ;  
  }
}
Click to show more...

or like this:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo'),),
      body: Container(
        child: Offstage(
          offstage: false,
          child: ListView(
            children: WidgetChain
              .addNeighbor(buildItem("amy"),)
              .addNeighbor(buildItem("billy"),),
          ),
        ),
      ),
    );
  }

  Container buildItem(String name) {
    return Icon(Icons.phone)
        .addNeighbor(Text(name))
        .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
        .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),);
  }
}

or like this:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo'),),
      body: Container(
        child: Offstage(
          offstage: false,
          child: WidgetChain
            .addNeighbor(buildItem("amy"),)
            .addNeighbor(buildItem("billy"),)
            .intoListView(),
        ),
      ),
    );
  }

  Container buildItem(String name) {
    return Icon(Icons.phone)
        .addNeighbor(Text(name))
        .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
        .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),);
  }
}

or like this:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo'),),
      body: Container(
        child: WidgetChain
           .addNeighbor(buildItem("amy"),)
           .addNeighbor(buildItem("billy"),)
           .intoListView()
           .intoOffstage(offstage: false,),
      ),
    );
  }

  Container buildItem(String name) {
    return Icon(Icons.phone)
        .addNeighbor(Text(name))
        .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
        .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),);
  }
}

or like this:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Demo'),),
        body: WidgetChain
              .addNeighbor(buildItem("amy"),)
              .addNeighbor(buildItem("billy"),)
              .intoListView()
              .intoOffstage(offstage: false)
              .intoContainer()
    );
  }

  Container buildItem(String name) {
    return Icon(Icons.phone)
        .addNeighbor(Text(name))
        .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
        .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),);
  }
}

use buildAllAsWidget extension of List<T>, it looks like this:

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var list = ["amy", "billy"]
            .buildAllAsWidget((name) =>
              Icon(Icons.phone)
              .addNeighbor(Text(name))
              .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
              .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),)
            );
    return Scaffold(
        appBar: AppBar(title: Text('Demo'),),
        body: list.intoListView()
            .intoOffstage(offstage: false)
            .intoContainer()
    );
  }
}
class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Demo'),),
        body: ["amy", "billy"]
            .buildAllAsWidget((name) =>
              Icon(Icons.phone)
              .addNeighbor(Text(name))
              .intoRow(crossAxisAlignment: CrossAxisAlignment.center,)
              .intoContainer(color: Colors.white, padding: EdgeInsets.all(20),)
            )
            .intoListView()
            .intoOffstage(offstage: false)
            .intoContainer()
    );
  }
}

Getting Started #

dependencies:
  widget_chain: ^0.1.0

Usage #

import 'package:widget_chain/widget_chain.dart';

for Widget:

return widgetA.intoBbb(parmas);

equivalent as:

return Bbb(
  params,
  child: widgetA,
);

for List<Widget>:

return widgetListC.intoDdd(parmas);

equivalent as:

return Ddd(
  params,
  children: widgetListC,
);