Skip to content
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# [Unreleased - 11 May 2026]

- Added `ResizableMonthView`, a new highly customizable month view with dynamic modes (Full, Compact, Minimal) and built-in event list.
- Added `ResizableMonthViewThemeData` and related theme configurations for styling the new view.
- Fixed `MonthViewBuilder` to be generic for improved type safety in `MonthView`. [#524](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/524)
- Added `DividerSettings` to customize the dividers in `WeekView` and `MultiDayView`. [#374](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/374), [#430](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/430), [#498](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/498)
- Added `timeSlotColorBuilder` in `DayView` and `WeekView` to customize background color. [#470](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/470)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dependencies:

- Multiple calendar view options:
- Month View
- Resizable Month View
- Day View
- Week View
- Highly customisable UI components
Expand Down
2 changes: 1 addition & 1 deletion example/lib/enumerations.dart
Original file line number Diff line number Diff line change
@@ -1 +1 @@
enum CalendarView { month, day, week }
enum CalendarView { month, day, week, resizableMonth }
5 changes: 0 additions & 5 deletions example/lib/extension.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import 'enumerations.dart';
import 'l10n/app_localizations.dart';
import 'theme/app_colors.dart';
import 'theme/app_theme_extension.dart';
Expand Down Expand Up @@ -124,10 +123,6 @@ extension StringExt on String {
String get capitalized => toBeginningOfSentenceCase(this) ?? "";
}

extension ViewNameExt on CalendarView {
String get name => toString().split(".").last;
}

extension BuildContextExtension on BuildContext {
AppThemeExtension get appColors =>
Theme.of(this).extension<AppThemeExtension>() ??
Expand Down
1 change: 1 addition & 0 deletions example/lib/l10n/app_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dayView": "عرض يومي",
"weekView": "عرض أسبوعي",
"multidayView": "عرض متعدد الأيام",
"resizableMonthView": "عرض شهري قابل للتغيير",
"appTitle": "مثال صفحة تقويم فلاتر",
"projectMeetingTitle": "اجتماع المشروع",
"projectMeetingDesc": "اليوم هو اجتماع المشروع.",
Expand Down
1 change: 1 addition & 0 deletions example/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dayView": "Day View",
"weekView": "Week View",
"multidayView": "Multi-Day View",
"resizableMonthView": "Resizable Month View",
"appTitle": "Flutter Calendar Page Demo",
"projectMeetingTitle": "Project meeting",
"projectMeetingDesc": "Today is project meeting.",
Expand Down
1 change: 1 addition & 0 deletions example/lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dayView": "Vista Diaria",
"weekView": "Vista Semanal",
"multidayView": "Vista de Varios Días",
"resizableMonthView": "Vista Mensual Redimensionable",
"appTitle": "Demo de Página de Calendario Flutter",
"projectMeetingTitle": "Reunión del proyecto",
"projectMeetingDesc": "Hoy hay reunión del proyecto.",
Expand Down
3 changes: 3 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class _MyAppState extends State<MyApp> {
multiDayViewTheme: isDarkMode
? MultiDayViewThemeData.dark()
: MultiDayViewThemeData.light(),
resizableMonthViewTheme: isDarkMode
? ResizableMonthViewThemeData.dark()
: ResizableMonthViewThemeData.light(),
),
child: CalendarControllerProvider(
controller: EventController(),
Expand Down
6 changes: 6 additions & 0 deletions example/lib/pages/mobile/mobile_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import '../../localization/locale_controller.dart';
import '../day_view_page.dart';
import '../month_view_page.dart';
import '../multi_day_view_page.dart';
import '../resizable_month_view_page.dart';
import '../week_view_page.dart';

class MobileHomePage extends StatefulWidget {
Expand Down Expand Up @@ -107,6 +108,11 @@ class _MobileHomePageState extends State<MobileHomePage> {
child: Text(translate.monthView),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => context.pushRoute(ResizableMonthViewPageDemo()),
child: Text(translate.resizableMonthView),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => context.pushRoute(DayViewPageDemo()),
child: Text(translate.dayView),
Expand Down
44 changes: 44 additions & 0 deletions example/lib/pages/resizable_month_view_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';

import '../extension.dart';
import '../widgets/resizable_month_view_widget.dart';
import '../widgets/responsive_widget.dart';
import 'create_event_page.dart';
import 'web/web_home_page.dart';
import '../enumerations.dart';

/// Full-screen demo page for [ResizableMonthViewWidget].
///
/// On mobile it renders a [Scaffold] with an AppBar and a FAB to create
/// events. On web/desktop it delegates to [WebHomePage] with the
/// [CalendarView.resizableMonth] view pre-selected.
class ResizableMonthViewPageDemo extends StatefulWidget {
const ResizableMonthViewPageDemo({super.key});

@override
State<ResizableMonthViewPageDemo> createState() =>
_ResizableMonthViewPageDemoState();
}

class _ResizableMonthViewPageDemoState
extends State<ResizableMonthViewPageDemo> {
@override
Widget build(BuildContext context) {
final appColors = context.appColors;

return ResponsiveWidget(
webWidget: WebHomePage(selectedView: CalendarView.resizableMonth),
mobileWidget: Scaffold(
primary: false,
appBar: AppBar(leading: const SizedBox.shrink()),
floatingActionButton: FloatingActionButton(
heroTag: 'add_event_resizable_month_view',
child: Icon(Icons.add, color: appColors.onPrimary),
elevation: 8,
onPressed: () => context.pushRoute(CreateEventPage()),
),
body: ResizableMonthViewWidget(),
),
);
}
}
12 changes: 10 additions & 2 deletions example/lib/theme/app_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ class AppTheme {
static final _dayViewTheme = DayViewThemeData.light();
static final _weekViewTheme = WeekViewThemeData.light();
static final _multiDayViewTheme = MultiDayViewThemeData.light();
static final _resizableMonthViewTheme = ResizableMonthViewThemeData.light();

// Dark colors
static final _appDarkTheme = AppThemeExtension.dark();
static final _monthViewDarkTheme = MonthViewThemeData.dark();
static final _dayViewDarkTheme = DayViewThemeData.dark();
static final _weekViewDarkTheme = WeekViewThemeData.dark();
static final _multiDayViewDarkTheme = MultiDayViewThemeData.dark();
static final _resizableMonthViewDarkTheme =
ResizableMonthViewThemeData.dark();

// Light theme
static final light = ThemeData.light().copyWith(
Expand All @@ -57,7 +60,12 @@ class AppTheme {
radioTheme: RadioThemeData(
fillColor: WidgetStateColor.resolveWith((_) => AppColors.primary),
),
extensions: [_dayViewTheme, _weekViewTheme, _multiDayViewTheme],
extensions: [
_dayViewTheme,
_weekViewTheme,
_multiDayViewTheme,
_resizableMonthViewTheme,
],
);

// Dark theme
Expand Down Expand Up @@ -95,13 +103,13 @@ class AppTheme {
radioTheme: RadioThemeData(
fillColor: WidgetStateColor.resolveWith((_) => DarkAppColors.primary),
),
// TODO(Shubham): Test dark theme update
extensions: [
_appDarkTheme,
_monthViewDarkTheme,
_dayViewDarkTheme,
_weekViewDarkTheme,
_multiDayViewDarkTheme,
_resizableMonthViewDarkTheme,
],
);
}
3 changes: 3 additions & 0 deletions example/lib/widgets/calendar_configs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ class _CalendarConfigState extends State<CalendarConfig> {
case CalendarView.week:
viewName = translate.weekView;
break;
case CalendarView.resizableMonth:
viewName = translate.resizableMonthView;
break;
}
return GestureDetector(
onTap: () => widget.onViewChange(view),
Expand Down
20 changes: 11 additions & 9 deletions example/lib/widgets/calendar_views.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,35 @@ import 'dart:math';
import 'package:flutter/material.dart';

import '../enumerations.dart';
import '../theme/app_colors.dart';
import 'day_view_widget.dart';
import 'month_view_widget.dart';
import 'resizable_month_view_widget.dart';
import 'week_view_widget.dart';

class CalendarViews extends StatelessWidget {
final CalendarView view;

const CalendarViews({super.key, this.view = CalendarView.month});

final _breakPoint = 490.0;
/// Maximum width for the calendar preview on web.
static const _maxCalendarWidth = 600.0;

@override
Widget build(BuildContext context) {
final availableWidth = MediaQuery.of(context).size.width;
final width = min(_breakPoint, availableWidth);
final width = min(_maxCalendarWidth, availableWidth);

return Container(
height: double.infinity,
width: double.infinity,
color: AppColors.grey,
color: Theme.of(context).scaffoldBackgroundColor,
child: Center(
child: view == CalendarView.month
? MonthViewWidget(width: width)
: view == CalendarView.day
? DayViewWidget(width: width)
: WeekViewWidget(width: width),
child: switch (view) {
CalendarView.month => MonthViewWidget(width: width),
CalendarView.day => DayViewWidget(width: width),
CalendarView.week => WeekViewWidget(width: width),
CalendarView.resizableMonth => ResizableMonthViewWidget(width: width),
},
),
);
}
Expand Down
Loading
Loading