From 3f5150814a2372381a91816fb4e0300c91965421 Mon Sep 17 00:00:00 2001 From: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:24:32 +0100 Subject: [PATCH] fix: Avatar update (#30) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * Component dialog (#18) * create showZetaDialog * finished dialog for DeviceType.mobilePortrait * dialog variant for bigger screens * create widgetbook; add Zeta parameter, also in ZetaButton * useRootNavigator: false * feat(main): AppBar (#19) * feat(main): AppBar * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * Component dialog (#22) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * create showZetaDialog * finished dialog for DeviceType.mobilePortrait * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * dialog variant for bigger screens * create widgetbook; add Zeta parameter, also in ZetaButton * useRootNavigator: false * add iconKnob in Dialog widgetbook * final iconData = iconKnob --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> * Merge * Component phone input (#21) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> * restore main.dart in example (#23) * Component phone input (#24) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog * don't use root navigator in widgetbook --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> * Component phone input (#25) * chore: update contributing * fix: Fix button group immutability (#1) * Fix errors * fix copywith function * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * [automated commit] lint format and import sort * update on-main to push to firebase (#3) * ci: move firebase to flutter main host for qa (#4) * feat: Add List Item (#5) * feat: Add List Item * [automated commit] lint format and import sort --------- Co-authored-by: Simeon Dimitrov Co-authored-by: github-actions * fix(main): ListItem disabled color (#8) * fix(main): ListItem disabled color * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat : Dropdown menu (#7) * Create dropdown * Add sizes * create stoyrybook and add size * Fix errrs and respond to comments * Fix issues * [automated commit] lint format and import sort * Alter isLarge * Fix spacing * [automated commit] lint format and import sort * Alter leading styles * [automated commit] lint format and import sort --------- Co-authored-by: Osman Co-authored-by: github-actions * Component ZetaSwitch (#6) * create ZetaSwitch * ZetaSwitch using MaterialSwitch * widgetbook for ZetaSwitch * remove hover; fix initState * add showHover parameter * add comments 'Zeta change' in material_switch.dart * remove size parameter and factory constructors * fix example and widgetbook * Component Zeta Radio Button (#9) * create component Zeta Radio Button * remove hover color * fix label line height * feat(main): SnackBar (#10) * add snackbar example * Add snackbar widgetbook * feat(main): SnackBar * [automated commit] lint format and import sort * remove view icon * Add view icon * Add widgetbook icon helper * [automated commit] lint format and import sort * fix alphabetical imports * Fix delete and error background color --------- Co-authored-by: github-actions * feat(main): Tabs (#11) * feat(main): Tabs * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * chore: Update text styles (#13) * fix: switch on web (#14) * Component date input (#12) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * Component date input (#16) * create ZetaDateInput * create different ZetaDateInput variants * fix show error style * date validation and input mask; documentation for ZetaDateInput properties * create widgetbook * changes according to comments * fix Typography of Date Input * restore * remove text line height * ZetaPhoneInput initial commit * complete ZetaPhoneInput; add flags * create phoneInputUseCase in Widgetbook * refactor phone input to use native alert dialog * don't use root navigator in widgetbook * pass parameter useRootNavigator * restore some missing countries in the list --------- Co-authored-by: Luke Co-authored-by: ahmed-osman3 <99483750+ahmed-osman3@users.noreply.github.com> Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> * Update avatar * Update avatar * [automated commit] lint format and import sort * Navigation rail (#27) * create NavigationRail * restore main.dart in example * navigation rail example * create widgetbook * add SafeArea; rename parameter wordWrap * add MouseRegion & SelectionContainer.disabled * Respond to comments * Component tooltip (#31) * create tooltip * create Widgetbook for ZetaTooltip * add LayoutBuilder * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * feat(main): Segmented control (#26) * feat(main): AppBar * Add segmented control * [automated commit] lint format and import sort * Fix mouse cursor, disable selection container and tap area * [automated commit] lint format and import sort --------- Co-authored-by: github-actions * [automated commit] lint format and import sort * Add pill notifications * [automated commit] lint format and import sort * Remove notification border * Change sizes --------- Co-authored-by: Luke Co-authored-by: Osman Co-authored-by: github-actions Co-authored-by: Luke Walton Co-authored-by: Simeon Dimitrov Co-authored-by: atanasyordanov21 <63714308+atanasyordanov21@users.noreply.github.com> Co-authored-by: sd-athlon <163880004+sd-athlon@users.noreply.github.com> --- .../lib/pages/components/avatar_example.dart | 56 ++-- .../pages/components/avatar_widgetbook.dart | 25 +- lib/src/components/avatars/avatar.dart | 310 ++++++++++++++---- lib/src/components/buttons/button_group.dart | 5 +- lib/src/theme/tokens.dart | 6 + 5 files changed, 301 insertions(+), 101 deletions(-) diff --git a/example/lib/pages/components/avatar_example.dart b/example/lib/pages/components/avatar_example.dart index 39f42a8f..ad683953 100644 --- a/example/lib/pages/components/avatar_example.dart +++ b/example/lib/pages/components/avatar_example.dart @@ -202,7 +202,7 @@ class AvatarExample extends StatelessWidget { children: [ ZetaAvatar.image( size: size, - upperBadge: ZetaIndicator.notification(value: 3), + upperBadge: ZetaAvatarBadge.notification(value: 3), ), const SizedBox(height: 20), ], @@ -217,7 +217,7 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.image( size: size, borderColor: Zeta.of(context).colors.green, - upperBadge: ZetaIndicator.notification(value: 3), + upperBadge: ZetaAvatarBadge.notification(value: 3), ), const SizedBox(height: 20), ], @@ -231,7 +231,7 @@ class AvatarExample extends StatelessWidget { children: [ ZetaAvatar.image( size: size, - upperBadge: ZetaIndicator.notification(value: 3), + upperBadge: ZetaAvatarBadge.notification(value: 3), image: image, ), const SizedBox(height: 20), @@ -247,7 +247,7 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.image( size: size, borderColor: Zeta.of(context).colors.green, - upperBadge: ZetaIndicator.notification(value: 3), + upperBadge: ZetaAvatarBadge.notification(value: 3), image: image, ), const SizedBox(height: 20), @@ -294,7 +294,7 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.initials( size: size, initials: 'AB', - upperBadge: ZetaIndicator.notification(value: 3), + upperBadge: ZetaAvatarBadge.notification(value: 3), ), const SizedBox(height: 20), ], @@ -310,7 +310,7 @@ class AvatarExample extends StatelessWidget { size: size, initials: 'AB', borderColor: Zeta.of(context).colors.green, - upperBadge: ZetaIndicator.notification(value: 3), + upperBadge: ZetaAvatarBadge.notification(value: 3), ), const SizedBox(height: 20), ], @@ -355,7 +355,7 @@ class AvatarExample extends StatelessWidget { children: [ ZetaAvatar.image( size: size, - lowerBadge: ZetaIndicator.icon(), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -370,7 +370,7 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.image( size: size, borderColor: Zeta.of(context).colors.green, - lowerBadge: ZetaIndicator.icon(), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -384,7 +384,7 @@ class AvatarExample extends StatelessWidget { children: [ ZetaAvatar.image( size: size, - lowerBadge: ZetaIndicator.icon(), + lowerBadge: ZetaAvatarBadge.icon(), image: image, ), const SizedBox(height: 20), @@ -400,7 +400,7 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.image( size: size, borderColor: Zeta.of(context).colors.green, - lowerBadge: ZetaIndicator.icon(), + lowerBadge: ZetaAvatarBadge.icon(), image: image, ), const SizedBox(height: 20), @@ -447,7 +447,7 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.initials( size: size, initials: 'AB', - lowerBadge: ZetaIndicator.icon(), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -463,7 +463,7 @@ class AvatarExample extends StatelessWidget { size: size, initials: 'AB', borderColor: Zeta.of(context).colors.green, - lowerBadge: ZetaIndicator.icon(), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -509,8 +509,8 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.image( size: size, image: image, - upperBadge: ZetaIndicator.notification(value: 3), - lowerBadge: ZetaIndicator.icon(), + upperBadge: ZetaAvatarBadge.notification(value: 3), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -526,8 +526,8 @@ class AvatarExample extends StatelessWidget { size: size, image: image, borderColor: Zeta.of(context).colors.green, - upperBadge: ZetaIndicator.notification(value: 3), - lowerBadge: ZetaIndicator.icon(), + upperBadge: ZetaAvatarBadge.notification(value: 3), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -541,8 +541,8 @@ class AvatarExample extends StatelessWidget { ZetaAvatar.initials( size: size, initials: 'AB', - upperBadge: ZetaIndicator.notification(value: 3), - lowerBadge: ZetaIndicator.icon(), + upperBadge: ZetaAvatarBadge.notification(value: 3), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -558,8 +558,8 @@ class AvatarExample extends StatelessWidget { size: size, initials: 'AB', borderColor: Zeta.of(context).colors.green, - upperBadge: ZetaIndicator.notification(value: 3), - lowerBadge: ZetaIndicator.icon(), + upperBadge: ZetaAvatarBadge.notification(value: 3), + lowerBadge: ZetaAvatarBadge.icon(), ), const SizedBox(height: 20), ], @@ -580,15 +580,23 @@ class AvatarExample extends StatelessWidget { extension on ZetaAvatarSize { double get pixelSize { switch (this) { + case ZetaAvatarSize.xxxl: + return ZetaSpacing.x50; + case ZetaAvatarSize.xxl: + return ZetaSpacing.x30; case ZetaAvatarSize.xl: - return ZetaSpacing.x16; + return ZetaSpacing.x20; case ZetaAvatarSize.l: - return ZetaSpacing.x12; + return ZetaSpacing.x16; case ZetaAvatarSize.m: - return ZetaSpacing.x10; + return ZetaSpacing.x12; case ZetaAvatarSize.s: - return ZetaSpacing.x8; + return ZetaSpacing.x10; case ZetaAvatarSize.xs: + return ZetaSpacing.x9; + case ZetaAvatarSize.xxs: + return ZetaSpacing.x8; + case ZetaAvatarSize.xxxs: return ZetaSpacing.x6; } } diff --git a/example/widgetbook/pages/components/avatar_widgetbook.dart b/example/widgetbook/pages/components/avatar_widgetbook.dart index f533cf08..488cd5a0 100644 --- a/example/widgetbook/pages/components/avatar_widgetbook.dart +++ b/example/widgetbook/pages/components/avatar_widgetbook.dart @@ -6,6 +6,7 @@ import '../../test/test_components.dart'; Widget avatarUseCase(BuildContext context) { final Widget image = Image.asset('assets/Omer.jpg', fit: BoxFit.cover); + final colors = Zeta.of(context).colors; return WidgetbookTestWidget( widget: ZetaAvatar( @@ -15,12 +16,26 @@ Widget avatarUseCase(BuildContext context) { options: ZetaAvatarSize.values, labelBuilder: (value) => value.name.split('.').last.toUpperCase(), ), - lowerBadge: context.knobs.boolean(label: 'Status Badge', initialValue: false) ? ZetaIndicator.icon() : null, - borderColor: context.knobs.colorOrNull(label: 'Outline', initialValue: null), - upperBadge: - context.knobs.boolean(label: 'Notification Badge', initialValue: false) ? ZetaIndicator.notification() : null, + upperBadge: context.knobs.boolean(label: 'Status Badge', initialValue: false) + ? ZetaAvatarBadge.icon( + icon: ZetaIcons.close_round, + iconColor: context.knobs.colorOrNull(label: "Badge Icon Color"), + color: context.knobs.colorOrNull(label: "Upper Badge Color", initialValue: colors.green) ?? + colors.iconDefault, + ) + : null, + borderColor: context.knobs.colorOrNull( + label: 'Outline', + ), + lowerBadge: context.knobs.boolean(label: 'Notification Badge', initialValue: false) + ? ZetaAvatarBadge.notification( + value: context.knobs.intOrNull.input(label: "Value", initialValue: 1), + ) + : null, initials: context.knobs.stringOrNull(label: 'Initials', initialValue: null), - backgroundColor: context.knobs.colorOrNull(label: 'Background color'), + backgroundColor: context.knobs.colorOrNull( + label: 'Background color', + ), ), ); } diff --git a/lib/src/components/avatars/avatar.dart b/lib/src/components/avatars/avatar.dart index c1d4bf6a..69b3cf72 100644 --- a/lib/src/components/avatars/avatar.dart +++ b/lib/src/components/avatars/avatar.dart @@ -1,23 +1,35 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import '../../../zeta_flutter.dart'; /// [ZetaAvatar] size enum ZetaAvatarSize { - /// [xl] 64 pixels + /// [xxxl] 200 pixels + xxxl, + + /// [xxl] 120 pixels + xxl, + + /// [xl] 80 pixels xl, - /// [l] 48 pixels + /// [l] 64 pixels l, - /// [m] 40 pixels + /// [m] 48 pixels m, - /// [s] 32 pixels + /// [s] 40 pixels s, - /// [xs] 24 pixels + /// [xs] 36 pixels xs, + + /// [xxs] 32 pixels + xxs, + + /// [xxxs] 24 pixels + xxxs, } /// ZetaAvatar component @@ -86,10 +98,10 @@ class ZetaAvatar extends StatelessWidget { final Color? borderColor; /// Status badge shown at lower right corner of avatar. - final ZetaIndicator? lowerBadge; + final ZetaAvatarBadge? lowerBadge; /// Notification Badge shown at top right corner of avatar. - final ZetaIndicator? upperBadge; + final ZetaAvatarBadge? upperBadge; bool get _showPlaceholder => image == null && (initials == null || initials!.isEmpty); @@ -99,39 +111,34 @@ class ZetaAvatar extends StatelessWidget { final borderSize = size.borderSize; final sizePixels = size.pixelSize; - final contentSizePixels = size.pixelSize - (borderColor != null ? size.borderSize * 2 : 0); + final contentSizePixels = size.pixelSize; - final innerContent = ClipRRect( - borderRadius: BorderRadius.circular(64), - clipBehavior: Clip.hardEdge, - child: image ?? - (_showPlaceholder - ? Container( - transform: Matrix4.translationValues(-contentSizePixels * 0.2, -contentSizePixels * 0.1, 0), - child: IconTheme( - data: IconThemeData( - color: Zeta.of(context).colors.cool, - size: contentSizePixels * 1.4, - ), - child: const Icon(ZetaIcons.user_round), + final innerChild = image ?? + (initials != null + ? Center( + child: Text( + size == ZetaAvatarSize.xs ? initials!.substring(0, 1) : initials!, + style: TextStyle( + fontSize: size.fontSize, + letterSpacing: 0, + color: backgroundColor?.onColor, ), - ) - : Center( - child: Text( - size == ZetaAvatarSize.xs ? initials!.substring(0, 1) : initials!, - style: TextStyle(fontSize: size.fontSize, letterSpacing: -0.5), - ), - )), + ), + ) + : null); + + final innerContent = ClipRRect( + borderRadius: ZetaRadius.full, + child: innerChild, ); return Stack( children: [ Container( - margin: const EdgeInsets.all(3), width: sizePixels, height: sizePixels, decoration: BoxDecoration( - border: borderColor != null ? Border.all(color: borderColor!, width: borderSize / ZetaSpacing.x0_5) : null, + border: borderColor != null ? Border.all(color: borderColor!, width: 0) : null, borderRadius: ZetaRadius.full, color: backgroundColor ?? (_showPlaceholder ? zetaColors.surfacePrimary : zetaColors.cool.shade20), ), @@ -140,30 +147,40 @@ class ZetaAvatar extends StatelessWidget { width: contentSizePixels, height: contentSizePixels, decoration: BoxDecoration( - color: _showPlaceholder ? backgroundColor ?? zetaColors.surfaceHovered : null, - border: Border.all(color: zetaColors.surfacePrimary, width: borderSize / ZetaSpacing.x0_5), + color: backgroundColor ?? zetaColors.surfaceHovered, + border: Border.all(color: borderColor!, width: borderSize), + borderRadius: ZetaRadius.full, + ), + child: ClipRRect( borderRadius: ZetaRadius.full, + child: innerContent, ), - child: ClipRRect(borderRadius: ZetaRadius.full, clipBehavior: Clip.hardEdge, child: innerContent), ) : DecoratedBox( decoration: BoxDecoration( borderRadius: ZetaRadius.full, color: backgroundColor ?? zetaColors.surfaceHovered, ), - child: innerContent, + child: ClipRRect( + borderRadius: ZetaRadius.full, + child: innerContent, + ), ), ), if (upperBadge != null) Positioned( - right: 1, - child: upperBadge!.copyWith(size: size.indicatorSize), + right: 0, + child: upperBadge!.copyWith( + size: size, + ), ), if (lowerBadge != null) Positioned( - right: 1, - bottom: 1, - child: lowerBadge!.copyWith(size: size.indicatorSize), + right: 0, + bottom: 0, + child: lowerBadge!.copyWith( + size: size, + ), ), ], ); @@ -175,8 +192,8 @@ class ZetaAvatar extends StatelessWidget { properties ..add(DiagnosticsProperty('size', size)) ..add(DiagnosticsProperty('name', initials)) - ..add(DiagnosticsProperty('specialStatus', lowerBadge)) - ..add(DiagnosticsProperty('badge', upperBadge)) + ..add(DiagnosticsProperty('specialStatus', lowerBadge)) + ..add(DiagnosticsProperty('badge', upperBadge)) ..add(DiagnosticsProperty('backgroundColor', backgroundColor)) ..add(ColorProperty('statusColor', borderColor)); } @@ -185,35 +202,32 @@ class ZetaAvatar extends StatelessWidget { extension on ZetaAvatarSize { double get pixelSize { switch (this) { + case ZetaAvatarSize.xxxl: + return ZetaSpacing.x50; + case ZetaAvatarSize.xxl: + return ZetaSpacing.x30; case ZetaAvatarSize.xl: - return ZetaSpacing.x16; + return ZetaSpacing.x20; case ZetaAvatarSize.l: - return ZetaSpacing.x12; + return ZetaSpacing.x16; case ZetaAvatarSize.m: - return ZetaSpacing.x10; + return ZetaSpacing.x12; case ZetaAvatarSize.s: - return ZetaSpacing.x8; + return ZetaSpacing.x10; case ZetaAvatarSize.xs: + return ZetaSpacing.x9; + case ZetaAvatarSize.xxs: + return ZetaSpacing.x8; + case ZetaAvatarSize.xxxs: return ZetaSpacing.x6; } } - ZetaWidgetSize get indicatorSize { - switch (this) { - case ZetaAvatarSize.xl: - case ZetaAvatarSize.l: - case ZetaAvatarSize.m: - return ZetaWidgetSize.large; - case ZetaAvatarSize.s: - return ZetaWidgetSize.medium; - - case ZetaAvatarSize.xs: - return ZetaWidgetSize.small; - } - } - double get borderSize { switch (this) { + case ZetaAvatarSize.xxxl: + return 11; + case ZetaAvatarSize.xxl: case ZetaAvatarSize.xl: case ZetaAvatarSize.l: case ZetaAvatarSize.m: @@ -221,21 +235,175 @@ extension on ZetaAvatarSize { case ZetaAvatarSize.s: case ZetaAvatarSize.xs: + case ZetaAvatarSize.xxs: + case ZetaAvatarSize.xxxs: return ZetaSpacing.x0_5; } } double get fontSize { - switch (this) { - case ZetaAvatarSize.xl: - return ZetaSpacing.x5; - case ZetaAvatarSize.l: - return ZetaSpacing.x4; - case ZetaAvatarSize.m: - return ZetaSpacing.x3_5; - case ZetaAvatarSize.s: - case ZetaAvatarSize.xs: - return ZetaSpacing.x3; - } + return pixelSize * 4 / 9; + } +} + +/// Enum of types for [ZetaAvatarBadge] +enum ZetaAvatarBadgeType { + /// Shows an icon on [ZetaAvatarBadge]. Defaults to [ZetaIcons.star_round]. + icon, + + /// Shows a number on [ZetaAvatarBadge] from provided [ZetaAvatarBadge.value]. + notification, +} + +/// ZetaAvatarBadge component + +class ZetaAvatarBadge extends StatelessWidget { + /// Constructor for [ZetaAvatarBadge] + const ZetaAvatarBadge({ + super.key, + this.color, + this.type = ZetaAvatarBadgeType.notification, + this.icon, + this.value, + this.iconColor, + }) : size = ZetaAvatarSize.xxxl; + + const ZetaAvatarBadge._({ + super.key, + required this.color, + required this.size, + required this.type, + this.icon, + this.value, + this.iconColor, + }); + + /// Constructs [ZetaAvatarBadge] with icon + const ZetaAvatarBadge.icon({ + super.key, + this.color, + this.icon = ZetaIcons.star_round, + this.iconColor, + }) : value = null, + size = ZetaAvatarSize.xxxl, + type = ZetaAvatarBadgeType.icon; + + /// Constructs [ZetaAvatarBadge] with notifications + + const ZetaAvatarBadge.notification({ + super.key, + required this.value, + }) : size = ZetaAvatarSize.xxxl, + icon = null, + iconColor = null, + color = null, + type = ZetaAvatarBadgeType.notification; + + /// Size of badge + final ZetaAvatarSize size; + + /// Type of badge + final ZetaAvatarBadgeType type; + + /// Background color for badge + final Color? color; + + /// Icon of badge + final IconData? icon; + + /// Icon color for badge + final Color? iconColor; + + /// Notification value for badge + final int? value; + + /// Returns copy of [ZetaAvatarBadge] + ZetaAvatarBadge copyWith({ + Color? color, + ZetaAvatarSize? size, + IconData? icon, + Color? iconColor, + int? value, + ZetaAvatarBadgeType? type, + }) { + return ZetaAvatarBadge._( + color: color ?? this.color, + size: size ?? this.size, + icon: icon ?? this.icon, + type: type ?? this.type, + value: value ?? this.value, + iconColor: iconColor ?? this.iconColor, + key: key, + ); + } + + @override + Widget build(BuildContext context) { + final colors = Zeta.of(context).colors; + final backgroundColor = type == ZetaAvatarBadgeType.notification ? colors.negative : color; + final badgeSize = _getContainerSize(); + final borderSize = _getBorderSize(); + final paddedSize = badgeSize + ZetaSpacing.x1; + + final innerContent = Container( + margin: const EdgeInsets.all(0.01), + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: ZetaRadius.full, + ), + child: value != null + ? Center( + child: Text( + value! > 99 ? '99+' : '$value', + style: TextStyle( + color: backgroundColor?.onColor, + fontSize: ((10 / 12) * badgeSize) - 2, + height: 1, + ), + ), + ) + : icon != null + ? Icon( + icon, + size: badgeSize - borderSize, + color: iconColor ?? backgroundColor?.onColor, + ) + : null, + ); + + return Container( + width: type == ZetaAvatarBadgeType.icon ? paddedSize : badgeSize * 1.8, + height: type == ZetaAvatarBadgeType.icon ? paddedSize : badgeSize, + decoration: BoxDecoration( + borderRadius: ZetaRadius.full, + border: type != ZetaAvatarBadgeType.notification + ? Border.all( + width: borderSize, + color: Zeta.of(context).colors.surfacePrimary, + ) + : null, + ), + child: Center(child: innerContent), + ); + } + + double _getContainerSize() { + return size.pixelSize / 3; + } + + double _getBorderSize() { + return size.pixelSize / 48; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(ColorProperty('color', color)) + ..add(EnumProperty('size', size)) + ..add(EnumProperty('type', type)) + ..add(DiagnosticsProperty('icon', icon)) + ..add(ColorProperty('iconColor', iconColor)) + ..add(IntProperty('value', value)); } } diff --git a/lib/src/components/buttons/button_group.dart b/lib/src/components/buttons/button_group.dart index bf903921..1f30db8e 100644 --- a/lib/src/components/buttons/button_group.dart +++ b/lib/src/components/buttons/button_group.dart @@ -245,7 +245,10 @@ class _ZetaGroupButtonState extends State { if (widget.icon != null) Icon(widget.icon, size: ZetaSpacing.x5), Text(widget.label ?? '', style: ZetaTextStyles.labelMedium), if (widget.dropdown != null) // TODO(UX-1006): Dropdown - Icon(widget.rounded ? ZetaIcons.expand_more_round : ZetaIcons.expand_more_sharp, size: ZetaSpacing.x5), + Icon( + widget.rounded ? ZetaIcons.expand_more_round : ZetaIcons.expand_more_sharp, + size: ZetaSpacing.x5, + ), ].divide(const SizedBox(width: ZetaSpacing.x1)).toList(), ).paddingAll(_padding), ), diff --git a/lib/src/theme/tokens.dart b/lib/src/theme/tokens.dart index caecce51..286ac88a 100644 --- a/lib/src/theme/tokens.dart +++ b/lib/src/theme/tokens.dart @@ -98,6 +98,12 @@ class ZetaSpacing { /// 96dp space. static const double xxxl = spacingBaseMultiplier * 24; + + /// 120dp space + static const double x30 = spacingBaseMultiplier * 30; + + /// 200dp space + static const double x50 = spacingBaseMultiplier * 50; } /// Tokens used for Border Radius.