@progress/kendo-angular-dateinputs
Version:
Kendo UI for Angular Date Inputs Package - Everything you need to add date selection functionality to apps (DatePicker, TimePicker, DateInput, DateRangePicker, DateTimePicker, Calendar, and MultiViewCalendar).
225 lines (224 loc) • 10.9 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
/* eslint-disable @angular-eslint/component-selector */
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, TemplateRef, ViewChild } from '@angular/core';
import { IntlService } from '@progress/kendo-angular-intl';
import { BusViewService } from './services/bus-view.service';
import { CalendarDOMService } from './services/dom.service';
import { CalendarViewEnum } from './models/view.enum';
import { VirtualizationComponent } from '../virtualization/virtualization.component';
import { MIN_DATE, MAX_DATE } from '../defaults';
import { cloneDate } from '@progress/kendo-date-math';
import { dateInRange } from '../util';
import { closestInScope } from '../common/dom-queries';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { KForOf } from './for.directive';
import { EventsOutsideAngularDirective } from '@progress/kendo-angular-common';
import * as i0 from "@angular/core";
import * as i1 from "./services/bus-view.service";
import * as i2 from "./services/dom.service";
import * as i3 from "@progress/kendo-angular-intl";
const ITEMS_COUNT = 30;
/**
* @hidden
*/
export class NavigationComponent {
bus;
dom;
intl;
cdr;
renderer;
activeView;
min = new Date(MIN_DATE);
max = new Date(MAX_DATE);
focusedDate = new Date();
templateRef;
valueChange = new EventEmitter();
pageChange = new EventEmitter();
virtualization;
list;
get getComponentClass() {
return true;
}
activeViewValue;
service;
dates = [];
style;
take = ITEMS_COUNT;
skip;
total;
itemHeight;
topOffset;
bottomOffset;
maxViewHeight;
indexToScroll = -1;
intlSubscription;
constructor(bus, dom, intl, cdr, renderer) {
this.bus = bus;
this.dom = dom;
this.intl = intl;
this.cdr = cdr;
this.renderer = renderer;
}
ngOnInit() {
this.dom.ensureHeights();
const calendarHeight = this.dom.calendarHeight;
this.itemHeight = this.dom.navigationItemHeight;
this.maxViewHeight = this.dom.monthViewHeight;
this.topOffset = (calendarHeight - this.itemHeight) / 2;
this.bottomOffset = calendarHeight - this.itemHeight;
this.intlSubscription = this.intl.changes.subscribe(this.intlChange.bind(this));
}
ngOnChanges(changes) {
this.service = this.bus.service(this.activeView);
if (!this.service) {
return;
}
this.activeViewValue = CalendarViewEnum[this.activeView];
const viewDate = dateInRange(this.focusedDate, this.min, this.max);
const total = this.service.total(this.min, this.max);
const totalChanged = this.total && this.total !== total;
this.skip = this.service.skip(viewDate, this.min);
this.total = total;
if (totalChanged || !this.service.isInArray(viewDate, this.dates)) {
this.dates = this.service.datesList(viewDate, this.getTake(this.skip));
}
if (!!changes.focusedDate || totalChanged) {
this.indexToScroll = this.service.skip(this.focusedDate, this.min);
}
}
ngOnDestroy() {
if (this.intlSubscription) {
this.intlSubscription.unsubscribe();
}
}
ngAfterViewInit() {
if (this.indexToScroll === -1) {
return;
}
this.virtualization.scrollToIndex(this.indexToScroll);
this.indexToScroll = -1;
}
ngAfterViewChecked() {
if (this.indexToScroll === -1) {
return;
}
this.virtualization.scrollToIndex(this.indexToScroll);
this.indexToScroll = -1;
}
onPageChange({ skip }) {
this.dates = this.service.datesList(this.service.addToDate(this.min, skip), this.getTake(skip));
this.pageChange.emit();
}
scrollChange({ offset }) {
const el = this.list.nativeElement;
const translate = `translateY(${offset}px)`;
this.renderer.setStyle(el, 'transform', translate);
this.renderer.setStyle(el, '-ms-transform', translate);
}
handleDateChange(args) {
const item = closestInScope(args.target, node => node.hasAttribute('data-date-index'), this.list.nativeElement);
if (item) {
const index = parseInt(item.getAttribute('data-date-index'), 10);
const candidate = this.dates[index];
this.valueChange.emit(cloneDate(candidate));
}
}
getTake(skip) {
return Math.min(this.total - skip, this.take);
}
intlChange() {
if (this.activeView === CalendarViewEnum.month) {
this.cdr.markForCheck();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationComponent, deps: [{ token: i1.BusViewService }, { token: i2.CalendarDOMService }, { token: i3.IntlService }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NavigationComponent, isStandalone: true, selector: "kendo-calendar-navigation", inputs: { activeView: "activeView", min: "min", max: "max", focusedDate: "focusedDate", templateRef: "templateRef" }, outputs: { valueChange: "valueChange", pageChange: "pageChange" }, host: { properties: { "class.k-calendar-navigation": "this.getComponentClass" } }, viewQueries: [{ propertyName: "virtualization", first: true, predicate: VirtualizationComponent, descendants: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
<span class="k-calendar-navigation-highlight"></span>
<kendo-virtualization
[skip]="skip"
[take]="take"
[total]="total"
[itemHeight]="itemHeight"
[topOffset]="topOffset"
[bottomOffset]="bottomOffset"
[maxScrollDifference]="maxViewHeight"
(pageChange)="onPageChange($event)"
(scrollChange)="scrollChange($event)"
>
<ul #list class="k-reset" [kendoEventsOutsideAngular]="{ click: handleDateChange }" [scope]="this">
<li *kFor="let date of dates; let index=index" [attr.data-date-index]="index">
<span [class.k-calendar-navigation-marker]="service.isRangeStart(date)">
<ng-template [ngIf]="!templateRef">{{service.navigationTitle(date)}}</ng-template>
<ng-template
[ngIf]="templateRef"
[ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{ $implicit: service.navigationTitle(date), activeView: activeViewValue, date: date }"
></ng-template>
</span>
</li>
</ul>
</kendo-virtualization>
`, isInline: true, dependencies: [{ kind: "component", type: VirtualizationComponent, selector: "kendo-virtualization", inputs: ["direction", "itemHeight", "itemWidth", "topOffset", "bottomOffset", "maxScrollDifference", "scrollOffsetSize", "scrollDuration", "skip", "take", "total"], outputs: ["activeIndexChange", "pageChange", "scrollChange"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "directive", type: KForOf, selector: "[kFor][kForOf]", inputs: ["kForOf", "kForTrackBy", "kForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationComponent, decorators: [{
type: Component,
args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'kendo-calendar-navigation',
template: `
<span class="k-calendar-navigation-highlight"></span>
<kendo-virtualization
[skip]="skip"
[take]="take"
[total]="total"
[itemHeight]="itemHeight"
[topOffset]="topOffset"
[bottomOffset]="bottomOffset"
[maxScrollDifference]="maxViewHeight"
(pageChange)="onPageChange($event)"
(scrollChange)="scrollChange($event)"
>
<ul #list class="k-reset" [kendoEventsOutsideAngular]="{ click: handleDateChange }" [scope]="this">
<li *kFor="let date of dates; let index=index" [attr.data-date-index]="index">
<span [class.k-calendar-navigation-marker]="service.isRangeStart(date)">
<ng-template [ngIf]="!templateRef">{{service.navigationTitle(date)}}</ng-template>
<ng-template
[ngIf]="templateRef"
[ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{ $implicit: service.navigationTitle(date), activeView: activeViewValue, date: date }"
></ng-template>
</span>
</li>
</ul>
</kendo-virtualization>
`,
standalone: true,
imports: [VirtualizationComponent, EventsOutsideAngularDirective, KForOf, NgIf, NgTemplateOutlet]
}]
}], ctorParameters: function () { return [{ type: i1.BusViewService }, { type: i2.CalendarDOMService }, { type: i3.IntlService }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; }, propDecorators: { activeView: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], focusedDate: [{
type: Input
}], templateRef: [{
type: Input
}], valueChange: [{
type: Output
}], pageChange: [{
type: Output
}], virtualization: [{
type: ViewChild,
args: [VirtualizationComponent, { static: false }]
}], list: [{
type: ViewChild,
args: ['list', { static: true }]
}], getComponentClass: [{
type: HostBinding,
args: ["class.k-calendar-navigation"]
}] } });