Theme Addon

The Theme Addon lets you inject a theme widget into your tree, to make your use-cases styled and try them out with different themes. There are 3 different variants of the Theme Addon, which depend on the theme data and widget you use in your application:

AddonTheme DataInherited Widget
MaterialThemeAddonThemeDataTheme
CupertinoThemeAddonCupertinoThemeDataCupertinoTheme
ThemeAddonCustomCustom

Usage

Material Theme

If your app is built using MaterialApp, then you are probably using ThemeData to define your themes. Then MaterialThemeAddon is the right choice for you.

widgetbook/lib/main.dart
import 'package:my_app/themes.dart'; // For AppThemes
import 'package:widgetbook/widgetbook.dart';

class WidgetbookApp extends StatelessWidget {
  const WidgetbookApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Widgetbook.material(
      // ...
      addons: [
        MaterialThemeAddon( 
          themes: [ 
            WidgetbookTheme( 
              name: 'Light', 
              data: AppThemes.light(), 
            ), 
            WidgetbookTheme( 
              name: 'Dark', 
              data: AppThemes.dark(), 
            ), 
          ], 
        ), 
      ],
    );
  }
}

Cupertino Theme

If your app is built using CupertinoApp, then you are probably using CupertinoThemeData to define your themes. Then CupertinoThemeAddon is the right choice for you.

widgetbook/lib/main.dart
import 'package:my_app/themes.dart'; // For AppThemes
import 'package:widgetbook/widgetbook.dart';

class WidgetbookApp extends StatelessWidget {
  const WidgetbookApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Widgetbook.cupertino(
      // ...
      addons: [
        CupertinoThemeAddon( 
          themes: [ 
            WidgetbookTheme( 
              name: 'Light', 
              data: AppThemes.light(), 
            ), 
            WidgetbookTheme( 
              name: 'Dark', 
              data: AppThemes.dark(), 
            ), 
          ], 
        ), 
      ],
    );
  }
}

Custom Theme

If you have a custom theme data and widget or you have a custom logic to build your theme, then ThemeAddon is the right choice for you.

widgetbook/lib/main.dart
import 'dart:ui';
import 'package:my_app/theme.dart'; // For AppTheme
import 'package:my_app/themes.dart'; // For AppThemes
import 'package:widgetbook/widgetbook.dart';

class WidgetbookApp extends StatelessWidget {
  const WidgetbookApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Widgetbook(
      // ...
      addons: [
        ThemeAddon<AppThemeData>( 
          themes: [ 
            WidgetbookTheme( 
              name: 'Light', 
              data: AppThemes.light(), 
            ), 
            WidgetbookTheme( 
              name: 'Dark', 
              data: AppThemes.dark(), 
              ), 
            ), 
          ], 
          themeBuilder: (context, theme, child) { 
            // Wrap use cases with the custom theme's InheritedWidget
            return AppTheme( 
              data: theme, 
              child: child, 
            ); 
          }, 
        ), 
      ],
    );
  }
}

Order

Since the order of addons matters, here are some guidelines to follow when using the ThemeAddon:

Addons that should come before the ThemeAddon:

  • ViewportAddon
  • DeviceFrameAddon

Multi-snapshot Support

The ThemeAddons are supported in the Multi Snapshot Reviews via the ThemeAddonConfig. Here's how to configure it:

widgetbook/lib/main.dart
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';

@App(
  cloudAddonsConfigs: {
    'Light': [
      ThemeAddonConfig('Light'), 
    ],
    'Dark': [
      ThemeAddonConfig('Dark'), 
    ],
  },
)
class WidgetbookApp extends StatelessWidget {
  const WidgetbookApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Widgetbook(
      // ...
      addons: [
        // Your theme addon of choice here...
      ],
    );
  }
}