@opentiny/vue-renderless
Version:
An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.
195 lines (194 loc) • 6.31 kB
JavaScript
import "../chunk-G2ADBYYC.js";
import { range as rangeDate, getDayCountOfMonth, nextDate, toDate1, hasClass, DATEPICKER } from "@opentiny/utils";
import { arrayFindIndex, coerceTruthyValueToArray, arrayFind } from "../date-table";
const datesInMonth = (year, month) => {
const numOfDays = getDayCountOfMonth(year, month);
const firstDay = new Date(year, month, 1);
return rangeDate(numOfDays).map((n) => nextDate(firstDay, n));
};
const clearDate = (date) => new Date(date.getFullYear(), date.getMonth());
const getMonthTimestamp = (time) => {
if (typeof time === "number" || typeof time === "string") {
return clearDate(new Date(time)).getTime();
} else if (time instanceof Date) {
return clearDate(time).getTime();
}
return NaN;
};
const getRows = ({ props, state, vm }) => () => {
const tableRows = state.tableRows;
const disabledDate = state.disabledDate;
const selectedDate = [];
const now = getMonthTimestamp(/* @__PURE__ */ new Date());
const { date, minDate, maxDate } = props;
for (let i = 0; i < 3; i++) {
const row = tableRows[i];
for (let j = 0; j < 4; j++) {
let cell = row[j];
if (!cell) {
cell = {
type: DATEPICKER.Normal,
row: i,
column: j,
inRange: false,
start: false,
end: false
};
}
cell.type = DATEPICKER.Normal;
const index = i * 4 + j;
const time = new Date(date.getFullYear(), index).getTime();
cell.start = minDate && time === getMonthTimestamp(minDate);
cell.end = maxDate && time === getMonthTimestamp(maxDate);
cell.inRange = time >= getMonthTimestamp(minDate) && time <= getMonthTimestamp(maxDate);
const isToday = time === now;
if (isToday) {
cell.type = DATEPICKER.Today;
}
cell.text = index;
let cellDate = new Date(time);
cell.disabled = typeof disabledDate === "function" && disabledDate(cellDate);
cell.selected = arrayFind(selectedDate, (selectDate) => selectDate.getTime() === cellDate.getTime());
vm.$set(row, j, cell);
}
}
return tableRows;
};
const markRange = ({ props, state }) => (minDate, maxDate) => {
minDate = getMonthTimestamp(minDate);
maxDate = getMonthTimestamp(maxDate);
if (minDate > maxDate) {
;
[minDate, maxDate] = [maxDate, minDate];
}
const rows = state.rows;
for (let i = 0, len = rows.length; i < len; i++) {
const row = rows[i];
for (let j = 0, l = row.length; j < l; j++) {
const cell = row[j];
const index = i * 4 + j;
const time = new Date(props.date.getFullYear(), index).getTime();
cell.start = minDate && time === minDate;
cell.end = maxDate && time === maxDate;
cell.inRange = minDate && time >= minDate && time <= maxDate;
}
}
};
const watchDate = ({ api, props }) => (value, oldvalue) => {
if (getMonthTimestamp(value) !== getMonthTimestamp(oldvalue)) {
api.markRange(props.minDate, props.maxDate);
}
};
const getTarget = (event) => {
let target = event.target;
if (target.tagName === "A") {
target = target.parentNode.parentNode;
}
if (target.tagName === "DIV") {
target = target.parentNode;
}
if (target.tagName !== "TD") {
return;
}
return target;
};
const handleMouseMove = ({ api, emit, props, state }) => (event) => {
if (!props.rangeState.selecting) {
return;
}
const target = getTarget(event);
if (!target) {
return;
}
const row = target.parentNode.rowIndex;
const colu = target.cellIndex;
if (state.rows[row][colu].disabled) {
return;
}
if (row !== state.lastRow || colu !== state.lastColumn) {
state.lastColumn = colu;
state.lastRow = row;
emit("changerange", {
maxDate: props.maxDate,
minDate: props.minDate,
rangeState: {
selecting: true,
endDate: api.getMonthOfCell(row * 4 + colu)
}
});
}
};
const handleMonthTableClick = ({ api, emit, props }) => (event) => {
if (props.readonly) {
return;
}
const target = getTarget(event);
if (!target) {
return;
}
if (hasClass(target, "disabled")) {
return;
}
const column = target.cellIndex;
const row = target.parentNode.rowIndex;
const month = row * 4 + column;
const newDate = api.getMonthOfCell(month);
if (props.selectionMode === DATEPICKER.Range) {
if (props.rangeState.selecting) {
if (newDate < props.minDate) {
emit("pick", { minDate: newDate, maxDate: props.minDate });
} else {
emit("pick", { minDate: props.minDate, maxDate: newDate });
}
props.rangeState.selecting = false;
} else {
emit("pick", { minDate: newDate, maxDate: null });
props.rangeState.selecting = true;
}
} else {
emit("pick", month);
}
};
const cellMatchesDate = (props) => (cell, date) => {
const value = new Date(date);
return props.date.getFullYear() === value.getFullYear() && Number(cell.text) === value.getMonth();
};
const getCellStyle = ({ api, props }) => (cell) => {
const style = {};
const year = props.date.getFullYear();
const today = /* @__PURE__ */ new Date();
const month = cell.text;
const defaultValue = props.defaultValue ? Array.isArray(props.defaultValue) ? props.defaultValue : [props.defaultValue] : [];
style.disabled = typeof props.disabledDate === "function" ? datesInMonth(year, month).every(props.disabledDate) : false;
const execDate = typeof props.value === "object" ? props.value : toDate1(props.value);
style.current = arrayFindIndex(
coerceTruthyValueToArray(execDate),
(date) => date.getFullYear() === year && date.getMonth() === month
) >= 0;
style.today = today.getFullYear() === year && today.getMonth() === month;
style.default = defaultValue.some((date) => api.cellMatchesDate(cell, date));
if (cell.inRange) {
style[DATEPICKER.InRange] = true;
if (cell.start) {
style[DATEPICKER.StartDate] = true;
}
if (cell.end) {
style[DATEPICKER.EndDate] = true;
}
}
return style;
};
const getMonthOfCell = (props) => (month) => new Date(props.date.getFullYear(), month, 1);
export {
cellMatchesDate,
clearDate,
datesInMonth,
getCellStyle,
getMonthOfCell,
getMonthTimestamp,
getRows,
handleMonthTableClick,
handleMouseMove,
markRange,
watchDate
};