전역 구조 리팩터링 및 테스트 확장
This commit is contained in:
133
lib/widgets/components/superport_date_picker.dart
Normal file
133
lib/widgets/components/superport_date_picker.dart
Normal file
@@ -0,0 +1,133 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart' as lucide;
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
|
||||
/// 단일 날짜 선택을 위한 공통 버튼 위젯.
|
||||
class SuperportDatePickerButton extends StatelessWidget {
|
||||
const SuperportDatePickerButton({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
this.firstDate,
|
||||
this.lastDate,
|
||||
this.dateFormat,
|
||||
this.placeholder = '날짜 선택',
|
||||
this.enabled = true,
|
||||
this.initialDate,
|
||||
});
|
||||
|
||||
final DateTime? value;
|
||||
final ValueChanged<DateTime> onChanged;
|
||||
final DateTime? firstDate;
|
||||
final DateTime? lastDate;
|
||||
final intl.DateFormat? dateFormat;
|
||||
final String placeholder;
|
||||
final bool enabled;
|
||||
final DateTime? initialDate;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final format = dateFormat ?? intl.DateFormat('yyyy-MM-dd');
|
||||
final displayText = value != null ? format.format(value!) : placeholder;
|
||||
return ShadButton.outline(
|
||||
onPressed: !enabled
|
||||
? null
|
||||
: () async {
|
||||
final now = DateTime.now();
|
||||
final baseFirst = firstDate ?? DateTime(now.year - 10);
|
||||
final baseLast = lastDate ?? DateTime(now.year + 5);
|
||||
final seed = value ?? initialDate ?? now;
|
||||
final adjustedInitial = seed.clamp(baseFirst, baseLast);
|
||||
final picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: adjustedInitial,
|
||||
firstDate: baseFirst,
|
||||
lastDate: baseLast,
|
||||
);
|
||||
if (picked != null) {
|
||||
onChanged(picked);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(displayText),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(lucide.LucideIcons.calendar, size: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 날짜 범위 선택을 위한 공통 버튼 위젯.
|
||||
class SuperportDateRangePickerButton extends StatelessWidget {
|
||||
const SuperportDateRangePickerButton({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
this.firstDate,
|
||||
this.lastDate,
|
||||
this.dateFormat,
|
||||
this.placeholder = '기간 선택',
|
||||
this.enabled = true,
|
||||
this.initialDateRange,
|
||||
});
|
||||
|
||||
final DateTimeRange? value;
|
||||
final ValueChanged<DateTimeRange?> onChanged;
|
||||
final DateTime? firstDate;
|
||||
final DateTime? lastDate;
|
||||
final intl.DateFormat? dateFormat;
|
||||
final String placeholder;
|
||||
final bool enabled;
|
||||
final DateTimeRange? initialDateRange;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final format = dateFormat ?? intl.DateFormat('yyyy-MM-dd');
|
||||
final label = value == null
|
||||
? placeholder
|
||||
: '${format.format(value!.start)} ~ ${format.format(value!.end)}';
|
||||
return ShadButton.outline(
|
||||
onPressed: !enabled
|
||||
? null
|
||||
: () async {
|
||||
final now = DateTime.now();
|
||||
final baseFirst = firstDate ?? DateTime(now.year - 10);
|
||||
final baseLast = lastDate ?? DateTime(now.year + 5);
|
||||
final initialRange = value ?? initialDateRange;
|
||||
final currentDate = initialRange?.start ?? now;
|
||||
final picked = await showDateRangePicker(
|
||||
context: context,
|
||||
firstDate: baseFirst,
|
||||
lastDate: baseLast,
|
||||
initialDateRange: initialRange,
|
||||
currentDate: currentDate.clamp(baseFirst, baseLast),
|
||||
);
|
||||
if (picked != null) {
|
||||
onChanged(picked);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(lucide.LucideIcons.calendar, size: 16),
|
||||
const SizedBox(width: 8),
|
||||
Flexible(child: Text(label, overflow: TextOverflow.ellipsis)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension _ClampDate on DateTime {
|
||||
DateTime clamp(DateTime min, DateTime max) {
|
||||
if (isBefore(min)) return min;
|
||||
if (isAfter(max)) return max;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user