fix: Prevent GenexButton crash with unbounded width constraints

Use LayoutBuilder to detect whether parent provides bounded width.
When fullWidth=true in an unbounded context (e.g. Row without
Expanded), gracefully fall back to content-sized width instead of
forcing SizedBox(width: double.infinity) which triggers
"BoxConstraints forces an infinite width" assertion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-11 07:08:09 -08:00
parent 5abb614d03
commit 665e494b4a
1 changed files with 50 additions and 52 deletions

View File

@ -53,12 +53,10 @@ class GenexButton extends StatelessWidget {
final effectiveOnPressed = isLoading ? null : onPressed; final effectiveOnPressed = isLoading ? null : onPressed;
Widget button;
switch (variant) { switch (variant) {
case GenexButtonVariant.primary: case GenexButtonVariant.primary:
return SizedBox( button = ElevatedButton(
width: fullWidth ? double.infinity : null,
height: _height,
child: ElevatedButton(
onPressed: effectiveOnPressed, onPressed: effectiveOnPressed,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary, backgroundColor: AppColors.primary,
@ -72,14 +70,10 @@ class GenexButton extends StatelessWidget {
textStyle: _textStyle, textStyle: _textStyle,
), ),
child: child, child: child,
),
); );
case GenexButtonVariant.secondary: case GenexButtonVariant.secondary:
return SizedBox( button = ElevatedButton(
width: fullWidth ? double.infinity : null,
height: _height,
child: ElevatedButton(
onPressed: effectiveOnPressed, onPressed: effectiveOnPressed,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primarySurface, backgroundColor: AppColors.primarySurface,
@ -91,14 +85,10 @@ class GenexButton extends StatelessWidget {
textStyle: _textStyle, textStyle: _textStyle,
), ),
child: child, child: child,
),
); );
case GenexButtonVariant.outline: case GenexButtonVariant.outline:
return SizedBox( button = OutlinedButton(
width: fullWidth ? double.infinity : null,
height: _height,
child: OutlinedButton(
onPressed: effectiveOnPressed, onPressed: effectiveOnPressed,
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: AppColors.primary, foregroundColor: AppColors.primary,
@ -109,22 +99,30 @@ class GenexButton extends StatelessWidget {
textStyle: _textStyle, textStyle: _textStyle,
), ),
child: child, child: child,
),
); );
case GenexButtonVariant.text: case GenexButtonVariant.text:
return SizedBox( button = TextButton(
height: _height,
child: TextButton(
onPressed: effectiveOnPressed, onPressed: effectiveOnPressed,
style: TextButton.styleFrom( style: TextButton.styleFrom(
foregroundColor: AppColors.primary, foregroundColor: AppColors.primary,
textStyle: _textStyle, textStyle: _textStyle,
), ),
child: child, child: child,
);
}
// Use LayoutBuilder to safely handle fullWidth in unbounded contexts (e.g. Row)
if (fullWidth) {
return LayoutBuilder(
builder: (context, constraints) => SizedBox(
width: constraints.hasBoundedWidth ? double.infinity : null,
height: _height,
child: button,
), ),
); );
} }
return SizedBox(height: _height, child: button);
} }
double get _height { double get _height {