resolveColumnWidths<T> function

List<DynamicTableColumn<T>> resolveColumnWidths<T>({
  1. required List<DynamicTableColumn<T>> columns,
  2. required List<T> rows,
  3. required DynamicTableStyle style,
  4. int autoFitSampleCount = 40,
})

Calculates resolved column widths taking into account DynamicTableColumn.autoFit, DynamicTableColumn.minWidth, and DynamicTableColumn.maxWidth.

Implementation

List<DynamicTableColumn<T>> resolveColumnWidths<T>({
  required List<DynamicTableColumn<T>> columns,
  required List<T> rows,
  required DynamicTableStyle style,
  int autoFitSampleCount = 40,
}) {
  final hasAutoFit = columns.any((col) => col.autoFit);
  if (!hasAutoFit) {
    return columns;
  }

  final sampleRows = rows.take(autoFitSampleCount).toList();
  final TextPainter textPainter = TextPainter(
    textDirection: TextDirection.ltr,
    maxLines: 1,
  );

  final defaultHeaderStyle = style.headerTextStyle ?? const TextStyle(fontWeight: FontWeight.w600);
  final defaultCellStyle = style.cellTextStyle ?? const TextStyle();
  final headerPadding = style.headerPadding;
  final cellPadding = style.cellPadding;

  return columns.map((col) {
    if (!col.autoFit) {
      return col;
    }

    double maxMeasuredWidth = col.minWidth;

    // 1. Measure header title if Text
    if (col.title is Text) {
      final textWidget = col.title as Text;
      final textData = textWidget.data ?? '';
      if (textData.isNotEmpty) {
        textPainter.text = TextSpan(
          text: textData,
          style: textWidget.style ?? defaultHeaderStyle,
        );
        textPainter.layout();
        final headerWidth = textPainter.width + headerPadding.horizontal + 16.0;
        if (headerWidth > maxMeasuredWidth) {
          maxMeasuredWidth = headerWidth;
        }
      }
    }

    // 2. Measure sample rows
    for (int i = 0; i < sampleRows.length; i++) {
      final row = sampleRows[i];
      final String textContent;
      if (col.getTextValue != null) {
        textContent = col.getTextValue!(row);
      } else {
        textContent = row.toString();
      }

      if (textContent.isNotEmpty) {
        textPainter.text = TextSpan(
          text: textContent,
          style: defaultCellStyle,
        );
        textPainter.layout();
        final cellWidth = textPainter.width + cellPadding.horizontal + 12.0;
        if (cellWidth > maxMeasuredWidth) {
          maxMeasuredWidth = cellWidth;
        }
      }
    }

    final resolvedWidth = maxMeasuredWidth.clamp(col.minWidth, col.maxWidth);
    return col.copyWith(width: resolvedWidth);
  }).toList();
}