UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 16.2 kB
{"version":3,"file":"basic-date-table.mjs","sources":["../../../../../../../packages/components/date-picker/src/date-picker-com/basic-date-table.vue"],"sourcesContent":["<template>\n <table\n cellspacing=\"0\"\n cellpadding=\"0\"\n class=\"el-date-table\"\n :class=\"{ 'is-week-mode': selectionMode === 'week' }\"\n @click=\"handleClick\"\n @mousemove=\"handleMouseMove\"\n >\n <tbody>\n <tr>\n <th v-if=\"showWeekNumber\">{{ t('el.datepicker.week') }}</th>\n <th v-for=\"(week, key) in WEEKS\" :key=\"key\">\n {{ t('el.datepicker.weeks.' + week) }}\n </th>\n </tr>\n <tr\n v-for=\"(row, key) in rows\"\n :key=\"key\"\n class=\"el-date-table__row\"\n :class=\"{ current: isWeekActive(row[1]) }\"\n >\n <td\n v-for=\"(cell, key_) in row\"\n :key=\"key_\"\n :class=\"getCellClasses(cell)\"\n >\n <el-date-picker-cell :cell=\"cell\" />\n </td>\n </tr>\n </tbody>\n </table>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, computed, ref } from 'vue'\nimport dayjs from 'dayjs'\nimport { useLocale } from '@element-plus/hooks'\nimport { castArray } from '@element-plus/utils'\nimport ElDatePickerCell from './basic-cell-render'\nimport type { PropType } from 'vue'\n\nimport type { Dayjs } from 'dayjs'\nimport type { DateCell } from '../date-picker.type'\n\nexport default defineComponent({\n components: {\n ElDatePickerCell,\n },\n props: {\n date: {\n type: Object as PropType<Dayjs>,\n },\n minDate: {\n type: Object as PropType<Dayjs>,\n },\n maxDate: {\n type: Object as PropType<Dayjs>,\n },\n parsedValue: {\n type: [Object, Array] as PropType<Dayjs | Dayjs[]>,\n },\n selectionMode: {\n type: String,\n default: 'day',\n },\n showWeekNumber: {\n type: Boolean,\n default: false,\n },\n disabledDate: {\n type: Function,\n },\n cellClassName: {\n type: Function,\n },\n rangeState: {\n type: Object,\n default: () => ({\n endDate: null,\n selecting: false,\n }),\n },\n },\n emits: ['changerange', 'pick', 'select'],\n\n setup(props, ctx) {\n const { t, lang } = useLocale()\n // data\n const lastRow = ref(null)\n const lastColumn = ref(null)\n const tableRows = ref<DateCell[][]>([[], [], [], [], [], []])\n\n // todo better way to get Day.js locale object\n const firstDayOfWeek = (props.date as any).$locale().weekStart || 7\n const WEEKS_CONSTANT = props.date\n .locale('en')\n .localeData()\n .weekdaysShort()\n .map((_) => _.toLowerCase())\n\n const offsetDay = computed(() => {\n // Sunday 7(0), cal the left and right offset days, 3217654, such as Monday is -1, the is to adjust the position of the first two rows of dates\n return firstDayOfWeek > 3 ? 7 - firstDayOfWeek : -firstDayOfWeek\n })\n\n const startDate = computed(() => {\n const startDayOfMonth = props.date.startOf('month')\n return startDayOfMonth.subtract(startDayOfMonth.day() || 7, 'day')\n })\n\n const WEEKS = computed(() => {\n return WEEKS_CONSTANT.concat(WEEKS_CONSTANT).slice(\n firstDayOfWeek,\n firstDayOfWeek + 7\n )\n })\n\n const rows = computed(() => {\n // TODO: refactory rows / getCellClasses\n const startOfMonth = props.date.startOf('month')\n const startOfMonthDay = startOfMonth.day() || 7 // day of first day\n const dateCountOfMonth = startOfMonth.daysInMonth()\n const dateCountOfLastMonth = startOfMonth\n .subtract(1, 'month')\n .daysInMonth()\n\n const offset = offsetDay.value\n const rows_ = tableRows.value\n let count = 1\n\n const selectedDate: Dayjs[] =\n props.selectionMode === 'dates' ? castArray(props.parsedValue) : []\n\n const calNow = dayjs().locale(lang.value).startOf('day')\n\n for (let i = 0; i < 6; i++) {\n const row = rows_[i]\n\n if (props.showWeekNumber) {\n if (!row[0]) {\n row[0] = {\n type: 'week',\n text: startDate.value.add(i * 7 + 1, 'day').week(),\n }\n }\n }\n\n for (let j = 0; j < 7; j++) {\n let cell = row[props.showWeekNumber ? j + 1 : j]\n if (!cell) {\n cell = {\n row: i,\n column: j,\n type: 'normal',\n inRange: false,\n start: false,\n end: false,\n }\n }\n const index = i * 7 + j\n const calTime = startDate.value.add(index - offset, 'day')\n cell.dayjs = calTime\n cell.date = calTime.toDate()\n cell.timestamp = calTime.valueOf()\n cell.type = 'normal'\n\n const calEndDate =\n props.rangeState.endDate ||\n props.maxDate ||\n (props.rangeState.selecting && props.minDate)\n\n cell.inRange =\n (props.minDate &&\n calTime.isSameOrAfter(props.minDate, 'day') &&\n calEndDate &&\n calTime.isSameOrBefore(calEndDate, 'day')) ||\n (props.minDate &&\n calTime.isSameOrBefore(props.minDate, 'day') &&\n calEndDate &&\n calTime.isSameOrAfter(calEndDate, 'day'))\n\n if (props.minDate?.isSameOrAfter(calEndDate)) {\n cell.start = calEndDate && calTime.isSame(calEndDate, 'day')\n cell.end = props.minDate && calTime.isSame(props.minDate, 'day')\n } else {\n cell.start = props.minDate && calTime.isSame(props.minDate, 'day')\n cell.end = calEndDate && calTime.isSame(calEndDate, 'day')\n }\n\n const isToday = calTime.isSame(calNow, 'day')\n\n if (isToday) {\n cell.type = 'today'\n }\n\n if (i >= 0 && i <= 1) {\n const numberOfDaysFromPreviousMonth =\n startOfMonthDay + offset < 0\n ? 7 + startOfMonthDay + offset\n : startOfMonthDay + offset\n\n if (j + i * 7 >= numberOfDaysFromPreviousMonth) {\n cell.text = count++\n } else {\n cell.text =\n dateCountOfLastMonth -\n (numberOfDaysFromPreviousMonth - (j % 7)) +\n 1 +\n i * 7\n cell.type = 'prev-month'\n }\n } else {\n if (count <= dateCountOfMonth) {\n cell.text = count++\n } else {\n cell.text = count++ - dateCountOfMonth\n cell.type = 'next-month'\n }\n }\n\n const cellDate = calTime.toDate()\n cell.selected = selectedDate.find(\n (_) => _.valueOf() === calTime.valueOf()\n )\n cell.isSelected = !!cell.selected\n cell.isCurrent = isCurrent(cell)\n cell.disabled = props.disabledDate && props.disabledDate(cellDate)\n cell.customClass =\n props.cellClassName && props.cellClassName(cellDate)\n row[props.showWeekNumber ? j + 1 : j] = cell\n }\n\n if (props.selectionMode === 'week') {\n const start = props.showWeekNumber ? 1 : 0\n const end = props.showWeekNumber ? 7 : 6\n const isActive = isWeekActive(row[start + 1])\n row[start].inRange = isActive\n row[start].start = isActive\n row[end].inRange = isActive\n row[end].end = isActive\n }\n }\n return rows_\n })\n\n const isCurrent = (cell): boolean => {\n return (\n props.selectionMode === 'day' &&\n (cell.type === 'normal' || cell.type === 'today') &&\n cellMatchesDate(cell, props.parsedValue)\n )\n }\n\n const cellMatchesDate = (cell, date) => {\n if (!date) return false\n return dayjs(date)\n .locale(lang.value)\n .isSame(props.date.date(Number(cell.text)), 'day')\n }\n\n const getCellClasses = (cell) => {\n const classes: string[] = []\n if ((cell.type === 'normal' || cell.type === 'today') && !cell.disabled) {\n classes.push('available')\n if (cell.type === 'today') {\n classes.push('today')\n }\n } else {\n classes.push(cell.type)\n }\n\n if (isCurrent(cell)) {\n classes.push('current')\n }\n\n if (\n cell.inRange &&\n (cell.type === 'normal' ||\n cell.type === 'today' ||\n props.selectionMode === 'week')\n ) {\n classes.push('in-range')\n\n if (cell.start) {\n classes.push('start-date')\n }\n\n if (cell.end) {\n classes.push('end-date')\n }\n }\n\n if (cell.disabled) {\n classes.push('disabled')\n }\n\n if (cell.selected) {\n classes.push('selected')\n }\n\n if (cell.customClass) {\n classes.push(cell.customClass)\n }\n\n return classes.join(' ')\n }\n\n const getDateOfCell = (row, column) => {\n const offsetFromStart =\n row * 7 + (column - (props.showWeekNumber ? 1 : 0)) - offsetDay.value\n return startDate.value.add(offsetFromStart, 'day')\n }\n\n const handleMouseMove = (event) => {\n if (!props.rangeState.selecting) return\n\n let target = event.target\n if (target.tagName === 'SPAN') {\n target = target.parentNode.parentNode\n }\n if (target.tagName === 'DIV') {\n target = target.parentNode\n }\n if (target.tagName !== 'TD') return\n\n const row = target.parentNode.rowIndex - 1\n const column = target.cellIndex\n\n // can not select disabled date\n if (rows.value[row][column].disabled) return\n\n // only update rangeState when mouse moves to a new cell\n // this avoids frequent Date object creation and improves performance\n if (row !== lastRow.value || column !== lastColumn.value) {\n lastRow.value = row\n lastColumn.value = column\n ctx.emit('changerange', {\n selecting: true,\n endDate: getDateOfCell(row, column),\n })\n }\n }\n\n const handleClick = (event) => {\n let target = event.target\n\n while (target) {\n if (target.tagName === 'TD') {\n break\n }\n target = target.parentNode\n }\n\n if (!target || target.tagName !== 'TD') return\n\n const row = target.parentNode.rowIndex - 1\n const column = target.cellIndex\n const cell = rows.value[row][column]\n\n if (cell.disabled || cell.type === 'week') return\n\n const newDate = getDateOfCell(row, column)\n\n if (props.selectionMode === 'range') {\n if (!props.rangeState.selecting) {\n ctx.emit('pick', { minDate: newDate, maxDate: null })\n ctx.emit('select', true)\n } else {\n if (newDate >= props.minDate) {\n ctx.emit('pick', { minDate: props.minDate, maxDate: newDate })\n } else {\n ctx.emit('pick', { minDate: newDate, maxDate: props.minDate })\n }\n ctx.emit('select', false)\n }\n } else if (props.selectionMode === 'day') {\n ctx.emit('pick', newDate)\n } else if (props.selectionMode === 'week') {\n const weekNumber = newDate.week()\n const value = `${newDate.year()}w${weekNumber}`\n ctx.emit('pick', {\n year: newDate.year(),\n week: weekNumber,\n value,\n date: newDate.startOf('week'),\n })\n } else if (props.selectionMode === 'dates') {\n const newValue = cell.selected\n ? castArray(props.parsedValue).filter(\n (_) => _.valueOf() !== newDate.valueOf()\n )\n : castArray(props.parsedValue).concat([newDate])\n ctx.emit('pick', newValue)\n }\n }\n\n const isWeekActive = (cell) => {\n if (props.selectionMode !== 'week') return false\n let newDate = props.date.startOf('day')\n\n if (cell.type === 'prev-month') {\n newDate = newDate.subtract(1, 'month')\n }\n\n if (cell.type === 'next-month') {\n newDate = newDate.add(1, 'month')\n }\n\n newDate = newDate.date(parseInt(cell.text, 10))\n\n if (props.parsedValue && !Array.isArray(props.parsedValue)) {\n const dayOffset =\n ((props.parsedValue.day() - firstDayOfWeek + 7) % 7) - 1\n const weekDate = props.parsedValue.subtract(dayOffset, 'day')\n return weekDate.isSame(newDate, 'day')\n }\n return false\n }\n\n return {\n handleMouseMove,\n t,\n rows,\n isWeekActive,\n getCellClasses,\n WEEKS,\n handleClick,\n }\n },\n})\n</script>\n"],"names":["_openBlock"],"mappings":"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"}