import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; /// ShadTable.list를 감싼 공통 테이블 래퍼. class SuperportTable extends StatelessWidget { const SuperportTable({ super.key, required List columns, required List> rows, this.columnSpanExtent, this.rowHeight = 56, this.maxHeight, this.onRowTap, this.emptyLabel = '데이터가 없습니다.', }) : _columns = columns, _rows = rows, _headerCells = null, _rowCells = null; const SuperportTable.fromCells({ super.key, required List header, required List> rows, this.columnSpanExtent, this.rowHeight = 56, this.maxHeight, this.onRowTap, this.emptyLabel = '데이터가 없습니다.', }) : _columns = null, _rows = null, _headerCells = header, _rowCells = rows; final List? _columns; final List>? _rows; final List? _headerCells; final List>? _rowCells; final TableSpanExtent? Function(int index)? columnSpanExtent; final double rowHeight; final double? maxHeight; final void Function(int index)? onRowTap; final String emptyLabel; @override Widget build(BuildContext context) { late final List headerCells; late final List> tableRows; if (_rowCells case final rows?) { if (rows.isEmpty) { final theme = ShadTheme.of(context); return Padding( padding: const EdgeInsets.all(32), child: Center(child: Text(emptyLabel, style: theme.textTheme.muted)), ); } final header = _headerCells; if (header == null) { throw StateError('header cells must not be null when using fromCells'); } headerCells = header; tableRows = rows; } else { final rows = _rows; if (rows == null || rows.isEmpty) { final theme = ShadTheme.of(context); return Padding( padding: const EdgeInsets.all(32), child: Center(child: Text(emptyLabel, style: theme.textTheme.muted)), ); } headerCells = _columns! .map( (cell) => cell is ShadTableCell ? cell : ShadTableCell.header(child: cell), ) .toList(); tableRows = [ for (final row in rows) row .map( (cell) => cell is ShadTableCell ? cell : ShadTableCell(child: cell), ) .toList(), ]; } final estimatedHeight = (tableRows.length + 1) * rowHeight; final minHeight = rowHeight * 2; final effectiveHeight = math.max( minHeight, maxHeight == null ? estimatedHeight : math.min(estimatedHeight, maxHeight!), ); return SizedBox( height: effectiveHeight, child: ShadTable.list( header: headerCells, columnSpanExtent: columnSpanExtent, rowSpanExtent: (_) => FixedTableSpanExtent(rowHeight), onRowTap: onRowTap, primary: false, children: tableRows, ), ); } }