@@ -98,10 +98,28 @@ class ReactiveDateTimePicker
9898 RouteSettings ? datePickerRouteSettings,
9999 TextInputType ? keyboardType,
100100 Offset ? anchorPoint,
101+ DateTime ? currentDate,
102+ bool barrierDismissible = true ,
103+ Color ? barrierColor,
104+ String ? barrierLabel,
105+ ValueChanged <DatePickerEntryMode >? onDatePickerModeChange,
101106
102107 // time picker params
103108 TimePickerEntryMode timePickerEntryMode = TimePickerEntryMode .dial,
104109 RouteSettings ? timePickerRouteSettings,
110+ bool timePickerBarrierDismissible = true ,
111+ Color ? timePickerBarrierColor,
112+ String ? timePickerBarrierLabel,
113+ String ? hourLabelText,
114+ String ? minuteLabelText,
115+ String ? timePickerErrorInvalidText,
116+ EntryModeChangeCallback ? onEntryModeChanged,
117+ Offset ? timePickerAnchorPoint,
118+ Orientation ? timePickerOrientation,
119+ Future <DateTime ?> Function (
120+ BuildContext context,
121+ DateTime ? value,
122+ )? onTap,
105123 Widget Function (BuildContext context, String error)? errorBuilder,
106124
107125 // input decorator props
@@ -111,6 +129,8 @@ class ReactiveDateTimePicker
111129 bool expands = false ,
112130 MouseCursor cursor = SystemMouseCursors .click,
113131 Widget Function (BuildContext context, String ? value)? valueBuilder,
132+ Icon ? switchToInputEntryModeIcon,
133+ Icon ? switchToCalendarEntryModeIcon,
114134 }) : super (
115135 valueAccessor:
116136 valueAccessor ?? _effectiveValueAccessor (type, dateFormat),
@@ -156,78 +176,111 @@ class ReactiveDateTimePicker
156176 field.control.focus ();
157177 field.control.updateValueAndValidity ();
158178
159- if (type == ReactiveDatePickerFieldType .date ||
160- type == ReactiveDatePickerFieldType .dateTime) {
161- date = await showDatePicker (
162- context: field.context,
163- initialDate: (getInitialDate ?? _getInitialDate)(
164- field.control.value,
165- effectiveLastDate,
179+ final initialDate = (getInitialDate ?? _getInitialDate)(
180+ field.control.value,
181+ effectiveLastDate,
182+ );
183+
184+ if (onTap != null ) {
185+ field.didChange (
186+ effectiveValueAccessor.modelToViewValue (
187+ await onTap (
188+ field.context,
189+ initialDate,
190+ ),
166191 ),
167- firstDate: firstDate ?? DateTime (1900 ),
168- lastDate: effectiveLastDate,
169- initialEntryMode: datePickerEntryMode,
170- selectableDayPredicate: selectableDayPredicate,
171- helpText: helpText,
172- cancelText: cancelText,
173- confirmText: confirmText,
174- locale: locale,
175- useRootNavigator: useRootNavigator,
176- routeSettings: datePickerRouteSettings,
177- textDirection: textDirection,
178- builder: builder,
179- initialDatePickerMode: initialDatePickerMode,
180- errorFormatText: errorFormatText,
181- errorInvalidText: errorInvalidText,
182- fieldHintText: fieldHintText,
183- fieldLabelText: fieldLabelText,
184- keyboardType: keyboardType,
185- anchorPoint: anchorPoint,
186- );
187- }
188-
189- if (type == ReactiveDatePickerFieldType .time ||
190- (type == ReactiveDatePickerFieldType .dateTime &&
191- // there is no need to show timepicker if cancel was pressed on datepicker
192- date != null )) {
193- time = await showTimePicker (
194- context: field.context,
195- initialTime: (getInitialTime ??
196- _getInitialTime)(field.control.value),
197- builder: builder,
198- useRootNavigator: useRootNavigator,
199- initialEntryMode: timePickerEntryMode,
200- cancelText: cancelText,
201- confirmText: confirmText,
202- helpText: helpText,
203- routeSettings: timePickerRouteSettings,
204192 );
205- }
193+ } else {
194+ if (type == ReactiveDatePickerFieldType .date ||
195+ type == ReactiveDatePickerFieldType .dateTime) {
196+ date = await showDatePicker (
197+ context: field.context,
198+ initialDate: initialDate,
199+ currentDate: currentDate,
200+ firstDate: firstDate ?? DateTime (1900 ),
201+ lastDate: effectiveLastDate,
202+ initialEntryMode: datePickerEntryMode,
203+ selectableDayPredicate: selectableDayPredicate,
204+ helpText: helpText,
205+ cancelText: cancelText,
206+ confirmText: confirmText,
207+ locale: locale,
208+ useRootNavigator: useRootNavigator,
209+ routeSettings: datePickerRouteSettings,
210+ textDirection: textDirection,
211+ builder: builder,
212+ initialDatePickerMode: initialDatePickerMode,
213+ errorFormatText: errorFormatText,
214+ errorInvalidText: errorInvalidText,
215+ fieldHintText: fieldHintText,
216+ fieldLabelText: fieldLabelText,
217+ keyboardType: keyboardType,
218+ anchorPoint: anchorPoint,
219+ barrierDismissible: barrierDismissible,
220+ barrierColor: barrierColor,
221+ barrierLabel: barrierLabel,
222+ onDatePickerModeChange: onDatePickerModeChange,
223+ switchToInputEntryModeIcon:
224+ switchToInputEntryModeIcon,
225+ switchToCalendarEntryModeIcon:
226+ switchToCalendarEntryModeIcon,
227+ );
228+ }
206229
207- if (
208- // if `date` and `time` in `dateTime` mode is not empty...
209- (type == ReactiveDatePickerFieldType .dateTime &&
210- (date != null && time != null )) ||
211- // ... or if `date` in `date` mode is not empty ...
212- (type == ReactiveDatePickerFieldType .date &&
213- date != null ) ||
214- // ... or if `time` in `time` mode is not empty ...
215- (type == ReactiveDatePickerFieldType .time &&
216- time != null )) {
217- final dateTime = _combine (date, time);
218-
219- final value = field.control.value;
220- // ... and new value is not the same as was before...
221- if (value == null || dateTime.compareTo (value) != 0 ) {
222- // ... this means that cancel was not pressed at any moment
223- // so we can update the field
224- field.didChange (
225- effectiveValueAccessor.modelToViewValue (
226- _combine (date, time),
227- ),
230+ if (type == ReactiveDatePickerFieldType .time ||
231+ (type == ReactiveDatePickerFieldType .dateTime &&
232+ // there is no need to show timepicker if cancel was pressed on datepicker
233+ date != null )) {
234+ time = await showTimePicker (
235+ context: field.context,
236+ initialTime: (getInitialTime ??
237+ _getInitialTime)(field.control.value),
238+ builder: builder,
239+ useRootNavigator: useRootNavigator,
240+ initialEntryMode: timePickerEntryMode,
241+ cancelText: cancelText,
242+ confirmText: confirmText,
243+ helpText: helpText,
244+ routeSettings: timePickerRouteSettings,
245+ barrierDismissible: timePickerBarrierDismissible,
246+ barrierColor: timePickerBarrierColor,
247+ barrierLabel: timePickerBarrierLabel,
248+ errorInvalidText: timePickerErrorInvalidText,
249+ hourLabelText: hourLabelText,
250+ minuteLabelText: minuteLabelText,
251+ onEntryModeChanged: onEntryModeChanged,
252+ anchorPoint: timePickerAnchorPoint,
253+ orientation: timePickerOrientation,
228254 );
229255 }
256+
257+ if (
258+ // if `date` and `time` in `dateTime` mode is not empty...
259+ (type == ReactiveDatePickerFieldType .dateTime &&
260+ (date != null && time != null )) ||
261+ // ... or if `date` in `date` mode is not empty ...
262+ (type == ReactiveDatePickerFieldType .date &&
263+ date != null ) ||
264+ // ... or if `time` in `time` mode is not empty ...
265+ (type == ReactiveDatePickerFieldType .time &&
266+ time != null )) {
267+ final dateTime = _combine (date, time);
268+
269+ final value = field.control.value;
270+ // ... and new value is not the same as was before...
271+ if (value == null ||
272+ dateTime.compareTo (value) != 0 ) {
273+ // ... this means that cancel was not pressed at any moment
274+ // so we can update the field
275+ field.didChange (
276+ effectiveValueAccessor.modelToViewValue (
277+ _combine (date, time),
278+ ),
279+ );
280+ }
281+ }
230282 }
283+
231284 field.control.unfocus ();
232285 field.control.updateValueAndValidity ();
233286 field.control.markAsTouched ();
@@ -273,9 +326,11 @@ class ReactiveDateTimePicker
273326 ? Theme .of (field.context).disabledColor
274327 : null ,
275328 ),
276- child: valueBuilder? .call (field.context, field.value) ?? Text (
277- field.value ?? '' ,
278- ),
329+ child:
330+ valueBuilder? .call (field.context, field.value) ??
331+ Text (
332+ field.value ?? '' ,
333+ ),
279334 ),
280335 ),
281336 ),
0 commit comments