DatePicker.mjs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
  2. import { ref, watch, computed, nextTick, onMounted, defineComponent } from "vue";
  3. import { pick, clamp, extend, isDate, padZero, makeStringProp, createNamespace } from "../utils/index.mjs";
  4. import { times, sharedProps, getTrueValue, getMonthEndDay, pickerInheritKeys, proxyPickerMethods } from "./utils.mjs";
  5. import { useExpose } from "../composables/use-expose.mjs";
  6. import { Picker } from "../picker/index.mjs";
  7. const currentYear = new Date().getFullYear();
  8. const [name] = createNamespace("date-picker");
  9. var stdin_default = defineComponent({
  10. name,
  11. props: extend({}, sharedProps, {
  12. type: makeStringProp("datetime"),
  13. modelValue: Date,
  14. minDate: {
  15. type: Date,
  16. default: () => new Date(currentYear - 10, 0, 1),
  17. validator: isDate
  18. },
  19. maxDate: {
  20. type: Date,
  21. default: () => new Date(currentYear + 10, 11, 31),
  22. validator: isDate
  23. }
  24. }),
  25. emits: ["confirm", "cancel", "change", "update:modelValue"],
  26. setup(props, {
  27. emit,
  28. slots
  29. }) {
  30. const formatValue = (value) => {
  31. if (isDate(value)) {
  32. const timestamp = clamp(value.getTime(), props.minDate.getTime(), props.maxDate.getTime());
  33. return new Date(timestamp);
  34. }
  35. return void 0;
  36. };
  37. const picker = ref();
  38. const currentDate = ref(formatValue(props.modelValue));
  39. const getBoundary = (type, value) => {
  40. const boundary = props[`${type}Date`];
  41. const year = boundary.getFullYear();
  42. let month = 1;
  43. let date = 1;
  44. let hour = 0;
  45. let minute = 0;
  46. if (type === "max") {
  47. month = 12;
  48. date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
  49. hour = 23;
  50. minute = 59;
  51. }
  52. if (value.getFullYear() === year) {
  53. month = boundary.getMonth() + 1;
  54. if (value.getMonth() + 1 === month) {
  55. date = boundary.getDate();
  56. if (value.getDate() === date) {
  57. hour = boundary.getHours();
  58. if (value.getHours() === hour) {
  59. minute = boundary.getMinutes();
  60. }
  61. }
  62. }
  63. }
  64. return {
  65. [`${type}Year`]: year,
  66. [`${type}Month`]: month,
  67. [`${type}Date`]: date,
  68. [`${type}Hour`]: hour,
  69. [`${type}Minute`]: minute
  70. };
  71. };
  72. const ranges = computed(() => {
  73. const {
  74. maxYear,
  75. maxDate,
  76. maxMonth,
  77. maxHour,
  78. maxMinute
  79. } = getBoundary("max", currentDate.value || props.minDate);
  80. const {
  81. minYear,
  82. minDate,
  83. minMonth,
  84. minHour,
  85. minMinute
  86. } = getBoundary("min", currentDate.value || props.minDate);
  87. let result = [{
  88. type: "year",
  89. range: [minYear, maxYear]
  90. }, {
  91. type: "month",
  92. range: [minMonth, maxMonth]
  93. }, {
  94. type: "day",
  95. range: [minDate, maxDate]
  96. }, {
  97. type: "hour",
  98. range: [minHour, maxHour]
  99. }, {
  100. type: "minute",
  101. range: [minMinute, maxMinute]
  102. }];
  103. switch (props.type) {
  104. case "date":
  105. result = result.slice(0, 3);
  106. break;
  107. case "year-month":
  108. result = result.slice(0, 2);
  109. break;
  110. case "month-day":
  111. result = result.slice(1, 3);
  112. break;
  113. case "datehour":
  114. result = result.slice(0, 4);
  115. break;
  116. }
  117. if (props.columnsOrder) {
  118. const columnsOrder = props.columnsOrder.concat(result.map((column) => column.type));
  119. result.sort((a, b) => columnsOrder.indexOf(a.type) - columnsOrder.indexOf(b.type));
  120. }
  121. return result;
  122. });
  123. const originColumns = computed(() => ranges.value.map(({
  124. type,
  125. range: rangeArr
  126. }) => {
  127. let values = times(rangeArr[1] - rangeArr[0] + 1, (index) => padZero(rangeArr[0] + index));
  128. if (props.filter) {
  129. values = props.filter(type, values);
  130. }
  131. return {
  132. type,
  133. values
  134. };
  135. }));
  136. const columns = computed(() => originColumns.value.map((column) => ({
  137. values: column.values.map((value) => props.formatter(column.type, value))
  138. })));
  139. const updateColumnValue = () => {
  140. const value = currentDate.value || props.minDate;
  141. const {
  142. formatter
  143. } = props;
  144. const values = originColumns.value.map((column) => {
  145. switch (column.type) {
  146. case "year":
  147. return formatter("year", `${value.getFullYear()}`);
  148. case "month":
  149. return formatter("month", padZero(value.getMonth() + 1));
  150. case "day":
  151. return formatter("day", padZero(value.getDate()));
  152. case "hour":
  153. return formatter("hour", padZero(value.getHours()));
  154. case "minute":
  155. return formatter("minute", padZero(value.getMinutes()));
  156. default:
  157. return "";
  158. }
  159. });
  160. nextTick(() => {
  161. var _a;
  162. (_a = picker.value) == null ? void 0 : _a.setValues(values);
  163. });
  164. };
  165. const updateInnerValue = () => {
  166. const {
  167. type
  168. } = props;
  169. const indexes = picker.value.getIndexes();
  170. const getValue = (type2) => {
  171. let index = 0;
  172. originColumns.value.forEach((column, columnIndex) => {
  173. if (type2 === column.type) {
  174. index = columnIndex;
  175. }
  176. });
  177. const {
  178. values
  179. } = originColumns.value[index];
  180. return getTrueValue(values[indexes[index]]);
  181. };
  182. let year;
  183. let month;
  184. let day;
  185. if (type === "month-day") {
  186. year = (currentDate.value || props.minDate).getFullYear();
  187. month = getValue("month");
  188. day = getValue("day");
  189. } else {
  190. year = getValue("year");
  191. month = getValue("month");
  192. day = type === "year-month" ? 1 : getValue("day");
  193. }
  194. const maxDay = getMonthEndDay(year, month);
  195. day = day > maxDay ? maxDay : day;
  196. let hour = 0;
  197. let minute = 0;
  198. if (type === "datehour") {
  199. hour = getValue("hour");
  200. }
  201. if (type === "datetime") {
  202. hour = getValue("hour");
  203. minute = getValue("minute");
  204. }
  205. const value = new Date(year, month - 1, day, hour, minute);
  206. currentDate.value = formatValue(value);
  207. };
  208. const onConfirm = () => {
  209. emit("update:modelValue", currentDate.value);
  210. emit("confirm", currentDate.value);
  211. };
  212. const onCancel = () => emit("cancel");
  213. const onChange = () => {
  214. updateInnerValue();
  215. nextTick(() => {
  216. updateInnerValue();
  217. nextTick(() => emit("change", currentDate.value));
  218. });
  219. };
  220. onMounted(() => {
  221. updateColumnValue();
  222. nextTick(updateInnerValue);
  223. });
  224. watch(columns, updateColumnValue);
  225. watch(currentDate, (value, oldValue) => emit("update:modelValue", oldValue ? value : null));
  226. watch(() => [props.filter, props.minDate, props.maxDate], () => {
  227. nextTick(updateInnerValue);
  228. });
  229. watch(() => props.modelValue, (value) => {
  230. var _a;
  231. value = formatValue(value);
  232. if (value && value.valueOf() !== ((_a = currentDate.value) == null ? void 0 : _a.valueOf())) {
  233. currentDate.value = value;
  234. }
  235. });
  236. useExpose({
  237. getPicker: () => picker.value && proxyPickerMethods(picker.value, updateInnerValue)
  238. });
  239. return () => _createVNode(Picker, _mergeProps({
  240. "ref": picker,
  241. "columns": columns.value,
  242. "onChange": onChange,
  243. "onCancel": onCancel,
  244. "onConfirm": onConfirm
  245. }, pick(props, pickerInheritKeys)), slots);
  246. }
  247. });
  248. export {
  249. stdin_default as default
  250. };