전역 구조 리팩터링 및 테스트 확장
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
|
||||
@@ -5,54 +7,107 @@ import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
class SuperportTable extends StatelessWidget {
|
||||
const SuperportTable({
|
||||
super.key,
|
||||
required this.columns,
|
||||
required this.rows,
|
||||
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;
|
||||
|
||||
final List<Widget> columns;
|
||||
final List<List<Widget>> rows;
|
||||
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) {
|
||||
if (rows.isEmpty) {
|
||||
final theme = ShadTheme.of(context);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Center(
|
||||
child: Text(emptyLabel, style: theme.textTheme.muted),
|
||||
),
|
||||
);
|
||||
}
|
||||
late final List<ShadTableCell> headerCells;
|
||||
late final List<List<ShadTableCell>> tableRows;
|
||||
|
||||
final tableRows = [
|
||||
for (final row in rows)
|
||||
row
|
||||
.map(
|
||||
(cell) => cell is ShadTableCell ? cell : ShadTableCell(child: cell),
|
||||
)
|
||||
.toList(),
|
||||
];
|
||||
|
||||
return ShadTable.list(
|
||||
header: columns
|
||||
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(),
|
||||
columnSpanExtent: columnSpanExtent,
|
||||
rowSpanExtent: (_) => FixedTableSpanExtent(rowHeight),
|
||||
onRowTap: onRowTap,
|
||||
children: tableRows,
|
||||
.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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user