VDatePickerMonth.mjs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { createVNode as _createVNode, createTextVNode as _createTextVNode } from "vue";
  2. // Styles
  3. import "./VDatePickerMonth.css";
  4. // Components
  5. import { VBtn } from "../VBtn/index.mjs";
  6. import { VDefaultsProvider } from "../VDefaultsProvider/index.mjs"; // Composables
  7. import { makeCalendarProps, useCalendar } from "../../composables/calendar.mjs";
  8. import { useDate } from "../../composables/date/date.mjs";
  9. import { MaybeTransition } from "../../composables/transition.mjs"; // Utilities
  10. import { computed, ref, shallowRef, watch } from 'vue';
  11. import { genericComponent, propsFactory } from "../../util/index.mjs"; // Types
  12. export const makeVDatePickerMonthProps = propsFactory({
  13. color: String,
  14. hideWeekdays: Boolean,
  15. multiple: [Boolean, Number, String],
  16. showWeek: Boolean,
  17. transition: {
  18. type: String,
  19. default: 'picker-transition'
  20. },
  21. reverseTransition: {
  22. type: String,
  23. default: 'picker-reverse-transition'
  24. },
  25. ...makeCalendarProps()
  26. }, 'VDatePickerMonth');
  27. export const VDatePickerMonth = genericComponent()({
  28. name: 'VDatePickerMonth',
  29. props: makeVDatePickerMonthProps(),
  30. emits: {
  31. 'update:modelValue': date => true,
  32. 'update:month': date => true,
  33. 'update:year': date => true
  34. },
  35. setup(props, _ref) {
  36. let {
  37. emit,
  38. slots
  39. } = _ref;
  40. const daysRef = ref();
  41. const {
  42. daysInMonth,
  43. model,
  44. weekNumbers
  45. } = useCalendar(props);
  46. const adapter = useDate();
  47. const rangeStart = shallowRef();
  48. const rangeStop = shallowRef();
  49. const isReverse = shallowRef(false);
  50. const transition = computed(() => {
  51. return !isReverse.value ? props.transition : props.reverseTransition;
  52. });
  53. if (props.multiple === 'range' && model.value.length > 0) {
  54. rangeStart.value = model.value[0];
  55. if (model.value.length > 1) {
  56. rangeStop.value = model.value[model.value.length - 1];
  57. }
  58. }
  59. const atMax = computed(() => {
  60. const max = ['number', 'string'].includes(typeof props.multiple) ? Number(props.multiple) : Infinity;
  61. return model.value.length >= max;
  62. });
  63. watch(daysInMonth, (val, oldVal) => {
  64. if (!oldVal) return;
  65. isReverse.value = adapter.isBefore(val[0].date, oldVal[0].date);
  66. });
  67. function onRangeClick(value) {
  68. const _value = adapter.startOfDay(value);
  69. if (model.value.length === 0) {
  70. rangeStart.value = undefined;
  71. } else if (model.value.length === 1) {
  72. rangeStart.value = model.value[0];
  73. rangeStop.value = undefined;
  74. }
  75. if (!rangeStart.value) {
  76. rangeStart.value = _value;
  77. model.value = [rangeStart.value];
  78. } else if (!rangeStop.value) {
  79. if (adapter.isSameDay(_value, rangeStart.value)) {
  80. rangeStart.value = undefined;
  81. model.value = [];
  82. return;
  83. } else if (adapter.isBefore(_value, rangeStart.value)) {
  84. rangeStop.value = adapter.endOfDay(rangeStart.value);
  85. rangeStart.value = _value;
  86. } else {
  87. rangeStop.value = adapter.endOfDay(_value);
  88. }
  89. const diff = adapter.getDiff(rangeStop.value, rangeStart.value, 'days');
  90. const datesInRange = [rangeStart.value];
  91. for (let i = 1; i < diff; i++) {
  92. const nextDate = adapter.addDays(rangeStart.value, i);
  93. datesInRange.push(nextDate);
  94. }
  95. datesInRange.push(rangeStop.value);
  96. model.value = datesInRange;
  97. } else {
  98. rangeStart.value = value;
  99. rangeStop.value = undefined;
  100. model.value = [rangeStart.value];
  101. }
  102. }
  103. function onMultipleClick(value) {
  104. const index = model.value.findIndex(selection => adapter.isSameDay(selection, value));
  105. if (index === -1) {
  106. model.value = [...model.value, value];
  107. } else {
  108. const value = [...model.value];
  109. value.splice(index, 1);
  110. model.value = value;
  111. }
  112. }
  113. function onClick(value) {
  114. if (props.multiple === 'range') {
  115. onRangeClick(value);
  116. } else if (props.multiple) {
  117. onMultipleClick(value);
  118. } else {
  119. model.value = [value];
  120. }
  121. }
  122. return () => _createVNode("div", {
  123. "class": "v-date-picker-month"
  124. }, [props.showWeek && _createVNode("div", {
  125. "key": "weeks",
  126. "class": "v-date-picker-month__weeks"
  127. }, [!props.hideWeekdays && _createVNode("div", {
  128. "key": "hide-week-days",
  129. "class": "v-date-picker-month__day"
  130. }, [_createTextVNode("\xA0")]), weekNumbers.value.map(week => _createVNode("div", {
  131. "class": ['v-date-picker-month__day', 'v-date-picker-month__day--adjacent']
  132. }, [week]))]), _createVNode(MaybeTransition, {
  133. "name": transition.value
  134. }, {
  135. default: () => [_createVNode("div", {
  136. "ref": daysRef,
  137. "key": daysInMonth.value[0].date?.toString(),
  138. "class": "v-date-picker-month__days"
  139. }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => _createVNode("div", {
  140. "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
  141. }, [weekDay])), daysInMonth.value.map((item, i) => {
  142. const slotProps = {
  143. props: {
  144. onClick: () => onClick(item.date)
  145. },
  146. item,
  147. i
  148. };
  149. if (atMax.value && !item.isSelected) {
  150. item.isDisabled = true;
  151. }
  152. return _createVNode("div", {
  153. "class": ['v-date-picker-month__day', {
  154. 'v-date-picker-month__day--adjacent': item.isAdjacent,
  155. 'v-date-picker-month__day--hide-adjacent': item.isHidden,
  156. 'v-date-picker-month__day--selected': item.isSelected,
  157. 'v-date-picker-month__day--week-end': item.isWeekEnd,
  158. 'v-date-picker-month__day--week-start': item.isWeekStart
  159. }],
  160. "data-v-date": !item.isDisabled ? item.isoDate : undefined
  161. }, [(props.showAdjacentMonths || !item.isAdjacent) && _createVNode(VDefaultsProvider, {
  162. "defaults": {
  163. VBtn: {
  164. class: 'v-date-picker-month__day-btn',
  165. color: (item.isSelected || item.isToday) && !item.isDisabled ? props.color : undefined,
  166. disabled: item.isDisabled,
  167. icon: true,
  168. ripple: false,
  169. text: item.localized,
  170. variant: item.isDisabled ? item.isToday ? 'outlined' : 'text' : item.isToday && !item.isSelected ? 'outlined' : 'flat',
  171. onClick: () => onClick(item.date)
  172. }
  173. }
  174. }, {
  175. default: () => [slots.day?.(slotProps) ?? _createVNode(VBtn, slotProps.props, null)]
  176. })]);
  177. })])]
  178. })]);
  179. }
  180. });
  181. //# sourceMappingURL=VDatePickerMonth.mjs.map