kalender 0.26.0
kalender: ^0.26.0 copied to clipboard
A highly customizable calendar widget with day, multi-day, month and schedule views, drag-and-drop rescheduling, event resizing, and timezone support.
Kalender #
A highly customizable Flutter calendar widget with Day, Multi-day, Month and Schedule views. It supports drag-and-drop rescheduling, event resizing, timezones, and full control over appearance and behavior.
Live Demo · Benchmarks · Migration Guide
Features #
- Four views, one widget. Day, Multi-day, Month and Schedule.
- Reschedule by hand. Drag, resize and zoom, on mouse, stylus, trackpad or touch.
- Snapping you control. To an interval, the time indicator, other events, or your own rule.
- No fixed event model. Subclass
CalendarEventand read your own fields anywhere. - Controllers and callbacks. Navigate from code, and react to taps, creation and changes.
- Replaceable, not just configurable. Swap any widget, or keep it and restyle it.
- Material 3 by default. Follows your app's theme with no setup.
- Timezone aware. Events stored as UTC, shown in any IANA location. Tested under a matrix of timezones.
- Localized. Day and month names from intl, and every string replaceable.
- MIT licensed. No commercial license to buy.
Warning
This package is still in development, so breaking changes land in minor releases until 1.0.0. A caret range like ^0.26.0 keeps you on 0.26.x, which is where fixes land. Every minor bump has an entry in the migration guide.
If part of the API does not work for you, please open an issue.
Installation #
flutter pub add kalender
If you plan to use location/timezones support, also add:
flutter pub add timezone
If you plan to use locale support, also add:
flutter pub add intl
Quick Start #
The minimal setup, using only the base CalendarEvent class with no custom fields:
import 'package:flutter/material.dart';
import 'package:kalender/kalender.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: MyCalendar()),
);
}
}
class MyCalendar extends StatefulWidget {
const MyCalendar({super.key});
@override
State<MyCalendar> createState() => _MyCalendarState();
}
class _MyCalendarState extends State<MyCalendar> {
final eventsController = DefaultEventsController();
final calendarController = CalendarController();
@override
void dispose() {
calendarController.dispose();
eventsController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CalendarView(
eventsController: eventsController,
calendarController: calendarController,
viewConfiguration: MultiDayViewConfiguration.week(
// Without this the day opens at midnight.
initialTimeOfDay: const TimeOfDay(hour: 7, minute: 0),
),
callbacks: CalendarCallbacks(
onEventCreated: (event) => eventsController.addEvent(event),
),
header: CalendarHeader(),
body: CalendarBody(),
);
}
}
For a real app you almost always want custom fields on your events. See Custom Events.
Examples #
Runnable apps in examples/:
| Example | Shows |
|---|---|
| Basic | All view types with a toolbar, sample events, and custom tiles. Start here. |
| Advanced | A custom event layout with a lane per person, zoom, and tap-location-aware event creation. |
| Recurrence | Recurring events built on top of the package, which has no recurrence of its own. |
| ICS | Importing and exporting .ics files, expanding RRULE recurrence lazily over the visible range. |
| Riverpod | Sharing the controllers and the selected view through providers. |
| Web demo | The source behind the live demo: every option, theming, locales, and a split view. |
Documentation #
The detailed guides live in doc/:
- Views. Multi-day (day, week, work week, custom day counts, free scroll), month and schedule. What carries over on a view switch: the focused date, the scroll position, the zoom level.
- Events. Subclassing
CalendarEventto attach your own data, updating events through the controller, and what puts an event in the multi-day header rather than the day timeline: theMultiDayRule, orisAllDayon the event itself. - Interaction. Creating, rescheduling and resizing, set separately for the header and the body and lockable per event. Snapping to an interval, the time indicator, other events, or your own strategy. Zoom driven from the controller.
- Controllers & Callbacks. Jumping and animating to a date or an event, switching views, reacting to taps, creation, resizing and rescheduling, and building a navigation toolbar.
- Appearance. A
ThemeExtensionwith Material 3 defaults that follows your app'sThemeData, and replacing components outright: event tiles, day headers, the timeline gutter, the time indicator, the multi-day overflow overlay. - Layout. Where tiles are placed and sized, and how overlapping events share a column. Only needed for a custom layout strategy, such as one lane per person.
- Timezones & Locales. Events stored as UTC and displayed in any IANA location, across daylight saving changes and midnight. Day and month names from intl in the calendar's locale, right-to-left layouts, and replacing any string.
Note
weekNumberStyle and timelineStyle decide how wide the calendar's gutters are. Those gutters are drawn in the body and reserved again in the header, so the calendar measures them once above both, and a KalenderTheme placed inside only the header or only the body cannot change them. Set either one above the CalendarView, or on the KalenderThemeData registered on ThemeData.extensions. A scoped value the calendar has to ignore is reported in debug builds.
Contributing #
Contributions are welcome! Please open an issue or pull request on GitHub.
License #
This project is licensed under the MIT License. See the LICENSE file for details.