Flutter package offers a Calendar Widget featuring integrated Day

This Flutter package offers a Calendar Widget featuring integrated Day, MultiDay, and Month views. Moreover, it empowers you to tailor the visual aspects of the calendar widget.

Web Example

Try it out here

Features

Mobile & Desktop - This package is compatible with mobile and desktop.

Calendar Views - There are 3 calendar views available, Day, MultiDay, and Month. Find out more

Reschedule - Drag and Drop events to your liking. Try it out

Resize - Resize events by dragging the edges of an event. Try it out

Event Handeling - When a there is interaction with a tile or component the event can be handeled by you. Find out more

Flexible View's - Each of the Calendar View's takes a ViewConfiguration, this has some parameters you can change, OR you can create your own. Find out more

Custom Object - CaledarEvent's can contain any object of your choosing. Find out more

Appearance - You can change the style of the calendar and default components. Find out more

Custom Builders - You can create your own builders for different components of the calendar. Find out more

Custom LayoutControllers - You can create your own algorithm to layout tiles. Find out more

Installation

Add this to your package's pubspec.yaml file:

$ flutter pub add kalender

Import it:

import 'package:kalender/kalender.dart';

Usage

Create a custom class to store your data.

class Event {
  final String title;
  final Color color;
   
  Event(this.title, this.description);
}

Create a EventsController

final eventsController = EventsController<Event>();

Add events to the controller

eventsController.addEvent(
  CalendarEvent(
    dateTimeRange: DateTimeRange()
    eventData: Event(  
        title: 'Event 1',
        color: Colors.blue,
    ),
  ),
);

Create a CalendarController

final calendarController = CalendarController();

Create tile builders

Widget _tileBuilder(event, tileConfiguration) => Widget()
Widget _multiDayTileBuilder(event, tileConfiguration) => Widget()
Widget _monthEventTileBuilder(event, tileConfiguration) => Widget()

Create a CalendarView

CalendarView(
  eventsController: eventsController,
  calendarController: calendarController,
  tileBuilder: _tileBuilder(),
  multiDayTileBuilder: _multiDayTileBuilder(),
  monthTileBuilder: _monthEventTileBuilder(),
)       

Additional information

Calendar Views

There are a few constructors that you can choose from to create a CalendarView.

Default Constructor - this constructor will build the correct view (Day, MultiDay, Month) based on the ViewConfiguration you pass it.

DayView - this constructor will build a DayView and does not need the monthTileBuilder.

MultiDayView - this constructor will build a MultiDayView and does not need the monthTileBuilder.

MonthView - this constructor will build a MonthView and does not need the tileBuilder or multiDayTileBuilder.

View Configuration

The CaledarView takes a ViewConfiguration object.

There are 3 'Types' of ViewConfiguration's: DayViewConfiguration, MultiDayViewConfiguration, and MonthViewConfiguration.

  • You can create a Custom ViewConfiguration by extending one of these 'Types'.

These are the default ViewConfiguration's:

DayConfiguration - This configuration is used to configure the SingleDayView.

DayConfiguration(
  // The width of the timeline on the left of the page.
  timelineWidth: 56,
  // The overlap between the timeline and hourlines.
  hourlineTimelineOverlap: 8,
  // The height of the multi day tiles.
  multidayTileHeight: 24,
  // The size of one slot in the calendar.
  slotSize: SlotSize(minutes: 15),
  // Allow EventTiles to snap to each other.
  eventSnapping: true,
  // Allow EventTiles snap to the time indicator.
  timeIndicatorSnapping: true,
  // Allow the view to create new events.
  createNewEvents: true,
  // The duration of the vertical step while dragging.
  verticalStepDuration: Duration(minutes: 15),
  // The vertical snap range while dragging.
  verticalSnapRange: Duration(minutes: 15),
),

MultiDayConfiguration - This configuration is used to configure the MultiDayView and can display any number of days.

MultiDayConfiguration(
  name: 'Two Day',
  numberOfDays: 2,
  timelineWidth: 56,
  hourlineTimelineOverlap: 8,
  multidayTileHeight: 24,
  slotSize: SlotSize(minutes: 15),
  paintWeekNumber: true,
  eventSnapping: true,
  timeIndicatorSnapping: true,
  createNewEvents: true,
  verticalStepDuration: Duration(minutes: 15),
  verticalSnapRange: Duration(minutes: 15),
),

WeekConfiguration - This configuration is used to configure the MultiDayView and displays 7 days that starts on the firstDayOfWeek.

WeekConfiguration(
  timelineWidth: 56,
  hourlineTimelineOverlap: 8,
  multidayTileHeight: 24,
  slotSize: SlotSize(minutes: 15),
  paintWeekNumber: true,
  eventSnapping: true,
  timeIndicatorSnapping: true,
  // The first day of the week.
  firstDayOfWeek: DateTime.monday,
  createNewEvents: true,
  verticalStepDuration: Duration(minutes: 15),
  verticalSnapRange: Duration(minutes: 15),
),

WorkWeekConfiguration - This configuration is used to configure the MultiDayView and displays 5 days that starts on monday.

WorkWeekConfiguration(
  timelineWidth: 56,
  hourlineTimelineOverlap: 8,
  multidayTileHeight: 24,
  slotSize: SlotSize(minutes: 15),
  paintWeekNumber: true,
  eventSnapping: true,
  timeIndicatorSnapping: true,
  createNewEvents: true,
  verticalStepDuration: Duration(minutes: 15),
  verticalSnapRange: Duration(minutes: 15),
)

MonthConfiguration - this configuration is used to configure the MonthView.

MonthConfiguration(
  firstDayOfWeek: DateTime.monday,
  // Can events be resized.
  enableRezising: true,
  createNewEvents: true,
)

Event Handling

The CaledarView can take a CalendarEventHandlers object. The CalendarEventHandlers handles the user's interaction with the calendar. (Do not confuse the CalendarEventHandlers with the EventsController)

There are 4 events at this time that can be handeled.

onEventChanged: this function is called when an event displayed on the calendar is changed. (resized or moved)

onEventTapped: this function is called when an event displayed on the calendar is tapped.

onCreateEvent: this function is called when a new event is created by the calendar.

onDateTapped: this function is called when a date on the calendar is tapped.

CalendarEventHandlers<Event>(
  onEventChangeStart: (CalendarEvent<T> event) {
    // This function is called when an event is about to be changed.
  }
  onEventChanged: (DateTimeRange initialDateTimeRange, CalendarEvent<Event> calendarEvent) async {
    // The initialDateTimeRange is the original DateTimeRange of the event.
    // The event is a reference to the event that was changed.

    // This is a async function, so you can do any async work here.

    // Once this function is complete the calendar will rebuild.
  },
  onEventTapped: (CalendarEvent<Event> calendarEvent) async {
    // The calendarEvent is a reference to the event that was tapped.

    // This is a async function, so you can do any async work here.

    // Once this function is complete the calendar will rebuild.
  },
  onCreateEvent: (CalendarEvent<Event> calendarEvent) async {
    // The calendarEvent is a empty event and is not yet added to the list of events.

    // This is a async function, so you can do any async work here.

    // If you want to add the event to the calendar 
    eventsController.addEvent(event);

    // Once this function completes the calendar will rebuild.
  },
  onDateTapped: (date) {
    // The date is the date that was tapped. see example for use case.
  },
);

Events Controller

The CaledarView takes a EventsController object. The EventsController is used to store and manage CalendarEvent's. (Do not confuse the EventsController with EventHandling)

FunctionParametersDescription
addEventCalendarEvent<T> eventAdds this event to the list and rebuilds the calendar view
addEventsList<CalendarEvent<T>> eventsAdds these events to the list and rebuilds the calendar view
removeEventCalendarEvent<T> eventRemoves this event from the list and rebuilds the calendar view
removeWherebool Function(CalendarEvent<T> element) testRemoves the event(s) where the test returns true
clearEvents Clears the list of stored events
updateEventT? newEventData, DateTimeRange? newDateTimeRange,bool Function(CalendarEventUpdates the eventData or newDateTimeRange (if provided), of the event where the test returns true

Calendar Controller

The CaledarView takes a CalendarController object. The CalendarController is used to control the CalendarView.

FunctionParametersDescription
animateToNextPageDuration? duration, Curve? curveAnimates to the next page.
animateToPreviousPageDuration? duration, Curve? curveAnimates to the previous page.
jumpToPageint pageJumps to the given page.
jumpToDateDateTime dateJumps to the given date.
animateToDateDateTime date, {Duration? duration, Curve? curve,}Animates to the DateTime provided.
adjustHeightPerMinutedouble heightPerMinuteChanges the heightPerMinute of the view.
animateToEventCalendarEventAnimates to the CalendarEvent.
lockScrollPhyscis Locks the vertical scroll of the current view.
unlockScrollPhysicsScrollPhysics? scrollPhysicsUnlocks the vertical scroll of the current view.

Custom Object

The CalendarEvent can contain any object. This object can be accessed by the tileBuilders and the CalendarEventHandlers.

Custom Object Example:

CalendarEvent<Event>(
  dateTimeRange: DateTimeRange(),
  eventData: Event(
    title: 'Event 1',
    color: Colors.blue,
  ),
);

Tile Builder Example:

Widget _tileBuilder(CalendarEvent<Event> event, tileConfiguration) {
  final customObject = event.eventData;
  return Card(
    color: customObject.color,
    child: Text(customObject.title),
  );
}

LayoutControllers

There are three types of layout controllers: DayLayoutController, MultiDayLayoutController, and MonthLayoutController.

(See the example app for examples)

DayLayoutController Create your own DayLayoutController by extending the DayLayoutController class.

 class DefaultDayLayoutController<T> extends DayTileLayoutController<T> {}

MultiDayLayoutController Create your own MultiDayLayoutController by extending the DayLayoutController class.

class DefaultMultidayLayoutController<T> extends MultiDayTileLayoutController<T> {}

MonthLayoutController Create your own MonthLayoutController by extending the DayLayoutController class.

class DefaultMultidayLayoutController<T> extends MultiDayTileLayoutController<T> {}

Appearance

The CalendarView consists of quite a few sub components: Each of these components can be customized in the CalendarStyle object or by passing a custom widget builder through the CalendarComponents object.

CalendarHeader - This is a custom widget that you can pass to the calendar to render in the header of the calendar.

(CalendarHeader)

DayHeader - This widget is displayed above a day colum in the calendar.

(DayHeader)

WeekNumber - This widget displays the week number of the year.

(WeekNumber)

DaySeprator - This widget is displayed between days in the calendar.

(DaySeprator)

Hourlines - This widget is displayes the hourlines in the calendar.

(Hourlines)

Timeline - This widget is displayed on the left side of the calendar to show the time.

(Timeline)

TimeIndicator - This widget is displayed on the current day to show the current time.

(TimeIndicator)

MonthHeader - This widget is displayed above the month grid in the calendar header.

(MonthHeader)

MonthCellHeader - This widget is displayed in a month cell in the month grid.

(MonthCellHeader)

MonthGrid - This widget is displayed in the month view to show the grid.

(MonthGrid)

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add kalender

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  kalender: ^0.0.7

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:kalender/kalender.dart' 

example/lib/main.dart

import 'dart:io';

import 'package:example/functions/generate_calendar_eventsd.dart';
import 'package:example/models/event.dart';
import 'package:example/screens/desktop_screen.dart';
import 'package:example/screens/mobile_screen.dart';
import 'package:example/theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:kalender/kalender.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  static MyAppState? of(BuildContext context) =>
      context.findAncestorStateOfType<MyAppState>();

  @override
  State<MyApp> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  ThemeMode themeMode = ThemeMode.dark;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: lightColorScheme,
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorScheme: darkColorScheme,
      ),
      themeMode: themeMode,
      home: MyHomePage(
        toggleTheme: toggleTheme,
      ),
    );
  }

  void toggleTheme() {
    setState(() {
      themeMode =
          themeMode == ThemeMode.dark ? ThemeMode.light : ThemeMode.dark;
    });
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    super.key,
    required this.toggleTheme,
  });
  final void Function() toggleTheme;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final CalendarEventsController<Event> eventController;

  @override
  void initState() {
    super.initState();
    eventController = CalendarEventsController<Event>();
    eventController.addEvents(generateCalendarEvents());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Builder(
        builder: (context) {
          if (kIsWeb || !(Platform.isAndroid || Platform.isIOS)) {
            return DesktopScreen(
              eventsController: eventController,
              viewConfigurations: viewConfigurations,
            );
          } else {
            return MobileScreen(
              eventsController: eventController,
              viewConfigurations: viewConfigurations,
            );
          }
        },
      ),
    );
  }

  /// The list of view configurations that can be used.
  List<ViewConfiguration> viewConfigurations = [
    const DayConfiguration(
      eventSnapping: true,
      timeIndicatorSnapping: true,
    ),
    const WeekConfiguration(
      eventSnapping: true,
      timeIndicatorSnapping: true,
    ),
    const WorkWeekConfiguration(
      eventSnapping: true,
      timeIndicatorSnapping: true,
    ),
    const MultiDayConfiguration(
      name: 'Two Day',
      numberOfDays: 2,
      eventSnapping: true,
      timeIndicatorSnapping: true,
    ),
    const MultiDayConfiguration(
      name: 'Three Day',
      numberOfDays: 3,
      eventSnapping: true,
      timeIndicatorSnapping: true,
    ),
    const MultiDayConfiguration(
      name: 'Four Day',
      numberOfDays: 4,
      eventSnapping: true,
      timeIndicatorSnapping: true,
    ),
    const MonthConfiguration(
      enableRezising: true,
    ),
  ];
} 

Download details:

Author: werner-scholtz

Source: https://github.com/werner-scholtz/kalender

#flutter #Calendar #Widget

Flutter package offers a Calendar Widget featuring integrated Day
2.85 GEEK