### Run Flutter Example App Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/CLAUDE.md Navigate to the example directory and run the example application. ```bash cd example && flutter run ``` -------------------------------- ### Get Flutter Project Dependencies Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/CLAUDE.md Download and install all the dependencies required by the Flutter project. ```bash flutter pub get ``` -------------------------------- ### Show OmniDateTimePicker Example Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/showOmniDateTimePicker.md Demonstrates how to use the `showOmniDateTimePicker` function to display a date and time picker. This example shows basic configuration including initial date, date range, 24-hour mode, and disabling Sundays. ```dart import 'package:flutter/material.dart'; import 'package:omni_datetime_picker/omni_datetime_picker.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: const DatePickerScreen(), ); } } class DatePickerScreen extends StatefulWidget { const DatePickerScreen({Key? key}) : super(key: key); @override State createState() => _DatePickerScreenState(); } class _DatePickerScreenState extends State { DateTime? selectedDateTime; void _showDateTimePicker() async { final DateTime? result = await showOmniDateTimePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), is24HourMode: true, isShowSeconds: false, minutesInterval: 5, borderRadius: const BorderRadius.all(Radius.circular(16)), constraints: const BoxConstraints( maxWidth: 350, maxHeight: 650, ), title: const Text('Select Date & Time'), selectableDayPredicate: (dateTime) { // Disable Sundays return dateTime.weekday != DateTime.sunday; }, ); if (result != null) { setState(() { selectedDateTime = result; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('DateTime Picker')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ if (selectedDateTime != null) Text('Selected: ${selectedDateTime?.toString()}'), ElevatedButton( onPressed: _showDateTimePicker, child: const Text('Pick Date & Time'), ), ], ), ), ); } } ``` -------------------------------- ### Basic Calendar Usage Example Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Calendar.md Demonstrates how to use the Calendar widget in a Flutter application, including setting initial, first, and last dates, and handling date changes. This example also shows how to disable weekends using the selectableDayPredicate. ```dart import 'package:flutter/material.dart'; import 'package:omni_datetime_picker/src/components/calendar/calendar.dart'; class CalendarScreen extends StatefulWidget { const CalendarScreen({Key? key}) : super(key: key); @override State createState() => _CalendarScreenState(); } class _CalendarScreenState extends State { DateTime? selectedDate; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Calendar Picker')), body: Column( children: [ Expanded( child: Calendar( initialDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), onDateChanged: (date) { setState(() { selectedDate = date; }); }, selectableDayPredicate: (dateTime) { // Disable weekends if (dateTime.weekday == DateTime.saturday || dateTime.weekday == DateTime.sunday) { return false; } return true; }, ), ), if (selectedDate != null) Padding( padding: const EdgeInsets.all(16), child: Text('Selected: ${selectedDate?.toString()}'), ), ], ), ); } } ``` -------------------------------- ### Direct OmniDatetimePickerBloc Usage Example Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/OmniDatetimePickerBloc.md Demonstrates how to instantiate, listen to, and interact with the OmniDatetimePickerBloc directly. This is useful for custom extensions or integrations. ```dart import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:omni_datetime_picker/src/bloc/omni_datetime_picker_bloc.dart'; // Create the BLoC final bloc = OmniDatetimePickerBloc( initialDateTime: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), ); // Listen to state changes bloc.stream.listen((state) { print('Current DateTime: ${state.dateTime}'); print('Is Valid: ${state.isValidTime}'); }); // Emit events to update state bloc.add(UpdateDate(dateTime: DateTime(2023, 6, 15))); bloc.add(UpdateHour(hour: 14)); bloc.add(UpdateMinute(minute: 30)); // Clean up await bloc.close(); ``` -------------------------------- ### Advanced Calendar: Holiday Blackout Example Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Calendar.md An advanced example demonstrating how to use the selectableDayPredicate to disable specific holidays and weekends, preventing users from selecting these dates. ```dart Calendar( initialDate: DateTime.now(), firstDate: DateTime(2024), lastDate: DateTime(2025), onDateChanged: (date) { print('Selected: $date'); }, selectableDayPredicate: (dateTime) { // Define holidays final holidays = [ DateTime(2024, 12, 25), // Christmas DateTime(2024, 12, 26), // Boxing Day DateTime(2025, 1, 1), // New Year ]; // Disable holidays for (final holiday in holidays) { if (dateTime.year == holiday.year && dateTime.month == holiday.month && dateTime.day == holiday.day) { return false; } } // Disable weekends return dateTime.weekday != DateTime.saturday && dateTime.weekday != DateTime.sunday; }, ) ``` -------------------------------- ### State Management with GetX Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Integrate the OmniDateTimePicker with the GetX state management library. This example demonstrates managing the selected date using Rx variables and a controller. ```dart class DateController extends GetxController { final selectedDate = Rx(null); Future pickDateTime() async { final result = await showOmniDateTimePicker( context: Get.context!, ); if (result != null) { selectedDate.value = result; } } } // Usage Obx(() => Text( Get.find().selectedDate.value?.toString() ?? 'Pick Date' )) ``` -------------------------------- ### State Management with Provider Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Integrate the OmniDateTimePicker with the Provider state management library. This example shows how to manage the selected date and trigger the picker from a button. ```dart class DatePickerProvider extends ChangeNotifier { DateTime? _selectedDate; DateTime? get selectedDate => _selectedDate; Future pickDateTime(BuildContext context) async { final result = await showOmniDateTimePicker(context: context); if (result != null) { _selectedDate = result; notifyListeners(); } } } // Usage Consumer( builder: (context, provider, child) { return ElevatedButton( onPressed: () => provider.pickDateTime(context), child: Text(provider.selectedDate?.toString() ?? 'Pick Date'), ); }, ) ``` -------------------------------- ### Custom Actions Builder Example Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/configuration.md Demonstrates how to build custom cancel and confirm buttons for the picker using the `actionsBuilder` parameter. This allows for full control over the appearance and behavior of the action buttons. ```dart actionsBuilder: (onCancel, cancelText, onSave, saveText) { return [ Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: OutlinedButton( onPressed: onCancel, child: Text(cancelText), ), ), ), Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: FilledButton( onPressed: onSave, child: Text(saveText), ), ), ), ]; } ``` -------------------------------- ### showOmniDateTimeRangePicker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/showOmniDateTimeRangePicker.md Displays a dialog for selecting a start and end date/time range. It returns a Future that resolves to a list containing the selected start and end DateTime objects, or null if the dialog is dismissed. ```APIDOC ## showOmniDateTimeRangePicker Displays a dialog for selecting a start and end date/time range. ### Parameters - **context** (BuildContext) - Required - The build context of the calling widget. - **startInitialDate** (DateTime?) - Optional - Initially selected start date/time. Defaults to the current date/time. - **startFirstDate** (DateTime?) - Optional - Earliest selectable start date. Defaults to 1970-01-01. - **startLastDate** (DateTime?) - Optional - Latest selectable start date. Defaults to 2100-12-31. - **endInitialDate** (DateTime?) - Optional - Initially selected end date/time. Defaults to the current date/time. - **endFirstDate** (DateTime?) - Optional - Earliest selectable end date. Defaults to 1970-01-01. - **endLastDate** (DateTime?) - Optional - Latest selectable end date. Defaults to 2100-12-31. - **is24HourMode** (bool?) - Optional - Whether to use 24-hour format. Defaults to false. - **isShowSeconds** (bool?) - Optional - Whether to display seconds in time picker. Defaults to false. - **minutesInterval** (int?) - Optional - Minute increment interval (1-60). Defaults to 1. - **secondsInterval** (int?) - Optional - Second increment interval (1-60). Defaults to 1. - **isForce2Digits** (bool?) - Optional - Whether to pad time values with leading zeros. Defaults to true. - **isForceEndDateAfterStartDate** (bool?) - Optional - If true, enforces that end date must be after start date. Defaults to false. - **onStartDateAfterEndDateError** (void Function()?) - Optional - Callback invoked if validation fails when start date is after end date. - **borderRadius** (BorderRadiusGeometry?) - Optional - Corner radius of the dialog. Defaults to BorderRadius.circular(16). - **transitionBuilder** (Widget Function(BuildContext, Animation, Animation, Widget)?) - Optional - Custom transition animation builder for dialog appearance. Defaults to FadeTransition. - **transitionDuration** (Duration?) - Optional - Duration of the dialog transition animation. Defaults to 200ms. - **barrierDismissible** (bool?) - Optional - Whether tapping outside the dialog closes it. Defaults to true. - **barrierColor** (Color?) - Optional - Color of the modal barrier. Defaults to Color(0x80000000). - **title** (Widget?) - Optional - Title widget displayed at the top of the dialog. - **titleSeparator** (Widget?) - Optional - Separator widget between title and picker content. - **startWidget** (Widget?) - Optional - Label widget for the start date tab. - **endWidget** (Widget?) - Optional - Label widget for the end date tab. - **separator** (Widget?) - Optional - Separator widget between date and time pickers. - **type** (OmniDateTimePickerType) - Optional - Type of picker: date, time, or dateAndTime. Defaults to OmniDateTimePickerType.dateAndTime. - **startSelectableDayPredicate** (bool Function(DateTime)?) - Optional - Callback to disable specific start dates; return false to disable. - **endSelectableDayPredicate** (bool Function(DateTime)?) - Optional - Callback to disable specific end dates; return false to disable. - **defaultTab** (DefaultTab) - Optional - Which tab (start or end) to display by default. Defaults to DefaultTab.start. - **padding** (EdgeInsets?) - Optional - Internal padding inside the dialog. - **insetPadding** (EdgeInsets?) - Optional - Margin around the dialog. - **theme** (ThemeData?) - Optional - Custom theme for the dialog. Defaults to the current theme. - **constraints** (BoxConstraints?) - Optional - Size constraints for the dialog. - **actionsBuilder** (ButtonRowBuilder?) - Optional - Custom builder for confirm/cancel buttons. ### Return Type `Future?>` - A Future that resolves to a list with two DateTime values: [startDateTime, endDateTime], or null if the dialog was canceled. ``` -------------------------------- ### State Management with Riverpod Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Integrate the OmniDateTimePicker with the Riverpod state management library. This example shows how to use a StateNotifierProvider to manage the selected date. ```dart final selectedDateProvider = StateNotifierProvider((ref) { return DateNotifier(); }); class DateNotifier extends StateNotifier { DateNotifier() : super(null); Future pickDateTime(BuildContext context) async { final result = await showOmniDateTimePicker(context: context); if (result != null) { state = result; } } } // Usage Consumer( builder: (context, ref, child) { final date = ref.watch(selectedDateProvider); return Text(date?.toString() ?? 'Pick Date'); }, ) ``` -------------------------------- ### Add Omni DateTime Picker Dependency Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md Add this to your package's pubspec.yaml file and run `flutter pub get`. ```yaml dependencies: omni_datetime_picker: ^2.3.2 ``` -------------------------------- ### Show Date/Time Range Picker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/showOmniDateTimeRangePicker.md Displays a dialog for selecting a start and end date/time. Customize appearance and behavior using various parameters. ```dart Future?>? result = await showOmniDateTimeRangePicker( context: context, startInitialDate: DateTime.now().subtract(const Duration(days: 5)), startLastDate: DateTime.now(), endInitialDate: DateTime.now(), endLastDate: DateTime.now().add(const Duration(days: 5)), is24HourMode: true, isShowSeconds: true, minutesInterval: 15, secondsInterval: 15, isForce2Digits: true, isForceEndDateAfterStartDate: true, onStartDateAfterEndDateError: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Start date must be before end date.')), ); }, borderRadius: BorderRadius.circular(16), transitionDuration: const Duration(milliseconds: 300), barrierDismissible: true, barrierColor: Colors.black.withOpacity(0.5), title: const Text('Select Date Range'), titleSeparator: const Divider(thickness: 1), startWidget: const Text('Start'), endWidget: const Text('End'), separator: const VerticalDivider(), type: OmniDateTimePickerType.dateAndTime, startSelectableDayPredicate: (DateTime day) { return day.weekday != DateTime.saturday && day.weekday != DateTime.sunday; }, endSelectableDayPredicate: (DateTime day) { return day.weekday != DateTime.saturday && day.weekday != DateTime.sunday; }, defaultTab: DefaultTab.start, padding: const EdgeInsets.all(16), insetPadding: const EdgeInsets.all(24), theme: ThemeData.light().copyWith( primaryColor: Colors.blue, colorScheme: const ColorScheme.light(primary: Colors.blue), ), constraints: const BoxConstraints(maxWidth: 500, maxHeight: 500), actionsBuilder: (context, ok, cancel) { return [ok, cancel]; }, ); if (result != null) { print('Selected range: ${result[0]} - ${result[1]}'); } else { print('Dialog canceled'); } ``` -------------------------------- ### Custom ButtonRowBuilder Example Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/types.md A type alias for a function that builds custom action buttons for the dialog. Use this to define your own cancel and confirm buttons. ```dart typedef ButtonRowBuilder = List Function( void Function() onCancelPressed, String cancelText, void Function()? onSavePressed, String saveText, ); ``` ```dart actionsBuilder: (onCancel, cancelText, onSave, saveText) { return [ TextButton( onPressed: onCancel, child: Text(cancelText), ), const SizedBox(width: 12), ElevatedButton( onPressed: onSave, child: Text(saveText), ), ]; } ``` -------------------------------- ### Custom Range Labels for Start and End Dates Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Customize the appearance of the start and end date selection widgets using `startWidget` and `endWidget` properties. ```dart List? result = await showOmniDateTimeRangePicker( context: context, startWidget: Padding( padding: const EdgeInsets.all(8), child: Row( children: [ const Icon(Icons.flag), const SizedBox(width: 8), const Text('Departure'), ], ), ), endWidget: Padding( padding: const EdgeInsets.all(8), child: Row( children: [ const Icon(Icons.flag_outlined), const SizedBox(width: 8), const Text('Return'), ], ), ), ); ``` -------------------------------- ### showOmniDateTimeRangePicker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/showOmniDateTimeRangePicker.md Presents a dialog for selecting a start and end date and time. It offers various customization options for date constraints, appearance, and behavior. ```APIDOC ## showOmniDateTimeRangePicker ### Description This function displays a modal dialog that allows the user to select both a start and an end date and time. It is highly customizable, enabling control over initial dates, selectable date ranges, time formats, visual elements like border radius and constraints, and custom error handling for date selection logic. ### Method `showOmniDateTimeRangePicker` ### Parameters - **context** (BuildContext) - Required - The build context for showing the dialog. - **startInitialDate** (DateTime?) - Optional - The initially selected start date. - **endInitialDate** (DateTime?) - Optional - The initially selected end date. - **startFirstDate** (DateTime?) - Optional - The earliest selectable date for the start date. - **startLastDate** (DateTime?) - Optional - The latest selectable date for the start date. - **endFirstDate** (DateTime?) - Optional - The earliest selectable date for the end date. - **endLastDate** (DateTime?) - Optional - The latest selectable date for the end date. - **is24HourMode** (bool) - Optional - If true, displays time in 24-hour format. - **isShowSeconds** (bool) - Optional - If true, displays seconds in the time picker. - **minutesInterval** (int) - Optional - The interval for minutes selection (e.g., 15 means options like 00, 15, 30, 45). - **isForceEndDateAfterStartDate** (bool) - Optional - If true, ensures the end date is always after the start date. - **borderRadius** (BorderRadius?) - Optional - Defines the border radius for the dialog. - **constraints** (BoxConstraints?) - Optional - Constraints for the dialog's size. - **title** (Widget?) - Optional - A custom title widget for the dialog. - **defaultTab** (DefaultTab?) - Optional - The default tab to show (start or end). - **onStartDateAfterEndDateError** (VoidCallback?) - Optional - A callback function executed when the start date is after the end date. - **startSelectableDayPredicate** (SelectableDayPredicate?) - Optional - A function to determine if a start date is selectable. - **endSelectableDayPredicate** (SelectableDayPredicate?) - Optional - A function to determine if an end date is selectable. ### Returns - `Future?>` - A future that resolves to a list containing the start and end `DateTime` objects, or `null` if the dialog is dismissed. ### Example ```dart final List? result = await showOmniDateTimeRangePicker( context: context, startInitialDate: DateTime.now(), endInitialDate: DateTime.now().add(const Duration(days: 7)), startFirstDate: DateTime(2020), startLastDate: DateTime(2030), endFirstDate: DateTime(2020), endLastDate: DateTime(2030), is24HourMode: true, isShowSeconds: false, minutesInterval: 15, isForceEndDateAfterStartDate: true, borderRadius: const BorderRadius.all(Radius.circular(16)), constraints: const BoxConstraints(maxWidth: 350, maxHeight: 650), title: const Text('Select Date Range'), defaultTab: DefaultTab.start, onStartDateAfterEndDateError: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Start date must be before end date')) ); }, startSelectableDayPredicate: (dateTime) { return dateTime.weekday != DateTime.saturday && dateTime.weekday != DateTime.sunday; }, endSelectableDayPredicate: (dateTime) { return dateTime.weekday != DateTime.saturday && dateTime.weekday != DateTime.sunday; }, ); if (result != null && result.length == 2) { // Handle the selected start and end dates DateTime startDate = result[0]; DateTime endDate = result[1]; } ``` ``` -------------------------------- ### Equatable Props for State Comparison Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/State-Management-Architecture.md Example of defining the `props` getter for a class that extends `Equatable`, used for value equality comparison in BLoC states. ```dart @override List get props => [dateTime, firstDate, lastDate]; ``` -------------------------------- ### Custom Theme Configuration Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/configuration.md Applies a custom theme to the OmniDateTimePicker using `ThemeData`. This example demonstrates setting a dark color scheme based on a seed color. ```dart DateTime? result = await showOmniDateTimePicker( context: context, theme: ThemeData( colorScheme: ColorScheme.fromSeed( seedColor: Colors.blue, brightness: Brightness.dark, ), ), ); ``` -------------------------------- ### Custom Slide-Up Transition for Dialog Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Implement a custom transition animation for the date picker dialog. This example uses `SlideTransition` to create a slide-up effect instead of the default fade animation. ```dart DateTime? result = await showOmniDateTimePicker( context: context, transitionBuilder: (context, anim1, anim2, child) { return SlideTransition( position: Tween( begin: const Offset(0, 1), end: Offset.zero, ).animate(anim1), child: child, ); }, transitionDuration: const Duration(milliseconds: 300), ); ``` -------------------------------- ### Customized OmniDateTimeRangePicker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md Demonstrates advanced customization for OmniDateTimeRangePicker, including separate date constraints for start and end dates, error handling for date order, and UI transitions. ```dart List? dateTimeList = await showOmniDateTimeRangePicker( context: context, startInitialDate: DateTime.now(), startFirstDate: DateTime(1600).subtract(const Duration(days: 3652)), startLastDate: DateTime.now().add( const Duration(days: 3652), ), endInitialDate: DateTime.now(), endFirstDate: DateTime(1600).subtract(const Duration(days: 3652)), endLastDate: DateTime.now().add( const Duration(days: 3652), ), is24HourMode: false, isShowSeconds: false, minutesInterval: 1, secondsInterval: 1, isForce2Digits: false, isForceEndDateAfterStartDate: true, onStartDateAfterEndDateError: () { // Handle error when start date is after end date print('Start date cannot be after end date!'); }, borderRadius: const BorderRadius.all(Radius.circular(16)), constraints: const BoxConstraints( maxWidth: 350, maxHeight: 650, ), transitionBuilder: (context, anim1, anim2, child) { return FadeTransition( opacity: anim1.drive( Tween( begin: 0, end: 1, ), ), child: child, ); }, ``` -------------------------------- ### Generate Minutes with Interval Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/State-Management-Architecture.md Generates a list of strings representing minutes based on a specified interval. For example, an interval of 5 produces ['0', '5', ..., '55']. ```dart List _generateMinutes() { final interval = minutesInterval; // e.g., 5 return List.generate( (60 / interval).floor(), // e.g., 12 items for interval=5 (index) => '${index * interval}', ); } // For interval=5: ['0', '5', '10', '15', ..., '55'] ``` -------------------------------- ### OmniDateTimePicker Return Value Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md The showOmniDateTimeRangePicker() function returns a List containing the start and end date/time. This is the standard output format for range selections. ```dart [startDateTime, endDateTime]. ``` -------------------------------- ### Configure OmniDateTimePicker for Date and Time Range Selection Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md Configure the date and time picker for a range selection with custom date predicates, UI elements, and actions. Use this for selecting a start and end date/time. ```dart transitionDuration: const Duration(milliseconds: 200), barrierDismissible: true, barrierColor: Colors.black54, startSelectableDayPredicate: (dateTime) { // Disable 25th Feb 2023 for start date if (dateTime == DateTime(2023, 2, 25)) { return false; } else { return true; } }, endSelectableDayPredicate: (dateTime) { // Disable 26th Feb 2023 for end date if (dateTime == DateTime(2023, 2, 26)) { return false; } else { return true; } }, type: OmniDateTimePickerType.dateAndTime, title: Text('Select Date & Time Range'), titleSeparator: Divider(), startWidget: Text('Start'), endWidget: Text('End'), separator: SizedBox(height: 16), defaultTab: DefaultTab.start, padding: EdgeInsets.all(16), insetPadding: EdgeInsets.symmetric(horizontal: 40, vertical: 24), theme: ThemeData.light(), actionsBuilder: (context, confirmCallback, cancelCallback) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( onPressed: cancelCallback, child: Text('Cancel'), ), ElevatedButton( onPressed: confirmCallback, child: Text('Confirm'), ), ], ); }, ``` -------------------------------- ### DefaultTab Enum Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/types.md Determines which tab (start or end) is displayed by default in the range picker dialog. Useful for guiding user interaction in range selection. ```dart enum DefaultTab { start, end, } ``` -------------------------------- ### Standard Import Pattern Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Module-Overview.md Demonstrates the recommended way to import and access public APIs from the omni_datetime_picker package. ```dart import 'package:omni_datetime_picker/omni_datetime_picker.dart'; // Access all public APIs showOmniDateTimePicker(context: context); OmniDateTimePicker(...); OmniDateTimePickerType.dateAndTime; DefaultTab.start; ``` -------------------------------- ### Prevent End Date Before Start Date Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Use the `isForceEndDateAfterStartDate` and `onStartDateAfterEndDateError` callbacks to enforce that the end date is always after the start date and display an error message. ```dart List? result = await showOmniDateTimeRangePicker( context: context, isForceEndDateAfterStartDate: true, onStartDateAfterEndDateError: () { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('End date must be after start date'), backgroundColor: Colors.red, duration: const Duration(seconds: 2), ), ); }, ); ``` -------------------------------- ### Main Entry Point Exports Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Module-Overview.md These are the primary exports from the main entry point of the omni_datetime_picker package. ```dart export 'src/omni_datetime_picker.dart'; export 'src/omni_datetime_picker_dialogs.dart'; export 'src/enums/default_tab.dart'; export 'src/enums/omni_datetime_picker_type.dart'; ``` -------------------------------- ### OmniDateTimePicker Source File Structure Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Module-Overview.md Illustrates the directory and file organization within the OmniDateTimePicker package's lib folder. ```tree lib/ ├── omni_datetime_picker.dart (main entry point) ├── src/ │ ├── bloc/ │ │ ├── omni_datetime_picker_bloc.dart │ │ ├── omni_datetime_picker_event.dart │ │ └── omni_datetime_picker_state.dart │ ├── components/ │ │ ├── button_row.dart │ │ ├── calendar/ │ │ │ ├── calendar.dart │ │ │ └── flutter_calendar.dart │ │ ├── custom_scroll_behavior.dart │ │ ├── custom_tab_view.dart │ │ ├── range_tab_bar.dart │ │ └── time_picker_spinner/ │ │ ├── time_picker_spinner.dart │ │ └── bloc/ │ │ ├── time_picker_spinner_bloc.dart │ │ ├── time_picker_spinner_event.dart │ │ ├── time_picker_spinner_state.dart │ │ └── utils.dart │ ├── enums/ │ │ ├── default_tab.dart │ │ └── omni_datetime_picker_type.dart │ ├── prebuilt_dialogs/ │ │ ├── range_picker_dialog.dart │ │ └── single_picker_dialog.dart │ ├── utils/ │ │ └── date_time_extensions.dart │ ├── omni_datetime_picker.dart │ └── omni_datetime_picker_dialogs.dart ``` -------------------------------- ### Simple OmniDateTimePicker Usage Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md Demonstrates the basic way to show the OmniDateTimePicker to select a single date and time. ```dart DateTime? dateTime = await showOmniDateTimePicker(context: context); ``` -------------------------------- ### Test Flutter Package Publishing Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/CLAUDE.md Perform a dry run of publishing the Flutter package to ensure it's ready. ```bash flutter pub publish --dry-run ``` -------------------------------- ### DefaultTab Enum Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Module-Overview.md An enum to define the default tab to be displayed when the picker is opened. It can be set to the start or end tab, influencing the initial view. ```APIDOC ## DefaultTab Enum ### Description Defines the default tab to be displayed when the picker opens. ### Values - `.start` - `.end` ### File `src/enums/default_tab.dart` ``` -------------------------------- ### Import OmniDateTimePicker Package Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/README.md Import the OmniDateTimePicker package to access its public API for showing date and time pickers. ```dart import 'package:omni_datetime_picker/omni_datetime_picker.dart'; ``` -------------------------------- ### Publish Flutter Package Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/CLAUDE.md Publish the Flutter package to the pub.dev repository. ```bash flutter pub publish ``` -------------------------------- ### Basic OmniDateTimePicker Implementation Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/OmniDateTimePicker.md Demonstrates how to integrate OmniDateTimePicker into a Flutter widget. It shows how to handle date/time changes and validity updates, and how to use the 'Confirm' button based on the selection's validity. ```dart import 'package:flutter/material.dart'; import 'package:omni_datetime_picker/omni_datetime_picker.dart'; class DateTimePickerWidget extends StatefulWidget { const DateTimePickerWidget({Key? key}) : super(key: key); @override State createState() => _DateTimePickerWidgetState(); } class _DateTimePickerWidgetState extends State { DateTime? selectedDateTime; bool canSave = true; @override Widget build(BuildContext context) { return Column( children: [ SizedBox( height: 400, child: OmniDateTimePicker( initialDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), is24HourMode: true, isShowSeconds: false, minutesInterval: 5, type: OmniDateTimePickerType.dateAndTime, onDateTimeChanged: (dateTime) { setState(() { selectedDateTime = dateTime; }); }, onCanSaveChanged: (canSave) { setState(() { this.canSave = canSave; }); }, separator: const SizedBox(height: 16), ), ), if (selectedDateTime != null) Padding( padding: const EdgeInsets.all(16), child: Text('Selected: ${selectedDateTime?.toString()}'), ), ElevatedButton( onPressed: canSave ? () { // Confirm selection Navigator.pop(context, selectedDateTime); } : null, child: const Text('Confirm'), ), ], ); } } ``` -------------------------------- ### Minimal OmniDateTimePicker Configuration Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/configuration.md Shows the most basic way to invoke the OmniDateTimePicker. This configuration uses all default settings. ```dart DateTime? result = await showOmniDateTimePicker( context: context, ); ``` -------------------------------- ### Run Flutter Tests Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/CLAUDE.md Execute all tests in the Flutter project. ```bash flutter test ``` -------------------------------- ### TimePickerSpinnerBloc Initialization Process Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/State-Management-Architecture.md Initializes the TimePickerSpinnerBloc by generating lists of possible hours, minutes, seconds, and abbreviations. It then calculates the initial indices for these lists based on the current datetime and emits a TimePickerSpinnerLoaded state. ```dart Future _initialize( TimePickerSpinnerEvent event, Emitter emit) async { // Generate all possible values final hours = _generateHours(); final minutes = _generateMinutes(); final seconds = _generateSeconds(); final abbreviations = _generateAbbreviations(); // Find initial indices final initialHourIndex = _getInitialHourIndex(hours: hours, now: initialDateTime); final initialMinuteIndex = _getInitialMinuteIndex(minutes: minutes, now: initialDateTime); final initialSecondIndex = _getInitialSecondIndex(seconds: seconds, now: initialDateTime); final initialAbbreviationIndex = _getInitialAbbreviationIndex( abbreviations: abbreviations, now: initialDateTime); // Create scroll controller final abbreviationController = FixedExtentScrollController( initialItem: initialAbbreviationIndex, ); // Emit loaded state emit(TimePickerSpinnerLoaded(...)); } ``` -------------------------------- ### Analyze Flutter Project for Linting Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/CLAUDE.md Perform static analysis on the Flutter project to identify potential issues and enforce code style. ```bash flutter analyze ``` -------------------------------- ### Manually Manage BLoC Lifecycle Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/State-Management-Architecture.md Demonstrates the manual creation and disposal of a BLoC instance. Ensure to close the BLoC in a finally block to prevent resource leaks when not using BlocProvider. ```dart final bloc = OmniDatetimePickerBloc(...); try { // Use bloc } finally { await bloc.close(); } ``` -------------------------------- ### Business Hours Configuration Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/configuration.md Sets up the picker for specific business hours (8 AM to 6 PM) with 15-minute intervals and 24-hour mode. It also disables selection of weekends using `selectableDayPredicate`. ```dart DateTime? result = await showOmniDateTimePicker( context: context, initialDate: DateTime.now().copyWith(hour: 9), minutesInterval: 15, is24HourMode: true, selectableDayPredicate: (date) { return date.weekday != DateTime.saturday && date.weekday != DateTime.sunday; }, ); ``` -------------------------------- ### showOmniDateTimePicker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/showOmniDateTimePicker.md Displays a dialog for single date and time selection. It offers various customization options for appearance, behavior, and date/time constraints. ```APIDOC ## showOmniDateTimePicker ### Description Dialog function that displays a date/time picker for single date selection. ### Method `Future` (Dart function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Function Parameters - **context** (BuildContext) - Required - The build context of the calling widget - **transitionBuilder** (Widget Function(BuildContext, Animation, Animation, Widget)?) - Optional - Custom transition animation builder for dialog appearance - **transitionDuration** (Duration?) - Optional - Duration of the dialog transition animation - **barrierDismissible** (bool?) - Optional - Whether tapping outside the dialog closes it - **barrierColor** (Color?) - Optional - Color of the modal barrier (semi-transparent black) - **title** (Widget?) - Optional - Title widget displayed at the top of the dialog - **titleSeparator** (Widget?) - Optional - Separator widget between title and picker content - **separator** (Widget?) - Optional - Separator widget between date and time pickers - **type** (OmniDateTimePickerType) - Optional - Type of picker: date, time, or dateAndTime (defaults to dateAndTime) - **initialDate** (DateTime?) - Optional - The initially selected date/time - **firstDate** (DateTime?) - Optional - Earliest selectable date (defaults to 1970-01-01) - **lastDate** (DateTime?) - Optional - Latest selectable date (defaults to 2100-12-31) - **is24HourMode** (bool?) - Optional - Whether to use 24-hour format; if false, shows AM/PM (defaults to false) - **isShowSeconds** (bool?) - Optional - Whether to display seconds in time picker (defaults to false) - **minutesInterval** (int?) - Optional - Minute increment interval (1-60) (defaults to 1) - **secondsInterval** (int?) - Optional - Second increment interval (1-60) (defaults to 1) - **isForce2Digits** (bool?) - Optional - Whether to pad time values with leading zeros (defaults to true) - **selectableDayPredicate** (bool Function(DateTime)?) - Optional - Callback to disable specific dates; return false to disable - **borderRadius** (BorderRadiusGeometry?) - Optional - Corner radius of the dialog (defaults to BorderRadius.circular(16)) - **padding** (EdgeInsets?) - Optional - Internal padding inside the dialog - **insetPadding** (EdgeInsets?) - Optional - Margin around the dialog - **constraints** (BoxConstraints?) - Optional - Size constraints for the dialog - **theme** (ThemeData?) - Optional - Custom theme for the dialog - **actionsBuilder** (ButtonRowBuilder?) - Optional - Custom builder for confirm/cancel buttons ### Request Example ```dart DateTime? selectedDateTime = await showOmniDateTimePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2023, 1, 1), lastDate: DateTime(2024, 12, 31), type: OmniDateTimePickerType.date, ); ``` ### Response #### Success Response `Future` - A Future that resolves to the selected DateTime, or null if the dialog was canceled. #### Response Example ```dart // If a date is selected: DateTime selectedDate = DateTime(2023, 10, 27, 10, 30); // If the dialog is dismissed without selection: DateTime? selectedDate = null; ``` ``` -------------------------------- ### Allow Only Business Days using selectableDayPredicate Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Restrict date selection to only weekdays (Monday to Friday) by implementing a `selectableDayPredicate`. This example checks the `weekday` property of the date to exclude Saturdays and Sundays. ```dart DateTime? result = await showOmniDateTimePicker( context: context, selectableDayPredicate: (date) { final weekday = date.weekday; return weekday != DateTime.saturday && weekday != DateTime.sunday; }, ); ``` -------------------------------- ### Show Basic Range Date/Time Picker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/README.md Use this snippet to display a basic date and time range picker dialog. It returns a list of selected DateTimes or null if dismissed. ```dart List? result = await showOmniDateTimeRangePicker( context: context, ); ``` -------------------------------- ### Customized OmniDateTimePicker Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md Illustrates how to customize OmniDateTimePicker with various properties such as initial date, date constraints, time format, intervals, and UI theming. ```dart DateTime? dateTime = await showOmniDateTimePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(1600).subtract(const Duration(days: 3652)), lastDate: DateTime.now().add( const Duration(days: 3652), ), is24HourMode: false, isShowSeconds: false, minutesInterval: 1, secondsInterval: 1, isForce2Digits: false, borderRadius: const BorderRadius.all(Radius.circular(16)), constraints: const BoxConstraints( maxWidth: 350, maxHeight: 650, ), transitionBuilder: (context, anim1, anim2, child) { return FadeTransition( opacity: anim1.drive( Tween( begin: 0, end: 1, ), ), child: child, ); }, transitionDuration: const Duration(milliseconds: 200), barrierDismissible: true, barrierColor: const Color(0x80000000), selectableDayPredicate: (dateTime) { // Disable 25th Feb 2023 if (dateTime == DateTime(2023, 2, 25)) { return false; } else { return true; } }, type: OmniDateTimePickerType.dateAndTime, title: Text('Select Date & Time'), titleSeparator: Divider(), separator: SizedBox(height: 16), padding: EdgeInsets.all(16), insetPadding: EdgeInsets.symmetric(horizontal: 40, vertical: 24), theme: ThemeData.light(), actionsBuilder: (context, confirmCallback, cancelCallback) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( onPressed: cancelCallback, child: Text('Cancel'), ), ElevatedButton( onPressed: confirmCallback, child: Text('Confirm'), ), ], ); }, ); ``` -------------------------------- ### Handle Range Picker Results Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md Unpack the results from a range picker. Ensure the end date is not before the start date. This pattern is useful when you need to validate and process a selected date range. ```dart final result = await showOmniDateTimeRangePicker(context: context); if (result != null && result.length == 2) { final startDate = result[0]; final endDate = result[1]; if (endDate.isBefore(startDate)) { // Handle invalid range ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Invalid date range')), ); return; } print('Range: $startDate to $endDate'); } else { print('Invalid or cancelled'); } ``` -------------------------------- ### Basic TimePickerSpinner Usage Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/TimePickerSpinner.md Demonstrates how to integrate the TimePickerSpinner within a Flutter application using BlocProvider. It displays the selected time and allows for time selection with seconds, AM/PM mode, and custom minute intervals. ```dart import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:omni_datetime_picker/omni_datetime_picker.dart'; import 'package:omni_datetime_picker/src/bloc/omni_datetime_picker_bloc.dart'; import 'package:omni_datetime_picker/src/components/time_picker_spinner/time_picker_spinner.dart'; class TimePickerScreen extends StatefulWidget { const TimePickerScreen({Key? key}) : super(key: key); @override State createState() => _TimePickerScreenState(); } class _TimePickerScreenState extends State { DateTime? selectedTime; @override Widget build(BuildContext context) { final localizations = MaterialLocalizations.of(context); return Scaffold( appBar: AppBar(title: const Text('Time Picker')), body: BlocProvider( create: (context) => OmniDatetimePickerBloc( initialDateTime: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), ), child: BlocBuilder( builder: (context, state) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Selected: ${state.dateTime}'), const SizedBox(height: 20), SizedBox( height: 200, child: TimePickerSpinner( amText: localizations.anteMeridiemAbbreviation, pmText: localizations.postMeridiemAbbreviation, isShowSeconds: true, is24HourMode: false, minutesInterval: 5, secondsInterval: 1, isForce2Digits: true, looping: true, ), ), ], ), ); }, ), ), ); } } ``` -------------------------------- ### Enforce Time Range on Same Date Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/Patterns-and-Techniques.md When firstDate and lastDate are on the same day, this pattern constrains time selection within the specified hours. It ensures that if the selected date is the firstDate, the hour is greater than or equal to the start hour, and if it's the lastDate, the hour is less than or equal to the end hour. ```dart OmniDateTimePicker( initialDate: DateTime.now(), firstDate: DateTime(2024, 6, 15, 9, 0, 0), // 9:00 AM lastDate: DateTime(2024, 6, 15, 17, 0, 0), // 5:00 PM onDateTimeChanged: (date) { print('Selected: $date'); }, ) ``` -------------------------------- ### Simple OmniDateTimeRangePicker Usage Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/README.md Shows the basic usage of OmniDateTimeRangePicker for selecting a range of dates and times. ```dart List? dateTimeList = await showOmniDateTimeRangePicker(context: context); ``` -------------------------------- ### OmniDatetimePickerBloc Constructor Source: https://github.com/alanchan-dev/omnidatetimepicker/blob/main/_autodocs/api-reference/OmniDatetimePickerBloc.md Initializes the OmniDatetimePickerBloc with the initial date/time and date range constraints. ```APIDOC ## OmniDatetimePickerBloc Constructor ### Description Initializes the OmniDatetimePickerBloc with the initial date/time and date range constraints. ### Parameters #### Constructor Parameters - **initialDateTime** (DateTime) - Required - The initial date/time to display - **firstDate** (DateTime) - Required - Earliest allowable date/time - **lastDate** (DateTime) - Required - Latest allowable date/time ```