element-plus
Version:
A Component Library for Vue 3
392 lines (385 loc) • 15.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var dayjs = require('dayjs');
require('../../../../hooks/index2.js');
require('../../../../utils/index2.js');
var basicCellRender = require('./basic-cell-render2.js');
var pluginVue_exportHelper = require('../../../../_virtual/plugin-vue_export-helper.js');
var index = require('../../../../hooks/use-locale/index2.js');
var arrays = require('../../../../utils/arrays2.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var dayjs__default = /*#__PURE__*/_interopDefaultLegacy(dayjs);
const _sfc_main = vue.defineComponent({
components: {
ElDatePickerCell: basicCellRender["default"]
},
props: {
date: {
type: Object
},
minDate: {
type: Object
},
maxDate: {
type: Object
},
parsedValue: {
type: [Object, Array]
},
selectionMode: {
type: String,
default: "date"
},
showWeekNumber: {
type: Boolean,
default: false
},
disabledDate: {
type: Function
},
cellClassName: {
type: Function
},
rangeState: {
type: Object,
default: () => ({
endDate: null,
selecting: false
})
}
},
emits: ["changerange", "pick", "select"],
expose: ["focus"],
setup(props, ctx) {
const { t, lang } = index.useLocale();
const tbodyRef = vue.ref();
const currentCellRef = vue.ref();
const lastRow = vue.ref(null);
const lastColumn = vue.ref(null);
const tableRows = vue.ref([[], [], [], [], [], []]);
const firstDayOfWeek = props.date.$locale().weekStart || 7;
const WEEKS_CONSTANT = props.date.locale("en").localeData().weekdaysShort().map((_) => _.toLowerCase());
const offsetDay = vue.computed(() => {
return firstDayOfWeek > 3 ? 7 - firstDayOfWeek : -firstDayOfWeek;
});
const startDate = vue.computed(() => {
const startDayOfMonth = props.date.startOf("month");
return startDayOfMonth.subtract(startDayOfMonth.day() || 7, "day");
});
const WEEKS = vue.computed(() => {
return WEEKS_CONSTANT.concat(WEEKS_CONSTANT).slice(firstDayOfWeek, firstDayOfWeek + 7);
});
const hasCurrent = vue.computed(() => {
return rows.value.flat().some((row) => {
return row.isCurrent;
});
});
const rows = vue.computed(() => {
var _a;
const startOfMonth = props.date.startOf("month");
const startOfMonthDay = startOfMonth.day() || 7;
const dateCountOfMonth = startOfMonth.daysInMonth();
const dateCountOfLastMonth = startOfMonth.subtract(1, "month").daysInMonth();
const offset = offsetDay.value;
const rows_ = tableRows.value;
let count = 1;
const selectedDate = props.selectionMode === "dates" ? arrays.castArray(props.parsedValue) : [];
const calNow = dayjs__default["default"]().locale(lang.value).startOf("day");
for (let i = 0; i < 6; i++) {
const row = rows_[i];
if (props.showWeekNumber) {
if (!row[0]) {
row[0] = {
type: "week",
text: startDate.value.add(i * 7 + 1, "day").week()
};
}
}
for (let j = 0; j < 7; j++) {
let cell = row[props.showWeekNumber ? j + 1 : j];
if (!cell) {
cell = {
row: i,
column: j,
type: "normal",
inRange: false,
start: false,
end: false
};
}
const index = i * 7 + j;
const calTime = startDate.value.add(index - offset, "day");
cell.dayjs = calTime;
cell.date = calTime.toDate();
cell.timestamp = calTime.valueOf();
cell.type = "normal";
const calEndDate = props.rangeState.endDate || props.maxDate || props.rangeState.selecting && props.minDate;
cell.inRange = props.minDate && calTime.isSameOrAfter(props.minDate, "day") && calEndDate && calTime.isSameOrBefore(calEndDate, "day") || props.minDate && calTime.isSameOrBefore(props.minDate, "day") && calEndDate && calTime.isSameOrAfter(calEndDate, "day");
if ((_a = props.minDate) == null ? void 0 : _a.isSameOrAfter(calEndDate)) {
cell.start = calEndDate && calTime.isSame(calEndDate, "day");
cell.end = props.minDate && calTime.isSame(props.minDate, "day");
} else {
cell.start = props.minDate && calTime.isSame(props.minDate, "day");
cell.end = calEndDate && calTime.isSame(calEndDate, "day");
}
const isToday = calTime.isSame(calNow, "day");
if (isToday) {
cell.type = "today";
}
if (i >= 0 && i <= 1) {
const numberOfDaysFromPreviousMonth = startOfMonthDay + offset < 0 ? 7 + startOfMonthDay + offset : startOfMonthDay + offset;
if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
cell.text = count++;
} else {
cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - j % 7) + 1 + i * 7;
cell.type = "prev-month";
}
} else {
if (count <= dateCountOfMonth) {
cell.text = count++;
} else {
cell.text = count++ - dateCountOfMonth;
cell.type = "next-month";
}
}
const cellDate = calTime.toDate();
cell.selected = selectedDate.find((_) => _.valueOf() === calTime.valueOf());
cell.isSelected = !!cell.selected;
cell.isCurrent = isCurrent(cell);
cell.disabled = props.disabledDate && props.disabledDate(cellDate);
cell.customClass = props.cellClassName && props.cellClassName(cellDate);
row[props.showWeekNumber ? j + 1 : j] = cell;
}
if (props.selectionMode === "week") {
const start = props.showWeekNumber ? 1 : 0;
const end = props.showWeekNumber ? 7 : 6;
const isActive = isWeekActive(row[start + 1]);
row[start].inRange = isActive;
row[start].start = isActive;
row[end].inRange = isActive;
row[end].end = isActive;
}
}
return rows_;
});
vue.watch(() => props.date, async () => {
var _a, _b;
if ((_a = tbodyRef.value) == null ? void 0 : _a.contains(document.activeElement)) {
await vue.nextTick();
(_b = currentCellRef.value) == null ? void 0 : _b.focus();
}
});
const focus = async () => {
var _a;
(_a = currentCellRef.value) == null ? void 0 : _a.focus();
};
const isCurrent = (cell) => {
return props.selectionMode === "date" && (cell.type === "normal" || cell.type === "today") && cellMatchesDate(cell, props.parsedValue);
};
const cellMatchesDate = (cell, date) => {
if (!date)
return false;
return dayjs__default["default"](date).locale(lang.value).isSame(props.date.date(Number(cell.text)), "day");
};
const getCellClasses = (cell) => {
const classes = [];
if ((cell.type === "normal" || cell.type === "today") && !cell.disabled) {
classes.push("available");
if (cell.type === "today") {
classes.push("today");
}
} else {
classes.push(cell.type);
}
if (isCurrent(cell)) {
classes.push("current");
}
if (cell.inRange && (cell.type === "normal" || cell.type === "today" || props.selectionMode === "week")) {
classes.push("in-range");
if (cell.start) {
classes.push("start-date");
}
if (cell.end) {
classes.push("end-date");
}
}
if (cell.disabled) {
classes.push("disabled");
}
if (cell.selected) {
classes.push("selected");
}
if (cell.customClass) {
classes.push(cell.customClass);
}
return classes.join(" ");
};
const getDateOfCell = (row, column) => {
const offsetFromStart = row * 7 + (column - (props.showWeekNumber ? 1 : 0)) - offsetDay.value;
return startDate.value.add(offsetFromStart, "day");
};
const handleMouseMove = (event) => {
if (!props.rangeState.selecting)
return;
let target = event.target;
if (target.tagName === "SPAN") {
target = target.parentNode.parentNode;
}
if (target.tagName === "DIV") {
target = target.parentNode;
}
if (target.tagName !== "TD")
return;
const row = target.parentNode.rowIndex - 1;
const column = target.cellIndex;
if (rows.value[row][column].disabled)
return;
if (row !== lastRow.value || column !== lastColumn.value) {
lastRow.value = row;
lastColumn.value = column;
ctx.emit("changerange", {
selecting: true,
endDate: getDateOfCell(row, column)
});
}
};
const isSelectedCell = (cell) => {
return !hasCurrent.value && (cell == null ? void 0 : cell.text) === 1 && cell.type === "normal" || cell.isCurrent;
};
const handleFocus = (event) => {
if (!hasCurrent.value && props.selectionMode === "date") {
handlePickDate(event, true);
}
};
const handlePickDate = (event, isKeyboardMovement = false) => {
let target = event.target;
target = target == null ? void 0 : target.closest("td");
if (!target || target.tagName !== "TD")
return;
const row = target.parentNode.rowIndex - 1;
const column = target.cellIndex;
const cell = rows.value[row][column];
if (cell.disabled || cell.type === "week")
return;
const newDate = getDateOfCell(row, column);
if (props.selectionMode === "range") {
if (!props.rangeState.selecting) {
ctx.emit("pick", { minDate: newDate, maxDate: null });
ctx.emit("select", true);
} else {
if (newDate >= props.minDate) {
ctx.emit("pick", { minDate: props.minDate, maxDate: newDate });
} else {
ctx.emit("pick", { minDate: newDate, maxDate: props.minDate });
}
ctx.emit("select", false);
}
} else if (props.selectionMode === "date") {
ctx.emit("pick", newDate, isKeyboardMovement);
} else if (props.selectionMode === "week") {
const weekNumber = newDate.week();
const value = `${newDate.year()}w${weekNumber}`;
ctx.emit("pick", {
year: newDate.year(),
week: weekNumber,
value,
date: newDate.startOf("week")
});
} else if (props.selectionMode === "dates") {
const newValue = cell.selected ? arrays.castArray(props.parsedValue).filter((_) => _.valueOf() !== newDate.valueOf()) : arrays.castArray(props.parsedValue).concat([newDate]);
ctx.emit("pick", newValue);
}
};
const isWeekActive = (cell) => {
if (props.selectionMode !== "week")
return false;
let newDate = props.date.startOf("day");
if (cell.type === "prev-month") {
newDate = newDate.subtract(1, "month");
}
if (cell.type === "next-month") {
newDate = newDate.add(1, "month");
}
newDate = newDate.date(Number.parseInt(cell.text, 10));
if (props.parsedValue && !Array.isArray(props.parsedValue)) {
const dayOffset = (props.parsedValue.day() - firstDayOfWeek + 7) % 7 - 1;
const weekDate = props.parsedValue.subtract(dayOffset, "day");
return weekDate.isSame(newDate, "day");
}
return false;
};
return {
tbodyRef,
currentCellRef,
handleMouseMove,
t,
hasCurrent,
rows,
isSelectedCell,
isWeekActive,
getCellClasses,
WEEKS,
handleFocus,
handlePickDate,
focus
};
}
});
const _hoisted_1 = ["aria-label"];
const _hoisted_2 = { ref: "tbodyRef" };
const _hoisted_3 = {
key: 0,
scope: "col"
};
const _hoisted_4 = ["aria-label"];
const _hoisted_5 = ["aria-current", "aria-selected", "tabindex"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_el_date_picker_cell = vue.resolveComponent("el-date-picker-cell");
return vue.openBlock(), vue.createElementBlock("table", {
role: "grid",
"aria-label": _ctx.t("el.datepicker.dateTablePrompt"),
cellspacing: "0",
cellpadding: "0",
class: vue.normalizeClass(["el-date-table", { "is-week-mode": _ctx.selectionMode === "week" }]),
onClick: _cache[1] || (_cache[1] = (...args) => _ctx.handlePickDate && _ctx.handlePickDate(...args)),
onMousemove: _cache[2] || (_cache[2] = (...args) => _ctx.handleMouseMove && _ctx.handleMouseMove(...args))
}, [
vue.createElementVNode("tbody", _hoisted_2, [
vue.createElementVNode("tr", null, [
_ctx.showWeekNumber ? (vue.openBlock(), vue.createElementBlock("th", _hoisted_3, vue.toDisplayString(_ctx.t("el.datepicker.week")), 1)) : vue.createCommentVNode("v-if", true),
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.WEEKS, (week, key) => {
return vue.openBlock(), vue.createElementBlock("th", {
key,
scope: "col",
"aria-label": _ctx.t("el.datepicker.weeksFull." + week)
}, vue.toDisplayString(_ctx.t("el.datepicker.weeks." + week)), 9, _hoisted_4);
}), 128))
]),
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.rows, (row, key) => {
return vue.openBlock(), vue.createElementBlock("tr", {
key,
class: vue.normalizeClass(["el-date-table__row", { current: _ctx.isWeekActive(row[1]) }])
}, [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(row, (cell, key_) => {
return vue.openBlock(), vue.createElementBlock("td", {
key: key_,
ref_for: true,
ref: (el) => _ctx.isSelectedCell(cell) && (_ctx.currentCellRef = el),
class: vue.normalizeClass(_ctx.getCellClasses(cell)),
"aria-current": cell.isCurrent ? "date" : void 0,
"aria-selected": `${cell.isCurrent}`,
tabindex: _ctx.isSelectedCell(cell) ? 0 : -1,
onFocus: _cache[0] || (_cache[0] = (...args) => _ctx.handleFocus && _ctx.handleFocus(...args))
}, [
vue.createVNode(_component_el_date_picker_cell, { cell }, null, 8, ["cell"])
], 42, _hoisted_5);
}), 128))
], 2);
}), 128))
], 512)
], 42, _hoisted_1);
}
var DateTable = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["render", _sfc_render], ["__file", "/home/runner/work/element-plus/element-plus/packages/components/date-picker/src/date-picker-com/basic-date-table.vue"]]);
exports["default"] = DateTable;
//# sourceMappingURL=basic-date-table2.js.map