angular 20.2+ calendar
Demo
Table of contents
About
A calendar component for angular 20.2+ that can display events on a month, week or day view. The successor of angular-bootstrap-calendar.
Getting started
ng add (recommended)
ng add angular-calendar
Manual setup (ng add will do this all for you)
First install through npm:
npm install angular-calendar date-fns
Next include the CSS file in the global (not component scoped) styles of your app:
/* angular-cli file: src/styles.css */
@import "../node_modules/angular-calendar/css/angular-calendar.css";
Finally add the calendar to a component in your app:
import { Component } from '@angular/core';
import { DateAdapter, provideCalendar, CalendarPreviousViewDirective, CalendarTodayDirective, CalendarNextViewDirective, CalendarMonthViewComponent, CalendarWeekViewComponent, CalendarDayViewComponent, CalendarEvent, CalendarView, CalendarDatePipe } from 'angular-calendar';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
@Component({
imports: [CalendarPreviousViewDirective, CalendarTodayDirective, CalendarNextViewDirective, CalendarMonthViewComponent, CalendarWeekViewComponent, CalendarDayViewComponent, CalendarDatePipe],
providers: [
provideCalendar({
provide: DateAdapter,
useFactory: adapterFactory,
}),
],
template: `
<button mwlCalendarPreviousView [view]="view" [(viewDate)]="viewDate" (viewDateChange)="closeOpenMonthViewDay()">Previous</button>
<button mwlCalendarToday [(viewDate)]="viewDate">Today</button>
<button mwlCalendarNextView [view]="view" [(viewDate)]="viewDate" (viewDateChange)="closeOpenMonthViewDay()">Next</button>
<h3>{{ viewDate | calendarDate: view + 'ViewTitle' : 'en' }}</h3>
<button (click)="setView(CalendarView.Month)" [class.active]="view === CalendarView.Month">Month</button>
<button (click)="setView(CalendarView.Week)" [class.active]="view === CalendarView.Week">Week</button>
<button (click)="setView(CalendarView.Day)" [class.active]="view === CalendarView.Day">Day</button>
@switch (view) {
@case (CalendarView.Month) {
<mwl-calendar-month-view [viewDate]="viewDate" [events]="events" />
}
@case (CalendarView.Week) {
<mwl-calendar-week-view [viewDate]="viewDate" [events]="events" />
}
@case (CalendarView.Day) {
<mwl-calendar-day-view [viewDate]="viewDate" [events]="events" />
}
}
`,
})
export class MyComponent {
readonly CalendarView = CalendarView;
viewDate = new Date();
events: CalendarEvent[] = [
{
start: new Date(),
title: 'An event',
},
];
setView(view: CalendarView) {
this.view = view;
}
}
In order to allow the most flexibility for all users there is a substantial amount of boilerplate required to get up and running. Please see the demos list for a series of comprehensive examples of how to use this library within your application.
Once you are up and running, to access a full list of options for each component, the individual APIs are documented here: mwl-calendar-month-view
, mwl-calendar-week-view
and mwl-calendar-day-view
.
Please note: angular-calendar uses Scarf to collect anonymized installation analytics. These analytics help support the maintainers of this library. However, if you'd like to opt out, you can do so by setting scarfSettings.enabled = false
in your project's package.json. Alternatively, you can set the environment variable SCARF_ANALYTICS=false
before you install.
Documentation
To see all available API options, take a look at the auto generated documentation. You may find it helpful to view the examples on the demo page.
Breaking changes
Where possible this library will strictly adhere to semver and only introduce API breaking changes in 0.x releases or new major versions post 1.0. The only exception to this is if you are using custom templates or extending the base components to add additional functionality, whereby critical bug fixes may introduce breakages as the internal API changes.
FAQ
Is this library AoT and universal compatible?
Yes.
What major versions of angular does this library support?
No styles are appearing?
No component styles are included with each component to make it easier to override them (otherwise you’d have to use !important
on every rule that you customised). Thus you need to import the CSS file separately from node_modules/angular-calendar/css/angular-calendar.css
.
How come there are so many dependencies?
When building the calendar some parts were found to be reusable so they were split out into their own modules. Only the bare minimum that is required is included with the calendar, there is no extra code than if there were no dependencies. date-fns
especially only imports directly the functions it needs and not the entire library.
The month, week or day view doesn’t meet my project requirements, but the other views do.
Build your own component to replace that view, and use it in place of the one this library provides. It’s impossible to provide a calendar component that meets everyones use cases, hopefully though at least some of the day / week / month view components provided can be customised with the calendars API enough to be of some use to most projects.
How come there’s no year view like the ng1 version?
As there are so many events to show on each month, it doesn’t provide a lot of value and is just an extra burden to maintain. There is nothing to stop someone from building a new lib like angular-calendar-year-view
though ;)
Does this calendar work with mobile?
This library is not optimised for mobile. Due to the complex nature of a calendar component, it is non trivial to build a calendar that has a great UX on both desktop and mobile. It is recommended to build your own calendar component for mobile that has a dedicated UX. You may be able to get some degree of mobile support by setting some custom CSS rules for smaller screens on the month view and showing less days on the week view.
How do I use a custom template?
All parts of this calendar can be customised via the use of an ng-template
. The recipe for applying one is as follows:
- Find the template you would like to customise for the month, week or day view component. You can find all available custom templates by reading the documentation for each component. For this example we will pick the
cellTemplate
from the month view.
- Next find the corresponding child component that will render the template by viewing the source. For our example of the month view cell it is this component
- Now copy the template source for your chosen template into your own component and modify as your see fit.
- Finally pass the template to the components input:
<mwl-calendar-month-view [cellTemplate]="cellTemplateId" />
- You can see an e2e working example of this here
What is the browser compatibility?
All evergreen browsers supported by angular.
Does this library require bootstrap?
No! While the demo site uses bootstrap, it isn't a requirement of this library. The styling is designed to adapt to whatever global styling your app has.
Angular 1 version
Development
Prepare your environment
- Install Node.js (>=24.5.0)
- Install pnpm:
corepack enable
- Install local dev dependencies:
pnpm install
while current directory is this repo
Development server
Run pnpm start
to start a development server on port 8000 with auto reload + tests.
Testing
Run pnpm test
to run tests once or pnpm test:watch
to continually run tests.
Release
- Bump the version in package.json (once the module hits 1.0 this will become automatic)
pnpm release
0.32.0 (2025-09-01)
⚠ BREAKING CHANGES
- date-fns v4 is now required to use this package
- angular 20.2.0 or higher is now required to use this package
- native Intl.PluralRules is now required to use this library, this should be available in all browsers supported by angular though
- if extending any of the built in classes and you implement a constructor, you no longer need to call
super()
with any injectables
- if extending the
CalendarWeekViewComponent
or CalendarMonthViewComponent
components, or using custom templates, all track by helper functions have been removed in favor of @for
and inlining the track
expression inside the template
Before:
<ng-template let-day="day" let-trackByEventId="trackByEventId">
<div *ngFor="let event of day.events; trackBy: trackByEventId">{{ event.title }}</div>
</ng-template>
After:
<ng-template let-day="day">
@for (event of day.events; track event.id ?? event) {
<div>{{ event.title }}</div>
}
</ng-template>
- the compiled .css is no longer auto prefixed. If using the angular CLI, it will automatically do this for you when you build your app
- The angular-draggable-droppable and angular-resizable-element dependencies should now be installed as dependencies to use this package
- angular 20 or higher is now required to use this package
Features
- add standalone components support and fix NgModule installation in ng-add schematic (#1783) (889319f)
- convert the library to standalone and deprecate the NgModules (#1782) (fd64bfd)
- migrate away from @angular/animations to css animations (53db311), closes #1769 #1770
- migrate repository to use inject() function instead of constructor based DI (#1776) (5da56cd)
- migrate to Angular's new control flow syntax and inline trackBy functions (#1774) (9613680)
Bug Fixes
- address sass deprecation warnings (d15a1a3), closes #1762 #1763
- don't auto prefix compiled css (9a2862c)
- move angular deps to peer dependencies (02fe7ef), closes #1761 #1547
- remove dependency on I18nPluralPipe and switch to Intl.PluralRules instead (8c18a7c)
build