UNPKG

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
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} @focus=${changePreview} @blur=${clearPreview} @mouseenter=${changePreview} @mouseleave=${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