From 2b0248b996b5f543f394249dee008b1ce961f3b3 Mon Sep 17 00:00:00 2001 From: Freek van de Ven Date: Fri, 12 Jul 2024 13:26:22 +0200 Subject: [PATCH] feat: update calendar drawing with 2 different modes --- .../lib/src/config/availability_options.dart | 13 ++ .../lib/src/ui/widgets/calendar_grid.dart | 112 ++++++++++++------ packages/flutter_availability/pubspec.yaml | 1 + 3 files changed, 92 insertions(+), 34 deletions(-) diff --git a/packages/flutter_availability/lib/src/config/availability_options.dart b/packages/flutter_availability/lib/src/config/availability_options.dart index 9135eba..0f9b1f8 100644 --- a/packages/flutter_availability/lib/src/config/availability_options.dart +++ b/packages/flutter_availability/lib/src/config/availability_options.dart @@ -13,6 +13,7 @@ class AvailabilityOptions { /// AvailabilityOptions constructor where everything is optional. AvailabilityOptions({ this.translations = const AvailabilityTranslations.empty(), + this.calendarDrawMode = CalendarDrawMode.background, this.baseScreenBuilder = DefaultBaseScreen.builder, this.primaryButtonBuilder = DefaultPrimaryButton.builder, this.secondaryButtonBuilder = DefaultSecondaryButton.builder, @@ -34,6 +35,9 @@ class AvailabilityOptions { /// The implementation for communicating with the persistance layer final AvailabilityDataInterface dataInterface; + /// The draw mode for the calendar cells + final CalendarDrawMode calendarDrawMode; + /// A method to wrap your availability screens with a base frame. /// /// If you provide a screen here make sure to use a [Scaffold], as some @@ -163,6 +167,15 @@ class AvailabilityColors { final List templateColors; } +/// The draw mode for the calendar cells +enum CalendarDrawMode { + /// The cell is drawn without a background but with a line under the text + underlined, + + /// The cell is drawn with a background color + background, +} + /// Builder definition for providing a base screen surrounding each page typedef BaseScreenBuilder = Widget Function( BuildContext context, diff --git a/packages/flutter_availability/lib/src/ui/widgets/calendar_grid.dart b/packages/flutter_availability/lib/src/ui/widgets/calendar_grid.dart index 23f7e4c..cb1c938 100644 --- a/packages/flutter_availability/lib/src/ui/widgets/calendar_grid.dart +++ b/packages/flutter_availability/lib/src/ui/widgets/calendar_grid.dart @@ -74,43 +74,11 @@ class CalendarGrid extends StatelessWidget { ), itemBuilder: (context, index) { var day = calendarDays[index]; - var dayColor = day.color ?? - colors.customAvailabilityColor ?? - colorScheme.secondary; - var textColor = day.outsideMonth && !day.isSelected - ? colors.outsideMonthTextColor ?? colorScheme.onSurface - : _getTextColor( - dayColor, - colors.textLightColor ?? Colors.white, - colors.textDarkColor, - ); - var textStyle = textTheme.bodyLarge?.copyWith(color: textColor); return GestureDetector( onTap: () => onDayTap(day.date), - child: DecoratedBox( - decoration: BoxDecoration( - color: dayColor, - borderRadius: BorderRadius.circular(5), - border: Border.all( - color: day.isSelected && !day.outsideMonth - ? colorScheme.primary - : Colors.transparent, - ), - ), - child: Stack( - children: [ - Center( - child: Text(day.date.day.toString(), style: textStyle), - ), - if (day.templateDeviation) ...[ - Positioned( - right: 4, - child: Text("*", style: textStyle), - ), - ], - ], - ), + child: _CalendarGridCell( + day: day, ), ); }, @@ -120,6 +88,78 @@ class CalendarGrid extends StatelessWidget { } } +class _CalendarGridCell extends StatelessWidget { + const _CalendarGridCell({ + required this.day, + }); + + final CalendarDay day; + + @override + Widget build(BuildContext context) { + var theme = Theme.of(context); + var textTheme = theme.textTheme; + var colorScheme = theme.colorScheme; + var availabilityScope = AvailabilityScope.of(context); + var options = availabilityScope.options; + var colors = options.colors; + + var backgroundDrawMode = + options.calendarDrawMode == CalendarDrawMode.background; + + var dayColor = day.color ?? Colors.transparent; + var textColor = day.outsideMonth && !day.isSelected + ? colors.outsideMonthTextColor ?? colorScheme.onSurface + : (backgroundDrawMode + ? _getTextColor( + dayColor, + colors.textLightColor ?? Colors.white, + colors.textDarkColor, + ) + : day.color); + var textStyle = textTheme.bodyLarge?.copyWith(color: textColor); + + return DecoratedBox( + decoration: BoxDecoration( + color: backgroundDrawMode ? dayColor : null, + borderRadius: BorderRadius.circular(5), + border: Border.all( + color: day.isSelected && !day.outsideMonth + ? colorScheme.primary + : Colors.transparent, + ), + ), + child: Stack( + children: [ + Center( + child: Container( + margin: const EdgeInsets.all(4), + // add a border at the bottom of the text + decoration: backgroundDrawMode || day.outsideMonth + ? null + : BoxDecoration( + border: Border( + bottom: BorderSide( + color: textColor ?? Colors.transparent, + width: 1, + ), + ), + ), + child: Text(day.date.day.toString(), style: textStyle), + ), + ), + if (day.templateDeviation) ...[ + Positioned( + right: 4, + child: Text("*", style: textStyle), + ), + ], + ], + ), + ); + } +} + /// A Special day in the calendar that needs to be displayed differently class CalendarDay { /// @@ -129,6 +169,7 @@ class CalendarDay { required this.color, required this.templateDeviation, this.outsideMonth = false, + this.hasAvailability = false, }); /// The date of the day @@ -141,6 +182,9 @@ class CalendarDay { /// If there is no template for an availability the color will be null final Color? color; + /// Whether there is an availability on this day + final bool hasAvailability; + /// Whether there is an availability on this day and it deviates from the /// used template final bool templateDeviation; diff --git a/packages/flutter_availability/pubspec.yaml b/packages/flutter_availability/pubspec.yaml index 1ea056c..c12796d 100644 --- a/packages/flutter_availability/pubspec.yaml +++ b/packages/flutter_availability/pubspec.yaml @@ -16,6 +16,7 @@ dependencies: git: url: https://github.com/Iconica-Development/flutter_availability ref: 1.0.0 + collection: ^1.18.0 dev_dependencies: flutter_test: