371a6dcd53b68ec041bebee54227d9d313f5360c0f26281ba099f49fd704b2b62d6df8c8e3f3deb411f6c3ee555996c44379b22d788e06e293e19aea7c990f 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import { defineComponent, ref, computed, watch, nextTick, openBlock, createElementBlock, unref, normalizeClass, createElementVNode, Fragment, renderList, withKeys, withModifiers, createVNode } from 'vue';
  2. import dayjs from 'dayjs';
  3. import { basicMonthTableProps } from '../props/basic-month-table.mjs';
  4. import { datesInMonth, getValidDateOfMonth } from '../utils.mjs';
  5. import ElDatePickerCell from './basic-cell-render.mjs';
  6. import _export_sfc from '../../../../_virtual/plugin-vue_export-helper.mjs';
  7. import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
  8. import { useLocale } from '../../../../hooks/use-locale/index.mjs';
  9. import { castArray } from '../../../../utils/arrays.mjs';
  10. import { hasClass } from '../../../../utils/dom/style.mjs';
  11. const _sfc_main = /* @__PURE__ */ defineComponent({
  12. __name: "basic-month-table",
  13. props: basicMonthTableProps,
  14. emits: ["changerange", "pick", "select"],
  15. setup(__props, { expose, emit }) {
  16. const props = __props;
  17. const ns = useNamespace("month-table");
  18. const { t, lang } = useLocale();
  19. const tbodyRef = ref();
  20. const currentCellRef = ref();
  21. const months = ref(props.date.locale("en").localeData().monthsShort().map((_) => _.toLowerCase()));
  22. const tableRows = ref([[], [], []]);
  23. const lastRow = ref();
  24. const lastColumn = ref();
  25. const rows = computed(() => {
  26. var _a, _b, _c;
  27. const rows2 = tableRows.value;
  28. const now = dayjs().locale(lang.value).startOf("month");
  29. for (let i = 0; i < 3; i++) {
  30. const row = rows2[i];
  31. for (let j = 0; j < 4; j++) {
  32. const cell = row[j] || (row[j] = {
  33. row: i,
  34. column: j,
  35. type: "normal",
  36. inRange: false,
  37. start: false,
  38. end: false,
  39. text: -1,
  40. disabled: false,
  41. isSelected: false,
  42. customClass: void 0,
  43. date: void 0,
  44. dayjs: void 0,
  45. isCurrent: void 0,
  46. selected: void 0,
  47. renderText: void 0,
  48. timestamp: void 0
  49. });
  50. cell.type = "normal";
  51. const index = i * 4 + j;
  52. const calTime = props.date.startOf("year").month(index);
  53. const calEndDate = props.rangeState.endDate || props.maxDate || props.rangeState.selecting && props.minDate || null;
  54. cell.inRange = !!(props.minDate && calTime.isSameOrAfter(props.minDate, "month") && calEndDate && calTime.isSameOrBefore(calEndDate, "month")) || !!(props.minDate && calTime.isSameOrBefore(props.minDate, "month") && calEndDate && calTime.isSameOrAfter(calEndDate, "month"));
  55. if ((_a = props.minDate) == null ? void 0 : _a.isSameOrAfter(calEndDate)) {
  56. cell.start = !!(calEndDate && calTime.isSame(calEndDate, "month"));
  57. cell.end = props.minDate && calTime.isSame(props.minDate, "month");
  58. } else {
  59. cell.start = !!(props.minDate && calTime.isSame(props.minDate, "month"));
  60. cell.end = !!(calEndDate && calTime.isSame(calEndDate, "month"));
  61. }
  62. const isToday = now.isSame(calTime);
  63. if (isToday) {
  64. cell.type = "today";
  65. }
  66. const cellDate = calTime.toDate();
  67. cell.text = index;
  68. cell.disabled = ((_b = props.disabledDate) == null ? void 0 : _b.call(props, cellDate)) || false;
  69. cell.date = cellDate;
  70. cell.customClass = (_c = props.cellClassName) == null ? void 0 : _c.call(props, cellDate);
  71. cell.dayjs = calTime;
  72. cell.timestamp = calTime.valueOf();
  73. cell.isSelected = isSelectedCell(cell);
  74. }
  75. }
  76. return rows2;
  77. });
  78. const focus = () => {
  79. var _a;
  80. (_a = currentCellRef.value) == null ? void 0 : _a.focus();
  81. };
  82. const getCellStyle = (cell) => {
  83. const style = {};
  84. const year = props.date.year();
  85. const today = /* @__PURE__ */ new Date();
  86. const month = cell.text;
  87. style.disabled = props.disabled || (props.disabledDate ? datesInMonth(props.date, year, month, lang.value).every(props.disabledDate) : false);
  88. style.current = castArray(props.parsedValue).findIndex((date) => dayjs.isDayjs(date) && date.year() === year && date.month() === month) >= 0;
  89. style.today = today.getFullYear() === year && today.getMonth() === month;
  90. if (cell.customClass) {
  91. style[cell.customClass] = true;
  92. }
  93. if (cell.inRange) {
  94. style["in-range"] = true;
  95. if (cell.start) {
  96. style["start-date"] = true;
  97. }
  98. if (cell.end) {
  99. style["end-date"] = true;
  100. }
  101. }
  102. return style;
  103. };
  104. const isSelectedCell = (cell) => {
  105. const year = props.date.year();
  106. const month = cell.text;
  107. return castArray(props.date).findIndex((date) => date.year() === year && date.month() === month) >= 0;
  108. };
  109. const handleMouseMove = (event) => {
  110. var _a;
  111. if (!props.rangeState.selecting)
  112. return;
  113. let target = event.target;
  114. if (target.tagName === "SPAN") {
  115. target = (_a = target.parentNode) == null ? void 0 : _a.parentNode;
  116. }
  117. if (target.tagName === "DIV") {
  118. target = target.parentNode;
  119. }
  120. if (target.tagName !== "TD")
  121. return;
  122. const row = target.parentNode.rowIndex;
  123. const column = target.cellIndex;
  124. if (rows.value[row][column].disabled)
  125. return;
  126. if (row !== lastRow.value || column !== lastColumn.value) {
  127. lastRow.value = row;
  128. lastColumn.value = column;
  129. emit("changerange", {
  130. selecting: true,
  131. endDate: props.date.startOf("year").month(row * 4 + column)
  132. });
  133. }
  134. };
  135. const handleMonthTableClick = (event) => {
  136. var _a;
  137. if (props.disabled)
  138. return;
  139. const target = (_a = event.target) == null ? void 0 : _a.closest("td");
  140. if ((target == null ? void 0 : target.tagName) !== "TD")
  141. return;
  142. if (hasClass(target, "disabled"))
  143. return;
  144. const column = target.cellIndex;
  145. const row = target.parentNode.rowIndex;
  146. const month = row * 4 + column;
  147. const newDate = props.date.startOf("year").month(month);
  148. if (props.selectionMode === "months") {
  149. if (event.type === "keydown") {
  150. emit("pick", castArray(props.parsedValue), false);
  151. return;
  152. }
  153. const newMonth = getValidDateOfMonth(props.date, props.date.year(), month, lang.value, props.disabledDate);
  154. const newValue = hasClass(target, "current") ? castArray(props.parsedValue).filter((d) => (d == null ? void 0 : d.year()) !== newMonth.year() || (d == null ? void 0 : d.month()) !== newMonth.month()) : castArray(props.parsedValue).concat([dayjs(newMonth)]);
  155. emit("pick", newValue);
  156. } else if (props.selectionMode === "range") {
  157. if (!props.rangeState.selecting) {
  158. emit("pick", { minDate: newDate, maxDate: null });
  159. emit("select", true);
  160. } else {
  161. if (props.minDate && newDate >= props.minDate) {
  162. emit("pick", { minDate: props.minDate, maxDate: newDate });
  163. } else {
  164. emit("pick", { minDate: newDate, maxDate: props.minDate });
  165. }
  166. emit("select", false);
  167. }
  168. } else {
  169. emit("pick", month);
  170. }
  171. };
  172. watch(() => props.date, async () => {
  173. var _a, _b;
  174. if ((_a = tbodyRef.value) == null ? void 0 : _a.contains(document.activeElement)) {
  175. await nextTick();
  176. (_b = currentCellRef.value) == null ? void 0 : _b.focus();
  177. }
  178. });
  179. expose({
  180. focus
  181. });
  182. return (_ctx, _cache) => {
  183. return openBlock(), createElementBlock("table", {
  184. role: "grid",
  185. "aria-label": unref(t)("el.datepicker.monthTablePrompt"),
  186. class: normalizeClass(unref(ns).b()),
  187. onClick: handleMonthTableClick,
  188. onMousemove: handleMouseMove
  189. }, [
  190. createElementVNode("tbody", {
  191. ref_key: "tbodyRef",
  192. ref: tbodyRef
  193. }, [
  194. (openBlock(true), createElementBlock(Fragment, null, renderList(unref(rows), (row, key) => {
  195. return openBlock(), createElementBlock("tr", { key }, [
  196. (openBlock(true), createElementBlock(Fragment, null, renderList(row, (cell, key_) => {
  197. return openBlock(), createElementBlock("td", {
  198. key: key_,
  199. ref_for: true,
  200. ref: (el) => cell.isSelected && (currentCellRef.value = el),
  201. class: normalizeClass(getCellStyle(cell)),
  202. "aria-selected": !!cell.isSelected,
  203. "aria-label": unref(t)(`el.datepicker.month${+cell.text + 1}`),
  204. tabindex: cell.isSelected ? 0 : -1,
  205. onKeydown: [
  206. withKeys(withModifiers(handleMonthTableClick, ["prevent", "stop"]), ["space"]),
  207. withKeys(withModifiers(handleMonthTableClick, ["prevent", "stop"]), ["enter"])
  208. ]
  209. }, [
  210. createVNode(unref(ElDatePickerCell), {
  211. cell: {
  212. ...cell,
  213. renderText: unref(t)("el.datepicker.months." + months.value[cell.text])
  214. }
  215. }, null, 8, ["cell"])
  216. ], 42, ["aria-selected", "aria-label", "tabindex", "onKeydown"]);
  217. }), 128))
  218. ]);
  219. }), 128))
  220. ], 512)
  221. ], 42, ["aria-label"]);
  222. };
  223. }
  224. });
  225. var MonthTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "basic-month-table.vue"]]);
  226. export { MonthTable as default };
  227. //# sourceMappingURL=basic-month-table.mjs.map