index.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { getDateRect, isSameDate, getMonthDateRect, isValidDate, getDate } from '../date';
  2. export default class TCalendar {
  3. constructor(options) {
  4. this.type = 'single';
  5. Object.assign(this, options);
  6. if (!this.minDate)
  7. this.minDate = getDate();
  8. if (!this.maxDate)
  9. this.maxDate = getDate(6);
  10. }
  11. getTrimValue() {
  12. const { value, type } = this;
  13. const format = (val) => {
  14. if (val instanceof Date)
  15. return val;
  16. if (typeof val === 'number')
  17. return new Date(val);
  18. return new Date();
  19. };
  20. if (type === 'single')
  21. return isValidDate(value) ? format(value) : new Date();
  22. if (type === 'multiple' || type === 'range') {
  23. if (Array.isArray(value)) {
  24. const isValid = value.every((item) => isValidDate(item));
  25. return isValid ? value.map((item) => format(item)) : [];
  26. }
  27. return [];
  28. }
  29. }
  30. getDays() {
  31. const raw = '日一二三四五六';
  32. const ans = [];
  33. let i = this.firstDayOfWeek % 7;
  34. while (ans.length < 7) {
  35. ans.push(raw[i]);
  36. i = (i + 1) % 7;
  37. }
  38. return ans;
  39. }
  40. getMonths() {
  41. const ans = [];
  42. const selectedDate = this.getTrimValue();
  43. const { minDate, maxDate, type, format } = this;
  44. let { year: minYear, month: minMonth, time: minTime } = getDateRect(minDate);
  45. const { year: maxYear, month: maxMonth, time: maxTime } = getDateRect(maxDate);
  46. const calcType = (year, month, date) => {
  47. const curDate = new Date(year, month, date, 23, 59, 59);
  48. if (type === 'single') {
  49. if (isSameDate({ year, month, date }, selectedDate))
  50. return 'selected';
  51. }
  52. if (type === 'multiple') {
  53. const hit = selectedDate.some((item) => isSameDate({ year, month, date }, item));
  54. if (hit) {
  55. return 'selected';
  56. }
  57. }
  58. if (type === 'range') {
  59. if (Array.isArray(selectedDate)) {
  60. const [startDate, endDate] = selectedDate;
  61. if (startDate && isSameDate({ year, month, date }, startDate))
  62. return 'start';
  63. if (endDate && isSameDate({ year, month, date }, endDate))
  64. return 'end';
  65. if (startDate && endDate && curDate.getTime() > startDate.getTime() && curDate.getTime() < endDate.getTime())
  66. return 'centre';
  67. }
  68. }
  69. const minCurDate = new Date(year, month, date, 0, 0, 0);
  70. if (curDate.getTime() < minTime || minCurDate.getTime() > maxTime) {
  71. return 'disabled';
  72. }
  73. return '';
  74. };
  75. while (minYear < maxYear || (minYear === maxYear && minMonth <= maxMonth)) {
  76. const target = getMonthDateRect(new Date(minYear, minMonth, 1));
  77. const months = [];
  78. for (let i = 1; i <= 31; i++) {
  79. if (i > target.lastDate)
  80. break;
  81. const dateObj = {
  82. date: new Date(minYear, minMonth, i),
  83. day: i,
  84. type: calcType(minYear, minMonth, i),
  85. };
  86. months.push(format ? format(dateObj) : dateObj);
  87. }
  88. ans.push({
  89. year: minYear,
  90. month: minMonth,
  91. months,
  92. weekdayOfFirstDay: target.weekdayOfFirstDay,
  93. });
  94. const curDate = getDateRect(new Date(minYear, minMonth + 1, 1));
  95. minYear = curDate.year;
  96. minMonth = curDate.month;
  97. }
  98. return ans;
  99. }
  100. select({ cellType, year, month, date }) {
  101. const { type } = this;
  102. const selectedDate = this.getTrimValue();
  103. if (cellType === 'disabled')
  104. return;
  105. const selected = new Date(year, month, date);
  106. if (type === 'range' && Array.isArray(selectedDate)) {
  107. if (selectedDate.length === 1) {
  108. if (selectedDate[0] > selected) {
  109. return [selected];
  110. }
  111. return [selectedDate[0], selected];
  112. }
  113. return [selected];
  114. }
  115. else if (type === 'multiple' && Array.isArray(selectedDate)) {
  116. const newVal = [...selectedDate];
  117. const index = selectedDate.findIndex((item) => isSameDate(item, selected));
  118. if (index > -1) {
  119. newVal.splice(index, 1);
  120. }
  121. else {
  122. newVal.push(selected);
  123. }
  124. return newVal;
  125. }
  126. return selected;
  127. }
  128. }