build method

  1. @override
Widget build(
  1. BuildContext context
)
override

Describes the part of the UI represented by this widget.

Implementation

@override
Widget build(BuildContext context) {
  final theme = ThemeScope.of(context);
  final bColor = borderColor ?? theme.border;
  final hStyle = _copyStyle(headerStyle ?? theme.titleSmall)
    ..foreground(theme.onSurface)
    ..bold();
  final cStyle = _copyStyle(cellStyle ?? theme.bodyMedium)
    ..foreground(theme.onSurface);
  final bStyle = _copyStyle(Style())..foreground(bColor);

  // Calculate column widths.
  final colCount = columns.length;
  final widths = List<int>.filled(colCount, 0);
  for (var i = 0; i < colCount; i++) {
    widths[i] = columns[i].length;
  }
  for (final row in rows) {
    for (var i = 0; i < colCount && i < row.length; i++) {
      if (row[i].length > widths[i]) {
        widths[i] = row[i].length;
      }
    }
  }

  final chars = _borderChars();
  final hasOuterBorder = chars.topLeft != null;

  // Build a horizontal rule line.
  String buildHRule(String h, String cross, String? left, String? right) {
    final parts = <String>[];
    if (left != null) parts.add(left);
    for (var i = 0; i < colCount; i++) {
      parts.add(h * widths[i]);
      if (i < colCount - 1) {
        parts.add('$h$cross$h');
      }
    }
    if (right != null) parts.add(right);
    return parts.join();
  }

  // Build a content row (header or data).
  Widget buildRow(List<String> values, Style textStyle) {
    final cells = <Widget>[];
    if (hasOuterBorder) {
      cells.add(Text('${chars.v} ', style: bStyle));
    }
    for (var i = 0; i < colCount; i++) {
      final value = i < values.length ? values[i] : '';
      cells.add(Text(value.padRight(widths[i]), style: textStyle));
      if (i < colCount - 1) {
        cells.add(Text(' ${chars.v} ', style: bStyle));
      }
    }
    if (hasOuterBorder) {
      cells.add(Text(' ${chars.v}', style: bStyle));
    }
    return Row(gap: 0, children: cells);
  }

  final children = <Widget>[];

  // Top border (only for styles with outer borders).
  if (hasOuterBorder) {
    children.add(
      Text(
        buildHRule(chars.h, chars.topCross!, chars.topLeft, chars.topRight),
        style: bStyle,
      ),
    );
  }

  // Header row.
  children.add(buildRow(columns, hStyle));

  // Header separator.
  children.add(
    Text(
      buildHRule(
        chars.h,
        chars.cross,
        hasOuterBorder ? chars.leftCross : null,
        hasOuterBorder ? chars.rightCross : null,
      ),
      style: bStyle,
    ),
  );

  // Data rows.
  for (final row in rows) {
    children.add(buildRow(row, cStyle));
  }

  // Bottom border (only for styles with outer borders).
  if (hasOuterBorder) {
    children.add(
      Text(
        buildHRule(
          chars.h,
          chars.bottomCross!,
          chars.bottomLeft,
          chars.bottomRight,
        ),
        style: bStyle,
      ),
    );
  }

  return Column(gap: 0, children: children);
}