framy_generator 0.1.6

  • Readme
  • Changelog
  • Example
  • Installing
  • new65

Framy_generator #

Example apps Acceptance tests Unit tests License: AGPL v3

A convenient code generator for app styleguide, gallery, wireframes and/or storyboard.

👉 Official documentation 👈

Packages #

In order to use Framy, you will need two following packages:

  • framy_annotation - A package containing annotation classes.
  • framy_generator - A powerful code generator which creates whole application based on the annotations used.
PackagePub
framy_annotationpub package
framy_generatorpub package

Examples #

ezgif com-video-to-gif (16)

Idea #

The idea behind Framy is to allow developers, designers, testers, managers and clients to easily access the components used in the Flutter app.

Framy is annotation-driven tool based on which you can generate:

  • a style guide describing the theme of your app
  • a component gallery showing the widgets you have written in out-of-context way
  • a playground for testing widgets with a variety of dependencies
  • and much more coming soon...

What makes Framy special? #

  • Fully responsive
    • The generated application is mobile, tablet, desktop and web friendly. Framy generates a separate main file with a separate MaterialApp but it does use the same widgets you are using in your own Flutter app.
  • Standalone
    • You can easily host generated app the way you prefer or just run it locally. (Automated hosting of Framy App is planned as well 😉)
  • Non-invasive
    • Framy doesn't require using any special widgets to be working. There is no Framy widget to wrap your app in so it doesn't affect your actual product. Only annotations.

Installation #

Get packages #

To use Framy, you will need your typical build_runner/code-generator setup.
First, install build_runner and Framy by adding them to your pubspec.yaml file:

dependencies:
  framy_annotation:

dev_dependencies:
  build_runner:
  framy_generator:

Add the @FramyApp annotation #

@FramyApp annotation is coming from framy_annotations package. It's only purpose is to specify where the Framy app should be generated. Without this, the generator will not work. There should be only one @FramyApp annotation for the project.

@FramyApp() //<--- Add this annotation
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(...);
  }
}

Run the generator #

You can either run flutter pub run build_runner build to generate the app from the current code or flutter pub run build_runner watch to keep listening to changes in the source code and update the Framy app accordingly.

Run the generated app #

Generator creates a new main file. Run flutter run lib/main.app.framy.dart to use Framy!

Annotations #

Framy Annotations package offers a variety of annotations to generate the widest variety of pages in your Framy App.

FramyTheme #

FramyTheme points out the ThemeData used in the Flutter application.

Using with ThemeData method or field

Since Framy uses the same widgets you do, it should use the same Theme as well. Use FramyTheme annotations to specify the Theme you are using. Based on that, Framy will generate your typography and color palette as well as it will use that theme for any other widget in the catalog.

@FramyTheme()
ThemeData getThemeData() => ThemeData(primarySwatch: Colors.orange);

Method annotated with FramyTheme must be public (available to use from outside the file)!

Using with custom theme class

Alternatively, you can use FramyTheme annotation with your own Theme class. If you have any colors (methods, fields, getters) defined in a class annotated with FramyTheme they will also be used in your color palette.

@FramyTheme()
 class AppTheme {
   static ThemeData get getTheme => ThemeData(primarySwatch: Colors.orange);
   Color get myAppBlack => Colors.black;
   static const myCompanyColorWhite = Color(0xFFFEFEFE);
}

There can be only one ThemeData accessor annotated in a project

FramyWidget #

Annotate your Widget classes to include them in the gallery.

Framy will generate a dependencies panel which will allow the user to pass any parameters that are defined in the Widget's constructor.

@FramyWidget()
class CounterTitle extends StatelessWidget {
  final String verb;
  final int counter;

  const CounterTitle({this.verb = 'pushed', this.counter = 0});

  @override
  Widget build(BuildContext context) {
    return Column(
      key: Key('Counter title'),
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('You have $verb the button this many times:'),
        Text('$counter', style: Theme.of(context).textTheme.headline4),
      ],
    );
  }
}

FramyModel #

Annotate your model classes to pass more complex parameters to your widgets

FramyWidget's constructor dependencies support by default only primitive types. In many cases you will pass a custom object instead of String or int. If you want to add an option to change custom dependencies, use FramyModel annotation with your model class.

@FramyModel()
class User {
  final String firstName;
  final String lastName;
  final int age;
  final List<String> emails;

  User(this.firstName, this.lastName, this.age, {this.emails});
}

You can annotate enums the same way:

@FramyModel()
enum Gender {female, male, other}

If your class uses other custom classes (e.g. Address in User), the subclasses have to be annotated with @framyModel as well

FramyPreset #

Define dependency presets to speed up testing parameters to your widgets

In cases when your models have a lot of dependencies and it would be a big hustle to click them all through, you can define a preset object models which will be accessible in dependencies panel.

@FramyPreset()
User teenageJohn() => User('John', 'Smith', 13);

Since presets will be part of your normal source code, we recommend having them in a separate file, e.g. for User presets file user.framy.dart would do. :)

FramyUseProvider #

If your widget dependency is passed by Provider and not constructor, just use @FramyUseProvider annotation

FramyUserProvider with FramyWidget will cause the generated app to pass a dependency using wrapped Provider around your widget.

@FramyUseProvider(User)
@framyWidget
class ProfilePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Consumer<User>( //<-- Framy will take care of this
      builder: (context, user, child) {
        return ...;
      },
    );
  }
}

Maintenance #

Our purpose is to make this tool as comprehensive as possible. We are trying to constantly improve it, add new features, handle new cases and fix any bugs.

If there is any use-case that we do not support and you think we should, feel free to submit an issue on GitHub. 🙂

Changelog #

[0.1.6] #

  • Added support for Riverpod dependencies #79

[0.1.5] #

  • Added option to wrap widgets with Scaffold, Center and SafeArea

[0.1.4] #

  • Fixed bug with losing state on hot reload #96
  • Fixed bug with generating theme #98
  • Framy now defaults to custom objects instead of nulls in dependency panel #97
  • Fixed bug with imports for models not annotated with FramyModel #99
  • Added support for Freezed dependencies #67

[0.1.3] #

  • Support for models with multiple constructors
  • Added usage of DevicePreview

[0.1.2] #

  • Support for List dependencies of classes annotated with @FramyModel
  • Added DropdownButton to Material Component's button page
  • Added Material Components' Toggle page
  • Added Material Components' TextField page

[0.1.1] #

  • Support for DateTime dependencies

[0.1.0] #

  • initial release

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:framy_annotation/framy_annotation.dart';

void main() {
  runApp(MyApp());
}

@FramyApp()
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: getThemeData(),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

@FramyTheme()
ThemeData getThemeData() => ThemeData(errorColor: Colors.redAccent);

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() => setState(() => _counter++);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: CounterTitle(counter: _counter),
      ),
      floatingActionButton: CounterFAB(onPressed: _incrementCounter),
    );
  }
}

@FramyWidget()
class CounterFAB extends StatelessWidget {
  final VoidCallback onPressed;

  const CounterFAB({Key key, this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      key: Key('MyCounterFAB'),
      onPressed: onPressed,
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }
}

@FramyWidget()
class CounterTitle extends StatelessWidget {
  final String verb;
  final int counter;

  const CounterTitle({Key key, this.verb = 'pushed', this.counter = 0})
      : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Column(
      key: Key('Counter title'),
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          'You have $verb the button this many times:',
        ),
        Text(
          '$counter',
          style: Theme.of(context).textTheme.headline4,
        ),
      ],
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  framy_generator: ^0.1.6

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:framy_generator/framy_generator.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
31
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
65
Learn more about scoring.

We analyzed this package on Jul 10, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.14

Analysis suggestions

Package not compatible with SDK flutter

Because it is not compatible with any of the supported runtimes: flutter-native, flutter-web

Package not compatible with runtime flutter-native on android

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/type_checker.dart that imports:
  • dart:mirrors

Package not compatible with runtime flutter-native on ios

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/type_checker.dart that imports:
  • dart:mirrors

Package not compatible with runtime flutter-native on linux

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/type_checker.dart that imports:
  • dart:mirrors

Package not compatible with runtime flutter-native on macos

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/type_checker.dart that imports:
  • dart:mirrors

Package not compatible with runtime flutter-native on windows

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/type_checker.dart that imports:
  • dart:mirrors

Package not compatible with runtime flutter-web on web

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/utils.dart that imports:
  • package:build/build.dart that imports:
  • package:build/src/generate/run_post_process_builder.dart that imports:
  • package:build/src/builder/post_process_builder.dart that imports:
  • package:build/src/builder/builder.dart that imports:
  • package:build/src/builder/build_step.dart that imports:
  • package:build/src/asset/reader.dart that imports:
  • package:glob/glob.dart that imports:
  • package:glob/src/list_tree.dart that imports:
  • package:glob/src/io.dart that imports:
  • package:glob/src/io_export.dart that imports:
  • dart:io

Package not compatible with runtime js

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/utils.dart that imports:
  • package:build/build.dart that imports:
  • package:build/src/generate/run_post_process_builder.dart that imports:
  • package:build/src/builder/post_process_builder.dart that imports:
  • package:build/src/builder/builder.dart that imports:
  • package:build/src/builder/build_step.dart that imports:
  • package:build/src/asset/reader.dart that imports:
  • package:glob/glob.dart that imports:
  • package:glob/src/list_tree.dart that imports:
  • package:glob/src/io.dart that imports:
  • package:glob/src/io_export.dart that imports:
  • dart:io

Package not compatible with runtime native-aot

Because:

  • package:framy_generator/framy_generator.dart that imports:
  • package:source_gen/source_gen.dart that imports:
  • package:source_gen/src/type_checker.dart that imports:
  • dart:mirrors

Health suggestions

Fix lib/json_builder.dart. (-0.50 points)

Analysis of lib/json_builder.dart reported 1 hint:

line 112 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

Format lib/generator/text_field_generator.dart.

Run dartfmt to format lib/generator/text_field_generator.dart.

Format lib/generator/toggle_page_generator.dart.

Run dartfmt to format lib/generator/toggle_page_generator.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
analyzer >=0.39.11 <0.40.0 0.39.12
build ^1.3.0 1.3.0
framy_annotation ^0.1.2 0.1.2
glob ^1.2.0 1.2.0
source_gen ^0.9.5 0.9.6
Transitive dependencies
_fe_analyzer_shared 5.0.0
args 1.6.0
async 2.4.2
charcode 1.1.3
collection 1.14.13 1.15.0-nullsafety
convert 2.1.1
crypto 2.1.5
csslib 0.16.1
dart_style 1.3.6
html 0.14.0+3
js 0.6.2
logging 0.11.4
meta 1.2.2 1.3.0-nullsafety
node_interop 1.1.1
node_io 1.1.1
package_config 1.9.3
path 1.7.0
pedantic 1.9.2
pub_semver 1.4.4
source_span 1.7.0
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.2.0 1.3.0-nullsafety
watcher 0.9.7+15
yaml 2.2.1
Dev dependencies
build_runner ^1.10.0
mockito any
source_gen_test
test any