From 981cac729b436381aa58d617f9d4ceb6c26d79b7 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 3 Feb 2023 11:59:30 +0100 Subject: [PATCH] Calendar component available without button functionality --- CHANGELOG.md | 5 + example/lib/main.dart | 8 + .../macos/Runner.xcodeproj/project.pbxproj | 9 +- example/pubspec.lock | 99 ++++++---- lib/flutter_date_time_picker.dart | 1 + lib/src/overlay_date_time_picker.dart | 6 +- .../date_time_picker/date_time_picker.dart | 174 ++++++++++++++++++ .../month_date_time_picker.dart | 7 +- .../week_date_time_picker.dart | 12 +- pubspec.yaml | 2 +- 10 files changed, 275 insertions(+), 48 deletions(-) create mode 100644 lib/src/widgets/date_time_picker/date_time_picker.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aa9f89..836ffe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ +## 2.3.0 + +- Added availability of datetimepicker without button + ## 2.2.4 - Fixed drag down date time picker not rebuilding + ## 2.2.3 - Fixed skipping month bug diff --git a/example/lib/main.dart b/example/lib/main.dart index e402d6e..ad3f006 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -79,6 +79,14 @@ class DatePickerDemo extends StatelessWidget { ), body: Stack( children: [ + Align( + alignment: Alignment.centerLeft, + child: DateTimePicker( + theme: dateTimePickerTheme, + size: const Size(270, 340), + onTapDay: (date) {}, + ), + ), Center( child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj index c84862c..d9333e4 100644 --- a/example/macos/Runner.xcodeproj/project.pbxproj +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -235,6 +235,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -344,7 +345,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +424,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +471,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/example/pubspec.lock b/example/pubspec.lock index d6d2aa1..35d6bb7 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,49 +5,56 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted version: "1.2.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" source: hosted version: "1.0.5" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" flutter: @@ -61,12 +68,13 @@ packages: path: ".." relative: true source: path - version: "2.2.2" + version: "2.2.3" flutter_lints: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" source: hosted version: "2.0.1" flutter_localizations: @@ -83,42 +91,56 @@ packages: dependency: "direct main" description: name: intl - url: "https://pub.dartlang.org" + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + url: "https://pub.dev" source: hosted version: "0.17.0" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted version: "1.8.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" source: hosted version: "1.8.2" sky_engine: @@ -130,51 +152,58 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.4.16" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" sdks: - dart: ">=2.17.6 <3.0.0" + dart: ">=2.18.0 <4.0.0" flutter: ">=2.0.0" diff --git a/lib/flutter_date_time_picker.dart b/lib/flutter_date_time_picker.dart index a95132a..4e45b41 100644 --- a/lib/flutter_date_time_picker.dart +++ b/lib/flutter_date_time_picker.dart @@ -14,3 +14,4 @@ export 'src/models/date_box_highlight_theme.dart'; export 'src/models/date_box_selected_theme.dart'; export 'src/models/date_time_picker_theme.dart'; export 'src/models/date_time_picker_bar_theme.dart'; +export 'src/widgets/date_time_picker/date_time_picker.dart'; diff --git a/lib/src/overlay_date_time_picker.dart b/lib/src/overlay_date_time_picker.dart index e514855..14a9e81 100644 --- a/lib/src/overlay_date_time_picker.dart +++ b/lib/src/overlay_date_time_picker.dart @@ -30,8 +30,12 @@ class OverlayDateTimePicker extends StatefulWidget { this.dateTimeConstraint = const DateTimeConstraint(), this.onNextPageButtonBuilder, this.onPreviousPageButtonBuilder, + this.isShown = false, }) : assert(child != null || buttonBuilder != null); + /// Determines wether the datepicker is shown at start. + final bool isShown; + /// The child contained by the DatePicker. final Widget? child; @@ -99,7 +103,7 @@ class _OverlayDateTimePickerState extends State { debugLabel: "Overlay Date Time Picker - Button", ); - bool _isShown = false; + late bool _isShown = widget.isShown; _DropdownRoute? _dropdownRoute; diff --git a/lib/src/widgets/date_time_picker/date_time_picker.dart b/lib/src/widgets/date_time_picker/date_time_picker.dart new file mode 100644 index 0000000..2af22be --- /dev/null +++ b/lib/src/widgets/date_time_picker/date_time_picker.dart @@ -0,0 +1,174 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_date_time_picker/flutter_date_time_picker.dart'; +import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart'; +import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/overlay.dart'; + +class DateTimePicker extends StatefulWidget { + /// The child contained by the DatePicker. + final Widget? child; + + /// Visual properties for the [OverlayDateTimePicker] + final DateTimePickerTheme theme; + + /// Style to base the text on + final TextStyle textStyle; + + /// Callback that provides the date tapped on as a [DateTime] object. + final Function(DateTime date)? onTapDay; + + /// Whether the current day should be highlighted in the [OverlayDateTimePicker] + final bool highlightToday; + + /// a [bool] to set de clock on [TimePickerDialog] to a fixed 24 or 12-hour format. + final bool alwaysUse24HourFormat; + + /// is a [bool] that determines if the user is able to pick a time after picking a date using the [TimePickerDialog]. + final bool pickTime; + + /// indicates the starting date. Default is [DateTime.now()] + final DateTime? initialDate; + + /// contain the dates [DateTime] that will be marked in the [OverlayDateTimePicker] by a small dot. + final List? markedDates; + + /// a [List] of [DateTime] objects that will be disabled and cannot be interacted with whatsoever. + final List? disabledDates; + + /// a [List] of [TimeOfDay] objects that cannot be picked in the [TimePickerDialog]. + final List? disabledTimes; + + /// a [Size] that indicates the size of the overlay + final Size size; + + /// [buttonBuilder] is a method for building the button that can trigger the overlay to appear + final Widget Function(Key key, void Function() onPressed)? buttonBuilder; + + /// is a [bool] that indicates if the overlay should be closed if a date has been picked. + final bool closeOnSelectDate; + + /// [showWeekDays] is a [bool] that determines if day in the week indicators should be shown + final bool showWeekDays; + + /// a [DateTimeConstraint] that dictates the constraints of the dates that can be picked. + final DateTimeConstraint dateTimeConstraint; + + /// a [Function] that determents the icon of the button for going to the next page + final Widget Function(void Function()? onPressed)? onNextPageButtonBuilder; + + /// a [Function] that determents the icon of the button for going to the previous page + final Widget Function(void Function()? onPressed)? + onPreviousPageButtonBuilder; + + const DateTimePicker( + {super.key, + this.child, + required this.theme, + this.textStyle = const TextStyle(), + this.onTapDay, + this.highlightToday = true, + this.alwaysUse24HourFormat = true, + this.pickTime = false, + this.initialDate, + this.markedDates, + this.disabledDates, + this.disabledTimes, + required this.size, + this.buttonBuilder, + this.closeOnSelectDate = false, + this.showWeekDays = true, + this.dateTimeConstraint = const DateTimeConstraint(), + this.onNextPageButtonBuilder, + this.onPreviousPageButtonBuilder}); + + @override + State createState() => _DateTimePickerState(); +} + +class _DateTimePickerState extends State { + late final DateTimePickerController _dateTimePickerController = + DateTimePickerController( + highlightToday: widget.highlightToday, + alwaysUse24HourFormat: widget.alwaysUse24HourFormat, + pickTime: widget.pickTime, + theme: widget.theme, + markedDates: widget.markedDates, + disabledDates: widget.disabledDates, + disabledTimes: widget.disabledTimes, + onTapDayCallBack: (date) { + widget.onTapDay?.call(date); + if (widget.closeOnSelectDate) { + Navigator.of(context).pop(); + } + }, + browsingDate: widget.initialDate ?? DateTime.now(), + selectedDate: widget.initialDate ?? DateTime.now(), + ); + + @override + Widget build(BuildContext context) { + return Container( + decoration: (widget.theme.shapeBorder == null) + ? BoxDecoration( + color: widget.theme.backgroundColor, + borderRadius: const BorderRadius.all(Radius.circular(16)), + boxShadow: [ + BoxShadow( + blurRadius: 5, + color: Colors.black.withOpacity(0.25), + ), + ], + ) + : ShapeDecoration( + shape: widget.theme.shapeBorder!, + color: widget.theme.backgroundColor, + shadows: [ + BoxShadow( + blurRadius: 5, + color: Colors.black.withOpacity(0.25), + ), + ], + ), + child: SizedBox( + width: widget.size.width, + height: widget.size.height, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: OverlayDateTimeContent( + theme: widget.theme, + textStyle: widget.textStyle, + size: widget.size, + controller: _dateTimePickerController, + showWeekDays: true, + onNextDate: nextDate, + onPreviousDate: previousDate, + dateTimeConstraint: widget.dateTimeConstraint, + onNextPageButtonChild: widget.onNextPageButtonBuilder, + onPreviousPageButtonChild: widget.onPreviousPageButtonBuilder, + ), + ), + ), + ); + } + + void nextDate() { + if (!mounted) return; + setState(() { + _dateTimePickerController.browsingDate = DateTime( + _dateTimePickerController.browsingDate.year, + _dateTimePickerController.browsingDate.month + 1, + _dateTimePickerController.browsingDate.day, + ); + }); + } + + void previousDate() { + if (!mounted) return; + setState(() { + _dateTimePickerController.browsingDate = DateTime( + _dateTimePickerController.browsingDate.year, + _dateTimePickerController.browsingDate.month - 1, + _dateTimePickerController.browsingDate.day, + ); + }); + } +} diff --git a/lib/src/widgets/month_date_time_picker/month_date_time_picker.dart b/lib/src/widgets/month_date_time_picker/month_date_time_picker.dart index 262e672..8b36da7 100644 --- a/lib/src/widgets/month_date_time_picker/month_date_time_picker.dart +++ b/lib/src/widgets/month_date_time_picker/month_date_time_picker.dart @@ -111,11 +111,14 @@ class MonthDateTimePicker extends StatelessWidget { dateTimePickerController.disabledTimes ?? [], )) { - showDialog( + if (context.mounted) { + showDialog( context: context, builder: (context) => dateTimePickerController - .wrongTimeDialog!); + .wrongTimeDialog!, + ); + } } } diff --git a/lib/src/widgets/week_date_time_picker/week_date_time_picker.dart b/lib/src/widgets/week_date_time_picker/week_date_time_picker.dart index fb34fc5..c3a253b 100644 --- a/lib/src/widgets/week_date_time_picker/week_date_time_picker.dart +++ b/lib/src/widgets/week_date_time_picker/week_date_time_picker.dart @@ -58,11 +58,13 @@ class WeekDateTimePicker extends StatelessWidget { timeOfDay.containsAny( dateTimePickerController.disabledTimes ?? [], )) { - showDialog( - context: context, - builder: (context) => - dateTimePickerController.wrongTimeDialog!, - ); + if (context.mounted) { + showDialog( + context: context, + builder: (context) => + dateTimePickerController.wrongTimeDialog!, + ); + } } } diff --git a/pubspec.yaml b/pubspec.yaml index 42f7ee4..4e52c11 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_date_time_picker description: A Flutter package for date and time picker. -version: 2.2.4 +version: 2.3.0 homepage: https://iconica.nl/ environment: