7bfd55daaa175c4eded1816ff841d38f513c23283d6f2280bccb5b778f761a9a1e8e36f74d033caeb6d816eb2e306a900e9da5891c4657eb8e7ec15f76ceda 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vue = require('vue');
  4. var dayjs = require('dayjs');
  5. var lodashUnified = require('lodash-unified');
  6. var utils = require('../utils.js');
  7. var index = require('../../../../hooks/use-locale/index.js');
  8. var arrays = require('../../../../utils/arrays.js');
  9. var index$1 = require('../../../../hooks/use-namespace/index.js');
  10. var shared = require('@vue/shared');
  11. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  12. var dayjs__default = /*#__PURE__*/_interopDefaultLegacy(dayjs);
  13. const isNormalDay = (type = "") => {
  14. return ["normal", "today"].includes(type);
  15. };
  16. const useBasicDateTable = (props, emit) => {
  17. const { lang } = index.useLocale();
  18. const tbodyRef = vue.ref();
  19. const currentCellRef = vue.ref();
  20. const lastRow = vue.ref();
  21. const lastColumn = vue.ref();
  22. const tableRows = vue.ref([[], [], [], [], [], []]);
  23. let focusWithClick = false;
  24. const firstDayOfWeek = props.date.$locale().weekStart || 7;
  25. const WEEKS_CONSTANT = props.date.locale("en").localeData().weekdaysShort().map((_) => _.toLowerCase());
  26. const offsetDay = vue.computed(() => {
  27. return firstDayOfWeek > 3 ? 7 - firstDayOfWeek : -firstDayOfWeek;
  28. });
  29. const startDate = vue.computed(() => {
  30. const startDayOfMonth = props.date.startOf("month");
  31. return startDayOfMonth.subtract(startDayOfMonth.day() || 7, "day");
  32. });
  33. const WEEKS = vue.computed(() => {
  34. return WEEKS_CONSTANT.concat(WEEKS_CONSTANT).slice(firstDayOfWeek, firstDayOfWeek + 7);
  35. });
  36. const hasCurrent = vue.computed(() => {
  37. return lodashUnified.flatten(vue.unref(rows)).some((row) => {
  38. return row.isCurrent;
  39. });
  40. });
  41. const days = vue.computed(() => {
  42. const startOfMonth = props.date.startOf("month");
  43. const startOfMonthDay = startOfMonth.day() || 7;
  44. const dateCountOfMonth = startOfMonth.daysInMonth();
  45. const dateCountOfLastMonth = startOfMonth.subtract(1, "month").daysInMonth();
  46. return {
  47. startOfMonthDay,
  48. dateCountOfMonth,
  49. dateCountOfLastMonth
  50. };
  51. });
  52. const selectedDate = vue.computed(() => {
  53. return props.selectionMode === "dates" ? arrays.castArray(props.parsedValue) : [];
  54. });
  55. const setDateText = (cell, { count, rowIndex, columnIndex }) => {
  56. const { startOfMonthDay, dateCountOfMonth, dateCountOfLastMonth } = vue.unref(days);
  57. const offset = vue.unref(offsetDay);
  58. if (rowIndex >= 0 && rowIndex <= 1) {
  59. const numberOfDaysFromPreviousMonth = startOfMonthDay + offset < 0 ? 7 + startOfMonthDay + offset : startOfMonthDay + offset;
  60. if (columnIndex + rowIndex * 7 >= numberOfDaysFromPreviousMonth) {
  61. cell.text = count;
  62. return true;
  63. } else {
  64. cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - columnIndex % 7) + 1 + rowIndex * 7;
  65. cell.type = "prev-month";
  66. }
  67. } else {
  68. if (count <= dateCountOfMonth) {
  69. cell.text = count;
  70. } else {
  71. cell.text = count - dateCountOfMonth;
  72. cell.type = "next-month";
  73. }
  74. return true;
  75. }
  76. return false;
  77. };
  78. const setCellMetadata = (cell, { columnIndex, rowIndex }, count) => {
  79. const { disabledDate, cellClassName } = props;
  80. const _selectedDate = vue.unref(selectedDate);
  81. const shouldIncrement = setDateText(cell, { count, rowIndex, columnIndex });
  82. const cellDate = cell.dayjs.toDate();
  83. cell.selected = _selectedDate.find((d) => d.isSame(cell.dayjs, "day"));
  84. cell.isSelected = !!cell.selected;
  85. cell.isCurrent = isCurrent(cell);
  86. cell.disabled = disabledDate == null ? void 0 : disabledDate(cellDate);
  87. cell.customClass = cellClassName == null ? void 0 : cellClassName(cellDate);
  88. return shouldIncrement;
  89. };
  90. const setRowMetadata = (row) => {
  91. if (props.selectionMode === "week") {
  92. const [start, end] = props.showWeekNumber ? [1, 7] : [0, 6];
  93. const isActive = isWeekActive(row[start + 1]);
  94. row[start].inRange = isActive;
  95. row[start].start = isActive;
  96. row[end].inRange = isActive;
  97. row[end].end = isActive;
  98. }
  99. };
  100. const rows = vue.computed(() => {
  101. const { minDate, maxDate, rangeState, showWeekNumber } = props;
  102. const offset = vue.unref(offsetDay);
  103. const rows_ = vue.unref(tableRows);
  104. const dateUnit = "day";
  105. let count = 1;
  106. utils.buildPickerTable({ row: 6, column: 7 }, rows_, {
  107. startDate: minDate,
  108. columnIndexOffset: showWeekNumber ? 1 : 0,
  109. nextEndDate: rangeState.endDate || maxDate || rangeState.selecting && minDate || null,
  110. now: dayjs__default["default"]().locale(vue.unref(lang)).startOf(dateUnit),
  111. unit: dateUnit,
  112. relativeDateGetter: (idx) => vue.unref(startDate).add(idx - offset, dateUnit),
  113. setCellMetadata: (...args) => {
  114. if (setCellMetadata(...args, count)) {
  115. count += 1;
  116. }
  117. },
  118. setRowMetadata
  119. });
  120. if (showWeekNumber) {
  121. for (let rowIndex = 0; rowIndex < 6; rowIndex++) {
  122. if (rows_[rowIndex][1].dayjs) {
  123. rows_[rowIndex][0] = {
  124. type: "week",
  125. text: rows_[rowIndex][1].dayjs.week()
  126. };
  127. }
  128. }
  129. }
  130. return rows_;
  131. });
  132. vue.watch(() => props.date, async () => {
  133. var _a;
  134. if ((_a = vue.unref(tbodyRef)) == null ? void 0 : _a.contains(document.activeElement)) {
  135. await vue.nextTick();
  136. await focus();
  137. }
  138. });
  139. const focus = async () => {
  140. var _a;
  141. return (_a = vue.unref(currentCellRef)) == null ? void 0 : _a.focus();
  142. };
  143. const isCurrent = (cell) => {
  144. return props.selectionMode === "date" && isNormalDay(cell.type) && cellMatchesDate(cell, props.parsedValue);
  145. };
  146. const cellMatchesDate = (cell, date) => {
  147. if (!date)
  148. return false;
  149. return dayjs__default["default"](date).locale(vue.unref(lang)).isSame(props.date.date(Number(cell.text)), "day");
  150. };
  151. const getDateOfCell = (row, column) => {
  152. const offsetFromStart = row * 7 + (column - (props.showWeekNumber ? 1 : 0)) - vue.unref(offsetDay);
  153. return vue.unref(startDate).add(offsetFromStart, "day");
  154. };
  155. const handleMouseMove = (event) => {
  156. var _a;
  157. if (!props.rangeState.selecting)
  158. return;
  159. let target = event.target;
  160. if (target.tagName === "SPAN") {
  161. target = (_a = target.parentNode) == null ? void 0 : _a.parentNode;
  162. }
  163. if (target.tagName === "DIV") {
  164. target = target.parentNode;
  165. }
  166. if (target.tagName !== "TD")
  167. return;
  168. const row = target.parentNode.rowIndex - 1;
  169. const column = target.cellIndex;
  170. if (vue.unref(rows)[row][column].disabled)
  171. return;
  172. if (row !== vue.unref(lastRow) || column !== vue.unref(lastColumn)) {
  173. lastRow.value = row;
  174. lastColumn.value = column;
  175. emit("changerange", {
  176. selecting: true,
  177. endDate: getDateOfCell(row, column)
  178. });
  179. }
  180. };
  181. const isSelectedCell = (cell) => {
  182. return !vue.unref(hasCurrent) && (cell == null ? void 0 : cell.text) === 1 && cell.type === "normal" || cell.isCurrent;
  183. };
  184. const handleFocus = (event) => {
  185. if (focusWithClick || vue.unref(hasCurrent) || props.selectionMode !== "date")
  186. return;
  187. handlePickDate(event, true);
  188. };
  189. const handleMouseDown = (event) => {
  190. const target = event.target.closest("td");
  191. if (!target)
  192. return;
  193. focusWithClick = true;
  194. };
  195. const handleMouseUp = (event) => {
  196. const target = event.target.closest("td");
  197. if (!target)
  198. return;
  199. focusWithClick = false;
  200. };
  201. const handleRangePick = (newDate) => {
  202. if (!props.rangeState.selecting || !props.minDate) {
  203. emit("pick", { minDate: newDate, maxDate: null });
  204. emit("select", true);
  205. } else {
  206. if (newDate >= props.minDate) {
  207. emit("pick", { minDate: props.minDate, maxDate: newDate });
  208. } else {
  209. emit("pick", { minDate: newDate, maxDate: props.minDate });
  210. }
  211. emit("select", false);
  212. }
  213. };
  214. const handleWeekPick = (newDate) => {
  215. const weekNumber = newDate.week();
  216. const value = `${newDate.year()}w${weekNumber}`;
  217. emit("pick", {
  218. year: newDate.year(),
  219. week: weekNumber,
  220. value,
  221. date: newDate.startOf("week")
  222. });
  223. };
  224. const handleDatesPick = (newDate, selected) => {
  225. const newValue = selected ? arrays.castArray(props.parsedValue).filter((d) => (d == null ? void 0 : d.valueOf()) !== newDate.valueOf()) : arrays.castArray(props.parsedValue).concat([newDate]);
  226. emit("pick", newValue);
  227. };
  228. const handlePickDate = (event, isKeyboardMovement = false) => {
  229. if (props.disabled)
  230. return;
  231. const target = event.target.closest("td");
  232. if (!target)
  233. return;
  234. const row = target.parentNode.rowIndex - 1;
  235. const column = target.cellIndex;
  236. const cell = vue.unref(rows)[row][column];
  237. if (cell.disabled || cell.type === "week")
  238. return;
  239. const newDate = getDateOfCell(row, column);
  240. switch (props.selectionMode) {
  241. case "range": {
  242. handleRangePick(newDate);
  243. break;
  244. }
  245. case "date": {
  246. emit("pick", newDate, isKeyboardMovement);
  247. break;
  248. }
  249. case "week": {
  250. handleWeekPick(newDate);
  251. break;
  252. }
  253. case "dates": {
  254. handleDatesPick(newDate, !!cell.selected);
  255. break;
  256. }
  257. }
  258. };
  259. const isWeekActive = (cell) => {
  260. if (props.selectionMode !== "week")
  261. return false;
  262. let newDate = props.date.startOf("day");
  263. if (cell.type === "prev-month") {
  264. newDate = newDate.subtract(1, "month");
  265. }
  266. if (cell.type === "next-month") {
  267. newDate = newDate.add(1, "month");
  268. }
  269. newDate = newDate.date(Number.parseInt(cell.text, 10));
  270. if (props.parsedValue && !shared.isArray(props.parsedValue)) {
  271. const dayOffset = (props.parsedValue.day() - firstDayOfWeek + 7) % 7 - 1;
  272. const weekDate = props.parsedValue.subtract(dayOffset, "day");
  273. return weekDate.isSame(newDate, "day");
  274. }
  275. return false;
  276. };
  277. return {
  278. WEEKS,
  279. rows,
  280. tbodyRef,
  281. currentCellRef,
  282. focus,
  283. isCurrent,
  284. isWeekActive,
  285. isSelectedCell,
  286. handlePickDate,
  287. handleMouseUp,
  288. handleMouseDown,
  289. handleMouseMove,
  290. handleFocus
  291. };
  292. };
  293. const useBasicDateTableDOM = (props, {
  294. isCurrent,
  295. isWeekActive
  296. }) => {
  297. const ns = index$1.useNamespace("date-table");
  298. const { t } = index.useLocale();
  299. const tableKls = vue.computed(() => [
  300. ns.b(),
  301. { "is-week-mode": props.selectionMode === "week" && !props.disabled }
  302. ]);
  303. const tableLabel = vue.computed(() => t("el.datepicker.dateTablePrompt"));
  304. const getCellClasses = (cell) => {
  305. const classes = [];
  306. if (isNormalDay(cell.type) && !cell.disabled) {
  307. classes.push("available");
  308. if (cell.type === "today") {
  309. classes.push("today");
  310. }
  311. } else {
  312. classes.push(cell.type);
  313. }
  314. if (isCurrent(cell)) {
  315. classes.push("current");
  316. }
  317. if (cell.inRange && (isNormalDay(cell.type) || props.selectionMode === "week")) {
  318. classes.push("in-range");
  319. if (cell.start) {
  320. classes.push("start-date");
  321. }
  322. if (cell.end) {
  323. classes.push("end-date");
  324. }
  325. }
  326. if (cell.disabled || props.disabled) {
  327. classes.push("disabled");
  328. }
  329. if (cell.selected) {
  330. classes.push("selected");
  331. }
  332. if (cell.customClass) {
  333. classes.push(cell.customClass);
  334. }
  335. return classes.join(" ");
  336. };
  337. const getRowKls = (cell) => [
  338. ns.e("row"),
  339. { current: isWeekActive(cell) }
  340. ];
  341. return {
  342. tableKls,
  343. tableLabel,
  344. weekHeaderClass: ns.e("week-header"),
  345. getCellClasses,
  346. getRowKls,
  347. t
  348. };
  349. };
  350. exports.useBasicDateTable = useBasicDateTable;
  351. exports.useBasicDateTableDOM = useBasicDateTableDOM;
  352. //# sourceMappingURL=use-basic-date-table.js.map