@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).
196 lines (195 loc) • 8.27 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Injectable } from '@angular/core';
import { CalendarViewEnum } from '../models/view.enum';
import { isDocumentAvailable } from '@progress/kendo-angular-common';
import { domContainerFactory as containerFactory } from '../../util';
import { isPresent } from '../../common/utils';
import * as i0 from "@angular/core";
const div = containerFactory('div');
const ul = containerFactory('ul');
const li = containerFactory('li');
const td = containerFactory('td');
const th = containerFactory('th');
const tr = containerFactory('tr');
const tbody = containerFactory('tbody');
const thead = containerFactory('thead');
const table = containerFactory('table');
const monthHeader = () => (div(`
<span class="k-button k-button-md k-rounded-md k-button-flat k-button-flat-base k-calendar-title">March 2017</span>
<span class="k-spacer"></span>
<span class="k-calendar-nav">
<button class="k-calendar-nav-today k-button k-button-md k-button-flat k-button-flat-base k-rounded-md">TODAY</button>
</span>
`, 'k-calendar-header'));
const monthWeekHeader = () => (table([
thead([
tr([th('MO', 'k-calendar-th')], 'k-calendar-tr')
], 'k-calendar-thead')
], 'k-calendar-weekdays k-calendar-table'));
const repeat = (count, mapper) => new Array(count).fill('1').map(mapper);
const content = (rows, cells = 1) => (table([
tbody([tr([th('1', 'k-calendar-th')], 'k-calendar-tr')].concat(repeat(rows, () => tr(repeat(cells, c => td(`<span class="k-link">${c}</span>`, 'k-calendar-td')), 'k-calendar-tr'))), 'k-calendar-tbody')
], 'k-calendar-table'));
const scrollable = (children) => div(children, 'k-flex k-content k-scrollable');
const view = (contentElement, className, renderWeekHeader) => (div([
monthHeader(),
renderWeekHeader ? monthWeekHeader() : null,
scrollable([contentElement, contentElement])
], className, { left: '-10000px', position: 'absolute' }));
const navigationList = (() => {
let navElement;
return () => {
if (!isDocumentAvailable) {
return null;
}
if (!navElement) {
navElement = div([scrollable([ul([li('<span>FEB</span>')])])], 'k-calendar-navigation', { left: '0px', position: 'absolute' });
}
return navElement;
};
})();
const viewFactory = ({ cells, rows }, className, renderWeekHeader) => {
let viewElement;
return () => {
if (!isDocumentAvailable) {
return null;
}
if (!viewElement) {
viewElement = view(content(rows, cells), className, renderWeekHeader);
}
return viewElement;
};
};
const getScrollable = (element) => element.querySelector('.k-scrollable');
const horizontal = element => {
const scrollableElement = getScrollable(element);
scrollableElement.classList.add('k-scrollable-horizontal');
return element;
};
const monthView = viewFactory({ cells: 7, rows: 6 }, 'k-vstack k-calendar-view k-calendar-monthview', true);
const yearView = viewFactory({ cells: 4, rows: 3 }, 'k-vstack k-calendar-view k-calendar-yearview', false);
const decadeView = viewFactory({ cells: 4, rows: 3 }, 'k-vstack k-calendar-view k-calendar-decadeview', false);
const horzMonthView = () => horizontal(monthView());
const horzYearView = () => horizontal(yearView());
const horzDecadeView = () => horizontal(decadeView());
const height = (element) => (parseFloat(window.getComputedStyle(element).height) || element.offsetHeight);
const width = (element) => {
const styles = window.getComputedStyle(element);
const computed = parseFloat(styles.width)
+ parseFloat(styles.paddingLeft)
+ parseFloat(styles.paddingRight);
return computed || element.offsetWidth;
};
const getBody = (element) => element.querySelector('tbody');
/**
* @hidden
*/
export class CalendarDOMService {
//heights
calendarHeight;
headerHeight;
monthViewHeight;
yearViewHeight;
decadeViewHeight;
centuryViewHeight;
navigationItemHeight;
scrollableContentHeight;
scrollableYearContentHeight;
//widths
calendarWidth;
monthViewWidth;
yearViewWidth;
decadeViewWidth;
centuryViewWidth;
scrollableContentWidth;
hostContainer;
ensureHeights() {
if (this.calendarHeight !== undefined) {
return;
}
this.calculateHeights();
}
calculateHeights(container) {
if (!isDocumentAvailable()) {
return;
}
this.hostContainer = container;
this.batch(monthView(), (contentElement) => {
const viewElement = getBody(contentElement);
this.calendarHeight = height(contentElement);
this.monthViewHeight = height(viewElement);
this.headerHeight = height(viewElement.children[0]);
this.scrollableContentHeight = height(getScrollable(contentElement));
});
this.batch(horzMonthView(), (contentElement) => {
const viewElement = getBody(contentElement);
this.calendarWidth = width(contentElement);
this.monthViewWidth = width(viewElement);
this.scrollableContentWidth = width(getScrollable(contentElement));
});
this.batch(yearView(), (contentElement) => {
this.yearViewHeight = height(getBody(contentElement));
this.scrollableYearContentHeight = height(getScrollable(contentElement));
});
this.batch(horzYearView(), (contentElement) => {
this.yearViewWidth = width(getBody(contentElement));
});
this.batch(decadeView(), (contentElement) => {
this.decadeViewHeight = height(getBody(contentElement));
this.centuryViewHeight = this.decadeViewHeight;
});
this.batch(horzDecadeView(), (contentElement) => {
this.decadeViewWidth = width(getBody(contentElement));
this.centuryViewWidth = this.decadeViewWidth;
});
this.batch(navigationList(), (contentElement) => {
this.navigationItemHeight = height(contentElement.querySelector('li'));
});
}
viewHeight(viewType) {
return this.viewDimension(viewType, 'height');
}
viewWidth(viewType) {
return this.viewDimension(viewType, 'width');
}
viewDimension(viewType, dimension) {
const viewProp = dimension === 'height' ? 'ViewHeight' : 'ViewWidth';
switch (viewType) {
case CalendarViewEnum.month:
return this[`month${viewProp}`];
case CalendarViewEnum.year:
return this[`year${viewProp}`];
case CalendarViewEnum.decade:
return this[`decade${viewProp}`];
case CalendarViewEnum.century:
return this[`century${viewProp}`];
default:
return 1;
}
}
batch(contentElement, action) {
if (!isPresent(this.hostContainer)) {
return;
}
const hostClone = this.hostContainer.cloneNode();
document.body.appendChild(hostClone);
try {
const appendedContent = hostClone.appendChild(contentElement);
action(appendedContent);
}
finally {
document.body.removeChild(hostClone);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalendarDOMService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalendarDOMService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalendarDOMService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });