UNPKG

@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.

366 lines (365 loc) 12.8 kB
import "../chunk-G2ADBYYC.js"; import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, prevDate, nextDate, isDate1 as isDate, clearTime, formatDate, DATEPICKER } from "@opentiny/utils"; const formatJudg = ({ day, offset, j, i, cell, count, dateCountOfLastMonth }) => { const nodfpm = day + offset <= 0 ? 7 + day + offset : day + offset; if (j + i * 7 >= nodfpm) { cell.text = count++; } else { cell.text = dateCountOfLastMonth - (nodfpm - j % 7) + 1 + i * 7; cell.type = DATEPICKER.PreMonth; } return { count }; }; const getOffsetDay = (props) => () => { const week = props.firstDayOfWeek; return week > 3 ? 7 - week : -week; }; const getWeeks = ({ props, state }) => () => { const week = props.firstDayOfWeek; return state.constWeeks.concat(state.constWeeks).slice(week, week + 7); }; const getDateTimestamp = (time) => { if (typeof time === "number" || typeof time === "string") { return clearTime(new Date(time)).getTime(); } else if (time instanceof Date) { return clearTime(time).getTime(); } return NaN; }; const getSelected = (props, cell, format, t, cellDate, selectedDate) => { let selected = cell.selected; if (props.selectionMode === "dates") { selected = arrayFind(selectedDate, (date) => formatDate(date, format, t) === formatDate(cellDate, format, t)); } else { selected = arrayFind(selectedDate, (date) => date.getTime() === cellDate.getTime()); } return selected; }; const getCell = ({ state, props }) => (row, i, j) => { const now = getDateTimestamp(/* @__PURE__ */ new Date()); let cell = row[props.showWeekNumber ? j + 1 : j]; if (!cell) { cell = { row: i, column: j, inRange: false, start: false, end: false, type: DATEPICKER.Normal }; } cell.type = DATEPICKER.Normal; const index = i * 7 + j; const time = nextDate(state.startDate, index - state.offsetDay).getTime(); cell.inRange = time >= getDateTimestamp(props.minDate) && time <= getDateTimestamp(props.maxDate); cell.start = props.minDate && time === getDateTimestamp(props.minDate); cell.end = props.maxDate && time === getDateTimestamp(props.maxDate); time === now && (cell.type = DATEPICKER.Today); return { cell, cellDate: new Date(time) }; }; const doCount = ({ i, day, offset, j, cell, count, dateCountOfLastMonth, dateCountOfMonth }) => { if (i >= 0 && i <= 1) { const ret = formatJudg({ day, offset, j, i, cell, count, dateCountOfLastMonth }); count = ret.count; } else { if (count <= dateCountOfMonth) { cell.text = count++; } else { cell.text = count++ - dateCountOfMonth; cell.type = DATEPICKER.NextMonth; } } return count; }; const getRows = ({ api, props, state, t, vm }) => () => { const date = new Date(state.year, state.month, 1); let day = getFirstDayOfMonth(date); const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth()); const dateCountOfLastMonth = getDayCountOfMonth( date.getFullYear(), date.getMonth() === 0 ? 11 : date.getMonth() - 1 ); day = day === 0 ? 7 : day; const offset = state.offsetDay; const rows = state.tableRows; const startDate = state.startDate; const disabledDate = props.disabledDate; const cellClassName = props.cellClassName; const selectedDate = props.selectionMode === DATEPICKER.Dates ? coerceTruthyValueToArray(props.value) : []; let count = 1; const isFunction = props.formatWeeks instanceof Function; const arr = []; for (let i = 0; i < 6; i++) { const row = rows[i]; if (props.showWeekNumber) { row[0] = { type: DATEPICKER.Week, text: getWeekNumber(nextDate(startDate, i * 7 + 1)) }; } arr[i] = []; for (let j = 0; j < 7; j++) { const { cell, cellDate } = api.getCell(row, i, j, DATEPICKER.Normal, props); count = doCount({ i, day, offset, j, cell, count, dateCountOfLastMonth, dateCountOfMonth }); cell.disabled = typeof disabledDate === "function" && disabledDate(cellDate); cell.selected = getSelected(props, cell, DATEPICKER.DateFormats.date, t, cellDate, selectedDate); cell.customClass = typeof cellClassName === "function" && cellClassName(cellDate); vm.$set(row, props.showWeekNumber ? j + 1 : j, cell); arr[i].push(cellDate); } if (props.selectionMode === DATEPICKER.Week) { const [start, end] = props.showWeekNumber ? [1, 7] : [0, 6]; const isWeekActive2 = api.isWeekActive(row[start + 1]); Object.assign(row[start], { inRange: isWeekActive2, start: isWeekActive2 }); Object.assign(row[end], { inRange: isWeekActive2, end: isWeekActive2 }); } } const res = []; for (let i = 0; i < arr.length; i++) { res.push(arr[i][0].getFullYear() + "/" + (arr[i][0].getMonth() + 1) + "/" + arr[i][0].getDate()); } if (props.showWeekNumber && isFunction) { for (let i = 0; i < 6; i++) { let val = getWeekNumber(nextDate(startDate, i * 7 + 1)); rows[i][0].text = props.formatWeeks(val, res); } } return rows; }; const arrayFindIndex = (arr, pred) => { for (let i = 0, len = arr.length; i !== len; ++i) { if (pred(arr[i])) { return i; } } return -1; }; const arrayFind = (arr, pred) => { const idx = arrayFindIndex(arr, pred); return ~idx ? arr[idx] : void 0; }; const coerceTruthyValueToArray = (val) => Array.isArray(val) ? val : val ? [val] : []; const watchMinDate = ({ api, props }) => (value, oldvalue) => { if (getDateTimestamp(value) !== getDateTimestamp(oldvalue)) { api.markRange(props.minDate, props.maxDate); } }; const watchMaxDate = ({ api, props }) => (value, oldvalue) => { if (getDateTimestamp(value) !== getDateTimestamp(oldvalue)) { api.markRange(props.minDate, props.maxDate); } }; const cellMatchesDate = (state) => (cell, date) => { const value = new Date(date); return state.year === value.getFullYear() && state.month === value.getMonth() && Number(cell.text) === value.getDate(); }; const getCellRangeClasses = ({ props }) => (cell, classes) => { if (cell.type === DATEPICKER.Normal || cell.type === DATEPICKER.Today || props.selectionMode === DATEPICKER.Week) { classes.push(DATEPICKER.InRange); if (cell.start) { classes.push(DATEPICKER.StartDate); } if (cell.end) { classes.push(DATEPICKER.EndDate); } } }; const getCellClasses = ({ api, props, state }) => (cell) => { let classes = []; const selectionMode = props.selectionMode; const defaultValue = props.defaultValue ? Array.isArray(props.defaultValue) ? props.defaultValue : [props.defaultValue] : []; if ((cell.type === DATEPICKER.Normal || cell.type === DATEPICKER.Today) && !cell.disabled) { classes.push(DATEPICKER.Aviailable); if (cell.type === DATEPICKER.Today) { classes.push(DATEPICKER.Today); } } else { classes.push(cell.type); } if (cell.type === DATEPICKER.Normal && defaultValue.some((date) => api.cellMatchesDate(cell, date))) { classes.push(DATEPICKER.Default); } if (selectionMode === DATEPICKER.Day && ~[DATEPICKER.Normal, DATEPICKER.Today].indexOf(cell.type) && api.cellMatchesDate(cell, props.value || state.date)) { classes.push(DATEPICKER.Current); } if (cell.inRange) { api.getCellRangeClasses(cell, classes); } if (cell.disabled) { classes.push(DATEPICKER.Disabled); } if (cell.selected) { classes.push(DATEPICKER.Selected); } if (cell.customClass) { classes.push(cell.customClass); } return classes.join(" "); }; const getDateOfCell = ({ props, state }) => (row, column) => { const offsetFromStart = row * 7 + (column - (props.showWeekNumber ? 1 : 0)) - state.offsetDay; return nextDate(state.startDate, offsetFromStart); }; const isWeekActive = ({ props, state }) => (cell) => { if (props.selectionMode !== DATEPICKER.Week) { return false; } const newDate = new Date(state.year, state.month, 1); const year = newDate.getFullYear(); const month = newDate.getMonth(); if (cell.type === DATEPICKER.PreMonth) { newDate.setMonth(month === 0 ? 11 : month - 1); newDate.setFullYear(month === 0 ? year - 1 : year); } if (cell.type === DATEPICKER.NextMonth) { newDate.setMonth(month === 11 ? 0 : month + 1); newDate.setFullYear(month === 11 ? year + 1 : year); } newDate.setDate(parseInt(cell.text, 10)); if (isDate(props.value)) { const dayOffset = (props.value.getDay() - props.firstDayOfWeek + 7) % 7 - 1; const weekDate = prevDate(props.value, dayOffset); return weekDate.getTime() === newDate.getTime(); } return false; }; const markRange = ({ props, state }) => (minDate, maxDate) => { const minDateTimestamp = getDateTimestamp(minDate); const maxDateTimestamp = getDateTimestamp(maxDate) || minDateTimestamp; minDate = Math.min(minDateTimestamp, maxDateTimestamp); maxDate = Math.max(minDateTimestamp, maxDateTimestamp); const startDate = state.startDate; const rows = state.rows; for (let i = 0, k = rows.length; i < k; i++) { const row = rows[i]; for (let j = 0, l = row.length; j < l; j++) { if (props.showWeekNumber && j === 0) continue; const cell = row[j]; const index = i * 7 + j + (props.showWeekNumber ? -1 : 0); const time = nextDate(startDate, index - state.offsetDay).getTime(); cell.inRange = minDate && time >= minDate && time <= maxDate; cell.start = minDate && time === minDate; cell.end = maxDate && time === maxDate; } } }; const handleMouseMove = ({ api, emit, props, state }) => (event) => { if (!props.rangeState.selecting) { return; } let targetEl = event.target; if (targetEl.tagName === "SPAN") { targetEl = targetEl.parentNode.parentNode; } if (targetEl.tagName === "DIV") { targetEl = targetEl.parentNode; } if (targetEl.tagName !== "TD") { return; } const row = targetEl.parentNode.rowIndex - 1; const column = targetEl.cellIndex; if (state.rows[row][column].disabled) { return; } if (row !== state.lastRow || column !== state.lastColumn) { state.lastRow = row; state.lastColumn = column; emit("changerange", { minDate: props.minDate, maxDate: props.maxDate, rangeState: { selecting: true, endDate: api.getDateOfCell(row, column) } }); } }; const getTarget = (event) => { let target = event.target; if (target.tagName === "SPAN") { target = target.parentNode.parentNode; } if (target.tagName === "DIV") { target = target.parentNode; } return target; }; const handleClick = ({ api, emit, props, state }) => (event) => { if (props.readonly) { return; } let target = getTarget(event); if (target.tagName !== "TD") { return; } const row = target.parentNode.rowIndex - 1; const column = props.selectionMode === DATEPICKER.Week ? 1 : target.cellIndex; const cell = state.rows[row][column]; if (cell.disabled || cell.type === DATEPICKER.Week) { return; } const newDate = api.getDateOfCell(row, column); if (props.selectionMode === DATEPICKER.Range) { if (!props.rangeState.selecting) { props.rangeState.selecting = true; emit("pick", { minDate: newDate, maxDate: null }); } else { if (newDate >= props.minDate) { emit("pick", { minDate: props.minDate, maxDate: newDate }); } else { emit("pick", { minDate: newDate, maxDate: props.minDate }); } props.rangeState.selecting = false; } } else if (props.selectionMode === DATEPICKER.Day) { emit("pick", newDate); } else if (props.selectionMode === DATEPICKER.Week) { const weekNumber = getWeekNumber(newDate); const value = newDate.getFullYear() + "w" + weekNumber; emit("pick", { year: newDate.getFullYear(), week: weekNumber, value, date: newDate }); } else if (props.selectionMode === DATEPICKER.Dates) { const value = props.value || []; const newValue = cell.selected ? removeFromArray(value, (date) => date.getTime() === newDate.getTime()) : [...value, newDate]; emit("pick", newValue); } }; const removeFromArray = (arr, pred) => { const idx = typeof pred === "function" ? arrayFindIndex(arr, pred) : arr.indexOf(pred); return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr; }; const getCssToken = ({ api }) => (cell, prexfix = "") => { const cssStr = api.getCellClasses(cell) || ""; return cssStr.split(" ").map((className) => prexfix + className); }; export { arrayFind, arrayFindIndex, cellMatchesDate, coerceTruthyValueToArray, getCell, getCellClasses, getCellRangeClasses, getCssToken, getDateOfCell, getDateTimestamp, getOffsetDay, getRows, getWeeks, handleClick, handleMouseMove, isWeekActive, markRange, removeFromArray, watchMaxDate, watchMinDate };