UNPKG

vuetify

Version:

Vue Material Component Framework

163 lines (142 loc) 5.03 kB
// Mixins import CalendarBase from './calendar-base' // Util import props from '../util/props' import { parseTime, copyTimestamp, updateMinutes, createDayList, createIntervalList, createNativeLocaleFormatter, VTime, MINUTES_IN_DAY, } from '../util/timestamp' import { CalendarTimestamp, CalendarFormatter, CalendarDayBodySlotScope } from 'vuetify/types' /* @vue/component */ export default CalendarBase.extend({ name: 'calendar-with-intervals', props: props.intervals, computed: { parsedFirstInterval (): number { return parseInt(this.firstInterval) }, parsedIntervalMinutes (): number { return parseInt(this.intervalMinutes) }, parsedIntervalCount (): number { return parseInt(this.intervalCount) }, parsedIntervalHeight (): number { return parseFloat(this.intervalHeight) }, parsedFirstTime (): number | false { return parseTime(this.firstTime) }, firstMinute (): number { const time = this.parsedFirstTime return time !== false && time >= 0 && time <= MINUTES_IN_DAY ? time : this.parsedFirstInterval * this.parsedIntervalMinutes }, bodyHeight (): number { return this.parsedIntervalCount * this.parsedIntervalHeight }, days (): CalendarTimestamp[] { return createDayList( this.parsedStart, this.parsedEnd, this.times.today, this.weekdaySkips, this.maxDays ) }, intervals (): CalendarTimestamp[][] { const days: CalendarTimestamp[] = this.days const first: number = this.firstMinute const minutes: number = this.parsedIntervalMinutes const count: number = this.parsedIntervalCount const now: CalendarTimestamp = this.times.now return days.map(d => createIntervalList(d, first, minutes, count, now)) }, intervalFormatter (): CalendarFormatter { if (this.intervalFormat) { return this.intervalFormat as CalendarFormatter } const longOptions = { timeZone: 'UTC', hour: '2-digit', minute: '2-digit' } const shortOptions = { timeZone: 'UTC', hour: 'numeric', minute: '2-digit' } const shortHourOptions = { timeZone: 'UTC', hour: 'numeric' } return createNativeLocaleFormatter( this.currentLocale, (tms, short) => short ? (tms.minute === 0 ? shortHourOptions : shortOptions) : longOptions ) }, }, methods: { showIntervalLabelDefault (interval: CalendarTimestamp): boolean { const first: CalendarTimestamp = this.intervals[0][0] const isFirst: boolean = first.hour === interval.hour && first.minute === interval.minute return !isFirst }, intervalStyleDefault (_interval: CalendarTimestamp): object | undefined { return undefined }, getTimestampAtEvent (e: MouseEvent | TouchEvent, day: CalendarTimestamp): CalendarTimestamp { const timestamp: CalendarTimestamp = copyTimestamp(day) const bounds = (e.currentTarget as HTMLElement).getBoundingClientRect() const baseMinutes: number = this.firstMinute const touchEvent: TouchEvent = e as TouchEvent const mouseEvent: MouseEvent = e as MouseEvent const touches: TouchList = touchEvent.changedTouches || touchEvent.touches const clientY: number = touches && touches[0] ? touches[0].clientY : mouseEvent.clientY const addIntervals: number = (clientY - bounds.top) / this.parsedIntervalHeight const addMinutes: number = Math.floor(addIntervals * this.parsedIntervalMinutes) const minutes: number = baseMinutes + addMinutes return updateMinutes(timestamp, minutes, this.times.now) }, getSlotScope (timestamp: CalendarTimestamp): CalendarDayBodySlotScope { const scope = copyTimestamp(timestamp) as any scope.timeToY = this.timeToY scope.timeDelta = this.timeDelta scope.minutesToPixels = this.minutesToPixels scope.week = this.days return scope }, scrollToTime (time: VTime): boolean { const y = this.timeToY(time) const pane = this.$refs.scrollArea as HTMLElement if (y === false || !pane) { return false } pane.scrollTop = y return true }, minutesToPixels (minutes: number): number { return minutes / this.parsedIntervalMinutes * this.parsedIntervalHeight }, timeToY (time: VTime, clamp = true): number | false { let y = this.timeDelta(time) if (y !== false) { y *= this.bodyHeight if (clamp) { if (y < 0) { y = 0 } if (y > this.bodyHeight) { y = this.bodyHeight } } } return y }, timeDelta (time: VTime): number | false { const minutes = parseTime(time) if (minutes === false) { return false } const min: number = this.firstMinute const gap: number = this.parsedIntervalCount * this.parsedIntervalMinutes return (minutes - min) / gap }, }, })