The Ignite UI for Angular Calendar component is developed as a native Angular component. Use it to provide your application with three easy and intuitive ways to display date information. Users can select a single date, multiple dates or pick a range of dates.

Calendar Demo


To get started with the Calendar component, first you need to install Ignite UI for Angular by typing the following command:

ng add igniteui-angular

For a complete introduction to the Ignite UI for Angular, read the getting started topic.

The next step is to import the IgxCalendarModule in the application's AppModule, typically this is the app.module.ts file. Note that the IgxCalendar is also dependent on the BrowserAnimationsModule and on the HammerModule for touch interactions, so they need to be added to the AppModule as well:

// app.module.ts
import { HammerModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { IgxCalendarModule } from 'igniteui-angular';
    imports: [..., BrowserAnimationsModule, HammerModule, IgxCalendarModule],
export class AppModule {}

You will usually also import the IgxCalendarComponent in the AppComponent file (or your editor will auto-import them for you) when declaring types that are part of the calendar API:

import { IgxCalendarComponent } from 'igniteui-angular';

@ViewChild('calendar', { read: IgxCalendarComponent }) public calendar: IgxCalendarComponent;

Note that the IgxCalendarComponent uses the Intl WebAPI for localization and formatting of dates. Consider using the appropriate polyfills if your target platform does not support them.


Instantiating the IgxCalendarComponent is as easy as placing its selector element in the template. This will display the current month in the calendar and use single selection mode. We switch to any of the other selection modes - multi and range, by setting the selection property:

<!-- app.component.html -->
<!-- Single selection mode -->
<!-- Multi selection mode -->
<igx-calendar selection="multi"></igx-calendar>
<!-- Range selection mode -->
<igx-calendar selection="range"></igx-calendar>

Notice that the calendar header is not rendered when the selection is either multi or range:

Localization and formatting

Due to their very nature, localization and formatting are essential to any calendar. In the IgxCalendarComponent those are controlled and customized through the following properties - locale, formatOptions, formatViews.
Let's go ahead and try those along with other customizations from the IgxCalendarComponent API. Say we are having visitors on our page coming from countries from EFTA (European Free Trade Association) countries, so we need to display the calendar in the corresponding culture. First thing we need to set is the weekstart, which controls the starting day of the week. It defaults to 0, which corresponds to Sunday, so we set a value of 1.

In the markup below we are also binding the formatOptions and formatViews properties to customize the display formatting. Finally we are binding the locale property to a value, based on the user's location choice:

<!-- app.component.html -->
<igx-calendar #calendar
<select id="locations" (change)="changeLocale($event)">...</select>

All property values are set in the AppCоmponent file:

// app.component.ts
@ViewChild('calendar', { read: IgxCalendarComponent }) public calendar: IgxCalendarComponent;

public formatOptions: any;
public formatViews: any;
public locale: string;
public select: HTMLSelectElement;

public ngOnInit() { = document.getElementById("locations") as HTMLSelectElement;
    this.locale =;
    this.formatOptions = { day: "2-digit", month: "long", weekday: "long", year: "numeric" };
    this.formatViews = { day: true, month: true, year: true };

// change the calendar locale
public changeLocale(event) {
    this.locale =;

Great, we should now have a calendar with customized dates display that also changes the locale representation based on the user location. Let's have a look at it:


Let's build on top of that sample a bit. We will require the user to enter a date range that does not exceed 5 days. We need to change the selection mode of the calendar to "range" and prompt the user to correct the selection, if the range is not valid. To do this we will use the onSelection event:

<!-- app.component.html -->
<igx-calendar #calendar

The value passed in the onSelection event is the collection of dates selected, so we can read its length to base our logic upon it. If we alert the user for the invalid selection, we also reset the selection to contain only the first date from the range using the selectDate method:

// app.component.ts
public verifyRange(dates: Date[]) {
    if (dates.length > 5) {

Let's try this out by playing around with selecting ranges:


We have seen how to make use of the IgxCalendarComponent API (properties, events, methods) so that we configure the calendar per our requirements and interact with it programmatically. Now we want to go further and customize its look, benefiting from the header and subheader templating capabilities.

To do that we need to decorate a ng-template inside the calendar with igxCalendarHeader or igxCalendarSubheader directive and use the context returned to customize the way the date is displayed. The template decorated with the igxCalendarHeader directive is rendered only when the calendar selection is set to single. The igxCalendarSubheader is available in all selection modes.

In our example we slightly modify the default template and will make the header display the full date and modify the subheader to include the weekday:

<!-- app.component.html-->
    <!-- Modify the header to display the month (in titlecase), day and weekday -->
    <ng-template igxCalendarHeader let-parts>
        {{ parts.month.combined | titlecase }} {{ }} {{ parts.weekday.combined }}
    <ng-template igxCalendarSubheader let-parts>
        <span class="date__el" (click)="parts.monthView()">{{ parts.month.combined }}</span>
        <span class="date__el" (click)="parts.yearView()">{{ parts.year.combined }}</span>

Keep in mind that for Internet Explorer and Edge browsers the date parts will be empty strings, because neither implement the Intl API providing this functionality. (See formatToParts)

To support those browsers we are going to use alternative template using ngIf directive:

<!-- app.component.html-->
<igx-calendar #component locale="fr">
    <div *ngIf="formatParts; else parseTemplate">
        <ng-template igxCalendarHeader let-parts>
            {{ parts.month.combined | titlecase }} {{ }} {{ parts.weekday.combined }}
        <ng-template igxCalendarSubheader let-parts>
            <span class="date__el" (click)="parts.monthView()">{{ parts.month.combined }}</span>
            <span class="date__el" (click)="parts.yearView()">{{ parts.year.combined }}</span>

    <!-- Parse template for browsers not supporting Intl parts-->
    <ng-template #parseTemplate>
        <ng-template igxCalendarHeader let-parts>
            {{ getDatePart(parts, component, 'month') | titlecase }} {{ getDatePart(parts, component, 'day') }} {{ getDatePart(parts, component, 'weekday') }}
        <ng-template igxCalendarSubheader let-parts>
            <span class="date__el" (click)="parts.monthView()">{{ getDatePart(parts, component, 'month') }}</span>
            <span class="date__el" (click)="parts.yearView()">{{ getDatePart(parts, component, 'year') }}</span>

Note that ngIf evaluates the value of the formatParts expression to control which template to use. Let's have a look at the alernative #parseTemplate template: the expressions in the curly brackets invokes the getDatePart method that returns the evaluated value, in our case this is a formatted date part (year, weekday, month, etc.). The parameters passed to the getDatePart are necessary so that formatting is based on the IgxCalendarComponent locale and format options:

// app.component.ts
public intlDateTimeFormat = new Intl.DateTimeFormat() as any;
public formatParts: boolean = this.intlDateTimeFormat.formatToParts;

public getDatePart(val: any, component: any, datePart: string) {
    const date = as Date;
    const locale = component.locale;
    const formatOptions: Intl.DateTimeFormatOptions = {};
    formatOptions[datePart] = component.formatOptions[datePart];

    return date.toLocaleString(locale, formatOptions);

    // instead of toLocaleString we can use Intl.DateTimeFormat.format as well:
    // const partFormatter = new Intl.DateTimeFormat(locale, formatOptions);
    // return partFormatter.format(date);

Having implemented this conditional templating and date parsing we should get consistent formatting across all browsers, let's verify that:

Disabled dates

This section demonstrates the usage of disabledDates functionality. Different single dates or range elements could be added to Array, and passed to the disabledDates descriptor.

this.calendar.disabledDates = [{ type: DateRangeType.Between, dateRange: [
    new Date(2018, 8, 2),
    new Date(2018, 8, 8)

The DateRangeType is used to specify the range that is going to be disabled. For example, DateRangeType.Between will disable the dates between two specific dates in Array. Code snippet above. Check the API table below for all available DateRangeType values.

This feature is covering the situations when we may need to restrict some dates to be selectable and focusable.

Let's create a sample that is disabling dates within specific range of dates:

export class CalendarSample6Component {
    @ViewChild("calendar") public calendar: IgxCalendarComponent;
    public today = new Date(;
    public range = [
        new Date(,, 3),
        new Date(,, 8)

    public ngOnInit() {
        this.calendar.disabledDates = [{ type: DateRangeType.Specific, dateRange: this.range }];

This is the result.

Special dates

Special dates feature is using almost the same configuration principles as Disabled dates. The difference here is dates styling and interaction. You are able to select and focus Special dates.

Lets add a Special dates to our igxCalendar, we are going to create a DateRangeDescriptor item of type DateRangeType.Specific and pass array of dates as dateRange:

export class CalendarSample7Component {
    @ViewChild("calendar") public calendar: IgxCalendarComponent;
    @ViewChild(IgxSnackbarComponent) public snackbar: IgxSnackbarComponent;
    public range = [];

    public selectPTOdays(dates: Date[]) {
        this.range = dates;

    public submitPTOdays(eventArgs) {
        this.calendar.specialDates =
            [{ type: DateRangeType.Specific, dateRange: this.range)];

        this.range.forEach((item) => {

<article class="sample-column calendar-wrapper">
    <span>Request Time Off</span>
    <igx-calendar #calendar
    <button igxButton="raised" (click)="submitPTOdays($event)">Submit Request</button>

We are going to use the selected dates array to define Special dates descriptor.



There are separate views provided by the IgxCalendarModule that can be used independently:

Keyboard navigation

When the igxCalendar component is focused, use:

  • PageUp key to move to the previous month,
  • PageDown key to move to the next month,
  • Shift + PageUp keys to move to the previous year,
  • Shift + PageDown keys to move to the next year,
  • Home key to focus the first day of the current month or first month in view
  • End key to focus the last day of the current month or last month in view
  • Tab key to navigate through the subheader buttons;

When prev or next month buttons (in the subheader) are focused, use:

  • Space or Enter key to scroll into view the next or previous month.

When months button (in the subheader) is focused, use:

  • Space or Enter key to open the months view.

When year button (in the subheader) is focused, use:

  • Space or Enter key to open the decade view.

When a day inside the current month is focused, use:

  • Arrow keys to navigate through the days,
  • Arrow keys to navigate to previous/next month as well,
  • Navigating next from last day in current month or previous from first day in current month, will move focus to next/previos month that is in view.
  • Navigating next from last day in last visible current month or previous from first day in first current month, will change the months in view.
  • Enter key to select the currently focused day.

When a month inside the months view is focused, use:

  • Arrow keys to navigate through the months,
  • Home key to focus the first month inside the months view,
  • End key to focus the last month inside the months view,
  • Enter key to select the currently focused month and close the view.

When an year inside the decade view is focused, use:

  • Arrow keys to navigate through the years,
  • Enter key to select the currently focused year and close the view.

Following version 8.2.0, keyboard navigation will not focus days that are outside of current month, but will rather change the month in view.

Multi View Calendar

Using the monthsViewNumber input the number of displayed months is set. There is no limit on the max value set, and the months are displayed in a flex container horizontally. Showing a multi view calendar, you may want to hide the days that do not belong to the current month, using the hideOutsideDays. Multiview calendar supports all three types of selection. Keyboard navigation moves to next/previous months when those are in view.



To get started with styling the calendar, we need to import the index file, where all the theme functions and component mixins live:

@import '~igniteui-angular/lib/core/styles/themes/index';

Following the simplest approach, we create a new theme that extends the igx-calendar-theme and accepts the $header-background $content-background, $header-text-color, $date-current-text-color, $picker-arrow-color, $picker-arrow-hover-color,$year-current-text-color, $year-hover-text-color, $month-current-text-color, $month-hover-text-color, $picker-text-color and the $picker-text-hover-color parameters.

$my-calendar-theme: igx-calendar-theme(
  $header-background: #345779,
  $content-background: #fdfdfd,
  $header-text-color: #ffffff,
  $date-current-text-color: #2dabe8,
  $picker-arrow-color: #2dabe8,
  $picker-arrow-hover-color: #000000,
  $year-current-text-color: #2dabe8,
  $year-hover-text-color: #2dabe8,
  $month-current-text-color: #2dabe8,
  $month-hover-text-color: #2dabe8,
  $picker-text-color: #2dabe8,
  $picker-text-hover-color: #000000

The last step is to include the component mixins:

 @include igx-calendar($my-calendar-theme);

If the component is using an Emulated ViewEncapsulation, it is necessary to penetrate this encapsulation using ::ng-deep:

:host {
 ::ng-deep {
   @include igx-calendar($my-calendar-theme);

Defining a color palette

Instead of hardcoding the color values like we just did, we can achieve greater flexibility in terms of colors by using the igx-palette and igx-color functions.

igx-palette generates a color palette based on the primary and secondary colors that are passed:

$blue-color: #345779;
$light-gray-color: #fdfdfd;

$my-custom-palette: igx-palette(
    $primary: $blue-color,
    $secondary: $light-gray-color

And then with igx-color we can easily retrieve color from the palette.

$my-calendar-theme: igx-calendar-theme(
  $header-background: igx-color($my-custom-palette, "primary", 500),
  $content-background: igx-color($my-custom-palette, "secondary", 500),
  $header-text-color: igx-color($my-custom-palette, "secondary", 50),
  $date-current-text-color: igx-color($my-custom-palette, "primary", 50),
  $picker-arrow-color: igx-color($my-custom-palette, "primary", 50),
  $picker-arrow-hover-color: igx-color($my-custom-palette, "grays", 900),
  $year-current-text-color: igx-color($my-custom-palette, "primary", 50),
  $year-hover-text-color: igx-color($my-custom-palette, "primary", 50),
  $month-current-text-color: igx-color($my-custom-palette, "primary", 50),
  $month-hover-text-color: igx-color($my-custom-palette, "primary", 50),
  $picker-text-color: igx-color($my-custom-palette, "primary", 50),
  $picker-text-hover-color: igx-color($my-custom-palette, "grays", 900),
  $date-selected-background: igx-color($my-custom-palette, "primary", 500),
  $date-selected-text-color: igx-color($my-custom-palette, "secondary", 500)

The igx-color and igx-palette are powerful functions for generating and retrieving colors. Please refer to Palettes topic for detailed guidance on how to use them.

Using Schemas

Going further with the theming engine, you can build a robust and flexible structure that benefits from schemas. A schema is a recipe of a theme.

Extend one of the two predefined schemas, that are provided for every component, in this case - _light-calendar:

// Extending the light calendar schema
$custom-calendar-schema: extend($_light-calendar,
        header-background: (igx-color: ('primary', 500)),
        content-background: (igx-color: ('secondary', 500)),
        header-text-color: (igx-color: ('secondary', 50)),
        date-current-text-color: (igx-color: ('primary', 50)),
        picker-arrow-color: (igx-color: ('primary', 50)),
        picker-arrow-hover-color: (igx-color: ('grays', 900)),
        year-current-text-color: (igx-color: ('primary', 50)),
        year-hover-text-color: (igx-color: ('primary', 50)),
        month-current-text-color: (igx-color: ('primary', 50)),
        month-hover-text-color: (igx-color: ('primary', 50)),
        picker-text-color: (igx-color: ('primary', 50)),
        picker-text-hover-color: (igx-color: ('grays', 900)),
        date-selected-background: (igx-color: ('primary', 500)),
        date-selected-text-color: (igx-color: ('secondary', 500))

In order to apply our custom schema we have to extend one of the globals (light or dark), which is basically pointing out the components with a custom schema, and after that add it to the respective component themes:

// Extending the global light-schema
$my-custom-schema: extend($light-schema, 
        igx-calendar: $custom-calendar-schema

// Defining our custom theme with the custom schema
$my-calendar-theme: igx-calendar-theme(
  $palette: $my-custom-palette,
  $schema: $my-custom-schema

Don't forget to include the themes in the same way as it was demonstrated above.


API References

Additional Resources

Our community is active and always welcoming to new ideas.