storybook_ds 1.2.5
storybook_ds: ^1.2.5 copied to clipboard
Storybook Uma forma de apresentar os componentes de qualquer Design System
Storybook Design System #
Flutter package to build a storybook for your Design System: attribute panel, live preview, and generated code snippet.
Live demo: showroom-ds.web.app
Reference implementation: example/lib/ — especially custom_card_storybook.dart and main.dart.
Install #
flutter pub add storybook_ds
dependencies:
flutter:
sdk: flutter
storybook_ds: ^1.2.5
import 'package:storybook_ds/storybook_ds.dart';
Step-by-step: add a story screen #
This follows the same structure as the CustomCard example.
1. Host the story in your app #
Wrap the story with MaterialApp. If the story can change the global theme, keep ThemeData in state (see main.dart):
home: MyWidgetStorybook(
onThemeChanged: (ThemeData next) {
setState(() => _appTheme = next);
},
),
2. Create the story StatefulWidget #
class MyWidgetStorybook extends StatefulWidget {
const MyWidgetStorybook({super.key, required this.onThemeChanged});
final ValueChanged<ThemeData> onThemeChanged;
@override
Storybook<MyWidgetStorybook> createState() => _MyWidgetStorybookState();
}
3. State extends Storybook<...> #
Implement:
| Member | Purpose |
|---|---|
String get title |
Panel title |
String get description |
Short description |
String get nameObjectInDisplay |
Class name in the code snippet (e.g. CustomCard) |
List<AttributeDto> attributes |
Panel controls |
Widget buildComponentWidget(BuildContext) |
Widget shown in the preview |
Minimal getters:
@override
String get title => 'My widget';
@override
String get description => 'Short description for DS consumers.';
@override
String get nameObjectInDisplay => 'MyWidget';
4. Define attributes #
Each AttributeDto is one control. name is the key for getWhereAttribut('name').
Use factories where useful: AttributeDto.enumType, AttributeDto.rangeDoubleInterval, AttributeDto.objectInObject, StorybookAttributeFactories.factoryAttributeDtoString, etc.
5. The builders field #
A list of strings saying which constructors/factories include that attribute:
| Value | Meaning |
|---|---|
'' |
Default (unnamed) constructor |
'inline', 'outline', … |
Same labels you compare against selectedConstructor |
Use '', not null, for the default.
If you omit builders, many factories default to [''] (default constructor only).
Tip: file-level constants avoid typos, as in the example:
const _all = ['', 'inline', 'outline'];
const _defaultOnly = [''];
Attributes that exist only on the default constructor use builders: _defaultOnly.
6. Implement buildComponentWidget #
- Read values with
getWhereAttribut('attributeName')(cast when needed). - Branch on
selectedConstructor:selectedConstructor.isEmpty→ default constructor (same as''inbuilders).selectedConstructor == 'inline'→ named factoryinline, etc.
Same pattern as the example:
@override
Widget buildComponentWidget(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (selectedConstructor.isEmpty) _buildDefault(),
if (selectedConstructor == 'inline') _buildInline(),
if (selectedConstructor == 'outline') _buildOutline(),
],
),
),
);
}
Optional helper: T? _knob<T>(String name) => getWhereAttribut(name) as T?;
7. Optional themes (MultipleThemeSettings) #
Assign multipleThemeSettings in initState (field is provided by base Storybook):
@override
void initState() {
super.initState();
multipleThemeSettings = MultipleThemeSettings(
selectableThemes: [
ThemeSettings(
title: 'Light / dark',
light: ThemeData.light(useMaterial3: true),
dark: ThemeData.dark(useMaterial3: true),
),
],
);
}
Forward the chosen theme in onUpdateTheme:
@override
void onUpdateTheme(MultipleThemeSettings settings) {
widget.onThemeChanged(settings.selectedThemes.currentTheme());
}
Nested objects in the panel #
For AttributeDto.objectInObject, pass merge: (instance, fieldName, newValue) returning the updated object. Implement by hand or generate with @StorybookModel() and storybook_ds_builder (see example/build.yaml and builder/).
No reflectable #
This package does not use reflectable. Build your AttributeDto list manually (or generate only the merge helper). See CHANGELOG.md.
Reflection-free code generation (optional) #
Flutter has no dart:mirrors on mobile/web. For merge helpers:
- Add
storybook_ds_builder+build_runnerasdev_dependencies. - Restrict
build.yamlgenerate_forto files with@StorybookModel(seeexample/build.yaml). - Annotate plain data classes, add
part '*.storybook.g.dart', rundart run build_runner build --delete-conflicting-outputs. - Wire
mergeMyModelintoAttributeDto.objectInObject.
If pub get fails between build_runner and the builder, pin build_runner: 2.4.13 like example/pubspec.yaml.
Cheat sheet #
StatefulWidget→State extends Storybook<T>.- Implement
title,description,nameObjectInDisplay,attributes,buildComponentWidget. builders:''= default; other strings = same tokens asselectedConstructor.getWhereAttribut+selectedConstructor.isEmpty/== 'name'.- Themes:
initState+onUpdateThemewhen needed.