render method

  1. @override
String render()
override

Renders the component as a string.

Implementation

@override
String render() {
  final normalizedRows = rows
      .map((row) => row.map((cell) => cell?.toString() ?? '').toList())
      .toList(growable: false);

  final columns = headers.length;
  final widths = List<int>.filled(columns, 0);

  // Calculate column widths
  for (var c = 0; c < columns; c++) {
    widths[c] = Style.visibleLength(headers[c]);
  }
  for (final row in normalizedRows) {
    for (var c = 0; c < columns; c++) {
      final cell = c < row.length ? row[c] : '';
      final len = Style.visibleLength(cell);
      if (len > widths[c]) widths[c] = len;
    }
  }

  final pad = ' ' * padding;

  String border() {
    final parts = widths.map((w) => '-' * (w + padding * 2));
    return '+${parts.join('+')}+';
  }

  String rowLine(List<String> cells, int rowIndex) {
    final parts = <String>[];
    for (var c = 0; c < columns; c++) {
      final raw = c < cells.length ? cells[c] : '';
      final visible = Style.visibleLength(raw);
      final fill = widths[c] - visible;
      final fillCount = fill > 0 ? fill : 0;

      var content = raw;
      if (styleFunc != null) {
        final style = styleFunc!(rowIndex, c, raw);
        if (style != null) {
          renderConfig.configureStyle(style);
          content = style.render(raw);
        }
      }

      parts.add('$pad$content${' ' * fillCount}$pad');
    }
    return '|${parts.join('|')}|';
  }

  final buffer = StringBuffer();
  buffer.writeln(border());
  buffer.writeln(rowLine(headers, -1)); // Header row is -1
  buffer.writeln(border());
  for (var i = 0; i < normalizedRows.length; i++) {
    buffer.writeln(rowLine(normalizedRows[i], i));
  }
  buffer.write(border());

  return buffer.toString();
}