Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Fixes issue #263: ✨ Support for dark theme #431

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,46 @@ WeekView(

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

## **Customise theme**
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create a separate file for theme customization instructions.

* 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

<table>
Expand Down
66 changes: 66 additions & 0 deletions doc/theme_guide.md
Original file line number Diff line number Diff line change
@@ -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,
),
```
18 changes: 15 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -11,7 +12,14 @@ void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
bool isDarkMode = false;

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
Expand All @@ -20,15 +28,19 @@ class MyApp extends StatelessWidget {
child: MaterialApp(
title: 'Flutter Calendar Page Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
scrollBehavior: ScrollBehavior().copyWith(
dragDevices: {
PointerDeviceKind.trackpad,
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
},
),
home: HomePage(),
home: HomePage(
onChangeTheme: (isDark) => setState(() => isDarkMode = isDark),
),
),
);
}
Expand Down
9 changes: 5 additions & 4 deletions example/lib/pages/create_event_page.dart
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -12,22 +11,24 @@ class CreateEventPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;

return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: color.surfaceContainerHigh,
centerTitle: false,
leading: IconButton(
onPressed: context.pop,
icon: Icon(
Icons.arrow_back,
color: AppColors.black,
color: color.onSurface,
),
),
title: Text(
event == null ? "Create New Event" : "Update Event",
style: TextStyle(
color: AppColors.black,
color: color.onSurface,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
Expand Down
5 changes: 5 additions & 0 deletions example/lib/pages/day_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class _DayViewPageDemoState extends State<DayViewPageDemo> {
selectedView: CalendarView.day,
),
mobileWidget: Scaffold(
primary: false,
appBar: AppBar(
leading: const SizedBox.shrink(),
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
elevation: 8,
Expand Down
12 changes: 10 additions & 2 deletions example/lib/pages/event_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,21 @@ class DetailsPage extends StatelessWidget {
children: [
Expanded(
child: ElevatedButton(
child: Text('Delete Event'),
style: ElevatedButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.surfaceContainer,
),
onPressed: () async {
await _handleDeleteEvent(context);
Navigator.of(context).pop();
},
child: Text('Delete Event'),
),
),
SizedBox(width: 30),
Expanded(
child: ElevatedButton(
child: Text('Edit Event'),
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
Expand All @@ -120,7 +125,10 @@ class DetailsPage extends StatelessWidget {
Navigator.of(context).pop();
}
},
child: Text('Edit Event'),
style: ElevatedButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.surfaceContainer,
),
),
),
],
Expand Down
13 changes: 10 additions & 3 deletions example/lib/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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),
);
}
}
25 changes: 24 additions & 1 deletion example/lib/pages/mobile/mobile_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<MobileHomePage> createState() => _MobileHomePageState();
}

class _MobileHomePageState extends State<MobileHomePage> {
bool isDarkMode = false;

@override
Widget build(BuildContext context) {
return Scaffold(
Expand Down Expand Up @@ -38,6 +52,15 @@ class MobileHomePage extends StatelessWidget {
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.dark_mode),
onPressed: () {
isDarkMode = !isDarkMode;
if (widget.onChangeTheme != null) {
widget.onChangeTheme!(isDarkMode);
}
setState(() {});
}),
);
}
}
5 changes: 5 additions & 0 deletions example/lib/pages/month_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class _MonthViewPageDemoState extends State<MonthViewPageDemo> {
selectedView: CalendarView.month,
),
mobileWidget: Scaffold(
primary: false,
appBar: AppBar(
leading: const SizedBox.shrink(),
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
elevation: 8,
Expand Down
3 changes: 3 additions & 0 deletions example/lib/pages/web/web_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -35,6 +37,7 @@ class _WebHomePageState extends State<WebHomePage> {
child: CalendarConfig(
onViewChange: _setView,
currentView: _selectedView,
onThemeChange: widget.onThemeChange,
),
),
Expanded(
Expand Down
5 changes: 5 additions & 0 deletions example/lib/pages/week_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class _WeekViewDemoState extends State<WeekViewDemo> {
selectedView: CalendarView.week,
),
mobileWidget: Scaffold(
primary: false,
appBar: AppBar(
leading: const SizedBox.shrink(),
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
elevation: 8,
Expand Down
24 changes: 24 additions & 0 deletions example/lib/theme/app_theme.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';

class AppTheme {
static final lightTheme = ThemeData(
appBarTheme: AppBarTheme(
backgroundColor: Colors.blue,
),
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
primary: Colors.blue,
),
);

static final darkTheme = ThemeData(
appBarTheme: AppBarTheme(
backgroundColor: Colors.blueAccent,
),
colorScheme: ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: Colors.blueAccent,
primary: Colors.blue,
),
);
}
Loading
Loading