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/time_picker.dart

191 lines
6.3 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/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
Future<TimeOfDay?> showThemedTimePicker({
required BuildContext context,
required TimeOfDay initialTime,
String? helpText,
String? cancelText,
String? confirmText,
TimePickerEntryMode initialEntryMode = TimePickerEntryMode.dial,
}) async {
return await showTimePicker(
context: context,
initialTime: initialTime,
helpText: helpText,
cancelText: cancelText,
confirmText: confirmText,
initialEntryMode: initialEntryMode,
builder: (BuildContext context, Widget? child) {
return Theme(
data: Theme.of(context).copyWith(
timePickerTheme: TimePickerThemeData(
// Background color
backgroundColor: AppColor.bottomSheetColor(context),
// Hour/Minute input boxes styling
hourMinuteShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: AppColor.borderColor(context)),
),
// AM/PM selector border
dayPeriodBorderSide: BorderSide(color: AppColor.borderColor(context)),
// AM/PM selector background color
dayPeriodColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10;
}
return Colors.transparent;
}),
// AM/PM selector text color
dayPeriodTextColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return Colors.white;
}
return AppColor.textStyleColor(context);
}),
// Clock dial hand color
dialHandColor: AppColor.primary10,
// Clock dial background
dialBackgroundColor: AppColor.scaffoldBackground(context),
// Hour/Minute box background color
hourMinuteColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10;
}
return AppColor.scaffoldBackground(context);
}),
// Hour/Minute box text color
hourMinuteTextColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return Colors.white;
}
return AppColor.textStyleColor(context);
}),
// Clock dial numbers text color
dialTextColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return Colors.white;
}
return AppColor.textStyleColor(context);
}),
// Entry mode switch icon color
entryModeIconColor: AppColor.primary10,
// Help text styling
helpTextStyle: TextStyle(
color: AppColor.textStyleColor(context),
),
// Dialog shape
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
// Action buttons (Cancel/OK) styling
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: AppColor.primary10,
textStyle: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
),
),
child: child!,
);
},
);
}
class ATimePicker extends StatelessWidget {
final TimeOfDay? time;
final String label;
final String? icon;
final String? hint;
final Function(TimeOfDay)? onTimePicker;
final bool enable, withBorder, withIcon;
final Color? backgroundColor;
final double? height;
const ATimePicker({
Key? key,
required this.label,
this.withBorder = true,
this.icon,
this.withIcon = true,
this.height,
this.backgroundColor,
this.hint,
this.time,
this.onTimePicker,
this.enable = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: height,
decoration: BoxDecoration(
color: backgroundColor ??
(context.isDark && (enable == false)
? AppColor.neutral50
: (enable == false)
? AppColor.neutral40
: AppColor.background(context)),
borderRadius: BorderRadius.circular(10),
border: withBorder ? Border.all(width: 1, color: Theme.of(context).scaffoldBackgroundColor) : const Border(),
boxShadow: [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: [
label.tinyFont(context),
(time == null ? hint ?? context.translation.pickTime : (time?.format(context) ?? context.translation.pickADate))
.bodyText(context)
.custom(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
],
).expanded,
enable ? 16.width : const Spacer(),
withIcon
? icon != null
? icon!.toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null)
: "calender".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null)
: const SizedBox(),
],
),
).onPress(enable
? () async {
// Use the unified themed time picker
TimeOfDay? pickedTime = await showThemedTimePicker(
context: context,
initialTime: time ?? TimeOfDay.now(),
);
if (pickedTime != null) {
if (onTimePicker != null) onTimePicker!(pickedTime);
}
}
: null);
}
}