359 lines
12 KiB
JavaScript
359 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var vue = require('vue');
|
|
var dayjs = require('dayjs');
|
|
var lodashUnified = require('lodash-unified');
|
|
var utils = require('../utils.js');
|
|
var index = require('../../../../hooks/use-locale/index.js');
|
|
var arrays = require('../../../../utils/arrays.js');
|
|
var index$1 = require('../../../../hooks/use-namespace/index.js');
|
|
var shared = require('@vue/shared');
|
|
|
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
|
|
var dayjs__default = /*#__PURE__*/_interopDefaultLegacy(dayjs);
|
|
|
|
const isNormalDay = (type = "") => {
|
|
return ["normal", "today"].includes(type);
|
|
};
|
|
const useBasicDateTable = (props, emit) => {
|
|
const { lang } = index.useLocale();
|
|
const tbodyRef = vue.ref();
|
|
const currentCellRef = vue.ref();
|
|
const lastRow = vue.ref();
|
|
const lastColumn = vue.ref();
|
|
const tableRows = vue.ref([[], [], [], [], [], []]);
|
|
let focusWithClick = false;
|
|
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 lodashUnified.flatten(vue.unref(rows)).some((row) => {
|
|
return row.isCurrent;
|
|
});
|
|
});
|
|
const days = vue.computed(() => {
|
|
const startOfMonth = props.date.startOf("month");
|
|
const startOfMonthDay = startOfMonth.day() || 7;
|
|
const dateCountOfMonth = startOfMonth.daysInMonth();
|
|
const dateCountOfLastMonth = startOfMonth.subtract(1, "month").daysInMonth();
|
|
return {
|
|
startOfMonthDay,
|
|
dateCountOfMonth,
|
|
dateCountOfLastMonth
|
|
};
|
|
});
|
|
const selectedDate = vue.computed(() => {
|
|
return props.selectionMode === "dates" ? arrays.castArray(props.parsedValue) : [];
|
|
});
|
|
const setDateText = (cell, { count, rowIndex, columnIndex }) => {
|
|
const { startOfMonthDay, dateCountOfMonth, dateCountOfLastMonth } = vue.unref(days);
|
|
const offset = vue.unref(offsetDay);
|
|
if (rowIndex >= 0 && rowIndex <= 1) {
|
|
const numberOfDaysFromPreviousMonth = startOfMonthDay + offset < 0 ? 7 + startOfMonthDay + offset : startOfMonthDay + offset;
|
|
if (columnIndex + rowIndex * 7 >= numberOfDaysFromPreviousMonth) {
|
|
cell.text = count;
|
|
return true;
|
|
} else {
|
|
cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - columnIndex % 7) + 1 + rowIndex * 7;
|
|
cell.type = "prev-month";
|
|
}
|
|
} else {
|
|
if (count <= dateCountOfMonth) {
|
|
cell.text = count;
|
|
} else {
|
|
cell.text = count - dateCountOfMonth;
|
|
cell.type = "next-month";
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
const setCellMetadata = (cell, { columnIndex, rowIndex }, count) => {
|
|
const { disabledDate, cellClassName } = props;
|
|
const _selectedDate = vue.unref(selectedDate);
|
|
const shouldIncrement = setDateText(cell, { count, rowIndex, columnIndex });
|
|
const cellDate = cell.dayjs.toDate();
|
|
cell.selected = _selectedDate.find((d) => d.isSame(cell.dayjs, "day"));
|
|
cell.isSelected = !!cell.selected;
|
|
cell.isCurrent = isCurrent(cell);
|
|
cell.disabled = disabledDate == null ? void 0 : disabledDate(cellDate);
|
|
cell.customClass = cellClassName == null ? void 0 : cellClassName(cellDate);
|
|
return shouldIncrement;
|
|
};
|
|
const setRowMetadata = (row) => {
|
|
if (props.selectionMode === "week") {
|
|
const [start, end] = props.showWeekNumber ? [1, 7] : [0, 6];
|
|
const isActive = isWeekActive(row[start + 1]);
|
|
row[start].inRange = isActive;
|
|
row[start].start = isActive;
|
|
row[end].inRange = isActive;
|
|
row[end].end = isActive;
|
|
}
|
|
};
|
|
const rows = vue.computed(() => {
|
|
const { minDate, maxDate, rangeState, showWeekNumber } = props;
|
|
const offset = vue.unref(offsetDay);
|
|
const rows_ = vue.unref(tableRows);
|
|
const dateUnit = "day";
|
|
let count = 1;
|
|
utils.buildPickerTable({ row: 6, column: 7 }, rows_, {
|
|
startDate: minDate,
|
|
columnIndexOffset: showWeekNumber ? 1 : 0,
|
|
nextEndDate: rangeState.endDate || maxDate || rangeState.selecting && minDate || null,
|
|
now: dayjs__default["default"]().locale(vue.unref(lang)).startOf(dateUnit),
|
|
unit: dateUnit,
|
|
relativeDateGetter: (idx) => vue.unref(startDate).add(idx - offset, dateUnit),
|
|
setCellMetadata: (...args) => {
|
|
if (setCellMetadata(...args, count)) {
|
|
count += 1;
|
|
}
|
|
},
|
|
setRowMetadata
|
|
});
|
|
if (showWeekNumber) {
|
|
for (let rowIndex = 0; rowIndex < 6; rowIndex++) {
|
|
if (rows_[rowIndex][1].dayjs) {
|
|
rows_[rowIndex][0] = {
|
|
type: "week",
|
|
text: rows_[rowIndex][1].dayjs.week()
|
|
};
|
|
}
|
|
}
|
|
}
|
|
return rows_;
|
|
});
|
|
vue.watch(() => props.date, async () => {
|
|
var _a;
|
|
if ((_a = vue.unref(tbodyRef)) == null ? void 0 : _a.contains(document.activeElement)) {
|
|
await vue.nextTick();
|
|
await focus();
|
|
}
|
|
});
|
|
const focus = async () => {
|
|
var _a;
|
|
return (_a = vue.unref(currentCellRef)) == null ? void 0 : _a.focus();
|
|
};
|
|
const isCurrent = (cell) => {
|
|
return props.selectionMode === "date" && isNormalDay(cell.type) && cellMatchesDate(cell, props.parsedValue);
|
|
};
|
|
const cellMatchesDate = (cell, date) => {
|
|
if (!date)
|
|
return false;
|
|
return dayjs__default["default"](date).locale(vue.unref(lang)).isSame(props.date.date(Number(cell.text)), "day");
|
|
};
|
|
const getDateOfCell = (row, column) => {
|
|
const offsetFromStart = row * 7 + (column - (props.showWeekNumber ? 1 : 0)) - vue.unref(offsetDay);
|
|
return vue.unref(startDate).add(offsetFromStart, "day");
|
|
};
|
|
const handleMouseMove = (event) => {
|
|
var _a;
|
|
if (!props.rangeState.selecting)
|
|
return;
|
|
let target = event.target;
|
|
if (target.tagName === "SPAN") {
|
|
target = (_a = target.parentNode) == null ? void 0 : _a.parentNode;
|
|
}
|
|
if (target.tagName === "DIV") {
|
|
target = target.parentNode;
|
|
}
|
|
if (target.tagName !== "TD")
|
|
return;
|
|
const row = target.parentNode.rowIndex - 1;
|
|
const column = target.cellIndex;
|
|
if (vue.unref(rows)[row][column].disabled)
|
|
return;
|
|
if (row !== vue.unref(lastRow) || column !== vue.unref(lastColumn)) {
|
|
lastRow.value = row;
|
|
lastColumn.value = column;
|
|
emit("changerange", {
|
|
selecting: true,
|
|
endDate: getDateOfCell(row, column)
|
|
});
|
|
}
|
|
};
|
|
const isSelectedCell = (cell) => {
|
|
return !vue.unref(hasCurrent) && (cell == null ? void 0 : cell.text) === 1 && cell.type === "normal" || cell.isCurrent;
|
|
};
|
|
const handleFocus = (event) => {
|
|
if (focusWithClick || vue.unref(hasCurrent) || props.selectionMode !== "date")
|
|
return;
|
|
handlePickDate(event, true);
|
|
};
|
|
const handleMouseDown = (event) => {
|
|
const target = event.target.closest("td");
|
|
if (!target)
|
|
return;
|
|
focusWithClick = true;
|
|
};
|
|
const handleMouseUp = (event) => {
|
|
const target = event.target.closest("td");
|
|
if (!target)
|
|
return;
|
|
focusWithClick = false;
|
|
};
|
|
const handleRangePick = (newDate) => {
|
|
if (!props.rangeState.selecting || !props.minDate) {
|
|
emit("pick", { minDate: newDate, maxDate: null });
|
|
emit("select", true);
|
|
} else {
|
|
if (newDate >= props.minDate) {
|
|
emit("pick", { minDate: props.minDate, maxDate: newDate });
|
|
} else {
|
|
emit("pick", { minDate: newDate, maxDate: props.minDate });
|
|
}
|
|
emit("select", false);
|
|
}
|
|
};
|
|
const handleWeekPick = (newDate) => {
|
|
const weekNumber = newDate.week();
|
|
const value = `${newDate.year()}w${weekNumber}`;
|
|
emit("pick", {
|
|
year: newDate.year(),
|
|
week: weekNumber,
|
|
value,
|
|
date: newDate.startOf("week")
|
|
});
|
|
};
|
|
const handleDatesPick = (newDate, selected) => {
|
|
const newValue = selected ? arrays.castArray(props.parsedValue).filter((d) => (d == null ? void 0 : d.valueOf()) !== newDate.valueOf()) : arrays.castArray(props.parsedValue).concat([newDate]);
|
|
emit("pick", newValue);
|
|
};
|
|
const handlePickDate = (event, isKeyboardMovement = false) => {
|
|
if (props.disabled)
|
|
return;
|
|
const target = event.target.closest("td");
|
|
if (!target)
|
|
return;
|
|
const row = target.parentNode.rowIndex - 1;
|
|
const column = target.cellIndex;
|
|
const cell = vue.unref(rows)[row][column];
|
|
if (cell.disabled || cell.type === "week")
|
|
return;
|
|
const newDate = getDateOfCell(row, column);
|
|
switch (props.selectionMode) {
|
|
case "range": {
|
|
handleRangePick(newDate);
|
|
break;
|
|
}
|
|
case "date": {
|
|
emit("pick", newDate, isKeyboardMovement);
|
|
break;
|
|
}
|
|
case "week": {
|
|
handleWeekPick(newDate);
|
|
break;
|
|
}
|
|
case "dates": {
|
|
handleDatesPick(newDate, !!cell.selected);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
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 && !shared.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 {
|
|
WEEKS,
|
|
rows,
|
|
tbodyRef,
|
|
currentCellRef,
|
|
focus,
|
|
isCurrent,
|
|
isWeekActive,
|
|
isSelectedCell,
|
|
handlePickDate,
|
|
handleMouseUp,
|
|
handleMouseDown,
|
|
handleMouseMove,
|
|
handleFocus
|
|
};
|
|
};
|
|
const useBasicDateTableDOM = (props, {
|
|
isCurrent,
|
|
isWeekActive
|
|
}) => {
|
|
const ns = index$1.useNamespace("date-table");
|
|
const { t } = index.useLocale();
|
|
const tableKls = vue.computed(() => [
|
|
ns.b(),
|
|
{ "is-week-mode": props.selectionMode === "week" && !props.disabled }
|
|
]);
|
|
const tableLabel = vue.computed(() => t("el.datepicker.dateTablePrompt"));
|
|
const getCellClasses = (cell) => {
|
|
const classes = [];
|
|
if (isNormalDay(cell.type) && !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 && (isNormalDay(cell.type) || props.selectionMode === "week")) {
|
|
classes.push("in-range");
|
|
if (cell.start) {
|
|
classes.push("start-date");
|
|
}
|
|
if (cell.end) {
|
|
classes.push("end-date");
|
|
}
|
|
}
|
|
if (cell.disabled || props.disabled) {
|
|
classes.push("disabled");
|
|
}
|
|
if (cell.selected) {
|
|
classes.push("selected");
|
|
}
|
|
if (cell.customClass) {
|
|
classes.push(cell.customClass);
|
|
}
|
|
return classes.join(" ");
|
|
};
|
|
const getRowKls = (cell) => [
|
|
ns.e("row"),
|
|
{ current: isWeekActive(cell) }
|
|
];
|
|
return {
|
|
tableKls,
|
|
tableLabel,
|
|
weekHeaderClass: ns.e("week-header"),
|
|
getCellClasses,
|
|
getRowKls,
|
|
t
|
|
};
|
|
};
|
|
|
|
exports.useBasicDateTable = useBasicDateTable;
|
|
exports.useBasicDateTableDOM = useBasicDateTableDOM;
|
|
//# sourceMappingURL=use-basic-date-table.js.map
|