Skip to content

Quick Start

Angular Quick Start

@thaparoyal/calendar-angular provides injectable Angular services (not prebuilt UI components).
You bind each service’s Observable state into your own template using the async pipe.

Installation

Terminal window
npm install @thaparoyal/calendar-angular @thaparoyal/calendar-core

Peer dependencies:

  • @angular/core >= 14
  • rxjs >= 7

Import Theme CSS

Add the core theme stylesheet in angular.json:

{
"styles": ["src/styles.css", "node_modules/@thaparoyal/calendar-core/themes/themes.css"]
}

Or import in your component stylesheet:

@import '@thaparoyal/calendar-core/themes/themes.css';

Services

ServicePurpose
CalendarServiceSingle-date calendar navigation and selection
SelectionServiceSingle/range/multiple selection state
DatePickerServiceInput + popup calendar logic
MultiCalendarServiceSide-by-side multi-month calendars

Common Lifecycle Pattern

Each service follows the same pattern: provide it in your component, inject it, and call initialize() in ngOnInit:

import { Component, OnInit } from '@angular/core';
import { CalendarService } from '@thaparoyal/calendar-angular';
@Component({
selector: 'app-calendar',
providers: [CalendarService],
template: `<p>{{ cal.title$ | async }}</p>`,
})
export class CalendarComponent implements OnInit {
constructor(public cal: CalendarService) {}
ngOnInit() {
this.cal.initialize({
config: { calendarType: 'BS', locale: 'en' },
});
}
}

Complete Calendar Template

A fully functional calendar with weekday headers, day/month/year view switching, and all state bindings:

<div class="trc-calendar" data-theme="ocean">
<div class="trc-calendar-header">
<button
class="trc-calendar-nav-button"
(click)="cal.prevMonth()"
[disabled]="cal.isPrevMonthDisabled$ | async"
>
&#8249;
</button>
<button class="trc-calendar-title" (click)="onTitleClick()">{{ cal.title$ | async }}</button>
<button
class="trc-calendar-nav-button"
(click)="cal.nextMonth()"
[disabled]="cal.isNextMonthDisabled$ | async"
>
&#8250;
</button>
</div>
<!-- Day grid -->
<ng-container *ngIf="(cal.viewMode$ | async) === 'day'">
<table class="trc-calendar-grid">
<thead class="trc-calendar-grid-head">
<tr>
<th *ngFor="let name of cal.weekdayNames$ | async" class="trc-calendar-weekday">
{{ name }}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let week of cal.weeks$ | async" class="trc-calendar-week">
<td
*ngFor="let day of week"
class="trc-calendar-cell"
[class.trc-calendar-cell-selected]="day.isSelected"
[class.trc-calendar-cell-today]="day.isToday"
[class.trc-calendar-cell-outside]="day.isOutsideMonth"
[class.trc-calendar-cell-disabled]="day.isDisabled"
>
<button
class="trc-calendar-day"
[disabled]="day.isDisabled"
(click)="cal.selectDate(day.date)"
>
{{ cal.formatDayNumber(day.date.day) }}
</button>
</td>
</tr>
</tbody>
</table>
</ng-container>
<!-- Month picker -->
<div *ngIf="(cal.viewMode$ | async) === 'month'" class="trc-calendar-month-picker">
<button
*ngFor="let m of cal.monthPickerItems$ | async"
class="trc-calendar-month-cell"
[class.trc-calendar-month-current]="m.isCurrentMonth"
(click)="cal.focusDate({ month: m.month }); cal.setViewMode('day')"
>
{{ m.shortName }}
</button>
</div>
<!-- Year picker -->
<div *ngIf="(cal.viewMode$ | async) === 'year'" class="trc-calendar-year-picker">
<button
*ngFor="let y of cal.yearPickerItems$ | async"
class="trc-calendar-year-cell"
[class.trc-calendar-year-current]="y.isCurrentYear"
(click)="cal.focusDate({ year: y.year }); cal.setViewMode('month')"
>
{{ y.year }}
</button>
</div>
</div>

With the component code:

onTitleClick() {
// Cycle: day → month → year → day
this.cal.viewMode$.pipe(take(1)).subscribe(mode => {
if (mode === 'day') this.cal.setViewMode('month');
else if (mode === 'month') this.cal.setViewMode('year');
else this.cal.setViewMode('day');
});
}

Locale and Calendar Type

this.cal.initialize({ config: { calendarType: 'BS', locale: 'en' } }); // Bikram Sambat
this.cal.initialize({ config: { calendarType: 'AD', locale: 'en' } }); // Gregorian
this.cal.initialize({ config: { calendarType: 'BS', locale: 'ne' } }); // Nepali numerals

Next Steps