2f02c27587f87322376b93cbb39881828af48897a01c375f136655410dac97b97124f10f85944a99a1f2a739ef4fad20fac5cccdc2612c455282d24e2d198c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { ref, computed } from 'vue';
  2. import dayjs from 'dayjs';
  3. import { useLocale } from '../../../hooks/use-locale/index.mjs';
  4. import { INPUT_EVENT, UPDATE_MODEL_EVENT } from '../../../constants/event.mjs';
  5. import { isArray, isDate } from '@vue/shared';
  6. const adjacentMonth = (start, end) => {
  7. const firstMonthLastDay = start.endOf("month");
  8. const lastMonthFirstDay = end.startOf("month");
  9. const isSameWeek = firstMonthLastDay.isSame(lastMonthFirstDay, "week");
  10. const lastMonthStartDay = isSameWeek ? lastMonthFirstDay.add(1, "week") : lastMonthFirstDay;
  11. return [
  12. [start, firstMonthLastDay],
  13. [lastMonthStartDay.startOf("week"), end]
  14. ];
  15. };
  16. const threeConsecutiveMonth = (start, end) => {
  17. const firstMonthLastDay = start.endOf("month");
  18. const secondMonthFirstDay = start.add(1, "month").startOf("month");
  19. const secondMonthStartDay = firstMonthLastDay.isSame(secondMonthFirstDay, "week") ? secondMonthFirstDay.add(1, "week") : secondMonthFirstDay;
  20. const secondMonthLastDay = secondMonthStartDay.endOf("month");
  21. const lastMonthFirstDay = end.startOf("month");
  22. const lastMonthStartDay = secondMonthLastDay.isSame(lastMonthFirstDay, "week") ? lastMonthFirstDay.add(1, "week") : lastMonthFirstDay;
  23. return [
  24. [start, firstMonthLastDay],
  25. [secondMonthStartDay.startOf("week"), secondMonthLastDay],
  26. [lastMonthStartDay.startOf("week"), end]
  27. ];
  28. };
  29. const useCalendar = (props, emit, componentName) => {
  30. const { lang } = useLocale();
  31. const selectedDay = ref();
  32. const now = dayjs().locale(lang.value);
  33. const realSelectedDay = computed({
  34. get() {
  35. if (!props.modelValue)
  36. return selectedDay.value;
  37. return date.value;
  38. },
  39. set(val) {
  40. if (!val)
  41. return;
  42. selectedDay.value = val;
  43. const result = val.toDate();
  44. emit(INPUT_EVENT, result);
  45. emit(UPDATE_MODEL_EVENT, result);
  46. }
  47. });
  48. const validatedRange = computed(() => {
  49. if (!props.range || !isArray(props.range) || props.range.length !== 2 || props.range.some((item) => !isDate(item)))
  50. return [];
  51. const rangeArrDayjs = props.range.map((_) => dayjs(_).locale(lang.value));
  52. const [startDayjs, endDayjs] = rangeArrDayjs;
  53. if (startDayjs.isAfter(endDayjs)) {
  54. return [];
  55. }
  56. if (startDayjs.isSame(endDayjs, "month")) {
  57. return calculateValidatedDateRange(startDayjs, endDayjs);
  58. } else {
  59. if (startDayjs.add(1, "month").month() !== endDayjs.month()) {
  60. return [];
  61. }
  62. return calculateValidatedDateRange(startDayjs, endDayjs);
  63. }
  64. });
  65. const date = computed(() => {
  66. if (!props.modelValue) {
  67. return realSelectedDay.value || (validatedRange.value.length ? validatedRange.value[0][0] : now);
  68. } else {
  69. return dayjs(props.modelValue).locale(lang.value);
  70. }
  71. });
  72. const prevMonthDayjs = computed(() => date.value.subtract(1, "month").date(1));
  73. const nextMonthDayjs = computed(() => date.value.add(1, "month").date(1));
  74. const prevYearDayjs = computed(() => date.value.subtract(1, "year").date(1));
  75. const nextYearDayjs = computed(() => date.value.add(1, "year").date(1));
  76. const calculateValidatedDateRange = (startDayjs, endDayjs) => {
  77. const firstDay = startDayjs.startOf("week");
  78. const lastDay = endDayjs.endOf("week");
  79. const firstMonth = firstDay.get("month");
  80. const lastMonth = lastDay.get("month");
  81. if (firstMonth === lastMonth) {
  82. return [[firstDay, lastDay]];
  83. } else if ((firstMonth + 1) % 12 === lastMonth) {
  84. return adjacentMonth(firstDay, lastDay);
  85. } else if (firstMonth + 2 === lastMonth || (firstMonth + 1) % 11 === lastMonth) {
  86. return threeConsecutiveMonth(firstDay, lastDay);
  87. } else {
  88. return [];
  89. }
  90. };
  91. const pickDay = (day) => {
  92. realSelectedDay.value = day;
  93. };
  94. const selectDate = (type) => {
  95. const dateMap = {
  96. "prev-month": prevMonthDayjs.value,
  97. "next-month": nextMonthDayjs.value,
  98. "prev-year": prevYearDayjs.value,
  99. "next-year": nextYearDayjs.value,
  100. today: now
  101. };
  102. const day = dateMap[type];
  103. if (!day.isSame(date.value, "day")) {
  104. pickDay(day);
  105. }
  106. };
  107. return {
  108. calculateValidatedDateRange,
  109. date,
  110. realSelectedDay,
  111. pickDay,
  112. selectDate,
  113. validatedRange
  114. };
  115. };
  116. export { useCalendar };
  117. //# sourceMappingURL=use-calendar.mjs.map