Flutter – Widgetbook (Storybook)

Component driven design is a great way to safe guard your brand/s and make it easy to quickly develop new screens and UI experiences from existing components, or to build new ones.

It was made popular by Storybook.js for good reasons:

  • Prevents the same components from been rebuilt in different parts of the UI.
  • Provides a toolbox of components, a bit like Lego.
  • Components can be built and modified in isolation so they are not affected by flakey date, business logic or unfinished UI’s
  • Makes it easy to focus on difficult use cases
  • Allows for collaboration with the design team and other stakeholders

Flutter is less mature than React and there is no clear alternative to storybook.

After a little research I selected Widgetbook because it is been actively developed and used.

Flutter gems storybook

Widgetbook
Widgetbook

And followed their instructions set it up in the new components project DigestableLego.

Ta Da

Widgetbook in action

Xp

Widgetbook Approach

I decide to use the widget book generator rather than the manual approach to avoid having to setup:

  • Categories
  • Folders
  • Widgets
  • Use cases
Widgetbook Manual Configuration Example
Widgetbook Manual Configuration Example

When you use the generator you just need to write the use cases and annotate them.

@WidgetbookUseCase(name: 'List', type: DlList)

There is a little more upfront, you need to add config for the Widgetbook application and for themes using two other annotations:

  • @WidgetbookApp
  • @WidgetbookTheme

Widgetbook Setup

I added Widgetbook to the /example project because it needs the macOS applications files to run and it meant that the examples created by the package code be reused by the scenarios.

I started by adding the package references for the generator recommend by the Widgetbook.

Then the App widget and annotated it with @WidgetbookApp.

// Flutter imports:
import 'package:flutter/cupertino.dart';

// Package imports:
import 'package:widgetbook_annotation/widgetbook_annotation.dart';

@WidgetbookApp.cupertino(
  name: 'Digestable Lego',
  devices: [
    Apple.iPhone13Mini, Apple.iPhone13, Apple.iPhone13Pro, Apple.iPhone13ProMax
  ],
  textScaleFactors: [
    1,
    2,
    3,
  ],
  foldersExpanded: true,
  widgetsExpanded: true,
)
class CupertionApplication extends StatelessWidget {
  const CupertionApplication({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

And the first use case:

// Flutter imports:
import 'package:flutter/cupertino.dart';

// Package imports:
import 'package:digestable_lego/widget/dl_list.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';

// Project imports:
import 'package:example/dl_list.dart';

@WidgetbookUseCase(name: 'List', type: DlList)
Widget listItemRecipe(BuildContext context) {
  return const CupertinoPageScaffold(
    navigationBar: CupertinoNavigationBar(
      middle: Text(
        "Example List Items",
      ),
    ),
    child: DlListExample(),
  );
}

Next I ran the builder:

flutter pub run build_runner build

// Optionally to automatically rerun when files change
flutter pub run build_runner watch

That generated the .widgetbook.dart file.

Widgetbook files
Widgetbook files

Then just run it:

flutter run -t lib/widgetbook/cupertino_application.widgetbook.dart -d macos

To make this step easier I added it as a new launch agent.

Widgetbook launch agent
Widgetbook launch agent

Widgetbook Themes

To support themes in widget book I had moved them to the DigestableLego package, they could potentially become their own package if the code and assets grows.

Upgrade a Git package

Whenever we make changes to DigestableLego and want to use those changes in DigestableMe, we need to update the package from the git repository.

To do this run

flutter pub upgrade digestable_lego
pub upgrade Digestable Lego
pub upgrade Digestable Lego

BackBurner

MaterialApp support for Widgetbook

The Widgetbook application runs widgets in a CupertinoApp, you get to choose as part of the application config.

@WidgetbookApp.cupertino

I would like a version of Widgetbook for Android devices, Ideally widget book would allow a dynamic switch of application types.

There does not seem an easy way to make @WidgetbookTheme work with both Material and Cupertino Apps in the same application so even if I have two @WidgetbookApp configurations each picks up all the @WidgetbookTheme themes and then one configuration complains that the ThemeData is the wrong type.

Excluding unused import warnings on generated files

Unable to ignore unused import warnings for the widget book generated file cupertino_application.widgetbook.dart

I was able to exclude other linting rules in the analysis_options.yaml file.

ignore:
      - lib/widgebook/cupertino_application.widgetbook.dart

Sound & Vision

One flew over the cuckoo's nest

Links

Please follow and like us:

Leave a Reply

Your email address will not be published.