adaptive<T, K> static method

Future<Widget> adaptive<T, K>(
  1. BuildContext context,
  2. List<TTableHeader<T, K>> headers,
  3. List<T> items, {
  4. TPdfTableDecoration decoration = const TPdfTableDecoration(),
  5. double availableWidth = 515,
  6. TKeyValueTheme? theme,
  7. Map<String, Uint8List>? imageCache,
})

Creates an adaptive layout: uses a standard table if it fits, otherwise uses a grid.

Implementation

static Future<pw.Widget> adaptive<T, K>(
  BuildContext context,
  List<TTableHeader<T, K>> headers,
  List<T> items, {
  TPdfTableDecoration decoration = const TPdfTableDecoration(),
  double availableWidth = 515,
  TKeyValueTheme? theme,
  Map<String, Uint8List>? imageCache,
}) async {
  final colors = context.colors;
  final wTheme = theme ?? TKeyValueTheme.defaultTheme(colors);

  // Only consider headers with map or builder (same as TTableHelper.from)
  final effectiveHeaders = headers.where((h) => h.map != null || h.builder != null).toList();

  double totalEstimatedWidth = 0;
  for (final header in effectiveHeaders) {
    final kv = TKeyValue(header.text, width: header.minWidth);
    totalEstimatedWidth += 150; //kv.estimateColumnWidth(availableWidth, wTheme);
  }

  // Heuristic: if it fits horizontally and has a reasonable number of columns, use table
  if (totalEstimatedWidth <= availableWidth && effectiveHeaders.length <= 6) {
    return TTableHelper.from<T, K>(context, headers, items, decoration: decoration);
  } else {
    return pw.Column(
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      children: items.map((item) {
        return pw.Column(
          crossAxisAlignment: pw.CrossAxisAlignment.start,
          children: [
            fromHeaders<T, K>(context, effectiveHeaders, item,
                decoration: decoration, availableWidth: availableWidth, theme: wTheme, imageCache: imageCache),
            pw.SizedBox(height: 15),
          ],
        );
      }).toList(),
    );
  }
}