From d2d653b76e23f2c496214c0411cb898fa4c235a4 Mon Sep 17 00:00:00 2001 From: Dominik Mosberger <9129636+mosberger@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:33:57 +0200 Subject: [PATCH] feat: implement all notification box styles (#151) --- CHANGELOG.md | 1 + example/lib/pages/notification_box_page.dart | 71 +++++++++++++++++++ .../notification_box/notification_box.dart | 56 ++++++++++----- .../notification_box.type.dart | 4 +- .../notification_box_content.dart | 17 +++-- .../notification_box_text_content.dart | 31 ++++++++ .../notification_box_title_content.dart | 25 +++---- 7 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 lib/src/notification_box/notification_box_text_content.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce2c705..fb74cdbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ It is expected that you keep this format strictly, since we depend on it in our ## [Unreleased] - (#148) Update SBB icons to version 1.0.0 +- Implement all Notification Box Styles [Figma Link](https://www.figma.com/design/WOtLIam1xwrqcgnAITsEhV/Design-System-Mobile?m=auto&node-id=7271-28&t=gismRyaDdiCfaHBj-1) ### Deprecated diff --git a/example/lib/pages/notification_box_page.dart b/example/lib/pages/notification_box_page.dart index 6cd25f50..bbda5176 100644 --- a/example/lib/pages/notification_box_page.dart +++ b/example/lib/pages/notification_box_page.dart @@ -31,10 +31,27 @@ class _NotificationBoxPage extends State { onTap: () {}, ), SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.alert( + text: text, + ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.alert( + title: title, + text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, + ), + SizedBox(height: sbbDefaultSpacing), SBBNotificationBox.alert( text: text, onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, ), + SizedBox(height: sbbDefaultSpacing), ], ), ), @@ -46,10 +63,28 @@ class _NotificationBoxPage extends State { SBBNotificationBox.warning( title: title, text: text, + onTap: () {}, + ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.warning( + text: text, + ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.warning( + title: title, + text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, ), SizedBox(height: sbbDefaultSpacing), SBBNotificationBox.warning( text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, ), ], ), @@ -62,11 +97,29 @@ class _NotificationBoxPage extends State { SBBNotificationBox.success( title: title, text: text, + onTap: () {}, ), SizedBox(height: sbbDefaultSpacing), SBBNotificationBox.success( text: text, ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.success( + title: title, + text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, + ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.success( + text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, + ), ], ), ), @@ -77,12 +130,30 @@ class _NotificationBoxPage extends State { children: [ SBBNotificationBox.information( title: title, + onTap: () {}, text: text, ), SizedBox(height: sbbDefaultSpacing), SBBNotificationBox.information( text: text, ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.information( + title: title, + text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, + ), + SizedBox(height: sbbDefaultSpacing), + SBBNotificationBox.information( + text: text, + onTap: () {}, + hasIcon: false, + isCloseable: false, + detailsIcon: SBBIcons.arrows_circle_small, + ), ], ), ), diff --git a/lib/src/notification_box/notification_box.dart b/lib/src/notification_box/notification_box.dart index 19a263db..13c531ca 100644 --- a/lib/src/notification_box/notification_box.dart +++ b/lib/src/notification_box/notification_box.dart @@ -11,7 +11,7 @@ part 'notification_box.type.dart'; class SBBNotificationBox extends StatefulWidget { const SBBNotificationBox({ - required this.type, + required this.state, required this.text, super.key, this.title, @@ -19,6 +19,8 @@ class SBBNotificationBox extends StatefulWidget { this.onTap, this.isCloseable = true, this.onClose, + this.hasIcon = true, + this.detailsIcon = SBBIcons.chevron_small_right_small, }); factory SBBNotificationBox.alert({ @@ -28,15 +30,19 @@ class SBBNotificationBox extends StatefulWidget { GestureTapCallback? onTap, bool isCloseable = true, GestureTapCallback? onClose, + bool hasIcon = true, + IconData detailsIcon = SBBIcons.chevron_small_right_small, }) => SBBNotificationBox( - type: SBBNotificationBoxType.alert, + state: SBBNotificationBoxState.alert, title: title, text: text, onControllerCreated: onControllerCreated, onTap: onTap, isCloseable: isCloseable, onClose: onClose, + hasIcon: hasIcon, + detailsIcon: detailsIcon, ); factory SBBNotificationBox.warning({ @@ -46,15 +52,19 @@ class SBBNotificationBox extends StatefulWidget { GestureTapCallback? onTap, bool isCloseable = true, GestureTapCallback? onClose, + bool hasIcon = true, + IconData detailsIcon = SBBIcons.chevron_small_right_small, }) => SBBNotificationBox( - type: SBBNotificationBoxType.warning, + state: SBBNotificationBoxState.warning, title: title, text: text, onControllerCreated: onControllerCreated, onTap: onTap, isCloseable: isCloseable, onClose: onClose, + hasIcon: hasIcon, + detailsIcon: detailsIcon, ); factory SBBNotificationBox.success({ @@ -64,15 +74,19 @@ class SBBNotificationBox extends StatefulWidget { GestureTapCallback? onTap, bool isCloseable = true, GestureTapCallback? onClose, + bool hasIcon = true, + IconData detailsIcon = SBBIcons.chevron_small_right_small, }) => SBBNotificationBox( - type: SBBNotificationBoxType.success, + state: SBBNotificationBoxState.success, title: title, text: text, onControllerCreated: onControllerCreated, onTap: onTap, isCloseable: isCloseable, onClose: onClose, + hasIcon: hasIcon, + detailsIcon: detailsIcon, ); factory SBBNotificationBox.information({ @@ -82,24 +96,30 @@ class SBBNotificationBox extends StatefulWidget { GestureTapCallback? onTap, bool isCloseable = true, GestureTapCallback? onClose, + bool hasIcon = true, + IconData detailsIcon = SBBIcons.chevron_small_right_small, }) => SBBNotificationBox( - type: SBBNotificationBoxType.information, + state: SBBNotificationBoxState.information, title: title, text: text, onControllerCreated: onControllerCreated, onTap: onTap, isCloseable: isCloseable, onClose: onClose, + hasIcon: hasIcon, + detailsIcon: detailsIcon, ); - final SBBNotificationBoxType type; + final SBBNotificationBoxState state; final String? title; final String text; final Function(CloseableBoxController controller)? onControllerCreated; final GestureTapCallback? onTap; final bool isCloseable; final GestureTapCallback? onClose; + final bool hasIcon; + final IconData detailsIcon; @override State createState() => _SBBNotificationBoxState(); @@ -132,13 +152,16 @@ class _SBBNotificationBoxState extends State @override Widget build(BuildContext context) { final iconColor = SBBBaseStyle.of(context).themeValue( - widget.type.iconColor, - widget.type.iconColorDark, - ); - final icon = Icon( - widget.type.icon, - color: iconColor, + widget.state.iconColor, + widget.state.iconColorDark, ); + final icon = widget.hasIcon + ? Icon( + widget.state.icon, + color: iconColor, + ) + : null; + final detailsIcon = widget.onTap != null ? Icon(widget.detailsIcon) : null; Widget child; switch (widget.title) { case null: @@ -146,13 +169,14 @@ class _SBBNotificationBoxState extends State icon: icon, text: widget.text, isCloseable: widget.isCloseable, + detailsIcon: detailsIcon, ); default: child = SBBNotificationBoxTitleContent( icon: icon, title: widget.title!, text: widget.text, - hasDetails: widget.onTap != null, + detailsIcon: detailsIcon, ); } return _animationBuilder( @@ -165,7 +189,7 @@ class _SBBNotificationBoxState extends State decoration: BoxDecoration( border: Border( left: BorderSide( - color: widget.type.backgroundColor, width: 8.0), + color: widget.state.backgroundColor, width: 8.0), ), borderRadius: BorderRadius.all( Radius.circular(16.0), @@ -173,14 +197,14 @@ class _SBBNotificationBoxState extends State ), child: Container( decoration: BoxDecoration( - border: Border.all(color: widget.type.backgroundColor), + border: Border.all(color: widget.state.backgroundColor), borderRadius: BorderRadius.only( topLeft: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), topRight: Radius.circular(15.0), bottomRight: Radius.circular(15.0), ), - color: widget.type.backgroundColor.withOpacity(.05), + color: widget.state.backgroundColor.withOpacity(.05), ), padding: const EdgeInsets.all(sbbDefaultSpacing), child: child, diff --git a/lib/src/notification_box/notification_box.type.dart b/lib/src/notification_box/notification_box.type.dart index 82a6f4e5..7eb16b3a 100644 --- a/lib/src/notification_box/notification_box.type.dart +++ b/lib/src/notification_box/notification_box.type.dart @@ -1,6 +1,6 @@ part of 'notification_box.dart'; -enum SBBNotificationBoxType { +enum SBBNotificationBoxState { alert( SBBColors.red, SBBColors.red, @@ -26,7 +26,7 @@ enum SBBNotificationBoxType { SBBIcons.circle_information_small, ); - const SBBNotificationBoxType( + const SBBNotificationBoxState( this.backgroundColor, this.iconColor, this.iconColorDark, diff --git a/lib/src/notification_box/notification_box_content.dart b/lib/src/notification_box/notification_box_content.dart index 81ed99bf..8f64722a 100644 --- a/lib/src/notification_box/notification_box_content.dart +++ b/lib/src/notification_box/notification_box_content.dart @@ -1,27 +1,34 @@ +import 'package:design_system_flutter/src/notification_box/notification_box_text_content.dart'; import 'package:flutter/material.dart'; import '../../design_system_flutter.dart'; class SBBNotificationBoxContent extends StatelessWidget { const SBBNotificationBoxContent({ - required this.icon, required this.text, required this.isCloseable, super.key, + this.icon, + this.detailsIcon, }); - final Widget icon; + final Widget? icon; final String text; final bool isCloseable; + final Widget? detailsIcon; @override Widget build(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - icon, - SizedBox(width: 8.0), - Expanded(child: Text(text)), + if (icon != null) ...[ + icon!, + SizedBox(width: 8.0), + ], + Expanded( + child: NotificationBoxTextContent(text: text, icon: detailsIcon), + ), if (isCloseable) const SizedBox(width: sbbIconSizeSmall), ], ); diff --git a/lib/src/notification_box/notification_box_text_content.dart b/lib/src/notification_box/notification_box_text_content.dart new file mode 100644 index 00000000..91c4ef9d --- /dev/null +++ b/lib/src/notification_box/notification_box_text_content.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +class NotificationBoxTextContent extends StatelessWidget { + const NotificationBoxTextContent({ + required this.text, + super.key, + this.clip = true, + this.icon, + }); + + final String text; + final bool clip; + final Widget? icon; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: Text( + text, + maxLines: clip ? 3 : null, + overflow: clip ? TextOverflow.ellipsis : null, + ), + ), + SizedBox(width: 8.0), + if (icon != null) icon!, + ], + ); + } +} diff --git a/lib/src/notification_box/notification_box_title_content.dart b/lib/src/notification_box/notification_box_title_content.dart index 6591955c..0923faf5 100644 --- a/lib/src/notification_box/notification_box_title_content.dart +++ b/lib/src/notification_box/notification_box_title_content.dart @@ -1,20 +1,19 @@ +import 'package:design_system_flutter/src/notification_box/notification_box_text_content.dart'; import 'package:flutter/material.dart'; -import '../../design_system_flutter.dart'; - class SBBNotificationBoxTitleContent extends StatelessWidget { const SBBNotificationBoxTitleContent({ - required this.icon, required this.title, required this.text, - required this.hasDetails, super.key, + this.icon, + this.detailsIcon, }); - final Widget icon; + final Widget? icon; final String title; final String text; - final bool hasDetails; + final Widget? detailsIcon; @override Widget build(BuildContext context) { @@ -22,8 +21,10 @@ class SBBNotificationBoxTitleContent extends StatelessWidget { children: [ Row( children: [ - icon, - SizedBox(width: 8.0), + if (icon != null) ...[ + icon!, + SizedBox(width: 8.0), + ], Expanded( child: Text( title, @@ -33,13 +34,7 @@ class SBBNotificationBoxTitleContent extends StatelessWidget { ], ), SizedBox(height: 8.0), - Row( - children: [ - Expanded(child: Text(text)), - SizedBox(width: 8.0), - if (hasDetails) Icon(SBBIcons.chevron_small_right_small), - ], - ), + NotificationBoxTextContent(text: text, icon: detailsIcon), ], ); }