UNPKG

ng-zorro-antd-mobile

Version:

An enterprise-class mobile UI components based on Ant Design and Angular

1 lines 107 kB
{"version":3,"file":"ng-zorro-antd-mobile-calendar.mjs","sources":["../../components/calendar/date/DataTypes.ts","../../components/calendar/util/index.ts","../../components/calendar/datepicker/datepicker.base.component.ts","../../components/calendar/week-panel/week-panel.component.ts","../../components/calendar/week-panel/week-panel.component.html","../../components/calendar/single-month/single-month.component.ts","../../components/calendar/single-month/single-month.component.html","../../components/calendar/datepicker/datepicker.component.ts","../../components/calendar/datepicker/datepicker.component.html","../../components/calendar/header/header.component.ts","../../components/calendar/header/header.component.html","../../components/calendar/timepicker/timepicker.component.ts","../../components/calendar/timepicker/timepicker.component.html","../../components/calendar/confirm-panel/confirm-panel.component.ts","../../components/calendar/confirm-panel/confirm-panel.component.html","../../components/calendar/shortcut-panel/shortcut-panel.component.ts","../../components/calendar/shortcut-panel/shortcut-panel.component.html","../../components/calendar/calendar.component.ts","../../components/calendar/calendar.component.html","../../components/calendar/calendar.module.ts","../../components/calendar/ng-zorro-antd-mobile-calendar.ts"],"sourcesContent":["export namespace DateModels {\n export enum SelectType {\n None,\n Single,\n All,\n Only,\n Start,\n Middle,\n End\n }\n\n export interface Locale {\n title: string;\n today: string;\n month: string;\n year: string;\n am: string;\n pm: string;\n dateFormat: string;\n dateTimeFormat: string;\n noChoose: string;\n week: string[];\n clear: string;\n selectTime: string;\n selectStartTime: string;\n selectEndTime: string;\n start: string;\n end: string;\n begin: string;\n over: string;\n begin_over: string;\n confirm: string;\n monthTitle: string;\n loadPrevMonth: string;\n yesterday: string;\n lastWeek: string;\n lastMonth: string;\n }\n\n export interface CellData {\n tick: number;\n dayOfMonth: number;\n selected: SelectType;\n isFirstOfMonth: boolean;\n isLastOfMonth: boolean;\n outOfDate: boolean;\n }\n\n export interface ExtraData {\n info?: string;\n disable?: boolean;\n cellCls?: any;\n cellRender?: any;\n }\n\n export interface MonthData {\n title: string;\n firstDate: Date;\n lastDate: Date;\n weeks: DateModels.CellData[][];\n component?: any;\n height?: number;\n y?: number;\n updateLayout?: Function;\n componentRef?: any;\n }\n}\n","import { DateModels } from '../date/DataTypes';\n\nexport const mergeDateTime = (date?: Date, time?: Date) => {\n date = date || new Date();\n if (!time) {\n return date;\n }\n return new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n time.getHours(),\n time.getMinutes(),\n time.getSeconds()\n );\n};\n\nexport const formatDate = (date: Date, format: string, locale?: DateModels.Locale) => {\n const week = locale && locale.week;\n\n let o: { [key: string]: any } = {\n 'M+': date.getMonth() + 1,\n 'd+': date.getDate(),\n 'h+': date.getHours(),\n 'm+': date.getMinutes(),\n 's+': date.getSeconds(),\n 'q+': Math.floor((date.getMonth() + 3) / 3),\n 'w+': week && week[date.getDay()],\n S: date.getMilliseconds()\n };\n if (/(y+)/.test(format)) {\n format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));\n }\n for (let k in o) {\n if (new RegExp('(' + k + ')').test(format)) {\n format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));\n }\n }\n return format;\n};\n\nexport const isSameDate = (day_one: Date, day_two: Date) => {\n if (!day_one || !day_two) {\n console.error('isSameDate function need two params');\n return 'need two params';\n }\n const compareDate = day_one.getDate() === day_two.getDate();\n const compareMonth = day_one.getMonth() === day_two.getMonth();\n const compareYear = day_one.getFullYear() === day_two.getFullYear();\n\n return compareDate && compareMonth && compareYear;\n};\n","import { DateModels } from '../date/DataTypes';\nimport { DatepickerPropsType } from './datepicker.props.component';\nimport { formatDate } from '../util';\nimport { zh_CN } from 'ng-zorro-antd-mobile/locale-provider';\n\nexport interface DatepickerStateType {\n months: DateModels.MonthData[];\n}\n\nexport class CalendarDatePickerBaseComponent {\n props = {\n prefixCls: 'rmc-calendar',\n infinite: false,\n infiniteOpt: false,\n defaultDate: new Date(),\n initalMonths: 6,\n locale: zh_CN.Calendar\n } as DatepickerPropsType;\n\n state: any = {\n months: []\n };\n\n visibleMonth: DateModels.MonthData[] = [];\n genMonthComponent: (data) => {};\n\n constructor() {}\n\n init() {\n const { initalMonths = 6, defaultDate } = this.props;\n for (let i = 0; i < initalMonths; i++) {\n if (this.canLoadNext()) {\n this.genMonthData(defaultDate, i);\n }\n }\n this.visibleMonth = [...this.state.months];\n }\n\n receiveProps(oldValue: DatepickerPropsType, newValue: DatepickerPropsType) {\n if (oldValue && newValue) {\n if (oldValue.startDate !== newValue.startDate || oldValue.endDate !== newValue.endDate) {\n if (oldValue.startDate) {\n this.selectDateRange(oldValue.startDate, oldValue.endDate, true);\n }\n if (newValue.startDate) {\n this.selectDateRange(newValue.startDate, newValue.endDate);\n }\n }\n }\n }\n\n getMonthDate(date = new Date(), addMonth = 0) {\n const y = date.getFullYear(),\n m = date.getMonth();\n return {\n firstDate: new Date(y, m + addMonth, 1),\n lastDate: new Date(y, m + 1 + addMonth, 0)\n };\n }\n\n canLoadPrev() {\n const { minDate } = this.props;\n return (\n !minDate ||\n this.state.months.length <= 0 ||\n +this.getMonthDate(minDate).firstDate < +this.state.months[0].firstDate\n );\n }\n\n canLoadNext() {\n const { maxDate } = this.props;\n return (\n !maxDate ||\n this.state.months.length <= 0 ||\n +this.getMonthDate(maxDate).firstDate > +this.state.months[this.state.months.length - 1].firstDate\n );\n }\n\n getDateWithoutTime = (date?: Date) => {\n if (!date) {\n return 0;\n }\n return +new Date(date.getFullYear(), date.getMonth(), date.getDate());\n };\n\n genWeekData = (firstDate: Date) => {\n const minDateTime = this.getDateWithoutTime(this.props.minDate);\n const maxDateTime = this.getDateWithoutTime(this.props.maxDate) || Number.POSITIVE_INFINITY;\n\n const weeks: DateModels.CellData[][] = [];\n const nextMonth = this.getMonthDate(firstDate, 1).firstDate;\n let currentDay = firstDate;\n let currentWeek: DateModels.CellData[] = [];\n weeks.push(currentWeek);\n\n let startWeekday = currentDay.getDay();\n if (startWeekday > 0) {\n for (let i = 0; i < startWeekday; i++) {\n currentWeek.push({} as DateModels.CellData);\n }\n }\n while (currentDay < nextMonth) {\n if (currentWeek.length === 7) {\n currentWeek = [];\n weeks.push(currentWeek);\n }\n const dayOfMonth = currentDay.getDate();\n const tick = +currentDay;\n currentWeek.push({\n tick,\n dayOfMonth,\n selected: DateModels.SelectType.None,\n isFirstOfMonth: dayOfMonth === 1,\n isLastOfMonth: false,\n outOfDate: tick < minDateTime || tick > maxDateTime\n });\n const year = currentDay.getFullYear();\n const month = currentDay.getMonth();\n const date = currentDay.getDate();\n currentDay = new Date(year, month, date + 1);\n }\n currentWeek[currentWeek.length - 1].isLastOfMonth = true;\n return weeks;\n };\n\n genMonthData(date?: Date, addMonth: number = 0) {\n if (!date) {\n date = addMonth >= 0 ? this.state.months[this.state.months.length - 1].firstDate : this.state.months[0].firstDate;\n }\n if (!date) {\n date = new Date();\n }\n const { locale } = this.props;\n const { firstDate, lastDate } = this.getMonthDate(date, addMonth);\n const weeks = this.genWeekData(firstDate);\n const title = formatDate(firstDate, locale ? locale.monthTitle : 'yyyy/MM', this.props.locale);\n const data = {\n title,\n firstDate,\n lastDate,\n weeks\n } as DateModels.MonthData;\n data.component = this.genMonthComponent(data);\n if (addMonth >= 0) {\n this.state.months.push(data);\n } else {\n this.state.months.unshift(data);\n }\n const { startDate, endDate } = this.props;\n if (startDate) {\n this.selectDateRange(startDate, endDate);\n }\n return data;\n }\n\n inDate(date: number, tick: number) {\n return date <= tick && tick < date + 24 * 3600000;\n }\n\n selectDateRange = (startDate: Date, endDate?: Date, clear = false) => {\n const { getDateExtra, type, onSelectHasDisableDate } = this.props;\n if (type === 'one') {\n endDate = undefined;\n }\n const time1 = this.getDateWithoutTime(startDate),\n time2 = this.getDateWithoutTime(endDate);\n const startDateTick = !time2 || time1 < time2 ? time1 : time2;\n const endDateTick = time2 && time1 > time2 ? time1 : time2;\n\n const startMonthDate = this.getMonthDate(new Date(startDateTick)).firstDate;\n const endMonthDate = endDateTick ? new Date(endDateTick) : this.getMonthDate(new Date(startDateTick)).lastDate;\n\n let unuseable: number[] = [],\n needUpdate = false;\n this.state.months\n .filter(m => {\n return m.firstDate >= startMonthDate && m.firstDate <= endMonthDate;\n })\n .forEach(m => {\n m.weeks.forEach(w =>\n w\n .filter(d => {\n if (!endDateTick) {\n return d.tick && this.inDate(startDateTick, d.tick);\n } else {\n return d.tick && d.tick >= startDateTick && d.tick <= endDateTick;\n }\n })\n .forEach(d => {\n const oldValue = d.selected;\n if (clear) {\n d.selected = DateModels.SelectType.None;\n } else {\n const info = (getDateExtra && getDateExtra(new Date(d.tick))) || {};\n if (d.outOfDate || info.disable) {\n unuseable.push(d.tick);\n }\n if (this.inDate(startDateTick, d.tick)) {\n if (type === 'one') {\n d.selected = DateModels.SelectType.Single;\n } else if (!endDateTick) {\n d.selected = DateModels.SelectType.Only;\n } else if (startDateTick !== endDateTick) {\n d.selected = DateModels.SelectType.Start;\n } else {\n d.selected = DateModels.SelectType.All;\n }\n } else if (this.inDate(endDateTick, d.tick)) {\n d.selected = DateModels.SelectType.End;\n } else {\n d.selected = DateModels.SelectType.Middle;\n }\n }\n needUpdate = needUpdate || d.selected !== oldValue;\n })\n );\n if (needUpdate && m.componentRef) {\n m.componentRef.updateWeeks();\n }\n });\n if (unuseable.length > 0) {\n if (onSelectHasDisableDate) {\n onSelectHasDisableDate(unuseable.map(tick => new Date(tick)));\n } else {\n console.warn('Unusable date. You can handle by onSelectHasDisableDate.', unuseable);\n }\n }\n };\n\n computeVisible = (clientHeight: number, scrollTop: number) => {\n let needUpdate = false;\n const MAX_VIEW_PORT = clientHeight * 2;\n const MIN_VIEW_PORT = clientHeight;\n\n // 大缓冲区外过滤规则\n const filterFunc = (vm: DateModels.MonthData) =>\n vm.y &&\n vm.height &&\n vm.y + vm.height > scrollTop - MAX_VIEW_PORT &&\n vm.y < scrollTop + clientHeight + MAX_VIEW_PORT;\n\n if (this.props.infiniteOpt && this.visibleMonth.length > 12) {\n this.visibleMonth = this.visibleMonth.filter(filterFunc).sort((a, b) => +a.firstDate - +b.firstDate);\n }\n\n // 当小缓冲区不满时填充\n if (this.visibleMonth.length > 0) {\n const last = this.visibleMonth[this.visibleMonth.length - 1];\n if (last.y !== undefined && last.height && last.y + last.height < scrollTop + clientHeight + MIN_VIEW_PORT) {\n const lastIndex = this.state.months.indexOf(last);\n for (let i = 1; i <= 2; i++) {\n const index = lastIndex + i;\n if (index < this.state.months.length && this.visibleMonth.indexOf(this.state.months[index]) < 0) {\n this.visibleMonth.push(this.state.months[index]);\n } else {\n if (this.canLoadNext()) {\n this.genMonthData(undefined, 1);\n }\n }\n }\n needUpdate = true;\n }\n\n const first = this.visibleMonth[0];\n if (first.y !== undefined && first.height && first.y > scrollTop - MIN_VIEW_PORT) {\n const firstIndex = this.state.months.indexOf(first);\n for (let i = 1; i <= 2; i++) {\n const index = firstIndex - i;\n if (index >= 0 && this.visibleMonth.indexOf(this.state.months[index]) < 0) {\n this.visibleMonth.unshift(this.state.months[index]);\n needUpdate = true;\n }\n }\n }\n } else if (this.state.months.length > 0) {\n this.visibleMonth = this.state.months.filter(filterFunc);\n needUpdate = true;\n }\n\n return needUpdate;\n };\n\n createOnScroll = () => {\n // let timer: any;\n let clientHeight = 0,\n scrollTop = 0;\n\n return (data: { full: number; client: number; top: number }) => {\n const { client, top } = data;\n clientHeight = client;\n scrollTop = top;\n\n this.computeVisible(clientHeight, scrollTop);\n\n // 以上方法目前无问题,如果后续有性能问题,改用如下方法,但以下方法会导致刷新稍微延迟现象\n\n // if (timer) {\n // return;\n // }\n //\n // timer = setTimeout(() => {\n // timer = undefined;\n //\n // if (this.computeVisible(clientHeight, scrollTop)) {\n // console.log('update dom');\n // }\n // }, 50);\n };\n };\n\n baseOnCellClick = (day: DateModels.CellData) => {\n if (!day.tick) {\n return;\n }\n if (this.props.onCellClick) {\n this.props.onCellClick(new Date(day.tick));\n }\n };\n}\n","import { Component, HostBinding, OnInit, ViewEncapsulation, Input } from '@angular/core';\nimport { DateModels } from '../date/DataTypes';\n\n@Component({\n selector: 'CalendarWeekPanel, nzm-calendar-week-panel',\n templateUrl: './week-panel.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarWeekPanelComponent implements OnInit {\n constructor() {}\n\n week: string[] = ['日', '一', '二', '三', '四', '五', '六'];\n\n private _locale: DateModels.Locale;\n\n @Input()\n set locale(value) {\n this._locale = value;\n }\n\n @HostBinding('class.week-panel') weekPanel: boolean = true;\n\n ngOnInit() {\n this.week = this._locale.week;\n }\n}\n","<div class=\"cell cell-grey\">{{ week[0] }}</div>\n<div class=\"cell\">{{ week[1] }}</div>\n<div class=\"cell\">{{ week[2] }}</div>\n<div class=\"cell\">{{ week[3] }}</div>\n<div class=\"cell\">{{ week[4] }}</div>\n<div class=\"cell\">{{ week[5] }}</div>\n<div class=\"cell cell-grey\">{{ week[6] }}</div>\n","import { Component, OnInit, ViewEncapsulation, HostBinding, Input, ElementRef, AfterViewInit } from '@angular/core';\nimport { DateModels } from '../date/DataTypes';\nimport { CalendarSingleMonthPropsType } from './PropsType';\n\n@Component({\n selector: 'CalendarSingleMonth, nzm-single-month',\n templateUrl: './single-month.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarSingleMonthComponent implements OnInit, AfterViewInit {\n props = {\n rowSize: 'normal'\n } as CalendarSingleMonthPropsType;\n\n state = {\n weekComponents: []\n };\n ref: (dom) => void;\n wrapperDivDOM: HTMLDivElement | null;\n\n @Input()\n set data(value) {\n this.props = {\n ...this.props,\n ...value\n };\n }\n\n @HostBinding('class.single-month') singleMonth: boolean = true;\n\n constructor(private _elementRef: ElementRef) {}\n\n genWeek = (weeksData: DateModels.CellData[], index: number) => {\n const { getDateExtra, monthData, onCellClick, locale, rowSize } = this.props;\n let rowCls = 'row';\n let weeksDataList = [];\n if (rowSize === 'xl') {\n rowCls += ' row-xl';\n }\n\n weeksData.forEach((day, dayOfWeek) => {\n const extra = (getDateExtra && getDateExtra(new Date(day.tick))) || {};\n let info = extra.info;\n const disable = extra.disable || day.outOfDate;\n\n let cls = 'date';\n let lCls = 'left';\n let rCls = 'right';\n let infoCls = 'info';\n\n if (dayOfWeek === 0 || dayOfWeek === 6) {\n cls += ' grey';\n }\n\n if (disable) {\n cls += ' disable';\n } else if (info) {\n cls += ' important';\n }\n\n if (day.selected) {\n cls += ' date-selected';\n let styleType = day.selected;\n switch (styleType) {\n case DateModels.SelectType.Only:\n info = locale.begin;\n infoCls += ' date-selected';\n break;\n case DateModels.SelectType.All:\n info = locale.begin_over;\n infoCls += ' date-selected';\n break;\n\n case DateModels.SelectType.Start:\n info = locale.begin;\n infoCls += ' date-selected';\n if (dayOfWeek === 6 || day.isLastOfMonth) {\n styleType = DateModels.SelectType.All;\n }\n break;\n case DateModels.SelectType.Middle:\n if (dayOfWeek === 0 || day.isFirstOfMonth) {\n if (day.isLastOfMonth || dayOfWeek === 6) {\n styleType = DateModels.SelectType.All;\n } else {\n styleType = DateModels.SelectType.Start;\n }\n } else if (dayOfWeek === 6 || day.isLastOfMonth) {\n styleType = DateModels.SelectType.End;\n }\n break;\n case DateModels.SelectType.End:\n info = locale.over;\n infoCls += ' date-selected';\n if (dayOfWeek === 0 || day.isFirstOfMonth) {\n styleType = DateModels.SelectType.All;\n }\n break;\n }\n\n switch (styleType) {\n case DateModels.SelectType.Single:\n case DateModels.SelectType.Only:\n case DateModels.SelectType.All:\n cls += ' selected-single';\n break;\n case DateModels.SelectType.Start:\n cls += ' selected-start';\n rCls += ' date-selected';\n break;\n case DateModels.SelectType.Middle:\n cls += ' selected-middle';\n lCls += ' date-selected';\n rCls += ' date-selected';\n break;\n case DateModels.SelectType.End:\n cls += ' selected-end';\n lCls += ' date-selected';\n break;\n }\n }\n\n weeksDataList[dayOfWeek] = {\n lCls,\n cls,\n day,\n rCls,\n infoCls,\n info,\n extra,\n disable,\n onCellClick: onCellClick,\n monthData\n };\n });\n\n this.state.weekComponents[index] = {\n index: index,\n rowCls,\n weeksDataList\n };\n }\n\n updateWeeks = (monthData?: DateModels.MonthData) => {\n (monthData || this.props.monthData).weeks.forEach((week, index) => {\n this.genWeek(week, index);\n });\n }\n\n setWarpper = (dom: HTMLDivElement) => {\n this.wrapperDivDOM = dom;\n }\n\n onClickCell(item) {\n if (!item.disable && item.onCellClick) {\n item.onCellClick(item.day, item.monthData);\n }\n }\n\n ngOnInit() {\n this.setWarpper(this._elementRef.nativeElement);\n this.props.monthData.weeks.forEach((week, index) => {\n this.genWeek(week, index);\n });\n }\n\n ngAfterViewInit() {\n this.ref = this.props.ref;\n this.ref(this);\n }\n}\n","<div class=\"month-title\">\n {{ props.monthData.title }}\n</div>\n<div class=\"date\">\n <div *ngFor=\"let row of state.weekComponents; let i = index\" [ngClass]=\"row.rowCls\">\n <div\n *ngFor=\"let cell of row.weeksDataList; let j = index\"\n class=\"{{ 'cell ' + ((cell.extra && cell.extra.cellCls) || '') }}\"\n (click)=\"onClickCell(cell)\"\n >\n <div *ngIf=\"row.extra && row.extra.cellRender\">test</div>\n <div *ngIf=\"!row.extra || (row.extra && row.extra.cellRender)\" class=\"date-wrapper\">\n <span [ngClass]=\"cell.lCls\"></span>\n <div [ngClass]=\"cell.cls\">\n {{ (cell.day && cell.day.dayOfMonth) || '' }}\n </div>\n <span [ngClass]=\"cell.rCls\"></span>\n </div>\n <div *ngIf=\"!row.extra || (row.extra && row.extra.cellRender)\" [ngClass]=\"cell.infoCls\">\n {{ cell.info }}\n </div>\n </div>\n </div>\n</div>\n","import { Component, HostBinding, OnInit, ViewEncapsulation, Input, ElementRef, ViewChild } from '@angular/core';\nimport { DateModels } from '../date/DataTypes';\nimport { CalendarDatePickerBaseComponent } from './datepicker.base.component';\n\n@Component({\n selector: 'CalendarDatePicker, nzm-calendar-date-picker',\n templateUrl: './datepicker.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarDatePickerComponent extends CalendarDatePickerBaseComponent implements OnInit {\n constructor() {\n super();\n }\n\n transform: string = '';\n private _panel: any;\n private _initDelta: number = 0;\n private _lastY: number = 0;\n private _delta: number = this._initDelta;\n\n @ViewChild('layout', { static: true })\n layoutDom: ElementRef;\n @ViewChild('panel', { static: true })\n panelDom: ElementRef;\n\n @Input()\n set onCellClick(value) {\n this.props.onCellClick = value;\n }\n @Input()\n set endDate(value) {\n const oldProps = Object.assign({}, this.props);\n this.props.endDate = value;\n this.receiveProps(oldProps, this.props);\n }\n @Input()\n set startDate(value) {\n const oldProps = Object.assign({}, this.props);\n this.props.startDate = value;\n this.receiveProps(oldProps, this.props);\n }\n @Input()\n set propsData(value) {\n this.props = {\n ...this.props,\n ...value\n };\n }\n @Input()\n set onSelectHasDisableDate(value) {\n this.props.onSelectHasDisableDate = value;\n }\n @Input()\n set onLayout(value) {\n this.props.onLayout = value;\n }\n\n @HostBinding('class.am-calendar') amCalendar: boolean = true;\n @HostBinding('class.date-picker') datePicker: boolean = true;\n\n genMonthComponent = (data?: DateModels.MonthData) => {\n if (!data) {\n return;\n }\n return {\n monthData: data,\n locale: this.props.locale,\n rowSize: this.props.rowSize,\n onCellClick: this.baseOnCellClick,\n getDateExtra: this.props.getDateExtra,\n ref: dom => {\n data.componentRef = dom || data.componentRef || undefined;\n data.updateLayout = () => {\n this.computeHeight(data, dom);\n };\n data.updateLayout();\n }\n };\n }\n\n computeHeight = (data: DateModels.MonthData, singleMonth) => {\n if (singleMonth && singleMonth.wrapperDivDOM) {\n if (!data.height && !singleMonth.wrapperDivDOM.clientHeight) {\n setTimeout(() => this.computeHeight(data, singleMonth), 500);\n return;\n }\n data.height = singleMonth.wrapperDivDOM.clientHeight || data.height || 0;\n data.y = singleMonth.wrapperDivDOM.offsetTop || data.y || 0;\n }\n }\n\n setLayout = (dom: HTMLDivElement) => {\n if (dom) {\n const { onLayout } = this.props;\n\n if (onLayout) {\n onLayout(dom.clientHeight);\n }\n\n const scrollHandler = this.createOnScroll();\n dom.onscroll = evt => {\n scrollHandler({\n client: dom.clientHeight,\n full: (evt.currentTarget as HTMLDivElement).clientHeight,\n top: (evt.currentTarget as HTMLDivElement).scrollTop\n });\n };\n }\n }\n\n setPanel = (dom: HTMLDivElement) => {\n this._panel = dom;\n }\n\n onTouchStart(event) {\n this._lastY = event.touches[0].screenY || event.touches[0].pageY;\n this._delta = this._initDelta;\n }\n\n onTouchMove(event) {\n const ele = event.currentTarget;\n const isReachTop = ele.scrollTop === 0;\n\n if (isReachTop) {\n this._delta = (event.touches[0].screenY || event.touches[0].pageY) - this._lastY;\n if (this._delta > 0) {\n event.preventDefault();\n if (this._delta > 80) {\n this._delta = 80;\n }\n } else {\n this._delta = 0;\n }\n this.setTransform(this._panel.style, `translate3d(0,${this._delta}px,0)`);\n }\n }\n\n onTouchEnd(event) {\n this.onFinish();\n }\n\n onFinish() {\n if (this._delta > 40 && this.canLoadPrev()) {\n this.genMonthData(this.state.months[0].firstDate, -1);\n\n this.visibleMonth = this.state.months.slice(0, this.props.initalMonths);\n\n this.state.months.forEach(m => {\n if (m.updateLayout) {\n m.updateLayout();\n }\n });\n }\n this.setTransform(this._panel.style, `translate3d(0,0,0)`);\n this.setTransition(this._panel.style, '.3s');\n setTimeout(() => {\n if (this._panel) {\n this.setTransition(this._panel.style, '');\n }\n }, 300);\n }\n\n setTransform(nodeStyle: CSSStyleDeclaration, value: any) {\n this.transform = value;\n nodeStyle.transform = value;\n nodeStyle.webkitTransform = value;\n }\n\n setTransition(nodeStyle: CSSStyleDeclaration, value: any) {\n nodeStyle.transition = value;\n nodeStyle.webkitTransition = value;\n }\n\n ngOnInit() {\n this.init();\n this.setLayout(this.layoutDom.nativeElement);\n this.setPanel(this.panelDom.nativeElement);\n }\n}\n","<CalendarWeekPanel [locale]=\"props.locale\"></CalendarWeekPanel>\n<div\n #layout\n class=\"wrapper\"\n style=\"overflow-x:hidden;overflow-y:visible;-webkit-overflow-scrolling:touch;\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n>\n <div #panel [ngStyle]=\"{ transform: transform }\">\n <div *ngIf=\"canLoadPrev()\" class=\"load-tip\">{{ props.locale.loadPrevMonth }}</div>\n <div class=\"months\">\n <CalendarSingleMonth\n *ngFor=\"let item of visibleMonth; let i = index\"\n style=\"display: block;\"\n [data]=\"item.component\"\n ></CalendarSingleMonth>\n </div>\n </div>\n</div>\n","import { Component, ViewEncapsulation, Input, Output, HostBinding, TemplateRef, EventEmitter } from '@angular/core';\nimport { DateModels } from '../date/DataTypes';\n\n@Component({\n selector: 'CalendarHeader, nzm-calendar-header',\n templateUrl: './header.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarHeaderComponent {\n title: string;\n closeIcon_component: boolean = false;\n clearIcon: any;\n\n private _locale: DateModels.Locale;\n private _showClear: boolean;\n private _closeIcon: any = 'X';\n\n @Input()\n get locale() {\n return this._locale;\n }\n set locale(value) {\n this._locale = value;\n }\n @Input()\n get closeIcon() {\n return this._closeIcon;\n }\n set closeIcon(value: string | TemplateRef<any>) {\n if (value instanceof TemplateRef) {\n this._closeIcon = value;\n this.closeIcon_component = true;\n } else {\n this._closeIcon = <string>value;\n this.closeIcon_component = false;\n }\n }\n @Input()\n get showClear() {\n return this._showClear;\n }\n set showClear(value) {\n this._showClear = value;\n }\n @Output()\n onCancel: EventEmitter<any> = new EventEmitter<any>();\n @Output()\n onClear: EventEmitter<any> = new EventEmitter<any>();\n\n @HostBinding('class.header') header: boolean = true;\n\n constructor() {}\n\n triggerCancel() {\n if (this.onCancel) {\n this.onCancel.emit();\n }\n }\n\n triggerClear() {\n if (this.onClear) {\n this.onClear.emit();\n }\n }\n}\n","<span *ngIf=\"!closeIcon_component\" class=\"left\" (click)=\"triggerCancel()\" [innerHTML]=\"closeIcon\"></span>\n<span *ngIf=\"closeIcon_component\" class=\"left\" (click)=\"triggerCancel()\">\n <ng-template [ngTemplateOutlet]=\"closeIcon\"></ng-template>\n</span>\n<span class=\"title\">{{ title || locale.title }}</span>\n<span *ngIf=\"showClear\" class=\"right\" (click)=\"triggerClear()\">{{ clearIcon || locale.clear }}</span>\n","import { Component, ViewEncapsulation, Input, HostBinding } from '@angular/core';\nimport { zh_CN, en_US } from 'ng-zorro-antd-mobile/locale-provider';\nimport { CalendarTimePickerPropsType } from './PropsType';\n\n@Component({\n selector: 'CalendarTimePicker, nzm-calendar-time-picker',\n templateUrl: './timepicker.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarTimePickerComponent {\n defaultProps = {\n minDate: new Date(0, 0, 0, 0, 0),\n maxDate: new Date(9999, 11, 31, 23, 59, 59),\n defaultValue: new Date(2000, 1, 1, 8),\n mode: 'time',\n datePickerViewLocale: zh_CN\n } as CalendarTimePickerPropsType;\n\n props = {\n minDate: new Date(0, 0, 0, 0, 0),\n maxDate: new Date(9999, 11, 31, 23, 59, 59),\n defaultValue: new Date(2000, 1, 1, 8),\n mode: 'time',\n datePickerViewLocale: zh_CN\n } as CalendarTimePickerPropsType;\n\n selfHeight: string;\n\n @Input()\n set propsData(value) {\n this.props = {\n ...this.props,\n ...value\n };\n\n if (this.props.locale && this.props.locale.today === 'Today') {\n this.props.datePickerViewLocale = en_US;\n } else {\n this.props.datePickerViewLocale = zh_CN;\n }\n }\n @Input()\n set title(value) {\n this.props.title = value;\n }\n @Input()\n set value(value) {\n this.props.value = value;\n }\n @Input()\n set prefixCls(value) {\n this.props.prefixCls = value;\n }\n @Input()\n set defaultValue(value) {\n this.props.defaultValue = value;\n }\n @Input()\n set pickerPrefixCls(value) {\n this.props.pickerPrefixCls = value;\n }\n @Input()\n set clientHeight(value) {\n this.props.clientHeight = value;\n const height = (value && (value * 3) / 8 - 52) || Number.POSITIVE_INFINITY;\n this.selfHeight = (height > 164 || height < 0 ? 164 : height) + 'px';\n }\n @Input()\n set onValueChange(value) {\n this.props.onValueChange = value;\n }\n\n @HostBinding('class.time-picker')\n timePicker: boolean = true;\n\n constructor() {}\n\n onDateChange = (date: { date: Date; index: number }) => {\n const { onValueChange } = this.props;\n if (onValueChange) {\n onValueChange(date.date);\n }\n }\n\n getMinTime(date?: Date) {\n const minDate = this.props.minDate as Date;\n if (\n !date ||\n date.getFullYear() > minDate.getFullYear() ||\n date.getMonth() > minDate.getMonth() ||\n date.getDate() > minDate.getDate()\n ) {\n return this.defaultProps.minDate;\n }\n return minDate;\n }\n\n getMaxTime(date?: Date) {\n const maxDate = this.props.maxDate as Date;\n if (\n !date ||\n date.getFullYear() < maxDate.getFullYear() ||\n date.getMonth() < maxDate.getMonth() ||\n date.getDate() < maxDate.getDate()\n ) {\n return this.defaultProps.maxDate;\n }\n return maxDate;\n }\n}\n","<div class=\"title\">{{ props.title }}</div>\n<DatePickerView\n [ngStyle]=\"{ height: selfHeight, overflow: 'hidden' }\"\n [mode]=\"props.mode\"\n [value]=\"props.value\"\n [locale]=\"props.datePickerViewLocale\"\n [minDate]=\"getMinTime(props.value || props.defaultValue || undefined)\"\n [maxDate]=\"getMaxTime(props.value || props.defaultValue || undefined)\"\n (onValueChange)=\"onDateChange($event)\"\n></DatePickerView>\n","import { Component, ViewEncapsulation, Input, HostBinding } from '@angular/core';\nimport { formatDate } from '../util/index';\nimport { CalendarConfirmPanelPropsType } from './PropsType';\n\n@Component({\n selector: 'CalendarConfirmPanel, nzm-calendar-confirm-panel',\n templateUrl: './confirm-panel.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarConfirmPanelComponent {\n props = {\n formatStr: 'yyyy-MM-dd hh:mm'\n } as CalendarConfirmPanelPropsType;\n startTimeStr: string;\n endTimeStr: string;\n btnCls: string;\n\n @Input()\n set propsData(value) {\n this.props = {\n ...this.props,\n ...value\n };\n }\n @Input()\n set disableBtn(value) {\n this.props.disableBtn = value;\n const { type } = this.props;\n let btnCls = value ? 'button button-disable' : 'button';\n if (type === 'one') {\n btnCls += ' button-full';\n }\n this.btnCls = btnCls;\n }\n @Input()\n set formatStr(value) {\n this.props.formatStr = value;\n }\n @Input()\n set startDateTime(value) {\n this.props.startDateTime = value;\n this.formatTime();\n }\n @Input()\n set endDateTime(value) {\n this.props.endDateTime = value;\n this.formatTime();\n }\n @Input()\n set onConfirm(value) {\n this.props.onConfirm = value;\n }\n\n @HostBinding('class.confirm-panel') confirmPane: boolean = true;\n\n constructor() {}\n\n formatTime() {\n const { locale } = this.props;\n let { startDateTime, endDateTime } = this.props;\n if (startDateTime && endDateTime && +startDateTime > +endDateTime) {\n const tmp = startDateTime;\n startDateTime = endDateTime;\n endDateTime = tmp;\n }\n\n this.startTimeStr = startDateTime ? this.selfFormatDate(startDateTime) : locale.noChoose;\n this.endTimeStr = endDateTime ? this.selfFormatDate(endDateTime) : locale.noChoose;\n }\n\n triggerConfirm = () => {\n const { onConfirm, disableBtn } = this.props;\n if (!disableBtn) {\n onConfirm();\n }\n }\n\n selfFormatDate(date: Date) {\n const { formatStr = '', locale } = this.props;\n return formatDate(date, formatStr, locale);\n }\n}\n","<div *ngIf=\"props.type === 'range'\" class=\"info\">\n <p>\n {{ props.locale.start }}: <span class=\"{{ !props.startDateTime ? 'grey' : '' }}\">{{ startTimeStr }}</span>\n </p>\n <p>\n {{ props.locale.end }}: <span class=\"{{ !props.endDateTime ? 'grey' : '' }}\">{{ endTimeStr }}</span>\n </p>\n</div>\n<div [ngClass]=\"btnCls\" (click)=\"triggerConfirm()\">\n {{ props.locale.confirm }}\n</div>\n","import { Component, ViewEncapsulation, HostBinding, Input } from '@angular/core';\nimport { CalendarShortcutPanelPropsType } from './PropsType';\n\n@Component({\n selector: 'CalendarShortcutPanel, nzm-calendar-shortcut-panel',\n templateUrl: './shortcut-panel.component.html',\n encapsulation: ViewEncapsulation.None\n})\nexport class CalendarShortcutPanelComponent {\n props = {} as CalendarShortcutPanelPropsType;\n\n @Input()\n set locale(value) {\n this.props.locale = value;\n }\n @Input()\n set onSelect(value) {\n this.props.onSelect = value;\n }\n\n @HostBinding('class.shortcut-panel') shortcutPanel: boolean = true;\n\n constructor() {}\n\n onClick = (type: string) => {\n const { onSelect } = this.props;\n const today = new Date();\n\n switch (type) {\n case 'today':\n onSelect(\n new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0),\n new Date(today.getFullYear(), today.getMonth(), today.getDate(), 12)\n );\n break;\n\n case 'yesterday':\n onSelect(\n new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1, 0),\n new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1, 12)\n );\n break;\n\n case 'lastweek':\n onSelect(\n new Date(today.getFullYear(), today.getMonth(), today.getDate() - 6, 0),\n new Date(today.getFullYear(), today.getMonth(), today.getDate(), 12)\n );\n break;\n\n case 'lastmonth':\n onSelect(\n new Date(today.getFullYear(), today.getMonth(), today.getDate() - 29, 0),\n new Date(today.getFullYear(), today.getMonth(), today.getDate(), 12)\n );\n break;\n }\n }\n}\n","<div class=\"item\" (click)=\"onClick('today')\">{{ props.locale.today }}</div>\n<div class=\"item\" (click)=\"onClick('yesterday')\">{{ props.locale.yesterday }}</div>\n<div class=\"item\" (click)=\"onClick('lastweek')\">{{ props.locale.lastWeek }}</div>\n<div class=\"item\" (click)=\"onClick('lastmonth')\">{{ props.locale.lastMonth }}</div>\n","import {\n Component,\n forwardRef,\n OnInit,\n OnDestroy,\n ViewEncapsulation,\n Input,\n Output,\n HostBinding,\n EventEmitter,\n ViewChild\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { DateModels } from './date/DataTypes';\nimport { zh_CN, en_US } from 'ng-zorro-antd-mobile/locale-provider';\nimport { CalendarPropsType } from './calendar.props.component';\nimport { LocaleProviderService } from 'ng-zorro-antd-mobile/locale-provider';\nimport { mergeDateTime, isSameDate } from './util/index';\nimport { takeUntil } from 'rxjs/operators';\nimport { CalendarDatePickerComponent } from './datepicker/datepicker.component';\nimport { Subject } from 'rxjs';\n\nexport { CalendarPropsType };\n\nexport interface CalendarStateType {\n showTimePicker: boolean;\n timePickerTitle?: string;\n startDate?: Date;\n endDate?: Date;\n disConfirmBtn?: boolean;\n clientHight?: number;\n}\n\n@Component({\n selector: 'Calendar, nzm-calendar',\n templateUrl: './calendar.component.html',\n encapsulation: ViewEncapsulation.None,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CalendarComponent), multi: true }]\n})\nexport class CalendarComponent implements ControlValueAccessor, OnInit, OnDestroy {\n isShow: boolean = false;\n contentAnimateClass: string;\n maskAnimateClass: string;\n showClear: boolean = false;\n isSameDate: Function = isSameDate;\n\n props = {\n visible: false,\n showHeader: true,\n locale: zh_CN.Calendar,\n pickTime: false,\n showShortcut: false,\n prefixCls: 'rmc-calendar',\n type: 'range',\n defaultTimeValue: new Date(2000, 0, 1, 8)\n } as CalendarPropsType;\n\n state = {\n showTimePicker: false,\n timePickerTitle: '',\n startDate: undefined,\n endDate: undefined,\n disConfirmBtn: true,\n clientHight: 0\n } as CalendarStateType;\n\n private _unsubscribe$ = new Subject<void>();\n private _enterDirection: string;\n private _dateModelType: number;\n private _dateModelValue: any;\n private _dateModelTime: number = 0;\n\n @ViewChild(CalendarDatePickerComponent)\n datepicker: CalendarDatePickerComponent;\n\n @Input()\n set locale(value) {\n if (value === 'enUS') {\n this.props.locale = en_US.Calendar;\n } else if (value === 'zhCN') {\n this.props.locale = zh_CN.Calendar;\n }\n\n this._unsubscribe$.next();\n this._unsubscribe$.complete();\n }\n @Input()\n set defaultTimeValue(value) {\n if (value) {\n this.props.defaultTimeValue = value;\n }\n }\n @Input()\n set prefixCls(value) {\n if (value) {\n this.props.prefixCls = value;\n }\n }\n @Input()\n set enterDirection(value) {\n this._enterDirection = value;\n if (this._enterDirection === 'horizontal') {\n this.contentAnimateClass = 'slideH-enter slideH-enter-active';\n } else {\n this.contentAnimateClass = 'slideV-enter slideV-enter-active';\n }\n }\n @Input()\n set visible(value) {\n this.props.visible = value;\n if (value === true || value === 'true') {\n this.showAnimation();\n this.isShow = true;\n } else {\n this.hideAnimation();\n setTimeout(() => {\n this.isShow = false;\n }, 300);\n }\n }\n @Input()\n set getDateExtra(value) {\n this.props.getDateExtra = value;\n }\n @Input()\n set defaultDate(value) {\n this.props.defaultDate = value;\n }\n @Input()\n set minDate(value) {\n this.props.minDate = value;\n }\n @Input()\n set maxDate(value) {\n this.props.maxDate = value;\n }\n @Input()\n set pickTime(value) {\n this.props.pickTime = value;\n }\n @Input()\n set type(value) {\n this.props.type = value;\n }\n @Input()\n set showShortcut(value) {\n this.props.showShortcut = value;\n }\n @Input()\n set rowSize(value) {\n this.props.rowSize = value;\n }\n @Input()\n set infinite(value) {}\n @Input()\n set defaultValue(value) {\n this.props.defaultValue = value;\n\n if (value) {\n this.receiveProps(this.props);\n }\n }\n @Input()\n set onSelect(value) {\n this.props.onSelect = value;\n }\n\n @Output()\n onCancel: EventEmitter<any> = new EventEmitter<any>();\n @Output()\n onConfirm: EventEmitter<any> = new EventEmitter<any>();\n @Output()\n onSelectHasDisableDate: EventEmitter<any> = new EventEmitter<any>();\n\n @HostBinding('class')\n class: string = 'am-calendar';\n\n constructor(private _localeProviderService: LocaleProviderService) {}\n\n writeValue(value: Date | Array<Date> | null): void {\n this._dateModelType = null;\n if (value && value instanceof Array) {\n if (value.length === 0) {\n console.error('[ng-zorro-antd-mobile]: calendar ngModel array need params!');\n return;\n }\n if (this.props.type === 'one' && value.length >= 2) {\n this._dateModelType = 1;\n console.error('[ng-zorro-antd-mobile]: type is one, but ngmodel has more than one param, just use first one');\n this.onSelectedDate(value[0]);\n } else if (value.length === 1) {\n this._dateModelType = 1;\n this.onSelectedDate(value[0]);\n } else {\n this._dateModelType = 2;\n this.onSelectedDate(value[0]);\n this.onSelectedDate(value[1]);\n }\n } else if (value && value instanceof Date) {\n this._dateModelType = 3;\n this.onSelectedDate(value);\n }\n }\n\n registerOnChange(fn: (date: Date | Array<Date>) => void): void {\n this.onChangeFn = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchFn = fn;\n }\n\n receiveProps(nextProps: CalendarPropsType) {\n if (nextProps.visible && nextProps.defaultValue) {\n this.shortcutSelect(nextProps.defaultValue[0], nextProps.defaultValue[1], nextProps);\n }\n }\n\n showAnimation() {\n if (this._enterDirection === 'horizontal') {\n this.contentAnimateClass = 'slideH-enter slideH-enter-active';\n } else {\n this.contentAnimateClass = 'slideV-enter slideV-enter-active';\n }\n this.maskAnimateClass = 'fade-enter fade-enter-active';\n }\n\n hideAnimation() {\n if (this._enterDirection === 'horizontal') {\n this.contentAnimateClass = 'slideH-leave slideH-leave-active';\n } else {\n this.contentAnimateClass = 'slideV-leave slideV-leave-active';\n }\n this.maskAnimateClass = 'fade-leave fade-leave-active';\n }\n\n selectDate = (\n date: Date,\n useDateTime = false,\n oldState: { startDate?: Date; endDate?: Date } = {},\n props = this.props\n ) => {\n if (!date) {\n return {} as CalendarStateType;\n }\n let newState = {} as CalendarStateType;\n const { type, pickTime, defaultTimeValue, locale = {} as DateModels.Locale } = props;\n const newDate = pickTime && !useDateTime ? mergeDateTime(date, defaultTimeValue) : date;\n const { startDate, endDate } = oldState;\n\n switch (type) {\n case 'one':\n newState = {\n ...newState,\n startDate: newDate,\n disConfirmBtn: false\n };\n if (pickTime) {\n newState = {\n ...newState,\n timePickerTitle: locale.selectTime,\n showTimePicker: true\n };\n }\n break;\n\n case 'range':\n if (!startDate || endDate) {\n newState = {\n ...newState,\n startDate: newDate,\n endDate: undefined,\n disConfirmBtn: true\n };\n if (pickTime) {\n newState = {\n ...newState,\n timePickerTitle: locale.selectStartTime,\n showTimePicker: true\n };\n }\n } else {\n newState = {\n ...newState,\n timePickerTitle:\n +newDate >= +startDate || this.isSameDate(startDate, newDate)\n ? locale.selectEndTime\n : locale.selectStartTime,\n disConfirmBtn: false,\n endDate:\n pickTime && !useDateTime && (+newDate >= +startDate || this.isSameDate(startDate, newDate))\n ? new Date(+mergeDateTime(newDate, startDate) + 3600000)\n : newDate\n };\n }\n break;\n }\n\n this.writeModelData(date);\n return newState;\n };\n\n writeModelData(date) {\n if (this._dateModelValue instanceof Array) {\n this._dateModelTime = this._dateModelValue.length;\n } else {\n this._dateModelTime = 0;\n }\n\n switch (this._dateModelType) {\n case 1:\n this._dateModelValue = [date];\n this.onChangeFn(this._dateModelValue);\n break;\n case 2:\n if (this._dateModelTime === 1) {\n if (+date < +this._dateModelValue[0]) {\n this._dateModelValue.unshift(date);\n } else {\n this._dateModelValue.push(date);\n }\n this.onChangeFn(this._dateModelValue);\n } else {\n this._dateModelValue = [];\n this._dateModelValue.push(date);\n }\n break;\n case 3:\n this._dateModelValue = date;\n this.onChangeFn(this._dateModelValue);\n break;\n default:\n break;\n }\n }\n\n onSelectedDate = (date: Date) => {\n const { startDate, endDate } = this.state;\n const { onSelect } = this.props;\n\n if (onSelect) {\n const value = onSelect(date, [startDate, endDate]);\n if (value) {\n this.shortcutSelect(value[0], value[1]);\n return;\n }\n }\n\n this.state = {\n ...this.state,\n ...this.selectDate(date, false, { startDate, endDate })\n };\n\n this.showClear = !!this.state.startDate;\n };\n\n triggerSelectHasDisableDate = (date: Date[]) => {\n this.triggerClear();\n if (this.onSelectHasDisableDate) {\n this.onSelectHasDisableDate.emit(date);\n }\n };\n\n onClose = () => {\n this.state = {\n showTimePicker: false,\n timePickerTitle: '',\n startDate: undefined,\n endDate: undefined,\n disConfirmBtn: true,\n clientHight: 0\n } as CalendarStateType;\n this.showClear = !!this.state.startDate;\n };\n\n triggerConfirm = () => {\n const { startDate, endDate } = this.state;\n if (startDate && endDate && +startDate > +endDate) {\n this.onClose();\n return this.onConfirm && this.onConfirm.emit({ startDate: endDate, endDate: startDate });\n }\n if (this.onConfirm) {\n this.onConfirm.emit({ startDate, endDate });\n }\n this.onClose();\n };\n\n triggerCancel() {\n if (this.props.onCancel) {\n this.props.onCancel();\n }\n this.onClose();\n if (this.onCancel) {\n this.onCancel.emit();\n }\n }\n\n triggerClear = () => {\n // 清除数据做延迟,否则同步刷新数据导致报错\n setTimeout(() => {\n this.state = {\n ...this.state,\n ...{ startDate: undefined, endDate: undefined, showTimePicker: false }\n };\n if (this.props.onClear) {\n this.props.onClear();\n }\n this.showClear = !!this.state.startDate;\n }, 0);\n };\n\n onTimeChange = (date: Date) => {\n const { startDate, endDate } = this.state;\n if (endDate) {\n this.state.endDate = date;\n } else if (startDate) {\n this.state.startDate = date;\n }\n };\n\n shortcutSelect = (startDate: Date, endDate: Date, props = this.props) => {\n this.state = {\n ...this.state,\n ...{ startDate, showTimePicker: false },\n ...this.selectDate(endDate, true, { startDate }, props)\n };\n this.showClear = !!this.state.startDate;\n };\n\n setClientHeight = (height: number) => {\n this.state.clientHight = height;\n };\n\n ngOnInit() {\n const defaultValue = this.props.defaultValue;\n if (defaultValue) {\n this.state = {\n ...this.state,\n ...this.selectDate(defaultValue[1], true, { startDate: defaultValue[0] }, this.props)\n };\n }\n\n this._localeProviderService.localeChange.pipe(takeUntil(this._unsubscribe$)).subscribe(_ => {\n this.props.locale = { ...this._localeProviderService.getLocaleSubObj('Calendar') } as DateModels.Locale;\n });\n }\n\n ngOnDestroy() {\n this._unsubscribe$.next();\n this._unsubscribe$.complete();\n }\n\n private onChangeFn: (date: Date | Array<Date>) => void = () => {};\n private onTouchFn: (date: Date | Array<Date>) => void = () => {};\n}\n","<span *ngIf=\"isShow\">\n <div class=\"{{ 'mask ' + maskAnimateClass }}\"></div>\n</span>\n<span *ngIf=\"isShow\">\n <div class=\"{{ 'content animate ' + contentAnimateClass }}\">\n <CalendarHeader\n [locale]=\"props.locale\"\n [closeIcon]=\"closeIconHtml\"\n [showClear]=\"showClear\"\n (onCancel)=\"triggerCancel()\"\n