114 lines
3.2 KiB
Dart
114 lines
3.2 KiB
Dart
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<Widget> columns,
|
|
required List<List<Widget>> 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<ShadTableCell> header,
|
|
required List<List<ShadTableCell>> rows,
|
|
this.columnSpanExtent,
|
|
this.rowHeight = 56,
|
|
this.maxHeight,
|
|
this.onRowTap,
|
|
this.emptyLabel = '데이터가 없습니다.',
|
|
}) : _columns = null,
|
|
_rows = null,
|
|
_headerCells = header,
|
|
_rowCells = rows;
|
|
|
|
final List<Widget>? _columns;
|
|
final List<List<Widget>>? _rows;
|
|
final List<ShadTableCell>? _headerCells;
|
|
final List<List<ShadTableCell>>? _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<ShadTableCell> headerCells;
|
|
late final List<List<ShadTableCell>> 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,
|
|
),
|
|
);
|
|
}
|
|
}
|