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(ui_shared): pass platform-specific icons and colors explicitly #10655

Merged
merged 1 commit into from
Mar 27, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ class _EmailVerificationBadgeState extends State<_EmailVerificationBadge> {
state != EmailVerificationState.sending)
UniversalButton(
variant: ButtonVariant.text,
color: Theme.of(context).colorScheme.error,
materialColor: Theme.of(context).colorScheme.error,
cupertinoColor: CupertinoColors.destructiveRed,
text: 'Dismiss',
onPressed: () {
setState(service.dismiss);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,16 @@ class _DeleteAccountButtonState extends State<DeleteAccountButton> {
@override
Widget build(BuildContext context) {
final l = FirebaseUILocalizations.labelsOf(context);
bool isCupertino = CupertinoUserInterfaceLevel.maybeOf(context) != null;

final themeData = Theme.of(context);
final colorScheme = themeData.colorScheme;

return LoadingButton(
isLoading: _isLoading,
color: isCupertino ? CupertinoColors.destructiveRed : colorScheme.error,
icon: isCupertino ? CupertinoIcons.delete : Icons.delete,
cupertinoColor: CupertinoColors.destructiveRed,
materialColor: colorScheme.error,
cupertinoIcon: CupertinoIcons.delete,
materialIcon: Icons.delete,
label: l.deleteAccount,
labelColor: colorScheme.onError,
onTap: _deleteAccount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ class EmailLinkSignInButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final isCupertino = CupertinoUserInterfaceLevel.maybeOf(context) != null;
final l = FirebaseUILocalizations.labelsOf(context);

return UniversalButton(
text: l.emailLinkSignInButtonLabel,
icon: isCupertino ? CupertinoIcons.link : Icons.link,
cupertinoIcon: CupertinoIcons.link,
materialIcon: Icons.link,
onPressed: () {
final action = FirebaseUIAction.ofType<EmailLinkSignInAction>(context);
if (action != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ class SignOutButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l = FirebaseUILocalizations.labelsOf(context);
final isCupertino = CupertinoUserInterfaceLevel.maybeOf(context) != null;

return UniversalButton(
text: l.signOutButtonText,
onPressed: () => FirebaseUIAuth.signOut(
context: context,
auth: auth,
),
icon: isCupertino ? CupertinoIcons.arrow_right_circle : Icons.logout,
cupertinoIcon: CupertinoIcons.arrow_right_circle,
materialIcon: Icons.logout,
variant: variant,
);
}
Expand Down
26 changes: 18 additions & 8 deletions packages/firebase_ui_shared/lib/src/loading_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,17 @@ class LoadingButton extends StatelessWidget {
/// The text to display in the button.
final String label;

/// The icon to display in the button.
final IconData? icon;
/// The icon to display in the button under [MaterialApp].
final IconData? materialIcon;

/// The color of the button background.
final Color? color;
/// The icon to display in the button under [CupertinoApp].
final IconData? cupertinoIcon;

/// The color of the button background under [MaterialApp].
final Color? materialColor;

/// The color of the button background under [CupertinoApp].
final Color? cupertinoColor;

/// The color of the button content.
final Color? labelColor;
Expand All @@ -75,8 +81,10 @@ class LoadingButton extends StatelessWidget {
required this.label,
required this.onTap,
this.isLoading = false,
this.icon,
this.color,
this.materialIcon,
this.cupertinoIcon,
this.materialColor,
this.cupertinoColor,
this.labelColor,
this.variant = ButtonVariant.outlined,
}) : super(key: key);
Expand All @@ -99,8 +107,10 @@ class LoadingButton extends StatelessWidget {
);

return UniversalButton(
color: color,
icon: icon,
materialColor: materialColor,
cupertinoColor: cupertinoColor,
materialIcon: materialIcon,
cupertinoIcon: cupertinoIcon,
contentColor: contentColor,
onPressed: onTap,
variant: variant,
Expand Down
44 changes: 26 additions & 18 deletions packages/firebase_ui_shared/lib/src/universal_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ class UniversalButton extends PlatformWidget {
/// The child to display in the button.
final Widget? child;

/// The icon to display in the button.
final IconData? icon;
/// The icon to display in the button under [MaterialApp].
final IconData? materialIcon;

/// The icon to display in the button under [CupertinoApp].
final IconData? cupertinoIcon;

/// Defines the order of the icon and the label.
/// Icon will be placed on the left if [TextDirection.ltr] and on the right
Expand All @@ -46,8 +49,11 @@ class UniversalButton extends PlatformWidget {
/// If not provided, [ButtonVariant.filled] will be used.
final ButtonVariant variant;

/// The color of the button background.
final Color? color;
/// The color of the button background under [MaterialApp].
final Color? materialColor;

/// The color of the button background under [CupertinoApp].
final Color? cupertinoColor;

/// The color of the button content.
final Color? contentColor;
Expand All @@ -57,10 +63,12 @@ class UniversalButton extends PlatformWidget {
this.text,
this.child,
this.onPressed,
this.icon,
this.materialIcon,
this.cupertinoIcon,
this.direction = TextDirection.ltr,
this.variant = ButtonVariant.filled,
this.color,
this.materialColor,
this.cupertinoColor,
this.contentColor,
}) : assert(text != null || child != null),
super(key: key);
Expand All @@ -73,9 +81,9 @@ class UniversalButton extends PlatformWidget {
textDirection: direction,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null) ...[
if (cupertinoIcon != null) ...[
if (direction == TextDirection.rtl) const SizedBox(width: 8),
Icon(icon, size: 20, color: contentColor),
Icon(cupertinoIcon, size: 20, color: contentColor),
if (direction == TextDirection.ltr) const SizedBox(width: 8),
],
this.child ?? Text(text!),
Expand All @@ -95,9 +103,9 @@ class UniversalButton extends PlatformWidget {
);
}

if (color != null) {
if (cupertinoColor != null) {
return CupertinoTheme(
data: CupertinoTheme.of(context).copyWith(primaryColor: color),
data: CupertinoTheme.of(context).copyWith(primaryColor: cupertinoColor),
child: button,
);
} else {
Expand All @@ -111,46 +119,46 @@ class UniversalButton extends PlatformWidget {

ButtonStyle? style;

if (color != null) {
if (materialColor != null) {
MaterialStateColor? foregroundColor;
MaterialStateColor? backgroundColor;

if (variant == ButtonVariant.text) {
foregroundColor = MaterialStateColor.resolveWith((_) => color!);
foregroundColor = MaterialStateColor.resolveWith((_) => materialColor!);
} else {
foregroundColor = MaterialStateColor.resolveWith((_) => contentColor!);
backgroundColor = MaterialStateColor.resolveWith((_) => color!);
backgroundColor = MaterialStateColor.resolveWith((_) => materialColor!);
}

style = ButtonStyle(
foregroundColor: foregroundColor,
backgroundColor: backgroundColor,
overlayColor: MaterialStateColor.resolveWith(
(states) => color!.withAlpha(20),
(states) => materialColor!.withAlpha(20),
),
);
}

if (icon != null) {
if (materialIcon != null) {
switch (variant) {
case ButtonVariant.text:
return TextButton.icon(
icon: Icon(icon, color: contentColor),
icon: Icon(materialIcon, color: contentColor),
onPressed: onPressed,
label: child,
style: style,
);
case ButtonVariant.filled:
return ElevatedButton.icon(
onPressed: onPressed,
icon: Icon(icon, color: contentColor),
icon: Icon(materialIcon, color: contentColor),
label: child,
style: style,
);
case ButtonVariant.outlined:
return OutlinedButton.icon(
onPressed: onPressed,
icon: Icon(icon, color: contentColor),
icon: Icon(materialIcon, color: contentColor),
label: child,
style: style,
);
Expand Down