Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: [DX-1155] Update OptimusIcon #536

Merged
merged 3 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 14 additions & 94 deletions optimus/lib/src/icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ enum OptimusIconColorOption {
info,
warning,
danger,
subtle,
inverse,
}

/// Icons are symbols that provide a visual representation of meaning in
Expand Down Expand Up @@ -55,6 +55,8 @@ class OptimusIcon extends StatelessWidget {
/// a sense of warning.
/// - [OptimusIconColorOption.danger] – used to emphasize the item and convey
/// a sense of danger or error.
/// - [OptimusIconColorOption.inverse] – used to emphasize the item in a
/// general way, but with an inverse color.
final OptimusIconColorOption? colorOption;

double _getIconSize(OptimusTokens tokens) => switch (iconSize) {
Expand All @@ -65,107 +67,25 @@ class OptimusIcon extends StatelessWidget {

@override
Widget build(BuildContext context) {
final theme = OptimusTheme.of(context);
final tokens = context.tokens;

return Icon(
iconData,
color: colorOption?.let((option) => option.toIconColor(theme)) ??
theme.colors.defaultTextColor,
color: colorOption?.let((option) => option.toIconColor(tokens)) ??
tokens.textStaticPrimary,
size: _getIconSize(context.tokens),
);
}
}

/// Icons are symbols that provide a visual representation of meaning in
/// situations where text is not enough or we want to emphasize its impact.
///
/// Supplementary icon is used when it's necessary to highlight information or
/// provide additional emphasis.
class OptimusSupplementaryIcon extends StatelessWidget {
const OptimusSupplementaryIcon({
super.key,
required this.iconData,
this.colorOption = OptimusIconColorOption.basic,
});

/// Controls the icon.
final IconData iconData;

/// Controls color of the icon.
///
/// - `null` – default value. Changes the color of the icon to match its
/// parent font color.
/// - [OptimusIconColorOption.basic] – variant with no extra emphasis.
/// - [OptimusIconColorOption.primary] – used to emphasize the item in a
/// general way.
/// - [OptimusIconColorOption.success] – used to emphasize the item and convey
/// a sense of success.
/// - [OptimusIconColorOption.warning] – used to emphasize the item and convey
/// a sense of warning.
/// - [OptimusIconColorOption.danger] – used to emphasize the item and convey
/// a sense of danger or error.
final OptimusIconColorOption colorOption;

@override
Widget build(BuildContext context) {
final theme = context.theme;
final tokens = context.tokens;

return Container(
width: _diameter,
height: _diameter,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: colorOption.toSupplementaryBackgroundColor(theme),
),
child: Icon(
iconData,
color: colorOption.toSupplementaryIconColor(theme),
size: tokens.sizing400,
),
);
}
}

extension on OptimusIconColorOption {
Color toIconColor(OptimusThemeData theme) => switch (this) {
OptimusIconColorOption.basic => theme.isDark
? theme.colors.neutral0
: theme.colors.neutral500, // TODO(witwash): to tokenss
OptimusIconColorOption.primary => theme.colors.primary500,
OptimusIconColorOption.success => theme.colors.success500,
OptimusIconColorOption.info => theme.colors.info500,
OptimusIconColorOption.warning => theme.colors.warning700,
OptimusIconColorOption.danger => theme.colors.danger500,
OptimusIconColorOption.subtle => theme.colors.neutral300,
};

Color toSupplementaryIconColor(OptimusThemeData theme) {
if (theme.isDark) return theme.colors.neutral1000;

return switch (this) {
OptimusIconColorOption.basic => theme.colors.neutral500,
OptimusIconColorOption.warning => theme.colors.neutral1000,
OptimusIconColorOption.danger ||
OptimusIconColorOption.primary ||
OptimusIconColorOption.success ||
OptimusIconColorOption.info ||
OptimusIconColorOption.subtle =>
theme.colors.neutral0,
};
}

Color toSupplementaryBackgroundColor(OptimusThemeData theme) =>
switch (this) {
OptimusIconColorOption.basic ||
OptimusIconColorOption.subtle =>
theme.colors.neutral50,
OptimusIconColorOption.primary => theme.colors.primary500,
OptimusIconColorOption.success => theme.colors.success500,
OptimusIconColorOption.info => theme.colors.info500,
OptimusIconColorOption.warning => theme.colors.warning500,
OptimusIconColorOption.danger => theme.colors.danger500,
Color toIconColor(OptimusTokens tokens) => switch (this) {
OptimusIconColorOption.basic => tokens.textStaticPrimary,
OptimusIconColorOption.primary => tokens.textInteractiveDefault,
OptimusIconColorOption.success => tokens.textAlertSuccess,
OptimusIconColorOption.info => tokens.textAlertInfo,
OptimusIconColorOption.warning => tokens.textAlertWarning,
OptimusIconColorOption.danger => tokens.textAlertDanger,
OptimusIconColorOption.inverse => tokens.textStaticInverse,
};
}

const double _diameter = 64;
1 change: 0 additions & 1 deletion storybook/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ class _MyAppState extends State<MyApp> {
allIconsStory,
iconStory,
logoStory,
supplementaryIconStory,
iconListStory,
cardStory,
nestedCardStory,
Expand Down
47 changes: 14 additions & 33 deletions storybook/lib/stories/icon/icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ final Story iconStory = Story(
);

return ListView(
children: OptimusIconColorOption.values
children: _colors
.map(
(c) => OptimusListTile(
title: OptimusTitleSmall(
child: Text(c.name.toUpperCase()),
),
title: OptimusTitleSmall(child: Text(c.label.toUpperCase())),
prefix: OptimusIcon(
iconData: icon,
colorOption: c,
colorOption: c.value,
iconSize: size,
),
),
Expand All @@ -37,34 +35,6 @@ final Story iconStory = Story(
},
);

final Story supplementaryIconStory = Story(
name: 'Media/Icons/Supplementary Icon',
builder: (context) {
final k = context.knobs;
final icon = k.options(
label: 'Icon',
initial: OptimusIcons.edit,
options: _icons,
);

return ListView(
children: OptimusIconColorOption.values
.map(
(c) => OptimusListTile(
title: OptimusTitleSmall(
child: Text(c.name.toUpperCase()),
),
prefix: OptimusSupplementaryIcon(
iconData: icon,
colorOption: c,
),
),
)
.toList(),
);
},
);

final List<Option<IconData>> _icons = [
const Option(label: 'Mews Logo', value: OptimusIcons.mews_logo),
const Option(label: 'Magic', value: OptimusIcons.magic),
Expand All @@ -75,4 +45,15 @@ final List<Option<IconData>> _icons = [
const Option(label: 'Chevron left', value: OptimusIcons.chevron_left),
];

final _colors = [
const Option(label: 'Basic', value: OptimusIconColorOption.basic),
const Option(label: 'Primary', value: OptimusIconColorOption.primary),
const Option(label: 'Success', value: OptimusIconColorOption.success),
const Option(label: 'Info', value: OptimusIconColorOption.info),
const Option(label: 'Warning', value: OptimusIconColorOption.warning),
const Option(label: 'Danger', value: OptimusIconColorOption.danger),
const Option(label: 'Inverse', value: OptimusIconColorOption.inverse),
const Option(label: 'Inherit', value: null),
];

final _sizes = OptimusIconSize.values.toOptions();
Loading