CalendarMonth.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. var __create = Object.create;
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __getProtoOf = Object.getPrototypeOf;
  6. var __hasOwnProp = Object.prototype.hasOwnProperty;
  7. var __export = (target, all) => {
  8. for (var name2 in all)
  9. __defProp(target, name2, { get: all[name2], enumerable: true });
  10. };
  11. var __copyProps = (to, from, except, desc) => {
  12. if (from && typeof from === "object" || typeof from === "function") {
  13. for (let key of __getOwnPropNames(from))
  14. if (!__hasOwnProp.call(to, key) && key !== except)
  15. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  16. }
  17. return to;
  18. };
  19. var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  20. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  21. mod
  22. ));
  23. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  24. var stdin_exports = {};
  25. __export(stdin_exports, {
  26. default: () => stdin_default
  27. });
  28. module.exports = __toCommonJS(stdin_exports);
  29. var import_vue = require("vue");
  30. var import_vue2 = require("vue");
  31. var import_utils = require("../utils");
  32. var import_utils2 = require("../datetime-picker/utils");
  33. var import_utils3 = require("./utils");
  34. var import_use = require("@vant/use");
  35. var import_use_expose = require("../composables/use-expose");
  36. var import_use_height = require("../composables/use-height");
  37. var import_CalendarDay = __toESM(require("./CalendarDay"));
  38. const [name] = (0, import_utils.createNamespace)("calendar-month");
  39. const calendarMonthProps = {
  40. date: (0, import_utils.makeRequiredProp)(Date),
  41. type: String,
  42. color: String,
  43. minDate: (0, import_utils.makeRequiredProp)(Date),
  44. maxDate: (0, import_utils.makeRequiredProp)(Date),
  45. showMark: Boolean,
  46. rowHeight: import_utils.numericProp,
  47. formatter: Function,
  48. lazyRender: Boolean,
  49. currentDate: [Date, Array],
  50. allowSameDay: Boolean,
  51. showSubtitle: Boolean,
  52. showMonthTitle: Boolean,
  53. firstDayOfWeek: Number
  54. };
  55. var stdin_default = (0, import_vue2.defineComponent)({
  56. name,
  57. props: calendarMonthProps,
  58. emits: ["click", "update-height"],
  59. setup(props, {
  60. emit,
  61. slots
  62. }) {
  63. const [visible, setVisible] = (0, import_use.useToggle)();
  64. const daysRef = (0, import_vue2.ref)();
  65. const monthRef = (0, import_vue2.ref)();
  66. const height = (0, import_use_height.useHeight)(monthRef);
  67. const title = (0, import_vue2.computed)(() => (0, import_utils3.formatMonthTitle)(props.date));
  68. const rowHeight = (0, import_vue2.computed)(() => (0, import_utils.addUnit)(props.rowHeight));
  69. const offset = (0, import_vue2.computed)(() => {
  70. const realDay = props.date.getDay();
  71. if (props.firstDayOfWeek) {
  72. return (realDay + 7 - props.firstDayOfWeek) % 7;
  73. }
  74. return realDay;
  75. });
  76. const totalDay = (0, import_vue2.computed)(() => (0, import_utils2.getMonthEndDay)(props.date.getFullYear(), props.date.getMonth() + 1));
  77. const shouldRender = (0, import_vue2.computed)(() => visible.value || !props.lazyRender);
  78. const getTitle = () => title.value;
  79. const getMultipleDayType = (day) => {
  80. const isSelected = (date) => props.currentDate.some((item) => (0, import_utils3.compareDay)(item, date) === 0);
  81. if (isSelected(day)) {
  82. const prevDay = (0, import_utils3.getPrevDay)(day);
  83. const nextDay = (0, import_utils3.getNextDay)(day);
  84. const prevSelected = isSelected(prevDay);
  85. const nextSelected = isSelected(nextDay);
  86. if (prevSelected && nextSelected) {
  87. return "multiple-middle";
  88. }
  89. if (prevSelected) {
  90. return "end";
  91. }
  92. if (nextSelected) {
  93. return "start";
  94. }
  95. return "multiple-selected";
  96. }
  97. return "";
  98. };
  99. const getRangeDayType = (day) => {
  100. const [startDay, endDay] = props.currentDate;
  101. if (!startDay) {
  102. return "";
  103. }
  104. const compareToStart = (0, import_utils3.compareDay)(day, startDay);
  105. if (!endDay) {
  106. return compareToStart === 0 ? "start" : "";
  107. }
  108. const compareToEnd = (0, import_utils3.compareDay)(day, endDay);
  109. if (props.allowSameDay && compareToStart === 0 && compareToEnd === 0) {
  110. return "start-end";
  111. }
  112. if (compareToStart === 0) {
  113. return "start";
  114. }
  115. if (compareToEnd === 0) {
  116. return "end";
  117. }
  118. if (compareToStart > 0 && compareToEnd < 0) {
  119. return "middle";
  120. }
  121. return "";
  122. };
  123. const getDayType = (day) => {
  124. const {
  125. type,
  126. minDate,
  127. maxDate,
  128. currentDate
  129. } = props;
  130. if ((0, import_utils3.compareDay)(day, minDate) < 0 || (0, import_utils3.compareDay)(day, maxDate) > 0) {
  131. return "disabled";
  132. }
  133. if (currentDate === null) {
  134. return "";
  135. }
  136. if (Array.isArray(currentDate)) {
  137. if (type === "multiple") {
  138. return getMultipleDayType(day);
  139. }
  140. if (type === "range") {
  141. return getRangeDayType(day);
  142. }
  143. } else if (type === "single") {
  144. return (0, import_utils3.compareDay)(day, currentDate) === 0 ? "selected" : "";
  145. }
  146. return "";
  147. };
  148. const getBottomInfo = (dayType) => {
  149. if (props.type === "range") {
  150. if (dayType === "start" || dayType === "end") {
  151. return (0, import_utils3.t)(dayType);
  152. }
  153. if (dayType === "start-end") {
  154. return `${(0, import_utils3.t)("start")}/${(0, import_utils3.t)("end")}`;
  155. }
  156. }
  157. };
  158. const renderTitle = () => {
  159. if (props.showMonthTitle) {
  160. return (0, import_vue.createVNode)("div", {
  161. "class": (0, import_utils3.bem)("month-title")
  162. }, [title.value]);
  163. }
  164. };
  165. const renderMark = () => {
  166. if (props.showMark && shouldRender.value) {
  167. return (0, import_vue.createVNode)("div", {
  168. "class": (0, import_utils3.bem)("month-mark")
  169. }, [props.date.getMonth() + 1]);
  170. }
  171. };
  172. const placeholders = (0, import_vue2.computed)(() => {
  173. const count = Math.ceil((totalDay.value + offset.value) / 7);
  174. return Array(count).fill({
  175. type: "placeholder"
  176. });
  177. });
  178. const days = (0, import_vue2.computed)(() => {
  179. const days2 = [];
  180. const year = props.date.getFullYear();
  181. const month = props.date.getMonth();
  182. for (let day = 1; day <= totalDay.value; day++) {
  183. const date = new Date(year, month, day);
  184. const type = getDayType(date);
  185. let config = {
  186. date,
  187. type,
  188. text: day,
  189. bottomInfo: getBottomInfo(type)
  190. };
  191. if (props.formatter) {
  192. config = props.formatter(config);
  193. }
  194. days2.push(config);
  195. }
  196. return days2;
  197. });
  198. const disabledDays = (0, import_vue2.computed)(() => days.value.filter((day) => day.type === "disabled"));
  199. const scrollToDate = (body, targetDate) => {
  200. if (daysRef.value) {
  201. const daysRect = (0, import_use.useRect)(daysRef.value);
  202. const totalRows = placeholders.value.length;
  203. const currentRow = Math.ceil((targetDate.getDate() + offset.value) / 7);
  204. const rowOffset = (currentRow - 1) * daysRect.height / totalRows;
  205. (0, import_utils.setScrollTop)(body, daysRect.top + rowOffset + body.scrollTop - (0, import_use.useRect)(body).top);
  206. }
  207. };
  208. const renderDay = (item, index) => (0, import_vue.createVNode)(import_CalendarDay.default, {
  209. "item": item,
  210. "index": index,
  211. "color": props.color,
  212. "offset": offset.value,
  213. "rowHeight": rowHeight.value,
  214. "onClick": (item2) => emit("click", item2)
  215. }, (0, import_utils.pick)(slots, ["top-info", "bottom-info"]));
  216. const renderDays = () => (0, import_vue.createVNode)("div", {
  217. "ref": daysRef,
  218. "role": "grid",
  219. "class": (0, import_utils3.bem)("days")
  220. }, [renderMark(), (shouldRender.value ? days : placeholders).value.map(renderDay)]);
  221. (0, import_use_expose.useExpose)({
  222. getTitle,
  223. getHeight: () => height.value,
  224. setVisible,
  225. scrollToDate,
  226. disabledDays
  227. });
  228. return () => (0, import_vue.createVNode)("div", {
  229. "class": (0, import_utils3.bem)("month"),
  230. "ref": monthRef
  231. }, [renderTitle(), renderDays()]);
  232. }
  233. });