Widgetbookとは?
Widgetbookとは名前からも想像できるとおり、FlutterのWidgetをカタログのように確認することができるライブラリです。
以下のようにブラウザでSimulatorと同じ画面を確認したり、設定によっては各デバイスごとのレイアウトやテーマ別の見た目を簡単に確認することができます。
ホットリロードにも対応しているようですね。
簡単なサンプルも作ってみたので気になる方はクローンして実際に動かして見て下さい。
https://github.com/Ryota-Nakamura-317/flutter_widgetbook_sample
手順
簡単に流れを説明します。
ライブラリの追加
dependencies:
widgetbook: ^2.4.1
フォルダの追加
main.dartの作成
先程のwidgetbook
配下にmain.dart
を追加します。
devices
には結構いろんな種類のデバイスを予め選択することができます。
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_sample/theme.dart';
import 'components.dart';
void main() {
runApp(
const WidgetBookHotReload(),
);
}
class WidgetBookHotReload extends StatelessWidget {
const WidgetBookHotReload({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Widgetbook.material( // appInfo, themes, cateforiesがrequired
appInfo: AppInfo(name: 'WidgetBook'),
devices: const [ // ここでいろんなデバイスの指定が可能
Apple.iPhone13Mini,
Samsung.s21ultra,
Desktop.desktop1080p,
],
themes: [],
categories: [],
);
}
}
これでセットアップ完了。
画面作成
widgetbook
に反映させるために適当な画面を作成します。
import 'package:flutter/material.dart';
import 'package:widgetbook_sample/theme.dart';
import 'package:widgetbook_sample/widgets.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'WidgetBook',
theme: lightTheme,
darkTheme: darkTheme,
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('WidgetBook'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircleWidget(), // component
SizedBox(height: 12),
ButtonWidget(), // component
],
),
),
);
}
}
Widgetbookでテーマ切り替えの状態が確認できるように以下のようにテーマも定義しました。
import 'package:flutter/material.dart';
ThemeData get lightTheme {
final base = ThemeData(
colorScheme: const ColorScheme.light(),
useMaterial3: true,
);
return base;
}
ThemeData get darkTheme {
final base = ThemeData(
colorScheme: const ColorScheme.dark(),
useMaterial3: true,
);
return base;
}
componentは以下の簡単なWidgetを用意。
import 'package:flutter/material.dart';
class CircleWidget extends StatelessWidget {
const CircleWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.amber,
),
child: const Center(child: Text('circle')),
);
}
}
class ButtonWidget extends StatelessWidget {
const ButtonWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {},
child: const Text('button'),
);
}
}
Widgetbookに追加
では、これらをWidgetbookに反映させていきます。
先程のwidgetbook/main.dart
にthemeとcategoryの追加をしました。
categoryはWidgetbookで左側のメニューにカテゴリとして表示されます。
class WidgetBookHotReload extends StatelessWidget {
const WidgetBookHotReload({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Widgetbook.material(
appInfo: AppInfo(name: 'WidgetBook'),
devices: const [
Apple.iPhone13Mini,
Samsung.s21ultra,
Desktop.desktop1080p,
],
themes: [ // theme追加
WidgetbookTheme(
name: 'light',
data: lightTheme,
),
WidgetbookTheme(
name: 'dark',
data: darkTheme,
),
],
categories: [ // category追加
WidgetbookCategory(
name: 'Screen',
widgets: [
screenComponent,
],
),
WidgetbookCategory(
name: 'Widgets',
widgets: [
widgetsComponent,
],
),
],
);
}
}
このあたりの運用はプロジェクトごとでやりやすいように決めるといいかもしれません。
categories
にはWidgetbookCategory
を配列で定義し、WidgetbookCategory
内のwidgetsにコンポーネントを渡します。以下コンポーネントです。
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_sample/main.dart';
import 'package:widgetbook_sample/widgets.dart';
final screenComponent = WidgetbookComponent(
name: 'screen',
useCases: [
WidgetbookUseCase(
name: 'MyHomePage',
builder: (_) => const MyHomePage(),
),
],
);
final widgetsComponent = WidgetbookComponent(
name: 'widgets',
useCases: [
WidgetbookUseCase.center(
name: 'Circle',
child: const CircleWidget(),
),
WidgetbookUseCase.center(
name: 'Button',
child: const ButtonWidget(),
),
],
);
WidgetBookComponent
を定義しuseCases
にWidgetbookUseCase
を配列で定義していきます。
WidgetbookUseCase
のbuilderに今回作成した画面を、WidgetbookUseCase.center
はwidgetbookで勝手に中心配置してくれるWidgetなのでこちらの場合はchildに切り出したWidgetを定義していきます。
さて、ここまでできたらwidgetbook/main.dart
をビルドします。
widgetbook/main.dart
をビルド
ビルドすると以下のような画面が立ち上がります。
左側には、WidgetbookCategory/WidgetbookComponent/WidgetbookUseCase
の順でディレクトリが表示されおり、
右側には、テーマの変更やデバイスの変更などがボタンひとつで操作できるパネルがあります。
ボタン
円
画面
こんな感じで左側ディレクトリをポチポチするだけで見た目がどんなものなのかを確認できます。
ダークモードもワンクリックで確認可能。
さいごに
以上、Widgetbookの紹介でした。
導入により一手間増えますが、デザインの確認はとてもしやすくなるなと感じました。
参考