A code generator to write widgets as function without loosing the benefits of classes.
Clone or download
Latest commit f1e678e Jan 13, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
code_gen_tester feature: generate overrides of debugFillPropertiesThis features allow… Jan 13, 2019
functional_widget readme Jan 13, 2019
functional_widget_annotation 0.3.0 (#13) Jan 1, 2019
tool quality (#4) Dec 3, 2018
.gitignore quality (#4) Dec 3, 2018
.travis.yml quality (#4) Dec 3, 2018
README.md add Awesome Flutter badge Jan 2, 2019

README.md

Build Status pub package pub package

Widgets are cool. But classes are quite verbose:

class Foo extends StatelessWidget {
  final int value;
  final int value2;

  const Foo({Key key, this.value, this.value2}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text('$value $value2');
  }
}

So much code for something that could be done much better using a plain function:

Widget foo(BuildContext context, { int value, int value2 }) {
  return Text('$value $value2');
}

The problem is, using functions instead of classes is not recommended:

... Or is it?


Introducing functional_widgets, a code generator that generates widget classes from functions.

Simply write your widget as a function, decorate it with a @widget, and then this library will generate a class for you to use.

Example

You write:

@widget
Widget foo(BuildContext context, int value) {
  return Text('$value');
}

It generates:

class Foo extends StatelessWidget {
  final int value;

  const Foo(this.value, {Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return foo(context, value);
  }
}

And then you use it:

runApp(
    Foo(42)
);

How to use

Install

There are a few separate packages you need to install:

  • functional_widget_annotation, a package containing decorators. You must install it as dependencies.
  • functional_widget, a generator that uses the decorators from the previous packages to generate your widget. Install it as dev_dependencies
  • build_runner, a tool that is able to run code-generators. Install it as dev_dependencies
dependencies:
  functional_widget_annotation: 0.1.0

dev_dependencies:
  functional_widget: 0.2.2
  build_runner: 1.1.2

Run the generator

To run the generator, you must use build_runner cli:

flutter pub pub run build_runner watch

All the potential syntaxtes

functional_widget will inject widget specific parameters if you ask for them. You can potentially write any of the following:

Widget foo();
Widget foo(BuildContext context);
Widget foo(Key key);
Widget foo(BuildContext context, Key key);
Widget foo(Key key, BuildContext context);

You can also replace BuildContext by HookContext from https://github.com/rrousselGit/flutter_hooks

You can then add however many arguments you like after the previously defined arguments. They will then be added to the class constructor and as a widget field:

  • positional
@widget
Widget foo(int value) => Text(value.toString());

// USAGE

new Foo(42);
  • named:
@widget
Widget foo({int value}) => Text(value.toString());

// USAGE

new Foo(value: 42);
  • A bit of everything:
@widget
Widget foo(BuildContext context, int value, { int value2 }) {
  return Text('$value $value2')
}

// USAGE

new Foo(42, value2: 24);