Complete Example
Let's add two more components, CustomCard
and CustomTextField
, with different use
cases for manual and generator approaches.

Folder structure
lib/
├── components/
│ ├── container.dart
│ ├── custom_card.dart
│ └── custom_text_field.dart
├── widgetbook_generator.dart (for generator approach)
├── widgetbook_generator.g.dart (will be generated eventually)
└── widgetbook.dart (for manual approach)
CustomCard Component
Create a file named custom_card.dart
in the lib/components
directory and add the
following code:
// lib/components/custom_card.dart
import 'package:flutter/material.dart';
class CustomCard extends StatelessWidget {
final Widget child;
final Color backgroundColor;
final double borderRadius;
const CustomCard({
Key? key,
required this.child,
this.backgroundColor = Colors.white,
this.borderRadius = 8.0,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
color: backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius),
),
child: child,
);
}
}
CustomTextField Component
Create a file named custom_text_field.dart
in the lib/components
directory and add the
following code:
// lib/components/custom_text_field.dart
import 'package:flutter/material.dart';
class CustomTextField extends StatelessWidget {
final TextEditingController controller;
final String hintText;
const CustomTextField({
Key? key,
required this.controller,
this.hintText = '',
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
controller: controller,
decoration: InputDecoration(
hintText: hintText,
border: const OutlineInputBorder(),
),
);
}
}
Add components
Update the lib/widgetbook.dart
file to add the new components and their use-cases:
- Update the
lib/components/custom_card.dart
andlib/components/custom_text_field.dart
files to add the@UseCase
annotation for the new components:
// lib/components/custom_card.dart
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;
/// ... [Rest of the code]
@widgetbook.UseCase(
name: 'Default Style',
type: CustomCard,
)
CustomCard defaultCustomCard(BuildContext context) {
return const CustomCard(
child: Text('This is a custom card'),
);
}
@widgetbook.UseCase(
name: 'With Custom Background Color',
type: CustomCard,
)
CustomCard customBackgroundCustomCard(BuildContext context) {
return CustomCard(
backgroundColor: Colors.green.shade100,
child: const Text('This is a custom card with a custom background color'),
);
}
// lib/components/custom_text_field.dart
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;
/// ... [Rest of the code]
@widgetbook.UseCase(
name: 'Default Style',
type: CustomTextField,
)
CustomTextField defaultCustomTextField(BuildContext context) {
return CustomTextField(
controller: TextEditingController(),
);
}
@widgetbook.UseCase(
name: 'With Hint Text',
type: CustomTextField,
)
CustomTextField hintTextCustomTextField(BuildContext context) {
return CustomTextField(
controller: TextEditingController(),
hintText: 'Enter your text here',
);
}
Then update widgetbook_generator.dart
to include @App
annotation:
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;
// import generated directories
import 'widgetbook_generator.g.dart';
void main() {
runApp(const WidgetbookApp());
}
// use @App annotation
@widgetbook.App()
class WidgetbookApp extends StatelessWidget {
const WidgetbookApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Widgetbook.material(
// Use the generated directories variable
directories: directories,
addons: [],
);
}
}
-
run
flutter pub run build_runner build
; -
run
flutter run -d chrome -t lib/widgetbook_generator.dart
See source code