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 += _estimateNaturalWidth(kv, wTheme, availableWidth);
  }

  // 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 {
    final finalImageCache = imageCache ?? await TPdfWidgetHelper.preCacheImages(context, effectiveHeaders, items);

    return pw.Column(
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      children: items.map((item) {
        return pw.Container(
          margin: const pw.EdgeInsets.only(bottom: 6),
          padding: const pw.EdgeInsets.all(4),
          decoration: pw.BoxDecoration(
            color: colors.surfaceContainerLowest.o(0.25).toPdfColor(),
            borderRadius: const pw.BorderRadius.all(pw.Radius.circular(8)),
            border: pw.Border.all(
              color: colors.outlineVariant.o(0.25).toPdfColor(),
              width: 0.5,
            ),
          ),
          child: fromHeaders<T, K>(
            context,
            effectiveHeaders,
            item,
            decoration: decoration,
            availableWidth: availableWidth - 8,
            theme: wTheme,
            imageCache: finalImageCache,
          ),
        );
      }).toList(),
    );
  }
}