estimateWidth method
Estimates the width of the button based on its content and size settings.
Implementation
double estimateWidth(BuildContext ctx) {
final defaultTheme = ctx.theme.buttonTheme;
final sizeData = size ?? theme?.size ?? defaultTheme.size;
final shapeData = shape ?? theme?.shape ?? defaultTheme.shape;
final baseTheme = theme?.baseTheme ??
defaultTheme.baseTheme.rebuild(color: active ? (activeColor ?? color) : color, type: type?.colorType);
// If it's a block button, it takes full width normally
if (sizeData.minW.isInfinite && size == TButtonSize.block) return double.infinity;
// If it's a circle, width = height (minH)
if (shapeData == TButtonShape.circle) {
return sizeData.minH;
}
double width = 0;
// Base horizontal padding (left + right)
width += sizeData.hPad * 2;
// Check for icon/imageUrl
final hasIcon = (active ? (activeIcon ?? icon) : icon) != null || imageUrl != null;
// Check for text (use loadingText if loading is true)
final buttonText = loading ? loadingText : text;
final hasText = !buttonText.isNullOrBlank;
final textStyle = TextStyle(
fontSize: sizeData.font,
fontWeight: baseTheme.type.fontWeight,
letterSpacing: 0.65,
);
if (shapeData == TButtonShape.tile) {
// Tile shape is a Column: width is max of (icon size) and (text width)
double iconWidth = hasIcon ? sizeData.icon : 0;
double textWidth = hasText ? WidthHelper.measureText(ctx, buttonText!, textStyle) : 0;
width += (iconWidth > textWidth ? iconWidth : textWidth);
} else {
// Normal Row layout
if (hasIcon) {
width += sizeData.icon;
if (hasText) {
width += sizeData.spacing;
}
}
if (hasText) {
width += WidthHelper.measureText(ctx, buttonText!, textStyle);
}
}
// Add child width if present
if (child != null) {
width += 24.0;
}
// Add a small buffer (4.0) to account for Material button's internal margins/rendering
width += 4.0;
// Clamp between minWidth and infinity
final minW = sizeData.minW.isInfinite ? 38.0 : sizeData.minW;
return width.clamp(minW, double.infinity);
}