diff --git a/CHANGELOG.md b/CHANGELOG.md index 2471b74..a9ac012 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,19 @@ It is expected that you keep this format strictly, since we depend on it in our ### Added - added `constraints` to `showSBBModalSheet` to allow varying screen sizes (tablet) + +### Deprecated +- `SBBIconFormButton` +- `SBBIconButtonSmallBorderless` +- `SBBPrimaryButtonNegative` + ### Fixed +- correct height for `SBBTertiaryButtonSmall` (40px => 32px) +- coloring of: + - `SBBSecondaryButton` (onHighlighted) + - `SBBTertiaryButton` (darkMode) + - `SBBIconButtonSmall` + - `SBBIconButtonLarge` - `iconColor` in `SBBButtonStyle` is correctly overriden to support Flutter SDK >=3.27.0 ## [2.0.0] - 2024-09-06 diff --git a/example/lib/pages/button_page.dart b/example/lib/pages/button_page.dart index 51f291d..6612a22 100644 --- a/example/lib/pages/button_page.dart +++ b/example/lib/pages/button_page.dart @@ -21,19 +21,19 @@ class ButtonPage extends StatelessWidget { child: Column( children: [ SBBPrimaryButton( - label: 'Primary Button Default', + label: 'Default', onPressed: () { sbbToast.show(message: 'SBBPrimaryButton'); }, ), const SizedBox(height: sbbDefaultSpacing), const SBBPrimaryButton( - label: 'Primary Button Disabled', + label: 'Disabled', onPressed: null, ), const SizedBox(height: sbbDefaultSpacing), SBBPrimaryButton( - label: 'Primary Button Loading', + label: 'Loading', onPressed: () {}, isLoading: true, ), @@ -41,54 +41,25 @@ class ButtonPage extends StatelessWidget { ), ), const SizedBox(height: sbbDefaultSpacing), - const SBBListHeader('Primary Button Negative'), - SBBGroup( - child: Container( - padding: const EdgeInsets.all(sbbDefaultSpacing), - color: style.themeValue(SBBColors.red, SBBColors.transparent), - child: Column( - children: [ - SBBPrimaryButtonNegative( - label: 'Primary Button Negative Default', - onPressed: () { - sbbToast.show(message: 'SBBPrimaryButtonNegative'); - }, - ), - const SizedBox(height: sbbDefaultSpacing), - const SBBPrimaryButtonNegative( - label: 'Primary Button Negative Disabled', - onPressed: null, - ), - const SizedBox(height: sbbDefaultSpacing), - SBBPrimaryButtonNegative( - label: 'Primary Button Negative Loading', - onPressed: () {}, - isLoading: true, - ), - ], - ), - ), - ), - const SizedBox(height: sbbDefaultSpacing), const SBBListHeader('Secondary Button'), SBBGroup( padding: const EdgeInsets.all(sbbDefaultSpacing), child: Column( children: [ SBBSecondaryButton( - label: 'Secondary Button Default', + label: 'Default', onPressed: () { sbbToast.show(message: 'SBBSecondaryButton'); }, ), const SizedBox(height: sbbDefaultSpacing), const SBBSecondaryButton( - label: 'Secondary Button Disabled', + label: 'Disabled', onPressed: null, ), const SizedBox(height: sbbDefaultSpacing), SBBSecondaryButton( - label: 'Secondary Button Loading', + label: 'Loading', onPressed: () {}, isLoading: true, ), @@ -105,40 +76,40 @@ class ButtonPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SBBTertiaryButtonLarge( - label: 'Tertiary Button Large Default', + label: 'Default', onPressed: () { sbbToast.show(message: 'SBBTertiaryButtonLarge'); }, ), const SizedBox(height: sbbDefaultSpacing), const SBBTertiaryButtonLarge( - label: 'Tertiary Button Large Disabled', + label: 'Disabled', onPressed: null, ), const SizedBox(height: sbbDefaultSpacing), SBBTertiaryButtonLarge( - label: 'Tertiary Button Large Loading', + label: 'Loading', onPressed: () {}, isLoading: true, ), const SizedBox(height: sbbDefaultSpacing), SBBTertiaryButtonLarge( - label: 'Tertiary Button Large Icon', - icon: SBBIcons.plus_small, + label: 'Icon', + icon: SBBIcons.dog_small, onPressed: () { sbbToast.show(message: 'SBBTertiaryButtonLarge'); }, ), const SizedBox(height: sbbDefaultSpacing), const SBBTertiaryButtonLarge( - label: 'Tertiary Button Large Icon Disabled', - icon: SBBIcons.plus_small, + label: 'Icon Disabled', + icon: SBBIcons.dog_small, onPressed: null, ), const SizedBox(height: sbbDefaultSpacing), SBBTertiaryButtonLarge( - label: 'Tertiary Button Large Icon Loading', - icon: SBBIcons.plus_small, + label: 'Icon Loading', + icon: SBBIcons.dog_small, onPressed: () {}, isLoading: true, ), @@ -156,40 +127,40 @@ class ButtonPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SBBTertiaryButtonSmall( - label: 'Tertiary Button Small Default', + label: 'Default', onPressed: () { sbbToast.show(message: 'SBBTertiaryButtonSmall'); }, ), const SizedBox(height: sbbDefaultSpacing), const SBBTertiaryButtonSmall( - label: 'Tertiary Button Small Disabled', + label: 'Disabled', onPressed: null, ), const SizedBox(height: sbbDefaultSpacing), const SBBTertiaryButtonSmall( - label: 'Tertiary Button Small Loading', + label: 'Loading', onPressed: null, isLoading: true, ), const SizedBox(height: sbbDefaultSpacing), SBBTertiaryButtonSmall( - label: 'Tertiary Button Small Icon', - icon: SBBIcons.plus_small, + label: 'Icon', + icon: SBBIcons.dog_small, onPressed: () { sbbToast.show(message: 'SBBTertiaryButtonSmall'); }, ), const SizedBox(height: sbbDefaultSpacing), const SBBTertiaryButtonSmall( - label: 'Tertiary Button Small Icon Disabled', - icon: SBBIcons.plus_small, + label: 'Icon Disabled', + icon: SBBIcons.dog_small, onPressed: null, ), const SizedBox(height: sbbDefaultSpacing), const SBBTertiaryButtonSmall( - label: 'Tertiary Button Small Icon Loading', - icon: SBBIcons.plus_small, + label: 'Icon Loading', + icon: SBBIcons.dog_small, onPressed: null, isLoading: true, ), @@ -208,12 +179,12 @@ class ButtonPage extends StatelessWidget { onPressed: () { sbbToast.show(message: 'SBBIconButtonLarge'); }, - icon: SBBIcons.pen_small, + icon: SBBIcons.glass_cocktail_small, ), const SizedBox(width: sbbDefaultSpacing), const SBBIconButtonLarge( onPressed: null, - icon: SBBIcons.pen_small, + icon: SBBIcons.glass_cocktail_small, ), ], ), @@ -229,86 +200,17 @@ class ButtonPage extends StatelessWidget { onPressed: () { sbbToast.show(message: 'SBBIconButtonSmall'); }, - icon: SBBIcons.circle_information_small_small, + icon: SBBIcons.glass_cocktail_small, ), const SizedBox(width: sbbDefaultSpacing), const SBBIconButtonSmall( onPressed: null, - icon: SBBIcons.circle_information_small_small, + icon: SBBIcons.glass_cocktail_small, ), const SizedBox(width: sbbDefaultSpacing), ], ), ), - const SizedBox(height: sbbDefaultSpacing), - const SBBListHeader('Icon Button Small Negative'), - SBBGroup( - child: Container( - padding: const EdgeInsets.all(sbbDefaultSpacing), - color: style.themeValue(SBBColors.red, SBBColors.transparent), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SBBIconButtonSmallNegative( - onPressed: () { - sbbToast.show(message: 'SBBIconButtonSmallNegative'); - }, - icon: SBBIcons.circle_information_small_small, - ), - const SizedBox(width: sbbDefaultSpacing), - const SBBIconButtonSmallNegative( - onPressed: null, - icon: SBBIcons.circle_information_small_small, - ), - const SizedBox(width: sbbDefaultSpacing), - ], - ), - ), - ), - const SizedBox(height: sbbDefaultSpacing), - const SBBListHeader('Icon Button Small Borderless'), - SBBGroup( - padding: const EdgeInsets.all(sbbDefaultSpacing), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SBBIconButtonSmallBorderless( - onPressed: () { - sbbToast.show(message: 'SBBIconButtonSmallBorderless'); - }, - icon: SBBIcons.drag_small, - ), - const SizedBox(width: sbbDefaultSpacing), - const SBBIconButtonSmallBorderless( - onPressed: null, - icon: SBBIcons.drag_small, - ), - const SizedBox(width: sbbDefaultSpacing), - ], - ), - ), - const SizedBox(height: sbbDefaultSpacing), - const SBBListHeader('Icon Form Button'), - SBBGroup( - padding: const EdgeInsets.all(sbbDefaultSpacing), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SBBIconFormButton( - onPressed: () { - sbbToast.show(message: 'SBBIconFormButton'); - }, - icon: SBBIcons.pen_small, - ), - const SizedBox(width: sbbDefaultSpacing), - const SBBIconFormButton( - onPressed: null, - icon: SBBIcons.pen_small, - ), - ], - ), - ), - const SizedBox(height: sbbDefaultSpacing), ], ), ); diff --git a/example/lib/pages/onboarding_page.dart b/example/lib/pages/onboarding_page.dart index 99f9803..0e78752 100644 --- a/example/lib/pages/onboarding_page.dart +++ b/example/lib/pages/onboarding_page.dart @@ -194,7 +194,7 @@ class _VerticalEndPage extends StatelessWidget { textAlign: TextAlign.center, ), const SizedBox(height: 67), - SBBPrimaryButtonNegative( + SBBPrimaryButton( label: 'Close Onboarding', onPressed: onFinish, ), @@ -240,7 +240,7 @@ class _HorizontalEndPage extends StatelessWidget { textAlign: TextAlign.center, ), const SizedBox(height: 67), - SBBPrimaryButtonNegative( + SBBPrimaryButton( label: 'Close Onboarding', onPressed: onFinish, ), @@ -285,16 +285,24 @@ class _VerticalStartPage extends StatelessWidget { ), textAlign: TextAlign.center, ), - const SizedBox(height: 67), - SBBPrimaryButtonNegative( - label: 'Start Onboarding', - onPressed: onStartOnboarding, - ), - const SizedBox(height: sbbDefaultSpacing), - SBBPrimaryButton( - label: 'Skip Onboarding', - onPressed: onFinish, - ), + const SizedBox(height: sbbDefaultSpacing * 9), + SBBGroup( + padding: EdgeInsets.symmetric(horizontal: sbbDefaultSpacing / 2, vertical: sbbDefaultSpacing), + child: + Column( + children: [ + SBBPrimaryButton( + label: 'Start Onboarding', + onPressed: onStartOnboarding, + ), + const SizedBox(height: sbbDefaultSpacing), + SBBSecondaryButton( + label: 'Skip Onboarding', + onPressed: onFinish, + ), + ], + ) + ) ], ), ), @@ -339,15 +347,23 @@ class _HorizontalStartPage extends StatelessWidget { textAlign: TextAlign.center, ), const SizedBox(height: 67), - SBBPrimaryButtonNegative( - label: 'Start Onboarding', - onPressed: onStartOnboarding, - ), - const SizedBox(height: sbbDefaultSpacing), - SBBPrimaryButton( - label: 'Skip Onboarding', - onPressed: onFinish, - ), + SBBGroup( + padding: EdgeInsets.symmetric(horizontal: sbbDefaultSpacing / 2, vertical: sbbDefaultSpacing), + child: + Column( + children: [ + SBBPrimaryButton( + label: 'Start Onboarding', + onPressed: onStartOnboarding, + ), + const SizedBox(height: sbbDefaultSpacing), + SBBSecondaryButton( + label: 'Skip Onboarding', + onPressed: onFinish, + ), + ], + ) + ) ], ), ), diff --git a/lib/sbb_design_system_mobile.dart b/lib/sbb_design_system_mobile.dart index c657d60..26b332a 100644 --- a/lib/sbb_design_system_mobile.dart +++ b/lib/sbb_design_system_mobile.dart @@ -1,7 +1,6 @@ library sbb_design_system_mobile; export 'src/accordion/sbb_accordion.dart'; -export 'src/button/sbb_button_style_extensions.dart'; export 'src/button/sbb_icon_button.dart'; export 'src/button/sbb_icon_form_button.dart'; export 'src/button/sbb_primary_button.dart'; diff --git a/lib/src/button/sbb_button_style_extensions.dart b/lib/src/button/sbb_button_style_extensions.dart deleted file mode 100644 index 115473c..0000000 --- a/lib/src/button/sbb_button_style_extensions.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../sbb_design_system_mobile.dart'; -import '../sbb_internal.dart'; - -extension SBBButtonStylesExtension on SBBButtonStyles { - /// follows https://digital.sbb.ch/de/design-system-mobile-new/elemente/button - /// - static final ButtonStyle _baseButtonStyle = ButtonStyle( - overlayColor: SBBTheme.allStates(SBBColors.transparent), - shape: SBBTheme.allStates( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - SBBInternal.defaultButtonHeight / 2, - ), - ), - ), - fixedSize: SBBTheme.allStates( - const Size.fromHeight(SBBInternal.defaultButtonHeight)), - padding: SBBTheme.allStates( - const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing)), - elevation: SBBTheme.allStates(0), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - mouseCursor: MaterialStateMouseCursor.clickable, - ); - - ButtonStyle get primaryMobile => - primaryStyle!.overrideButtonStyle(_baseButtonStyle); - - ButtonStyle get primaryMobileNegative => - primaryNegativeStyle!.overrideButtonStyle(_baseButtonStyle); -} diff --git a/lib/src/button/sbb_icon_button.dart b/lib/src/button/sbb_icon_button.dart index 78f6f69..fb2b94f 100644 --- a/lib/src/button/sbb_icon_button.dart +++ b/lib/src/button/sbb_icon_button.dart @@ -6,10 +6,9 @@ import 'package:flutter/rendering.dart'; import '../../sbb_design_system_mobile.dart'; import '../sbb_internal.dart'; -/// Large variant of the SBB Icon Button. Use according to documentation. +/// SBBIconButtonLarge. Use this as [SBBTertiaryButtonLarge] without label. /// -/// The [icon] parameter must not be null. Make sure to use small icons -/// ([sbbIconSizeSmall] - 24x24). +/// The [icon] parameter must not be null. Make sure to use small or medium icons. /// /// If [onPressed] callback is null, then the button will be disabled. /// @@ -35,19 +34,13 @@ class SBBIconButtonLarge extends StatelessWidget { @override Widget build(BuildContext context) { final baseStyle = Theme.of(context).textButtonTheme.style?.copyWith( - minimumSize: SBBTheme.allStates(const Size( - SBBInternal.defaultButtonHeight, - SBBInternal.defaultButtonHeight)), - fixedSize: SBBTheme.allStates(const Size( - SBBInternal.defaultButtonHeight, - SBBInternal.defaultButtonHeight)), + minimumSize: SBBTheme.allStates(const Size(SBBInternal.defaultButtonHeight, SBBInternal.defaultButtonHeight)), + fixedSize: SBBTheme.allStates(const Size(SBBInternal.defaultButtonHeight, SBBInternal.defaultButtonHeight)), padding: SBBTheme.allStates(EdgeInsets.zero), ); final style = buttonStyle != null ? buttonStyle!.merge(baseStyle) - : SBBButtonStyles.of(context) - .iconLargeStyle - ?.overrideButtonStyle(baseStyle); + : SBBButtonStyles.of(context).iconLargeStyle?.overrideButtonStyle(baseStyle); return TextButton( style: style, onPressed: onPressed, @@ -60,16 +53,15 @@ class SBBIconButtonLarge extends StatelessWidget { } } -/// Small variant of the SBB Icon Button. Use according to documentation. +/// SBBIconButtonSmall. Use this as [SBBTertiaryButtonSmall] without label. /// /// The [icon] parameter must not be null. Make sure to use small icons /// ([sbbIconSizeSmall] - 24x24). -/// /// If [onPressed] callback is null, then the button will be disabled. /// /// See also: /// -/// * +/// * class SBBIconButtonSmall extends StatelessWidget { const SBBIconButtonSmall({ super.key, @@ -94,17 +86,14 @@ class SBBIconButtonSmall extends StatelessWidget { } } -/// Small negative variant of the SBB Icon Button. Use according to -/// documentation. +/// Negative variant of the [SBBIconButtonSmall]. +/// +/// THIS IS NOT IN THE MOBILE DESIGN SPECS. Can be removed in a future version. /// /// The [icon] parameter must not be null. Make sure to use small icons /// ([sbbIconSizeSmall] - 24x24). /// /// If [onPressed] callback is null, then the button will be disabled. -/// -/// See also: -/// -/// * class SBBIconButtonSmallNegative extends StatelessWidget { const SBBIconButtonSmallNegative({ super.key, @@ -129,17 +118,15 @@ class SBBIconButtonSmallNegative extends StatelessWidget { } } -/// Small borderless variant of the SBB Icon Button. Use according to -/// documentation. +/// Borderless variant of the [SBBIconButtonSmall]. +/// +/// THIS IS NOT IN THE MOBILE DESIGN SPECS. Can be removed in a future version. /// /// The [icon] parameter must not be null. Make sure to use small icons /// ([sbbIconSizeSmall] - 24x24). /// /// If [onPressed] callback is null, then the button will be disabled. -/// -/// See also: -/// -/// * +@Deprecated("This component is not in the design specs and will be removed in the next major version.") class SBBIconButtonSmallBorderless extends StatelessWidget { const SBBIconButtonSmallBorderless({ super.key, @@ -221,9 +208,9 @@ class _SBBIconButtonSmallRaw extends StatelessWidget { } } -/// Copied from [ButtonStyleButton] +/// Copied from [ButtonStyleButton] in version Flutter SDK 3.24.5 /// -/// A widget to pad the area around a [MaterialButton]'s inner [Material]. +/// A widget to pad the area around a [ButtonStyleButton]'s inner [Material]. /// /// Redirect taps that occur in the padded area around the child to the center /// of the child. This increases the size of the button and the button's @@ -242,8 +229,7 @@ class _InputPadding extends SingleChildRenderObjectWidget { } @override - void updateRenderObject( - BuildContext context, covariant _RenderInputPadding renderObject) { + void updateRenderObject(BuildContext context, covariant _RenderInputPadding renderObject) { renderObject.minSize = minSize; } } @@ -292,9 +278,7 @@ class _RenderInputPadding extends RenderShiftedBox { return 0.0; } - Size _computeSize( - {required BoxConstraints constraints, - required ChildLayouter layoutChild}) { + Size _computeSize({required BoxConstraints constraints, required ChildLayouter layoutChild}) { if (child != null) { final Size childSize = layoutChild(child!, constraints); final double height = math.max(childSize.width, minSize.width); @@ -312,6 +296,21 @@ class _RenderInputPadding extends RenderShiftedBox { ); } + // add this method as soon as 3.19.6 is removed + // @override + // double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) { + // final RenderBox? child = this.child; + // if (child == null) { + // return null; + // } + // final double? result = child.getDryBaseline(constraints, baseline); + // if (result == null) { + // return null; + // } + // final Size childSize = child.getDryLayout(constraints); + // return result + Alignment.center.alongOffset(getDryLayout(constraints) - childSize as Offset).dy; + // } + @override void performLayout() { size = _computeSize( @@ -320,8 +319,7 @@ class _RenderInputPadding extends RenderShiftedBox { ); if (child != null) { final BoxParentData childParentData = child!.parentData! as BoxParentData; - childParentData.offset = - Alignment.center.alongOffset(size - child!.size as Offset); + childParentData.offset = Alignment.center.alongOffset(size - child!.size as Offset); } } @@ -334,7 +332,7 @@ class _RenderInputPadding extends RenderShiftedBox { return result.addWithRawTransform( transform: MatrixUtils.forceToPoint(center), position: center, - hitTest: (BoxHitTestResult result, Offset? position) { + hitTest: (BoxHitTestResult result, Offset position) { assert(position == center); return child!.hitTest(result, position: center); }, diff --git a/lib/src/button/sbb_icon_form_button.dart b/lib/src/button/sbb_icon_form_button.dart index 7f271ad..1026384 100644 --- a/lib/src/button/sbb_icon_form_button.dart +++ b/lib/src/button/sbb_icon_form_button.dart @@ -2,16 +2,15 @@ import 'package:flutter/material.dart'; import '../../sbb_design_system_mobile.dart'; -/// The SBB Icon Form Button. Use according to documentation. +/// The SBB Icon Form Button. +/// +/// THIS IS NOT IN THE MOBILE DESIGN SPECS. Can be removed in a future version. /// /// The [icon] parameter must not be null. Make sure to use small icons /// ([sbbIconSizeSmall] - 24x24). /// /// If [onPressed] callback is null, then the button will be disabled. -/// -/// See also: -/// -/// * +@Deprecated("This component is not in the design specs and will be removed in the next major version.") class SBBIconFormButton extends StatelessWidget { const SBBIconFormButton({ super.key, diff --git a/lib/src/button/sbb_primary_button.dart b/lib/src/button/sbb_primary_button.dart index 802fa88..108b161 100644 --- a/lib/src/button/sbb_primary_button.dart +++ b/lib/src/button/sbb_primary_button.dart @@ -11,9 +11,9 @@ import '../../sbb_design_system_mobile.dart'; /// /// If [onPressed] callback is null, then the button will be disabled. /// -/// See also: +/// For specifications see: /// -/// * +/// * class SBBPrimaryButton extends StatelessWidget { const SBBPrimaryButton({ super.key, @@ -31,8 +31,7 @@ class SBBPrimaryButton extends StatelessWidget { @override Widget build(BuildContext context) { final styles = SBBButtonStyles.of(context); - return ElevatedButton( - style: styles.primaryMobile, + return FilledButton( onPressed: isLoading ? null : onPressed, focusNode: focusNode, child: Row( @@ -46,7 +45,9 @@ class SBBPrimaryButton extends StatelessWidget { } } -/// Negative variant of the SBB Primary Button. Use according to documentation. +/// Negative variant of the [SBBPrimaryButton]. +/// +/// THIS IS NOT IN THE MOBILE DESIGN SPECS. Can be removed in a future version. /// /// The [label] parameter must not be null. /// @@ -54,10 +55,7 @@ class SBBPrimaryButton extends StatelessWidget { /// inside the button and the [onPressed] callback will be ignored. /// /// If [onPressed] callback is null, then the button will be disabled. -/// -/// See also: -/// -/// * +@Deprecated("This component is not in the design specs and will be removed in the next major version.") class SBBPrimaryButtonNegative extends StatelessWidget { const SBBPrimaryButtonNegative({ super.key, @@ -75,8 +73,7 @@ class SBBPrimaryButtonNegative extends StatelessWidget { @override Widget build(BuildContext context) { final styles = SBBButtonStyles.of(context); - return ElevatedButton( - style: styles.primaryMobileNegative, + return FilledButton( onPressed: isLoading ? null : onPressed, focusNode: focusNode, child: Row( diff --git a/lib/src/button/sbb_secondary_button.dart b/lib/src/button/sbb_secondary_button.dart index 2936ea3..2854d50 100644 --- a/lib/src/button/sbb_secondary_button.dart +++ b/lib/src/button/sbb_secondary_button.dart @@ -6,13 +6,14 @@ import '../../sbb_design_system_mobile.dart'; /// /// The [label] parameter must not be null. /// -/// If [isLoading] is true, then the [SBBLoadingIndicator] will be displayed inside the button and the [onPressed] callback will be ignored. +/// If [isLoading] is true, then the [SBBLoadingIndicator] will be displayed +/// inside the button and the [onPressed] callback will be ignored. /// /// If [onPressed] callback is null, then the button will be disabled. /// /// See also: /// -/// * +/// * class SBBSecondaryButton extends StatelessWidget { const SBBSecondaryButton({ super.key, @@ -32,24 +33,18 @@ class SBBSecondaryButton extends StatelessWidget { final style = SBBBaseStyle.of(context); final buttonStyles = SBBButtonStyles.of(context); return OutlinedButton( - style: Theme.of(context).outlinedButtonTheme.style?.copyWith( - padding: SBBTheme.allStates(EdgeInsets.zero), - ), onPressed: isLoading ? null : onPressed, focusNode: focusNode, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (isLoading) - style.themeValue( - const SBBLoadingIndicator.tinySmoke(), - const SBBLoadingIndicator.tinyCement(), - ), - buttonStyles.buttonLabelBuilder!(context, label), - ], - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (isLoading) + style.themeValue( + const SBBLoadingIndicator.tinySmoke(), + const SBBLoadingIndicator.tinyCement(), + ), + buttonStyles.buttonLabelBuilder!(context, label), + ], ), ); } diff --git a/lib/src/button/sbb_tertiary_button.dart b/lib/src/button/sbb_tertiary_button.dart index aea3588..10d0e21 100644 --- a/lib/src/button/sbb_tertiary_button.dart +++ b/lib/src/button/sbb_tertiary_button.dart @@ -5,15 +5,17 @@ import '../sbb_internal.dart'; /// Large variant of the SBB Tertiary Button. Use according to documentation. /// -/// The [label] parameter must not be null. +/// The [label] parameter must not be null. In case you want to show a variant of this button +/// without a label, use the [SBBIconButtonLarge]. /// -/// If [isLoading] is true, then the [SBBLoadingIndicator] will be displayed inside the button and the [onPressed] callback will be ignored. +/// If [isLoading] is true, then the [SBBLoadingIndicator] will be displayed +/// inside the button and the [onPressed] callback will be ignored. /// /// If [onPressed] callback is null, then the button will be disabled. /// /// See also: /// -/// * +/// * class SBBTertiaryButtonLarge extends StatelessWidget { const SBBTertiaryButtonLarge({ super.key, @@ -35,29 +37,19 @@ class SBBTertiaryButtonLarge extends StatelessWidget { final style = SBBBaseStyle.of(context); final buttonStyles = SBBButtonStyles.of(context); return TextButton( - style: Theme.of(context).textButtonTheme.style?.copyWith( - padding: SBBTheme.allStates(EdgeInsets.zero), - ), onPressed: isLoading ? null : onPressed, focusNode: focusNode, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (isLoading) - style.themeValue( - const SBBLoadingIndicator.tinySmoke(), - const SBBLoadingIndicator.tinyCement(), - ) - else if (icon != null) - Padding( - padding: const EdgeInsetsDirectional.only(end: 4.0), - child: Icon(icon, size: sbbIconSizeSmall), - ), - buttonStyles.buttonLabelBuilder!(context, label), - ], - ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isLoading) + style.themeValue( + const SBBLoadingIndicator.tinySmoke(), + const SBBLoadingIndicator.tinyCement(), + ) + else if (icon != null) ...[Icon(icon, size: sbbIconSizeSmall), SizedBox(width: 4.0)], + buttonStyles.buttonLabelBuilder!(context, label), + ], ), ); } @@ -65,7 +57,8 @@ class SBBTertiaryButtonLarge extends StatelessWidget { /// Small variant of the SBB Tertiary Button. Use according to documentation. /// -/// The [label] parameter must not be null. +/// The [label] parameter must not be null. In case you want to show a variant of this button +/// without a label, use the [SBBIconButtonSmall]. /// /// If [isLoading] is true, then the [SBBLoadingIndicator] will be displayed inside the button and the [onPressed] callback will be ignored. /// @@ -73,7 +66,7 @@ class SBBTertiaryButtonLarge extends StatelessWidget { /// /// See also: /// -/// * +/// * class SBBTertiaryButtonSmall extends StatelessWidget { const SBBTertiaryButtonSmall({ super.key, @@ -92,37 +85,40 @@ class SBBTertiaryButtonSmall extends StatelessWidget { @override Widget build(BuildContext context) { - final baseStyle = Theme.of(context).textButtonTheme.style?.copyWith( - fixedSize: SBBTheme.allStates( - const Size.fromHeight(SBBInternal.defaultButtonHeightSmall), - ), - padding: SBBTheme.allStates(EdgeInsets.zero), - ); + final smallButtonStyle = _baseButtonStyleWithSmallerHeight(context); final style = SBBBaseStyle.of(context); final buttonStyle = SBBButtonStyles.of(context); return TextButton( - style: buttonStyle.tertiarySmallStyle?.overrideButtonStyle(baseStyle), + style: smallButtonStyle, onPressed: onPressed, focusNode: focusNode, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (isLoading) - style.themeValue( - const SBBLoadingIndicator.tinyCement(), - const SBBLoadingIndicator.tinySmoke(), - ) - else if (icon != null) - Padding( - padding: const EdgeInsetsDirectional.only(end: 4.0), - child: Icon(icon, size: sbbIconSizeSmall), - ), - buttonStyle.buttonLabelBuilder!(context, label), - ], - ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isLoading) + style.themeValue( + const SBBLoadingIndicator.tinyCement(), + const SBBLoadingIndicator.tinySmoke(), + ) + else if (icon != null) ...[Icon(icon, size: sbbIconSizeSmall), SizedBox(width: 4.0)], + buttonStyle.buttonLabelBuilder!(context, label), + ], ), ); } + + ButtonStyle? _baseButtonStyleWithSmallerHeight(BuildContext context) { + final buttonStyle = SBBButtonStyles.of(context); + + return buttonStyle.tertiarySmallStyle?.overrideButtonStyle( + Theme.of(context).textButtonTheme.style?.copyWith( + fixedSize: SBBTheme.allStates( + const Size.fromHeight(SBBInternal.defaultButtonHeightSmall), + ), + minimumSize: SBBTheme.allStates( + const Size(0, SBBInternal.defaultButtonHeightSmall), + ), + ), + ); + } } diff --git a/lib/src/theme/sbb_theme.dart b/lib/src/theme/sbb_theme.dart index 906613b..eb8565d 100644 --- a/lib/src/theme/sbb_theme.dart +++ b/lib/src/theme/sbb_theme.dart @@ -97,7 +97,7 @@ class SBBTheme { fontFamily: baseStyle.defaultFontFamily, textTheme: baseStyle.createTextTheme(), appBarTheme: controlStyles.appBarTheme, - elevatedButtonTheme: buttonStyles.elevatedButtonTheme, + filledButtonTheme: buttonStyles.filledButtonTheme, outlinedButtonTheme: buttonStyles.outlinedButtonTheme, textButtonTheme: buttonStyles.textButtonTheme, cardTheme: controlStyles.cardTheme, diff --git a/lib/src/theme/styles/src/sbb_button_styles.dart b/lib/src/theme/styles/src/sbb_button_styles.dart index b65f845..cdb1961 100644 --- a/lib/src/theme/styles/src/sbb_button_styles.dart +++ b/lib/src/theme/styles/src/sbb_button_styles.dart @@ -59,64 +59,74 @@ class SBBButtonStyles extends ThemeExtension { backgroundColor: baseStyle.themeValue(SBBColors.white, SBBColors.iron), backgroundColorHighlighted: - baseStyle.themeValue(SBBColors.milk, SBBColors.smoke), + baseStyle.themeValue(SBBColors.graphite, SBBColors.charcoal), backgroundColorDisabled: SBBColors.transparent, backgroundColorLoading: SBBColors.transparent, borderColor: - baseStyle.themeValue(baseStyle.primaryColor, SBBColors.white), + baseStyle.themeValue(baseStyle.primaryColor, SBBColors.smoke), borderColorHighlighted: - baseStyle.themeValue(baseStyle.primaryColorDark, SBBColors.white), + baseStyle.themeValue(baseStyle.primaryColor, SBBColors.smoke), borderColorDisabled: - baseStyle.themeValue(SBBColors.cement, SBBColors.iron), + baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), borderColorLoading: - baseStyle.themeValue(SBBColors.cement, SBBColors.iron), + baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), textStyle: baseStyle.themedTextStyle( color: baseStyle.themeValue( baseStyle.primaryColor, SBBColors.white)), textStyleHighlighted: baseStyle.themedTextStyle( color: baseStyle.themeValue( baseStyle.primaryColorDark, SBBColors.white)), - textStyleDisabled: baseStyle.themedTextStyle(color: SBBColors.metal), - textStyleLoading: baseStyle.themedTextStyle(color: SBBColors.metal), + textStyleDisabled: baseStyle.themedTextStyle(color: baseStyle.themeValue( + SBBColors.graphite, SBBColors.smoke)), + textStyleLoading: baseStyle.themedTextStyle(color: baseStyle.themeValue( + SBBColors.graphite, SBBColors.smoke)), ), tertiarySmallStyle: SBBButtonStyle( backgroundColor: - baseStyle.themeValue(SBBColors.white, SBBColors.transparent), + baseStyle.themeValue(SBBColors.white, SBBColors.charcoal), backgroundColorHighlighted: - baseStyle.themeValue(SBBColors.milk, SBBColors.iron), - backgroundColorDisabled: baseStyle.themeValue( - SBBColors.transparent, SBBColors.transparent), + baseStyle.themeValue(SBBColors.graphite, SBBColors.black), + backgroundColorDisabled: SBBColors.transparent, borderColor: SBBColors.smoke, borderColorHighlighted: SBBColors.smoke, borderColorDisabled: baseStyle.themeValue(SBBColors.cloud, SBBColors.iron), textStyle: - baseStyle.themedTextStyle(textStyle: SBBTextStyles.smallLight), + baseStyle.themedTextStyle(textStyle: SBBTextStyles.mediumLight), textStyleHighlighted: - baseStyle.themedTextStyle(textStyle: SBBTextStyles.smallLight), + baseStyle.themedTextStyle(textStyle: SBBTextStyles.mediumLight), textStyleDisabled: baseStyle.themedTextStyle( - textStyle: SBBTextStyles.smallLight, color: SBBColors.metal), + textStyle: SBBTextStyles.mediumLight, + color: baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), + ), + iconColor: baseStyle.iconColor, + iconColorHighlighted: baseStyle.iconColor, + iconColorDisabled: baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), ), tertiaryLargeStyle: SBBButtonStyle( - backgroundColor: - baseStyle.themeValue(SBBColors.white, SBBColors.transparent), + backgroundColor: + baseStyle.themeValue(SBBColors.white, SBBColors.charcoal), backgroundColorHighlighted: - baseStyle.themeValue(SBBColors.milk, SBBColors.iron), - backgroundColorDisabled: baseStyle.themeValue( - SBBColors.transparent, SBBColors.transparent), + baseStyle.themeValue(SBBColors.graphite, SBBColors.black), + backgroundColorDisabled: SBBColors.transparent, borderColor: SBBColors.smoke, borderColorHighlighted: SBBColors.smoke, borderColorDisabled: baseStyle.themeValue(SBBColors.cloud, SBBColors.iron), textStyle: baseStyle.themedTextStyle(), textStyleHighlighted: baseStyle.themedTextStyle(), - textStyleDisabled: baseStyle.themedTextStyle(color: SBBColors.metal), + textStyleDisabled: baseStyle.themedTextStyle( + color: baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), + ), + iconColor: baseStyle.iconColor, + iconColorHighlighted: baseStyle.iconColor, + iconColorDisabled: baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), ), iconLargeStyle: SBBButtonStyle( backgroundColor: - baseStyle.themeValue(SBBColors.white, SBBColors.transparent), + baseStyle.themeValue(SBBColors.white, SBBColors.charcoal), backgroundColorHighlighted: - baseStyle.themeValue(SBBColors.milk, SBBColors.iron), + baseStyle.themeValue(SBBColors.graphite, SBBColors.black), backgroundColorDisabled: SBBColors.transparent, borderColor: SBBColors.smoke, borderColorHighlighted: SBBColors.smoke, @@ -125,7 +135,7 @@ class SBBButtonStyles extends ThemeExtension { iconColor: baseStyle.iconColor, iconColorHighlighted: baseStyle.iconColor, iconColorDisabled: - baseStyle.themeValue(SBBColors.cloud, SBBColors.iron), + baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), ), iconLargeNegativeStyle: SBBButtonStyle( backgroundColor: SBBColors.transparent, @@ -142,9 +152,9 @@ class SBBButtonStyles extends ThemeExtension { ), iconSmallStyle: SBBButtonStyle( backgroundColor: - baseStyle.themeValue(SBBColors.white, SBBColors.transparent), + baseStyle.themeValue(SBBColors.white, SBBColors.charcoal), backgroundColorHighlighted: - baseStyle.themeValue(SBBColors.milk, SBBColors.iron), + baseStyle.themeValue(SBBColors.graphite, SBBColors.black), backgroundColorDisabled: SBBColors.transparent, borderColor: SBBColors.smoke, borderColorHighlighted: SBBColors.smoke, @@ -153,7 +163,7 @@ class SBBButtonStyles extends ThemeExtension { iconColor: baseStyle.iconColor, iconColorHighlighted: baseStyle.iconColor, iconColorDisabled: - baseStyle.themeValue(SBBColors.cloud, SBBColors.iron), + baseStyle.themeValue(SBBColors.graphite, SBBColors.smoke), ), iconSmallNegativeStyle: SBBButtonStyle( backgroundColor: SBBColors.transparent, @@ -250,7 +260,7 @@ class SBBButtonStyles extends ThemeExtension { mouseCursor: MaterialStateMouseCursor.clickable, ); - ElevatedButtonThemeData get elevatedButtonTheme => ElevatedButtonThemeData( + FilledButtonThemeData get filledButtonTheme => FilledButtonThemeData( style: primaryStyle?.overrideButtonStyle(baseButtonStyle), ); diff --git a/lib/src/toast/sbb_toast.dart b/lib/src/toast/sbb_toast.dart index b680aa4..a4137c4 100644 --- a/lib/src/toast/sbb_toast.dart +++ b/lib/src/toast/sbb_toast.dart @@ -139,7 +139,7 @@ class Toast extends StatefulWidget { stream: stream, backgroundColor: SBBColors.white, textColor: SBBColors.green, - icon: SBBIcons.tick_medium, + icon: SBBIcons.tick_small, ); const Toast.warning({ @@ -154,7 +154,7 @@ class Toast extends StatefulWidget { stream: stream, backgroundColor: SBBColors.orange, textColor: SBBColors.white, - icon: SBBIcons.sign_x_medium, + icon: SBBIcons.sign_x_small, ); const Toast.error({ @@ -169,7 +169,7 @@ class Toast extends StatefulWidget { stream: stream, backgroundColor: SBBColors.red, textColor: SBBColors.white, - icon: SBBIcons.sign_x_medium, + icon: SBBIcons.sign_x_small, ); const Toast({ diff --git a/pubspec.yaml b/pubspec.yaml index e6e1a60..8540dd7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: sdk: flutter # https://pub.dev/packages/intl - intl: "<=0.20.1" + intl: ">=0.18.0" # https://pub.dev/packages/collection collection: ^1.18.0 diff --git a/test/goldens/icon_button.dark.png b/test/goldens/icon_button.dark.png new file mode 100644 index 0000000..8300840 Binary files /dev/null and b/test/goldens/icon_button.dark.png differ diff --git a/test/goldens/icon_button.light.png b/test/goldens/icon_button.light.png new file mode 100644 index 0000000..535ad9e Binary files /dev/null and b/test/goldens/icon_button.light.png differ diff --git a/test/goldens/message_test_3.dark.png b/test/goldens/message_test_3.dark.png index 9a71ac5..e6aa0d0 100644 Binary files a/test/goldens/message_test_3.dark.png and b/test/goldens/message_test_3.dark.png differ diff --git a/test/goldens/message_test_3.light.png b/test/goldens/message_test_3.light.png index 53d981f..d62a1ed 100644 Binary files a/test/goldens/message_test_3.light.png and b/test/goldens/message_test_3.light.png differ diff --git a/test/goldens/onboarding_card1.dark.png b/test/goldens/onboarding_card1.dark.png index 23e7ad6..311a3f5 100644 Binary files a/test/goldens/onboarding_card1.dark.png and b/test/goldens/onboarding_card1.dark.png differ diff --git a/test/goldens/onboarding_card1.light.png b/test/goldens/onboarding_card1.light.png index 6b21b31..9e8a008 100644 Binary files a/test/goldens/onboarding_card1.light.png and b/test/goldens/onboarding_card1.light.png differ diff --git a/test/goldens/onboarding_card2.dark.png b/test/goldens/onboarding_card2.dark.png index 408c872..3f0eb41 100644 Binary files a/test/goldens/onboarding_card2.dark.png and b/test/goldens/onboarding_card2.dark.png differ diff --git a/test/goldens/onboarding_card2.light.png b/test/goldens/onboarding_card2.light.png index 3899d6a..ba247d9 100644 Binary files a/test/goldens/onboarding_card2.light.png and b/test/goldens/onboarding_card2.light.png differ diff --git a/test/goldens/onboarding_endpage.dark.png b/test/goldens/onboarding_endpage.dark.png index 9e7f641..2fe88ff 100644 Binary files a/test/goldens/onboarding_endpage.dark.png and b/test/goldens/onboarding_endpage.dark.png differ diff --git a/test/goldens/onboarding_startpage.dark.png b/test/goldens/onboarding_startpage.dark.png index 8d03200..46ed88b 100644 Binary files a/test/goldens/onboarding_startpage.dark.png and b/test/goldens/onboarding_startpage.dark.png differ diff --git a/test/goldens/primary_button.dark.png b/test/goldens/primary_button.dark.png new file mode 100644 index 0000000..c5ac5bd Binary files /dev/null and b/test/goldens/primary_button.dark.png differ diff --git a/test/goldens/primary_button.light.png b/test/goldens/primary_button.light.png new file mode 100644 index 0000000..3ae7e58 Binary files /dev/null and b/test/goldens/primary_button.light.png differ diff --git a/test/goldens/secondary_button.dark.png b/test/goldens/secondary_button.dark.png new file mode 100644 index 0000000..77d39b8 Binary files /dev/null and b/test/goldens/secondary_button.dark.png differ diff --git a/test/goldens/secondary_button.light.png b/test/goldens/secondary_button.light.png new file mode 100644 index 0000000..1c4516d Binary files /dev/null and b/test/goldens/secondary_button.light.png differ diff --git a/test/goldens/tertiary_button.dark.png b/test/goldens/tertiary_button.dark.png new file mode 100644 index 0000000..8195a1f Binary files /dev/null and b/test/goldens/tertiary_button.dark.png differ diff --git a/test/goldens/tertiary_button.light.png b/test/goldens/tertiary_button.light.png new file mode 100644 index 0000000..e8058c3 Binary files /dev/null and b/test/goldens/tertiary_button.light.png differ diff --git a/test/sbb_icon_button_test.dart b/test/sbb_icon_button_test.dart new file mode 100644 index 0000000..98158c4 --- /dev/null +++ b/test/sbb_icon_button_test.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart'; + +import 'test_app.dart'; + +void main() { + testWidgets('icon_button', (WidgetTester tester) async { + final widget = Padding( + padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing / 2), + child: Column( + children: [ + const SizedBox(height: sbbDefaultSpacing), + SBBIconButtonLarge(onPressed: () {}, icon: SBBIcons.glass_cocktail_small), + const SizedBox(height: sbbDefaultSpacing), + SBBIconButtonLarge(onPressed: null, icon: SBBIcons.glass_cocktail_small), + const SizedBox(height: sbbDefaultSpacing), + SBBIconButtonSmall(onPressed: () {}, icon: SBBIcons.glass_cocktail_small), + const SizedBox(height: sbbDefaultSpacing), + SBBIconButtonSmall(onPressed: null, icon: SBBIcons.glass_cocktail_small), + ], + ), + ); + await TestSpecs.run( + TestSpecs.themedSpecs, + widget, + tester, + 'icon_button', + find.byType(Column).first, + ); + }); +} diff --git a/test/sbb_message_test.dart b/test/sbb_message_test.dart index d834c18..e5e44a7 100644 --- a/test/sbb_message_test.dart +++ b/test/sbb_message_test.dart @@ -45,7 +45,7 @@ void main() { description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate massa ut ex fringilla, vel rutrum nulla pretium. Vivamus auctor ex sed nunc maximus.', onInteraction: () {}, - interactionIcon: SBBIcons.train_medium, + interactionIcon: SBBIcons.train_small, ), ); diff --git a/test/sbb_primary_button_test.dart b/test/sbb_primary_button_test.dart new file mode 100644 index 0000000..b7c15a8 --- /dev/null +++ b/test/sbb_primary_button_test.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart'; + +import 'test_app.dart'; + +void main() { + testWidgets('primary_button', (WidgetTester tester) async { + final widget = Padding( + padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing / 2), + child: Column( + children: [ + const SizedBox(height: sbbDefaultSpacing), + SBBPrimaryButton(label: "Default", onPressed: () {}), + const SizedBox(height: sbbDefaultSpacing), + SBBPrimaryButton(label: "Disabled", onPressed: null), + ], + ), + ); + await TestSpecs.run( + TestSpecs.themedSpecs, + widget, + tester, + 'primary_button', + find.byType(Column).first, + ); + }); +} diff --git a/test/sbb_secondary_button_test.dart b/test/sbb_secondary_button_test.dart new file mode 100644 index 0000000..8fbfbe3 --- /dev/null +++ b/test/sbb_secondary_button_test.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart'; + +import 'test_app.dart'; + +void main() { + testWidgets('secondary_button', (WidgetTester tester) async { + final widget = Padding( + padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing / 2), + + child: Column( + children: [ + const SizedBox(height: sbbDefaultSpacing), + SBBSecondaryButton(label: "Default", onPressed: () {}), + const SizedBox(height: sbbDefaultSpacing), + SBBSecondaryButton(label: "Disabled", onPressed: null), + ], + ), + ); + await TestSpecs.run( + TestSpecs.themedSpecs, + widget, + tester, + 'secondary_button', + find.byType(Column).first, + ); + }); +} diff --git a/test/sbb_tertiary_button_test.dart b/test/sbb_tertiary_button_test.dart new file mode 100644 index 0000000..aeac41a --- /dev/null +++ b/test/sbb_tertiary_button_test.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart'; + +import 'test_app.dart'; + +void main() { + testWidgets('tertiary_button', (WidgetTester tester) async { + final widget = Padding( + padding: const EdgeInsets.symmetric(horizontal: sbbDefaultSpacing / 2), + child: Column( + children: [ + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonLarge(label: "Default", onPressed: () {}), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonLarge(label: "Disabled", onPressed: null), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonLarge(label: "Icon", onPressed: () {}, icon: SBBIcons.dog_small), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonLarge(label: "Icon Disabled", onPressed: null, icon: SBBIcons.dog_small), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonSmall(label: "Default", onPressed: () {}), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonSmall(label: "Disabled", onPressed: null), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonSmall(label: "Icon", onPressed: () {}, icon: SBBIcons.dog_small), + const SizedBox(height: sbbDefaultSpacing), + SBBTertiaryButtonSmall(label: "Icon Disabled", onPressed: null, icon: SBBIcons.dog_small), + ], + ), + ); + await TestSpecs.run( + TestSpecs.themedSpecs, + widget, + tester, + 'tertiary_button', + find.byType(Column).first, + ); + }); +}