diff --git a/example/lib/src/component_library/components/avatar/avatar_library_variant.dart b/example/lib/src/component_library/components/avatar/avatar_library_variant.dart index 05b37a02..1aeb5441 100644 --- a/example/lib/src/component_library/components/avatar/avatar_library_variant.dart +++ b/example/lib/src/component_library/components/avatar/avatar_library_variant.dart @@ -4,8 +4,7 @@ import 'package:impaktfull_ui_example/src/component_library/components/avatar/av import 'package:impaktfull_ui_example/src/component_library/config/component_library_item.dart'; import 'package:impaktfull_ui_example/src/util/network_images.dart'; -class AvatarLibraryVariant - extends ComponentLibraryVariant { +class AvatarLibraryVariant extends ComponentLibraryVariant { const AvatarLibraryVariant(); @override @@ -20,8 +19,7 @@ class AvatarLibraryVariant ), ImpaktfullUiAvatar( url: null, - onTap: () => - ImpaktfullUiNotification.show(title: 'Empty Avatar tapped'), + onTap: () => ImpaktfullUiNotification.show(title: 'Empty Avatar tapped'), ), ]; } diff --git a/example/lib/src/widget/theme/theme_button.dart b/example/lib/src/widget/theme/theme_button.dart index a6ef0f9c..bb8827c8 100644 --- a/example/lib/src/widget/theme/theme_button.dart +++ b/example/lib/src/widget/theme/theme_button.dart @@ -32,10 +32,15 @@ class _ThemeButtonState extends State { assetSuffix: 'theme_dark', ), ImpaktfullUiTheme.custom( - label: 'Blue theme', - primary: const Color.fromARGB(255, 255, 255, 255), - accent: const Color.fromARGB(255, 23, 121, 206), - secondary: const Color.fromARGB(255, 23, 121, 206), + label: 'Light mode (zero border radius)', + primary: const Color(0xFF1A1A1A), + accent: const Color(0xFF7d64f2), + secondary: const Color(0xFF7d64f2), + borderRadiusExtraSmall: BorderRadius.zero, + borderRadiusSmall: BorderRadius.zero, + borderRadius: BorderRadius.zero, + borderRadiusLarge: BorderRadius.zero, + borderRadiusExtraLarge: BorderRadius.zero, package: null, ), ]; diff --git a/lib/src/components/avatar/avatar.dart b/lib/src/components/avatar/avatar.dart index c510752d..640f2978 100644 --- a/lib/src/components/avatar/avatar.dart +++ b/lib/src/components/avatar/avatar.dart @@ -39,6 +39,12 @@ class ImpaktfullUiAvatar extends StatelessWidget with ComponentDescriptorMixin { child: Stack( alignment: Alignment.center, children: [ + Container( + decoration: BoxDecoration( + borderRadius: componentTheme.dimens.borderRadius, + color: componentTheme.colors.background, + ), + ), Container( decoration: BoxDecoration( border: Border.all( @@ -48,23 +54,33 @@ class ImpaktfullUiAvatar extends StatelessWidget with ComponentDescriptorMixin { borderRadius: componentTheme.dimens.borderRadius, color: componentTheme.colors.background, ), - child: ClipRRect( + ), + Positioned.fill( + child: ImpaktfullUiAssetWidget( + asset: placeholderAsset ?? componentTheme.assets.placeholder, + color: componentTheme.colors.placeholder, + size: width / 2, + ), + ), + if (url != null) ...[ + Positioned.fill( + child: ClipRRect( + borderRadius: componentTheme.dimens.borderRadius, + child: Builder( + builder: (context) => ImpaktfullUiNetworkImage( + url: url!, + ), + ), + ), + ), + ], + Container( + decoration: BoxDecoration( + border: Border.all( + color: componentTheme.colors.border, + width: 1, + ), borderRadius: componentTheme.dimens.borderRadius, - child: Builder(builder: (context) { - if (url == null) { - return Center( - child: ImpaktfullUiAssetWidget( - asset: placeholderAsset ?? - componentTheme.assets.placeholder, - color: componentTheme.colors.placeholder, - size: width / 2, - ), - ); - } - return ImpaktfullUiNetworkImage( - url: url!, - ); - }), ), ), if (onTap != null) ...[ diff --git a/lib/src/components/checkbox/checkbox.describe.dart b/lib/src/components/checkbox/checkbox.describe.dart index 2e5dc381..263f5080 100644 --- a/lib/src/components/checkbox/checkbox.describe.dart +++ b/lib/src/components/checkbox/checkbox.describe.dart @@ -2,7 +2,7 @@ part of 'checkbox.dart'; String _describeInstance(BuildContext context, ImpaktfullUiCheckBox instance) { final descriptor = ComponentDescriptor(); - descriptor.add('value', instance.value); + descriptor.add('value', instance.value ?? 'null'); descriptor.add('onChanged', instance.onChanged); descriptor.add('theme', instance.theme); return descriptor.describe(); diff --git a/lib/src/components/notification_badge/notification_badge.dart b/lib/src/components/notification_badge/notification_badge.dart index 42ee2cc6..7ecccaf3 100644 --- a/lib/src/components/notification_badge/notification_badge.dart +++ b/lib/src/components/notification_badge/notification_badge.dart @@ -18,8 +18,9 @@ enum ImpaktfullUiNotificationBadgeLocation { const ImpaktfullUiNotificationBadgeLocation(this.alignment); } -class ImpaktfullUiNotificationBadge extends StatelessWidget - with ComponentDescriptorMixin { +class ImpaktfullUiNotificationBadge extends StatelessWidget with ComponentDescriptorMixin { + static const dotSize = 4.0; + final bool show; final Color? color; final String? text; @@ -39,8 +40,7 @@ class ImpaktfullUiNotificationBadge extends StatelessWidget @override Widget build(BuildContext context) { - return ImpaktfullUiComponentThemeBuidler< - ImpaktfullUiNotificationBadgeTheme>( + return ImpaktfullUiComponentThemeBuidler( overrideComponentTheme: theme, builder: (context, theme, componentTheme) { final showBadge = show || text != null; @@ -49,121 +49,111 @@ class ImpaktfullUiNotificationBadge extends StatelessWidget final textSize = _textWidth(text ?? '', textStyle); final textWidth = textSize.width + 12; final textHeight = textSize.height; - return Center( - child: Stack( - clipBehavior: Clip.none, - children: [ - child, - Positioned( - top: _getTop(textWidth, textHeight), - bottom: _getBottom(textWidth, textHeight), - right: _getRight(textWidth, textHeight), - left: _getLeft(textWidth, textHeight), - child: AnimatedOpacity( - opacity: showBadge ? 1 : 0, - duration: componentTheme.durations.opacity, - child: Transform.scale( - scale: 0.75, - child: Container( - constraints: const BoxConstraints( - minWidth: 16, - minHeight: 16, - ), - decoration: BoxDecoration( - color: color, - borderRadius: componentTheme.dimens.borderRadius, - border: componentTheme.colors.border == null - ? null - : Border.all( - color: componentTheme.colors.border!, - width: 2, - strokeAlign: BorderSide.strokeAlignOutside, - ), - ), - alignment: Alignment.center, - child: Builder( - builder: (context) { - if (text == null) { - return Container( - width: 4, - height: 4, - decoration: BoxDecoration( - color: color, - borderRadius: - componentTheme.dimens.borderRadius, - ), - ); - } - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Text( - text ?? '', - style: componentTheme.textStyles.text, - textAlign: TextAlign.center, + return Stack( + clipBehavior: Clip.none, + children: [ + child, + Positioned( + top: _getTop(dotSize, textWidth, textHeight), + bottom: _getBottom(dotSize, textWidth, textHeight), + right: _getRight(dotSize, textWidth, textHeight), + left: _getLeft(dotSize, textWidth, textHeight), + child: AnimatedOpacity( + opacity: showBadge ? 1 : 0, + duration: componentTheme.durations.opacity, + child: Transform.scale( + scale: 0.75, + child: Container( + constraints: const BoxConstraints( + minWidth: 16, + minHeight: 16, + ), + decoration: BoxDecoration( + color: color, + borderRadius: componentTheme.dimens.borderRadius, + border: componentTheme.colors.border == null + ? null + : Border.all( + color: componentTheme.colors.border!, + width: 2, + strokeAlign: BorderSide.strokeAlignOutside, + ), + ), + alignment: Alignment.center, + child: Builder( + builder: (context) { + if (text == null) { + return Container( + width: dotSize, + height: dotSize, + decoration: BoxDecoration( + color: color, + borderRadius: componentTheme.dimens.borderRadius, ), ); - }, - ), + } + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Text( + text ?? '', + style: componentTheme.textStyles.text, + textAlign: TextAlign.center, + ), + ); + }, ), ), ), ), - ], - ), + ), + ], ); }, ); } Size _textWidth(String text, TextStyle style) { - final TextPainter textPainter = TextPainter( - text: TextSpan(text: text, style: style), - maxLines: 1, - textDirection: TextDirection.ltr) - ..layout(minWidth: 0, maxWidth: double.infinity); + final TextPainter textPainter = + TextPainter(text: TextSpan(text: text, style: style), maxLines: 1, textDirection: TextDirection.ltr) + ..layout(minWidth: 0, maxWidth: double.infinity); return textPainter.size; } - double? _getTop(double textWidth, double textHeight) { + double? _getTop(double dotSize, double textWidth, double textHeight) { final alignment = location.alignment; if (alignment == Alignment.bottomCenter || alignment == Alignment.bottomLeft || alignment == Alignment.bottomRight) { return null; } - if (text == null) return -4; + if (text == null) return -(dotSize / 2); return -(textHeight / 2); } - double? _getBottom(double textWidth, double textHeight) { + double? _getBottom(double dotSize, double textWidth, double textHeight) { final alignment = location.alignment; - if (alignment == Alignment.topCenter || - alignment == Alignment.topLeft || - alignment == Alignment.topRight) { + if (alignment == Alignment.topCenter || alignment == Alignment.topLeft || alignment == Alignment.topRight) { return null; } - if (text == null) return -4; + if (text == null) return -(dotSize / 2); return -(textHeight / 2); } - double? _getRight(double textWidth, double textHeight) { + double? _getRight(double dotSize, double textWidth, double textHeight) { final alignment = location.alignment; - if (alignment == Alignment.centerLeft || - alignment == Alignment.topLeft || - alignment == Alignment.bottomLeft) { + if (alignment == Alignment.centerLeft || alignment == Alignment.topLeft || alignment == Alignment.bottomLeft) { return null; } - if (text == null) return -4; + if (text == null) return -(dotSize / 2); return -(textWidth / 2); } - double? _getLeft(double textWidth, double textHeight) { + double? _getLeft(double dotSize, double textWidth, double textHeight) { final alignment = location.alignment; - if (alignment == Alignment.centerRight || - alignment == Alignment.topRight || - alignment == Alignment.bottomRight) { + if (alignment == Alignment.centerRight || alignment == Alignment.topRight || alignment == Alignment.bottomRight) { return null; } + if (text == null) return -(dotSize / 2); return -(textWidth / 2); }