From 8038eea8e4993accd2d0845f724a53b661ea88e4 Mon Sep 17 00:00:00 2001 From: Alzalia Date: Thu, 12 Feb 2026 13:12:46 +0100 Subject: [PATCH 1/3] fix: removed DeviceOrientationBuilder to prevent collision with Flutter's native implementation --- lib/src/date/days_picker.dart | 316 +++++++++-------- lib/src/date/show_date_picker_dialog.dart | 97 +++--- lib/src/range/range_days_picker.dart | 319 ++++++++++-------- lib/src/range/show_range_picker_dialog.dart | 101 +++--- .../shared/device_orientation_builder.dart | 19 -- lib/src/shared/month_picker.dart | 291 ++++++++-------- lib/src/shared/year_picker.dart | 262 +++++++------- 7 files changed, 744 insertions(+), 661 deletions(-) delete mode 100644 lib/src/shared/device_orientation_builder.dart diff --git a/lib/src/date/days_picker.dart b/lib/src/date/days_picker.dart index 20521d1..c7f9f6d 100644 --- a/lib/src/date/days_picker.dart +++ b/lib/src/date/days_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/types.dart'; import '../shared/utils.dart'; import 'days_view.dart'; @@ -76,27 +75,29 @@ class DaysPicker extends StatefulWidget { this.disabledDayPredicate, }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert( - () { - if (initialDate == null) return true; - final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); + assert(() { + if (initialDate == null) return true; + final init = DateTime( + initialDate!.year, + initialDate!.month, + initialDate!.day, + ); - final min = DateTime(minDate.year, minDate.month, minDate.day); + final min = DateTime(minDate.year, minDate.month, minDate.day); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), - 'initialDate $initialDate must be on or after minDate $minDate.', - ); - assert( - () { - if (initialDate == null) return true; - final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); - - final max = DateTime(maxDate.year, maxDate.month, maxDate.day); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), - 'initialDate $initialDate must be on or before maxDate $maxDate.', - ); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), 'initialDate $initialDate must be on or after minDate $minDate.'); + assert(() { + if (initialDate == null) return true; + final init = DateTime( + initialDate!.year, + initialDate!.month, + initialDate!.day, + ); + + final max = DateTime(maxDate.year, maxDate.month, maxDate.day); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); } /// The date which will be displayed on first opening. If not specified, the picker @@ -251,10 +252,17 @@ class _DaysPickerState extends State { @override void initState() { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); - _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); - _selectedDate = widget.selectedDate != null ? DateUtils.dateOnly(widget.selectedDate!) : null; + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); + _displayedMonth = DateUtils.dateOnly( + widget.initialDate ?? clampedInitailDate, + ); + _selectedDate = widget.selectedDate != null + ? DateUtils.dateOnly(widget.selectedDate!) + : null; _pageController = PageController( initialPage: DateUtils.monthDelta(widget.minDate, _displayedMonth!), ); @@ -268,9 +276,14 @@ class _DaysPickerState extends State { // but for makeing debuging easy, we will navigate to the initial date again // if it changes. if (oldWidget.initialDate != widget.initialDate) { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); - _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); + _displayedMonth = DateUtils.dateOnly( + widget.initialDate ?? clampedInitailDate, + ); _pageController.jumpToPage( DateUtils.monthDelta(widget.minDate, _displayedMonth!), @@ -278,7 +291,9 @@ class _DaysPickerState extends State { } if (oldWidget.selectedDate != widget.selectedDate) { - _selectedDate = widget.selectedDate != null ? DateUtils.dateOnly(widget.selectedDate!) : null; + _selectedDate = widget.selectedDate != null + ? DateUtils.dateOnly(widget.selectedDate!) + : null; } super.didUpdateWidget(oldWidget); } @@ -298,7 +313,8 @@ class _DaysPickerState extends State { //! days of the week // // - final TextStyle daysOfTheWeekTextStyle = widget.daysOfTheWeekTextStyle ?? + final TextStyle daysOfTheWeekTextStyle = + widget.daysOfTheWeekTextStyle ?? textTheme.titleSmall!.copyWith( color: colorScheme.onSurface.withValues(alpha: 0.30), fontWeight: FontWeight.bold, @@ -310,7 +326,8 @@ class _DaysPickerState extends State { // // - final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = + widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -323,26 +340,30 @@ class _DaysPickerState extends State { // // - final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = + widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = + widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = + widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = + widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -353,23 +374,23 @@ class _DaysPickerState extends State { // // - final TextStyle selectedCellTextStyle = widget.selectedCellTextStyle ?? + final TextStyle selectedCellTextStyle = + widget.selectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration selectedCellDecoration = widget.selectedCellDecoration ?? - BoxDecoration( - color: colorScheme.primary, - shape: BoxShape.circle, - ); + final BoxDecoration selectedCellDecoration = + widget.selectedCellDecoration ?? + BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); // // // //! header - final leadingDateTextStyle = widget.leadingDateTextStyle ?? + final leadingDateTextStyle = + widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -382,117 +403,130 @@ class _DaysPickerState extends State { // //! splash - final splashColor = widget.splashColor ?? + final splashColor = + widget.splashColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = widget.highlightColor ?? + final highlightColor = + widget.highlightColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder(builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: MaterialLocalizations.of(context) - .formatMonthYear(_displayedMonth!) - .replaceAll('٩', '9') - .replaceAll('٨', '8') - .replaceAll('٧', '7') - .replaceAll('٦', '6') - .replaceAll('٥', '5') - .replaceAll('٤', '4') - .replaceAll('٣', '3') - .replaceAll('٢', '2') - .replaceAll('١', '1') - .replaceAll('٠', '0'), - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - ), - const SizedBox(height: 10), - Expanded( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, - onPageChanged: (monthPage) { - final DateTime monthDate = DateUtils.addMonthsToMonthDate(widget.minDate, monthPage); - - setState(() { - _displayedMonth = monthDate; - }); + return DeviceOrientationBuilder( + builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: MaterialLocalizations.of(context) + .formatMonthYear(_displayedMonth!) + .replaceAll('٩', '9') + .replaceAll('٨', '8') + .replaceAll('٧', '7') + .replaceAll('٦', '6') + .replaceAll('٥', '5') + .replaceAll('٤', '4') + .replaceAll('٣', '3') + .replaceAll('٢', '2') + .replaceAll('١', '1') + .replaceAll('٠', '0'), + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); }, - itemBuilder: (context, index) { - final DateTime month = DateUtils.addMonthsToMonthDate(widget.minDate, index); - - return DaysView( - key: ValueKey(month), - currentDate: DateUtils.dateOnly(widget.currentDate ?? DateTime.now()), - maxDate: DateUtils.dateOnly(widget.maxDate), - minDate: DateUtils.dateOnly(widget.minDate), - displayedMonth: month, - selectedDate: _selectedDate, - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - enabledCellsTextStyle: enabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedDayDecoration: selectedCellDecoration, - selectedDayTextStyle: selectedCellTextStyle, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - disabledDayPredicate: widget.disabledDayPredicate, - onChanged: (value) { - setState(() { - _selectedDate = value; - }); - widget.onDateSelected?.call(value); - }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, ); }, + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, ), - ), - ], - ), - ); - }); + const SizedBox(height: 10), + Expanded( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: + DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, + onPageChanged: (monthPage) { + final DateTime monthDate = DateUtils.addMonthsToMonthDate( + widget.minDate, + monthPage, + ); + + setState(() { + _displayedMonth = monthDate; + }); + }, + itemBuilder: (context, index) { + final DateTime month = DateUtils.addMonthsToMonthDate( + widget.minDate, + index, + ); + + return DaysView( + key: ValueKey(month), + currentDate: DateUtils.dateOnly( + widget.currentDate ?? DateTime.now(), + ), + maxDate: DateUtils.dateOnly(widget.maxDate), + minDate: DateUtils.dateOnly(widget.minDate), + displayedMonth: month, + selectedDate: _selectedDate, + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + enabledCellsTextStyle: enabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedDayDecoration: selectedCellDecoration, + selectedDayTextStyle: selectedCellTextStyle, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + disabledDayPredicate: widget.disabledDayPredicate, + onChanged: (value) { + setState(() { + _selectedDate = value; + }); + widget.onDateSelected?.call(value); + }, + ); + }, + ), + ), + ], + ), + ); + }, + ); } } diff --git a/lib/src/date/show_date_picker_dialog.dart b/lib/src/date/show_date_picker_dialog.dart index 4e79eca..5d21406 100644 --- a/lib/src/date/show_date_picker_dialog.dart +++ b/lib/src/date/show_date_picker_dialog.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/picker_type.dart'; import 'date_picker.dart'; @@ -82,55 +81,57 @@ Future showDatePickerDialog({ useRootNavigator: useRootNavigator, useSafeArea: useSafeArea, builder: (context) { - return DeviceOrientationBuilder(builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 400.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return Padding( - padding: padding, - child: Dialog( - insetPadding: EdgeInsets.zero, - child: SizedBox( - width: width ?? size.width, - height: height ?? size.height, - child: DatePicker( - centerLeadingDate: centerLeadingDate, - initialDate: initialDate, - maxDate: maxDate, - minDate: minDate, - currentDate: currentDate, - selectedDate: selectedDate, - onDateSelected: (value) => Navigator.pop(context, value), - initialPickerType: initialPickerType, - padding: contentPadding, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - disabledCellsDecoration: disabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - selectedCellDecoration: selectedCellDecoration, - selectedCellTextStyle: selectedCellTextStyle, - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: splashRadius, - previousPageSemanticLabel: previousPageSemanticLabel, - nextPageSemanticLabel: nextPageSemanticLabel, + return DeviceOrientationBuilder( + builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 400.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return Padding( + padding: padding, + child: Dialog( + insetPadding: EdgeInsets.zero, + child: SizedBox( + width: width ?? size.width, + height: height ?? size.height, + child: DatePicker( + centerLeadingDate: centerLeadingDate, + initialDate: initialDate, + maxDate: maxDate, + minDate: minDate, + currentDate: currentDate, + selectedDate: selectedDate, + onDateSelected: (value) => Navigator.pop(context, value), + initialPickerType: initialPickerType, + padding: contentPadding, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + disabledCellsDecoration: disabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + selectedCellDecoration: selectedCellDecoration, + selectedCellTextStyle: selectedCellTextStyle, + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: splashRadius, + previousPageSemanticLabel: previousPageSemanticLabel, + nextPageSemanticLabel: nextPageSemanticLabel, + ), ), ), - ), - ); - }); + ); + }, + ); }, ); } diff --git a/lib/src/range/range_days_picker.dart b/lib/src/range/range_days_picker.dart index 8282732..7f2c5f6 100644 --- a/lib/src/range/range_days_picker.dart +++ b/lib/src/range/range_days_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/header.dart'; import '../shared/utils.dart'; import 'range_days_view.dart'; @@ -41,27 +40,29 @@ class RangeDaysPicker extends StatefulWidget { }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert( - () { - if (initialDate == null) return true; - final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); + assert(() { + if (initialDate == null) return true; + final init = DateTime( + initialDate!.year, + initialDate!.month, + initialDate!.day, + ); - final min = DateTime(minDate.year, minDate.month, minDate.day); + final min = DateTime(minDate.year, minDate.month, minDate.day); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), - 'initialDate $initialDate must be on or after minDate $minDate.', - ); - assert( - () { - if (initialDate == null) return true; - final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); - - final max = DateTime(maxDate.year, maxDate.month, maxDate.day); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), - 'initialDate $initialDate must be on or before maxDate $maxDate.', - ); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), 'initialDate $initialDate must be on or after minDate $minDate.'); + assert(() { + if (initialDate == null) return true; + final init = DateTime( + initialDate!.year, + initialDate!.month, + initialDate!.day, + ); + + final max = DateTime(maxDate.year, maxDate.month, maxDate.day); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); } /// The date which will be displayed on first opening. If not specified, the picker @@ -228,9 +229,14 @@ class __RangeDaysPickerState extends State { @override void initState() { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); - _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); + _displayedMonth = DateUtils.dateOnly( + widget.initialDate ?? clampedInitailDate, + ); _pageController = PageController( initialPage: DateUtils.monthDelta(widget.minDate, _displayedMonth!), ); @@ -245,9 +251,14 @@ class __RangeDaysPickerState extends State { // but for makeing debuging easy, we will navigate to the initial date again // if it changes. if (oldWidget.initialDate != widget.initialDate) { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); - _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); + _displayedMonth = DateUtils.dateOnly( + widget.initialDate ?? clampedInitailDate, + ); _pageController.jumpToPage( DateUtils.monthDelta(widget.minDate, _displayedMonth!), ); @@ -270,7 +281,8 @@ class __RangeDaysPickerState extends State { //! days of the week // // - final TextStyle daysOfTheWeekTextStyle = widget.daysOfTheWeekTextStyle ?? + final TextStyle daysOfTheWeekTextStyle = + widget.daysOfTheWeekTextStyle ?? textTheme.titleSmall!.copyWith( color: colorScheme.onSurface.withValues(alpha: 0.30), fontWeight: FontWeight.bold, @@ -282,7 +294,8 @@ class __RangeDaysPickerState extends State { // // - final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = + widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -295,25 +308,29 @@ class __RangeDaysPickerState extends State { // // - final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = + widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = + widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = + widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = + widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -324,13 +341,15 @@ class __RangeDaysPickerState extends State { // // - final TextStyle selectedCellsTextStyle = widget.selectedCellsTextStyle ?? + final TextStyle selectedCellsTextStyle = + widget.selectedCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimaryContainer, ); - final BoxDecoration selectedCellsDecoration = widget.selectedCellsDecoration ?? + final BoxDecoration selectedCellsDecoration = + widget.selectedCellsDecoration ?? BoxDecoration( color: colorScheme.primaryContainer, shape: BoxShape.rectangle, @@ -339,23 +358,23 @@ class __RangeDaysPickerState extends State { // //! single - final TextStyle singleSelectedCellTextStyle = widget.singleSelectedCellTextStyle ?? + final TextStyle singleSelectedCellTextStyle = + widget.singleSelectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration singleSelectedCellDecoration = widget.singleSelectedCellDecoration ?? - BoxDecoration( - color: colorScheme.primary, - shape: BoxShape.circle, - ); + final BoxDecoration singleSelectedCellDecoration = + widget.singleSelectedCellDecoration ?? + BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); // // // //! header - final leadingDateTextStyle = widget.leadingDateTextStyle ?? + final leadingDateTextStyle = + widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -367,117 +386,135 @@ class __RangeDaysPickerState extends State { // //! splash - final splashColor = widget.splashColor ?? + final splashColor = + widget.splashColor ?? singleSelectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = widget.highlightColor ?? + final highlightColor = + widget.highlightColor ?? singleSelectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder(builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: MaterialLocalizations.of(context) - .formatMonthYear(_displayedMonth!) - .replaceAll('٩', '9') - .replaceAll('٨', '8') - .replaceAll('٧', '7') - .replaceAll('٦', '6') - .replaceAll('٥', '5') - .replaceAll('٤', '4') - .replaceAll('٣', '3') - .replaceAll('٢', '2') - .replaceAll('١', '1') - .replaceAll('٠', '0'), - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - ), - const SizedBox(height: 10), - Expanded( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, - onPageChanged: (monthPage) { - final DateTime monthDate = DateUtils.addMonthsToMonthDate(widget.minDate, monthPage); - - setState(() { - _displayedMonth = monthDate; - }); + return DeviceOrientationBuilder( + builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: MaterialLocalizations.of(context) + .formatMonthYear(_displayedMonth!) + .replaceAll('٩', '9') + .replaceAll('٨', '8') + .replaceAll('٧', '7') + .replaceAll('٦', '6') + .replaceAll('٥', '5') + .replaceAll('٤', '4') + .replaceAll('٣', '3') + .replaceAll('٢', '2') + .replaceAll('١', '1') + .replaceAll('٠', '0'), + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); }, - itemBuilder: (context, index) { - final DateTime month = DateUtils.addMonthsToMonthDate(widget.minDate, index); - - return RangeDaysView( - key: ValueKey(month), - currentDate: DateUtils.dateOnly(widget.currentDate ?? DateTime.now()), - minDate: DateUtils.dateOnly(widget.minDate), - maxDate: DateUtils.dateOnly(widget.maxDate), - displayedMonth: month, - selectedEndDate: - widget.selectedEndDate == null ? null : DateUtils.dateOnly(widget.selectedEndDate!), - selectedStartDate: - widget.selectedStartDate == null ? null : DateUtils.dateOnly(widget.selectedStartDate!), - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - enabledCellsTextStyle: enabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedCellsDecoration: selectedCellsDecoration, - selectedCellsTextStyle: selectedCellsTextStyle, - singleSelectedCellTextStyle: singleSelectedCellTextStyle, - singleSelectedCellDecoration: singleSelectedCellDecoration, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - onEndDateChanged: (value) => widget.onEndDateChanged?.call(value), - onStartDateChanged: (value) => widget.onStartDateChanged?.call(value), + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, ); }, ), - ), - ], - ), - ); - }); + const SizedBox(height: 10), + Expanded( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: + DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, + onPageChanged: (monthPage) { + final DateTime monthDate = DateUtils.addMonthsToMonthDate( + widget.minDate, + monthPage, + ); + + setState(() { + _displayedMonth = monthDate; + }); + }, + itemBuilder: (context, index) { + final DateTime month = DateUtils.addMonthsToMonthDate( + widget.minDate, + index, + ); + + return RangeDaysView( + key: ValueKey(month), + currentDate: DateUtils.dateOnly( + widget.currentDate ?? DateTime.now(), + ), + minDate: DateUtils.dateOnly(widget.minDate), + maxDate: DateUtils.dateOnly(widget.maxDate), + displayedMonth: month, + selectedEndDate: widget.selectedEndDate == null + ? null + : DateUtils.dateOnly(widget.selectedEndDate!), + selectedStartDate: widget.selectedStartDate == null + ? null + : DateUtils.dateOnly(widget.selectedStartDate!), + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + enabledCellsTextStyle: enabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedCellsDecoration: selectedCellsDecoration, + selectedCellsTextStyle: selectedCellsTextStyle, + singleSelectedCellTextStyle: singleSelectedCellTextStyle, + singleSelectedCellDecoration: + singleSelectedCellDecoration, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + onEndDateChanged: (value) => + widget.onEndDateChanged?.call(value), + onStartDateChanged: (value) => + widget.onStartDateChanged?.call(value), + ); + }, + ), + ), + ], + ), + ); + }, + ); } } diff --git a/lib/src/range/show_range_picker_dialog.dart b/lib/src/range/show_range_picker_dialog.dart index cdd4b70..cfd32af 100644 --- a/lib/src/range/show_range_picker_dialog.dart +++ b/lib/src/range/show_range_picker_dialog.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/picker_type.dart'; import 'range_picker.dart'; @@ -83,57 +82,59 @@ Future showRangePickerDialog({ useRootNavigator: useRootNavigator, useSafeArea: useSafeArea, builder: (context) { - return DeviceOrientationBuilder(builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 400.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return Padding( - padding: padding, - child: Dialog( - insetPadding: EdgeInsets.zero, - child: SizedBox( - width: width ?? size.width, - height: height ?? size.height, - child: RangeDatePicker( - centerLeadingDate: centerLeadingDate, - currentDate: currentDate, - maxDate: maxDate, - minDate: minDate, - initialDate: initialDate, - selectedRange: selectedRange, - onRangeSelected: (value) => Navigator.pop(context, value), - initialPickerType: initialPickerType, - padding: contentPadding, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - disabledCellsDecoration: disabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - selectedCellsDecoration: selectedCellsDecoration, - selectedCellsTextStyle: selectedCellsTextStyle, - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - singleSelectedCellTextStyle: singleSelectedCellTextStyle, - singleSelectedCellDecoration: singleSelectedCellDecoration, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: splashRadius, - previousPageSemanticLabel: previousPageSemanticLabel, - nextPageSemanticLabel: nextPageSemanticLabel, + return DeviceOrientationBuilder( + builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 400.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return Padding( + padding: padding, + child: Dialog( + insetPadding: EdgeInsets.zero, + child: SizedBox( + width: width ?? size.width, + height: height ?? size.height, + child: RangeDatePicker( + centerLeadingDate: centerLeadingDate, + currentDate: currentDate, + maxDate: maxDate, + minDate: minDate, + initialDate: initialDate, + selectedRange: selectedRange, + onRangeSelected: (value) => Navigator.pop(context, value), + initialPickerType: initialPickerType, + padding: contentPadding, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + disabledCellsDecoration: disabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + selectedCellsDecoration: selectedCellsDecoration, + selectedCellsTextStyle: selectedCellsTextStyle, + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + singleSelectedCellTextStyle: singleSelectedCellTextStyle, + singleSelectedCellDecoration: singleSelectedCellDecoration, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: splashRadius, + previousPageSemanticLabel: previousPageSemanticLabel, + nextPageSemanticLabel: nextPageSemanticLabel, + ), ), ), - ), - ); - }); + ); + }, + ); }, ); } diff --git a/lib/src/shared/device_orientation_builder.dart b/lib/src/shared/device_orientation_builder.dart deleted file mode 100644 index 113ef34..0000000 --- a/lib/src/shared/device_orientation_builder.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Builds a widget tree that can depend on the device orientation. -class DeviceOrientationBuilder extends StatelessWidget { - /// Builds a widget tree that can depend on the device orientation. - final Widget Function(BuildContext context, Orientation orientation) builder; - - /// Builds a widget tree that can depend on the device orientation. - const DeviceOrientationBuilder({ - super.key, - required this.builder, - }); - - @override - Widget build(BuildContext context) { - final orientation = MediaQuery.orientationOf(context); - return builder(context, orientation); - } -} diff --git a/lib/src/shared/month_picker.dart b/lib/src/shared/month_picker.dart index 295ccd4..b40043a 100644 --- a/lib/src/shared/month_picker.dart +++ b/lib/src/shared/month_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'device_orientation_builder.dart'; import 'header.dart'; import 'month_view.dart'; import 'utils.dart'; @@ -74,27 +73,21 @@ class MonthPicker extends StatefulWidget { }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert( - () { - if (initialDate == null) return true; - final init = DateUtilsX.monthOnly(initialDate!); + assert(() { + if (initialDate == null) return true; + final init = DateUtilsX.monthOnly(initialDate!); - final min = DateUtilsX.monthOnly(minDate); + final min = DateUtilsX.monthOnly(minDate); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), - 'initialDate $initialDate must be on or after minDate $minDate.', - ); - assert( - () { - if (initialDate == null) return true; - final init = DateUtilsX.monthOnly(initialDate!); - - final max = DateUtilsX.monthOnly(maxDate); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), - 'initialDate $initialDate must be on or before maxDate $maxDate.', - ); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), 'initialDate $initialDate must be on or after minDate $minDate.'); + assert(() { + if (initialDate == null) return true; + final init = DateUtilsX.monthOnly(initialDate!); + + final max = DateUtilsX.monthOnly(maxDate); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); } /// The date which will be displayed on first opening. If not specified, the picker @@ -241,11 +234,18 @@ class _MonthPickerState extends State { @override void initState() { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); - _displayedYear = DateUtilsX.yearOnly(widget.initialDate ?? clampedInitailDate); + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); + _displayedYear = DateUtilsX.yearOnly( + widget.initialDate ?? clampedInitailDate, + ); - _selectedDate = widget.selectedDate != null ? DateUtilsX.monthOnly(widget.selectedDate!) : null; + _selectedDate = widget.selectedDate != null + ? DateUtilsX.monthOnly(widget.selectedDate!) + : null; _pageController = PageController( initialPage: (_displayedYear!.year - widget.minDate.year), ); @@ -259,14 +259,21 @@ class _MonthPickerState extends State { // but for makeing debuging easy, we will navigate to the initial date again // if it changes. if (oldWidget.initialDate != widget.initialDate) { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); - _displayedYear = DateUtilsX.yearOnly(widget.initialDate ?? clampedInitailDate); + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); + _displayedYear = DateUtilsX.yearOnly( + widget.initialDate ?? clampedInitailDate, + ); _pageController.jumpToPage(_displayedYear!.year - widget.minDate.year); } if (oldWidget.selectedDate != _selectedDate) { - _selectedDate = widget.selectedDate != null ? DateUtilsX.monthOnly(widget.selectedDate!) : null; + _selectedDate = widget.selectedDate != null + ? DateUtilsX.monthOnly(widget.selectedDate!) + : null; } super.didUpdateWidget(oldWidget); } @@ -287,7 +294,8 @@ class _MonthPickerState extends State { // // - final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = + widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -300,26 +308,30 @@ class _MonthPickerState extends State { // // - final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = + widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = + widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = + widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = + widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -330,143 +342,148 @@ class _MonthPickerState extends State { // // - final TextStyle selectedCellTextStyle = widget.selectedCellTextStyle ?? + final TextStyle selectedCellTextStyle = + widget.selectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration selectedCellDecoration = widget.selectedCellDecoration ?? - BoxDecoration( - color: colorScheme.primary, - shape: BoxShape.circle, - ); + final BoxDecoration selectedCellDecoration = + widget.selectedCellDecoration ?? + BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); // // // //! header - final leadingDateTextStyle = widget.leadingDateTextStyle ?? + final leadingDateTextStyle = + widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ); - final slidersColor = widget.slidersColor ?? Theme.of(context).colorScheme.primary; + final slidersColor = + widget.slidersColor ?? Theme.of(context).colorScheme.primary; final slidersSize = widget.slidersSize ?? 20; // //! splash - final splashColor = widget.splashColor ?? + final splashColor = + widget.splashColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = widget.highlightColor ?? + final highlightColor = + widget.highlightColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder(builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: _displayedYear!.year.toString(), - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - ), - const SizedBox(height: 10), - Expanded( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: yearsCount, - onPageChanged: (yearPage) { - final DateTime year = DateTime( - widget.minDate.year + yearPage, - // widget.minDate.month, - // widget.minDate.day, + return DeviceOrientationBuilder( + builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: _displayedYear!.year.toString(), + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, ); - - setState(() { - _displayedYear = year; - }); }, - itemBuilder: (context, index) { - final DateTime year = DateTime( - widget.minDate.year + index, - // widget.minDate.month, - // widget.minDate.day, - ); - - return MonthView( - key: ValueKey(year), - currentDate: widget.currentDate != null - ? DateUtilsX.monthOnly(widget.currentDate!) - : DateUtilsX.monthOnly(DateTime.now()), - maxDate: DateUtilsX.monthOnly(widget.maxDate), - minDate: DateUtilsX.monthOnly(widget.minDate), - displayedDate: year, - selectedDate: _selectedDate, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedCellDecoration: selectedCellDecoration, - selectedCellTextStyle: selectedCellTextStyle, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - onChanged: (value) { - final selected = DateUtilsX.monthOnly(value); - widget.onDateSelected?.call(selected); - setState(() { - _selectedDate = selected; - }); - }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, ); }, ), - ), - ], - ), - ); - }); + const SizedBox(height: 10), + Expanded( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: yearsCount, + onPageChanged: (yearPage) { + final DateTime year = DateTime( + widget.minDate.year + yearPage, + // widget.minDate.month, + // widget.minDate.day, + ); + + setState(() { + _displayedYear = year; + }); + }, + itemBuilder: (context, index) { + final DateTime year = DateTime( + widget.minDate.year + index, + // widget.minDate.month, + // widget.minDate.day, + ); + + return MonthView( + key: ValueKey(year), + currentDate: widget.currentDate != null + ? DateUtilsX.monthOnly(widget.currentDate!) + : DateUtilsX.monthOnly(DateTime.now()), + maxDate: DateUtilsX.monthOnly(widget.maxDate), + minDate: DateUtilsX.monthOnly(widget.minDate), + displayedDate: year, + selectedDate: _selectedDate, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedCellDecoration: selectedCellDecoration, + selectedCellTextStyle: selectedCellTextStyle, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + onChanged: (value) { + final selected = DateUtilsX.monthOnly(value); + widget.onDateSelected?.call(selected); + setState(() { + _selectedDate = selected; + }); + }, + ); + }, + ), + ), + ], + ), + ); + }, + ); } } diff --git a/lib/src/shared/year_picker.dart b/lib/src/shared/year_picker.dart index 90196b9..a7e34a7 100644 --- a/lib/src/shared/year_picker.dart +++ b/lib/src/shared/year_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'device_orientation_builder.dart'; import 'header.dart'; import '../date/show_date_picker_dialog.dart'; import 'utils.dart'; @@ -72,27 +71,21 @@ class YearsPicker extends StatefulWidget { }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert( - () { - if (initialDate == null) return true; - final init = DateUtilsX.yearOnly(initialDate!); + assert(() { + if (initialDate == null) return true; + final init = DateUtilsX.yearOnly(initialDate!); - final min = DateUtilsX.yearOnly(minDate); + final min = DateUtilsX.yearOnly(minDate); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), - 'initialDate $initialDate must be on or after minDate $minDate.', - ); - assert( - () { - if (initialDate == null) return true; - final init = DateUtilsX.yearOnly(initialDate!); - - final max = DateUtilsX.yearOnly(maxDate); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), - 'initialDate $initialDate must be on or before maxDate $maxDate.', - ); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), 'initialDate $initialDate must be on or after minDate $minDate.'); + assert(() { + if (initialDate == null) return true; + final init = DateUtilsX.yearOnly(initialDate!); + + final max = DateUtilsX.yearOnly(maxDate); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); } /// The date which will be displayed on first opening. If not specified, the picker @@ -243,7 +236,9 @@ class _YearsPickerState extends State { start: DateTime(widget.minDate.year + initialPageNumber * 12), end: DateTime(widget.minDate.year + initialPageNumber * 12 - 1 + 12), ); - _selectedDate = widget.selectedDate != null ? DateUtilsX.yearOnly(widget.selectedDate!) : null; + _selectedDate = widget.selectedDate != null + ? DateUtilsX.yearOnly(widget.selectedDate!) + : null; super.initState(); } @@ -261,7 +256,9 @@ class _YearsPickerState extends State { } if (oldWidget.selectedDate != widget.selectedDate) { - _selectedDate = widget.selectedDate != null ? DateUtilsX.yearOnly(widget.selectedDate!) : null; + _selectedDate = widget.selectedDate != null + ? DateUtilsX.yearOnly(widget.selectedDate!) + : null; } super.didUpdateWidget(oldWidget); @@ -277,11 +274,15 @@ class _YearsPickerState extends State { /// between [minDate] and [maxDate]. /// /// Each page will contains 12 years in a 3 x 4 grid. - int get pageCount => ((widget.maxDate.year - widget.minDate.year + 1) / 12).ceil(); + int get pageCount => + ((widget.maxDate.year - widget.minDate.year + 1) / 12).ceil(); int get initialPageNumber { - final clampedInitailDate = - DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + final clampedInitailDate = DateUtilsX.clampDateToRange( + max: widget.maxDate, + min: widget.minDate, + date: DateTime.now(), + ); final init = widget.initialDate ?? clampedInitailDate; final page = ((init.year - widget.minDate.year + 1) / 12).ceil() - 1; @@ -306,7 +307,8 @@ class _YearsPickerState extends State { // // - final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = + widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -319,26 +321,30 @@ class _YearsPickerState extends State { // // - final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = + widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = + widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = + widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = + widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -349,133 +355,139 @@ class _YearsPickerState extends State { // // - final TextStyle selectedCellTextStyle = widget.selectedCellTextStyle ?? + final TextStyle selectedCellTextStyle = + widget.selectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration selectedCellDecoration = widget.selectedCellDecoration ?? - BoxDecoration( - color: colorScheme.primary, - shape: BoxShape.circle, - ); + final BoxDecoration selectedCellDecoration = + widget.selectedCellDecoration ?? + BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); // // // //! header - final leadingDateTextStyle = widget.leadingDateTextStyle ?? + final leadingDateTextStyle = + widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ); - final slidersColor = widget.slidersColor ?? Theme.of(context).colorScheme.primary; + final slidersColor = + widget.slidersColor ?? Theme.of(context).colorScheme.primary; final slidersSize = widget.slidersSize ?? 20; // //! splash - final splashColor = widget.splashColor ?? + final splashColor = + widget.splashColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = widget.highlightColor ?? + final highlightColor = + widget.highlightColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder(builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: '${_displayedRange?.start.year} - ${_displayedRange?.end.year}', - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); - }, - ), - const SizedBox(height: 10), - Flexible( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: pageCount, - onPageChanged: (yearPage) { - setState(() { - _displayedRange = calculateDateRange(yearPage); - }); + return DeviceOrientationBuilder( + builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: + '${_displayedRange?.start.year} - ${_displayedRange?.end.year}', + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); }, - itemBuilder: (context, index) { - final yearRange = calculateDateRange(index); - - return YearView( - key: ValueKey(yearRange), - currentDate: widget.currentDate != null - ? DateUtilsX.yearOnly(widget.currentDate!) - : DateUtilsX.yearOnly(DateTime.now()), - maxDate: DateUtilsX.yearOnly(widget.maxDate), - minDate: DateUtilsX.yearOnly(widget.minDate), - displayedYearRange: yearRange, - selectedDate: _selectedDate, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedCellDecoration: selectedCellDecoration, - selectedCellTextStyle: selectedCellTextStyle, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - onChanged: (value) { - final selected = DateUtilsX.yearOnly(value); - widget.onDateSelected?.call(selected); - setState(() { - _selectedDate = selected; - }); - }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, ); }, ), - ), - ], - ), - ); - }); + const SizedBox(height: 10), + Flexible( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: pageCount, + onPageChanged: (yearPage) { + setState(() { + _displayedRange = calculateDateRange(yearPage); + }); + }, + itemBuilder: (context, index) { + final yearRange = calculateDateRange(index); + + return YearView( + key: ValueKey(yearRange), + currentDate: widget.currentDate != null + ? DateUtilsX.yearOnly(widget.currentDate!) + : DateUtilsX.yearOnly(DateTime.now()), + maxDate: DateUtilsX.yearOnly(widget.maxDate), + minDate: DateUtilsX.yearOnly(widget.minDate), + displayedYearRange: yearRange, + selectedDate: _selectedDate, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedCellDecoration: selectedCellDecoration, + selectedCellTextStyle: selectedCellTextStyle, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + onChanged: (value) { + final selected = DateUtilsX.yearOnly(value); + widget.onDateSelected?.call(selected); + setState(() { + _selectedDate = selected; + }); + }, + ); + }, + ), + ), + ], + ), + ); + }, + ); } } From fd5ac61e957c1a440b8a27d7fc798f95508ed8e8 Mon Sep 17 00:00:00 2001 From: Alzalia Date: Thu, 12 Feb 2026 13:18:07 +0100 Subject: [PATCH 2/3] Revert "fix: removed DeviceOrientationBuilder to prevent collision with Flutter's native implementation" This reverts commit 8038eea8e4993accd2d0845f724a53b661ea88e4. --- lib/src/date/days_picker.dart | 316 ++++++++--------- lib/src/date/show_date_picker_dialog.dart | 97 +++--- lib/src/range/range_days_picker.dart | 319 ++++++++---------- lib/src/range/show_range_picker_dialog.dart | 101 +++--- .../shared/device_orientation_builder.dart | 19 ++ lib/src/shared/month_picker.dart | 291 ++++++++-------- lib/src/shared/year_picker.dart | 262 +++++++------- 7 files changed, 661 insertions(+), 744 deletions(-) create mode 100644 lib/src/shared/device_orientation_builder.dart diff --git a/lib/src/date/days_picker.dart b/lib/src/date/days_picker.dart index c7f9f6d..20521d1 100644 --- a/lib/src/date/days_picker.dart +++ b/lib/src/date/days_picker.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../shared/device_orientation_builder.dart'; import '../shared/types.dart'; import '../shared/utils.dart'; import 'days_view.dart'; @@ -75,29 +76,27 @@ class DaysPicker extends StatefulWidget { this.disabledDayPredicate, }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert(() { - if (initialDate == null) return true; - final init = DateTime( - initialDate!.year, - initialDate!.month, - initialDate!.day, - ); - - final min = DateTime(minDate.year, minDate.month, minDate.day); + assert( + () { + if (initialDate == null) return true; + final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), 'initialDate $initialDate must be on or after minDate $minDate.'); - assert(() { - if (initialDate == null) return true; - final init = DateTime( - initialDate!.year, - initialDate!.month, - initialDate!.day, - ); + final min = DateTime(minDate.year, minDate.month, minDate.day); - final max = DateTime(maxDate.year, maxDate.month, maxDate.day); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), + 'initialDate $initialDate must be on or after minDate $minDate.', + ); + assert( + () { + if (initialDate == null) return true; + final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); + + final max = DateTime(maxDate.year, maxDate.month, maxDate.day); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), + 'initialDate $initialDate must be on or before maxDate $maxDate.', + ); } /// The date which will be displayed on first opening. If not specified, the picker @@ -252,17 +251,10 @@ class _DaysPickerState extends State { @override void initState() { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); - _displayedMonth = DateUtils.dateOnly( - widget.initialDate ?? clampedInitailDate, - ); - _selectedDate = widget.selectedDate != null - ? DateUtils.dateOnly(widget.selectedDate!) - : null; + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); + _selectedDate = widget.selectedDate != null ? DateUtils.dateOnly(widget.selectedDate!) : null; _pageController = PageController( initialPage: DateUtils.monthDelta(widget.minDate, _displayedMonth!), ); @@ -276,14 +268,9 @@ class _DaysPickerState extends State { // but for makeing debuging easy, we will navigate to the initial date again // if it changes. if (oldWidget.initialDate != widget.initialDate) { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); - _displayedMonth = DateUtils.dateOnly( - widget.initialDate ?? clampedInitailDate, - ); + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); _pageController.jumpToPage( DateUtils.monthDelta(widget.minDate, _displayedMonth!), @@ -291,9 +278,7 @@ class _DaysPickerState extends State { } if (oldWidget.selectedDate != widget.selectedDate) { - _selectedDate = widget.selectedDate != null - ? DateUtils.dateOnly(widget.selectedDate!) - : null; + _selectedDate = widget.selectedDate != null ? DateUtils.dateOnly(widget.selectedDate!) : null; } super.didUpdateWidget(oldWidget); } @@ -313,8 +298,7 @@ class _DaysPickerState extends State { //! days of the week // // - final TextStyle daysOfTheWeekTextStyle = - widget.daysOfTheWeekTextStyle ?? + final TextStyle daysOfTheWeekTextStyle = widget.daysOfTheWeekTextStyle ?? textTheme.titleSmall!.copyWith( color: colorScheme.onSurface.withValues(alpha: 0.30), fontWeight: FontWeight.bold, @@ -326,8 +310,7 @@ class _DaysPickerState extends State { // // - final TextStyle enabledCellsTextStyle = - widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -340,30 +323,26 @@ class _DaysPickerState extends State { // // - final TextStyle disabledCellsTextStyle = - widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = - widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = - widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = - widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -374,23 +353,23 @@ class _DaysPickerState extends State { // // - final TextStyle selectedCellTextStyle = - widget.selectedCellTextStyle ?? + final TextStyle selectedCellTextStyle = widget.selectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration selectedCellDecoration = - widget.selectedCellDecoration ?? - BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); + final BoxDecoration selectedCellDecoration = widget.selectedCellDecoration ?? + BoxDecoration( + color: colorScheme.primary, + shape: BoxShape.circle, + ); // // // //! header - final leadingDateTextStyle = - widget.leadingDateTextStyle ?? + final leadingDateTextStyle = widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -403,130 +382,117 @@ class _DaysPickerState extends State { // //! splash - final splashColor = - widget.splashColor ?? + final splashColor = widget.splashColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = - widget.highlightColor ?? + final highlightColor = widget.highlightColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder( - builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: MaterialLocalizations.of(context) - .formatMonthYear(_displayedMonth!) - .replaceAll('٩', '9') - .replaceAll('٨', '8') - .replaceAll('٧', '7') - .replaceAll('٦', '6') - .replaceAll('٥', '5') - .replaceAll('٤', '4') - .replaceAll('٣', '3') - .replaceAll('٢', '2') - .replaceAll('١', '1') - .replaceAll('٠', '0'), - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); + return DeviceOrientationBuilder(builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: MaterialLocalizations.of(context) + .formatMonthYear(_displayedMonth!) + .replaceAll('٩', '9') + .replaceAll('٨', '8') + .replaceAll('٧', '7') + .replaceAll('٦', '6') + .replaceAll('٥', '5') + .replaceAll('٤', '4') + .replaceAll('٣', '3') + .replaceAll('٢', '2') + .replaceAll('١', '1') + .replaceAll('٠', '0'), + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + ), + const SizedBox(height: 10), + Expanded( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, + onPageChanged: (monthPage) { + final DateTime monthDate = DateUtils.addMonthsToMonthDate(widget.minDate, monthPage); + + setState(() { + _displayedMonth = monthDate; + }); }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, + itemBuilder: (context, index) { + final DateTime month = DateUtils.addMonthsToMonthDate(widget.minDate, index); + + return DaysView( + key: ValueKey(month), + currentDate: DateUtils.dateOnly(widget.currentDate ?? DateTime.now()), + maxDate: DateUtils.dateOnly(widget.maxDate), + minDate: DateUtils.dateOnly(widget.minDate), + displayedMonth: month, + selectedDate: _selectedDate, + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + enabledCellsTextStyle: enabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedDayDecoration: selectedCellDecoration, + selectedDayTextStyle: selectedCellTextStyle, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + disabledDayPredicate: widget.disabledDayPredicate, + onChanged: (value) { + setState(() { + _selectedDate = value; + }); + widget.onDateSelected?.call(value); + }, ); }, - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, ), - const SizedBox(height: 10), - Expanded( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: - DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, - onPageChanged: (monthPage) { - final DateTime monthDate = DateUtils.addMonthsToMonthDate( - widget.minDate, - monthPage, - ); - - setState(() { - _displayedMonth = monthDate; - }); - }, - itemBuilder: (context, index) { - final DateTime month = DateUtils.addMonthsToMonthDate( - widget.minDate, - index, - ); - - return DaysView( - key: ValueKey(month), - currentDate: DateUtils.dateOnly( - widget.currentDate ?? DateTime.now(), - ), - maxDate: DateUtils.dateOnly(widget.maxDate), - minDate: DateUtils.dateOnly(widget.minDate), - displayedMonth: month, - selectedDate: _selectedDate, - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - enabledCellsTextStyle: enabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedDayDecoration: selectedCellDecoration, - selectedDayTextStyle: selectedCellTextStyle, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - disabledDayPredicate: widget.disabledDayPredicate, - onChanged: (value) { - setState(() { - _selectedDate = value; - }); - widget.onDateSelected?.call(value); - }, - ); - }, - ), - ), - ], - ), - ); - }, - ); + ), + ], + ), + ); + }); } } diff --git a/lib/src/date/show_date_picker_dialog.dart b/lib/src/date/show_date_picker_dialog.dart index 5d21406..4e79eca 100644 --- a/lib/src/date/show_date_picker_dialog.dart +++ b/lib/src/date/show_date_picker_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../shared/device_orientation_builder.dart'; import '../shared/picker_type.dart'; import 'date_picker.dart'; @@ -81,57 +82,55 @@ Future showDatePickerDialog({ useRootNavigator: useRootNavigator, useSafeArea: useSafeArea, builder: (context) { - return DeviceOrientationBuilder( - builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 400.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return Padding( - padding: padding, - child: Dialog( - insetPadding: EdgeInsets.zero, - child: SizedBox( - width: width ?? size.width, - height: height ?? size.height, - child: DatePicker( - centerLeadingDate: centerLeadingDate, - initialDate: initialDate, - maxDate: maxDate, - minDate: minDate, - currentDate: currentDate, - selectedDate: selectedDate, - onDateSelected: (value) => Navigator.pop(context, value), - initialPickerType: initialPickerType, - padding: contentPadding, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - disabledCellsDecoration: disabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - selectedCellDecoration: selectedCellDecoration, - selectedCellTextStyle: selectedCellTextStyle, - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: splashRadius, - previousPageSemanticLabel: previousPageSemanticLabel, - nextPageSemanticLabel: nextPageSemanticLabel, - ), + return DeviceOrientationBuilder(builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 400.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return Padding( + padding: padding, + child: Dialog( + insetPadding: EdgeInsets.zero, + child: SizedBox( + width: width ?? size.width, + height: height ?? size.height, + child: DatePicker( + centerLeadingDate: centerLeadingDate, + initialDate: initialDate, + maxDate: maxDate, + minDate: minDate, + currentDate: currentDate, + selectedDate: selectedDate, + onDateSelected: (value) => Navigator.pop(context, value), + initialPickerType: initialPickerType, + padding: contentPadding, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + disabledCellsDecoration: disabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + selectedCellDecoration: selectedCellDecoration, + selectedCellTextStyle: selectedCellTextStyle, + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: splashRadius, + previousPageSemanticLabel: previousPageSemanticLabel, + nextPageSemanticLabel: nextPageSemanticLabel, ), ), - ); - }, - ); + ), + ); + }); }, ); } diff --git a/lib/src/range/range_days_picker.dart b/lib/src/range/range_days_picker.dart index 7f2c5f6..8282732 100644 --- a/lib/src/range/range_days_picker.dart +++ b/lib/src/range/range_days_picker.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../shared/device_orientation_builder.dart'; import '../shared/header.dart'; import '../shared/utils.dart'; import 'range_days_view.dart'; @@ -40,29 +41,27 @@ class RangeDaysPicker extends StatefulWidget { }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert(() { - if (initialDate == null) return true; - final init = DateTime( - initialDate!.year, - initialDate!.month, - initialDate!.day, - ); - - final min = DateTime(minDate.year, minDate.month, minDate.day); + assert( + () { + if (initialDate == null) return true; + final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), 'initialDate $initialDate must be on or after minDate $minDate.'); - assert(() { - if (initialDate == null) return true; - final init = DateTime( - initialDate!.year, - initialDate!.month, - initialDate!.day, - ); + final min = DateTime(minDate.year, minDate.month, minDate.day); - final max = DateTime(maxDate.year, maxDate.month, maxDate.day); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), + 'initialDate $initialDate must be on or after minDate $minDate.', + ); + assert( + () { + if (initialDate == null) return true; + final init = DateTime(initialDate!.year, initialDate!.month, initialDate!.day); + + final max = DateTime(maxDate.year, maxDate.month, maxDate.day); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), + 'initialDate $initialDate must be on or before maxDate $maxDate.', + ); } /// The date which will be displayed on first opening. If not specified, the picker @@ -229,14 +228,9 @@ class __RangeDaysPickerState extends State { @override void initState() { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); - _displayedMonth = DateUtils.dateOnly( - widget.initialDate ?? clampedInitailDate, - ); + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); _pageController = PageController( initialPage: DateUtils.monthDelta(widget.minDate, _displayedMonth!), ); @@ -251,14 +245,9 @@ class __RangeDaysPickerState extends State { // but for makeing debuging easy, we will navigate to the initial date again // if it changes. if (oldWidget.initialDate != widget.initialDate) { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); - _displayedMonth = DateUtils.dateOnly( - widget.initialDate ?? clampedInitailDate, - ); + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + _displayedMonth = DateUtils.dateOnly(widget.initialDate ?? clampedInitailDate); _pageController.jumpToPage( DateUtils.monthDelta(widget.minDate, _displayedMonth!), ); @@ -281,8 +270,7 @@ class __RangeDaysPickerState extends State { //! days of the week // // - final TextStyle daysOfTheWeekTextStyle = - widget.daysOfTheWeekTextStyle ?? + final TextStyle daysOfTheWeekTextStyle = widget.daysOfTheWeekTextStyle ?? textTheme.titleSmall!.copyWith( color: colorScheme.onSurface.withValues(alpha: 0.30), fontWeight: FontWeight.bold, @@ -294,8 +282,7 @@ class __RangeDaysPickerState extends State { // // - final TextStyle enabledCellsTextStyle = - widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -308,29 +295,25 @@ class __RangeDaysPickerState extends State { // // - final TextStyle disabledCellsTextStyle = - widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = - widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = - widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = - widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -341,15 +324,13 @@ class __RangeDaysPickerState extends State { // // - final TextStyle selectedCellsTextStyle = - widget.selectedCellsTextStyle ?? + final TextStyle selectedCellsTextStyle = widget.selectedCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimaryContainer, ); - final BoxDecoration selectedCellsDecoration = - widget.selectedCellsDecoration ?? + final BoxDecoration selectedCellsDecoration = widget.selectedCellsDecoration ?? BoxDecoration( color: colorScheme.primaryContainer, shape: BoxShape.rectangle, @@ -358,23 +339,23 @@ class __RangeDaysPickerState extends State { // //! single - final TextStyle singleSelectedCellTextStyle = - widget.singleSelectedCellTextStyle ?? + final TextStyle singleSelectedCellTextStyle = widget.singleSelectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration singleSelectedCellDecoration = - widget.singleSelectedCellDecoration ?? - BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); + final BoxDecoration singleSelectedCellDecoration = widget.singleSelectedCellDecoration ?? + BoxDecoration( + color: colorScheme.primary, + shape: BoxShape.circle, + ); // // // //! header - final leadingDateTextStyle = - widget.leadingDateTextStyle ?? + final leadingDateTextStyle = widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -386,135 +367,117 @@ class __RangeDaysPickerState extends State { // //! splash - final splashColor = - widget.splashColor ?? + final splashColor = widget.splashColor ?? singleSelectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = - widget.highlightColor ?? + final highlightColor = widget.highlightColor ?? singleSelectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder( - builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: MaterialLocalizations.of(context) - .formatMonthYear(_displayedMonth!) - .replaceAll('٩', '9') - .replaceAll('٨', '8') - .replaceAll('٧', '7') - .replaceAll('٦', '6') - .replaceAll('٥', '5') - .replaceAll('٤', '4') - .replaceAll('٣', '3') - .replaceAll('٢', '2') - .replaceAll('١', '1') - .replaceAll('٠', '0'), - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); + return DeviceOrientationBuilder(builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: MaterialLocalizations.of(context) + .formatMonthYear(_displayedMonth!) + .replaceAll('٩', '9') + .replaceAll('٨', '8') + .replaceAll('٧', '7') + .replaceAll('٦', '6') + .replaceAll('٥', '5') + .replaceAll('٤', '4') + .replaceAll('٣', '3') + .replaceAll('٢', '2') + .replaceAll('١', '1') + .replaceAll('٠', '0'), + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + ), + const SizedBox(height: 10), + Expanded( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, + onPageChanged: (monthPage) { + final DateTime monthDate = DateUtils.addMonthsToMonthDate(widget.minDate, monthPage); + + setState(() { + _displayedMonth = monthDate; + }); }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, + itemBuilder: (context, index) { + final DateTime month = DateUtils.addMonthsToMonthDate(widget.minDate, index); + + return RangeDaysView( + key: ValueKey(month), + currentDate: DateUtils.dateOnly(widget.currentDate ?? DateTime.now()), + minDate: DateUtils.dateOnly(widget.minDate), + maxDate: DateUtils.dateOnly(widget.maxDate), + displayedMonth: month, + selectedEndDate: + widget.selectedEndDate == null ? null : DateUtils.dateOnly(widget.selectedEndDate!), + selectedStartDate: + widget.selectedStartDate == null ? null : DateUtils.dateOnly(widget.selectedStartDate!), + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + enabledCellsTextStyle: enabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedCellsDecoration: selectedCellsDecoration, + selectedCellsTextStyle: selectedCellsTextStyle, + singleSelectedCellTextStyle: singleSelectedCellTextStyle, + singleSelectedCellDecoration: singleSelectedCellDecoration, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + onEndDateChanged: (value) => widget.onEndDateChanged?.call(value), + onStartDateChanged: (value) => widget.onStartDateChanged?.call(value), ); }, ), - const SizedBox(height: 10), - Expanded( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: - DateUtils.monthDelta(widget.minDate, widget.maxDate) + 1, - onPageChanged: (monthPage) { - final DateTime monthDate = DateUtils.addMonthsToMonthDate( - widget.minDate, - monthPage, - ); - - setState(() { - _displayedMonth = monthDate; - }); - }, - itemBuilder: (context, index) { - final DateTime month = DateUtils.addMonthsToMonthDate( - widget.minDate, - index, - ); - - return RangeDaysView( - key: ValueKey(month), - currentDate: DateUtils.dateOnly( - widget.currentDate ?? DateTime.now(), - ), - minDate: DateUtils.dateOnly(widget.minDate), - maxDate: DateUtils.dateOnly(widget.maxDate), - displayedMonth: month, - selectedEndDate: widget.selectedEndDate == null - ? null - : DateUtils.dateOnly(widget.selectedEndDate!), - selectedStartDate: widget.selectedStartDate == null - ? null - : DateUtils.dateOnly(widget.selectedStartDate!), - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - enabledCellsTextStyle: enabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedCellsDecoration: selectedCellsDecoration, - selectedCellsTextStyle: selectedCellsTextStyle, - singleSelectedCellTextStyle: singleSelectedCellTextStyle, - singleSelectedCellDecoration: - singleSelectedCellDecoration, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - onEndDateChanged: (value) => - widget.onEndDateChanged?.call(value), - onStartDateChanged: (value) => - widget.onStartDateChanged?.call(value), - ); - }, - ), - ), - ], - ), - ); - }, - ); + ), + ], + ), + ); + }); } } diff --git a/lib/src/range/show_range_picker_dialog.dart b/lib/src/range/show_range_picker_dialog.dart index cfd32af..cdd4b70 100644 --- a/lib/src/range/show_range_picker_dialog.dart +++ b/lib/src/range/show_range_picker_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../shared/device_orientation_builder.dart'; import '../shared/picker_type.dart'; import 'range_picker.dart'; @@ -82,59 +83,57 @@ Future showRangePickerDialog({ useRootNavigator: useRootNavigator, useSafeArea: useSafeArea, builder: (context) { - return DeviceOrientationBuilder( - builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 400.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return Padding( - padding: padding, - child: Dialog( - insetPadding: EdgeInsets.zero, - child: SizedBox( - width: width ?? size.width, - height: height ?? size.height, - child: RangeDatePicker( - centerLeadingDate: centerLeadingDate, - currentDate: currentDate, - maxDate: maxDate, - minDate: minDate, - initialDate: initialDate, - selectedRange: selectedRange, - onRangeSelected: (value) => Navigator.pop(context, value), - initialPickerType: initialPickerType, - padding: contentPadding, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - disabledCellsDecoration: disabledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - selectedCellsDecoration: selectedCellsDecoration, - selectedCellsTextStyle: selectedCellsTextStyle, - daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, - singleSelectedCellTextStyle: singleSelectedCellTextStyle, - singleSelectedCellDecoration: singleSelectedCellDecoration, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: splashRadius, - previousPageSemanticLabel: previousPageSemanticLabel, - nextPageSemanticLabel: nextPageSemanticLabel, - ), + return DeviceOrientationBuilder(builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 400.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return Padding( + padding: padding, + child: Dialog( + insetPadding: EdgeInsets.zero, + child: SizedBox( + width: width ?? size.width, + height: height ?? size.height, + child: RangeDatePicker( + centerLeadingDate: centerLeadingDate, + currentDate: currentDate, + maxDate: maxDate, + minDate: minDate, + initialDate: initialDate, + selectedRange: selectedRange, + onRangeSelected: (value) => Navigator.pop(context, value), + initialPickerType: initialPickerType, + padding: contentPadding, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + disabledCellsDecoration: disabledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + selectedCellsDecoration: selectedCellsDecoration, + selectedCellsTextStyle: selectedCellsTextStyle, + daysOfTheWeekTextStyle: daysOfTheWeekTextStyle, + singleSelectedCellTextStyle: singleSelectedCellTextStyle, + singleSelectedCellDecoration: singleSelectedCellDecoration, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: splashRadius, + previousPageSemanticLabel: previousPageSemanticLabel, + nextPageSemanticLabel: nextPageSemanticLabel, ), ), - ); - }, - ); + ), + ); + }); }, ); } diff --git a/lib/src/shared/device_orientation_builder.dart b/lib/src/shared/device_orientation_builder.dart new file mode 100644 index 0000000..113ef34 --- /dev/null +++ b/lib/src/shared/device_orientation_builder.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +/// Builds a widget tree that can depend on the device orientation. +class DeviceOrientationBuilder extends StatelessWidget { + /// Builds a widget tree that can depend on the device orientation. + final Widget Function(BuildContext context, Orientation orientation) builder; + + /// Builds a widget tree that can depend on the device orientation. + const DeviceOrientationBuilder({ + super.key, + required this.builder, + }); + + @override + Widget build(BuildContext context) { + final orientation = MediaQuery.orientationOf(context); + return builder(context, orientation); + } +} diff --git a/lib/src/shared/month_picker.dart b/lib/src/shared/month_picker.dart index b40043a..295ccd4 100644 --- a/lib/src/shared/month_picker.dart +++ b/lib/src/shared/month_picker.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import 'device_orientation_builder.dart'; import 'header.dart'; import 'month_view.dart'; import 'utils.dart'; @@ -73,21 +74,27 @@ class MonthPicker extends StatefulWidget { }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert(() { - if (initialDate == null) return true; - final init = DateUtilsX.monthOnly(initialDate!); + assert( + () { + if (initialDate == null) return true; + final init = DateUtilsX.monthOnly(initialDate!); - final min = DateUtilsX.monthOnly(minDate); + final min = DateUtilsX.monthOnly(minDate); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), 'initialDate $initialDate must be on or after minDate $minDate.'); - assert(() { - if (initialDate == null) return true; - final init = DateUtilsX.monthOnly(initialDate!); - - final max = DateUtilsX.monthOnly(maxDate); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), + 'initialDate $initialDate must be on or after minDate $minDate.', + ); + assert( + () { + if (initialDate == null) return true; + final init = DateUtilsX.monthOnly(initialDate!); + + final max = DateUtilsX.monthOnly(maxDate); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), + 'initialDate $initialDate must be on or before maxDate $maxDate.', + ); } /// The date which will be displayed on first opening. If not specified, the picker @@ -234,18 +241,11 @@ class _MonthPickerState extends State { @override void initState() { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); - _displayedYear = DateUtilsX.yearOnly( - widget.initialDate ?? clampedInitailDate, - ); + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + _displayedYear = DateUtilsX.yearOnly(widget.initialDate ?? clampedInitailDate); - _selectedDate = widget.selectedDate != null - ? DateUtilsX.monthOnly(widget.selectedDate!) - : null; + _selectedDate = widget.selectedDate != null ? DateUtilsX.monthOnly(widget.selectedDate!) : null; _pageController = PageController( initialPage: (_displayedYear!.year - widget.minDate.year), ); @@ -259,21 +259,14 @@ class _MonthPickerState extends State { // but for makeing debuging easy, we will navigate to the initial date again // if it changes. if (oldWidget.initialDate != widget.initialDate) { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); - _displayedYear = DateUtilsX.yearOnly( - widget.initialDate ?? clampedInitailDate, - ); + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); + _displayedYear = DateUtilsX.yearOnly(widget.initialDate ?? clampedInitailDate); _pageController.jumpToPage(_displayedYear!.year - widget.minDate.year); } if (oldWidget.selectedDate != _selectedDate) { - _selectedDate = widget.selectedDate != null - ? DateUtilsX.monthOnly(widget.selectedDate!) - : null; + _selectedDate = widget.selectedDate != null ? DateUtilsX.monthOnly(widget.selectedDate!) : null; } super.didUpdateWidget(oldWidget); } @@ -294,8 +287,7 @@ class _MonthPickerState extends State { // // - final TextStyle enabledCellsTextStyle = - widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -308,30 +300,26 @@ class _MonthPickerState extends State { // // - final TextStyle disabledCellsTextStyle = - widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = - widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = - widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = - widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -342,148 +330,143 @@ class _MonthPickerState extends State { // // - final TextStyle selectedCellTextStyle = - widget.selectedCellTextStyle ?? + final TextStyle selectedCellTextStyle = widget.selectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration selectedCellDecoration = - widget.selectedCellDecoration ?? - BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); + final BoxDecoration selectedCellDecoration = widget.selectedCellDecoration ?? + BoxDecoration( + color: colorScheme.primary, + shape: BoxShape.circle, + ); // // // //! header - final leadingDateTextStyle = - widget.leadingDateTextStyle ?? + final leadingDateTextStyle = widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ); - final slidersColor = - widget.slidersColor ?? Theme.of(context).colorScheme.primary; + final slidersColor = widget.slidersColor ?? Theme.of(context).colorScheme.primary; final slidersSize = widget.slidersSize ?? 20; // //! splash - final splashColor = - widget.splashColor ?? + final splashColor = widget.splashColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = - widget.highlightColor ?? + final highlightColor = widget.highlightColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder( - builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: _displayedYear!.year.toString(), - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, + return DeviceOrientationBuilder(builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: _displayedYear!.year.toString(), + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + ), + const SizedBox(height: 10), + Expanded( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: yearsCount, + onPageChanged: (yearPage) { + final DateTime year = DateTime( + widget.minDate.year + yearPage, + // widget.minDate.month, + // widget.minDate.day, ); + + setState(() { + _displayedYear = year; + }); }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, + itemBuilder: (context, index) { + final DateTime year = DateTime( + widget.minDate.year + index, + // widget.minDate.month, + // widget.minDate.day, + ); + + return MonthView( + key: ValueKey(year), + currentDate: widget.currentDate != null + ? DateUtilsX.monthOnly(widget.currentDate!) + : DateUtilsX.monthOnly(DateTime.now()), + maxDate: DateUtilsX.monthOnly(widget.maxDate), + minDate: DateUtilsX.monthOnly(widget.minDate), + displayedDate: year, + selectedDate: _selectedDate, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedCellDecoration: selectedCellDecoration, + selectedCellTextStyle: selectedCellTextStyle, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + onChanged: (value) { + final selected = DateUtilsX.monthOnly(value); + widget.onDateSelected?.call(selected); + setState(() { + _selectedDate = selected; + }); + }, ); }, ), - const SizedBox(height: 10), - Expanded( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: yearsCount, - onPageChanged: (yearPage) { - final DateTime year = DateTime( - widget.minDate.year + yearPage, - // widget.minDate.month, - // widget.minDate.day, - ); - - setState(() { - _displayedYear = year; - }); - }, - itemBuilder: (context, index) { - final DateTime year = DateTime( - widget.minDate.year + index, - // widget.minDate.month, - // widget.minDate.day, - ); - - return MonthView( - key: ValueKey(year), - currentDate: widget.currentDate != null - ? DateUtilsX.monthOnly(widget.currentDate!) - : DateUtilsX.monthOnly(DateTime.now()), - maxDate: DateUtilsX.monthOnly(widget.maxDate), - minDate: DateUtilsX.monthOnly(widget.minDate), - displayedDate: year, - selectedDate: _selectedDate, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedCellDecoration: selectedCellDecoration, - selectedCellTextStyle: selectedCellTextStyle, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - onChanged: (value) { - final selected = DateUtilsX.monthOnly(value); - widget.onDateSelected?.call(selected); - setState(() { - _selectedDate = selected; - }); - }, - ); - }, - ), - ), - ], - ), - ); - }, - ); + ), + ], + ), + ); + }); } } diff --git a/lib/src/shared/year_picker.dart b/lib/src/shared/year_picker.dart index a7e34a7..90196b9 100644 --- a/lib/src/shared/year_picker.dart +++ b/lib/src/shared/year_picker.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import 'device_orientation_builder.dart'; import 'header.dart'; import '../date/show_date_picker_dialog.dart'; import 'utils.dart'; @@ -71,21 +72,27 @@ class YearsPicker extends StatefulWidget { }) { assert(!minDate.isAfter(maxDate), "minDate can't be after maxDate"); - assert(() { - if (initialDate == null) return true; - final init = DateUtilsX.yearOnly(initialDate!); + assert( + () { + if (initialDate == null) return true; + final init = DateUtilsX.yearOnly(initialDate!); - final min = DateUtilsX.yearOnly(minDate); + final min = DateUtilsX.yearOnly(minDate); - return init.isAfter(min) || init.isAtSameMomentAs(min); - }(), 'initialDate $initialDate must be on or after minDate $minDate.'); - assert(() { - if (initialDate == null) return true; - final init = DateUtilsX.yearOnly(initialDate!); - - final max = DateUtilsX.yearOnly(maxDate); - return init.isBefore(max) || init.isAtSameMomentAs(max); - }(), 'initialDate $initialDate must be on or before maxDate $maxDate.'); + return init.isAfter(min) || init.isAtSameMomentAs(min); + }(), + 'initialDate $initialDate must be on or after minDate $minDate.', + ); + assert( + () { + if (initialDate == null) return true; + final init = DateUtilsX.yearOnly(initialDate!); + + final max = DateUtilsX.yearOnly(maxDate); + return init.isBefore(max) || init.isAtSameMomentAs(max); + }(), + 'initialDate $initialDate must be on or before maxDate $maxDate.', + ); } /// The date which will be displayed on first opening. If not specified, the picker @@ -236,9 +243,7 @@ class _YearsPickerState extends State { start: DateTime(widget.minDate.year + initialPageNumber * 12), end: DateTime(widget.minDate.year + initialPageNumber * 12 - 1 + 12), ); - _selectedDate = widget.selectedDate != null - ? DateUtilsX.yearOnly(widget.selectedDate!) - : null; + _selectedDate = widget.selectedDate != null ? DateUtilsX.yearOnly(widget.selectedDate!) : null; super.initState(); } @@ -256,9 +261,7 @@ class _YearsPickerState extends State { } if (oldWidget.selectedDate != widget.selectedDate) { - _selectedDate = widget.selectedDate != null - ? DateUtilsX.yearOnly(widget.selectedDate!) - : null; + _selectedDate = widget.selectedDate != null ? DateUtilsX.yearOnly(widget.selectedDate!) : null; } super.didUpdateWidget(oldWidget); @@ -274,15 +277,11 @@ class _YearsPickerState extends State { /// between [minDate] and [maxDate]. /// /// Each page will contains 12 years in a 3 x 4 grid. - int get pageCount => - ((widget.maxDate.year - widget.minDate.year + 1) / 12).ceil(); + int get pageCount => ((widget.maxDate.year - widget.minDate.year + 1) / 12).ceil(); int get initialPageNumber { - final clampedInitailDate = DateUtilsX.clampDateToRange( - max: widget.maxDate, - min: widget.minDate, - date: DateTime.now(), - ); + final clampedInitailDate = + DateUtilsX.clampDateToRange(max: widget.maxDate, min: widget.minDate, date: DateTime.now()); final init = widget.initialDate ?? clampedInitailDate; final page = ((init.year - widget.minDate.year + 1) / 12).ceil() - 1; @@ -307,8 +306,7 @@ class _YearsPickerState extends State { // // - final TextStyle enabledCellsTextStyle = - widget.enabledCellsTextStyle ?? + final TextStyle enabledCellsTextStyle = widget.enabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface, @@ -321,30 +319,26 @@ class _YearsPickerState extends State { // // - final TextStyle disabledCellsTextStyle = - widget.disabledCellsTextStyle ?? + final TextStyle disabledCellsTextStyle = widget.disabledCellsTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onSurface.withValues(alpha: 0.30), ); - final BoxDecoration disbaledCellsDecoration = - widget.disabledCellsDecoration; + final BoxDecoration disbaledCellsDecoration = widget.disabledCellsDecoration; // //! current // // - final TextStyle currentDateTextStyle = - widget.currentDateTextStyle ?? + final TextStyle currentDateTextStyle = widget.currentDateTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.primary, ); - final BoxDecoration currentDateDecoration = - widget.currentDateDecoration ?? + final BoxDecoration currentDateDecoration = widget.currentDateDecoration ?? BoxDecoration( border: Border.all(color: colorScheme.primary), shape: BoxShape.circle, @@ -355,139 +349,133 @@ class _YearsPickerState extends State { // // - final TextStyle selectedCellTextStyle = - widget.selectedCellTextStyle ?? + final TextStyle selectedCellTextStyle = widget.selectedCellTextStyle ?? textTheme.titleLarge!.copyWith( fontWeight: FontWeight.normal, color: colorScheme.onPrimary, ); - final BoxDecoration selectedCellDecoration = - widget.selectedCellDecoration ?? - BoxDecoration(color: colorScheme.primary, shape: BoxShape.circle); + final BoxDecoration selectedCellDecoration = widget.selectedCellDecoration ?? + BoxDecoration( + color: colorScheme.primary, + shape: BoxShape.circle, + ); // // // //! header - final leadingDateTextStyle = - widget.leadingDateTextStyle ?? + final leadingDateTextStyle = widget.leadingDateTextStyle ?? TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ); - final slidersColor = - widget.slidersColor ?? Theme.of(context).colorScheme.primary; + final slidersColor = widget.slidersColor ?? Theme.of(context).colorScheme.primary; final slidersSize = widget.slidersSize ?? 20; // //! splash - final splashColor = - widget.splashColor ?? + final splashColor = widget.splashColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); - final highlightColor = - widget.highlightColor ?? + final highlightColor = widget.highlightColor ?? selectedCellDecoration.color?.withValues(alpha: 0.3) ?? colorScheme.primary.withValues(alpha: 0.3); // // - return DeviceOrientationBuilder( - builder: (context, o) { - late final Size size; - switch (o) { - case Orientation.portrait: - size = const Size(328.0, 402.0); - break; - case Orientation.landscape: - size = const Size(328.0, 300.0); - break; - } - return LimitedBox( - maxHeight: size.height, - maxWidth: size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Header( - previousPageSemanticLabel: widget.previousPageSemanticLabel, - nextPageSemanticLabel: widget.nextPageSemanticLabel, - centerLeadingDate: widget.centerLeadingDate, - leadingDateTextStyle: leadingDateTextStyle, - slidersColor: slidersColor, - slidersSize: slidersSize, - onDateTap: () => widget.onLeadingDateTap?.call(), - displayedDate: - '${_displayedRange?.start.year} - ${_displayedRange?.end.year}', - onNextPage: () { - _pageController.nextPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, - ); + return DeviceOrientationBuilder(builder: (context, o) { + late final Size size; + switch (o) { + case Orientation.portrait: + size = const Size(328.0, 402.0); + break; + case Orientation.landscape: + size = const Size(328.0, 300.0); + break; + } + return LimitedBox( + maxHeight: size.height, + maxWidth: size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Header( + previousPageSemanticLabel: widget.previousPageSemanticLabel, + nextPageSemanticLabel: widget.nextPageSemanticLabel, + centerLeadingDate: widget.centerLeadingDate, + leadingDateTextStyle: leadingDateTextStyle, + slidersColor: slidersColor, + slidersSize: slidersSize, + onDateTap: () => widget.onLeadingDateTap?.call(), + displayedDate: '${_displayedRange?.start.year} - ${_displayedRange?.end.year}', + onNextPage: () { + _pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + onPreviousPage: () { + _pageController.previousPage( + duration: const Duration(milliseconds: 300), + curve: Curves.ease, + ); + }, + ), + const SizedBox(height: 10), + Flexible( + child: PageView.builder( + scrollDirection: Axis.horizontal, + key: _pageViewKey, + controller: _pageController, + itemCount: pageCount, + onPageChanged: (yearPage) { + setState(() { + _displayedRange = calculateDateRange(yearPage); + }); }, - onPreviousPage: () { - _pageController.previousPage( - duration: const Duration(milliseconds: 300), - curve: Curves.ease, + itemBuilder: (context, index) { + final yearRange = calculateDateRange(index); + + return YearView( + key: ValueKey(yearRange), + currentDate: widget.currentDate != null + ? DateUtilsX.yearOnly(widget.currentDate!) + : DateUtilsX.yearOnly(DateTime.now()), + maxDate: DateUtilsX.yearOnly(widget.maxDate), + minDate: DateUtilsX.yearOnly(widget.minDate), + displayedYearRange: yearRange, + selectedDate: _selectedDate, + enabledCellsDecoration: enabledCellsDecoration, + enabledCellsTextStyle: enabledCellsTextStyle, + disabledCellsDecoration: disbaledCellsDecoration, + disabledCellsTextStyle: disabledCellsTextStyle, + currentDateDecoration: currentDateDecoration, + currentDateTextStyle: currentDateTextStyle, + selectedCellDecoration: selectedCellDecoration, + selectedCellTextStyle: selectedCellTextStyle, + highlightColor: highlightColor, + splashColor: splashColor, + splashRadius: widget.splashRadius, + onChanged: (value) { + final selected = DateUtilsX.yearOnly(value); + widget.onDateSelected?.call(selected); + setState(() { + _selectedDate = selected; + }); + }, ); }, ), - const SizedBox(height: 10), - Flexible( - child: PageView.builder( - scrollDirection: Axis.horizontal, - key: _pageViewKey, - controller: _pageController, - itemCount: pageCount, - onPageChanged: (yearPage) { - setState(() { - _displayedRange = calculateDateRange(yearPage); - }); - }, - itemBuilder: (context, index) { - final yearRange = calculateDateRange(index); - - return YearView( - key: ValueKey(yearRange), - currentDate: widget.currentDate != null - ? DateUtilsX.yearOnly(widget.currentDate!) - : DateUtilsX.yearOnly(DateTime.now()), - maxDate: DateUtilsX.yearOnly(widget.maxDate), - minDate: DateUtilsX.yearOnly(widget.minDate), - displayedYearRange: yearRange, - selectedDate: _selectedDate, - enabledCellsDecoration: enabledCellsDecoration, - enabledCellsTextStyle: enabledCellsTextStyle, - disabledCellsDecoration: disbaledCellsDecoration, - disabledCellsTextStyle: disabledCellsTextStyle, - currentDateDecoration: currentDateDecoration, - currentDateTextStyle: currentDateTextStyle, - selectedCellDecoration: selectedCellDecoration, - selectedCellTextStyle: selectedCellTextStyle, - highlightColor: highlightColor, - splashColor: splashColor, - splashRadius: widget.splashRadius, - onChanged: (value) { - final selected = DateUtilsX.yearOnly(value); - widget.onDateSelected?.call(selected); - setState(() { - _selectedDate = selected; - }); - }, - ); - }, - ), - ), - ], - ), - ); - }, - ); + ), + ], + ), + ); + }); } } From 4f44558151e1f8d56980574c4c27e310d36d7051 Mon Sep 17 00:00:00 2001 From: Alzalia Date: Thu, 12 Feb 2026 13:26:08 +0100 Subject: [PATCH 3/3] fix: removed DeviceOrientationBuilder to prevent collision with Flutter's native implementation --- lib/src/date/days_picker.dart | 1 - lib/src/date/show_date_picker_dialog.dart | 1 - lib/src/range/range_days_picker.dart | 1 - lib/src/range/show_range_picker_dialog.dart | 1 - .../shared/device_orientation_builder.dart | 19 ------------------- lib/src/shared/month_picker.dart | 1 - lib/src/shared/year_picker.dart | 1 - 7 files changed, 25 deletions(-) delete mode 100644 lib/src/shared/device_orientation_builder.dart diff --git a/lib/src/date/days_picker.dart b/lib/src/date/days_picker.dart index 20521d1..07f1548 100644 --- a/lib/src/date/days_picker.dart +++ b/lib/src/date/days_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/types.dart'; import '../shared/utils.dart'; import 'days_view.dart'; diff --git a/lib/src/date/show_date_picker_dialog.dart b/lib/src/date/show_date_picker_dialog.dart index 4e79eca..80b7e3d 100644 --- a/lib/src/date/show_date_picker_dialog.dart +++ b/lib/src/date/show_date_picker_dialog.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/picker_type.dart'; import 'date_picker.dart'; diff --git a/lib/src/range/range_days_picker.dart b/lib/src/range/range_days_picker.dart index 8282732..32d97f4 100644 --- a/lib/src/range/range_days_picker.dart +++ b/lib/src/range/range_days_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/header.dart'; import '../shared/utils.dart'; import 'range_days_view.dart'; diff --git a/lib/src/range/show_range_picker_dialog.dart b/lib/src/range/show_range_picker_dialog.dart index cdd4b70..5650857 100644 --- a/lib/src/range/show_range_picker_dialog.dart +++ b/lib/src/range/show_range_picker_dialog.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import '../shared/device_orientation_builder.dart'; import '../shared/picker_type.dart'; import 'range_picker.dart'; diff --git a/lib/src/shared/device_orientation_builder.dart b/lib/src/shared/device_orientation_builder.dart deleted file mode 100644 index 113ef34..0000000 --- a/lib/src/shared/device_orientation_builder.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Builds a widget tree that can depend on the device orientation. -class DeviceOrientationBuilder extends StatelessWidget { - /// Builds a widget tree that can depend on the device orientation. - final Widget Function(BuildContext context, Orientation orientation) builder; - - /// Builds a widget tree that can depend on the device orientation. - const DeviceOrientationBuilder({ - super.key, - required this.builder, - }); - - @override - Widget build(BuildContext context) { - final orientation = MediaQuery.orientationOf(context); - return builder(context, orientation); - } -} diff --git a/lib/src/shared/month_picker.dart b/lib/src/shared/month_picker.dart index 295ccd4..6506fe8 100644 --- a/lib/src/shared/month_picker.dart +++ b/lib/src/shared/month_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'device_orientation_builder.dart'; import 'header.dart'; import 'month_view.dart'; import 'utils.dart'; diff --git a/lib/src/shared/year_picker.dart b/lib/src/shared/year_picker.dart index 90196b9..6c4ad3d 100644 --- a/lib/src/shared/year_picker.dart +++ b/lib/src/shared/year_picker.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'device_orientation_builder.dart'; import 'header.dart'; import '../date/show_date_picker_dialog.dart'; import 'utils.dart';