From 54c410dceeecc08e0f3ab2f39cf319a2e14bac88 Mon Sep 17 00:00:00 2001 From: Radomir Epur Date: Fri, 26 Sep 2025 15:43:50 +0300 Subject: [PATCH 1/4] fix(ui_oauth): sign in button's layout(made responsive) --- .../lib/src/oauth_provider_button_base.dart | 122 ++++++++++++------ 1 file changed, 85 insertions(+), 37 deletions(-) diff --git a/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart b/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart index c12d5795..a40a734c 100644 --- a/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart +++ b/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart @@ -388,17 +388,11 @@ class _ButtonContent extends StatelessWidget { required this.iconBackgroundColor, }); - Widget _buildLoadingIndicator() { - return SizedBox( - height: fontSize, - width: fontSize, - child: loadingIndicator, - ); - } + static const kEndPadding = 16.0; @override Widget build(BuildContext context) { - Widget child = Padding( + final icon = Padding( padding: EdgeInsets.all(iconPadding), child: SvgPicture.string( iconSrc, @@ -407,39 +401,93 @@ class _ButtonContent extends StatelessWidget { ), ); - if (label.isNotEmpty) { - final content = isLoading - ? _buildLoadingIndicator() - : Text( - label, - textAlign: TextAlign.center, - style: TextStyle( - height: 1.1, - color: textColor, - fontSize: fontSize, - ), - ); - - final isCupertino = CupertinoUserInterfaceLevel.maybeOf(context) != null; - final topMargin = isCupertino ? (height - fontSize) / 2 : 0.0; + if (label.isEmpty) { + if (!isLoading) return icon; - child = Stack( - children: [ - child, - Align( - alignment: AlignmentDirectional.center, - child: Padding( - padding: EdgeInsets.only(top: topMargin), - child: content, - ), - ), - ], + return SizedBox.square( + dimension: fontSize, + child: loadingIndicator, ); - } else if (isLoading) { - child = _buildLoadingIndicator(); } - return child; + final text = TextSpan( + text: label, + style: TextStyle( + height: 1.1, + color: textColor, + fontSize: fontSize, + ), + ); + + return Row( + children: [ + // + icon, + // + Expanded( + child: LayoutBuilder( + builder: (context, constraints) { + // + final availableWidth = constraints.maxWidth; + + // "height" is also the button's width + final totalIconWidth = height + (iconPadding * 2); + final totalButtonWidth = + availableWidth + totalIconWidth + kEndPadding; + + if (isLoading) { + // "fontSize" is also the indicator's width + final freeSpace = totalButtonWidth - fontSize; + final startPadding = + (freeSpace / 2 - totalIconWidth).clamp(0.0, availableWidth); + + return Padding( + padding: EdgeInsetsDirectional.only( + start: startPadding, + ), + child: Align( + alignment: AlignmentDirectional.centerStart, + child: SizedBox.square( + dimension: fontSize, + child: loadingIndicator, + ), + ), + ); + } + + final isCupertino = + CupertinoUserInterfaceLevel.maybeOf(context) != null; + final topPadding = isCupertino ? (height - fontSize) / 2 : 0.0; + + final textWidth = (TextPainter( + text: text, + textDirection: Directionality.of(context), + maxLines: 1, + )..layout(maxWidth: availableWidth)) + .size + .width; + final freeSpace = totalButtonWidth - textWidth; + final startPadding = + (freeSpace / 2 - totalIconWidth).clamp(0.0, availableWidth); + + return Padding( + padding: EdgeInsetsDirectional.only( + top: topPadding, + start: startPadding, + ), + child: FittedBox( + fit: BoxFit.scaleDown, + alignment: AlignmentDirectional.centerStart, + child: Text.rich(text), + ), + ); + }, + ), + ), + // + const SizedBox(width: kEndPadding), + ], + ); } } From 67d73abcb5d34088b200ba2cad674f3d94f0f6d3 Mon Sep 17 00:00:00 2001 From: Radomir Epur Date: Fri, 26 Sep 2025 17:42:10 +0300 Subject: [PATCH 2/4] docs: fix emulators launching command in CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1487234c..9328c309 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -136,7 +136,7 @@ These tests require the Firebase Emulator. To start the Firebase Emulator, run this command: ```bash -firebase emulator:start +melos emulator:start ``` Once the Firebase Emulator is up and running, execute the following Melos command from the terminal: From 63f41f3bc91912b80208551c2aba422c4f016774 Mon Sep 17 00:00:00 2001 From: Radomir Epur Date: Fri, 26 Sep 2025 18:19:34 +0300 Subject: [PATCH 3/4] fix(ui_oauth): pass text style to the RichText explicity --- .../lib/src/oauth_provider_button_base.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart b/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart index a40a734c..b9a83594 100644 --- a/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart +++ b/packages/firebase_ui_oauth/lib/src/oauth_provider_button_base.dart @@ -478,7 +478,10 @@ class _ButtonContent extends StatelessWidget { child: FittedBox( fit: BoxFit.scaleDown, alignment: AlignmentDirectional.centerStart, - child: Text.rich(text), + child: Text.rich( + text, + style: text.style, + ), ), ); }, From fbea049ad12807fa920d557a5f2aaf39a659ec2c Mon Sep 17 00:00:00 2001 From: Radomir Epur Date: Fri, 26 Sep 2025 18:20:24 +0300 Subject: [PATCH 4/4] test(ui_oauth): fix a test because the button layout has changed --- .../test/flutterfire_ui_oauth_test.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/firebase_ui_oauth/test/flutterfire_ui_oauth_test.dart b/packages/firebase_ui_oauth/test/flutterfire_ui_oauth_test.dart index b80f1480..7abdad99 100644 --- a/packages/firebase_ui_oauth/test/flutterfire_ui_oauth_test.dart +++ b/packages/firebase_ui_oauth/test/flutterfire_ui_oauth_test.dart @@ -205,11 +205,13 @@ void main() { home: Scaffold( body: Row( children: [ - OAuthProviderButtonBase( - provider: provider, - auth: FakeAuth(), - label: 'Sign in with Fake provider', - loadingIndicator: const CircularProgressIndicator(), + Expanded( + child: OAuthProviderButtonBase( + provider: provider, + auth: FakeAuth(), + label: 'Sign in with Fake provider', + loadingIndicator: const CircularProgressIndicator(), + ), ) ], ),