feat(zipcode): compact column widths for popup; ensure no horizontal scroll within dialog
- ZipcodeTable: dynamic widths; shrink columns when target width < standard - Use computed widths for header and rows; actions width fixed - Works with tableMaxWidthFraction from ZipcodeSearchScreen],
This commit is contained in:
@@ -35,15 +35,51 @@ class ZipcodeTable extends StatelessWidget {
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
// 고정폭 + 마지막 filler
|
||||
const double minW = 160 + 180 + 180 + 320 + 140 + 24;
|
||||
// Standard widths
|
||||
const double zipStd = 160.0;
|
||||
const double sidoStd = 180.0;
|
||||
const double guStd = 180.0;
|
||||
const double etcStd = 320.0;
|
||||
const double actionsStd = 140.0;
|
||||
const double fudge = 24.0; // internal paddings/margins
|
||||
|
||||
final double viewportW = constraints.maxWidth.isFinite
|
||||
? constraints.maxWidth
|
||||
: MediaQuery.sizeOf(context).width;
|
||||
final double cappedW = maxWidthCap != null
|
||||
final double targetW = maxWidthCap != null
|
||||
? math.min(viewportW, maxWidthCap!)
|
||||
: viewportW;
|
||||
final double tableW = cappedW >= minW ? cappedW : minW;
|
||||
const double etcW = 320.0;
|
||||
|
||||
final double stdMin = zipStd + sidoStd + guStd + etcStd + actionsStd + fudge;
|
||||
final bool compact = targetW < stdMin;
|
||||
|
||||
// Effective widths
|
||||
double zipW;
|
||||
double sidoW;
|
||||
double guW;
|
||||
double etcW;
|
||||
double actionsW;
|
||||
bool includeFiller;
|
||||
|
||||
if (!compact) {
|
||||
zipW = zipStd;
|
||||
sidoW = sidoStd;
|
||||
guW = guStd;
|
||||
etcW = etcStd;
|
||||
actionsW = actionsStd;
|
||||
includeFiller = true; // use remaining width as filler column
|
||||
} else {
|
||||
// Compact widths to fit inside targetW without horizontal scroll
|
||||
zipW = 110.0;
|
||||
sidoW = 120.0;
|
||||
guW = 120.0;
|
||||
actionsW = 110.0;
|
||||
final double remaining = targetW - fudge - (zipW + sidoW + guW + actionsW);
|
||||
etcW = math.max(180.0, remaining);
|
||||
includeFiller = false; // no filler in compact mode
|
||||
}
|
||||
|
||||
final double tableW = targetW;
|
||||
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
@@ -53,17 +89,19 @@ class ZipcodeTable extends StatelessWidget {
|
||||
columnSpanExtent: (index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return const FixedTableSpanExtent(160); // 우편번호
|
||||
return FixedTableSpanExtent(zipW); // 우편번호
|
||||
case 1:
|
||||
return const FixedTableSpanExtent(180); // 시도
|
||||
return FixedTableSpanExtent(sidoW); // 시도
|
||||
case 2:
|
||||
return const FixedTableSpanExtent(180); // 구/군
|
||||
return FixedTableSpanExtent(guW); // 구/군
|
||||
case 3:
|
||||
return const FixedTableSpanExtent(etcW); // 상세주소
|
||||
return FixedTableSpanExtent(etcW); // 상세주소
|
||||
case 4:
|
||||
return const FixedTableSpanExtent(140); // 작업
|
||||
return FixedTableSpanExtent(actionsW); // 작업
|
||||
case 5:
|
||||
return const RemainingTableSpanExtent(); // filler
|
||||
return includeFiller
|
||||
? const RemainingTableSpanExtent()
|
||||
: const FixedTableSpanExtent(0);
|
||||
default:
|
||||
return const FixedTableSpanExtent(100);
|
||||
}
|
||||
@@ -73,15 +111,15 @@ class ZipcodeTable extends StatelessWidget {
|
||||
const ShadTableCell.header(child: Text('시도')),
|
||||
const ShadTableCell.header(child: Text('구/군')),
|
||||
ShadTableCell.header(child: SizedBox(width: etcW, child: const Text('상세주소'))),
|
||||
const ShadTableCell.header(child: Text('작업')),
|
||||
const ShadTableCell.header(child: SizedBox.shrink()),
|
||||
ShadTableCell.header(child: SizedBox(width: actionsW, child: const Text('작업'))),
|
||||
if (includeFiller) const ShadTableCell.header(child: SizedBox.shrink()),
|
||||
],
|
||||
children: zipcodes.map((zipcode) {
|
||||
return [
|
||||
// 우편번호 (오버플로우 방지)
|
||||
ShadTableCell(
|
||||
child: SizedBox(
|
||||
width: 160,
|
||||
width: zipW,
|
||||
child: FittedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
fit: BoxFit.scaleDown,
|
||||
@@ -138,13 +176,16 @@ class ZipcodeTable extends StatelessWidget {
|
||||
),
|
||||
// 작업
|
||||
ShadTableCell(
|
||||
child: SizedBox(
|
||||
width: actionsW,
|
||||
child: ShadButton(
|
||||
onPressed: () => onSelect(zipcode),
|
||||
size: ShadButtonSize.sm,
|
||||
child: const Text('선택', style: TextStyle(fontSize: 11)),
|
||||
),
|
||||
),
|
||||
const ShadTableCell(child: SizedBox.shrink()),
|
||||
),
|
||||
if (includeFiller) const ShadTableCell(child: SizedBox.shrink()),
|
||||
];
|
||||
}).toList(),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user