TimeBody.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { createVNode as _createVNode } from "vue";
  3. import TimeUnitColumn from './TimeUnitColumn';
  4. import { leftPad } from '../../utils/miscUtil';
  5. import { setTime as utilSetTime } from '../../utils/timeUtil';
  6. import { cloneElement } from '../../../_util/vnode';
  7. import { onBeforeUpdate, ref, watchEffect, computed, defineComponent } from 'vue';
  8. function generateUnits(start, end, step, disabledUnits) {
  9. const units = [];
  10. for (let i = start; i <= end; i += step) {
  11. units.push({
  12. label: leftPad(i, 2),
  13. value: i,
  14. disabled: (disabledUnits || []).includes(i)
  15. });
  16. }
  17. return units;
  18. }
  19. const TimeBody = defineComponent({
  20. compatConfig: {
  21. MODE: 3
  22. },
  23. name: 'TimeBody',
  24. inheritAttrs: false,
  25. props: ['generateConfig', 'prefixCls', 'operationRef', 'activeColumnIndex', 'value', 'showHour', 'showMinute', 'showSecond', 'use12Hours', 'hourStep', 'minuteStep', 'secondStep', 'disabledHours', 'disabledMinutes', 'disabledSeconds', 'disabledTime', 'hideDisabledOptions', 'onSelect'],
  26. setup(props) {
  27. const originHour = computed(() => props.value ? props.generateConfig.getHour(props.value) : -1);
  28. const isPM = computed(() => {
  29. if (props.use12Hours) {
  30. return originHour.value >= 12; // -1 means should display AM
  31. } else {
  32. return false;
  33. }
  34. });
  35. const hour = computed(() => {
  36. // Should additional logic to handle 12 hours
  37. if (props.use12Hours) {
  38. return originHour.value % 12;
  39. } else {
  40. return originHour.value;
  41. }
  42. });
  43. const minute = computed(() => props.value ? props.generateConfig.getMinute(props.value) : -1);
  44. const second = computed(() => props.value ? props.generateConfig.getSecond(props.value) : -1);
  45. const now = ref(props.generateConfig.getNow());
  46. const mergedDisabledHours = ref();
  47. const mergedDisabledMinutes = ref();
  48. const mergedDisabledSeconds = ref();
  49. onBeforeUpdate(() => {
  50. now.value = props.generateConfig.getNow();
  51. });
  52. watchEffect(() => {
  53. if (props.disabledTime) {
  54. const disabledConfig = props.disabledTime(now);
  55. [mergedDisabledHours.value, mergedDisabledMinutes.value, mergedDisabledSeconds.value] = [disabledConfig.disabledHours, disabledConfig.disabledMinutes, disabledConfig.disabledSeconds];
  56. } else {
  57. [mergedDisabledHours.value, mergedDisabledMinutes.value, mergedDisabledSeconds.value] = [props.disabledHours, props.disabledMinutes, props.disabledSeconds];
  58. }
  59. });
  60. const setTime = (isNewPM, newHour, newMinute, newSecond) => {
  61. let newDate = props.value || props.generateConfig.getNow();
  62. const mergedHour = Math.max(0, newHour);
  63. const mergedMinute = Math.max(0, newMinute);
  64. const mergedSecond = Math.max(0, newSecond);
  65. newDate = utilSetTime(props.generateConfig, newDate, !props.use12Hours || !isNewPM ? mergedHour : mergedHour + 12, mergedMinute, mergedSecond);
  66. return newDate;
  67. };
  68. // ========================= Unit =========================
  69. const rawHours = computed(() => {
  70. var _a;
  71. return generateUnits(0, 23, (_a = props.hourStep) !== null && _a !== void 0 ? _a : 1, mergedDisabledHours.value && mergedDisabledHours.value());
  72. });
  73. // const memorizedRawHours = useMemo(() => rawHours, rawHours, shouldUnitsUpdate);
  74. const AMPMDisabled = computed(() => {
  75. if (!props.use12Hours) {
  76. return [false, false];
  77. }
  78. const AMPMDisabled = [true, true];
  79. rawHours.value.forEach(_ref => {
  80. let {
  81. disabled,
  82. value: hourValue
  83. } = _ref;
  84. if (disabled) return;
  85. if (hourValue >= 12) {
  86. AMPMDisabled[1] = false;
  87. } else {
  88. AMPMDisabled[0] = false;
  89. }
  90. });
  91. return AMPMDisabled;
  92. });
  93. const hours = computed(() => {
  94. if (!props.use12Hours) return rawHours.value;
  95. return rawHours.value.filter(isPM.value ? hourMeta => hourMeta.value >= 12 : hourMeta => hourMeta.value < 12).map(hourMeta => {
  96. const hourValue = hourMeta.value % 12;
  97. const hourLabel = hourValue === 0 ? '12' : leftPad(hourValue, 2);
  98. return _extends(_extends({}, hourMeta), {
  99. label: hourLabel,
  100. value: hourValue
  101. });
  102. });
  103. });
  104. const minutes = computed(() => {
  105. var _a;
  106. return generateUnits(0, 59, (_a = props.minuteStep) !== null && _a !== void 0 ? _a : 1, mergedDisabledMinutes.value && mergedDisabledMinutes.value(originHour.value));
  107. });
  108. const seconds = computed(() => {
  109. var _a;
  110. return generateUnits(0, 59, (_a = props.secondStep) !== null && _a !== void 0 ? _a : 1, mergedDisabledSeconds.value && mergedDisabledSeconds.value(originHour.value, minute.value));
  111. });
  112. return () => {
  113. const {
  114. prefixCls,
  115. operationRef,
  116. activeColumnIndex,
  117. showHour,
  118. showMinute,
  119. showSecond,
  120. use12Hours,
  121. hideDisabledOptions,
  122. onSelect
  123. } = props;
  124. const columns = [];
  125. const contentPrefixCls = `${prefixCls}-content`;
  126. const columnPrefixCls = `${prefixCls}-time-panel`;
  127. // ====================== Operations ======================
  128. operationRef.value = {
  129. onUpDown: diff => {
  130. const column = columns[activeColumnIndex];
  131. if (column) {
  132. const valueIndex = column.units.findIndex(unit => unit.value === column.value);
  133. const unitLen = column.units.length;
  134. for (let i = 1; i < unitLen; i += 1) {
  135. const nextUnit = column.units[(valueIndex + diff * i + unitLen) % unitLen];
  136. if (nextUnit.disabled !== true) {
  137. column.onSelect(nextUnit.value);
  138. break;
  139. }
  140. }
  141. }
  142. }
  143. };
  144. // ======================== Render ========================
  145. function addColumnNode(condition, node, columnValue, units, onColumnSelect) {
  146. if (condition !== false) {
  147. columns.push({
  148. node: cloneElement(node, {
  149. prefixCls: columnPrefixCls,
  150. value: columnValue,
  151. active: activeColumnIndex === columns.length,
  152. onSelect: onColumnSelect,
  153. units,
  154. hideDisabledOptions
  155. }),
  156. onSelect: onColumnSelect,
  157. value: columnValue,
  158. units
  159. });
  160. }
  161. }
  162. // Hour
  163. addColumnNode(showHour, _createVNode(TimeUnitColumn, {
  164. "key": "hour"
  165. }, null), hour.value, hours.value, num => {
  166. onSelect(setTime(isPM.value, num, minute.value, second.value), 'mouse');
  167. });
  168. // Minute
  169. addColumnNode(showMinute, _createVNode(TimeUnitColumn, {
  170. "key": "minute"
  171. }, null), minute.value, minutes.value, num => {
  172. onSelect(setTime(isPM.value, hour.value, num, second.value), 'mouse');
  173. });
  174. // Second
  175. addColumnNode(showSecond, _createVNode(TimeUnitColumn, {
  176. "key": "second"
  177. }, null), second.value, seconds.value, num => {
  178. onSelect(setTime(isPM.value, hour.value, minute.value, num), 'mouse');
  179. });
  180. // 12 Hours
  181. let PMIndex = -1;
  182. if (typeof isPM.value === 'boolean') {
  183. PMIndex = isPM.value ? 1 : 0;
  184. }
  185. addColumnNode(use12Hours === true, _createVNode(TimeUnitColumn, {
  186. "key": "12hours"
  187. }, null), PMIndex, [{
  188. label: 'AM',
  189. value: 0,
  190. disabled: AMPMDisabled.value[0]
  191. }, {
  192. label: 'PM',
  193. value: 1,
  194. disabled: AMPMDisabled.value[1]
  195. }], num => {
  196. onSelect(setTime(!!num, hour.value, minute.value, second.value), 'mouse');
  197. });
  198. return _createVNode("div", {
  199. "class": contentPrefixCls
  200. }, [columns.map(_ref2 => {
  201. let {
  202. node
  203. } = _ref2;
  204. return node;
  205. })]);
  206. };
  207. }
  208. });
  209. export default TimeBody;