From 554fe7f54fc3099f140bf7648fe78ce5e15d5b0f Mon Sep 17 00:00:00 2001 From: Luke Walton Date: Wed, 3 Apr 2024 15:20:10 +0100 Subject: [PATCH] fix: switch on web (#14) --- .../pages/components/badges_widgetbook.dart | 6 +-- .../pages/components/banner_widgetbook.dart | 2 +- .../components/snack_bar_widgetbook.dart | 2 +- .../pages/components/switch_widgetbook.dart | 6 +++ example/widgetbook/utils/utils.dart | 2 +- .../components/switch/material_switch.dart | 15 ++++-- lib/src/components/switch/zeta_switch.dart | 47 ++++++++++++++++++- 7 files changed, 68 insertions(+), 12 deletions(-) diff --git a/example/widgetbook/pages/components/badges_widgetbook.dart b/example/widgetbook/pages/components/badges_widgetbook.dart index d10cdb0d..4b17f1bd 100644 --- a/example/widgetbook/pages/components/badges_widgetbook.dart +++ b/example/widgetbook/pages/components/badges_widgetbook.dart @@ -74,7 +74,7 @@ Widget tagsUseCase(BuildContext context) => WidgetbookTestWidget( direction: context.knobs.list( label: 'Direction', options: ZetaTagDirection.values, - labelBuilder: (value) => value.name.split('.').last.capitalize(), + labelBuilder: enumLabelBuilder, ), ), ], @@ -90,12 +90,12 @@ Widget workcloudIndicatorsUseCase(BuildContext context) { label: context.knobs.string(label: 'Label', initialValue: 'Label'), prioritySize: context.knobs.list( label: 'Size', - labelBuilder: (value) => value.name.split('.').last.capitalize(), + labelBuilder: enumLabelBuilder, options: ZetaWidgetSize.values, ), priorityType: context.knobs.list( label: 'Type', - labelBuilder: (value) => value.name.split('.').last.capitalize(), + labelBuilder: enumLabelBuilder, options: ZetaWorkcloudIndicatorType.values, ), icon: iconKnob(context, rounded: rounded, nullable: true), diff --git a/example/widgetbook/pages/components/banner_widgetbook.dart b/example/widgetbook/pages/components/banner_widgetbook.dart index 85792576..5c796843 100644 --- a/example/widgetbook/pages/components/banner_widgetbook.dart +++ b/example/widgetbook/pages/components/banner_widgetbook.dart @@ -14,7 +14,7 @@ Widget bannerUseCase(BuildContext context) { type: context.knobs.list( label: 'Type', options: ZetaSystemBannerStatus.values, - labelBuilder: (value) => value.name.split('.').last.capitalize(), + labelBuilder: enumLabelBuilder, ), leadingIcon: iconKnob(context, rounded: rounded, nullable: true), titleStart: context.knobs.boolean(label: 'Center title'), diff --git a/example/widgetbook/pages/components/snack_bar_widgetbook.dart b/example/widgetbook/pages/components/snack_bar_widgetbook.dart index 7f3deeba..92430c67 100644 --- a/example/widgetbook/pages/components/snack_bar_widgetbook.dart +++ b/example/widgetbook/pages/components/snack_bar_widgetbook.dart @@ -22,7 +22,7 @@ Widget snackBarUseCase(BuildContext context) { final type = context.knobs.listOrNull( label: 'Type', options: [null, ...ZetaSnackBarType.values], - labelBuilder: (type) => type?.name ?? '', + labelBuilder: enumLabelBuilder, ); final leadingIcon = iconKnob( diff --git a/example/widgetbook/pages/components/switch_widgetbook.dart b/example/widgetbook/pages/components/switch_widgetbook.dart index 50aaf294..0ee2f9c3 100644 --- a/example/widgetbook/pages/components/switch_widgetbook.dart +++ b/example/widgetbook/pages/components/switch_widgetbook.dart @@ -3,6 +3,7 @@ import 'package:widgetbook/widgetbook.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; import '../../test/test_components.dart'; +import '../../utils/utils.dart'; Widget switchUseCase(BuildContext context) { bool? isOn = false; @@ -21,6 +22,11 @@ Widget switchUseCase(BuildContext context) { ZetaSwitch( value: isOn, onChanged: onChanged, + variant: context.knobs.listOrNull( + label: 'Variant', + options: ZetaSwitchType.values, + labelBuilder: enumLabelBuilder, + ), ), Text(isOn == true ? 'On' : 'Off'), ], diff --git a/example/widgetbook/utils/utils.dart b/example/widgetbook/utils/utils.dart index 4baec50c..207ec12c 100644 --- a/example/widgetbook/utils/utils.dart +++ b/example/widgetbook/utils/utils.dart @@ -16,7 +16,7 @@ String iconLabelBuilder(IconData? value, [bool rounded = true]) { List iconOptions(rounded) => rounded ? iconsRounded.values.toList() : iconsSharp.values.toList(); -String enumLabelBuilder(Enum value) => value.name.split('.').last.capitalize(); +String enumLabelBuilder(Enum? value) => value?.name.split('.').last.capitalize() ?? ''; IconData? iconKnob(BuildContext context, {bool rounded = true, bool nullable = false, String name = 'Icon', final IconData? initial}) { diff --git a/lib/src/components/switch/material_switch.dart b/lib/src/components/switch/material_switch.dart index a63ed13f..34cf6d62 100644 --- a/lib/src/components/switch/material_switch.dart +++ b/lib/src/components/switch/material_switch.dart @@ -45,8 +45,9 @@ class MaterialSwitch extends StatefulWidget { this.focusNode, this.onFocusChange, this.autofocus = false, - // Zeta change: added optional parameter `showHover`. + // Zeta change: added optional parameter `showHover` and `thumbSize`. this.showHover = false, + this.thumbSize, }) : assert(activeThumbImage != null || onActiveThumbImageError == null), assert(inactiveThumbImage != null || onInactiveThumbImageError == null); @@ -75,8 +76,9 @@ class MaterialSwitch extends StatefulWidget { final FocusNode? focusNode; final ValueChanged? onFocusChange; final bool autofocus; - // Zeta change: added optional parameter `showHover`. + // Zeta change: added optional parameters `showHover` and `thumbSize`. final bool showHover; + final Size? thumbSize; final Size size; @override @@ -369,7 +371,9 @@ class _MaterialSwitchState extends State with TickerProviderStat ..inactiveIcon = effectiveInactiveIcon ..iconTheme = IconTheme.of(context) ..thumbShadow = _switchConfig.thumbShadow - ..positionController = positionController, + ..positionController = positionController + // Zeta change: pass thumbsize + .._thumbSize = widget.thumbSize, ), ), ); @@ -685,6 +689,8 @@ class _SwitchPainter extends ToggleablePainter { ImageProvider? _cachedThumbImage; ImageErrorListener? _cachedThumbErrorListener; BoxPainter? _cachedThumbPainter; + // Zeta change: add `_thumbSize`. + Size? _thumbSize; ShapeDecoration _createDefaultThumbDecoration(Color color, ImageProvider? image, ImageErrorListener? errorListener) { return ShapeDecoration( @@ -730,7 +736,8 @@ class _SwitchPainter extends ToggleablePainter { _pressedThumbExtension = 0; } - Size? thumbSize = Size.fromRadius(pressedThumbRadius); + // Zeta change: `_thumbSize` override. + Size? thumbSize = _thumbSize ?? Size.fromRadius(pressedThumbRadius); // The thumb contracts slightly during the animation in Material 2. final double inset = thumbOffset == null ? 0 : 1.0 - (currentValue - thumbOffset!).abs() * 2.0; diff --git a/lib/src/components/switch/zeta_switch.dart b/lib/src/components/switch/zeta_switch.dart index 81dbf7e8..0dd121ae 100644 --- a/lib/src/components/switch/zeta_switch.dart +++ b/lib/src/components/switch/zeta_switch.dart @@ -8,16 +8,33 @@ import 'material_switch.dart'; const _sizeAndroid = Size(48, 24); const _sizeIOS = Size(56, 32); +const _sizeWeb = Size(64, 32); + +/// Variants of [ZetaSwitch]. +enum ZetaSwitchType { + /// 64 x 32 + web, + + /// 48 x 24 + android, + + /// 56 x 32 + ios, +} /// Zeta Switch. /// /// Switch can turn an option on or off. +/// +/// Switch has styles for Android, iOS and Web. +// TODO(switch): Add web icon support. class ZetaSwitch extends StatelessWidget { /// Constructor for [ZetaSwitch]. const ZetaSwitch({ super.key, this.value = false, this.onChanged, + this.variant, }); /// Determines whether the switch is on or off. @@ -26,19 +43,44 @@ class ZetaSwitch extends StatelessWidget { /// Called when the value of the switch should change. final ValueChanged? onChanged; + /// Variant of switch for different platforms. + /// + /// Defaults to match the platform, or falls back to web. + final ZetaSwitchType? variant; + @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties ..add(FlagProperty('value', value: value, ifTrue: 'on', ifFalse: 'off', showName: true)) - ..add(ObjectFlagProperty>('onChanged', onChanged, ifNull: 'disabled')); + ..add(ObjectFlagProperty>('onChanged', onChanged, ifNull: 'disabled')) + ..add(EnumProperty('variant', variant)); + } + + ZetaSwitchType get _variant { + if (variant != null) return variant!; + if (kIsWeb) return ZetaSwitchType.web; + return switch (Platform.operatingSystem) { + 'ios' => ZetaSwitchType.ios, + 'android' => ZetaSwitchType.android, + _ => ZetaSwitchType.web, + }; + } + + Size get _size { + return switch (_variant) { + ZetaSwitchType.ios => _sizeIOS, + ZetaSwitchType.android => _sizeAndroid, + _ => _sizeWeb, + }; } @override Widget build(BuildContext context) { final zetaColors = Zeta.of(context).colors; + return MaterialSwitch( - size: Platform.isIOS ? _sizeIOS : _sizeAndroid, + size: _size, trackOutlineWidth: const MaterialStatePropertyAll(0), trackOutlineColor: const MaterialStatePropertyAll(Colors.transparent), trackColor: MaterialStateProperty.resolveWith((states) { @@ -53,6 +95,7 @@ class ZetaSwitch extends StatelessWidget { ), value: value ?? false, onChanged: onChanged, + thumbSize: _variant == ZetaSwitchType.web ? const Size.square(ZetaSpacing.m) : null, ); } }