Skip to content

Commit

Permalink
feat: Widgetbook hot reload (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
thelukewalton authored Mar 5, 2024
1 parent 36a60e7 commit 44b8f98
Show file tree
Hide file tree
Showing 26 changed files with 835 additions and 1,174 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ Zeta is the new, formal, standardized Zebra Design System based off the successe

> 🚧 **Note**: This package is in pre-release, and so many aspects are incomplete.
### Prerequisites

```
dart sdk: ">=3.2.0 <4.0.0"
flutter: ">=3.16.0"
```

## Installation

To install `zeta_flutter`, follow the instructions [here](https://pub.dev/packages/zeta_flutter/install).
Expand Down
14 changes: 7 additions & 7 deletions example/lib/pages/components/progress_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ class ProgressExampleState extends State<ProgressExample> {
SizedBox(
height: 20,
),
Wrapper(stepsCompleted: 0, type: ZetaBarType.standard, isThin: false, stateChangeable: true),
Wrapper(stepsCompleted: 0, type: ZetaProgressBarType.standard, isThin: false, stateChangeable: true),
SizedBox(
height: 20,
),
Wrapper(
stepsCompleted: 0,
type: ZetaBarType.indeterminate,
type: ZetaProgressBarType.indeterminate,
isThin: false,
label: "UPLOADING ...",
),
Expand All @@ -50,15 +50,15 @@ class Wrapper extends StatefulWidget {
const Wrapper(
{super.key,
required this.stepsCompleted,
this.type = ZetaBarType.standard,
this.type = ZetaProgressBarType.standard,
this.isThin = false,
this.rounded = true,
this.stateChangeable = false,
this.label});

final int stepsCompleted;
final bool rounded;
final ZetaBarType type;
final ZetaProgressBarType type;
final bool isThin;
final String? label;
final bool stateChangeable;
Expand All @@ -70,7 +70,7 @@ class Wrapper extends StatefulWidget {
class _WrapperState extends State<Wrapper> {
late int stepsCompleted;
late double progress;
late ZetaBarType type;
late ZetaProgressBarType type;

@override
void initState() {
Expand All @@ -90,7 +90,7 @@ class _WrapperState extends State<Wrapper> {

void setLoading() {
setState(() {
type = type == ZetaBarType.buffering ? ZetaBarType.standard : ZetaBarType.buffering;
type = type == ZetaProgressBarType.buffering ? ZetaProgressBarType.standard : ZetaProgressBarType.buffering;
});
}

Expand All @@ -108,7 +108,7 @@ class _WrapperState extends State<Wrapper> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
widget.type != ZetaBarType.indeterminate
widget.type != ZetaProgressBarType.indeterminate
? FilledButton(onPressed: increasePercentage, child: Text("Increase"))
: Container(),
const SizedBox(width: 40),
Expand Down
3 changes: 2 additions & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ version: 0.0.1
publish_to: "none"

environment:
sdk: ">=3.0.1 <4.0.0"
sdk: ">=3.2.0 <4.0.0"
flutter: ">=3.16.0"

dependencies:
cached_network_image: ^3.3.1
Expand Down
180 changes: 176 additions & 4 deletions example/widgetbook/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,179 @@
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:zeta_flutter/zeta_flutter.dart';

import 'widgetbook.dart';
import 'pages/assets/icon_widgetbook.dart';
import 'pages/components/accordion_widgetbook.dart';
import 'pages/components/avatar_widgetbook.dart';
import 'pages/components/badges_widgetbook.dart';
import 'pages/components/banner_widgetbook.dart';
import 'pages/components/bottom_sheet_widgetbook.dart';
import 'pages/components/button_widgetbook.dart';
import 'pages/components/checkbox_widgetbook.dart';
import 'pages/components/chip_widgetbook.dart';
import 'pages/components/dial_pad_widgetbook.dart';
import 'pages/components/in_page_banner_widgetbook.dart';
import 'pages/components/navigation_bar_widgetbook.dart';
import 'pages/components/password_input_widgetbook.dart';
import 'pages/components/progress_widgetbook.dart';
import 'pages/theme/color_widgetbook.dart';
import 'pages/theme/radius_widgetbook.dart';
import 'pages/theme/spacing_widgetbook.dart';
import 'pages/theme/typography_widgetbook.dart';
import 'utils/zebra.dart';

void main() {
runApp(const HotReload());
void main() => runApp(const HotReload());

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

@override
Widget build(BuildContext context) {
return Widgetbook(
appBuilder: (context, child) => child,
directories: [
WidgetbookCategory(
name: 'Components',
isInitiallyExpanded: false,
children: [
WidgetbookComponent(
name: 'Badge',
useCases: [
WidgetbookUseCase(name: 'Status Label', builder: (context) => statusLabelUseCase(context)),
WidgetbookUseCase(name: 'Priority Pill', builder: (context) => priorityPillUseCase(context)),
WidgetbookUseCase(name: 'Badge', builder: (context) => badgeUseCase(context)),
WidgetbookUseCase(name: 'Indicators', builder: (context) => indicatorsUseCase(context)),
WidgetbookUseCase(name: 'Tags', builder: (context) => tagsUseCase(context)),
WidgetbookUseCase(
name: 'Workcloud Indicators', builder: (context) => workcloudIndicatorsUseCase(context)),
],
),
WidgetbookUseCase(name: 'Avatar', builder: (context) => avatarUseCase(context)),
WidgetbookUseCase(name: 'Checkbox', builder: (context) => checkboxUseCase(context)),
WidgetbookComponent(
name: 'Buttons',
useCases: [
WidgetbookUseCase(name: 'Button', builder: (context) => buttonUseCase(context)),
WidgetbookUseCase(name: 'Icon Button', builder: (context) => iconButtonUseCase(context)),
WidgetbookUseCase(
name: 'Floating Action Button', builder: (context) => floatingActionButtonUseCase(context)),
],
),
WidgetbookUseCase(name: 'Banners', builder: (context) => bannerUseCase(context)),
WidgetbookUseCase(name: 'In Page Banners', builder: (context) => inPageBannerUseCase(context)),
WidgetbookUseCase(name: 'Accordion', builder: (context) => accordionUseCase(context)),
WidgetbookComponent(
name: 'Badge',
useCases: [
WidgetbookUseCase(name: 'Filter Chip', builder: (context) => filterChipUseCase(context)),
WidgetbookUseCase(name: 'Input Chip', builder: (context) => inputChipUseCase(context)),
WidgetbookUseCase(name: 'Assist Chip', builder: (context) => assistChipUseCase(context)),
],
),
WidgetbookUseCase(name: 'Password Input', builder: (context) => passwordInputUseCase(context)),
WidgetbookComponent(
name: 'Bottom Sheet',
useCases: [
WidgetbookUseCase(name: 'Content', builder: (context) => bottomSheetContentUseCase(context)),
WidgetbookUseCase(name: 'Live', builder: (context) => bottomSheetLiveUseCase(context)),
],
),
WidgetbookUseCase(name: 'Dial Pad', builder: (context) => dialPadUseCase(context)),
WidgetbookUseCase(name: 'Navigation Bar', builder: (context) => navigationBarUseCase(context)),
WidgetbookComponent(
name: 'Progress',
useCases: [
WidgetbookUseCase(name: 'Bar', builder: (context) => progressBarUseCase(context)),
],
),
]..sort((a, b) => a.name.compareTo(b.name)),
),
WidgetbookCategory(
name: 'Theme',
isInitiallyExpanded: false,
children: [
WidgetbookUseCase(name: 'Typography', builder: (context) => typographyUseCase(context)),
WidgetbookUseCase(name: 'Color', builder: (context) => colorUseCase(context)),
WidgetbookUseCase(name: 'Spacing', builder: (context) => spacingUseCase(context)),
WidgetbookUseCase(name: 'Radius', builder: (context) => radiusUseCase(context)),
]..sort((a, b) => a.name.compareTo(b.name)),
),
WidgetbookCategory(
name: 'Assets',
isInitiallyExpanded: false,
children: [
WidgetbookUseCase(name: 'Icons', builder: (context) => iconsUseCase(context)),
]..sort((a, b) => a.name.compareTo(b.name)),
),
],
addons: [
DeviceFrameAddon(
devices: [
Devices.windows.wideMonitor,
Devices.macOS.wideMonitor,
Devices.ios.iPad,
Devices.ios.iPhone13,
Zebra.ec30,
Zebra.ec50,
],
),
ThemeAddon(
themes: [
WidgetbookTheme(name: 'Light Mode', data: _Theme(isDark: false, isAAA: false)),
WidgetbookTheme(name: 'Dark Mode', data: _Theme(isDark: true, isAAA: false)),
WidgetbookTheme(name: 'Light Mode AAA', data: _Theme(isDark: false, isAAA: true)),
WidgetbookTheme(name: 'Dark Mode AAA', data: _Theme(isDark: true, isAAA: true)),
],
themeBuilder: (context, theme, child) {
_Theme _theme = theme;
return ZetaProvider(
initialContrast: _theme.isAAA ? ZetaContrast.aaa : ZetaContrast.aa,
initialThemeMode: _theme.isDark ? ThemeMode.dark : ThemeMode.light,
builder: (context, theme, themeMode) {
return Builder(
builder: (context) {
final dark = theme.colorsDark.toScheme();
final light = theme.colorsLight.toScheme();

return MaterialApp(
debugShowCheckedModeBanner: false,
themeMode: themeMode,
theme: ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: light.background,
colorScheme: light,
textTheme: zetaTextTheme,
brightness: Brightness.light,
),
darkTheme: ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: dark.background,
colorScheme: dark,
textTheme: zetaTextTheme,
brightness: Brightness.dark,
),
builder: (context, child) {
return ColoredBox(
color: Zeta.of(context).colors.surfacePrimary,
child: child,
);
},
home: child,
);
},
);
},
);
},
),
],
);
}
}

class _Theme {
final bool isDark;
final bool isAAA;

_Theme({required this.isDark, required this.isAAA});
}
101 changes: 47 additions & 54 deletions example/widgetbook/pages/assets/icon_widgetbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,57 @@ import 'package:zeta_flutter/zeta_flutter.dart';

import '../../test/test_components.dart';

WidgetbookComponent iconWidgetbook() {
return WidgetbookComponent(
isInitiallyExpanded: false,
name: 'Icons',
useCases: [
WidgetbookUseCase(
name: 'All Icons',
builder: (context) {
Map<String, IconData> icons =
((context.knobs.boolean(label: 'Rounded', initialValue: true)) ? iconsRounded : iconsSharp);
Widget iconsUseCase(BuildContext context) {
Map<String, IconData> icons =
((context.knobs.boolean(label: 'Rounded', initialValue: true)) ? iconsRounded : iconsSharp);

final Map<String, IconData> sortedIcons = Map.fromEntries(icons.entries.toList()
..sort((a, b) {
final _a = (a.key.split('_')..removeLast()).join();
final _b = (b.key.split('_')..removeLast()).join();
return _a.compareTo(_b);
}));
final Map<String, IconData> sortedIcons = Map.fromEntries(icons.entries.toList()
..sort((a, b) {
final _a = (a.key.split('_')..removeLast()).join();
final _b = (b.key.split('_')..removeLast()).join();
return _a.compareTo(_b);
}));

return WidgetbookTestWidget(
removeBody: true,
widget: SingleChildScrollView(
key: PageStorageKey(0),
child: Center(
child: Column(
children: [
Text('Tap icon to copy name to clipboard', style: ZetaTextStyles.titleMedium)
.paddingAll(ZetaSpacing.l),
Wrap(
spacing: ZetaSpacing.l,
runSpacing: ZetaSpacing.l,
children: sortedIcons.entries.map(
(e) {
final nameArr = (e.key.split('_')..removeLast()).join(' ').capitalize();
return Container(
width: 100,
height: 100,
child: InkWell(
borderRadius: ZetaRadius.rounded,
hoverColor: Zeta.of(context).colors.surfaceHovered,
onTap: () async {
await Clipboard.setData(ClipboardData(text: 'ZetaIcons.' + e.key));
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [Icon(e.value, size: 40), Text(nameArr, textAlign: TextAlign.center)],
),
),
);
},
).toList(),
return WidgetbookTestWidget(
removeBody: true,
widget: SingleChildScrollView(
key: PageStorageKey(0),
child: Center(
child: Column(
children: [
Text('Tap icon to copy name to clipboard', style: ZetaTextStyles.titleMedium).paddingAll(ZetaSpacing.l),
Wrap(
spacing: ZetaSpacing.l,
runSpacing: ZetaSpacing.l,
children: sortedIcons.entries.map(
(e) {
final nameArr = (e.key.split('_')..removeLast()).join(' ').capitalize();
return Container(
width: 100,
height: 100,
child: InkWell(
borderRadius: ZetaRadius.rounded,
hoverColor: Zeta.of(context).colors.surfaceHovered,
onTap: () async {
await Clipboard.setData(ClipboardData(text: 'ZetaIcons.' + e.key));
ScaffoldMessenger.of(context).showMaterialBanner(
ZetaSystemBanner(context: context, title: 'Icon name copied'),
);
await Future.delayed(Duration(seconds: 4));
ScaffoldMessenger.of(context).clearMaterialBanners();
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [Icon(e.value, size: 40), Text(nameArr, textAlign: TextAlign.center)],
),
),
],
),
),
);
},
).toList(),
),
);
},
],
),
),
],
),
);
}
Loading

0 comments on commit 44b8f98

Please sign in to comment.