You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/views/widgets/date_and_time/date_picker.dart

216 lines
8.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
class ADatePicker extends StatelessWidget {
final DateTime? date; // Nullable
final DateTime? from; // Nullable
final DateTime? to; // Nullable
final String label;
final bool hideShadow;
final String? hint; // Nullable
final Function(DateTime)? onDatePicker; // Nullable
final bool enable;
final bool withBorder;
final bool withIcon;
final Color? backgroundColor; // Nullable
final bool formatDateWithTime;
final double? height; // Nullable
const ADatePicker({
Key? key,
required this.label,
this.withBorder = true,
this.height,
this.backgroundColor,
this.hideShadow = false,
this.hint,
this.date,
this.withIcon = true,
this.formatDateWithTime = false,
this.onDatePicker,
this.from,
this.to,
this.enable = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: height,
decoration: BoxDecoration(
color: !enable ? AppColor.disableFieldBackground(context) : AppColor.dropDownBackground(context),
borderRadius: BorderRadius.circular(16),
border: withBorder ? Border.all(width: 1, color: AppColor.border2Color(context)) : const Border(),
boxShadow: hideShadow ? null : [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Text(
label,
style: AppTextStyles.tinyFont.copyWith(color: AppColor.floatingTextStyleColor(context)),
),
4.height,
(date == null
? hint ?? context.translation.pickADate
: (formatDateWithTime
? date?.toIso8601String().toFirstActionFormat // Use null-aware operator
: (date?.toIso8601String().split("T").first ?? context.translation.pickADate)))!
.bodyText(context)
.custom(color: AppColor.textStyleColor(context)),
],
).expanded,
// enable ? 16.width : const Spacer(),
withIcon ? "calender".toSvgAsset(width: 20, color: AppColor.icon2Color(context)) : const SizedBox(),
],
),
).onPress(enable
? () async {
final DateTime? picked = await showDatePicker(
// Nullable DateTime
context: context,
initialDate: DateTime.now(),
firstDate: from ?? DateTime.now(),
lastDate: to ?? DateTime.now(),
builder: (BuildContext context, Widget? child) {
final ThemeData currentTheme = Theme.of(context);
final bool isDark = context.isDark;
return Theme(
data: currentTheme.copyWith(
datePickerTheme: DatePickerThemeData(
// Header styling
headerBackgroundColor: AppColor.primary10,
headerForegroundColor: Colors.white,
subHeaderForegroundColor: AppColor.textColor(context),
// Background
backgroundColor: AppColor.bottomSheetColor(context),
// Surface tint removal for clean look
surfaceTintColor: Colors.transparent,
// Day cell styling
dayForegroundColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return Colors.white;
}
if (states.contains(WidgetState.disabled)) {
return isDark ? AppColor.neutral10.withOpacity(0.3) : AppColor.neutral20.withOpacity(0.4);
}
return AppColor.textStyleColor(context);
}),
dayBackgroundColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10;
}
return Colors.transparent;
}),
// Today's date styling
todayForegroundColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return Colors.white;
}
return AppColor.primary10;
}),
todayBackgroundColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10;
}
return Colors.transparent;
}),
todayBorder: const BorderSide(color: AppColor.primary10, width: 1),
// Year selector styling
yearForegroundColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return Colors.white;
}
if (states.contains(WidgetState.disabled)) {
return isDark ? AppColor.neutral10.withOpacity(0.3) : AppColor.neutral20.withOpacity(0.4);
}
return AppColor.textStyleColor(context);
}),
yearBackgroundColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10;
}
return Colors.transparent;
}),
// Weekday labels
weekdayStyle: TextStyle(
color: AppColor.labelTextStyleColor(context),
fontWeight: FontWeight.w600,
),
// Day style
dayStyle: TextStyle(
color: AppColor.textStyleColor(context),
),
// Year style
yearStyle: TextStyle(
color: AppColor.textStyleColor(context),
),
// Divider
dividerColor: AppColor.borderColor(context),
// Shape
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
// Input decoration for text field mode
inputDecorationTheme: InputDecorationTheme(
focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide(color: AppColor.primary10, width: 2),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColor.borderColor(context)),
),
),
),
// Button styling (Cancel/OK buttons)
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: AppColor.primary10,
textStyle: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
),
// Icon theme for navigation arrows
iconTheme: IconThemeData(color: Colors.white),
),
child: child!,
);
},
);
if (picked != null && onDatePicker != null) {
onDatePicker!(picked); // Use null-aware operator
}
}
: null);
}
}