Skip to content

Commit 75d196d

Browse files
author
Shubham Jitiya
committed
feat: Fixes issue #263: ✨ Support for dark theme
1 parent 469cc29 commit 75d196d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1235
-227
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# [1.4.1 - Unreleased]
22

33
- Adds clear method to `EventController`.
4+
- Adds support for dark theme. [#263](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/263)
45

56
# [1.4.0 - 7 Jan 2025](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.4.0)
67

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,43 @@ WeekView(
355355

356356
Above code will create `WeekView` with only five days, from monday to friday.
357357

358+
## **Customise theme**
359+
* The default theme includes support for dark mode.
360+
_
361+
_### Use default light & dark theme
362+
* CalendarTheme.light() & CalendarTheme.dark() provides the default colors for light & dark mode.
363+
* If no any theme is provided then default light theme is taken.
364+
```dart
365+
child: MaterialApp(
366+
theme: CalendarTheme.light,
367+
darkTheme: CalendarTheme.dark,
368+
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
369+
)
370+
```
371+
* Month-view, day-view & week-view each have separate theme to customise its component.
372+
* Refer [app_theme](example/lib/theme/app_theme.dart) of example to understand how to change colors of components.
373+
```dart
374+
// app_theme.dart
375+
static final _monthViewTheme = MonthViewTheme.light().copyWith(
376+
cellInMonth: Colors.redAccent,
377+
cellNotInMonth: Colors.red,
378+
cellText: Colors.amber,
379+
);
380+
381+
// Light theme: Use this in MaterialApp theme & dark theme.
382+
static final light = CalendarTheme.light.copyWith(
383+
extensions: [
384+
_monthViewTheme,
385+
],
386+
);
387+
388+
// main.dart
389+
MaterialApp(
390+
theme: AppTheme.light,
391+
)
392+
```
393+
[//]: # (TODO(Shubham): Add docs)
394+
358395
## Main Contributors
359396

360397
<table>

doc/theme_guide.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
## **Customise theme**
2+
The default theme supports dark mode. Refer this colors to override it.
3+
4+
| Name | Parameter | Default color |
5+
|-----------------------------------------------|------------------------|-------------------------------------|
6+
| `MonthView` Border color | Color? borderColor | colorScheme.surfaceContainerHigh |
7+
| `WeekView` Background color of week view page | Color? backgroundColor | colorScheme.surfaceContainerLowest |
8+
| `DayView` Default background color | Color? backgroundColor | colorScheme.surfaceContainerLow |
9+
| `FilledCell` Dates in month cell color | Color? backgroundColor | colorScheme.surfaceContainerLowest |
10+
| `FilledCell` Dates not in month cell color | Color? backgroundColor | colorScheme.surfaceContainerLow |
11+
| `WeekDayTile` Border color | Color? borderColor | colorScheme.secondaryContainer |
12+
| `WeekDayTile` Background color | Color? backgroundColor | colorScheme.surfaceContainerHigh |
13+
| `WeekDayTile` Text style color | TextStyle? textStyle | colorScheme.onSecondaryContainer |
14+
15+
To customise `MonthView`, `DayView` & `WeekView` page header use `HeaderStyle`.
16+
17+
```dart
18+
headerStyle: HeaderStyle(
19+
leftIconConfig: IconDataConfig(color: Colors.red),
20+
rightIconConfig: IconDataConfig(color: Colors.red),
21+
decoration: BoxDecoration(
22+
color: Theme.of(context).highlightColor,
23+
),
24+
),
25+
```
26+
27+
### Day view
28+
* Default timeline text color is `colorScheme.onSurface`.
29+
* Use `markingStyle` in `DefaultTimeLineMark` to give text style.
30+
* Default `LiveTimeIndicatorSettings` color `colorScheme.primaryColorLight`.
31+
* Use `liveTimeIndicatorSettings` to customise it.
32+
* Default hour, half hour & quarter color is `colorScheme.surfaceContainerHighest`.
33+
* Use `hourIndicatorSettings` to customise it.
34+
35+
Default hour indicator settings.
36+
```dart
37+
HourIndicatorSettings(
38+
height: widget.heightPerMinute,
39+
// Color of horizontal and vertical lines
40+
color: Theme.of(context).colorScheme.surfaceContainerHighest,
41+
offset: 5,
42+
);
43+
```
44+
45+
### Week view
46+
* To customise week number & weekdays use `weekNumberBuilder` & `weekDayBuilder`.
47+
* Default week tile background color is `colorScheme.surfaceContainerHigh`.
48+
* Use `weekTitleBackgroundColor` to change background color.
49+
* Default page background color is `colorScheme.surfaceContainerLowest`.
50+
* Use `backgroundColor` to change background color.
51+
* Default timeline text color is `colorScheme.onSurface`. Use `markingStyle` in `DefaultTimeLineMark` to give text style.
52+
* To customise timeline use `timeLineBuilder`.
53+
* To change Hour lines color use `HourIndicatorSettings`.
54+
* To style hours, half hours & quarter hours use `HourIndicatorSettings`. Default color used is `surfaceContainerHighest`
55+
56+
```dart
57+
hourIndicatorSettings: HourIndicatorSettings(
58+
color: Colors.greenAccent,
59+
lineStyle: LineStyle.dashed,
60+
),
61+
showHalfHours: true,
62+
halfHourIndicatorSettings: HourIndicatorSettings(
63+
color: Colors.redAccent,
64+
lineStyle: LineStyle.dashed,
65+
),
66+
```

example/lib/constants.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:flutter/material.dart';
22

3-
import 'app_colors.dart';
3+
import 'theme/app_colors.dart';
44

55
class AppConstants {
66
AppConstants._();
@@ -11,7 +11,7 @@ class AppConstants {
1111
borderRadius: BorderRadius.circular(7),
1212
borderSide: BorderSide(
1313
width: 2,
14-
color: AppColors.lightNavyBlue,
14+
color: AppColors.outlineVariant,
1515
),
1616
);
1717

example/lib/extension.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import 'package:example/theme/app_theme_extension.dart';
12
import 'package:flutter/material.dart';
23
import 'package:intl/intl.dart';
34

4-
import 'app_colors.dart';
55
import 'enumerations.dart';
6+
import 'theme/app_colors.dart';
67

78
enum TimeStampFormat { parse_12, parse_24 }
89

@@ -128,3 +129,9 @@ extension StringExt on String {
128129
extension ViewNameExt on CalendarView {
129130
String get name => toString().split(".").last;
130131
}
132+
133+
extension BuildContextExtension on BuildContext {
134+
AppThemeExtension get appColors =>
135+
Theme.of(this).extension<AppThemeExtension>() ??
136+
AppThemeExtension.light();
137+
}

example/lib/main.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:ui';
22

33
import 'package:calendar_view/calendar_view.dart';
4+
import 'package:example/theme/app_theme.dart';
45
import 'package:flutter/material.dart';
56

67
import 'pages/home_page.dart';
@@ -11,7 +12,14 @@ void main() {
1112
runApp(MyApp());
1213
}
1314

14-
class MyApp extends StatelessWidget {
15+
class MyApp extends StatefulWidget {
16+
@override
17+
State<MyApp> createState() => _MyAppState();
18+
}
19+
20+
class _MyAppState extends State<MyApp> {
21+
bool isDarkMode = false;
22+
1523
// This widget is the root of your application.
1624
@override
1725
Widget build(BuildContext context) {
@@ -20,15 +28,19 @@ class MyApp extends StatelessWidget {
2028
child: MaterialApp(
2129
title: 'Flutter Calendar Page Demo',
2230
debugShowCheckedModeBanner: false,
23-
theme: ThemeData.light(),
31+
theme: AppTheme.light,
32+
darkTheme: AppTheme.dark,
33+
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
2434
scrollBehavior: ScrollBehavior().copyWith(
2535
dragDevices: {
2636
PointerDeviceKind.trackpad,
2737
PointerDeviceKind.mouse,
2838
PointerDeviceKind.touch,
2939
},
3040
),
31-
home: HomePage(),
41+
home: HomePage(
42+
onChangeTheme: (isDark) => setState(() => isDarkMode = isDark),
43+
),
3244
),
3345
);
3446
}

example/lib/pages/create_event_page.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import 'package:calendar_view/calendar_view.dart';
22
import 'package:flutter/material.dart';
33

4-
import '../app_colors.dart';
54
import '../extension.dart';
65
import '../widgets/add_event_form.dart';
76

@@ -12,22 +11,23 @@ class CreateEventPage extends StatelessWidget {
1211

1312
@override
1413
Widget build(BuildContext context) {
14+
final themeColor = context.appColors;
15+
1516
return Scaffold(
1617
appBar: AppBar(
1718
elevation: 0,
18-
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
1919
centerTitle: false,
2020
leading: IconButton(
2121
onPressed: context.pop,
2222
icon: Icon(
2323
Icons.arrow_back,
24-
color: AppColors.black,
24+
color: themeColor.onPrimary,
2525
),
2626
),
2727
title: Text(
2828
event == null ? "Create New Event" : "Update Event",
2929
style: TextStyle(
30-
color: AppColors.black,
30+
color: themeColor.onPrimary,
3131
fontSize: 20.0,
3232
fontWeight: FontWeight.bold,
3333
),

example/lib/pages/day_view_page.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,22 @@ class DayViewPageDemo extends StatefulWidget {
1717
class _DayViewPageDemoState extends State<DayViewPageDemo> {
1818
@override
1919
Widget build(BuildContext context) {
20+
final appColors = context.appColors;
21+
2022
return ResponsiveWidget(
2123
webWidget: WebHomePage(
2224
selectedView: CalendarView.day,
2325
),
2426
mobileWidget: Scaffold(
27+
primary: false,
28+
appBar: AppBar(
29+
leading: const SizedBox.shrink(),
30+
),
2531
floatingActionButton: FloatingActionButton(
26-
child: Icon(Icons.add),
32+
child: Icon(
33+
Icons.add,
34+
color: appColors.onPrimary,
35+
),
2736
elevation: 8,
2837
onPressed: () => context.pushRoute(CreateEventPage()),
2938
),

example/lib/pages/event_details_page.dart

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:calendar_view/calendar_view.dart';
2+
import 'package:example/theme/app_colors.dart';
23
import 'package:example/widgets/delete_event_dialog.dart';
34
import 'package:flutter/material.dart';
45

@@ -97,16 +98,30 @@ class DetailsPage extends StatelessWidget {
9798
children: [
9899
Expanded(
99100
child: ElevatedButton(
101+
child: Text(
102+
'Delete Event',
103+
style: TextStyle(
104+
color: AppColors.black,
105+
),
106+
),
107+
style: ElevatedButton.styleFrom(
108+
backgroundColor: Colors.white70,
109+
),
100110
onPressed: () async {
101111
await _handleDeleteEvent(context);
102112
Navigator.of(context).pop();
103113
},
104-
child: Text('Delete Event'),
105114
),
106115
),
107116
SizedBox(width: 30),
108117
Expanded(
109118
child: ElevatedButton(
119+
child: Text(
120+
'Edit Event',
121+
style: TextStyle(
122+
color: AppColors.black,
123+
),
124+
),
110125
onPressed: () async {
111126
final result = await Navigator.of(context).push(
112127
MaterialPageRoute(
@@ -120,7 +135,9 @@ class DetailsPage extends StatelessWidget {
120135
Navigator.of(context).pop();
121136
}
122137
},
123-
child: Text('Edit Event'),
138+
style: ElevatedButton.styleFrom(
139+
backgroundColor: Colors.white70,
140+
),
124141
),
125142
),
126143
],

example/lib/pages/home_page.dart

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,20 @@ import 'mobile/mobile_home_page.dart';
55
import 'web/web_home_page.dart';
66

77
class HomePage extends StatelessWidget {
8-
const HomePage({super.key});
8+
const HomePage({
9+
this.onChangeTheme,
10+
super.key,
11+
});
12+
13+
/// Return true for dark mode
14+
/// false for light mode
15+
final void Function(bool)? onChangeTheme;
916

1017
@override
1118
Widget build(BuildContext context) {
1219
return ResponsiveWidget(
13-
mobileWidget: MobileHomePage(),
14-
webWidget: WebHomePage(),
20+
mobileWidget: MobileHomePage(onChangeTheme: onChangeTheme),
21+
webWidget: WebHomePage(onThemeChange: onChangeTheme),
1522
);
1623
}
1724
}

0 commit comments

Comments
 (0)