diff --git a/CHANGELOG.md b/CHANGELOG.md
index 982d4db6..79c4f4e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
# [1.4.1 - Unreleased]
- Adds clear method to `EventController`.
+- Adds support for dark theme. [#263](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/263)
# [1.4.0 - 7 Jan 2025](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.4.0)
diff --git a/README.md b/README.md
index 4984a0ee..c74d84f2 100644
--- a/README.md
+++ b/README.md
@@ -355,6 +355,46 @@ WeekView(
Above code will create `WeekView` with only five days, from monday to friday.
+## **Customise theme**
+* The default theme includes support for dark mode.
+* For detailed instructions on how to override the default colors please refer to [this](doc/theme_guide.md) guide.
+
+### Day view
+* Default timeline text color is `colorScheme.onSurface`.
+* Default hour, half hour & quarter color is `colorScheme.surfaceContainerHighest`.
+* Default timeline color `colorScheme.primaryColorLight`.
+
+Default hour indicator settings.
+```dart
+ HourIndicatorSettings(
+ height: widget.heightPerMinute,
+ // Color of horizontal and vertical lines
+ color: Theme.of(context).colorScheme.surfaceContainerHighest,
+ offset: 5,
+ );
+```
+
+### Week view
+* Week-number text color - Default color `onSecondaryContainer`.
+* To customise week number & weekdays use `weekNumberBuilder` & `weekDayBuilder`.
+* Default week tile color is `colorScheme.surfaceContainerHigh`.
+* To give background color use `backgroundColor` Default background color is `colorScheme.surfaceContainerLowest`.
+* To customise timeline use `timeLineBuilder`. Default text color is `colorScheme.onSurface`.
+* To change Hour lines color use `HourIndicatorSettings`.
+* To style hours, half hours & quarter hours use `HourIndicatorSettings`. Default color used is `surfaceContainerHighest`
+
+```dart
+ hourIndicatorSettings: HourIndicatorSettings(
+ color: Colors.greenAccent,
+ lineStyle: LineStyle.dashed,
+ ),
+ showHalfHours: true,
+ halfHourIndicatorSettings: HourIndicatorSettings(
+ color: Colors.redAccent,
+ lineStyle: LineStyle.dashed,
+ ),
+```
+
## Main Contributors
diff --git a/doc/theme_guide.md b/doc/theme_guide.md
new file mode 100644
index 00000000..21a3d7ec
--- /dev/null
+++ b/doc/theme_guide.md
@@ -0,0 +1,66 @@
+## **Customise theme**
+The default theme supports dark mode. Refer this colors to override it.
+
+| Name | Parameter | Default color |
+|-----------------------------------------------|------------------------|-------------------------------------|
+| `MonthView` Border color | Color? borderColor | colorScheme.surfaceContainerHigh |
+| `WeekView` Background color of week view page | Color? backgroundColor | colorScheme.surfaceContainerLowest |
+| `DayView` Default background color | Color? backgroundColor | colorScheme.surfaceContainerLow |
+| `FilledCell` Dates in month cell color | Color? backgroundColor | colorScheme.surfaceContainerLowest |
+| `FilledCell` Dates not in month cell color | Color? backgroundColor | colorScheme.surfaceContainerLow |
+| `WeekDayTile` Border color | Color? borderColor | colorScheme.secondaryContainer |
+| `WeekDayTile` Background color | Color? backgroundColor | colorScheme.surfaceContainerHigh |
+| `WeekDayTile` Text style color | TextStyle? textStyle | colorScheme.onSecondaryContainer |
+
+To customise `MonthView`, `DayView` & `WeekView` page header use `HeaderStyle`.
+
+```dart
+ headerStyle: HeaderStyle(
+ leftIconConfig: IconDataConfig(color: Colors.red),
+ rightIconConfig: IconDataConfig(color: Colors.red),
+ decoration: BoxDecoration(
+ color: Theme.of(context).highlightColor,
+ ),
+ ),
+```
+
+### Day view
+* Default timeline text color is `colorScheme.onSurface`.
+ * Use `markingStyle` in `DefaultTimeLineMark` to give text style.
+* Default `LiveTimeIndicatorSettings` color `colorScheme.primaryColorLight`.
+ * Use `liveTimeIndicatorSettings` to customise it.
+* Default hour, half hour & quarter color is `colorScheme.surfaceContainerHighest`.
+ * Use `hourIndicatorSettings` to customise it.
+
+Default hour indicator settings.
+```dart
+ HourIndicatorSettings(
+ height: widget.heightPerMinute,
+ // Color of horizontal and vertical lines
+ color: Theme.of(context).colorScheme.surfaceContainerHighest,
+ offset: 5,
+ );
+```
+
+### Week view
+* To customise week number & weekdays use `weekNumberBuilder` & `weekDayBuilder`.
+* Default week tile background color is `colorScheme.surfaceContainerHigh`.
+ * Use `weekTitleBackgroundColor` to change background color.
+* Default page background color is `colorScheme.surfaceContainerLowest`.
+ * Use `backgroundColor` to change background color.
+* Default timeline text color is `colorScheme.onSurface`. Use `markingStyle` in `DefaultTimeLineMark` to give text style.
+ * To customise timeline use `timeLineBuilder`.
+* To change Hour lines color use `HourIndicatorSettings`.
+* To style hours, half hours & quarter hours use `HourIndicatorSettings`. Default color used is `surfaceContainerHighest`
+
+```dart
+ hourIndicatorSettings: HourIndicatorSettings(
+ color: Colors.greenAccent,
+ lineStyle: LineStyle.dashed,
+ ),
+ showHalfHours: true,
+ halfHourIndicatorSettings: HourIndicatorSettings(
+ color: Colors.redAccent,
+ lineStyle: LineStyle.dashed,
+ ),
+```
diff --git a/example/lib/constants.dart b/example/lib/constants.dart
index 21da78d8..a305b1ad 100644
--- a/example/lib/constants.dart
+++ b/example/lib/constants.dart
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
-import 'app_colors.dart';
+import 'theme/app_colors.dart';
class AppConstants {
AppConstants._();
@@ -11,7 +11,7 @@ class AppConstants {
borderRadius: BorderRadius.circular(7),
borderSide: BorderSide(
width: 2,
- color: AppColors.lightNavyBlue,
+ color: AppColors.outlineVariant,
),
);
diff --git a/example/lib/extension.dart b/example/lib/extension.dart
index f70df402..ca795552 100644
--- a/example/lib/extension.dart
+++ b/example/lib/extension.dart
@@ -1,8 +1,9 @@
+import 'package:example/theme/app_theme_extension.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
-import 'app_colors.dart';
import 'enumerations.dart';
+import 'theme/app_colors.dart';
enum TimeStampFormat { parse_12, parse_24 }
@@ -128,3 +129,9 @@ extension StringExt on String {
extension ViewNameExt on CalendarView {
String get name => toString().split(".").last;
}
+
+extension BuildContextExtension on BuildContext {
+ AppThemeExtension get appColors =>
+ Theme.of(this).extension() ??
+ AppThemeExtension.light();
+}
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 1bb7d9da..4aa29ff0 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,6 +1,7 @@
import 'dart:ui';
import 'package:calendar_view/calendar_view.dart';
+import 'package:example/theme/app_theme.dart';
import 'package:flutter/material.dart';
import 'pages/home_page.dart';
@@ -11,7 +12,14 @@ void main() {
runApp(MyApp());
}
-class MyApp extends StatelessWidget {
+class MyApp extends StatefulWidget {
+ @override
+ State createState() => _MyAppState();
+}
+
+class _MyAppState extends State {
+ bool isDarkMode = false;
+
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
@@ -20,7 +28,9 @@ class MyApp extends StatelessWidget {
child: MaterialApp(
title: 'Flutter Calendar Page Demo',
debugShowCheckedModeBanner: false,
- theme: ThemeData.light(),
+ theme: AppTheme.light,
+ darkTheme: AppTheme.dark,
+ themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
scrollBehavior: ScrollBehavior().copyWith(
dragDevices: {
PointerDeviceKind.trackpad,
@@ -28,7 +38,9 @@ class MyApp extends StatelessWidget {
PointerDeviceKind.touch,
},
),
- home: HomePage(),
+ home: HomePage(
+ onChangeTheme: (isDark) => setState(() => isDarkMode = isDark),
+ ),
),
);
}
diff --git a/example/lib/pages/create_event_page.dart b/example/lib/pages/create_event_page.dart
index 3b8e2499..9b5ba021 100644
--- a/example/lib/pages/create_event_page.dart
+++ b/example/lib/pages/create_event_page.dart
@@ -1,7 +1,6 @@
import 'package:calendar_view/calendar_view.dart';
import 'package:flutter/material.dart';
-import '../app_colors.dart';
import '../extension.dart';
import '../widgets/add_event_form.dart';
@@ -12,22 +11,23 @@ class CreateEventPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final themeColor = context.appColors;
+
return Scaffold(
appBar: AppBar(
elevation: 0,
- backgroundColor: Theme.of(context).scaffoldBackgroundColor,
centerTitle: false,
leading: IconButton(
onPressed: context.pop,
icon: Icon(
Icons.arrow_back,
- color: AppColors.black,
+ color: themeColor.onPrimary,
),
),
title: Text(
event == null ? "Create New Event" : "Update Event",
style: TextStyle(
- color: AppColors.black,
+ color: themeColor.onPrimary,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
diff --git a/example/lib/pages/day_view_page.dart b/example/lib/pages/day_view_page.dart
index 1a80aba2..b2269bac 100644
--- a/example/lib/pages/day_view_page.dart
+++ b/example/lib/pages/day_view_page.dart
@@ -17,13 +17,22 @@ class DayViewPageDemo extends StatefulWidget {
class _DayViewPageDemoState extends State {
@override
Widget build(BuildContext context) {
+ final appColors = context.appColors;
+
return ResponsiveWidget(
webWidget: WebHomePage(
selectedView: CalendarView.day,
),
mobileWidget: Scaffold(
+ primary: false,
+ appBar: AppBar(
+ leading: const SizedBox.shrink(),
+ ),
floatingActionButton: FloatingActionButton(
- child: Icon(Icons.add),
+ child: Icon(
+ Icons.add,
+ color: appColors.onPrimary,
+ ),
elevation: 8,
onPressed: () => context.pushRoute(CreateEventPage()),
),
diff --git a/example/lib/pages/event_details_page.dart b/example/lib/pages/event_details_page.dart
index a9f38220..1f4748e4 100644
--- a/example/lib/pages/event_details_page.dart
+++ b/example/lib/pages/event_details_page.dart
@@ -1,4 +1,5 @@
import 'package:calendar_view/calendar_view.dart';
+import 'package:example/theme/app_colors.dart';
import 'package:example/widgets/delete_event_dialog.dart';
import 'package:flutter/material.dart';
@@ -97,16 +98,30 @@ class DetailsPage extends StatelessWidget {
children: [
Expanded(
child: ElevatedButton(
+ child: Text(
+ 'Delete Event',
+ style: TextStyle(
+ color: AppColors.black,
+ ),
+ ),
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.white70,
+ ),
onPressed: () async {
await _handleDeleteEvent(context);
Navigator.of(context).pop();
},
- child: Text('Delete Event'),
),
),
SizedBox(width: 30),
Expanded(
child: ElevatedButton(
+ child: Text(
+ 'Edit Event',
+ style: TextStyle(
+ color: AppColors.black,
+ ),
+ ),
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
@@ -120,7 +135,9 @@ class DetailsPage extends StatelessWidget {
Navigator.of(context).pop();
}
},
- child: Text('Edit Event'),
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.white70,
+ ),
),
),
],
diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart
index 85d8f05d..a0cb5d40 100644
--- a/example/lib/pages/home_page.dart
+++ b/example/lib/pages/home_page.dart
@@ -5,13 +5,20 @@ import 'mobile/mobile_home_page.dart';
import 'web/web_home_page.dart';
class HomePage extends StatelessWidget {
- const HomePage({super.key});
+ const HomePage({
+ this.onChangeTheme,
+ super.key,
+ });
+
+ /// Return true for dark mode
+ /// false for light mode
+ final void Function(bool)? onChangeTheme;
@override
Widget build(BuildContext context) {
return ResponsiveWidget(
- mobileWidget: MobileHomePage(),
- webWidget: WebHomePage(),
+ mobileWidget: MobileHomePage(onChangeTheme: onChangeTheme),
+ webWidget: WebHomePage(onThemeChange: onChangeTheme),
);
}
}
diff --git a/example/lib/pages/mobile/mobile_home_page.dart b/example/lib/pages/mobile/mobile_home_page.dart
index 640dde95..113c03d0 100644
--- a/example/lib/pages/mobile/mobile_home_page.dart
+++ b/example/lib/pages/mobile/mobile_home_page.dart
@@ -5,7 +5,21 @@ import '../day_view_page.dart';
import '../month_view_page.dart';
import '../week_view_page.dart';
-class MobileHomePage extends StatelessWidget {
+class MobileHomePage extends StatefulWidget {
+ MobileHomePage({
+ this.onChangeTheme,
+ super.key,
+ });
+
+ final void Function(bool)? onChangeTheme;
+
+ @override
+ State createState() => _MobileHomePageState();
+}
+
+class _MobileHomePageState extends State {
+ bool isDarkMode = false;
+
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -38,6 +52,19 @@ class MobileHomePage extends StatelessWidget {
],
),
),
+ floatingActionButton: FloatingActionButton(
+ child: Icon(
+ Icons.dark_mode,
+ color: context.appColors.onPrimary,
+ ),
+ onPressed: () {
+ isDarkMode = !isDarkMode;
+ if (widget.onChangeTheme != null) {
+ widget.onChangeTheme!(isDarkMode);
+ }
+ setState(() {});
+ },
+ ),
);
}
}
diff --git a/example/lib/pages/month_view_page.dart b/example/lib/pages/month_view_page.dart
index 9bd798c2..d71f289b 100644
--- a/example/lib/pages/month_view_page.dart
+++ b/example/lib/pages/month_view_page.dart
@@ -19,13 +19,22 @@ class MonthViewPageDemo extends StatefulWidget {
class _MonthViewPageDemoState extends State {
@override
Widget build(BuildContext context) {
+ final appColors = context.appColors;
+
return ResponsiveWidget(
webWidget: WebHomePage(
selectedView: CalendarView.month,
),
mobileWidget: Scaffold(
+ primary: false,
+ appBar: AppBar(
+ leading: const SizedBox.shrink(),
+ ),
floatingActionButton: FloatingActionButton(
- child: Icon(Icons.add),
+ child: Icon(
+ Icons.add,
+ color: appColors.onPrimary,
+ ),
elevation: 8,
onPressed: () => context.pushRoute(CreateEventPage()),
),
diff --git a/example/lib/pages/web/web_home_page.dart b/example/lib/pages/web/web_home_page.dart
index 3fe2b836..71c3b0fa 100644
--- a/example/lib/pages/web/web_home_page.dart
+++ b/example/lib/pages/web/web_home_page.dart
@@ -7,9 +7,11 @@ import '../../widgets/calendar_views.dart';
class WebHomePage extends StatefulWidget {
WebHomePage({
this.selectedView = CalendarView.month,
+ this.onThemeChange,
});
final CalendarView selectedView;
+ final void Function(bool)? onThemeChange;
@override
_WebHomePageState createState() => _WebHomePageState();
@@ -35,6 +37,7 @@ class _WebHomePageState extends State {
child: CalendarConfig(
onViewChange: _setView,
currentView: _selectedView,
+ onThemeChange: widget.onThemeChange,
),
),
Expanded(
diff --git a/example/lib/pages/week_view_page.dart b/example/lib/pages/week_view_page.dart
index 3a183f5e..08a8d2d4 100644
--- a/example/lib/pages/week_view_page.dart
+++ b/example/lib/pages/week_view_page.dart
@@ -17,13 +17,22 @@ class WeekViewDemo extends StatefulWidget {
class _WeekViewDemoState extends State {
@override
Widget build(BuildContext context) {
+ final themeColors = context.appColors;
+
return ResponsiveWidget(
webWidget: WebHomePage(
selectedView: CalendarView.week,
),
mobileWidget: Scaffold(
+ primary: false,
+ appBar: AppBar(
+ leading: const SizedBox.shrink(),
+ ),
floatingActionButton: FloatingActionButton(
- child: Icon(Icons.add),
+ child: Icon(
+ Icons.add,
+ color: themeColors.onPrimary,
+ ),
elevation: 8,
onPressed: () => context.pushRoute(CreateEventPage()),
),
diff --git a/example/lib/app_colors.dart b/example/lib/theme/app_colors.dart
similarity index 64%
rename from example/lib/app_colors.dart
rename to example/lib/theme/app_colors.dart
index 96ba7680..b667b109 100644
--- a/example/lib/app_colors.dart
+++ b/example/lib/theme/app_colors.dart
@@ -1,8 +1,13 @@
import 'dart:ui';
+// TODO(Shubham): Remove if not required
class AppColors {
AppColors._();
+ static const Color primary = Color(0xffEF5366);
+ static const Color onPrimary = Color(0xfff0f0f0);
+ static const Color outlineVariant = Color(0xffd7c1c2);
+ static const Color outline = Color(0xff857373);
static const Color black = Color(0xff626262);
static const Color radiantWhite = Color(0xffffffff);
static const Color white = Color(0xfff0f0f0);
diff --git a/example/lib/theme/app_theme.dart b/example/lib/theme/app_theme.dart
new file mode 100644
index 00000000..b888d91a
--- /dev/null
+++ b/example/lib/theme/app_theme.dart
@@ -0,0 +1,142 @@
+import 'package:calendar_view/calendar_view.dart';
+import 'package:example/constants.dart';
+import 'package:example/theme/app_colors.dart';
+import 'package:example/theme/app_theme_extension.dart';
+import 'package:flutter/material.dart';
+
+import 'dark_app_colors.dart';
+
+class AppTheme {
+ // Base InputDecorationTheme
+ static final baseInputDecorationTheme = InputDecorationTheme(
+ border: AppConstants.inputBorder,
+ disabledBorder: AppConstants.inputBorder,
+ errorBorder: AppConstants.inputBorder.copyWith(
+ borderSide: const BorderSide(
+ width: 2,
+ color: AppColors.red,
+ ),
+ ),
+ enabledBorder: AppConstants.inputBorder,
+ focusedBorder: AppConstants.inputBorder.copyWith(
+ borderSide: const BorderSide(
+ width: 2,
+ color: AppColors.outline,
+ ),
+ ),
+ focusedErrorBorder: AppConstants.inputBorder,
+ hintStyle: const TextStyle(
+ color: AppColors.black,
+ fontSize: 17,
+ ),
+ labelStyle: const TextStyle(
+ color: AppColors.black,
+ fontSize: 17,
+ ),
+ helperStyle: const TextStyle(
+ color: AppColors.black,
+ fontSize: 17,
+ ),
+ errorStyle: const TextStyle(
+ color: AppColors.red,
+ fontSize: 12,
+ ),
+ contentPadding: const EdgeInsets.symmetric(
+ vertical: 10,
+ horizontal: 20,
+ ),
+ );
+
+ // Light colors
+ static final _lightAppColors = CalendarThemeExtension.light();
+ static final _dayViewTheme = DayViewTheme.light().copyWith(
+ halfHourLine: Colors.red,
+ );
+ static final _appTheme = AppThemeExtension.light();
+
+ // Dark colors
+ static final _appDarkTheme = AppThemeExtension.dark();
+ static final _calendarDarkTheme = CalendarThemeExtension.dark();
+ static final _monthViewDarkTheme = MonthViewTheme.dark();
+ static final _dayViewDarkTheme = DayViewTheme.dark();
+ static final _weekViewDarkTheme = WeekViewTheme.dark();
+
+ // Light theme
+ static final light = CalendarTheme.light.copyWith(
+ elevatedButtonTheme: ElevatedButtonThemeData(
+ style: ElevatedButton.styleFrom(
+ backgroundColor: AppColors.primary,
+ foregroundColor: AppColors.onPrimary,
+ ),
+ ),
+ floatingActionButtonTheme: const FloatingActionButtonThemeData(
+ backgroundColor: AppColors.primary,
+ ),
+ inputDecorationTheme: baseInputDecorationTheme,
+ appBarTheme: const AppBarTheme(
+ backgroundColor: AppColors.primary,
+ foregroundColor: AppColors.onPrimary,
+ ),
+ radioTheme: RadioThemeData(
+ fillColor: WidgetStateColor.resolveWith(
+ (_) => AppColors.primary,
+ ),
+ ),
+ extensions: [
+ _appTheme,
+ _lightAppColors,
+ _dayViewTheme,
+ ],
+ );
+
+ // Dark theme
+ static final dark = CalendarTheme.dark.copyWith(
+ appBarTheme: const AppBarTheme(
+ backgroundColor: DarkAppColors.primary,
+ foregroundColor: DarkAppColors.onPrimary,
+ ),
+ elevatedButtonTheme: ElevatedButtonThemeData(
+ style: ElevatedButton.styleFrom(
+ backgroundColor: DarkAppColors.primary,
+ foregroundColor: DarkAppColors.onPrimary,
+ ),
+ ),
+ inputDecorationTheme: baseInputDecorationTheme.copyWith(
+ disabledBorder: AppConstants.inputBorder.copyWith(
+ borderSide: const BorderSide(
+ width: 2,
+ color: DarkAppColors.outlineVariant,
+ ),
+ ),
+ enabledBorder: AppConstants.inputBorder.copyWith(
+ borderSide: const BorderSide(
+ width: 2,
+ color: DarkAppColors.outlineVariant,
+ ),
+ ),
+ focusedBorder: AppConstants.inputBorder.copyWith(
+ borderSide: const BorderSide(
+ width: 2,
+ color: DarkAppColors.outline,
+ ),
+ ),
+ ),
+ floatingActionButtonTheme: const FloatingActionButtonThemeData(
+ backgroundColor: DarkAppColors.primary,
+ ),
+ radioTheme: RadioThemeData(
+ fillColor: WidgetStateColor.resolveWith(
+ (_) => DarkAppColors.primary,
+ ),
+ ),
+ // TODO(Shubham): Test dark theme update
+ // extensions:
+ extensions: [
+ _appDarkTheme,
+ _calendarDarkTheme,
+ _monthViewDarkTheme,
+ _dayViewDarkTheme,
+ _weekViewDarkTheme,
+ ],
+ );
+}
diff --git a/example/lib/theme/app_theme_extension.dart b/example/lib/theme/app_theme_extension.dart
new file mode 100644
index 00000000..72a57b6a
--- /dev/null
+++ b/example/lib/theme/app_theme_extension.dart
@@ -0,0 +1,59 @@
+import 'package:flutter/material.dart';
+
+import 'app_colors.dart';
+import 'dark_app_colors.dart';
+
+// TODO(Shubham): May not required to export remove it
+// Default theme is light theme
+class AppThemeExtension extends ThemeExtension {
+ AppThemeExtension({
+ this.primary = AppColors.primary,
+ this.onPrimary = AppColors.onPrimary,
+ this.outlineVariant = AppColors.outlineVariant,
+ });
+
+ // Light theme constructor
+ AppThemeExtension.light()
+ : primary = AppColors.primary,
+ onPrimary = AppColors.onPrimary,
+ outlineVariant = AppColors.outlineVariant;
+
+ // Dark theme constructor
+ AppThemeExtension.dark()
+ : primary = DarkAppColors.primary,
+ onPrimary = DarkAppColors.onPrimary,
+ outlineVariant = DarkAppColors.outlineVariant;
+
+ final Color primary;
+ final Color onPrimary;
+ final Color outlineVariant;
+
+ @override
+ ThemeExtension copyWith({
+ Color? primary,
+ Color? onPrimary,
+ Color? outlineVariant,
+ }) {
+ return AppThemeExtension(
+ primary: primary ?? this.primary,
+ onPrimary: onPrimary ?? this.onPrimary,
+ outlineVariant: outlineVariant ?? this.outlineVariant,
+ );
+ }
+
+ @override
+ ThemeExtension lerp(
+ covariant ThemeExtension? other,
+ double t,
+ ) {
+ if (other is! AppThemeExtension) {
+ return this;
+ }
+ return AppThemeExtension(
+ primary: Color.lerp(primary, other.primary, t) ?? primary,
+ onPrimary: Color.lerp(onPrimary, other.onPrimary, t) ?? onPrimary,
+ outlineVariant:
+ Color.lerp(outlineVariant, other.outlineVariant, t) ?? outlineVariant,
+ );
+ }
+}
diff --git a/example/lib/theme/dark_app_colors.dart b/example/lib/theme/dark_app_colors.dart
new file mode 100644
index 00000000..a5ec0a7d
--- /dev/null
+++ b/example/lib/theme/dark_app_colors.dart
@@ -0,0 +1,10 @@
+import 'dart:ui';
+
+class DarkAppColors {
+ DarkAppColors._();
+
+ static const Color primary = Color(0xffffb3b6);
+ static const Color onPrimary = Color(0xff561d23);
+ static const Color outline = Color(0xff9f8c8c);
+ static const Color outlineVariant = Color(0xff524343);
+}
diff --git a/example/lib/widgets/add_event_form.dart b/example/lib/widgets/add_event_form.dart
index dbdf31c9..f9702456 100644
--- a/example/lib/widgets/add_event_form.dart
+++ b/example/lib/widgets/add_event_form.dart
@@ -2,9 +2,9 @@ import 'package:calendar_view/calendar_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
-import '../app_colors.dart';
import '../constants.dart';
import '../extension.dart';
+import '../theme/app_colors.dart';
import 'custom_button.dart';
import 'date_time_selector.dart';
@@ -63,6 +63,8 @@ class _AddOrEditEventFormState extends State {
@override
Widget build(BuildContext context) {
+ final color = Theme.of(context).colorScheme;
+
return Form(
key: _form,
child: Column(
@@ -70,11 +72,14 @@ class _AddOrEditEventFormState extends State {
children: [
TextFormField(
controller: _titleController,
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
labelText: "Event Title",
- ),
+ labelStyle: TextStyle(
+ color: color.onSurfaceVariant,
+ ),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
style: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17.0,
),
validator: (value) {
@@ -96,9 +101,12 @@ class _AddOrEditEventFormState extends State {
children: [
Expanded(
child: DateTimeSelectorFormField(
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
labelText: "Start Date",
- ),
+ labelStyle: TextStyle(
+ color: color.onSurfaceVariant,
+ ),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
initialDateTime: _startDate,
onSelect: (date) {
if (date.withoutTime.withoutTime
@@ -121,7 +129,7 @@ class _AddOrEditEventFormState extends State {
return null;
},
textStyle: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17.0,
),
onSave: (date) => _startDate = date ?? _startDate,
@@ -132,9 +140,12 @@ class _AddOrEditEventFormState extends State {
Expanded(
child: DateTimeSelectorFormField(
initialDateTime: _endDate,
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
labelText: "End Date",
- ),
+ labelStyle: TextStyle(
+ color: color.onSurfaceVariant,
+ ),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
onSelect: (date) {
if (date.withoutTime.withoutTime
.isBefore(_startDate.withoutTime)) {
@@ -159,7 +170,7 @@ class _AddOrEditEventFormState extends State {
return null;
},
textStyle: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17.0,
),
onSave: (date) => _endDate = date ?? _endDate,
@@ -173,9 +184,12 @@ class _AddOrEditEventFormState extends State {
children: [
Expanded(
child: DateTimeSelectorFormField(
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
labelText: "Start Time",
- ),
+ labelStyle: TextStyle(
+ color: color.onSurfaceVariant,
+ ),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
initialDateTime: _startTime,
minimumDateTime: CalendarConstants.epochDate,
onSelect: (date) {
@@ -191,7 +205,7 @@ class _AddOrEditEventFormState extends State {
},
onSave: (date) => _startTime = date,
textStyle: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17.0,
),
type: DateTimeSelectionType.time,
@@ -200,9 +214,12 @@ class _AddOrEditEventFormState extends State {
SizedBox(width: 20.0),
Expanded(
child: DateTimeSelectorFormField(
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
labelText: "End Time",
- ),
+ labelStyle: TextStyle(
+ color: color.onSurfaceVariant,
+ ),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
initialDateTime: _endTime,
onSelect: (date) {
if (_startTime != null &&
@@ -220,7 +237,7 @@ class _AddOrEditEventFormState extends State {
},
onSave: (date) => _endTime = date,
textStyle: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17.0,
),
type: DateTimeSelectionType.time,
@@ -235,7 +252,7 @@ class _AddOrEditEventFormState extends State {
controller: _descriptionController,
focusNode: _descriptionNode,
style: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17.0,
),
keyboardType: TextInputType.multiline,
@@ -251,9 +268,10 @@ class _AddOrEditEventFormState extends State {
return null;
},
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
hintText: "Event Description",
- ),
+ counterStyle: TextStyle(color: color.onSurfaceVariant),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
),
Align(
alignment: Alignment.centerLeft,
@@ -271,6 +289,7 @@ class _AddOrEditEventFormState extends State {
Radio(
value: RepeatFrequency.doNotRepeat,
groupValue: _selectedFrequency,
+ // activeColor: context.themeColor.primary,
onChanged: (value) {
setState(
() => _selectedFrequency = value,
@@ -459,9 +478,9 @@ class _AddOrEditEventFormState extends State {
if (_selectedRecurrenceEnd == RecurrenceEnd.onDate)
DateTimeSelectorFormField(
initialDateTime: _recurrenceEndDate,
- decoration: AppConstants.inputDecoration.copyWith(
+ decoration: InputDecoration(
labelText: 'Ends on',
- ),
+ ).applyDefaults(Theme.of(context).inputDecorationTheme),
onSelect: (date) {
if (date.withoutTime.isBefore(_endDate.withoutTime)) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
@@ -521,7 +540,7 @@ class _AddOrEditEventFormState extends State {
Text(
"Event Color: ",
style: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 17,
),
),
diff --git a/example/lib/widgets/calendar_configs.dart b/example/lib/widgets/calendar_configs.dart
index 9f976f88..5902c02d 100644
--- a/example/lib/widgets/calendar_configs.dart
+++ b/example/lib/widgets/calendar_configs.dart
@@ -1,23 +1,34 @@
import 'package:calendar_view/calendar_view.dart';
import 'package:flutter/material.dart';
-import '../app_colors.dart';
import '../enumerations.dart';
import '../extension.dart';
+import '../theme/app_colors.dart';
import 'add_event_form.dart';
-class CalendarConfig extends StatelessWidget {
+class CalendarConfig extends StatefulWidget {
final void Function(CalendarView view) onViewChange;
+ final void Function(bool)? onThemeChange;
final CalendarView currentView;
const CalendarConfig({
super.key,
required this.onViewChange,
+ this.onThemeChange,
this.currentView = CalendarView.month,
});
+ @override
+ State createState() => _CalendarConfigState();
+}
+
+class _CalendarConfigState extends State {
+ bool isDarkMode = false;
+
@override
Widget build(BuildContext context) {
+ final color = Theme.of(context).colorScheme;
+
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -27,7 +38,7 @@ class CalendarConfig extends StatelessWidget {
child: Text(
"Flutter Calendar Page",
style: TextStyle(
- color: AppColors.black,
+ color: color.onSurface,
fontSize: 30,
),
),
@@ -42,11 +53,32 @@ class CalendarConfig extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Text(
+ 'Dark mode: ',
+ style: TextStyle(
+ fontSize: 20.0,
+ color: color.onSurface,
+ ),
+ ),
+ Switch(
+ value: isDarkMode,
+ onChanged: (value) {
+ setState(() => isDarkMode = value);
+ if (widget.onThemeChange != null) {
+ widget.onThemeChange!(isDarkMode);
+ }
+ },
+ ),
+ ],
+ ),
Text(
"Active View:",
style: TextStyle(
fontSize: 20.0,
- color: AppColors.black,
+ color: Theme.of(context).colorScheme.onSurface,
),
),
Wrap(
@@ -55,7 +87,7 @@ class CalendarConfig extends StatelessWidget {
(index) {
final view = CalendarView.values[index];
return GestureDetector(
- onTap: () => onViewChange(view),
+ onTap: () => widget.onViewChange(view),
child: Container(
padding: EdgeInsets.symmetric(
vertical: 10,
@@ -67,14 +99,14 @@ class CalendarConfig extends StatelessWidget {
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
- color: view == currentView
+ color: view == widget.currentView
? AppColors.navyBlue
: AppColors.bluishGrey,
),
child: Text(
view.name.capitalized,
style: TextStyle(
- color: view == currentView
+ color: view == widget.currentView
? AppColors.white
: AppColors.black,
fontSize: 17,
@@ -92,7 +124,7 @@ class CalendarConfig extends StatelessWidget {
"Add Event: ",
style: TextStyle(
fontSize: 20.0,
- color: AppColors.black,
+ color: color.onSurface,
),
),
SizedBox(
diff --git a/example/lib/widgets/calendar_views.dart b/example/lib/widgets/calendar_views.dart
index 28509775..715d2830 100644
--- a/example/lib/widgets/calendar_views.dart
+++ b/example/lib/widgets/calendar_views.dart
@@ -2,8 +2,8 @@ import 'dart:math';
import 'package:flutter/material.dart';
-import '../app_colors.dart';
import '../enumerations.dart';
+import '../theme/app_colors.dart';
import 'day_view_widget.dart';
import 'month_view_widget.dart';
import 'week_view_widget.dart';
diff --git a/example/lib/widgets/custom_button.dart b/example/lib/widgets/custom_button.dart
index 02a92a9b..c9af5d6b 100644
--- a/example/lib/widgets/custom_button.dart
+++ b/example/lib/widgets/custom_button.dart
@@ -1,6 +1,7 @@
+import 'package:example/extension.dart';
import 'package:flutter/material.dart';
-import '../app_colors.dart';
+import '../theme/app_colors.dart';
class CustomButton extends StatelessWidget {
final String title;
@@ -10,6 +11,8 @@ class CustomButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final themeColors = context.appColors;
+
return GestureDetector(
onTap: onTap,
child: Container(
@@ -18,7 +21,7 @@ class CustomButton extends StatelessWidget {
horizontal: 40,
),
decoration: BoxDecoration(
- color: AppColors.navyBlue,
+ color: themeColors.primary,
borderRadius: BorderRadius.circular(7.0),
boxShadow: [
BoxShadow(
@@ -32,7 +35,7 @@ class CustomButton extends StatelessWidget {
child: Text(
title,
style: TextStyle(
- color: AppColors.white,
+ color: themeColors.onPrimary,
fontSize: 20,
),
),
diff --git a/example/lib/widgets/day_view_widget.dart b/example/lib/widgets/day_view_widget.dart
index a02c189f..88639666 100644
--- a/example/lib/widgets/day_view_widget.dart
+++ b/example/lib/widgets/day_view_widget.dart
@@ -21,9 +21,10 @@ class DayViewWidget extends StatelessWidget {
startDuration: Duration(hours: 8),
showHalfHours: true,
heightPerMinute: 3,
- timeLineBuilder: _timeLineBuilder,
+ // timeLineBuilder: _timeLineBuilder,
scrollPhysics: const BouncingScrollPhysics(),
eventArranger: SideEventArranger(maxWidth: 30),
+ showQuarterHours: false,
hourIndicatorSettings: HourIndicatorSettings(
color: Theme.of(context).dividerColor,
),
@@ -48,18 +49,18 @@ class DayViewWidget extends StatelessWidget {
ScaffoldMessenger.of(context).showSnackBar(snackBar);
},
halfHourIndicatorSettings: HourIndicatorSettings(
- color: Theme.of(context).dividerColor,
+ color: context.dayViewColors.halfHourLine,
lineStyle: LineStyle.dashed,
),
verticalLineOffset: 0,
timeLineWidth: 65,
showLiveTimeLineInAllDays: true,
- liveTimeIndicatorSettings: LiveTimeIndicatorSettings(
- color: Colors.redAccent,
- showBullet: false,
- showTime: true,
- showTimeBackgroundView: true,
- ),
+ // liveTimeIndicatorSettings: LiveTimeIndicatorSettings(
+ // color: Colors.redAccent,
+ // showBullet: false,
+ // showTime: true,
+ // showTimeBackgroundView: true,
+ // ),
);
}
@@ -75,7 +76,7 @@ class DayViewWidget extends StatelessWidget {
"${date.hour}:${date.minute}",
textAlign: TextAlign.right,
style: TextStyle(
- color: Colors.black.withAlpha(50),
+ color: Colors.grey,
fontStyle: FontStyle.italic,
fontSize: 12,
),
diff --git a/example/lib/widgets/month_view_widget.dart b/example/lib/widgets/month_view_widget.dart
index d9102d0c..84cbbad6 100644
--- a/example/lib/widgets/month_view_widget.dart
+++ b/example/lib/widgets/month_view_widget.dart
@@ -21,6 +21,7 @@ class MonthViewWidget extends StatelessWidget {
showWeekends: true,
startDay: WeekDays.friday,
useAvailableVerticalSpace: true,
+ hideDaysNotInMonth: true,
onEventTap: (event, date) {
Navigator.of(context).push(
MaterialPageRoute(
diff --git a/example/lib/widgets/week_view_widget.dart b/example/lib/widgets/week_view_widget.dart
index 4222c531..8ffce0c2 100644
--- a/example/lib/widgets/week_view_widget.dart
+++ b/example/lib/widgets/week_view_widget.dart
@@ -19,10 +19,10 @@ class WeekViewWidget extends StatelessWidget {
eventArranger: SideEventArranger(maxWidth: 30),
timeLineWidth: 65,
scrollPhysics: const BouncingScrollPhysics(),
- liveTimeIndicatorSettings: LiveTimeIndicatorSettings(
- color: Colors.redAccent,
- showTime: true,
- ),
+ // liveTimeIndicatorSettings: LiveTimeIndicatorSettings(
+ // color: Colors.redAccent,
+ // showTime: true,
+ // ),
onTimestampTap: (date) {
SnackBar snackBar = SnackBar(
content: Text("On tap: ${date.hour} Hr : ${date.minute} Min"),
diff --git a/lib/calendar_view.dart b/lib/calendar_view.dart
index 80e038ea..b7b656fa 100644
--- a/lib/calendar_view.dart
+++ b/lib/calendar_view.dart
@@ -16,5 +16,10 @@ export './src/extensions.dart';
export './src/modals.dart';
export './src/month_view/month_view.dart';
export './src/style/header_style.dart';
+export './src/theme/calendar_theme.dart';
+export './src/theme/calendar_theme_extension.dart'; // TODO(Shubham): Check if it is required
+export './src/theme/day_view_theme.dart';
+export './src/theme/month_view_theme.dart';
+export './src/theme/week_view_theme.dart';
export './src/typedefs.dart';
export './src/week_view/week_view.dart';
diff --git a/lib/src/components/day_view_components.dart b/lib/src/components/day_view_components.dart
index b8e28e9e..47e4d5d2 100644
--- a/lib/src/components/day_view_components.dart
+++ b/lib/src/components/day_view_components.dart
@@ -145,6 +145,7 @@ class DefaultTimeLineMark extends StatelessWidget {
textAlign: TextAlign.right,
style: markingStyle ??
TextStyle(
+ color: context.themeColor.timelineText,
fontSize: 15.0,
),
),
diff --git a/lib/src/components/headers/calendar_page_header.dart b/lib/src/components/headers/calendar_page_header.dart
index b84bcbe1..90dae67e 100644
--- a/lib/src/components/headers/calendar_page_header.dart
+++ b/lib/src/components/headers/calendar_page_header.dart
@@ -7,9 +7,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import '../../../calendar_view.dart';
import '../../constants.dart';
-import '../../style/header_style.dart';
-import '../../typedefs.dart';
class CalendarPageHeader extends StatelessWidget {
/// When user taps on right arrow.
@@ -104,8 +103,10 @@ class CalendarPageHeader extends StatelessWidget {
return Container(
margin: headerStyle.headerMargin,
padding: headerStyle.headerPadding,
- decoration:
- headerStyle.decoration ?? BoxDecoration(color: backgroundColor),
+ decoration: headerStyle.decoration ??
+ BoxDecoration(
+ color: backgroundColor,
+ ),
clipBehavior: Clip.antiAlias,
child: Row(
mainAxisSize: headerStyle.mainAxisSize,
@@ -130,7 +131,7 @@ class CalendarPageHeader extends StatelessWidget {
Icons.chevron_left,
size: headerStyle.leftIconConfig!.size,
color:
- iconColor ?? headerStyle.leftIconConfig!.color,
+ iconColor ?? headerStyle.leftIconConfig?.color,
),
),
),
diff --git a/lib/src/components/headers/day_page_header.dart b/lib/src/components/headers/day_page_header.dart
index 22e43a5e..07d5d5f2 100644
--- a/lib/src/components/headers/day_page_header.dart
+++ b/lib/src/components/headers/day_page_header.dart
@@ -33,7 +33,6 @@ class DayPageHeader extends CalendarPageHeader {
backgroundColor: backgroundColor,
iconColor: iconColor,
onNextDay: onNextDay,
-
showNextIcon: showNextIcon,
onPreviousDay: onPreviousDay,
showPreviousIcon: showPreviousIcon,
diff --git a/lib/src/components/headers/month_page_header.dart b/lib/src/components/headers/month_page_header.dart
index 2df8f6c4..1db8390f 100644
--- a/lib/src/components/headers/month_page_header.dart
+++ b/lib/src/components/headers/month_page_header.dart
@@ -5,10 +5,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import '../../../calendar_view.dart';
import '../../constants.dart';
-import '../../style/header_style.dart';
-import '../../typedefs.dart';
-import 'calendar_page_header.dart';
class MonthPageHeader extends CalendarPageHeader {
/// A header widget to display on month view.
@@ -24,7 +22,8 @@ class MonthPageHeader extends CalendarPageHeader {
Color backgroundColor = Constants.headerBackground,
StringProvider? dateStringBuilder,
required DateTime date,
- HeaderStyle headerStyle = const HeaderStyle(),
+ HeaderStyle headerStyle =
+ const HeaderStyle(), // TODO(Shubham): Update default header style
}) : super(
key: key,
date: date,
diff --git a/lib/src/components/month_view_components.dart b/lib/src/components/month_view_components.dart
index a7cd5c5f..6a2023b4 100644
--- a/lib/src/components/month_view_components.dart
+++ b/lib/src/components/month_view_components.dart
@@ -4,10 +4,8 @@
import 'package:flutter/material.dart';
-import '../calendar_event_data.dart';
+import '../../calendar_view.dart';
import '../constants.dart';
-import '../extensions.dart';
-import '../typedefs.dart';
class CircularCell extends StatelessWidget {
/// Date of cell.
@@ -211,7 +209,9 @@ class WeekDayTile extends StatelessWidget {
final String Function(int)? weekDayStringBuilder;
/// Background color of single week day tile.
- final Color backgroundColor;
+ final Color? backgroundColor;
+
+ final Color? borderColor;
/// Should display border or not.
final bool displayBorder;
@@ -223,7 +223,8 @@ class WeekDayTile extends StatelessWidget {
const WeekDayTile({
Key? key,
required this.dayIndex,
- this.backgroundColor = Constants.white,
+ this.backgroundColor,
+ this.borderColor,
this.displayBorder = true,
this.textStyle,
this.weekDayStringBuilder,
@@ -231,15 +232,17 @@ class WeekDayTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final themeColors = context.monthViewColors;
+
return Container(
alignment: Alignment.center,
margin: EdgeInsets.zero,
padding: EdgeInsets.symmetric(vertical: 10.0),
decoration: BoxDecoration(
- color: backgroundColor,
+ color: backgroundColor ?? themeColors.weekDayTile,
border: displayBorder
? Border.all(
- color: Constants.defaultBorderColor,
+ color: borderColor ?? themeColors.weekDayBorder,
width: 0.5,
)
: null,
@@ -249,7 +252,7 @@ class WeekDayTile extends StatelessWidget {
style: textStyle ??
TextStyle(
fontSize: 17,
- color: Constants.black,
+ color: themeColors.weekDayText,
),
),
);
diff --git a/lib/src/constants.dart b/lib/src/constants.dart
index 158379c8..920a0ccb 100644
--- a/lib/src/constants.dart
+++ b/lib/src/constants.dart
@@ -17,10 +17,8 @@ class Constants {
static final List weekTitles = ["M", "T", "W", "T", "F", "S", "S"];
static const Color defaultLiveTimeIndicatorColor = Color(0xff444444);
- static const Color defaultBorderColor = Color(0xffdddddd);
static const Color black = Color(0xff000000);
static const Color white = Color(0xffffffff);
- static const Color offWhite = Color(0xfff0f0f0);
static const Color headerBackground = Color(0xFFDCF0FF);
static Color get randomColor {
diff --git a/lib/src/day_view/day_view.dart b/lib/src/day_view/day_view.dart
index c290fd19..98807222 100644
--- a/lib/src/day_view/day_view.dart
+++ b/lib/src/day_view/day_view.dart
@@ -193,7 +193,7 @@ class DayView extends StatefulWidget {
final ScrollPhysics? pageViewPhysics;
/// Style for DayView header.
- final HeaderStyle headerStyle;
+ final HeaderStyle? headerStyle;
/// Option for SafeArea.
final SafeAreaOption safeAreaOption;
@@ -252,14 +252,14 @@ class DayView extends StatefulWidget {
this.dayTitleBuilder,
this.eventArranger,
this.verticalLineOffset = 10,
- this.backgroundColor = Colors.white,
+ this.backgroundColor,
this.scrollOffset,
this.onEventTap,
this.onEventLongTap,
this.onDateLongPress,
this.onDateTap,
this.minuteSlotSize = MinuteSlotSize.minutes60,
- this.headerStyle = const HeaderStyle(),
+ this.headerStyle,
this.fullDayEventBuilder,
this.safeAreaOption = const SafeAreaOption(),
this.scrollPhysics,
@@ -431,6 +431,8 @@ class DayViewState extends State> {
@override
Widget build(BuildContext context) {
+ final themeColor = context.dayViewColors;
+
return SafeAreaWrapper(
option: widget.safeAreaOption,
child: LayoutBuilder(builder: (context, constraint) {
@@ -445,7 +447,9 @@ class DayViewState extends State> {
_dayTitleBuilder(_currentDate),
Expanded(
child: DecoratedBox(
- decoration: BoxDecoration(color: widget.backgroundColor),
+ decoration: BoxDecoration(
+ color: widget.backgroundColor ?? themeColor.pageBackground,
+ ),
child: SizedBox(
height: _height,
child: PageView.builder(
@@ -545,7 +549,7 @@ class DayViewState extends State> {
_liveTimeIndicatorSettings = widget.liveTimeIndicatorSettings ??
LiveTimeIndicatorSettings(
- color: Constants.defaultLiveTimeIndicatorColor,
+ color: context.dayViewColors.liveIndicator,
height: widget.heightPerMinute,
offset: 5 + widget.verticalLineOffset,
);
@@ -556,7 +560,7 @@ class DayViewState extends State> {
_hourIndicatorSettings = widget.hourIndicatorSettings ??
HourIndicatorSettings(
height: widget.heightPerMinute,
- color: Constants.defaultBorderColor,
+ color: context.dayViewColors.hourLine,
offset: 5,
);
@@ -566,7 +570,7 @@ class DayViewState extends State> {
_halfHourIndicatorSettings = widget.halfHourIndicatorSettings ??
HourIndicatorSettings(
height: widget.heightPerMinute,
- color: Constants.defaultBorderColor,
+ color: context.dayViewColors.halfHourLine,
offset: 5,
);
@@ -576,7 +580,7 @@ class DayViewState extends State> {
_quarterHourIndicatorSettings = widget.quarterHourIndicatorSettings ??
HourIndicatorSettings(
height: widget.heightPerMinute,
- color: Constants.defaultBorderColor,
+ color: context.dayViewColors.quarterHourLine,
offset: 5,
);
@@ -703,7 +707,22 @@ class DayViewState extends State> {
jumpToDate(selectedDate);
}
},
- headerStyle: widget.headerStyle,
+ headerStyle: widget.headerStyle ??
+ HeaderStyle(
+ decoration: BoxDecoration(
+ color: context.dayViewColors.headerBackground,
+ ),
+ leftIconConfig: IconDataConfig(
+ color: context.dayViewColors.headerIcon,
+ ),
+ rightIconConfig: IconDataConfig(
+ color: context.dayViewColors.headerIcon,
+ ),
+ headerTextStyle: TextStyle(
+ color: context.dayViewColors.headerText,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
);
}
diff --git a/lib/src/extensions.dart b/lib/src/extensions.dart
index 7e6165d7..0eca4b6f 100644
--- a/lib/src/extensions.dart
+++ b/lib/src/extensions.dart
@@ -252,3 +252,20 @@ void debugLog(String message) {
return false;
}(), '');
}
+
+extension BuildContextExtension on BuildContext {
+ // TODO(Shubham): Update here theme based if possible
+ // Update to colors
+ CalendarThemeExtension get themeColor =>
+ Theme.of(this).extension() ??
+ CalendarThemeExtension.light();
+
+ MonthViewTheme get monthViewColors =>
+ Theme.of(this).extension() ?? MonthViewTheme.light();
+
+ DayViewTheme get dayViewColors =>
+ Theme.of(this).extension() ?? DayViewTheme.light();
+
+ WeekViewTheme get weekViewColors =>
+ Theme.of(this).extension() ?? WeekViewTheme.light();
+}
diff --git a/lib/src/month_view/month_view.dart b/lib/src/month_view/month_view.dart
index 194d4759..9e8fabfd 100644
--- a/lib/src/month_view/month_view.dart
+++ b/lib/src/month_view/month_view.dart
@@ -5,7 +5,6 @@
import 'package:flutter/material.dart';
import '../../calendar_view.dart';
-import '../constants.dart';
class MonthView extends StatefulWidget {
/// A function that returns a [Widget] that determines appearance of
@@ -101,7 +100,7 @@ class MonthView extends StatefulWidget {
/// Default value is [Colors.blue]
///
/// It will take affect only if [showBorder] is set.
- final Color borderColor;
+ final Color? borderColor;
/// Page transition duration used when user try to change page using
/// [MonthView.nextPage] or [MonthView.previousPage]
@@ -148,7 +147,7 @@ class MonthView extends StatefulWidget {
final WeekDays startDay;
/// Style for MontView header.
- final HeaderStyle headerStyle;
+ final HeaderStyle? headerStyle;
/// Option for SafeArea.
final SafeAreaOption safeAreaOption;
@@ -174,7 +173,7 @@ class MonthView extends StatefulWidget {
const MonthView({
Key? key,
this.showBorder = true,
- this.borderColor = Constants.defaultBorderColor,
+ this.borderColor,
this.cellBuilder,
this.minMonth,
this.maxMonth,
@@ -198,7 +197,7 @@ class MonthView extends StatefulWidget {
this.headerStringBuilder,
this.dateStringBuilder,
this.weekDayStringBuilder,
- this.headerStyle = const HeaderStyle(),
+ this.headerStyle,
this.safeAreaOption = const SafeAreaOption(),
this.onHeaderTitleTap,
this.pagePhysics = const ClampingScrollPhysics(),
@@ -543,7 +542,22 @@ class MonthViewState extends State> {
date: date,
dateStringBuilder: widget.headerStringBuilder,
onNextMonth: nextPage,
- headerStyle: widget.headerStyle,
+ headerStyle: widget.headerStyle ??
+ HeaderStyle(
+ decoration: BoxDecoration(
+ color: context.monthViewColors.headerBackground,
+ ),
+ leftIconConfig: IconDataConfig(
+ color: context.monthViewColors.headerIcon,
+ ),
+ rightIconConfig: IconDataConfig(
+ color: context.monthViewColors.headerIcon,
+ ),
+ headerTextStyle: TextStyle(
+ color: context.monthViewColors.headerText,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
);
}
@@ -564,11 +578,14 @@ class MonthViewState extends State> {
isInMonth,
hideDaysNotInMonth,
) {
+ final themeColor = context.monthViewColors;
+
if (hideDaysNotInMonth) {
return FilledCell(
date: date,
shouldHighlight: isToday,
- backgroundColor: isInMonth ? Constants.white : Constants.offWhite,
+ backgroundColor:
+ isInMonth ? themeColor.cellInMonth : themeColor.cellNotInMonth,
events: events,
isInMonth: isInMonth,
onTileTap: widget.onEventTap,
@@ -576,21 +593,22 @@ class MonthViewState extends State> {
onTileLongTap: widget.onEventLongTap,
dateStringBuilder: widget.dateStringBuilder,
hideDaysNotInMonth: hideDaysNotInMonth,
+ titleColor: themeColor.cellText,
);
}
return FilledCell(
date: date,
shouldHighlight: isToday,
- backgroundColor: isInMonth ? Constants.white : Constants.offWhite,
+ backgroundColor:
+ isInMonth ? themeColor.cellInMonth : themeColor.cellNotInMonth,
events: events,
onTileTap: widget.onEventTap,
onTileLongTap: widget.onEventLongTap,
dateStringBuilder: widget.dateStringBuilder,
onTileDoubleTap: widget.onEventDoubleTap,
hideDaysNotInMonth: hideDaysNotInMonth,
- titleColor: isInMonth
- ? Theme.of(context).colorScheme.onPrimaryContainer
- : Theme.of(context).colorScheme.onSurfaceVariant.withAlpha(150),
+ titleColor:
+ isInMonth ? themeColor.cellText : themeColor.cellText.withAlpha(150),
);
}
@@ -672,7 +690,7 @@ class _MonthPageBuilder extends StatelessWidget {
final double cellRatio;
final bool showBorder;
final double borderSize;
- final Color borderColor;
+ final Color? borderColor;
final CellBuilder cellBuilder;
final DateTime date;
final EventController controller;
@@ -690,7 +708,6 @@ class _MonthPageBuilder extends StatelessWidget {
required this.cellRatio,
required this.showBorder,
required this.borderSize,
- required this.borderColor,
required this.cellBuilder,
required this.date,
required this.controller,
@@ -702,6 +719,7 @@ class _MonthPageBuilder extends StatelessWidget {
required this.physics,
required this.hideDaysNotInMonth,
required this.weekDays,
+ this.borderColor,
}) : super(key: key);
@override
@@ -738,7 +756,8 @@ class _MonthPageBuilder extends StatelessWidget {
decoration: BoxDecoration(
border: showBorder
? Border.all(
- color: borderColor,
+ color:
+ borderColor ?? context.monthViewColors.cellBorder,
width: borderSize,
)
: null,
diff --git a/lib/src/style/header_style.dart b/lib/src/style/header_style.dart
index b7728ff3..e1b67d0b 100644
--- a/lib/src/style/header_style.dart
+++ b/lib/src/style/header_style.dart
@@ -137,8 +137,8 @@ class HeaderStyle {
/// Defines the data for icons used in calendar_view.
class IconDataConfig {
- /// Color of the default Icon.
- final Color color;
+ /// Color of the Icon.
+ final Color? color;
/// Size of the default Icon.
final double size;
@@ -164,7 +164,7 @@ class IconDataConfig {
/// Defines the data for icons used in calendar_view.
const IconDataConfig({
- this.color = Colors.black,
+ this.color,
this.size = 30,
this.padding = const EdgeInsets.all(10),
this.icon,
diff --git a/lib/src/theme/calendar_theme.dart b/lib/src/theme/calendar_theme.dart
new file mode 100644
index 00000000..2223a26d
--- /dev/null
+++ b/lib/src/theme/calendar_theme.dart
@@ -0,0 +1,27 @@
+import 'package:flutter/material.dart';
+
+import '../../calendar_view.dart';
+
+class CalendarTheme {
+ CalendarTheme._();
+
+ // Light theme
+ static final light = ThemeData.light().copyWith(
+ extensions: [
+ CalendarThemeExtension.light(),
+ MonthViewTheme.light(),
+ DayViewTheme.light(),
+ WeekViewTheme.light(),
+ ],
+ );
+
+ // Dark theme
+ static final dark = ThemeData.dark().copyWith(
+ extensions: [
+ CalendarThemeExtension.dark(),
+ MonthViewTheme.dark(),
+ DayViewTheme.dark(),
+ WeekViewTheme.dark(),
+ ],
+ );
+}
diff --git a/lib/src/theme/calendar_theme_extension.dart b/lib/src/theme/calendar_theme_extension.dart
new file mode 100644
index 00000000..3d3d6735
--- /dev/null
+++ b/lib/src/theme/calendar_theme_extension.dart
@@ -0,0 +1,42 @@
+import 'package:flutter/material.dart';
+
+import 'dark_app_colors.dart';
+import 'light_app_colors.dart';
+
+/// Contains global colors which applies to month-view, day-view & week-view components.
+class CalendarThemeExtension extends ThemeExtension {
+ CalendarThemeExtension({
+ required this.timelineText,
+ });
+
+ final Color timelineText;
+
+ // Light theme constructor
+ CalendarThemeExtension.light() : timelineText = LightAppColors.onSurface;
+
+ // Dark theme constructor
+ CalendarThemeExtension.dark() : timelineText = DarkAppColors.onSurface;
+
+ @override
+ ThemeExtension copyWith({
+ Color? timelineText,
+ }) {
+ return CalendarThemeExtension(
+ timelineText: timelineText ?? this.timelineText,
+ );
+ }
+
+ @override
+ ThemeExtension lerp(
+ covariant ThemeExtension? other,
+ double t,
+ ) {
+ if (other is! CalendarThemeExtension) {
+ return this;
+ }
+ return CalendarThemeExtension(
+ timelineText:
+ Color.lerp(timelineText, other.timelineText, t) ?? timelineText,
+ );
+ }
+}
diff --git a/lib/src/theme/dark_app_colors.dart b/lib/src/theme/dark_app_colors.dart
new file mode 100644
index 00000000..2538021e
--- /dev/null
+++ b/lib/src/theme/dark_app_colors.dart
@@ -0,0 +1,14 @@
+import 'dart:ui';
+
+class DarkAppColors {
+ DarkAppColors._();
+
+ static const Color primary = Color(0xffffb3b6);
+ static const Color onPrimary = Color(0xff561d23);
+ static const Color surfaceContainerHigh = Color(0xff322828);
+ static const Color outlineVariant = Color(0xff524343);
+ static const Color onSurface = Color(0xfff0dede);
+ static const Color surfaceContainerLowest = Color(0xff140c0c);
+ static const Color surfaceContainerLow = Color(0xff22191a);
+ static const Color surfaceContainerHighest = Color(0xff3d3232);
+}
diff --git a/lib/src/theme/day_view_theme.dart b/lib/src/theme/day_view_theme.dart
new file mode 100644
index 00000000..d2a64c47
--- /dev/null
+++ b/lib/src/theme/day_view_theme.dart
@@ -0,0 +1,99 @@
+import 'package:flutter/material.dart';
+
+import 'dark_app_colors.dart';
+import 'light_app_colors.dart';
+
+class DayViewTheme extends ThemeExtension {
+ DayViewTheme({
+ required this.hourLine,
+ required this.halfHourLine,
+ required this.quarterHourLine,
+ required this.pageBackground,
+ required this.liveIndicator,
+ required this.headerIcon,
+ required this.headerText,
+ required this.headerBackground,
+ });
+
+ final Color hourLine;
+ final Color halfHourLine;
+ final Color quarterHourLine;
+ final Color pageBackground;
+ final Color liveIndicator;
+
+ // Calendar page header
+ final Color headerIcon;
+ final Color headerText;
+ final Color headerBackground;
+
+ // Light theme
+ DayViewTheme.light()
+ : hourLine = LightAppColors.surfaceContainerHighest,
+ halfHourLine = LightAppColors.surfaceContainerHighest,
+ quarterHourLine = LightAppColors.surfaceContainerHighest,
+ pageBackground = LightAppColors.surfaceContainerLowest,
+ liveIndicator = LightAppColors.primary,
+ headerIcon = LightAppColors.onPrimary,
+ headerText = LightAppColors.onPrimary,
+ headerBackground = LightAppColors.primary;
+
+ // Dark theme
+ DayViewTheme.dark()
+ : hourLine = DarkAppColors.surfaceContainerHighest,
+ halfHourLine = DarkAppColors.surfaceContainerHighest,
+ quarterHourLine = DarkAppColors.surfaceContainerHighest,
+ pageBackground = DarkAppColors.surfaceContainerLowest,
+ liveIndicator = DarkAppColors.primary,
+ headerIcon = DarkAppColors.onPrimary,
+ headerText = DarkAppColors.onPrimary,
+ headerBackground = DarkAppColors.primary;
+
+ @override
+ ThemeExtension copyWith({
+ Color? hourLine,
+ Color? halfHourLine,
+ Color? quarterHourLine,
+ Color? pageBackground,
+ Color? liveIndicator,
+ Color? headerIcon,
+ Color? headerText,
+ Color? headerBackground,
+ }) {
+ return DayViewTheme(
+ hourLine: hourLine ?? this.hourLine,
+ halfHourLine: halfHourLine ?? this.halfHourLine,
+ quarterHourLine: quarterHourLine ?? this.quarterHourLine,
+ pageBackground: pageBackground ?? this.pageBackground,
+ liveIndicator: liveIndicator ?? this.liveIndicator,
+ headerIcon: headerIcon ?? this.headerIcon,
+ headerText: headerText ?? this.headerText,
+ headerBackground: headerBackground ?? this.headerBackground,
+ );
+ }
+
+ @override
+ ThemeExtension lerp(
+ covariant ThemeExtension? other,
+ double t,
+ ) {
+ if (other is! DayViewTheme) {
+ return this;
+ }
+ return DayViewTheme(
+ hourLine: Color.lerp(hourLine, other.hourLine, t) ?? hourLine,
+ halfHourLine:
+ Color.lerp(halfHourLine, other.halfHourLine, t) ?? halfHourLine,
+ quarterHourLine: Color.lerp(quarterHourLine, other.quarterHourLine, t) ??
+ quarterHourLine,
+ pageBackground:
+ Color.lerp(pageBackground, other.pageBackground, t) ?? pageBackground,
+ liveIndicator:
+ Color.lerp(liveIndicator, other.liveIndicator, t) ?? liveIndicator,
+ headerIcon: Color.lerp(headerIcon, other.headerIcon, t) ?? headerIcon,
+ headerText: Color.lerp(headerText, other.headerText, t) ?? headerText,
+ headerBackground:
+ Color.lerp(headerBackground, other.headerBackground, t) ??
+ headerBackground,
+ );
+ }
+}
diff --git a/lib/src/theme/light_app_colors.dart b/lib/src/theme/light_app_colors.dart
new file mode 100644
index 00000000..50c31788
--- /dev/null
+++ b/lib/src/theme/light_app_colors.dart
@@ -0,0 +1,14 @@
+import 'dart:ui';
+
+class LightAppColors {
+ LightAppColors();
+
+ static const Color primary = Color(0xffEF5366);
+ static const Color onPrimary = Color(0xffffffff);
+ static const Color surfaceContainerHigh = Color(0xfff6e4e4);
+ static const Color outlineVariant = Color(0xffd7c1c2);
+ static const Color onSurface = Color(0xff22191a);
+ static const Color surfaceContainerLowest = Color(0xffffffff);
+ static const Color surfaceContainerLow = Color(0xfffff0f0);
+ static const Color surfaceContainerHighest = Color(0xfff0dede);
+}
diff --git a/lib/src/theme/month_view_theme.dart b/lib/src/theme/month_view_theme.dart
new file mode 100644
index 00000000..28a7a548
--- /dev/null
+++ b/lib/src/theme/month_view_theme.dart
@@ -0,0 +1,111 @@
+import 'package:flutter/material.dart';
+
+import 'dark_app_colors.dart';
+import 'light_app_colors.dart';
+
+class MonthViewTheme extends ThemeExtension {
+ MonthViewTheme({
+ required this.cellInMonth,
+ required this.cellNotInMonth,
+ required this.cellText,
+ required this.cellBorder,
+ required this.weekDayTile,
+ required this.weekDayText,
+ required this.weekDayBorder,
+ required this.headerIcon,
+ required this.headerText,
+ required this.headerBackground,
+ });
+
+ final Color cellInMonth;
+ final Color cellNotInMonth;
+ final Color cellText;
+ final Color cellBorder;
+ final Color weekDayTile;
+ final Color weekDayText;
+ final Color weekDayBorder;
+
+ // Calendar page header
+ final Color headerIcon;
+ final Color headerText;
+ final Color headerBackground;
+
+ // Light theme
+ MonthViewTheme.light()
+ : cellInMonth = LightAppColors.surfaceContainerLowest,
+ cellNotInMonth = LightAppColors.surfaceContainerLow,
+ cellText = LightAppColors.onSurface,
+ cellBorder = LightAppColors.surfaceContainerHigh,
+ weekDayTile = LightAppColors.surfaceContainerHigh,
+ weekDayText = LightAppColors.onSurface,
+ weekDayBorder = LightAppColors.outlineVariant,
+ headerIcon = LightAppColors.onPrimary,
+ headerText = LightAppColors.onPrimary,
+ headerBackground = LightAppColors.primary;
+
+ // Dark theme
+ MonthViewTheme.dark()
+ : cellInMonth = DarkAppColors.surfaceContainerLowest,
+ cellNotInMonth = DarkAppColors.surfaceContainerLow,
+ cellText = DarkAppColors.onSurface,
+ cellBorder = DarkAppColors.surfaceContainerHigh,
+ weekDayTile = DarkAppColors.surfaceContainerHigh,
+ weekDayText = DarkAppColors.onSurface,
+ weekDayBorder = DarkAppColors.outlineVariant,
+ headerIcon = DarkAppColors.onPrimary,
+ headerText = DarkAppColors.onPrimary,
+ headerBackground = DarkAppColors.primary;
+
+ @override
+ ThemeExtension copyWith({
+ Color? cellInMonth,
+ Color? cellNotInMonth,
+ Color? cellText,
+ Color? cellBorder,
+ Color? weekDayTile,
+ Color? weekDayText,
+ Color? weekDayBorder,
+ Color? headerIcon,
+ Color? headerText,
+ Color? headerBackground,
+ }) {
+ return MonthViewTheme(
+ cellInMonth: cellInMonth ?? this.cellInMonth,
+ cellNotInMonth: cellNotInMonth ?? this.cellNotInMonth,
+ cellText: cellText ?? this.cellText,
+ cellBorder: cellBorder ?? this.cellBorder,
+ weekDayTile: weekDayTile ?? this.weekDayTile,
+ weekDayText: weekDayText ?? this.weekDayText,
+ weekDayBorder: weekDayBorder ?? this.weekDayBorder,
+ headerIcon: headerIcon ?? this.headerIcon,
+ headerText: headerText ?? this.headerText,
+ headerBackground: headerBackground ?? this.headerBackground,
+ );
+ }
+
+ @override
+ ThemeExtension lerp(
+ covariant ThemeExtension? other,
+ double t,
+ ) {
+ if (other is! MonthViewTheme) {
+ return this;
+ }
+ return MonthViewTheme(
+ cellInMonth: Color.lerp(cellInMonth, other.cellInMonth, t) ?? cellInMonth,
+ cellNotInMonth:
+ Color.lerp(cellNotInMonth, other.cellNotInMonth, t) ?? cellNotInMonth,
+ cellText: Color.lerp(cellText, other.cellText, t) ?? cellText,
+ cellBorder: Color.lerp(cellBorder, other.cellBorder, t) ?? cellBorder,
+ weekDayTile: Color.lerp(weekDayTile, other.weekDayTile, t) ?? weekDayTile,
+ weekDayText: Color.lerp(weekDayText, other.weekDayText, t) ?? weekDayText,
+ weekDayBorder:
+ Color.lerp(weekDayBorder, other.weekDayBorder, t) ?? weekDayBorder,
+ headerIcon: Color.lerp(headerIcon, other.headerIcon, t) ?? headerIcon,
+ headerText: Color.lerp(headerText, other.headerText, t) ?? headerText,
+ headerBackground:
+ Color.lerp(headerBackground, other.headerBackground, t) ??
+ headerBackground,
+ );
+ }
+}
diff --git a/lib/src/theme/week_view_theme.dart b/lib/src/theme/week_view_theme.dart
new file mode 100644
index 00000000..4d480f05
--- /dev/null
+++ b/lib/src/theme/week_view_theme.dart
@@ -0,0 +1,121 @@
+import 'package:flutter/material.dart';
+
+import 'dark_app_colors.dart';
+import 'light_app_colors.dart';
+
+class WeekViewTheme extends ThemeExtension {
+ WeekViewTheme({
+ required this.weekDayTile,
+ required this.weekDayText,
+ required this.weekDayBorder,
+ required this.hourLine,
+ required this.halfHourLine,
+ required this.quarterHourLine,
+ required this.liveIndicator,
+ required this.pageBackground,
+ required this.headerIcon,
+ required this.headerText,
+ required this.headerBackground,
+ });
+
+ final Color weekDayTile;
+ final Color weekDayText;
+ final Color weekDayBorder;
+ final Color hourLine;
+ final Color halfHourLine;
+ final Color quarterHourLine;
+ final Color liveIndicator;
+ final Color pageBackground;
+
+ // Calendar page header
+ final Color headerIcon;
+ final Color headerText;
+ final Color headerBackground;
+
+ // Light theme
+ WeekViewTheme.light()
+ : weekDayTile = LightAppColors.surfaceContainerHigh,
+ weekDayText = LightAppColors.onSurface,
+ weekDayBorder = LightAppColors.outlineVariant,
+ hourLine = LightAppColors.surfaceContainerHighest,
+ halfHourLine = LightAppColors.surfaceContainerHighest,
+ quarterHourLine = LightAppColors.surfaceContainerHighest,
+ liveIndicator = LightAppColors.primary,
+ pageBackground = LightAppColors.surfaceContainerLowest,
+ headerIcon = LightAppColors.onPrimary,
+ headerText = LightAppColors.onPrimary,
+ headerBackground = LightAppColors.primary;
+
+ // Dark theme
+ WeekViewTheme.dark()
+ : weekDayTile = DarkAppColors.surfaceContainerHigh,
+ weekDayText = DarkAppColors.onSurface,
+ weekDayBorder = DarkAppColors.outlineVariant,
+ hourLine = DarkAppColors.surfaceContainerHighest,
+ halfHourLine = DarkAppColors.surfaceContainerHighest,
+ quarterHourLine = DarkAppColors.surfaceContainerHighest,
+ liveIndicator = DarkAppColors.primary,
+ pageBackground = DarkAppColors.surfaceContainerLowest,
+ headerIcon = DarkAppColors.onPrimary,
+ headerText = DarkAppColors.onPrimary,
+ headerBackground = DarkAppColors.primary;
+
+ @override
+ ThemeExtension copyWith({
+ Color? weekDayTile,
+ Color? weekDayText,
+ Color? weekDayBorder,
+ Color? hourLine,
+ Color? halfHourLine,
+ Color? quarterHourLine,
+ Color? liveIndicator,
+ Color? pageBackground,
+ Color? headerIcon,
+ Color? headerText,
+ Color? headerBackground,
+ }) {
+ return WeekViewTheme(
+ weekDayTile: weekDayTile ?? this.weekDayTile,
+ weekDayText: weekDayText ?? this.weekDayText,
+ weekDayBorder: weekDayBorder ?? this.weekDayBorder,
+ hourLine: hourLine ?? this.hourLine,
+ halfHourLine: halfHourLine ?? this.halfHourLine,
+ quarterHourLine: quarterHourLine ?? this.quarterHourLine,
+ liveIndicator: liveIndicator ?? this.liveIndicator,
+ pageBackground: pageBackground ?? this.pageBackground,
+ headerIcon: headerIcon ?? this.headerIcon,
+ headerText: headerText ?? this.headerText,
+ headerBackground: headerBackground ?? this.headerBackground,
+ );
+ }
+
+ @override
+ ThemeExtension lerp(
+ covariant ThemeExtension? other,
+ double t,
+ ) {
+ if (other is! WeekViewTheme) {
+ return this;
+ }
+ return WeekViewTheme(
+ weekDayTile: Color.lerp(weekDayTile, other.weekDayTile, t) ?? weekDayTile,
+ weekDayText: Color.lerp(weekDayText, other.weekDayText, t) ?? weekDayText,
+ weekDayBorder:
+ Color.lerp(weekDayBorder, other.weekDayBorder, t) ?? weekDayBorder,
+ hourLine: Color.lerp(hourLine, other.hourLine, t) ?? hourLine,
+ halfHourLine:
+ Color.lerp(halfHourLine, other.halfHourLine, t) ?? halfHourLine,
+ quarterHourLine: Color.lerp(quarterHourLine, other.quarterHourLine, t) ??
+ quarterHourLine,
+ liveIndicator:
+ Color.lerp(liveIndicator, other.liveIndicator, t) ?? liveIndicator,
+ pageBackground:
+ Color.lerp(pageBackground, other.pageBackground, t) ?? pageBackground,
+ headerIcon: Color.lerp(headerIcon, other.headerIcon, t) ?? headerIcon,
+ headerText: Color.lerp(headerText, other.headerText, t) ?? headerText,
+ headerBackground:
+ Color.lerp(headerBackground, other.headerBackground, t) ??
+ headerBackground,
+ );
+ }
+}
diff --git a/lib/src/week_view/_internal_week_view_page.dart b/lib/src/week_view/_internal_week_view_page.dart
index 85d36b54..3d17e1cb 100644
--- a/lib/src/week_view/_internal_week_view_page.dart
+++ b/lib/src/week_view/_internal_week_view_page.dart
@@ -4,15 +4,9 @@
import 'package:flutter/material.dart';
+import '../../calendar_view.dart';
import '../components/_internal_components.dart';
-import '../components/event_scroll_notifier.dart';
-import '../components/week_view_components.dart';
-import '../enumerations.dart';
-import '../event_arrangers/event_arrangers.dart';
-import '../event_controller.dart';
-import '../modals.dart';
import '../painters.dart';
-import '../typedefs.dart';
/// A single page for week view.
class InternalWeekViewPage extends StatefulWidget {
@@ -89,6 +83,9 @@ class InternalWeekViewPage extends StatefulWidget {
/// Width of week title.
final double weekTitleWidth;
+ /// Background color of week title
+ final Color? weekTitleBackgroundColor;
+
/// Called when user taps on event tile.
final CellTapCallback? onTileTap;
@@ -166,6 +163,9 @@ class InternalWeekViewPage extends StatefulWidget {
/// This method will be called when user taps on timestamp in timeline.
final TimestampCallback? onTimestampTap;
+ /// Use this to change background color of week view page
+ final Color? backgroundColor;
+
/// A single page for week view.
const InternalWeekViewPage({
Key? key,
@@ -192,6 +192,7 @@ class InternalWeekViewPage extends StatefulWidget {
required this.eventArranger,
required this.verticalLineOffset,
required this.weekTitleWidth,
+ required this.weekTitleBackgroundColor,
required this.onTileTap,
required this.onTileLongTap,
required this.onDateLongPress,
@@ -216,6 +217,7 @@ class InternalWeekViewPage extends StatefulWidget {
required this.weekViewScrollController,
this.lastScrollOffset = 0.0,
this.keepScrollOffset = false,
+ this.backgroundColor,
}) : super(key: key);
@override
@@ -251,7 +253,10 @@ class _InternalWeekViewPageState
@override
Widget build(BuildContext context) {
final filteredDates = _filteredDate();
+ final themeColor = context.weekViewColors;
+
return Container(
+ color: widget.backgroundColor ?? themeColor.pageBackground,
height: widget.height + widget.weekTitleHeight,
width: widget.width,
child: Column(
@@ -262,26 +267,29 @@ class _InternalWeekViewPageState
children: [
SizedBox(
width: widget.width,
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SizedBox(
- height: widget.weekTitleHeight,
- width: widget.timeLineWidth +
- widget.hourIndicatorSettings.offset,
- child: widget.weekNumberBuilder.call(filteredDates[0]),
- ),
- ...List.generate(
- filteredDates.length,
- (index) => SizedBox(
+ child: ColoredBox(
+ color: widget.weekTitleBackgroundColor ?? themeColor.weekDayTile,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(
height: widget.weekTitleHeight,
- width: widget.weekTitleWidth,
- child: widget.weekDayBuilder(
- filteredDates[index],
- ),
+ width: widget.timeLineWidth +
+ widget.hourIndicatorSettings.offset,
+ child: widget.weekNumberBuilder.call(filteredDates[0]),
),
- )
- ],
+ ...List.generate(
+ filteredDates.length,
+ (index) => SizedBox(
+ height: widget.weekTitleHeight,
+ width: widget.weekTitleWidth,
+ child: widget.weekDayBuilder(
+ filteredDates[index],
+ ),
+ ),
+ )
+ ],
+ ),
),
),
Divider(
@@ -419,6 +427,11 @@ class _InternalWeekViewPageState
(index) => Container(
decoration: widget.showVerticalLine
? BoxDecoration(
+ // To apply different colors to the timeline
+ // and cells, use the background color for the timeline.
+ // Additionally, set the `color` property here with an alpha value
+ // to see horizontal & vertical lines
+ // color: Colors.red,
border: Border(
right: BorderSide(
color: widget
diff --git a/lib/src/week_view/week_view.dart b/lib/src/week_view/week_view.dart
index b91efa13..c6ab37ec 100644
--- a/lib/src/week_view/week_view.dart
+++ b/lib/src/week_view/week_view.dart
@@ -137,6 +137,9 @@ class WeekView extends StatefulWidget {
/// Height of week day title,
final double weekTitleHeight;
+ /// Background color of week title
+ final Color? weekTitleBackgroundColor;
+
/// Builder to build week day.
final DateWidgetBuilder? weekDayBuilder;
@@ -144,7 +147,7 @@ class WeekView extends StatefulWidget {
final WeekNumberBuilder? weekNumberBuilder;
/// Background color of week view page.
- final Color backgroundColor;
+ final Color? backgroundColor;
/// Scroll offset of week view page.
final double scrollOffset;
@@ -204,7 +207,7 @@ class WeekView extends StatefulWidget {
final MinuteSlotSize minuteSlotSize;
/// Style for WeekView header.
- final HeaderStyle headerStyle;
+ final HeaderStyle? headerStyle;
/// Option for SafeArea.
final SafeAreaOption safeAreaOption;
@@ -276,9 +279,10 @@ class WeekView extends StatefulWidget {
this.weekPageHeaderBuilder,
this.eventArranger,
this.weekTitleHeight = 50,
+ this.weekTitleBackgroundColor,
this.weekDayBuilder,
this.weekNumberBuilder,
- this.backgroundColor = Colors.white,
+ this.backgroundColor,
this.scrollPhysics,
this.scrollOffset = 0.0,
this.onEventTap,
@@ -294,7 +298,7 @@ class WeekView extends StatefulWidget {
this.timeLineStringBuilder,
this.weekDayStringBuilder,
this.weekDayDateStringBuilder,
- this.headerStyle = const HeaderStyle(),
+ this.headerStyle,
this.safeAreaOption = const SafeAreaOption(),
this.fullDayEventBuilder,
this.startHour = 0,
@@ -508,85 +512,82 @@ class WeekViewState extends State> {
_currentEndDate,
),
Expanded(
- child: DecoratedBox(
- decoration: BoxDecoration(color: widget.backgroundColor),
- child: SizedBox(
- height: _height,
- width: _width,
- child: PageView.builder(
- itemCount: _totalWeeks,
- controller: _pageController,
- physics: widget.pageViewPhysics,
- onPageChanged: _onPageChange,
- itemBuilder: (_, index) {
- final dates = DateTime(_minDate.year, _minDate.month,
- _minDate.day + (index * DateTime.daysPerWeek))
- .datesOfWeek(
- start: widget.startDay,
- showWeekEnds: widget.showWeekends,
- );
-
- return ValueListenableBuilder(
- valueListenable: _scrollConfiguration,
- builder: (_, __, ___) => InternalWeekViewPage(
- key: ValueKey(
- _hourHeight.toString() + dates[0].toString()),
- height: _height,
- width: _width,
- weekTitleWidth: _weekTitleWidth,
- weekTitleHeight: widget.weekTitleHeight,
- weekDayBuilder: _weekDayBuilder,
- weekNumberBuilder: _weekNumberBuilder,
- weekDetectorBuilder: _weekDetectorBuilder,
- liveTimeIndicatorSettings:
- _liveTimeIndicatorSettings,
- timeLineBuilder: _timeLineBuilder,
- onTimestampTap: widget.onTimestampTap,
- onTileTap: widget.onEventTap,
- onTileLongTap: widget.onEventLongTap,
- onDateLongPress: widget.onDateLongPress,
- onDateTap: widget.onDateTap,
- onTileDoubleTap: widget.onEventDoubleTap,
- eventTileBuilder: _eventTileBuilder,
- heightPerMinute: widget.heightPerMinute,
- hourIndicatorSettings: _hourIndicatorSettings,
- hourLinePainter: _hourLinePainter,
- halfHourIndicatorSettings:
- _halfHourIndicatorSettings,
- quarterHourIndicatorSettings:
- _quarterHourIndicatorSettings,
- dates: dates,
- showLiveLine: widget.showLiveTimeLineInAllDays ||
- _showLiveTimeIndicator(dates),
- timeLineOffset: widget.timeLineOffset,
- timeLineWidth: _timeLineWidth,
- verticalLineOffset: 0,
- showVerticalLine: widget.showVerticalLines,
- controller: controller,
- hourHeight: _hourHeight,
- weekViewScrollController: _scrollController,
- eventArranger: _eventArranger,
- weekDays: _weekDays,
- minuteSlotSize: widget.minuteSlotSize,
- scrollConfiguration: _scrollConfiguration,
- fullDayEventBuilder: _fullDayEventBuilder,
- startHour: _startHour,
- showHalfHours: widget.showHalfHours,
- showQuarterHours: widget.showQuarterHours,
- emulateVerticalOffsetBy:
- widget.emulateVerticalOffsetBy,
- showWeekDayAtBottom: widget.showWeekDayAtBottom,
- endHour: _endHour,
- fullDayHeaderTitle: _fullDayHeaderTitle,
- fullDayHeaderTextConfig: _fullDayHeaderTextConfig,
- lastScrollOffset: _lastScrollOffset,
- scrollPhysics: widget.scrollPhysics,
- scrollListener: _scrollPageListener,
- keepScrollOffset: widget.keepScrollOffset,
- ),
- );
- },
- ),
+ child: SizedBox(
+ height: _height,
+ width: _width,
+ child: PageView.builder(
+ itemCount: _totalWeeks,
+ controller: _pageController,
+ physics: widget.pageViewPhysics,
+ onPageChanged: _onPageChange,
+ itemBuilder: (_, index) {
+ final dates = DateTime(_minDate.year, _minDate.month,
+ _minDate.day + (index * DateTime.daysPerWeek))
+ .datesOfWeek(
+ start: widget.startDay,
+ showWeekEnds: widget.showWeekends,
+ );
+ return ValueListenableBuilder(
+ valueListenable: _scrollConfiguration,
+ builder: (_, __, ___) => InternalWeekViewPage(
+ key: ValueKey(
+ _hourHeight.toString() + dates[0].toString()),
+ height: _height,
+ width: _width,
+ weekTitleWidth: _weekTitleWidth,
+ weekTitleHeight: widget.weekTitleHeight,
+ weekTitleBackgroundColor:
+ widget.weekTitleBackgroundColor,
+ weekDayBuilder: _weekDayBuilder,
+ weekNumberBuilder: _weekNumberBuilder,
+ weekDetectorBuilder: _weekDetectorBuilder,
+ liveTimeIndicatorSettings: _liveTimeIndicatorSettings,
+ timeLineBuilder: _timeLineBuilder,
+ onTimestampTap: widget.onTimestampTap,
+ onTileTap: widget.onEventTap,
+ onTileLongTap: widget.onEventLongTap,
+ onDateLongPress: widget.onDateLongPress,
+ onDateTap: widget.onDateTap,
+ onTileDoubleTap: widget.onEventDoubleTap,
+ eventTileBuilder: _eventTileBuilder,
+ heightPerMinute: widget.heightPerMinute,
+ backgroundColor: widget.backgroundColor,
+ hourIndicatorSettings: _hourIndicatorSettings,
+ hourLinePainter: _hourLinePainter,
+ halfHourIndicatorSettings: _halfHourIndicatorSettings,
+ quarterHourIndicatorSettings:
+ _quarterHourIndicatorSettings,
+ dates: dates,
+ showLiveLine: widget.showLiveTimeLineInAllDays ||
+ _showLiveTimeIndicator(dates),
+ timeLineOffset: widget.timeLineOffset,
+ timeLineWidth: _timeLineWidth,
+ verticalLineOffset: 0,
+ showVerticalLine: widget.showVerticalLines,
+ controller: controller,
+ hourHeight: _hourHeight,
+ weekViewScrollController: _scrollController,
+ eventArranger: _eventArranger,
+ weekDays: _weekDays,
+ minuteSlotSize: widget.minuteSlotSize,
+ scrollConfiguration: _scrollConfiguration,
+ fullDayEventBuilder: _fullDayEventBuilder,
+ startHour: _startHour,
+ showHalfHours: widget.showHalfHours,
+ showQuarterHours: widget.showQuarterHours,
+ emulateVerticalOffsetBy:
+ widget.emulateVerticalOffsetBy,
+ showWeekDayAtBottom: widget.showWeekDayAtBottom,
+ endHour: _endHour,
+ fullDayHeaderTitle: _fullDayHeaderTitle,
+ fullDayHeaderTextConfig: _fullDayHeaderTextConfig,
+ lastScrollOffset: _lastScrollOffset,
+ scrollPhysics: widget.scrollPhysics,
+ scrollListener: _scrollPageListener,
+ keepScrollOffset: widget.keepScrollOffset,
+ ),
+ );
+ },
),
),
),
@@ -639,7 +640,7 @@ class WeekViewState extends State> {
_liveTimeIndicatorSettings = widget.liveTimeIndicatorSettings ??
LiveTimeIndicatorSettings(
- color: Constants.defaultLiveTimeIndicatorColor,
+ color: context.weekViewColors.liveIndicator,
height: widget.heightPerMinute,
);
@@ -649,7 +650,7 @@ class WeekViewState extends State> {
_hourIndicatorSettings = widget.hourIndicatorSettings ??
HourIndicatorSettings(
height: widget.heightPerMinute,
- color: Constants.defaultBorderColor,
+ color: context.weekViewColors.hourLine,
offset: 5,
);
@@ -663,7 +664,7 @@ class WeekViewState extends State> {
_halfHourIndicatorSettings = widget.halfHourIndicatorSettings ??
HourIndicatorSettings(
height: widget.heightPerMinute,
- color: Constants.defaultBorderColor,
+ color: context.weekViewColors.halfHourLine,
offset: 5,
);
@@ -672,7 +673,7 @@ class WeekViewState extends State> {
_quarterHourIndicatorSettings = widget.quarterHourIndicatorSettings ??
HourIndicatorSettings(
- color: Constants.defaultBorderColor,
+ color: context.weekViewColors.quarterHourLine,
);
assert(_quarterHourIndicatorSettings.height < _hourHeight,
@@ -855,7 +856,22 @@ class WeekViewState extends State> {
}
},
headerStringBuilder: widget.headerStringBuilder,
- headerStyle: widget.headerStyle,
+ headerStyle: widget.headerStyle ??
+ HeaderStyle(
+ decoration: BoxDecoration(
+ color: context.monthViewColors.headerBackground,
+ ),
+ leftIconConfig: IconDataConfig(
+ color: context.monthViewColors.headerIcon,
+ ),
+ rightIconConfig: IconDataConfig(
+ color: context.monthViewColors.headerIcon,
+ ),
+ headerTextStyle: TextStyle(
+ color: context.monthViewColors.headerText,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
);
}