UNPKG

@universal-material/web

Version:
188 lines 6.47 kB
import { __decorate } from "tslib"; import { html, LitElement } from 'lit'; import { property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { styles } from './calendar-base.styles.js'; import { DefaultCalendarAdapter } from './default-calendar-adapter.js'; export class UmCalendarBase extends LitElement { static { this.styles = [styles]; } get year() { return this._displayingMonthDate.getFullYear(); } set year(year) { this._displayingMonthDate.setFullYear(year); this._displayingMonthDate = new Date(this._displayingMonthDate); } get month() { return this._displayingMonthDate.getMonth(); } set month(month) { this._displayingMonthDate.setMonth(month); this._displayingMonthDate = new Date(this._displayingMonthDate); } #currentDate; constructor() { super(); this.weekDays = []; this.dateRenderer = null; this.dateOutsideMonth = false; this.#currentDate = new Date(); this.locale = null; this._innerLocale = navigator.language; this.adapter = new DefaultCalendarAdapter(); this.#currentDate.setHours(0); this.#currentDate.setMinutes(0); this.#currentDate.setSeconds(0); this.#currentDate.setMilliseconds(0); this._displayingMonthDate = new Date(this.#currentDate); this._displayingMonthDate.setDate(1); } connectedCallback() { super.connectedCallback(); this.#setLocaleDependantProperties(); window.addEventListener('languagechange', () => { if (this.locale !== null) { return; } this._innerLocale = navigator.language; this.#setLocaleDependantProperties(); }); } render() { return html ` <div> <u-button-set> <u-button class="month-button" type="button" variant="text"> ${this.adapter.getMonth(this.#getDisplayingMonthDate())} </u-button> <u-icon-button class="previous-month-button" @click=${() => this.#addMonth(-1)}> <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" width="1em" fill="currentColor"> <path d="M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z" /> </svg> </u-icon-button> <u-icon-button @click=${() => this.#addMonth(1)}> <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" width="1em" fill="currentColor"> <path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z" /> </svg> </u-icon-button> </u-button-set> </div> <div class="calendar ${this._getCalendarClassMap()}">${this.#renderWeekDays()}${this.#renderDays()}</div> `; } #renderWeekDays() { return this.weekDays.map(weekDay => html ` <div class="calendar-item"> <span class="week-day">${weekDay}</span> </div> `); } #getDisplayingMonthDate() { return this._getDateFromIsoDate(`${this.year}-${this.month + 1}-1`); } #renderDays() { const date = new Date(this._displayingMonthDate); date.setDate(date.getDate() - date.getDay()); const month = this.month; const year = this.year; const daysTemplates = []; do { for (let i = 0; i < 7; i++) { const dateOutsideMonth = date.getMonth() !== month; const dateClasses = this._getSelectedDateClasses(date); if (!Object.keys(dateClasses).length && this.#currentDate.getTime() === date.getTime()) { dateClasses['current-date'] = true; } if (dateOutsideMonth) { dateClasses['date-outside-month'] = true; } const classes = classMap(dateClasses); const dateTemplate = dateOutsideMonth && !this.dateOutsideMonth ? null : html ` <u-ripple></u-ripple> <span class="date"> ${this.dateRenderer ? this.dateRenderer(new Date(date), this.adapter.getDay(date)) : this.adapter.getDay(date)} </span> `; daysTemplates.push(html ` <div class="calendar-item ${classes}" @click=${this.#handleDateClick(new Date(date))}> ${dateTemplate} </div> `); date.setDate(date.getDate() + 1); } } while (date.getMonth() <= month && date.getFullYear() <= year); return daysTemplates; } #handleDateClick(date) { return () => this._selectDate(date); } _getCalendarClassMap() { return null; } _getDateFromIsoDate(isoDate) { const date = new Date(isoDate); const offsetMs = date.getTimezoneOffset() * 60 * 1000; date.setTime(date.getTime() + offsetMs); return date; } _getDateString(date) { if (!date) { return ''; } return Intl .DateTimeFormat('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit', }) .format(date); } _getDateFromString(dateString) { if (!dateString) { return null; } const dateTime = Date.parse(dateString); if (!dateTime && dateTime !== 0) { return null; } return this._getDateFromIsoDate(dateString); } #addMonth(value) { this.month += value; } #setLocaleDependantProperties() { this.weekDays = this.adapter.getWeekDays(this._innerLocale); } } __decorate([ state() ], UmCalendarBase.prototype, "weekDays", void 0); __decorate([ state() ], UmCalendarBase.prototype, "dateRenderer", void 0); __decorate([ property({ type: Boolean }) ], UmCalendarBase.prototype, "dateOutsideMonth", void 0); __decorate([ state() ], UmCalendarBase.prototype, "_displayingMonthDate", void 0); __decorate([ property() ], UmCalendarBase.prototype, "locale", void 0); //# sourceMappingURL=calendar-base.js.map