Build Status codecov

Compose is a Flutter library for building component-based form like user interfaces.

It simply uses a SliverList with sections and rows similar to UITableView in iOS.


Compose uses Composable's in order to build your UI. Just like everything in Flutter they are simply Widgets.

Stateful and Stateless Composables

Like there is a StatelessWidget and a StatefulWidget there are StatelessComposable and StatefulComposable. To build a Composable you need a ComposableModel which is basically a ViewModel for our Widget.

class ExampleStatelessComposableModel {
  String value;

class ExampleStatelessComposable<ExampleStatelessComposableModel>
    extends ComposableStatelessWidget {
  ExampleStatelessComposable({ExampleStatelessComposableModel composableModel, Key key})
      : super(componentModel, key: key);

  Widget build(BuildContext context) {
    return Text(composableModel.value);

Once you implemented Composable's you can use them in ComposedWidget.


To use a Composable you need to create a ComposedWidget which is a StatefulWidget itself. There are two ways you can build Composable's. Either use prepareCompose() method or just set composables array. ComposedWidgets are formed from Section's (also a Composable) and Section's are formed from Rows (yep, a Composable).

class ExamplePage extends ComposedWidget {
  State<StatefulWidget> createState() {
    return ExamplePageState();

class ExamplePageState extends ComposedWidgetState {
    // or you can override build() and just set composables = [] whenever you want
  List<Section> prepareCompose(BuildContext context) {
    var exampleComposable = ExampleComposable("My first Composable");     
    var exampleSection = (SectionComposer()..withTitle("Section Title")).compose();
    exampleSection = Section(firstSectionWidget, [button]);
    return [exampleSection];

Setting state of Composables

To modify the state of your StatefulComposable just re-set its ComposableModel.

exampleComposable.composableModel = newViewModel;

Composable Validation

Unlike StatelessComposable's StatefulComposable's can be validated. In order to validate a StatefulComposable its corresponding ComposableModel has to implement ViewModelValidateable.

class ExampleStatefulComposableModel implements ViewModelValidateable {

  bool validate(List<Validator> validators) {
	// Your custom implementation for a list of validators.

And in StatefulComposable's we use the validateable constructor with a GlobalKey.

super.validateable(composableModel, validators, GlobalKey<_State>());

You can also call validate() anytime to validate all Composable's inside your ComposedWidget.

Adding or removing Composables

If you would like to edit Sections or Rows inside your ComposedWidget there are two things you can do. First is simply re-setting the whole composables array;

composables = [firstSection, secondSection];

or you can use helper methods such as;

void appendRow({@required Section section, @required Composable composable, int index});
void removeRow({@required Section section, @required Composable composable});
void appendSection({@required  Section section, int index, SliverAnimation animation}) {
void removeSection(Section section);

Header and Footer Views

ComposedWidget takes header and footer views optionally. All you need to is prepare your Composable's and set topComposables or bottomComposables.

Composer (Optional)

Composer is just a builder for your Composable's. Just extend your class to Composer<ComposableModel> and implement compose() function. See /example for implementation details.

Future of this repo

The way SliverList and SliverPersistentHeaderDelegate works forced me into some bad design choices. I might consider creating a new custom widget more suited for a ListView with section and rows just like UITableView with proper animations and helper functions.