igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
378 lines • 14.1 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var IgcDaysViewComponent_1;
import { html, nothing } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { themes } from '../../../theming/theming-decorator.js';
import { addKeybindings } from '../../common/controllers/key-bindings.js';
import { blazorIndirectRender } from '../../common/decorators/blazorIndirectRender.js';
import { blazorSuppressComponent } from '../../common/decorators/blazorSuppressComponent.js';
import { watch } from '../../common/decorators/watch.js';
import { registerComponent } from '../../common/definitions/register.js';
import { IgcCalendarResourceStringEN } from '../../common/i18n/calendar.resources.js';
import { createDateTimeFormatters } from '../../common/localization/intl-formatters.js';
import { EventEmitterMixin } from '../../common/mixins/event-emitter.js';
import { chunk, first, last, partNameMap, take } from '../../common/util.js';
import { IgcCalendarBaseComponent } from '../base.js';
import { areSameMonth, calendarRange, generateMonth, getViewElement, isDateInRanges, isNextMonth, isPreviousMonth, } from '../helpers.js';
import { CalendarDay, daysInWeek } from '../model.js';
import { styles } from '../themes/days-view.base.css.js';
import { all } from '../themes/days.js';
import { DateRangeType } from '../types.js';
let IgcDaysViewComponent = IgcDaysViewComponent_1 = class IgcDaysViewComponent extends EventEmitterMixin(IgcCalendarBaseComponent) {
static register() {
registerComponent(IgcDaysViewComponent_1);
}
set rangePreviewDate(value) {
this._rangePreviewDate = value ? CalendarDay.from(value) : undefined;
}
get rangePreviewDate() {
return this._rangePreviewDate?.native;
}
localeChange() {
this._intl.locale = this.locale;
}
weekDayFormatChange() {
this._intl.update({ weekday: { weekday: this.weekDayFormat } });
}
datesChange() {
this.dates = Array.from(generateMonth(this._activeDate, this._firstDayOfWeek));
}
constructor() {
super();
this.active = false;
this.hideLeadingDays = false;
this.hideTrailingDays = false;
this.resourceStrings = IgcCalendarResourceStringEN;
this.weekDayFormat = 'narrow';
this._intl = createDateTimeFormatters(this.locale, {
weekday: { weekday: this.weekDayFormat },
label: { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },
ariaWeekday: { weekday: 'long' },
});
addKeybindings(this, {
bindingDefaults: { preventDefault: true },
}).setActivateHandler(this.handleInteraction);
this.addEventListener('click', this.handleInteraction);
}
connectedCallback() {
super.connectedCallback();
this.role = 'grid';
}
focusActiveDate() {
this.activeDay.focus();
}
handleInteraction(event) {
const value = getViewElement(event);
if (value !== -1) {
const date = CalendarDay.from(new Date(value));
if (this._rangePreviewDate) {
this.setRangePreviewDate();
}
if (this.selectDate(date)) {
this.emitEvent('igcChange', { detail: date.native });
}
if (event.type === 'click') {
event.stopPropagation();
this.emitEvent('igcActiveDateChange', { detail: date.native });
this._activeDate = date;
}
}
}
_selectMultiple(day) {
const values = this._values;
const idx = values.findIndex((v) => v.equalTo(day));
idx < 0 ? values.push(day) : values.splice(idx, 1);
values.sort((a, b) => a.timestamp - b.timestamp);
this._values = Array.from(values);
}
_selectRange(day) {
let values = this._values;
if (values.length !== 1) {
values = [day];
}
else {
const beginning = first(values);
if (beginning.equalTo(day)) {
this._values = [];
return;
}
values = beginning.greaterThan(day)
? Array.from(calendarRange({ start: day, end: beginning }))
: Array.from(calendarRange({ start: beginning, end: day }));
values.push(last(values).add('day', 1));
}
this._values = values.filter((v) => !isDateInRanges(v, this._disabledDates));
}
selectDate(value) {
if (isDateInRanges(value, this._disabledDates)) {
return false;
}
if (this._isSingle) {
if (this._value?.equalTo(value)) {
return false;
}
this._value = value;
}
if (this._isMultiple) {
this._selectMultiple(value);
}
if (this._isRange) {
this._selectRange(value);
}
return true;
}
isSelected(day) {
if (isDateInRanges(day, this._disabledDates)) {
return false;
}
if (this._isSingle) {
return !!this._value && this._value.equalTo(day);
}
if (!this._hasValues) {
return false;
}
if (this._isMultiple) {
return isDateInRanges(day, [
{
type: DateRangeType.Specific,
dateRange: this.values,
},
]);
}
return isDateInRanges(day, [
{
type: DateRangeType.Between,
dateRange: [first(this._values).native, last(this._values).native],
},
]);
}
setRangePreviewDate(day) {
this._rangePreviewDate = day;
this.emitEvent('igcRangePreviewDateChange', {
detail: day ? day.native : undefined,
});
}
changeRangePreview(day) {
if (this._values.length === 1 && !first(this._values).equalTo(day)) {
this.setRangePreviewDate(day);
}
}
clearRangePreview() {
if (this._rangePreviewDate) {
this.setRangePreviewDate();
}
}
isFirstInRange(day) {
if (this._isSingle || !this._hasValues) {
return false;
}
const target = this._rangePreviewDate?.lessThan(first(this._values))
? this._rangePreviewDate
: first(this._values);
return target.equalTo(day);
}
isLastInRange(day) {
if (this._isSingle || !this._hasValues) {
return false;
}
const target = this._rangePreviewDate?.greaterThan(last(this._values))
? this._rangePreviewDate
: last(this._values);
return target.equalTo(day);
}
isRangeDate(day) {
const isSingleRange = this._values.length === 1;
if (!this._hasValues || (isSingleRange && !this._rangePreviewDate)) {
return false;
}
const min = first(this._values);
const max = isSingleRange ? this._rangePreviewDate : last(this._values);
return isDateInRanges(day, [
{
type: DateRangeType.Between,
dateRange: [min.native, max.native],
},
]);
}
isRangePreview(day) {
if (!(this._hasValues && this._rangePreviewDate)) {
return false;
}
return isDateInRanges(day, [
{
type: DateRangeType.Between,
dateRange: [first(this._values).native, this._rangePreviewDate.native],
},
]);
}
intlFormatDay(day) {
const fmt = this._intl.get('label');
if (this._rangePreviewDate?.equalTo(day)) {
return fmt.formatRange(first(this._values).native, this._rangePreviewDate.native);
}
if (this.isFirstInRange(day) || this.isLastInRange(day)) {
return fmt.formatRange(first(this._values).native, last(this._values).native);
}
return fmt.format(day.native);
}
getDayHandlers(day) {
const range = this._isRange;
const changePreview = range
? this.changeRangePreview.bind(this, day)
: nothing;
const clearPreview = range ? this.clearRangePreview : nothing;
return { changePreview, clearPreview };
}
getDayProperties(day, today) {
const isRange = this._isRange;
const disabled = isDateInRanges(day, this._disabledDates);
const hiddenLeading = this.hideLeadingDays && isPreviousMonth(day, this._activeDate);
const hiddenTrailing = this.hideTrailingDays && isNextMonth(day, this._activeDate);
const hidden = hiddenLeading || hiddenTrailing;
const inactive = !areSameMonth(day, this._activeDate);
return {
date: true,
disabled: disabled || hidden,
first: this.isFirstInRange(day),
last: this.isLastInRange(day),
range: isRange && this.isRangeDate(day),
preview: isRange && this.isRangePreview(day),
current: !inactive && day.equalTo(today),
inactive,
hidden,
weekend: day.weekend,
single: !isRange,
selected: !disabled && this.isSelected(day),
special: isDateInRanges(day, this._specialDates) && !inactive,
};
}
renderDay(day, today) {
const ariaLabel = this.intlFormatDay(day);
const { changePreview, clearPreview } = this.getDayHandlers(day);
const props = this.getDayProperties(day, today);
const parts = partNameMap(props);
return html `
<span part=${parts}>
<span
role="gridcell"
part=${parts.replace('date', 'date-inner')}
aria-label=${ariaLabel}
aria-disabled=${props.disabled}
aria-selected=${props.selected}
data-value=${day.timestamp}
tabindex=${day.equalTo(this._activeDate) ? 0 : -1}
=${changePreview}
=${clearPreview}
=${changePreview}
=${clearPreview}
>
${day.date}
</span>
</span>
`;
}
renderHeaderWeekNumber() {
return html `
<span role="columnheader" part="label week-number first">
<span part="week-number-inner first">
${this.resourceStrings.weekLabel}
</span>
</span>
`;
}
renderWeekNumber(start, last) {
return html `
<span role="rowheader" part=${partNameMap({ 'week-number': true, last })}>
<span part=${partNameMap({ 'week-number-inner': true, last })}>
${start.week}
</span>
</span>
`;
}
renderHeaders() {
const label = this._intl.get('weekday');
const aria = this._intl.get('ariaWeekday');
const days = take(generateMonth(this._activeDate, this._firstDayOfWeek), daysInWeek);
const weekNumber = this.showWeekNumbers
? this.renderHeaderWeekNumber()
: nothing;
const headers = days.map((day) => html `
<span
role="columnheader"
part="label"
aria-label=${aria.format(day.native)}
>
<span part="label-inner">${label.format(day.native)}</span>
</span>
`);
return html `
<div role="row" part="days-row first">${weekNumber}${headers}</div>
`;
}
*renderWeeks() {
const today = CalendarDay.today;
const weeks = Array.from(chunk(this.dates, daysInWeek));
const last = weeks.length - 1;
for (const [idx, week] of weeks.entries()) {
yield html `
<div role="row" part="days-row">
${this.showWeekNumbers
? this.renderWeekNumber(week[0], idx === last)
: nothing}
${week.map((day) => this.renderDay(day, today))}
</div>
`;
}
}
render() {
return html `${this.renderHeaders()}${this.renderWeeks()}`;
}
};
IgcDaysViewComponent.tagName = 'igc-days-view';
IgcDaysViewComponent.styles = styles;
__decorate([
state()
], IgcDaysViewComponent.prototype, "dates", void 0);
__decorate([
query('[tabindex="0"]')
], IgcDaysViewComponent.prototype, "activeDay", void 0);
__decorate([
property({ type: Boolean })
], IgcDaysViewComponent.prototype, "active", void 0);
__decorate([
property({ type: Boolean, attribute: 'hide-leading-days' })
], IgcDaysViewComponent.prototype, "hideLeadingDays", void 0);
__decorate([
property({ type: Boolean, attribute: 'hide-trailing-days' })
], IgcDaysViewComponent.prototype, "hideTrailingDays", void 0);
__decorate([
property({ attribute: false })
], IgcDaysViewComponent.prototype, "rangePreviewDate", null);
__decorate([
property({ attribute: false })
], IgcDaysViewComponent.prototype, "resourceStrings", void 0);
__decorate([
property({ attribute: 'week-day-format' })
], IgcDaysViewComponent.prototype, "weekDayFormat", void 0);
__decorate([
watch('locale')
], IgcDaysViewComponent.prototype, "localeChange", null);
__decorate([
watch('weekDayFormat')
], IgcDaysViewComponent.prototype, "weekDayFormatChange", null);
__decorate([
watch('weekStart'),
watch('activeDate')
], IgcDaysViewComponent.prototype, "datesChange", null);
IgcDaysViewComponent = IgcDaysViewComponent_1 = __decorate([
blazorSuppressComponent,
blazorIndirectRender,
themes(all)
], IgcDaysViewComponent);
export default IgcDaysViewComponent;
//# sourceMappingURL=days-view.js.map