1
// Mixins
2
import DatePickerTable from './mixins/date-picker-table'
3

4
// Utils
5
import { weekNumber } from '../../util/dateTimeUtils'
6
import { pad, createNativeLocaleFormatter, monthChange } from './util'
7
import { createRange } from '../../util/helpers'
8
import mixins from '../../util/mixins'
9

10
// Types
11
import { VNode, VNodeChildren, PropType } from 'vue'
12
import { DatePickerFormatter } from 'vuetify/types'
13

14
export default mixins(
15
  DatePickerTable
16
/* @vue/component */
17
).extend({
18
  name: 'v-date-picker-date-table',
19

20
  props: {
21
    firstDayOfWeek: {
22
      type: [String, Number],
23
      default: 0,
24
    },
25
    localeFirstDayOfYear: {
26
      type: [String, Number],
27
      default: 0,
28
    },
29
    showWeek: Boolean,
30
    weekdayFormat: Function as PropType<DatePickerFormatter | undefined>,
31
  },
32

33
  computed: {
34 1
    formatter (): DatePickerFormatter {
35 1
      return this.format || createNativeLocaleFormatter(this.currentLocale, { day: 'numeric', timeZone: 'UTC' }, { start: 8, length: 2 })
36
    },
37 1
    weekdayFormatter (): DatePickerFormatter | undefined {
38 1
      return this.weekdayFormat || createNativeLocaleFormatter(this.currentLocale, { weekday: 'narrow', timeZone: 'UTC' })
39
    },
40 1
    weekDays (): string[] {
41 1
      const first = parseInt(this.firstDayOfWeek, 10)
42

43 1
      return this.weekdayFormatter
44 1
        ? createRange(7).map(i => this.weekdayFormatter!(`2017-01-${first + i + 15}`)) // 2017-01-15 is Sunday
45 0
        : createRange(7).map(i => ['S', 'M', 'T', 'W', 'T', 'F', 'S'][(i + first) % 7])
46
    },
47
  },
48

49
  methods: {
50 1
    calculateTableDate (delta: number) {
51 1
      return monthChange(this.tableDate, Math.sign(delta || 1))
52
    },
53 1
    genTHead () {
54 1
      const days = this.weekDays.map(day => this.$createElement('th', day))
55 1
      if (this.showWeek) {
56 1
        days.unshift(this.$createElement('th'))
57
      }
58

59 1
      return this.$createElement('thead', this.genTR(days))
60
    },
61
    // Returns number of the days from the firstDayOfWeek to the first day of the current month
62 1
    weekDaysBeforeFirstDayOfTheMonth () {
63 1
      const firstDayOfTheMonth = new Date(`${this.displayedYear}-${pad(this.displayedMonth + 1)}-01T00:00:00+00:00`)
64 1
      const weekDay = firstDayOfTheMonth.getUTCDay()
65

66 1
      return (weekDay - parseInt(this.firstDayOfWeek) + 7) % 7
67
    },
68 1
    getWeekNumber (dayInMonth: number) {
69 1
      return weekNumber(
70
        this.displayedYear,
71
        this.displayedMonth,
72
        dayInMonth,
73
        parseInt(this.firstDayOfWeek),
74
        parseInt(this.localeFirstDayOfYear)
75
      )
76
    },
77 1
    genWeekNumber (weekNumber: number) {
78 1
      return this.$createElement('td', [
79
        this.$createElement('small', {
80
          staticClass: 'v-date-picker-table--date__week',
81
        }, String(weekNumber).padStart(2, '0')),
82
      ])
83
    },
84 1
    genTBody () {
85 1
      const children = []
86 1
      const daysInMonth = new Date(this.displayedYear, this.displayedMonth + 1, 0).getDate()
87 1
      let rows = []
88 1
      let day = this.weekDaysBeforeFirstDayOfTheMonth()
89

90 1
      if (this.showWeek) {
91 1
        rows.push(this.genWeekNumber(this.getWeekNumber(1)))
92
      }
93

94 1
      while (day--) rows.push(this.$createElement('td'))
95 1
      for (day = 1; day <= daysInMonth; day++) {
96 1
        const date = `${this.displayedYear}-${pad(this.displayedMonth + 1)}-${pad(day)}`
97

98 1
        rows.push(this.$createElement('td', [
99
          this.genButton(date, true, 'date', this.formatter),
100
        ]))
101

102 1
        if (rows.length % (this.showWeek ? 8 : 7) === 0) {
103 1
          children.push(this.genTR(rows))
104 1
          rows = []
105 1
          if (this.showWeek && (day < daysInMonth)) {
106 1
            rows.push(this.genWeekNumber(this.getWeekNumber(day + 7)))
107
          }
108
        }
109
      }
110

111 1
      if (rows.length) {
112 1
        children.push(this.genTR(rows))
113
      }
114

115 1
      return this.$createElement('tbody', children)
116
    },
117 1
    genTR (children: VNodeChildren) {
118 1
      return [this.$createElement('tr', children)]
119
    },
120
  },
121

122 1
  render (): VNode {
123 1
    return this.genTable('v-date-picker-table v-date-picker-table--date', [
124
      this.genTHead(),
125
      this.genTBody(),
126
    ], this.calculateTableDate)
127
  },
128
})

Read our documentation on viewing source code .

Loading