Limitations
Animations
If your use cases include animations (e.g., CircularProgressIndicator
), visual comparison may not work as expected.
The visual comparison algorithm cannot accurately compare animations.
We suggest the following workarounds:
-
Adaptive animations: you might want to still enjoy your animations while running Widgetbook, but you just need to disable them when the use-case is being used in a Widgetbook-Cloud-context. To do so, you can use the following
extension
, to make your use-cases adaptive to the Widgetbook Cloud Reviews and disable the animations during the visual comparison.extension WidgetbookContext on BuildContext { /// The `preview` query parameter is used while taking snapshots of the /// use-case for Widgetbook Cloud Reviews. This getter can be used to /// customize the behavior of the use-case while taking the snapshots, /// for example, to disable animations. bool get isInWidgetbookCloud => WidgetbookState.of(this).previewMode; } @UseCase(name: 'Default', type: CircularProgressIndicator) Widget adaptiveAnimationUseCase(BuildContext context) { return CircularProgressIndicator( value: context.isInWidgetbookCloud ? 0.5 : null, ); }
-
Start animations on demand: Use a
boolean
knob to control your animations. This allows you to disable animations during visual comparison but still see them in Widgetbook.@UseCase(name: 'Default', type: CircularProgressIndicator) Widget onDemandAnimationUseCase(BuildContext context) { return CircularProgressIndicator( value: context.knobs.boolean(label: 'Static') ? 0.5 : null, ); }
Random Values
If your use case displays random values (e.g., dates) that differ across builds, visual comparison may produce noisy diffs.
We suggest the following workarounds:
-
Use a constant value instead of a random value.
@UseCase(name: 'Default', type: Text) Widget constantValueUseCase(BuildContext context) { return Text(Random().nextInt(10).toString()); return Text('10'); }
-
Use Knobs with a default value.
@UseCase(name: 'Default', type: Text) Widget constantValueUseCase(BuildContext context) { return Text(Random().nextInt(10).toString()); return Text( context.knobs.string(label: 'value', defaultValue: '10'), ); }