Customization
Root Widget
All use-cases are wrapped in an root widget (i.e. an App widget) to provide a context for the use-cases to render in.
RootWidget
└── Addon 1
└── Addon 2
└── UseCaseRenderer
└── UseCase
└── Widget
Here are the available constructors for the root widgets:
| Constructor | Root Widget |
|---|---|
Widgetbook.material | MaterialApp |
Widgetbook.cupertino | CupertinoApp |
Widgetbook | Custom Widget |
You can use a custom root widget by providing an appBuilder function to the Widgetbook constructor.
This is helpful if you need to wrap your app widget (i.e. MaterialApp, CupertinoApp) with a custom widget.
If you want to wrap your use-case in a custom widget, you can also use the Addons API, which provides some more flexibility.
@override
Widget build(BuildContext context) {
return Widgetbook(
// ...
appBuilder: (context, child) {
return AwesomePackage(
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: child,
)
);
}
);
}
Use-cases Navigation Path
By default, use-cases has a navigation path in Widgetbook that is based on where their component file is located. There are multiple ways to customize the navigation path either globally or locally.
The component name (e.g. Button) and the use-case name (e.g. Primary) are
concatenated at the end of the path.
[ Nav Path ] / [ Component Name ] / [ Use-case Name ]
Using nav_path_mode option
You can globally change the behavior of the navigation path generation for all use-cases by providing a nav_path_mode option in build.yaml as follows:
| Option Value | Navigation Path Based on |
|---|---|
component (default) | The component (i.e. Widget) file. |
use-case | The use-case file (i.e. where the @UseCase annotation is used) |
targets:
$default:
builders:
widgetbook_generator:use_case_builder:
options:
nav_path_mode: use-case
Using @UseCase.path parameter
To provide a custom navigation path for a single use-case, you can use the path parameter in the @UseCase annotation.
import 'package:your_app/widgets/button.dart';
// Navigation path: `widgets/Button/Primary`
@widgetbook.UseCase(
name: 'Primary',
type: Button
)
Widget buildPrimaryButton() {
return Button();
}
If you wrap a folder name in square brackets, it will be treated as a category in the navigation path.
import 'package:your_app/components/button.dart';
// Navigation path: `[Interactions]/buttons/Button/Primary`
@widgetbook.UseCase(
name: 'Primary',
type: Button,
path: '[Interactions]/buttons',
)
Widget buildPrimaryButton() {
return Button();
}
Initial Route
Initial routes can be used to pick the home page that is used on first launch by providing a initialRoute parameter to the Widgetbook constructor.
To easily get the exact route for a use-case, run your Widgetbook project on
web, and copy the value of the URL, then paste it as the value of the
initialRoute parameter.
@override
Widget build(BuildContext context) {
return Widgetbook(
initialRoute: '?path=introduction/home-use-case',
// ...
);
}
Home Widget
The home widget is a widget that is shown on startup when no use-case is selected.
This widget does not inherit from the appBuilder or the addons;
Meaning that if Theme.of(context) is called inside this widget, then it will use Widgetbook's lightTheme or darkTheme,
and not the Theme from the appBuilder or the ThemeAddon.
@override
Widget build(BuildContext context) {
return Widgetbook(
home: const MyCustomHomeWidget(),
// ...
);
}
Header Widget
You can add a custom header to the navigation panel by providing a header parameter to the Widgetbook constructor.
This can be used for branding or additional information.
@override
Widget build(BuildContext context) {
return Widgetbook(
header: const MyCustomHeaderWidget(),
// ...
);
}
Widgetbook's UI
If you want to change some Widgetbook's UI colors, or want to enforce a specific theme mode, you can do so using these parameters:
| Parameter | Description |
|---|---|
lightTheme | ThemeData that is used when themeMode is ThemeMode.light |
darkTheme | ThemeData that is used when themeMode is ThemeMode.dark. |
themeMode | Controls which ThemeMode to use. Defaults to ThemeMode.system. |
@override
Widget build(BuildContext context) {
return Widgetbook(
lightTheme: ThemeData.light(), // Custom light theme
darkTheme: ThemeData.dark(), // Custom dark theme
themeMode: ThemeMode.light, // Forcing light mode
// ...
);
}

