@@ -388,17 +388,11 @@ class _ButtonContent extends StatelessWidget {
388388 required this .iconBackgroundColor,
389389 });
390390
391- Widget _buildLoadingIndicator () {
392- return SizedBox (
393- height: fontSize,
394- width: fontSize,
395- child: loadingIndicator,
396- );
397- }
391+ static const kEndPadding = 16.0 ;
398392
399393 @override
400394 Widget build (BuildContext context) {
401- Widget child = Padding (
395+ final icon = Padding (
402396 padding: EdgeInsets .all (iconPadding),
403397 child: SvgPicture .string (
404398 iconSrc,
@@ -407,39 +401,96 @@ class _ButtonContent extends StatelessWidget {
407401 ),
408402 );
409403
410- if (label.isNotEmpty) {
411- final content = isLoading
412- ? _buildLoadingIndicator ()
413- : Text (
414- label,
415- textAlign: TextAlign .center,
416- style: TextStyle (
417- height: 1.1 ,
418- color: textColor,
419- fontSize: fontSize,
420- ),
421- );
422-
423- final isCupertino = CupertinoUserInterfaceLevel .maybeOf (context) != null ;
424- final topMargin = isCupertino ? (height - fontSize) / 2 : 0.0 ;
404+ if (label.isEmpty) {
405+ if (! isLoading) return icon;
425406
426- child = Stack (
427- children: [
428- child,
429- Align (
430- alignment: AlignmentDirectional .center,
431- child: Padding (
432- padding: EdgeInsets .only (top: topMargin),
433- child: content,
434- ),
435- ),
436- ],
407+ return SizedBox .square (
408+ dimension: fontSize,
409+ child: loadingIndicator,
437410 );
438- } else if (isLoading) {
439- child = _buildLoadingIndicator ();
440411 }
441412
442- return child;
413+ final text = TextSpan (
414+ text: label,
415+ style: TextStyle (
416+ height: 1.1 ,
417+ color: textColor,
418+ fontSize: fontSize,
419+ ),
420+ );
421+
422+ return Row (
423+ children: [
424+ //
425+ icon,
426+ //
427+ Expanded (
428+ child: LayoutBuilder (
429+ builder: (context, constraints) {
430+ //
431+ final availableWidth = constraints.maxWidth;
432+
433+ // "height" is also the button's width
434+ final totalIconWidth = height + (iconPadding * 2 );
435+ final totalButtonWidth =
436+ availableWidth + totalIconWidth + kEndPadding;
437+
438+ if (isLoading) {
439+ // "fontSize" is also the indicator's width
440+ final freeSpace = totalButtonWidth - fontSize;
441+ final startPadding =
442+ (freeSpace / 2 - totalIconWidth).clamp (0.0 , availableWidth);
443+
444+ return Padding (
445+ padding: EdgeInsetsDirectional .only (
446+ start: startPadding,
447+ ),
448+ child: Align (
449+ alignment: AlignmentDirectional .centerStart,
450+ child: SizedBox .square (
451+ dimension: fontSize,
452+ child: loadingIndicator,
453+ ),
454+ ),
455+ );
456+ }
457+
458+ final isCupertino =
459+ CupertinoUserInterfaceLevel .maybeOf (context) != null ;
460+ final topPadding = isCupertino ? (height - fontSize) / 2 : 0.0 ;
461+
462+ final textWidth = (TextPainter (
463+ text: text,
464+ textDirection: Directionality .of (context),
465+ maxLines: 1 ,
466+ )..layout (maxWidth: availableWidth))
467+ .size
468+ .width;
469+ final freeSpace = totalButtonWidth - textWidth;
470+ final startPadding =
471+ (freeSpace / 2 - totalIconWidth).clamp (0.0 , availableWidth);
472+
473+ return Padding (
474+ padding: EdgeInsetsDirectional .only (
475+ top: topPadding,
476+ start: startPadding,
477+ ),
478+ child: FittedBox (
479+ fit: BoxFit .scaleDown,
480+ alignment: AlignmentDirectional .centerStart,
481+ child: Text .rich (
482+ text,
483+ style: text.style,
484+ ),
485+ ),
486+ );
487+ },
488+ ),
489+ ),
490+ //
491+ const SizedBox (width: kEndPadding),
492+ ],
493+ );
443494 }
444495}
445496
0 commit comments