| | |
| | | import { getDateRect, isSameDate, getMonthDateRect, isValidDate, getDate } from '../date'; |
| | | export default class TCalendar { |
| | | constructor(options = {}) { |
| | | this.type = 'single'; |
| | | Object.assign(this, options); |
| | | if (!this.minDate) |
| | | this.minDate = getDate(); |
| | | if (!this.maxDate) |
| | | this.maxDate = getDate(6); |
| | | } |
| | | getTrimValue() { |
| | | const { value, type } = this; |
| | | const format = (val) => { |
| | | if (val instanceof Date) |
| | | return val; |
| | | if (typeof val === 'number') |
| | | return new Date(val); |
| | | return new Date(); |
| | | }; |
| | | if (type === 'single' && isValidDate(value)) |
| | | return format(value); |
| | | if (type === 'multiple' || type === 'range') { |
| | | if (Array.isArray(value)) { |
| | | const isValid = value.every((item) => isValidDate(item)); |
| | | return isValid ? value.map((item) => format(item)) : []; |
| | | } |
| | | return []; |
| | | } |
| | | } |
| | | getDays() { |
| | | const raw = '日一二三四五六'; |
| | | const ans = []; |
| | | let i = this.firstDayOfWeek % 7; |
| | | while (ans.length < 7) { |
| | | ans.push(raw[i]); |
| | | i = (i + 1) % 7; |
| | | } |
| | | return ans; |
| | | } |
| | | getMonths() { |
| | | const ans = []; |
| | | const selectedDate = this.getTrimValue(); |
| | | const { minDate, maxDate, type, format } = this; |
| | | let { year: minYear, month: minMonth, time: minTime } = getDateRect(minDate); |
| | | const { year: maxYear, month: maxMonth, time: maxTime } = getDateRect(maxDate); |
| | | const calcType = (year, month, date) => { |
| | | const curDate = new Date(year, month, date, 23, 59, 59); |
| | | if (type === 'single' && selectedDate) { |
| | | if (isSameDate({ year, month, date }, selectedDate)) |
| | | return 'selected'; |
| | | } |
| | | if (type === 'multiple' && selectedDate) { |
| | | const hit = selectedDate.some((item) => isSameDate({ year, month, date }, item)); |
| | | if (hit) { |
| | | return 'selected'; |
| | | } |
| | | } |
| | | if (type === 'range' && selectedDate) { |
| | | if (Array.isArray(selectedDate)) { |
| | | const [startDate, endDate] = selectedDate; |
| | | if (startDate && isSameDate({ year, month, date }, startDate)) |
| | | return 'start'; |
| | | if (endDate && isSameDate({ year, month, date }, endDate)) |
| | | return 'end'; |
| | | if (startDate && endDate && curDate.getTime() > startDate.getTime() && curDate.getTime() < endDate.getTime()) |
| | | return 'centre'; |
| | | } |
| | | } |
| | | const minCurDate = new Date(year, month, date, 0, 0, 0); |
| | | if (curDate.getTime() < minTime || minCurDate.getTime() > maxTime) { |
| | | return 'disabled'; |
| | | } |
| | | return ''; |
| | | }; |
| | | while (minYear < maxYear || (minYear === maxYear && minMonth <= maxMonth)) { |
| | | const target = getMonthDateRect(new Date(minYear, minMonth, 1)); |
| | | const months = []; |
| | | for (let i = 1; i <= 31; i++) { |
| | | if (i > target.lastDate) |
| | | break; |
| | | const dateObj = { |
| | | date: new Date(minYear, minMonth, i), |
| | | day: i, |
| | | type: calcType(minYear, minMonth, i), |
| | | }; |
| | | months.push(format ? format(dateObj) : dateObj); |
| | | } |
| | | ans.push({ |
| | | year: minYear, |
| | | month: minMonth, |
| | | months, |
| | | weekdayOfFirstDay: target.weekdayOfFirstDay, |
| | | }); |
| | | const curDate = getDateRect(new Date(minYear, minMonth + 1, 1)); |
| | | minYear = curDate.year; |
| | | minMonth = curDate.month; |
| | | } |
| | | return ans; |
| | | } |
| | | select({ cellType, year, month, date }) { |
| | | const { type } = this; |
| | | const selectedDate = this.getTrimValue(); |
| | | if (cellType === 'disabled') |
| | | return; |
| | | const selected = new Date(year, month, date); |
| | | this.value = selected; |
| | | if (type === 'range' && Array.isArray(selectedDate)) { |
| | | if (selectedDate.length === 1 && selected > selectedDate[0]) { |
| | | this.value = [selectedDate[0], selected]; |
| | | } |
| | | else { |
| | | this.value = [selected]; |
| | | } |
| | | } |
| | | else if (type === 'multiple' && Array.isArray(selectedDate)) { |
| | | const newVal = [...selectedDate]; |
| | | const index = selectedDate.findIndex((item) => isSameDate(item, selected)); |
| | | if (index > -1) { |
| | | newVal.splice(index, 1); |
| | | } |
| | | else { |
| | | newVal.push(selected); |
| | | } |
| | | this.value = newVal; |
| | | } |
| | | return this.value; |
| | | } |
| | | } |
| | | import{getDateRect,isSameDate,getMonthDateRect,isValidDate,getDate}from"../date";export default class TCalendar{constructor(e={}){this.type="single",Object.assign(this,e),this.minDate||(this.minDate=getDate()),this.maxDate||(this.maxDate=getDate(6))}getTrimValue(){const{value:e,type:t}=this,a=e=>e instanceof Date?e:"number"==typeof e?new Date(e):new Date;if("single"===t&&isValidDate(e))return a(e);if("multiple"===t||"range"===t){if(Array.isArray(e)){return e.every(e=>isValidDate(e))?e.map(e=>a(e)):[]}return[]}}getDays(e){const t=[];let a=this.firstDayOfWeek%7;for(;t.length<7;)t.push(e[a]),a=(a+1)%7;return t}getMonths(){const e=[],t=this.getTrimValue(),{minDate:a,maxDate:i,type:r,allowSameDay:s,format:n}=this,m=getDateRect(a);let{year:l,month:o}=m;const{time:D}=m,{year:h,month:u,time:y}=getDateRect(i),c=(e,a,i)=>{const n=new Date(e,a,i,23,59,59);if("single"===r&&t&&isSameDate({year:e,month:a,date:i},t))return"selected";if("multiple"===r&&t){if(t.some(t=>isSameDate({year:e,month:a,date:i},t)))return"selected"}if("range"===r&&t&&Array.isArray(t)){const[r,m]=t,l=r&&isSameDate({year:e,month:a,date:i},r),o=m&&isSameDate({year:e,month:a,date:i},m);if(l&&o&&s)return"start-end";if(l)return"start";if(o)return"end";if(r&&m&&n.getTime()>r.getTime()&&n.getTime()<m.getTime())return"centre"}const m=new Date(e,a,i,0,0,0);return n.getTime()<D||m.getTime()>y?"disabled":""};for(;l<h||l===h&&o<=u;){const t=getMonthDateRect(new Date(l,o,1)),a=[];for(let e=1;e<=31&&!(e>t.lastDate);e+=1){const t={date:new Date(l,o,e),day:e,type:c(l,o,e)};a.push(n?n(t):t)}e.push({year:l,month:o,months:a,weekdayOfFirstDay:t.weekdayOfFirstDay});const i=getDateRect(new Date(l,o+1,1));l=i.year,o=i.month}return e}select({cellType:e,year:t,month:a,date:i}){const{type:r}=this,s=this.getTrimValue();if("disabled"===e)return;const n=new Date(t,a,i);if(this.value=n,"range"===r&&Array.isArray(s))1===s.length&&n>=s[0]?this.value=[s[0],n]:this.value=[n];else if("multiple"===r&&Array.isArray(s)){const e=[...s],t=s.findIndex(e=>isSameDate(e,n));t>-1?e.splice(t,1):e.push(n),this.value=e}return this.value}} |