estimateWidth method

double estimateWidth(
  1. BuildContext ctx
)

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);
}