mirror of
https://github.com/Iconica-Development/flutter_date_time_picker.git
synced 2025-05-18 18:33:49 +02:00
added date constraints to overlay date time picker
This commit is contained in:
parent
3edcbe4b5a
commit
66e0090597
15 changed files with 538 additions and 118 deletions
44
README.md
44
README.md
|
@ -11,12 +11,25 @@ and the Flutter guide for
|
||||||
[developing packages and plugins](https://flutter.dev/developing-packages).
|
[developing packages and plugins](https://flutter.dev/developing-packages).
|
||||||
-->
|
-->
|
||||||
|
|
||||||
TODO: Put a short description of the package here that helps potential users
|
# Date Time Picker
|
||||||
know whether this package might be useful for them.
|
|
||||||
|
The date time picker to be able to input a date.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
### Drag down date time picker
|
||||||
|
|
||||||
|
A picker that is placed in the top of the screen.
|
||||||
|
You are able to select a day at this point.
|
||||||
|
When it is dragged down you are able to select a day for a given month.
|
||||||
|
|
||||||
|
### Overlay date time picker
|
||||||
|
|
||||||
|
A picker, that when opened using a button, is placed over the screen.
|
||||||
|
Then you are able to swipe through the month to select a day.
|
||||||
|
It is possible to add a constraint to de picker to limit the choice of day.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
|
@ -25,15 +38,24 @@ start using the package.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
TODO: Include short and useful examples for package users. Add longer examples
|
|
||||||
to `/example` folder.
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
const like = 'sample';
|
OverlayDateTimePicker(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: const Text("Select Day"),
|
||||||
|
onTapDay: (date) {},
|
||||||
|
),
|
||||||
```
|
```
|
||||||
|
|
||||||
## Additional information
|
See the [Example Code](example/lib/main.dart) for more example's on how to use this package.
|
||||||
|
|
||||||
TODO: Tell users more about the package: where to find more information, how to
|
## Issues
|
||||||
contribute to the package, how to file issues, what response they can expect
|
|
||||||
from the package authors, and more.
|
Please file any issues, bugs or feature request as an issue on our [GitHub](https://github.com/Iconica-Development/flutter_date_time_picker/pulls) page. Commercial support is available if you need help with integration with your app or services. You can contact us at [support@iconica.nl](mailto:support@iconica.nl).
|
||||||
|
|
||||||
|
## Want to contribute
|
||||||
|
|
||||||
|
If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](../CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_date_time_picker/pulls).
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
This `flutter-date-time-picker` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>
|
||||||
|
|
|
@ -1,16 +1,3 @@
|
||||||
# example
|
# example
|
||||||
|
|
||||||
A new Flutter project.
|
The example Flutter app for the date time picker
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
||||||
|
|
|
@ -80,6 +80,9 @@ class DatePickerDemo extends StatelessWidget {
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: const Text("Select Day"),
|
child: const Text("Select Day"),
|
||||||
),
|
),
|
||||||
|
dateTimeConstraint: DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime.now()),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
OverlayDateTimePicker(
|
OverlayDateTimePicker(
|
||||||
theme: dateTimePickerTheme,
|
theme: dateTimePickerTheme,
|
||||||
|
@ -91,6 +94,18 @@ class DatePickerDemo extends StatelessWidget {
|
||||||
Icons.schedule,
|
Icons.schedule,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
dateTimeConstraint: DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime.now()),
|
||||||
|
max: DateConstraint(
|
||||||
|
date: DateTime(
|
||||||
|
DateTime.now().year,
|
||||||
|
DateTime.now().month + 4,
|
||||||
|
DateTime.now().day,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onNextPageButtonChild: const Icon(Icons.add),
|
||||||
|
onPreviousPageButtonChild: const Icon(Icons.minimize),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -61,7 +61,7 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "2.0.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -6,6 +6,7 @@ library flutter_date_time_picker;
|
||||||
|
|
||||||
export 'src/drag_down_date_time_picker.dart' show DragDownDateTimePicker;
|
export 'src/drag_down_date_time_picker.dart' show DragDownDateTimePicker;
|
||||||
export 'src/overlay_date_time_picker.dart' show OverlayDateTimePicker;
|
export 'src/overlay_date_time_picker.dart' show OverlayDateTimePicker;
|
||||||
|
export 'src/models/date_constraint.dart';
|
||||||
export 'src/enums/date_box_shape.dart';
|
export 'src/enums/date_box_shape.dart';
|
||||||
export 'src/models/date_box_base_theme.dart';
|
export 'src/models/date_box_base_theme.dart';
|
||||||
export 'src/models/date_box_disabled_theme.dart';
|
export 'src/models/date_box_disabled_theme.dart';
|
||||||
|
|
107
lib/src/models/date_constraint.dart
Normal file
107
lib/src/models/date_constraint.dart
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
class DateTimeConstraint {
|
||||||
|
final DateConstraint min;
|
||||||
|
final DateConstraint max;
|
||||||
|
|
||||||
|
const DateTimeConstraint({
|
||||||
|
this.min = DateConstraint.infinity,
|
||||||
|
this.max = DateConstraint.infinity,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool inRange(DateTime date) {
|
||||||
|
return _checkDate(
|
||||||
|
min,
|
||||||
|
() => !date.isBefore(min.date!),
|
||||||
|
) &&
|
||||||
|
_checkDate(
|
||||||
|
max,
|
||||||
|
() => !date.isAfter(max.date!),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inDateRange(DateTime date) {
|
||||||
|
return _checkDate(
|
||||||
|
min,
|
||||||
|
() => !_stripToDateOnly(date).isBefore(_stripToDateOnly(min.date!)),
|
||||||
|
) &&
|
||||||
|
_checkDate(
|
||||||
|
max,
|
||||||
|
() => !_stripToDateOnly(date).isAfter(_stripToDateOnly(max.date!)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inMonthRange(DateTime date) {
|
||||||
|
return _checkDate(
|
||||||
|
min,
|
||||||
|
() =>
|
||||||
|
!_stripToMonthsOnly(date).isBefore(_stripToMonthsOnly(min.date!)),
|
||||||
|
) &&
|
||||||
|
_checkDate(
|
||||||
|
max,
|
||||||
|
() =>
|
||||||
|
!_stripToMonthsOnly(date).isAfter(_stripToMonthsOnly(max.date!)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inYearRange(DateTime date) {
|
||||||
|
return _checkDate(
|
||||||
|
min,
|
||||||
|
() => !_stripToYearsOnly(date).isBefore(_stripToYearsOnly(min.date!)),
|
||||||
|
) &&
|
||||||
|
_checkDate(
|
||||||
|
max,
|
||||||
|
() => !_stripToYearsOnly(date).isAfter(_stripToYearsOnly(max.date!)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime _stripToDateOnly(DateTime date) {
|
||||||
|
return DateTime(
|
||||||
|
date.year,
|
||||||
|
date.month,
|
||||||
|
date.day,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime _stripToMonthsOnly(DateTime date) {
|
||||||
|
return DateTime(
|
||||||
|
date.year,
|
||||||
|
date.month,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime _stripToYearsOnly(DateTime date) {
|
||||||
|
return DateTime(
|
||||||
|
date.year,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _checkDate(DateConstraint constraint, bool Function() checker) {
|
||||||
|
if (!constraint.isInfinite) {
|
||||||
|
return checker();
|
||||||
|
}
|
||||||
|
return constraint.isInfinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DateConstraint {
|
||||||
|
static const DateConstraint infinity =
|
||||||
|
DateConstraint(date: null, isInfinite: true);
|
||||||
|
final DateTime? date;
|
||||||
|
final bool isInfinite;
|
||||||
|
|
||||||
|
const DateConstraint({this.date, this.isInfinite = false})
|
||||||
|
: assert(
|
||||||
|
!(date != null && isInfinite),
|
||||||
|
'Can NOT have a limit set and be infinite.',
|
||||||
|
),
|
||||||
|
assert(
|
||||||
|
date != null || isInfinite,
|
||||||
|
'Must set some form of a limit.',
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,3 +1,7 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class DateTimePickerBarTheme {
|
class DateTimePickerBarTheme {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_date_time_picker/src/extensions/date_time.dart';
|
import 'package:flutter_date_time_picker/src/extensions/date_time.dart';
|
||||||
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
|
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
|
||||||
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
|
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
|
||||||
|
import 'package:flutter_date_time_picker/src/models/date_constraint.dart';
|
||||||
import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/overlay.dart';
|
import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/overlay.dart';
|
||||||
|
|
||||||
class OverlayDateTimePicker extends StatefulWidget {
|
class OverlayDateTimePicker extends StatefulWidget {
|
||||||
|
@ -14,8 +15,7 @@ class OverlayDateTimePicker extends StatefulWidget {
|
||||||
this.textStyle = const TextStyle(),
|
this.textStyle = const TextStyle(),
|
||||||
this.alignment = Alignment.bottomRight,
|
this.alignment = Alignment.bottomRight,
|
||||||
this.initialDate,
|
this.initialDate,
|
||||||
this.size = const Size(325, 350),
|
this.size = const Size(325, 375),
|
||||||
this.wrongTimeDialog,
|
|
||||||
this.onTapDay,
|
this.onTapDay,
|
||||||
this.highlightToday = true,
|
this.highlightToday = true,
|
||||||
this.alwaysUse24HourFormat = true,
|
this.alwaysUse24HourFormat = true,
|
||||||
|
@ -28,14 +28,14 @@ class OverlayDateTimePicker extends StatefulWidget {
|
||||||
this.buttonBuilder,
|
this.buttonBuilder,
|
||||||
this.closeOnSelectDate = true,
|
this.closeOnSelectDate = true,
|
||||||
this.showWeekDays = true,
|
this.showWeekDays = true,
|
||||||
|
this.dateTimeConstraint = const DateTimeConstraint(),
|
||||||
|
this.onNextPageButtonChild,
|
||||||
|
this.onPreviousPageButtonChild,
|
||||||
}) : assert(child != null || buttonBuilder != null);
|
}) : assert(child != null || buttonBuilder != null);
|
||||||
|
|
||||||
/// The child contained by the DatePicker.
|
/// The child contained by the DatePicker.
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
|
|
||||||
/// A [Widget] to display when the user picks a disabled time in the [TimePickerDialog]
|
|
||||||
final Widget? wrongTimeDialog;
|
|
||||||
|
|
||||||
/// Visual properties for the [OverlayDateTimePicker]
|
/// Visual properties for the [OverlayDateTimePicker]
|
||||||
final DateTimePickerTheme theme;
|
final DateTimePickerTheme theme;
|
||||||
|
|
||||||
|
@ -51,13 +51,13 @@ class OverlayDateTimePicker extends StatefulWidget {
|
||||||
/// a [bool] to set de clock on [TimePickerDialog] to a fixed 24 or 12-hour format.
|
/// a [bool] to set de clock on [TimePickerDialog] to a fixed 24 or 12-hour format.
|
||||||
final bool alwaysUse24HourFormat;
|
final bool alwaysUse24HourFormat;
|
||||||
|
|
||||||
/// [pickTime] is a [bool] that determines if the user is able to pick a time after picking a date using the [TimePickerDialog].
|
/// is a [bool] that determines if the user is able to pick a time after picking a date using the [TimePickerDialog].
|
||||||
final bool pickTime;
|
final bool pickTime;
|
||||||
|
|
||||||
/// indicates the starting date. Default is [DateTime.now()]
|
/// indicates the starting date. Default is [DateTime.now()]
|
||||||
final DateTime? initialDate;
|
final DateTime? initialDate;
|
||||||
|
|
||||||
/// [markedDates] contain the dates [DateTime] that will be marked in the [OverlayDateTimePicker] by a small dot.
|
/// contain the dates [DateTime] that will be marked in the [OverlayDateTimePicker] by a small dot.
|
||||||
final List<DateTime>? markedDates;
|
final List<DateTime>? markedDates;
|
||||||
|
|
||||||
/// a [List] of [DateTime] objects that will be disabled and cannot be interacted with whatsoever.
|
/// a [List] of [DateTime] objects that will be disabled and cannot be interacted with whatsoever.
|
||||||
|
@ -75,12 +75,21 @@ class OverlayDateTimePicker extends StatefulWidget {
|
||||||
/// [buttonBuilder] is a method for building the button that can trigger the overlay to appear
|
/// [buttonBuilder] is a method for building the button that can trigger the overlay to appear
|
||||||
final Widget Function(Key key, void Function() onPressed)? buttonBuilder;
|
final Widget Function(Key key, void Function() onPressed)? buttonBuilder;
|
||||||
|
|
||||||
/// [closeOnSelectDate] is a bool that indicates if the overlay should be closed if a date has been picked.
|
/// is a [bool] that indicates if the overlay should be closed if a date has been picked.
|
||||||
final bool closeOnSelectDate;
|
final bool closeOnSelectDate;
|
||||||
|
|
||||||
/// [showWeekDays] is a [bool] that determines if day in the week indicators should be shown
|
/// [showWeekDays] is a [bool] that determines if day in the week indicators should be shown
|
||||||
final bool showWeekDays;
|
final bool showWeekDays;
|
||||||
|
|
||||||
|
/// a [DateTimeConstraint] that dictates the constraints of the dates that can be picked.
|
||||||
|
final DateTimeConstraint dateTimeConstraint;
|
||||||
|
|
||||||
|
/// a [Widget] that determents the icon of the button for going to the next page
|
||||||
|
final Widget? onNextPageButtonChild;
|
||||||
|
|
||||||
|
/// a [Widget] that determents the icon of the button for going to the previous page
|
||||||
|
final Widget? onPreviousPageButtonChild;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<OverlayDateTimePicker> createState() => _OverlayDateTimePickerState();
|
State<OverlayDateTimePicker> createState() => _OverlayDateTimePickerState();
|
||||||
}
|
}
|
||||||
|
@ -222,6 +231,9 @@ class _OverlayDateTimePickerState extends State<OverlayDateTimePicker> {
|
||||||
showWeekDays: true,
|
showWeekDays: true,
|
||||||
onNextDate: nextDate,
|
onNextDate: nextDate,
|
||||||
onPreviousDate: previousDate,
|
onPreviousDate: previousDate,
|
||||||
|
dateTimeConstraint: widget.dateTimeConstraint,
|
||||||
|
onNextPageButtonChild: widget.onNextPageButtonChild,
|
||||||
|
onPreviousPageButtonChild: widget.onPreviousPageButtonChild,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
36
lib/src/utils/locking_page_scroll_physics.dart
Normal file
36
lib/src/utils/locking_page_scroll_physics.dart
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LockingPageScrollPhysics extends ScrollPhysics {
|
||||||
|
final bool Function() allowedNextPage;
|
||||||
|
final bool Function() allowedPreviousPage;
|
||||||
|
|
||||||
|
const LockingPageScrollPhysics({
|
||||||
|
required this.allowedNextPage,
|
||||||
|
required this.allowedPreviousPage,
|
||||||
|
ScrollPhysics? parent,
|
||||||
|
}) : super(parent: parent);
|
||||||
|
|
||||||
|
@override
|
||||||
|
ScrollPhysics applyTo(ScrollPhysics? ancestor) {
|
||||||
|
return LockingPageScrollPhysics(
|
||||||
|
allowedNextPage: allowedNextPage,
|
||||||
|
allowedPreviousPage: allowedPreviousPage,
|
||||||
|
parent: buildParent(ancestor));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double applyBoundaryConditions(ScrollMetrics position, double value) {
|
||||||
|
bool movingLeft = value > position.pixels;
|
||||||
|
if (movingLeft && allowedNextPage()) {
|
||||||
|
return super.applyBoundaryConditions(position, value);
|
||||||
|
}
|
||||||
|
if (!movingLeft && allowedPreviousPage()) {
|
||||||
|
return super.applyBoundaryConditions(position, value);
|
||||||
|
}
|
||||||
|
return value - position.pixels;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ class DatePicker extends StatelessWidget {
|
||||||
required this.onSelectDate,
|
required this.onSelectDate,
|
||||||
required this.date,
|
required this.date,
|
||||||
required this.showWeekDays,
|
required this.showWeekDays,
|
||||||
|
required this.dateTimeConstraint,
|
||||||
});
|
});
|
||||||
|
|
||||||
final DateTimePickerController controller;
|
final DateTimePickerController controller;
|
||||||
|
@ -26,6 +27,7 @@ class DatePicker extends StatelessWidget {
|
||||||
final void Function(DateTime date) onSelectDate;
|
final void Function(DateTime date) onSelectDate;
|
||||||
final DateTime date;
|
final DateTime date;
|
||||||
final bool showWeekDays;
|
final bool showWeekDays;
|
||||||
|
final DateTimeConstraint dateTimeConstraint;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -85,7 +87,8 @@ class DatePicker extends StatelessWidget {
|
||||||
padding: const EdgeInsets.all(2.0),
|
padding: const EdgeInsets.all(2.0),
|
||||||
child: PickableDate(
|
child: PickableDate(
|
||||||
isOffMonth: date.month != todayDate.month,
|
isOffMonth: date.month != todayDate.month,
|
||||||
isDisabled: isDisabled(addedIndex + index, daysToSkip),
|
isDisabled:
|
||||||
|
isDisabled(addedIndex + index, daysToSkip, todayDate),
|
||||||
isSelected: controller.selectedDate == todayDate,
|
isSelected: controller.selectedDate == todayDate,
|
||||||
isToday: isToday(todayDate) && controller.highlightToday,
|
isToday: isToday(todayDate) && controller.highlightToday,
|
||||||
theme: theme,
|
theme: theme,
|
||||||
|
@ -108,13 +111,14 @@ class DatePicker extends StatelessWidget {
|
||||||
date.day == now.day;
|
date.day == now.day;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDisabled(int index, int daysToSkip) {
|
bool isDisabled(int index, int daysToSkip, DateTime date) {
|
||||||
return DateTime(
|
return DateTime(
|
||||||
date.year,
|
date.year,
|
||||||
date.month,
|
date.month,
|
||||||
index + 1 - daysToSkip,
|
index + 1 - daysToSkip,
|
||||||
).containsAny(
|
).containsAny(
|
||||||
controller.disabledDates ?? [],
|
controller.disabledDates ?? [],
|
||||||
);
|
) ||
|
||||||
|
!dateTimeConstraint.inRange(date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
|
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
|
||||||
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
|
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
|
||||||
|
import 'package:flutter_date_time_picker/src/utils/locking_page_scroll_physics.dart';
|
||||||
import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/date_picker.dart';
|
import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/date_picker.dart';
|
||||||
|
import 'package:flutter_date_time_picker/src/models/date_constraint.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class OverlayDateTimeContent extends StatefulWidget {
|
class OverlayDateTimeContent extends StatefulWidget {
|
||||||
|
@ -18,6 +20,9 @@ class OverlayDateTimeContent extends StatefulWidget {
|
||||||
required this.showWeekDays,
|
required this.showWeekDays,
|
||||||
required this.onNextDate,
|
required this.onNextDate,
|
||||||
required this.onPreviousDate,
|
required this.onPreviousDate,
|
||||||
|
required this.dateTimeConstraint,
|
||||||
|
required this.onPreviousPageButtonChild,
|
||||||
|
required this.onNextPageButtonChild,
|
||||||
});
|
});
|
||||||
|
|
||||||
final DateTimePickerTheme theme;
|
final DateTimePickerTheme theme;
|
||||||
|
@ -25,6 +30,11 @@ class OverlayDateTimeContent extends StatefulWidget {
|
||||||
final Size size;
|
final Size size;
|
||||||
final DateTimePickerController controller;
|
final DateTimePickerController controller;
|
||||||
final bool showWeekDays;
|
final bool showWeekDays;
|
||||||
|
final DateTimeConstraint dateTimeConstraint;
|
||||||
|
|
||||||
|
final Widget? onNextPageButtonChild;
|
||||||
|
final Widget? onPreviousPageButtonChild;
|
||||||
|
|
||||||
final void Function() onNextDate;
|
final void Function() onNextDate;
|
||||||
final void Function() onPreviousDate;
|
final void Function() onPreviousDate;
|
||||||
|
|
||||||
|
@ -34,10 +44,22 @@ class OverlayDateTimeContent extends StatefulWidget {
|
||||||
|
|
||||||
class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
bool usesButtons = false;
|
bool usesButtons = false;
|
||||||
|
late DateTime nextDate;
|
||||||
|
late DateTime previousDate;
|
||||||
late final PageController _pageController;
|
late final PageController _pageController;
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_pageController = PageController(initialPage: 1);
|
_pageController = PageController(initialPage: 1);
|
||||||
|
nextDate = DateTime(
|
||||||
|
widget.controller.browsingDate.year,
|
||||||
|
widget.controller.browsingDate.month + 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
previousDate = DateTime(
|
||||||
|
widget.controller.browsingDate.year,
|
||||||
|
widget.controller.browsingDate.month - 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,16 +78,25 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: goToPreviousPage,
|
onPressed: (widget.dateTimeConstraint.inMonthRange(previousDate))
|
||||||
icon: const Icon(Icons.arrow_circle_left_outlined),
|
? _goToPreviousPage
|
||||||
|
: null,
|
||||||
|
icon: widget.onPreviousPageButtonChild ??
|
||||||
|
const Icon(Icons.arrow_circle_left_outlined),
|
||||||
color: widget.theme.barTheme.barColor,
|
color: widget.theme.barTheme.barColor,
|
||||||
),
|
),
|
||||||
Text(DateFormat.yMMMM().format(
|
Text(
|
||||||
widget.controller.browsingDate,
|
DateFormat.yMMMM().format(
|
||||||
)),
|
widget.controller.browsingDate,
|
||||||
|
),
|
||||||
|
style: widget.theme.baseTheme.textStyle,
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: goToNextPage,
|
onPressed: (widget.dateTimeConstraint.inMonthRange(nextDate))
|
||||||
icon: const Icon(Icons.arrow_circle_right_outlined),
|
? _goToNextPage
|
||||||
|
: null,
|
||||||
|
icon: widget.onNextPageButtonChild ??
|
||||||
|
const Icon(Icons.arrow_circle_right_outlined),
|
||||||
color: widget.theme.barTheme.barColor,
|
color: widget.theme.barTheme.barColor,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -78,9 +109,15 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PageView(
|
child: PageView(
|
||||||
|
physics: LockingPageScrollPhysics(
|
||||||
|
allowedNextPage: () =>
|
||||||
|
widget.dateTimeConstraint.inMonthRange(nextDate),
|
||||||
|
allowedPreviousPage: () =>
|
||||||
|
widget.dateTimeConstraint.inMonthRange(previousDate),
|
||||||
|
),
|
||||||
controller: _pageController,
|
controller: _pageController,
|
||||||
onPageChanged: (value) {
|
onPageChanged: (value) {
|
||||||
if (!usesButtons) movePage(1 - value);
|
if (!usesButtons) _movePage(1 - value);
|
||||||
},
|
},
|
||||||
pageSnapping: true,
|
pageSnapping: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
|
@ -88,34 +125,29 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
children: [
|
children: [
|
||||||
DatePicker(
|
DatePicker(
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
onSelectDate: onSelectDate,
|
onSelectDate: _onSelectDate,
|
||||||
theme: widget.theme,
|
theme: widget.theme,
|
||||||
textStyle: widget.textStyle,
|
textStyle: widget.textStyle,
|
||||||
date: DateTime(
|
date: previousDate,
|
||||||
widget.controller.browsingDate.year,
|
dateTimeConstraint: widget.dateTimeConstraint,
|
||||||
widget.controller.browsingDate.month - 1,
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
showWeekDays: widget.showWeekDays,
|
showWeekDays: widget.showWeekDays,
|
||||||
),
|
),
|
||||||
DatePicker(
|
DatePicker(
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
onSelectDate: onSelectDate,
|
onSelectDate: _onSelectDate,
|
||||||
theme: widget.theme,
|
theme: widget.theme,
|
||||||
textStyle: widget.textStyle,
|
textStyle: widget.textStyle,
|
||||||
date: widget.controller.browsingDate,
|
date: widget.controller.browsingDate,
|
||||||
showWeekDays: widget.showWeekDays,
|
showWeekDays: widget.showWeekDays,
|
||||||
|
dateTimeConstraint: widget.dateTimeConstraint,
|
||||||
),
|
),
|
||||||
DatePicker(
|
DatePicker(
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
onSelectDate: onSelectDate,
|
onSelectDate: _onSelectDate,
|
||||||
theme: widget.theme,
|
theme: widget.theme,
|
||||||
textStyle: widget.textStyle,
|
textStyle: widget.textStyle,
|
||||||
date: DateTime(
|
date: nextDate,
|
||||||
widget.controller.browsingDate.year,
|
dateTimeConstraint: widget.dateTimeConstraint,
|
||||||
widget.controller.browsingDate.month + 1,
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
showWeekDays: widget.showWeekDays,
|
showWeekDays: widget.showWeekDays,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -125,7 +157,7 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void goToNextPage() async {
|
void _goToNextPage() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
usesButtons = true;
|
usesButtons = true;
|
||||||
});
|
});
|
||||||
|
@ -133,10 +165,10 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
);
|
);
|
||||||
nextPage();
|
_nextPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void goToPreviousPage() async {
|
void _goToPreviousPage() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
usesButtons = true;
|
usesButtons = true;
|
||||||
});
|
});
|
||||||
|
@ -144,41 +176,59 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
);
|
);
|
||||||
previousPage();
|
_previousPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nextPage() {
|
void _nextPage() {
|
||||||
widget.onNextDate.call();
|
widget.onNextDate.call();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_pageController.jumpToPage(1);
|
||||||
setState(() {
|
setState(() {
|
||||||
usesButtons = false;
|
usesButtons = false;
|
||||||
});
|
});
|
||||||
_pageController.jumpToPage(1);
|
_setDates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void previousPage() {
|
void _previousPage() {
|
||||||
widget.onPreviousDate.call();
|
widget.onPreviousDate.call();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_pageController.jumpToPage(1);
|
||||||
setState(() {
|
setState(() {
|
||||||
usesButtons = false;
|
usesButtons = false;
|
||||||
});
|
});
|
||||||
_pageController.jumpToPage(1);
|
_setDates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void movePage(int direction) {
|
void _movePage(int direction) {
|
||||||
if (direction < 0) {
|
if (direction < 0) {
|
||||||
nextPage();
|
_nextPage();
|
||||||
} else if (direction > 0) {
|
} else if (direction > 0) {
|
||||||
previousPage();
|
_previousPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSelectDate(DateTime date) {
|
void _onSelectDate(DateTime date) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
widget.controller.selectedDate = date;
|
widget.controller.selectedDate = date;
|
||||||
movePage(widget.controller.browsingDate.month - date.month);
|
_movePage(widget.controller.browsingDate.month - date.month);
|
||||||
widget.controller.onTapDayCallBack?.call(date);
|
widget.controller.onTapDayCallBack?.call(date);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _setDates() {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() {
|
||||||
|
nextDate = DateTime(
|
||||||
|
widget.controller.browsingDate.year,
|
||||||
|
widget.controller.browsingDate.month + 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
previousDate = DateTime(
|
||||||
|
widget.controller.browsingDate.year,
|
||||||
|
widget.controller.browsingDate.month - 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,6 @@ class PickableDate extends StatelessWidget {
|
||||||
TextStyle? getStyle(bool isToday, bool isSelected) {
|
TextStyle? getStyle(bool isToday, bool isSelected) {
|
||||||
if (isToday) return theme.highlightTheme.textStyle;
|
if (isToday) return theme.highlightTheme.textStyle;
|
||||||
if (isSelected) return theme.selectedTheme.textStyle;
|
if (isSelected) return theme.selectedTheme.textStyle;
|
||||||
return null;
|
return theme.baseTheme.textStyle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
overlay_date_time_picker.gif
Normal file
BIN
overlay_date_time_picker.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
39
pubspec.yaml
39
pubspec.yaml
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_date_time_picker
|
name: flutter_date_time_picker
|
||||||
description: A new Flutter package project.
|
description: A new Flutter package project.
|
||||||
version: 0.0.1
|
version: 2.0.0
|
||||||
homepage: https://iconica.nl/
|
homepage: https://iconica.nl/
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -16,40 +16,3 @@ dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^2.0.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
|
||||||
|
|
||||||
# The following section is specific to Flutter packages.
|
|
||||||
flutter:
|
|
||||||
|
|
||||||
# To add assets to your package, add an assets section, like this:
|
|
||||||
# assets:
|
|
||||||
# - images/a_dot_burr.jpeg
|
|
||||||
# - images/a_dot_ham.jpeg
|
|
||||||
#
|
|
||||||
# For details regarding assets in packages, see
|
|
||||||
# https://flutter.dev/assets-and-images/#from-packages
|
|
||||||
#
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
|
||||||
|
|
||||||
# To add custom fonts to your package, add a fonts section here,
|
|
||||||
# in this "flutter" section. Each entry in this list should have a
|
|
||||||
# "family" key with the font family name, and a "fonts" key with a
|
|
||||||
# list giving the asset and other descriptors for the font. For
|
|
||||||
# example:
|
|
||||||
# fonts:
|
|
||||||
# - family: Schyler
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/Schyler-Regular.ttf
|
|
||||||
# - asset: fonts/Schyler-Italic.ttf
|
|
||||||
# style: italic
|
|
||||||
# - family: Trajan Pro
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/TrajanPro.ttf
|
|
||||||
# - asset: fonts/TrajanPro_Bold.ttf
|
|
||||||
# weight: 700
|
|
||||||
#
|
|
||||||
# For details regarding fonts in packages, see
|
|
||||||
# https://flutter.dev/custom-fonts/#from-packages
|
|
||||||
|
|
219
test/date_constraint_test.dart
Normal file
219
test/date_constraint_test.dart
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
import 'package:flutter_date_time_picker/src/models/date_constraint.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('Date Range', () {
|
||||||
|
group('inRange()', () {
|
||||||
|
test(
|
||||||
|
'inRange() should return true when date is between min and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 06, 01)),
|
||||||
|
max: DateConstraint(date: DateTime(2022, 07, 01)),
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 07, 20)), false);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 20)), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'inRange() should return true when date is between infinity and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint.infinity,
|
||||||
|
max: DateConstraint(date: DateTime(2022, 07, 01)),
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 07, 20)), false);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 20)), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'inRange() should return true when date is between min and infinity otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 06, 01)),
|
||||||
|
max: DateConstraint.infinity,
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 07, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 20)), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('inRange() should return true when date is lower then max', () {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
max: DateConstraint(date: DateTime(2022, 07, 01)),
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 07, 20)), false);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 20)), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('inRange() should return true when date is higher then min', () {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 06, 01)),
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 07, 20)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 20)), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('inRange() should return true when date is equal to max', () {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
max: DateConstraint(date: DateTime(2022, 06, 01)),
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 01)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 30)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 02)), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('inRange() should return true when date is equal to min', () {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 06, 01)),
|
||||||
|
);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 01)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 06, 02)), true);
|
||||||
|
expect(range.inRange(DateTime(2022, 05, 30)), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
group('inYearRange()', () {
|
||||||
|
test(
|
||||||
|
'inYearRange() should return true when year is between min and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 1, 1)),
|
||||||
|
max: DateConstraint(date: DateTime(2024, 1, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2021, 1, 1)), false);
|
||||||
|
expect(range.inYearRange(DateTime(2025, 1, 1)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inYearRange() should return true when year equals min or max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 1, 1)),
|
||||||
|
max: DateConstraint(date: DateTime(2023, 1, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inYearRange(DateTime(2022, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2021, 1, 1)), false);
|
||||||
|
expect(range.inYearRange(DateTime(2024, 1, 1)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inYearRange() should return true when year is between min and infinity otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 1, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2025, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2021, 1, 1)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inYearRange() should return true when year is between infinity and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
max: DateConstraint(date: DateTime(2024, 1, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2021, 1, 1)), true);
|
||||||
|
expect(range.inYearRange(DateTime(2025, 1, 1)), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
group('inMonthRange()', () {
|
||||||
|
test(
|
||||||
|
'inMonthRange() should return true when year is between min and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 5, 1)),
|
||||||
|
max: DateConstraint(date: DateTime(2022, 7, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 3, 1)), false);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 8, 1)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inMonthRange() should return true when year equals min or max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 5, 1)),
|
||||||
|
max: DateConstraint(date: DateTime(2022, 6, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 5, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 4, 1)), false);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 7, 1)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inMonthRange() should return true when year is between min and infinity otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 5, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 8, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 3, 1)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inMonthRange() should return true when year is between infinity and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
max: DateConstraint(date: DateTime(2022, 7, 1)),
|
||||||
|
);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 3, 1)), true);
|
||||||
|
expect(range.inMonthRange(DateTime(2022, 8, 1)), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
group('inDateRange()', () {
|
||||||
|
test(
|
||||||
|
'inDateRange() should return true when year is between min and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 1, 4)),
|
||||||
|
max: DateConstraint(date: DateTime(2022, 1, 6)),
|
||||||
|
);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 3)), false);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 7)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inDateRange() should return true when year equals min or max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 1, 4)),
|
||||||
|
max: DateConstraint(date: DateTime(2022, 1, 5)),
|
||||||
|
);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 4)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 3)), false);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 6)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inDateRange() should return true when year is between min and infinity otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
min: DateConstraint(date: DateTime(2022, 1, 4)),
|
||||||
|
);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 7)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 3)), false);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
'inDateRange() should return true when year is between infinity and max otherwise false',
|
||||||
|
() {
|
||||||
|
DateTimeConstraint range = DateTimeConstraint(
|
||||||
|
max: DateConstraint(date: DateTime(2022, 1, 6)),
|
||||||
|
);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 3)), true);
|
||||||
|
expect(range.inDateRange(DateTime(2022, 1, 7)), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue