123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- import { ref, computed, unref, watch, nextTick } from 'vue';
- import dayjs from 'dayjs';
- import { flatten } from 'lodash-unified';
- import { buildPickerTable } from '../utils.mjs';
- import { useLocale } from '../../../../hooks/use-locale/index.mjs';
- import { castArray } from '../../../../utils/arrays.mjs';
- import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
- import { isArray } from '@vue/shared';
- const isNormalDay = (type = "") => {
- return ["normal", "today"].includes(type);
- };
- const useBasicDateTable = (props, emit) => {
- const { lang } = useLocale();
- const tbodyRef = ref();
- const currentCellRef = ref();
- const lastRow = ref();
- const lastColumn = ref();
- const tableRows = ref([[], [], [], [], [], []]);
- let focusWithClick = false;
- const firstDayOfWeek = props.date.$locale().weekStart || 7;
- const WEEKS_CONSTANT = props.date.locale("en").localeData().weekdaysShort().map((_) => _.toLowerCase());
- const offsetDay = computed(() => {
- return firstDayOfWeek > 3 ? 7 - firstDayOfWeek : -firstDayOfWeek;
- });
- const startDate = computed(() => {
- const startDayOfMonth = props.date.startOf("month");
- return startDayOfMonth.subtract(startDayOfMonth.day() || 7, "day");
- });
- const WEEKS = computed(() => {
- return WEEKS_CONSTANT.concat(WEEKS_CONSTANT).slice(firstDayOfWeek, firstDayOfWeek + 7);
- });
- const hasCurrent = computed(() => {
- return flatten(unref(rows)).some((row) => {
- return row.isCurrent;
- });
- });
- const days = 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 = computed(() => {
- return props.selectionMode === "dates" ? castArray(props.parsedValue) : [];
- });
- const setDateText = (cell, { count, rowIndex, columnIndex }) => {
- const { startOfMonthDay, dateCountOfMonth, dateCountOfLastMonth } = unref(days);
- const offset = 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 = 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 = computed(() => {
- const { minDate, maxDate, rangeState, showWeekNumber } = props;
- const offset = unref(offsetDay);
- const rows_ = unref(tableRows);
- const dateUnit = "day";
- let count = 1;
- if (showWeekNumber) {
- for (let rowIndex = 0; rowIndex < 6; rowIndex++) {
- if (!rows_[rowIndex][0]) {
- rows_[rowIndex][0] = {
- type: "week",
- text: unref(startDate).add(rowIndex * 7 + 1, dateUnit).week()
- };
- }
- }
- }
- buildPickerTable({ row: 6, column: 7 }, rows_, {
- startDate: minDate,
- columnIndexOffset: showWeekNumber ? 1 : 0,
- nextEndDate: rangeState.endDate || maxDate || rangeState.selecting && minDate || null,
- now: dayjs().locale(unref(lang)).startOf(dateUnit),
- unit: dateUnit,
- relativeDateGetter: (idx) => unref(startDate).add(idx - offset, dateUnit),
- setCellMetadata: (...args) => {
- if (setCellMetadata(...args, count)) {
- count += 1;
- }
- },
- setRowMetadata
- });
- return rows_;
- });
- watch(() => props.date, async () => {
- var _a;
- if ((_a = unref(tbodyRef)) == null ? void 0 : _a.contains(document.activeElement)) {
- await nextTick();
- await focus();
- }
- });
- const focus = async () => {
- var _a;
- return (_a = 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(date).locale(unref(lang)).isSame(props.date.date(Number(cell.text)), "day");
- };
- const getDateOfCell = (row, column) => {
- const offsetFromStart = row * 7 + (column - (props.showWeekNumber ? 1 : 0)) - unref(offsetDay);
- return 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 (unref(rows)[row][column].disabled)
- return;
- if (row !== unref(lastRow) || column !== unref(lastColumn)) {
- lastRow.value = row;
- lastColumn.value = column;
- emit("changerange", {
- selecting: true,
- endDate: getDateOfCell(row, column)
- });
- }
- };
- const isSelectedCell = (cell) => {
- return !unref(hasCurrent) && (cell == null ? void 0 : cell.text) === 1 && cell.type === "normal" || cell.isCurrent;
- };
- const handleFocus = (event) => {
- if (focusWithClick || 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 ? castArray(props.parsedValue).filter((d) => (d == null ? void 0 : d.valueOf()) !== newDate.valueOf()) : castArray(props.parsedValue).concat([newDate]);
- emit("pick", newValue);
- };
- const handlePickDate = (event, isKeyboardMovement = false) => {
- const target = event.target.closest("td");
- if (!target)
- return;
- const row = target.parentNode.rowIndex - 1;
- const column = target.cellIndex;
- const cell = 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 && !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 = useNamespace("date-table");
- const { t } = useLocale();
- const tableKls = computed(() => [
- ns.b(),
- { "is-week-mode": props.selectionMode === "week" }
- ]);
- const tableLabel = computed(() => t("el.datepicker.dateTablePrompt"));
- const weekLabel = computed(() => t("el.datepicker.week"));
- 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) {
- 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,
- weekLabel,
- getCellClasses,
- getRowKls,
- t
- };
- };
- export { useBasicDateTable, useBasicDateTableDOM };
- //# sourceMappingURL=use-basic-date-table.mjs.map
|