From 5e1c48aca84bbe49233deca10f64dcd6e8b8eb59 Mon Sep 17 00:00:00 2001 From: Luke Walton Date: Wed, 14 Feb 2024 17:07:27 +0000 Subject: [PATCH] fix: WIdgetbook theme (#16) * Added theme support for Widgetbook. This had been casuing issues where the theme mode was not rendering the correct widgets. This also lead to the discovery of theme issues on checkbox and avatar, which have been fixed. * fix type story and add icon story * Adding spacing widgetbook * adding icon names --- .github/workflows/pull-request.yml | 2 +- example/pubspec.yaml | 1 + .../components/accordion_widgetbook.dart | 39 ----- .../components/checkbox_widgetbook.dart | 32 ---- .../pages/assets/icon_widgetbook.dart | 63 +++++++ .../components/accordion_widgetbook.dart | 40 +++++ .../components/avatar_widgetbook.dart | 4 +- .../components/badges_widgetbook.dart | 8 +- .../components/banner_widgetbook.dart | 5 +- .../components/bottom_sheet_widgetbook.dart | 4 +- .../components/button_widgetbook.dart | 26 +-- .../pages/components/checkbox_widgetbook.dart | 96 +++++++++++ .../components/chip_widgetbook.dart | 31 ++-- .../components/password_input_widgetbook.dart | 2 +- .../pages/theme/color_widgetbook.dart | 140 +++++++++++++++ .../pages/theme/radius_widgetbook.dart | 75 +++++++++ .../pages/theme/spacing_widgetbook.dart | 138 +++++++++++++++ .../pages/theme/typography_widgetbook.dart | 71 ++++++++ example/widgetbook/test/test_components.dart | 46 ++--- .../widgetbook/theme/color_widgetbook.dart | 144 ---------------- .../theme/typography_widgetbook.dart | 46 ----- example/widgetbook/widgetbook.dart | 159 ++++++++++++------ lib/src/components/avatars/avatar.dart | 8 +- lib/src/components/badges/status_label.dart | 6 +- lib/src/components/banners/system_banner.dart | 1 + lib/src/components/checkbox/checkbox.dart | 34 ++-- 26 files changed, 820 insertions(+), 401 deletions(-) delete mode 100644 example/widgetbook/components/accordion_widgetbook.dart delete mode 100644 example/widgetbook/components/checkbox_widgetbook.dart create mode 100644 example/widgetbook/pages/assets/icon_widgetbook.dart create mode 100644 example/widgetbook/pages/components/accordion_widgetbook.dart rename example/widgetbook/{ => pages}/components/avatar_widgetbook.dart (95%) rename example/widgetbook/{ => pages}/components/badges_widgetbook.dart (96%) rename example/widgetbook/{ => pages}/components/banner_widgetbook.dart (97%) rename example/widgetbook/{ => pages}/components/bottom_sheet_widgetbook.dart (94%) rename example/widgetbook/{ => pages}/components/button_widgetbook.dart (77%) create mode 100644 example/widgetbook/pages/components/checkbox_widgetbook.dart rename example/widgetbook/{ => pages}/components/chip_widgetbook.dart (73%) rename example/widgetbook/{ => pages}/components/password_input_widgetbook.dart (98%) create mode 100644 example/widgetbook/pages/theme/color_widgetbook.dart create mode 100644 example/widgetbook/pages/theme/radius_widgetbook.dart create mode 100644 example/widgetbook/pages/theme/spacing_widgetbook.dart create mode 100644 example/widgetbook/pages/theme/typography_widgetbook.dart delete mode 100644 example/widgetbook/theme/color_widgetbook.dart delete mode 100644 example/widgetbook/theme/typography_widgetbook.dart diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index df90b783..30591e87 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -95,7 +95,7 @@ jobs: - name: Build example app run: | cd example - flutter build web -o ../build --no-tree-shake-icons + flutter build web -t widgetbook/main.dart -o ../build --no-tree-shake-icons - uses: FirebaseExtended/action-hosting-deploy@v0 with: repoToken: "${{ secrets.GITHUB_TOKEN }}" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 6b891784..00110aaa 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: sdk: flutter go_router: ^11.1.2 google_fonts: ^6.1.0 + path_drawing: ^1.0.1 shared_preferences: ^2.2.2 zeta_flutter: path: ../ diff --git a/example/widgetbook/components/accordion_widgetbook.dart b/example/widgetbook/components/accordion_widgetbook.dart deleted file mode 100644 index 5df1a2d8..00000000 --- a/example/widgetbook/components/accordion_widgetbook.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:widgetbook/widgetbook.dart'; -import 'package:zeta_flutter/zeta_flutter.dart'; - -import '../test/test_components.dart'; - -WidgetbookComponent accordionWidgetBook() { - return WidgetbookComponent( - isInitiallyExpanded: false, - name: 'Accordion', - useCases: [ - WidgetbookUseCase( - name: 'Accordion', - builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, - widget: Padding( - padding: const EdgeInsets.all(20), - child: ZetaAccordion( - child: context.knobs.boolean(label: 'Disabled') - ? null - : Column( - children: [ - ListTile(title: Text('Item One')), - ListTile(title: Text('Item two')), - ListTile(title: Text('Item three')), - ListTile(title: Text('Item four')), - ], - ), - title: context.knobs.string(label: 'Accordion Title', initialValue: 'Title'), - contained: context.knobs.boolean(label: 'Contained', initialValue: false), - isOpen: context.knobs.boolean(label: 'Open', initialValue: false), - rounded: context.knobs.boolean(label: 'Rounded', initialValue: false), - ), - ), - ), - ), - ], - ); -} diff --git a/example/widgetbook/components/checkbox_widgetbook.dart b/example/widgetbook/components/checkbox_widgetbook.dart deleted file mode 100644 index 87f79678..00000000 --- a/example/widgetbook/components/checkbox_widgetbook.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:widgetbook/widgetbook.dart'; -import 'package:zeta_flutter/zeta_flutter.dart'; - -import '../test/test_components.dart'; - -WidgetbookComponent checkboxWidgetBook() { - return WidgetbookComponent( - isInitiallyExpanded: false, - name: 'Checkbox', - useCases: [ - WidgetbookUseCase( - name: 'Checkbox', - builder: (context) => WidgetbookTestWidget( - widget: Column( - children: [ - Padding( - padding: EdgeInsets.only(top: 10), - child: ZetaCheckbox( - value: context.knobs.booleanOrNull(label: 'Checked'), - onChanged: context.knobs.boolean(label: 'Enabled', initialValue: true) ? (_) {} : null, - rounded: context.knobs.boolean(label: 'Rounded'), - label: context.knobs.string(label: 'Label', initialValue: 'Checkbox'), - ), - ), - ], - ), - ), - ), - ], - ); -} diff --git a/example/widgetbook/pages/assets/icon_widgetbook.dart b/example/widgetbook/pages/assets/icon_widgetbook.dart new file mode 100644 index 00000000..897eb07d --- /dev/null +++ b/example/widgetbook/pages/assets/icon_widgetbook.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:widgetbook/widgetbook.dart'; +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 icons = + (context.knobs.boolean(label: 'Rounded', initialValue: true)) ? iconsRounded : iconsSharp; + + return WidgetbookTestWidget( + removeBody: true, + widget: SingleChildScrollView( + 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: icons.entries.map( + (e) { + final nameArr = e.key.split('_')..removeLast(); + 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.join(' '), textAlign: TextAlign.center) + ], + ), + ), + ); + }, + ).toList(), + ), + ], + ), + ), + ), + ); + }, + ), + ], + ); +} diff --git a/example/widgetbook/pages/components/accordion_widgetbook.dart b/example/widgetbook/pages/components/accordion_widgetbook.dart new file mode 100644 index 00000000..d7297153 --- /dev/null +++ b/example/widgetbook/pages/components/accordion_widgetbook.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +WidgetbookComponent accordionWidgetBook() { + return WidgetbookComponent( + isInitiallyExpanded: false, + name: 'Accordion', + useCases: [ + WidgetbookUseCase( + name: 'Accordion', + builder: (context) { + return WidgetbookTestWidget( + widget: Padding( + padding: const EdgeInsets.all(20), + child: ZetaAccordion( + child: context.knobs.boolean(label: 'Disabled') + ? null + : Column( + children: [ + ListTile(title: Text('Item One')), + ListTile(title: Text('Item two')), + ListTile(title: Text('Item three')), + ListTile(title: Text('Item four')), + ], + ), + title: context.knobs.string(label: 'Accordion Title', initialValue: 'Title'), + contained: context.knobs.boolean(label: 'Contained', initialValue: false), + isOpen: context.knobs.boolean(label: 'Open', initialValue: false), + rounded: context.knobs.boolean(label: 'Rounded', initialValue: false), + ), + ), + ); + }, + ), + ], + ); +} diff --git a/example/widgetbook/components/avatar_widgetbook.dart b/example/widgetbook/pages/components/avatar_widgetbook.dart similarity index 95% rename from example/widgetbook/components/avatar_widgetbook.dart rename to example/widgetbook/pages/components/avatar_widgetbook.dart index 8e16b1ab..0a91e51c 100644 --- a/example/widgetbook/components/avatar_widgetbook.dart +++ b/example/widgetbook/pages/components/avatar_widgetbook.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; WidgetbookComponent avatarWidgetBook() { return WidgetbookComponent( @@ -15,7 +15,6 @@ WidgetbookComponent avatarWidgetBook() { final Widget image = Image.network('https://i.ytimg.com/vi/KItsWUzFUOs/maxresdefault.jpg', fit: BoxFit.cover); return WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Column( children: [ Padding( @@ -40,7 +39,6 @@ WidgetbookComponent avatarWidgetBook() { name: 'Initials Avatar', builder: (context) { return WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Column( children: [ Padding( diff --git a/example/widgetbook/components/badges_widgetbook.dart b/example/widgetbook/pages/components/badges_widgetbook.dart similarity index 96% rename from example/widgetbook/components/badges_widgetbook.dart rename to example/widgetbook/pages/components/badges_widgetbook.dart index 798902a2..6cdafb88 100644 --- a/example/widgetbook/components/badges_widgetbook.dart +++ b/example/widgetbook/pages/components/badges_widgetbook.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; WidgetbookComponent badgeWidgetBook() { return WidgetbookComponent( @@ -13,7 +13,6 @@ WidgetbookComponent badgeWidgetBook() { name: 'Status Label', builder: (context) { return WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Column( children: [ Padding( @@ -48,7 +47,6 @@ WidgetbookComponent badgeWidgetBook() { WidgetbookUseCase( name: 'Priority Pill', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Column( children: [ Padding( @@ -66,7 +64,6 @@ WidgetbookComponent badgeWidgetBook() { WidgetbookUseCase( name: 'Badge', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -85,7 +82,6 @@ WidgetbookComponent badgeWidgetBook() { WidgetbookUseCase( name: 'Indicators', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -121,7 +117,6 @@ WidgetbookComponent badgeWidgetBook() { WidgetbookUseCase( name: 'Tags', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -140,7 +135,6 @@ WidgetbookComponent badgeWidgetBook() { WidgetbookUseCase( name: 'Workcloud Indicators', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/example/widgetbook/components/banner_widgetbook.dart b/example/widgetbook/pages/components/banner_widgetbook.dart similarity index 97% rename from example/widgetbook/components/banner_widgetbook.dart rename to example/widgetbook/pages/components/banner_widgetbook.dart index cf549758..de5b538c 100644 --- a/example/widgetbook/components/banner_widgetbook.dart +++ b/example/widgetbook/pages/components/banner_widgetbook.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; -WidgetbookComponent BannerWidgetBook() { +WidgetbookComponent bannerWidgetBook() { return WidgetbookComponent( isInitiallyExpanded: false, name: 'Banners', @@ -49,7 +49,6 @@ WidgetbookComponent BannerWidgetBook() { WidgetbookUseCase( name: 'In Page Banner', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Padding( padding: EdgeInsets.all(20), child: Column( diff --git a/example/widgetbook/components/bottom_sheet_widgetbook.dart b/example/widgetbook/pages/components/bottom_sheet_widgetbook.dart similarity index 94% rename from example/widgetbook/components/bottom_sheet_widgetbook.dart rename to example/widgetbook/pages/components/bottom_sheet_widgetbook.dart index 53ef7ded..a305ebcf 100644 --- a/example/widgetbook/components/bottom_sheet_widgetbook.dart +++ b/example/widgetbook/pages/components/bottom_sheet_widgetbook.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; WidgetbookComponent bottomSheetWidgetBook() { return WidgetbookComponent( @@ -12,7 +12,6 @@ WidgetbookComponent bottomSheetWidgetBook() { WidgetbookUseCase( name: 'Content', builder: (context) => WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Padding( padding: const EdgeInsets.all(20), child: _bottomSheet(context), @@ -24,7 +23,6 @@ WidgetbookComponent bottomSheetWidgetBook() { builder: (context) { final sheet = _bottomSheet(context); return WidgetbookTestWidget( - themeMode: ThemeMode.dark, widget: Padding( padding: const EdgeInsets.all(20), child: ElevatedButton( diff --git a/example/widgetbook/components/button_widgetbook.dart b/example/widgetbook/pages/components/button_widgetbook.dart similarity index 77% rename from example/widgetbook/components/button_widgetbook.dart rename to example/widgetbook/pages/components/button_widgetbook.dart index ac7bc83d..74161006 100644 --- a/example/widgetbook/components/button_widgetbook.dart +++ b/example/widgetbook/pages/components/button_widgetbook.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; WidgetbookComponent buttonWidgetBook() { return WidgetbookComponent( @@ -13,15 +13,21 @@ WidgetbookComponent buttonWidgetBook() { name: 'Button', builder: (context) { return WidgetbookTestWidget( - widget: Padding( - padding: EdgeInsets.all(20), - child: ZetaButton( - label: context.knobs.string(label: 'Text', initialValue: 'Button'), - onPressed: context.knobs.boolean(label: 'Disabled') ? null : () {}, - borderType: context.knobs.boolean(label: 'Rounded') ? ZetaWidgetBorder.rounded : ZetaWidgetBorder.sharp, - size: context.knobs.list(label: 'Size', options: ZetaWidgetSize.values), - type: context.knobs.list(label: 'Type', options: ZetaButtonType.values), - ), + widget: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.all(20), + child: ZetaButton( + label: context.knobs.string(label: 'Text', initialValue: 'Button'), + onPressed: context.knobs.boolean(label: 'Disabled') ? null : () {}, + borderType: + context.knobs.boolean(label: 'Rounded') ? ZetaWidgetBorder.rounded : ZetaWidgetBorder.sharp, + size: context.knobs.list(label: 'Size', options: ZetaWidgetSize.values), + type: context.knobs.list(label: 'Type', options: ZetaButtonType.values), + ), + ), + ], ), ); }, diff --git a/example/widgetbook/pages/components/checkbox_widgetbook.dart b/example/widgetbook/pages/components/checkbox_widgetbook.dart new file mode 100644 index 00000000..eeef1945 --- /dev/null +++ b/example/widgetbook/pages/components/checkbox_widgetbook.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +import '../../test/test_components.dart'; + +WidgetbookComponent checkboxWidgetBook() { + return WidgetbookComponent( + isInitiallyExpanded: false, + name: 'Checkbox', + useCases: [ + WidgetbookUseCase( + name: 'Checked', + builder: (context) { + return WidgetbookTestWidget( + widget: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 10), + child: _CheckState(context: context, initialState: true), + ), + ], + ), + ); + }, + ), + WidgetbookUseCase( + name: 'Indeterminate', + builder: (context) { + return WidgetbookTestWidget( + widget: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 10), + child: _CheckState(context: context, initialState: null), + ), + ], + ), + ); + }, + ), + WidgetbookUseCase( + name: 'Unchecked', + builder: (context) { + return WidgetbookTestWidget( + widget: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 10), + child: _CheckState(context: context, initialState: false), + ), + ], + ), + ); + }, + ), + ], + ); +} + +class _CheckState extends StatefulWidget { + final BuildContext context; + final bool? initialState; + const _CheckState({required this.context, this.initialState}); + + @override + State<_CheckState> createState() => __CheckStateState(); +} + +class __CheckStateState extends State<_CheckState> { + bool? b = null; + + @override + void initState() { + super.initState(); + b = widget.initialState; + } + + @override + Widget build(BuildContext _) { + dynamic onChanged = + context.knobs.boolean(label: 'Enabled', initialValue: true) ? (b2) => setState(() => b = b2) : null; + + return Column( + children: [ + ZetaCheckbox( + value: b, + onChanged: onChanged, + useIndeterminate: context.knobs.boolean(label: 'Use Indeterminate', initialValue: true), + rounded: context.knobs.boolean(label: 'Rounded'), + label: context.knobs.string(label: 'Label', initialValue: 'Checkbox'), + ), + ], + ); + } +} diff --git a/example/widgetbook/components/chip_widgetbook.dart b/example/widgetbook/pages/components/chip_widgetbook.dart similarity index 73% rename from example/widgetbook/components/chip_widgetbook.dart rename to example/widgetbook/pages/components/chip_widgetbook.dart index 9a11ea42..e4f1a9f4 100644 --- a/example/widgetbook/components/chip_widgetbook.dart +++ b/example/widgetbook/pages/components/chip_widgetbook.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; WidgetbookComponent chipWidgetBook() { return WidgetbookComponent( @@ -30,16 +30,25 @@ WidgetbookComponent chipWidgetBook() { }, ); return WidgetbookTestWidget( - widget: ZetaInputChip( - label: context.knobs.string(label: 'Label', initialValue: 'Label'), - leading: context.knobs.boolean(label: 'Avatar') - ? ZetaAvatar( - initials: 'AZ', - size: ZetaAvatarSize.xs, - ) - : null, - rounded: context.knobs.boolean(label: 'Rounded'), - trailing: trailing != null ? Icon(trailing) : null, + widget: Padding( + padding: const EdgeInsets.all(20), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ZetaInputChip( + label: context.knobs.string(label: 'Label', initialValue: 'Label'), + leading: context.knobs.boolean(label: 'Avatar') + ? ZetaAvatar( + initials: 'AZ', + size: ZetaAvatarSize.xs, + ) + : null, + rounded: context.knobs.boolean(label: 'Rounded'), + trailing: trailing != null ? Icon(trailing) : null, + ), + ], + ), ), ); }, diff --git a/example/widgetbook/components/password_input_widgetbook.dart b/example/widgetbook/pages/components/password_input_widgetbook.dart similarity index 98% rename from example/widgetbook/components/password_input_widgetbook.dart rename to example/widgetbook/pages/components/password_input_widgetbook.dart index 539c2baa..eca168ef 100644 --- a/example/widgetbook/components/password_input_widgetbook.dart +++ b/example/widgetbook/pages/components/password_input_widgetbook.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import '../test/test_components.dart'; +import '../../test/test_components.dart'; WidgetbookComponent passwordInputWidgetBook() { return WidgetbookComponent( diff --git a/example/widgetbook/pages/theme/color_widgetbook.dart b/example/widgetbook/pages/theme/color_widgetbook.dart new file mode 100644 index 00000000..5afd0cfa --- /dev/null +++ b/example/widgetbook/pages/theme/color_widgetbook.dart @@ -0,0 +1,140 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:zeta_example/pages/theme/color_example.dart'; +import 'package:zeta_flutter/zeta_flutter.dart'; + +WidgetbookComponent colorWidgetBook() { + return WidgetbookComponent( + name: 'Colors', + useCases: [ + WidgetbookUseCase( + name: 'Colors', + builder: (BuildContext context) { + return ZetaProvider( + initialThemeMode: ThemeMode.light, + builder: (_, __, ___) => ColorBody(), + ); + }, + ), + ], + ); +} + +class ColorBody extends StatelessWidget { + const ColorBody({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (_, constraints) { + final colors = Zeta.of(context).colors; + + final Map swatches = { + 'Blue': colors.blue, + 'Green': colors.green, + 'Red': colors.red, + 'Orange': colors.orange, + 'Purple': colors.purple, + 'Yellow': colors.yellow, + 'Teal': colors.teal, + 'Pink': colors.pink, + 'Grey Warm': colors.warm, + 'Grey Cool': colors.cool, + }; + final Map textIcon = { + 'textDefault': colors.textDefault, + 'textSubtle': colors.textSubtle, + 'textDisabled': colors.textDisabled, + 'textInverse': colors.textInverse, + }; + final Map border = { + 'borderDefault': colors.borderDefault, + 'borderSubtle': colors.borderSubtle, + 'borderDisabled': colors.borderDisabled, + 'borderSelected': colors.borderSelected, + }; + final Map links = { + 'linkDefault': colors.link, + 'linkVisited': colors.linkVisited, + }; + final Map backdrop = { + 'surfacePrimary': colors.surfacePrimary, + 'surfaceDisabled': colors.surfaceDisabled, + 'surfaceHovered': colors.surfaceHovered, + 'surfaceSecondary': colors.surfaceSecondary, + 'surfaceTertiary': colors.surfaceTertiary, + 'surfaceSelectedHovered': colors.surfaceSelectedHovered, + 'surfaceSelected': colors.surfaceSelected, + }; + + final Map alerts = { + 'positive': colors.positive, + 'negative': colors.negative, + 'warning': colors.warning, + 'info': colors.info, + }; + + return DefaultTextStyle( + style: ZetaTextStyles.displayMedium.apply( + color: Zeta.of(context).colors.cool, + decoration: TextDecoration.none, + ), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: ZetaSpacing.l), + child: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: ZetaSpacing.l), + MyRow(children: textIcon, title: 'Text and icon styles'), + MyRow(children: border, title: 'Border styles'), + MyRow(children: links, title: 'Links'), + MyRow(children: backdrop, title: 'Backdrop colors'), + MyRow(children: alerts, title: 'Alert colors'), + Row(children: [Text('Full color swatches')]).paddingVertical(ZetaSpacing.x8), + ...swatches.entries.map( + (value) { + return Row( + children: List.generate(10, (index) => 100 - (10 * index)).map( + (e) { + return Expanded( + child: Container( + height: constraints.maxWidth / 10, + color: value.value[e], + child: FittedBox( + fit: BoxFit.scaleDown, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + DefaultTextStyle( + style: ZetaTextStyles.bodyMedium.copyWith( + color: calculateTextColor(value.value[e] ?? Colors.white), + ), + child: Column( + children: [ + Text('${value.key.toLowerCase().replaceAll(' ', '')}-$e'), + Text( + value.value[e].toString().replaceAll('Color(0xff', '#').substring(0, 7), + ), + ], + ), + ), + ], + ), + ), + ), + ); + }, + ).toList(), + ); + }, + ), + const SizedBox(height: ZetaSpacing.l), + ], + ), + ), + ), + ); + }); + } +} diff --git a/example/widgetbook/pages/theme/radius_widgetbook.dart b/example/widgetbook/pages/theme/radius_widgetbook.dart new file mode 100644 index 00000000..ccb63a73 --- /dev/null +++ b/example/widgetbook/pages/theme/radius_widgetbook.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; + +import 'package:zeta_flutter/zeta_flutter.dart'; + +WidgetbookComponent radiusWidgetbook() { + return WidgetbookComponent( + name: 'Radius', + useCases: [ + WidgetbookUseCase( + name: 'Radius', + builder: (context) => SingleChildScrollView( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + children: radii.entries + .map((obj) => _RadiiDemo(obj)) + .divide(const SizedBox.square(dimension: ZetaSpacing.l)) + .toList(), + ).paddingTop(ZetaSpacing.l), + ], + ), + ), + ), + ], + ); +} + +Map radii = { + 'none': ZetaRadius.none, + 'minimal': ZetaRadius.minimal, + 'rounded': ZetaRadius.rounded, + 'wide': ZetaRadius.wide, + 'full': ZetaRadius.full, +}; + +class _RadiiDemo extends StatelessWidget { + final MapEntry obj; + const _RadiiDemo(this.obj); + + @override + Widget build(BuildContext context) { + final colors = Zeta.of(context).colors; + + return Container( + width: 250, + height: 250, + decoration: BoxDecoration( + borderRadius: obj.value, + color: Zeta.of(context).colors.blue.shade30, + border: Border.all(color: colors.blue.shade80, width: 3), + ), + child: Center( + child: Container( + decoration: BoxDecoration( + borderRadius: obj.value, + color: Zeta.of(context).colors.surfacePrimary, + border: Border.all(color: colors.blue.shade50, width: 3), + ), + padding: EdgeInsets.all(ZetaSpacing.b), + child: Text( + 'ZetaRadius.' + obj.key, + style: ZetaTextStyles.titleMedium.apply( + color: Zeta.of(context).colors.textDefault, + fontStyle: FontStyle.normal, + decoration: TextDecoration.none, + ), + ), + ), + ), + ); + } +} diff --git a/example/widgetbook/pages/theme/spacing_widgetbook.dart b/example/widgetbook/pages/theme/spacing_widgetbook.dart new file mode 100644 index 00000000..53a08235 --- /dev/null +++ b/example/widgetbook/pages/theme/spacing_widgetbook.dart @@ -0,0 +1,138 @@ +import 'package:flutter/material.dart'; +import 'package:path_drawing/path_drawing.dart'; +import 'package:widgetbook/widgetbook.dart'; + +import 'package:zeta_flutter/zeta_flutter.dart'; + +WidgetbookComponent spacingWidgetBook() { + return WidgetbookComponent( + name: 'Spacing', + useCases: [ + WidgetbookUseCase( + name: 'Named spaces', + builder: (context) => SingleChildScrollView( + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: namedSpacings.entries.map((obj) => _SpacingDemo(obj)).toList(), + ) + ], + ), + ), + ), + WidgetbookUseCase( + name: 'Value spaces', + builder: (context) => SingleChildScrollView( + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: valueSpacings.entries.map((obj) => _SpacingDemo(obj)).toList(), + ) + ], + ), + ), + ), + ], + ); +} + +Map namedSpacings = { + 'xxs': ZetaSpacing.xxs, + 'xs': ZetaSpacing.xs, + 's': ZetaSpacing.s, + 'b': ZetaSpacing.b, + 'm': ZetaSpacing.m, + 'l': ZetaSpacing.l, + 'xl': ZetaSpacing.xl, + 'xxl': ZetaSpacing.xxl, + 'xxxl': ZetaSpacing.xxxl, +}; +Map valueSpacings = { + 'x1': ZetaSpacing.x1, + 'x2': ZetaSpacing.x2, + 'x3': ZetaSpacing.x3, + 'x3.5': ZetaSpacing.x3_5, + 'x4': ZetaSpacing.x4, + 'x5': ZetaSpacing.x5, + 'x6': ZetaSpacing.x6, + 'x7': ZetaSpacing.x7, + 'x8': ZetaSpacing.x8, + 'x9': ZetaSpacing.x9, + 'x10': ZetaSpacing.x10, + 'x11': ZetaSpacing.x11, + 'x12': ZetaSpacing.x12, + 'x13': ZetaSpacing.x13, + 'x14': ZetaSpacing.x14, + 'x16': ZetaSpacing.x16, + 'x20': ZetaSpacing.x20, + 'x24': ZetaSpacing.x24, +}; + +class _SpacingDemo extends StatelessWidget { + final MapEntry size; + + const _SpacingDemo(this.size); + + @override + Widget build(BuildContext context) { + final colors = Zeta.of(context).colors; + return Container( + color: colors.blue.shade30, + margin: EdgeInsets.all(ZetaSpacing.m), + child: CustomPaint( + painter: _TagPainter(color: colors.pink), + child: LayoutBuilder(builder: (context, c2) { + return Container( + margin: EdgeInsets.all(size.value), + padding: EdgeInsets.all(ZetaSpacing.s), + color: colors.surfacePrimary, + child: Text( + 'ZetaSpacing.' + size.key, + style: ZetaTextStyles.titleMedium.apply( + color: Zeta.of(context).colors.textDefault, + fontStyle: FontStyle.normal, + decoration: TextDecoration.none, + ), + ), + ); + }), + ), + ); + } +} + +class _TagPainter extends CustomPainter { + const _TagPainter({ + required this.color, + }); + + final Color color; + + @override + void paint(Canvas canvas, Size size) { + final Paint paint = Paint() + ..color = color + ..style = PaintingStyle.stroke; + + final horizontal = Path() + ..moveTo(0, (size.height / 2)) + ..lineTo(size.width, (size.height / 2)) + ..close(); + + final vertical = Path() + ..moveTo(size.width / 2, 0) + ..lineTo(size.width / 2, size.height) + ..close(); + + canvas.drawPath(dashPath(horizontal, dashArray: CircularIntervalList([2, 3])), paint); + canvas.drawPath( + dashPath(vertical, dashArray: CircularIntervalList([2, 3]), dashOffset: DashOffset.absolute(size.height)), + paint, + ); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => false; +} diff --git a/example/widgetbook/pages/theme/typography_widgetbook.dart b/example/widgetbook/pages/theme/typography_widgetbook.dart new file mode 100644 index 00000000..e2c281c1 --- /dev/null +++ b/example/widgetbook/pages/theme/typography_widgetbook.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; + +import 'package:zeta_flutter/zeta_flutter.dart'; + +WidgetbookComponent textWidgetBook() { + final Map allTypes = { + 'Display large': ZetaTextStyles.displayLarge, + 'Display medium': ZetaTextStyles.displayMedium, + 'Display small': ZetaTextStyles.displaySmall, + 'Heading 1': ZetaTextStyles.heading1, + 'Heading 2': ZetaTextStyles.heading2, + 'Heading 3': ZetaTextStyles.heading3, + 'Title large': ZetaTextStyles.titleLarge, + 'Title medium': ZetaTextStyles.titleMedium, + 'Title small': ZetaTextStyles.titleSmall, + 'Body large': ZetaTextStyles.bodyLarge, + 'Body medium': ZetaTextStyles.bodyMedium, + 'Body small': ZetaTextStyles.bodySmall, + 'Label large': ZetaTextStyles.labelLarge, + 'Label medium': ZetaTextStyles.labelMedium, + 'Label small': ZetaTextStyles.labelSmall, + 'Label indicator': ZetaTextStyles.labelIndicator, + 'Label tiny': ZetaTextStyles.labelTiny, + }; + return WidgetbookComponent( + name: 'Typography', + useCases: [ + WidgetbookUseCase( + name: 'Individual text styles', + builder: (context) => Text( + context.knobs.string(label: 'Text', initialValue: 'The quick brown fox jumps over the lazy dog.'), + style: context.knobs + .list( + label: 'Sizes', + labelBuilder: (p0) => allTypes.entries.firstWhere((element) => element.value == p0).key, + options: allTypes.values.toList(), + ) + .apply( + color: Zeta.of(context).colors.textDefault, + fontStyle: FontStyle.normal, + decoration: TextDecoration.none, + ), + ), + ), + WidgetbookUseCase( + name: 'All text styles', + builder: (context) => SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: allTypes.keys.map( + (e) { + return Text( + e, + style: allTypes[e]?.apply( + color: Zeta.of(context).colors.textDefault, + fontStyle: FontStyle.normal, + decoration: TextDecoration.none, + ), + ).paddingAll(ZetaSpacing.b); + }, + ).toList()), + ], + ), + )), + ], + ); +} diff --git a/example/widgetbook/test/test_components.dart b/example/widgetbook/test/test_components.dart index bfd99ce2..c6d62693 100644 --- a/example/widgetbook/test/test_components.dart +++ b/example/widgetbook/test/test_components.dart @@ -1,17 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:zeta_flutter/zeta_flutter.dart'; class WidgetbookTestWidget extends StatelessWidget { final Size? screenSize; final Widget widget; - final ThemeMode? themeMode; final bool removeBody; const WidgetbookTestWidget({ required this.widget, this.screenSize, super.key, - this.themeMode, this.removeBody = false, }); @@ -19,39 +16,18 @@ class WidgetbookTestWidget extends StatelessWidget { Widget build(BuildContext context) { final size = screenSize ?? const Size(1280, 720); - return ZetaProvider( - initialThemeMode: themeMode ?? ThemeMode.system, - builder: (context, theme, __) { - return Builder( - builder: (context) { - return MaterialApp( - debugShowCheckedModeBanner: false, - theme: ThemeData( - fontFamily: theme.fontFamily, - colorScheme: theme.colorsLight.toScheme(), - textTheme: zetaTextTheme, + return Scaffold( + backgroundColor: Colors.transparent, + body: removeBody + ? widget + : SizedBox( + width: size.width, + height: size.height, + child: MediaQuery( + data: MediaQueryData(size: Size(size.width, size.height)), + child: SingleChildScrollView(child: widget), ), - darkTheme: ThemeData( - fontFamily: theme.fontFamily, - colorScheme: theme.colorsDark.toScheme(), - textTheme: zetaTextTheme, - ), - home: Scaffold( - body: removeBody - ? widget - : SizedBox( - width: size.width, - height: size.height, - child: MediaQuery( - data: MediaQueryData(size: Size(size.width, size.height)), - child: SingleChildScrollView(child: widget), - ), - ), - ), - ); - }, - ); - }, + ), ); } } diff --git a/example/widgetbook/theme/color_widgetbook.dart b/example/widgetbook/theme/color_widgetbook.dart deleted file mode 100644 index 8beaf9cb..00000000 --- a/example/widgetbook/theme/color_widgetbook.dart +++ /dev/null @@ -1,144 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:widgetbook/widgetbook.dart'; -import 'package:zeta_example/pages/theme/color_example.dart'; -import 'package:zeta_flutter/zeta_flutter.dart'; - -WidgetbookComponent colorWidgetBook() { - return WidgetbookComponent( - name: 'Colors', - useCases: [ - WidgetbookUseCase( - name: 'Light Mode', - builder: (BuildContext context) { - return ZetaProvider( - initialThemeMode: ThemeMode.light, - builder: (_, __, ___) => ColorBody(), - ); - }, - ), - WidgetbookUseCase( - name: 'Dark Mode', - builder: (BuildContext context) { - return ZetaProvider( - initialThemeMode: ThemeMode.dark, - builder: (_, __, ___) => ColorBody(), - ); - }, - ) - ], - ); -} - -class ColorBody extends StatelessWidget { - const ColorBody({ - super.key, - }); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (_, constraints) { - final colors = Zeta.of(context).colors; - - final Map swatches = { - 'Blue': colors.blue, - 'Green': colors.green, - 'Red': colors.red, - 'Orange': colors.orange, - 'Purple': colors.purple, - 'Yellow': colors.yellow, - 'Teal': colors.teal, - 'Pink': colors.pink, - 'Grey Warm': colors.warm, - 'Grey Cool': colors.cool, - }; - final Map textIcon = { - 'textDefault': colors.textDefault, - 'textSubtle': colors.textSubtle, - 'textDisabled': colors.textDisabled, - 'textInverse': colors.textInverse, - }; - final Map border = { - 'borderDefault': colors.borderDefault, - 'borderSubtle': colors.borderSubtle, - 'borderDisabled': colors.borderDisabled, - 'borderSelected': colors.borderSelected, - }; - final Map links = { - 'linkDefault': colors.link, - 'linkVisited': colors.linkVisited, - }; - final Map backdrop = { - 'surfacePrimary': colors.surfacePrimary, - 'surfaceDisabled': colors.surfaceDisabled, - 'surfaceHovered': colors.surfaceHovered, - 'surfaceSecondary': colors.surfaceSecondary, - 'surfaceTertiary': colors.surfaceTertiary, - 'surfaceSelectedHovered': colors.surfaceSelectedHovered, - 'surfaceSelected': colors.surfaceSelected, - }; - - final Map alerts = { - 'positive': colors.positive, - 'negative': colors.negative, - 'warning': colors.warning, - 'info': colors.info, - }; - - return Container( - padding: const EdgeInsets.symmetric(horizontal: ZetaSpacing.l), - child: SingleChildScrollView( - child: Column( - children: [ - const SizedBox(height: ZetaSpacing.l), - MyRow(children: textIcon, title: 'Text and icon styles'), - MyRow(children: border, title: 'Border styles'), - MyRow(children: links, title: 'Links'), - MyRow(children: backdrop, title: 'Backdrop colors'), - MyRow(children: alerts, title: 'Alert colors'), - Row(children: [Text('Full color swatches', style: ZetaTextStyles.displayMedium)]) - .paddingVertical(ZetaSpacing.x8), - ...swatches.entries.map( - (value) { - return Row( - children: List.generate(10, (index) => 100 - (10 * index)).map( - (e) { - return Expanded( - child: Container( - height: constraints.maxWidth / 10, - color: value.value[e], - child: FittedBox( - fit: BoxFit.scaleDown, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - DefaultTextStyle( - style: ZetaTextStyles.bodyMedium.copyWith( - color: calculateTextColor(value.value[e] ?? Colors.white), - ), - child: Column( - children: [ - Text('${value.key.toLowerCase().replaceAll(' ', '')}-$e'), - Text( - value.value[e].toString().replaceAll('Color(0xff', '#').substring(0, 7), - ), - ], - ), - ), - ], - ), - ), - ), - ); - }, - ).toList(), - ); - }, - ), - const SizedBox(height: ZetaSpacing.l), - ], - ), - ), - ); - }); - } -} diff --git a/example/widgetbook/theme/typography_widgetbook.dart b/example/widgetbook/theme/typography_widgetbook.dart deleted file mode 100644 index 6eb20fe5..00000000 --- a/example/widgetbook/theme/typography_widgetbook.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:widgetbook/widgetbook.dart'; - -import 'package:zeta_flutter/zeta_flutter.dart'; - -WidgetbookComponent textWidgetBook() { - final dedicatedSizes = { - 'Display large': ZetaTextStyles.displayLarge, - 'Display medium': ZetaTextStyles.displayMedium, - 'Display small': ZetaTextStyles.displaySmall, - 'Heading 1': ZetaTextStyles.heading1, - 'Heading 2': ZetaTextStyles.heading2, - 'Heading 3': ZetaTextStyles.heading3, - 'Title large': ZetaTextStyles.titleLarge, - 'Title medium': ZetaTextStyles.titleMedium, - 'Title small': ZetaTextStyles.titleSmall, - 'Body large': ZetaTextStyles.bodyLarge, - 'Body medium': ZetaTextStyles.bodyMedium, - 'Body small': ZetaTextStyles.bodySmall, - 'Label large': ZetaTextStyles.labelLarge, - 'Label medium': ZetaTextStyles.labelMedium, - 'Label small': ZetaTextStyles.labelSmall, - 'Label indicator': ZetaTextStyles.labelIndicator, - 'Label tiny': ZetaTextStyles.labelTiny, - }; - return WidgetbookComponent( - name: 'Typography', - useCases: [ - WidgetbookUseCase( - name: 'Text styles', - builder: (context) => Container( - color: Theme.of(context).colorScheme.background, - padding: const EdgeInsets.all(ZetaSpacing.l), - child: Text( - context.knobs.string(label: 'Text', initialValue: 'The quick brown fox jumps over the lazy dog.'), - style: context.knobs.list( - label: 'Sizes', - labelBuilder: (p0) => dedicatedSizes.entries.firstWhere((element) => element.value == p0).key, - options: dedicatedSizes.values.toList(), - ), - ), - ), - ), - ], - ); -} diff --git a/example/widgetbook/widgetbook.dart b/example/widgetbook/widgetbook.dart index 507d869a..8d467c86 100644 --- a/example/widgetbook/widgetbook.dart +++ b/example/widgetbook/widgetbook.dart @@ -2,17 +2,20 @@ import 'package:flutter/material.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; -import 'components/accordion_widgetbook.dart'; -import 'components/avatar_widgetbook.dart'; -import 'components/badges_widgetbook.dart'; -import 'components/bottom_sheet_widgetbook.dart'; -import 'components/button_widgetbook.dart'; -import 'components/checkbox_widgetbook.dart'; -import 'theme/color_widgetbook.dart'; -import 'components/banner_widgetbook.dart'; -import 'components/chip_widgetbook.dart'; -import 'components/password_input_widgetbook.dart'; -import 'theme/typography_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/bottom_sheet_widgetbook.dart'; +import 'pages/components/button_widgetbook.dart'; +import 'pages/components/checkbox_widgetbook.dart'; +import 'pages/theme/color_widgetbook.dart'; +import 'pages/components/banner_widgetbook.dart'; +import 'pages/components/chip_widgetbook.dart'; +import 'pages/components/password_input_widgetbook.dart'; +import 'pages/theme/radius_widgetbook.dart'; +import 'pages/theme/spacing_widgetbook.dart'; +import 'pages/theme/typography_widgetbook.dart'; import 'utils/zebra.dart'; class HotReload extends StatelessWidget { @@ -20,45 +23,105 @@ class HotReload extends StatelessWidget { @override Widget build(BuildContext context) { - return ZetaProvider( - builder: (context, theme, colors) { - return Widgetbook.material( - directories: [ - WidgetbookCategory( - name: 'Components', - isInitiallyExpanded: false, - children: [ - badgeWidgetBook(), - avatarWidgetBook(), - checkboxWidgetBook(), - buttonWidgetBook(), - BannerWidgetBook(), - accordionWidgetBook(), - chipWidgetBook(), - passwordInputWidgetBook(), - bottomSheetWidgetBook(), - ]..sort((a, b) => a.name.compareTo(b.name)), - ), - WidgetbookCategory( - name: 'Theme', - isInitiallyExpanded: false, - children: [textWidgetBook(), colorWidgetBook(), checkboxWidgetBook()], - ), + return Widgetbook( + appBuilder: (context, child) => child, + directories: [ + WidgetbookCategory( + name: 'Components', + isInitiallyExpanded: false, + children: [ + badgeWidgetBook(), + avatarWidgetBook(), + checkboxWidgetBook(), + buttonWidgetBook(), + bannerWidgetBook(), + accordionWidgetBook(), + chipWidgetBook(), + passwordInputWidgetBook(), + bottomSheetWidgetBook(), + ]..sort((a, b) => a.name.compareTo(b.name)), + ), + WidgetbookCategory( + name: 'Theme', + isInitiallyExpanded: false, + children: [textWidgetBook(), colorWidgetBook(), spacingWidgetBook(), radiusWidgetbook()] + ..sort((a, b) => a.name.compareTo(b.name)), + ), + WidgetbookCategory( + name: 'Assets', + isInitiallyExpanded: false, + children: [iconWidgetbook()]..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, ], - 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(); + + print(child); + 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}); +} diff --git a/lib/src/components/avatars/avatar.dart b/lib/src/components/avatars/avatar.dart index 376c9f28..5a2fa7e2 100644 --- a/lib/src/components/avatars/avatar.dart +++ b/lib/src/components/avatars/avatar.dart @@ -146,7 +146,13 @@ class ZetaAvatar extends StatelessWidget { ), child: ClipRRect(borderRadius: ZetaRadius.full, clipBehavior: Clip.hardEdge, child: innerContent), ) - : innerContent, + : DecoratedBox( + decoration: BoxDecoration( + borderRadius: ZetaRadius.full, + color: backgroundColor ?? zetaColors.surfaceHovered, + ), + child: innerContent, + ), ), if (upperBadge != null) Positioned( diff --git a/lib/src/components/badges/status_label.dart b/lib/src/components/badges/status_label.dart index e403d0a2..acb035d5 100644 --- a/lib/src/components/badges/status_label.dart +++ b/lib/src/components/badges/status_label.dart @@ -43,7 +43,11 @@ class ZetaStatusLabel extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Icon(customIcon ?? Icons.circle, size: ZetaSpacing.x2, color: colors.icon), + Icon( + customIcon ?? Icons.circle, + size: customIcon != null ? ZetaSpacing.x5 : ZetaSpacing.x2, + color: colors.icon, + ), const SizedBox(width: ZetaSpacing.xs), Text( label, diff --git a/lib/src/components/banners/system_banner.dart b/lib/src/components/banners/system_banner.dart index 40f2cc34..e6b40dff 100644 --- a/lib/src/components/banners/system_banner.dart +++ b/lib/src/components/banners/system_banner.dart @@ -35,6 +35,7 @@ class ZetaSystemBanner extends MaterialBanner { bool titleStart = false, Widget? trailing, }) : super( + dividerColor: Colors.transparent, content: Builder( builder: (context) { final backgroundColor = _backgroundColorFromType(context, type); diff --git a/lib/src/components/checkbox/checkbox.dart b/lib/src/components/checkbox/checkbox.dart index 96c4c18d..350f49b0 100644 --- a/lib/src/components/checkbox/checkbox.dart +++ b/lib/src/components/checkbox/checkbox.dart @@ -31,6 +31,7 @@ class ZetaCheckbox extends FormField { useIndeterminate: useIndeterminate, value: value, error: !field.isValid, + enabled: onChanged != null, ); }, ); @@ -75,18 +76,19 @@ class ZetaCheckboxFormFieldState extends FormFieldState { class _Checkbox extends StatefulWidget { const _Checkbox({ this.value = false, - this.onChanged, + required this.onChanged, this.label, this.rounded = true, this.useIndeterminate = false, this.error = false, + required this.enabled, }); /// Whether the checkbox is selected, unselected or null (indeterminate) final bool? value; /// Called when the value of the checkbox should change. - final ValueChanged? onChanged; + final ValueChanged onChanged; /// The label displayed next to the checkbox final String? label; @@ -101,6 +103,8 @@ class _Checkbox extends StatefulWidget { final bool error; + final bool enabled; + @override State<_Checkbox> createState() => _CheckboxState(); @override @@ -108,17 +112,16 @@ class _Checkbox extends StatefulWidget { super.debugFillProperties(properties); properties ..add(DiagnosticsProperty('value', value)) - ..add(ObjectFlagProperty?>.has('onChanged', onChanged)) ..add(StringProperty('label', label)) ..add(DiagnosticsProperty('rounded', rounded)) ..add(DiagnosticsProperty('useIndeterminate', useIndeterminate)) - ..add(DiagnosticsProperty('error', error)); + ..add(DiagnosticsProperty('error', error)) + ..add(DiagnosticsProperty('enabled', enabled)) + ..add(ObjectFlagProperty>.has('onChanged', onChanged)); } } class _CheckboxState extends State<_Checkbox> { - bool get _enabled => widget.onChanged != null; - bool? get _value => widget.useIndeterminate ? widget.value : (widget.value ?? false); bool? get _updatedValue { @@ -141,18 +144,17 @@ class _CheckboxState extends State<_Checkbox> { @override Widget build(BuildContext context) { return Semantics( - checked: _value ?? false, mixed: widget.useIndeterminate, - enabled: _enabled, + enabled: widget.enabled, child: MouseRegion( - cursor: _enabled ? SystemMouseCursors.click : SystemMouseCursors.forbidden, + cursor: widget.enabled ? SystemMouseCursors.click : SystemMouseCursors.forbidden, onEnter: (event) => setState(() => _isHovered = true), onExit: (event) => setState(() => _isHovered = false), - child: _enabled + child: widget.enabled ? FocusableActionDetector( onFocusChange: (bool focus) => setState(() => _isFocused = focus), child: GestureDetector( - onTap: _enabled ? () => widget.onChanged?.call(_updatedValue) : null, + onTap: widget.enabled ? () => widget.onChanged.call(_updatedValue) : null, child: _buildContent(context), ), ) @@ -174,7 +176,7 @@ class _CheckboxState extends State<_Checkbox> { : widget.rounded ? ZetaIcons.remove_round : ZetaIcons.remove_sharp, - color: _enabled ? theme.colors.white : theme.colors.textDisabled, + color: widget.enabled ? theme.colors.white : theme.colors.textDisabled, size: ZetaSpacing.x3_5, ); @@ -186,7 +188,7 @@ class _CheckboxState extends State<_Checkbox> { duration: const Duration(milliseconds: 200), decoration: BoxDecoration( boxShadow: [ - if (_isFocused && _enabled) + if (_isFocused && widget.enabled) BoxShadow( spreadRadius: 2, blurStyle: BlurStyle.solid, @@ -194,7 +196,7 @@ class _CheckboxState extends State<_Checkbox> { ), ], color: _getBackground(theme), - border: _enabled ? Border.all(color: _getBorderColor(theme), width: ZetaSpacing.x0_5) : null, + border: widget.enabled ? Border.all(color: _getBorderColor(theme), width: ZetaSpacing.x0_5) : null, borderRadius: widget.rounded ? ZetaRadius.minimal : ZetaRadius.none, ), width: ZetaSpacing.x5, @@ -215,8 +217,8 @@ class _CheckboxState extends State<_Checkbox> { Color _getBackground(Zeta theme) { final ZetaColorSwatch color = widget.error ? theme.colors.error : theme.colors.primary; - - if (!_enabled || (_value != null && !_value!)) return theme.colors.surfacePrimary; + if (!widget.enabled) return theme.colors.surfaceDisabled; + if (_value != null && !_value!) return theme.colors.surfacePrimary; if (_isHovered) return color.hover; return color;