RangePicker.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. import _typeof from "@babel/runtime/helpers/esm/typeof";
  2. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  3. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  4. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  5. import { resolveDirective as _resolveDirective, Fragment as _Fragment, createVNode as _createVNode } from "vue";
  6. import PickerTrigger from './PickerTrigger';
  7. import PickerPanel from './PickerPanel';
  8. import usePickerInput from './hooks/usePickerInput';
  9. import getDataOrAriaProps, { toArray, getValue, updateValues } from './utils/miscUtil';
  10. import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil';
  11. import { useProvidePanel } from './PanelContext';
  12. import { isEqual, getClosingViewDate, isSameDate, isSameWeek, isSameQuarter, formatValue, parseValue } from './utils/dateUtil';
  13. import useValueTexts from './hooks/useValueTexts';
  14. import useTextValueMapping from './hooks/useTextValueMapping';
  15. import { RangeContextProvider } from './RangeContext';
  16. import useRangeDisabled from './hooks/useRangeDisabled';
  17. import getExtraFooter from './utils/getExtraFooter';
  18. import getRanges from './utils/getRanges';
  19. import useRangeViewDates from './hooks/useRangeViewDates';
  20. import useHoverValue from './hooks/useHoverValue';
  21. import { computed, defineComponent, ref, toRef, watch, watchEffect } from 'vue';
  22. import useMergedState from '../_util/hooks/useMergedState';
  23. import { warning } from '../vc-util/warning';
  24. import useState from '../_util/hooks/useState';
  25. import classNames from '../_util/classNames';
  26. import { useProviderTrigger } from '../vc-trigger/context';
  27. import { legacyPropsWarning } from './utils/warnUtil';
  28. import { useElementSize } from '../_util/hooks/_vueuse/useElementSize';
  29. function reorderValues(values, generateConfig) {
  30. if (values && values[0] && values[1] && generateConfig.isAfter(values[0], values[1])) {
  31. return [values[1], values[0]];
  32. }
  33. return values;
  34. }
  35. function canValueTrigger(value, index, disabled, allowEmpty) {
  36. if (value) {
  37. return true;
  38. }
  39. if (allowEmpty && allowEmpty[index]) {
  40. return true;
  41. }
  42. if (disabled[(index + 1) % 2]) {
  43. return true;
  44. }
  45. return false;
  46. }
  47. function RangerPicker() {
  48. return defineComponent({
  49. name: 'RangerPicker',
  50. inheritAttrs: false,
  51. props: ['prefixCls', 'id', 'popupStyle', 'dropdownClassName', 'transitionName', 'dropdownAlign', 'getPopupContainer', 'generateConfig', 'locale', 'placeholder', 'autofocus', 'disabled', 'format', 'picker', 'showTime', 'showNow', 'showHour', 'showMinute', 'showSecond', 'use12Hours', 'separator', 'value', 'defaultValue', 'defaultPickerValue', 'open', 'defaultOpen', 'disabledDate', 'disabledTime', 'dateRender', 'panelRender', 'ranges', 'allowEmpty', 'allowClear', 'suffixIcon', 'clearIcon', 'pickerRef', 'inputReadOnly', 'mode', 'renderExtraFooter', 'onChange', 'onOpenChange', 'onPanelChange', 'onCalendarChange', 'onFocus', 'onBlur', 'onMousedown', 'onMouseup', 'onMouseenter', 'onMouseleave', 'onClick', 'onOk', 'onKeydown', 'components', 'order', 'direction', 'activePickerIndex', 'autocomplete', 'minuteStep', 'hourStep', 'secondStep', 'hideDisabledOptions', 'disabledMinutes'],
  52. setup: function setup(props, _ref) {
  53. var attrs = _ref.attrs,
  54. expose = _ref.expose;
  55. var needConfirmButton = computed(function () {
  56. return props.picker === 'date' && !!props.showTime || props.picker === 'time';
  57. });
  58. var getPortal = useProviderTrigger();
  59. // We record opened status here in case repeat open with picker
  60. var openRecordsRef = ref({});
  61. var containerRef = ref(null);
  62. var panelDivRef = ref(null);
  63. var startInputDivRef = ref(null);
  64. var endInputDivRef = ref(null);
  65. var separatorRef = ref(null);
  66. var startInputRef = ref(null);
  67. var endInputRef = ref(null);
  68. var arrowRef = ref(null);
  69. // ============================ Warning ============================
  70. if (process.env.NODE_ENV !== 'production') {
  71. legacyPropsWarning(props);
  72. }
  73. // ============================= Misc ==============================
  74. var formatList = computed(function () {
  75. return toArray(getDefaultFormat(props.format, props.picker, props.showTime, props.use12Hours));
  76. });
  77. // Active picker
  78. var _useMergedState = useMergedState(0, {
  79. value: toRef(props, 'activePickerIndex')
  80. }),
  81. _useMergedState2 = _slicedToArray(_useMergedState, 2),
  82. mergedActivePickerIndex = _useMergedState2[0],
  83. setMergedActivePickerIndex = _useMergedState2[1];
  84. // Operation ref
  85. var operationRef = ref(null);
  86. var mergedDisabled = computed(function () {
  87. var disabled = props.disabled;
  88. if (Array.isArray(disabled)) {
  89. return disabled;
  90. }
  91. return [disabled || false, disabled || false];
  92. });
  93. // ============================= Value =============================
  94. var _useMergedState3 = useMergedState(null, {
  95. value: toRef(props, 'value'),
  96. defaultValue: props.defaultValue,
  97. postState: function postState(values) {
  98. return props.picker === 'time' && !props.order ? values : reorderValues(values, props.generateConfig);
  99. }
  100. }),
  101. _useMergedState4 = _slicedToArray(_useMergedState3, 2),
  102. mergedValue = _useMergedState4[0],
  103. setInnerValue = _useMergedState4[1];
  104. // =========================== View Date ===========================
  105. // Config view panel
  106. var _useRangeViewDates = useRangeViewDates({
  107. values: mergedValue,
  108. picker: toRef(props, 'picker'),
  109. defaultDates: props.defaultPickerValue,
  110. generateConfig: toRef(props, 'generateConfig')
  111. }),
  112. _useRangeViewDates2 = _slicedToArray(_useRangeViewDates, 3),
  113. startViewDate = _useRangeViewDates2[0],
  114. endViewDate = _useRangeViewDates2[1],
  115. setViewDate = _useRangeViewDates2[2];
  116. // ========================= Select Values =========================
  117. var _useMergedState5 = useMergedState(mergedValue.value, {
  118. postState: function postState(values) {
  119. var postValues = values;
  120. if (mergedDisabled.value[0] && mergedDisabled.value[1]) {
  121. return postValues;
  122. }
  123. // Fill disabled unit
  124. for (var i = 0; i < 2; i += 1) {
  125. if (mergedDisabled[i] && !getValue(postValues, i) && !getValue(props.allowEmpty, i)) {
  126. postValues = updateValues(postValues, props.generateConfig.getNow(), i);
  127. }
  128. }
  129. return postValues;
  130. }
  131. }),
  132. _useMergedState6 = _slicedToArray(_useMergedState5, 2),
  133. selectedValue = _useMergedState6[0],
  134. setSelectedValue = _useMergedState6[1];
  135. // ============================= Modes =============================
  136. var _useMergedState7 = useMergedState([props.picker, props.picker], {
  137. value: toRef(props, 'mode')
  138. }),
  139. _useMergedState8 = _slicedToArray(_useMergedState7, 2),
  140. mergedModes = _useMergedState8[0],
  141. setInnerModes = _useMergedState8[1];
  142. watch(function () {
  143. return props.picker;
  144. }, function () {
  145. setInnerModes([props.picker, props.picker]);
  146. });
  147. var triggerModesChange = function triggerModesChange(modes, values) {
  148. var _props$onPanelChange;
  149. setInnerModes(modes);
  150. (_props$onPanelChange = props.onPanelChange) === null || _props$onPanelChange === void 0 ? void 0 : _props$onPanelChange.call(props, values, modes);
  151. };
  152. // ========================= Disable Date ==========================
  153. var _useRangeDisabled = useRangeDisabled({
  154. picker: toRef(props, 'picker'),
  155. selectedValue: selectedValue,
  156. locale: toRef(props, 'locale'),
  157. disabled: mergedDisabled,
  158. disabledDate: toRef(props, 'disabledDate'),
  159. generateConfig: toRef(props, 'generateConfig')
  160. }, openRecordsRef),
  161. _useRangeDisabled2 = _slicedToArray(_useRangeDisabled, 2),
  162. disabledStartDate = _useRangeDisabled2[0],
  163. disabledEndDate = _useRangeDisabled2[1];
  164. // ============================= Open ==============================
  165. var _useMergedState9 = useMergedState(false, {
  166. value: toRef(props, 'open'),
  167. defaultValue: props.defaultOpen,
  168. postState: function postState(postOpen) {
  169. return mergedDisabled.value[mergedActivePickerIndex.value] ? false : postOpen;
  170. },
  171. onChange: function onChange(newOpen) {
  172. var _props$onOpenChange;
  173. (_props$onOpenChange = props.onOpenChange) === null || _props$onOpenChange === void 0 ? void 0 : _props$onOpenChange.call(props, newOpen);
  174. if (!newOpen && operationRef.value && operationRef.value.onClose) {
  175. operationRef.value.onClose();
  176. }
  177. }
  178. }),
  179. _useMergedState10 = _slicedToArray(_useMergedState9, 2),
  180. mergedOpen = _useMergedState10[0],
  181. triggerInnerOpen = _useMergedState10[1];
  182. var startOpen = computed(function () {
  183. return mergedOpen.value && mergedActivePickerIndex.value === 0;
  184. });
  185. var endOpen = computed(function () {
  186. return mergedOpen.value && mergedActivePickerIndex.value === 1;
  187. });
  188. var panelLeft = ref(0);
  189. var arrowLeft = ref(0);
  190. // ============================= Popup =============================
  191. // Popup min width
  192. var popupMinWidth = ref(0);
  193. var _useElementSize = useElementSize(containerRef),
  194. containerWidth = _useElementSize.width;
  195. watch([mergedOpen, containerWidth], function () {
  196. if (!mergedOpen.value && containerRef.value) {
  197. popupMinWidth.value = containerWidth.value;
  198. }
  199. });
  200. var _useElementSize2 = useElementSize(panelDivRef),
  201. panelDivWidth = _useElementSize2.width;
  202. var _useElementSize3 = useElementSize(arrowRef),
  203. arrowWidth = _useElementSize3.width;
  204. var _useElementSize4 = useElementSize(startInputDivRef),
  205. startInputDivWidth = _useElementSize4.width;
  206. var _useElementSize5 = useElementSize(separatorRef),
  207. separatorWidth = _useElementSize5.width;
  208. watch([mergedActivePickerIndex, mergedOpen, panelDivWidth, arrowWidth, startInputDivWidth, separatorWidth, function () {
  209. return props.direction;
  210. }], function () {
  211. arrowLeft.value = 0;
  212. if (mergedOpen.value && mergedActivePickerIndex.value) {
  213. if (startInputDivRef.value && separatorRef.value && panelDivRef.value) {
  214. arrowLeft.value = startInputDivWidth.value + separatorWidth.value;
  215. if (panelDivWidth.value && arrowWidth.value && arrowLeft.value > panelDivWidth.value - arrowWidth.value - (props.direction === 'rtl' || arrowRef.value.offsetLeft > arrowLeft.value ? 0 : arrowRef.value.offsetLeft)) {
  216. panelLeft.value = arrowLeft.value;
  217. }
  218. }
  219. } else if (mergedActivePickerIndex.value === 0) {
  220. panelLeft.value = 0;
  221. }
  222. }, {
  223. immediate: true
  224. });
  225. // ============================ Trigger ============================
  226. var triggerRef = ref();
  227. function _triggerOpen(newOpen, index) {
  228. if (newOpen) {
  229. clearTimeout(triggerRef.value);
  230. openRecordsRef.value[index] = true;
  231. setMergedActivePickerIndex(index);
  232. triggerInnerOpen(newOpen);
  233. // Open to reset view date
  234. if (!mergedOpen.value) {
  235. setViewDate(null, index);
  236. }
  237. } else if (mergedActivePickerIndex.value === index) {
  238. triggerInnerOpen(newOpen);
  239. // Clean up async
  240. // This makes ref not quick refresh in case user open another input with blur trigger
  241. var openRecords = openRecordsRef.value;
  242. triggerRef.value = setTimeout(function () {
  243. if (openRecords === openRecordsRef.value) {
  244. openRecordsRef.value = {};
  245. }
  246. });
  247. }
  248. }
  249. function triggerOpenAndFocus(index) {
  250. _triggerOpen(true, index);
  251. // Use setTimeout to make sure panel DOM exists
  252. setTimeout(function () {
  253. var inputRef = [startInputRef, endInputRef][index];
  254. if (inputRef.value) {
  255. inputRef.value.focus();
  256. }
  257. }, 0);
  258. }
  259. function triggerChange(newValue, sourceIndex) {
  260. var values = newValue;
  261. var startValue = getValue(values, 0);
  262. var endValue = getValue(values, 1);
  263. var generateConfig = props.generateConfig,
  264. locale = props.locale,
  265. picker = props.picker,
  266. order = props.order,
  267. onCalendarChange = props.onCalendarChange,
  268. allowEmpty = props.allowEmpty,
  269. onChange = props.onChange,
  270. showTime = props.showTime;
  271. // >>>>> Format start & end values
  272. if (startValue && endValue && generateConfig.isAfter(startValue, endValue)) {
  273. if (
  274. // WeekPicker only compare week
  275. picker === 'week' && !isSameWeek(generateConfig, locale.locale, startValue, endValue) ||
  276. // QuotaPicker only compare week
  277. picker === 'quarter' && !isSameQuarter(generateConfig, startValue, endValue) ||
  278. // Other non-TimePicker compare date
  279. picker !== 'week' && picker !== 'quarter' && picker !== 'time' && !(showTime ? isEqual(generateConfig, startValue, endValue) : isSameDate(generateConfig, startValue, endValue))) {
  280. // Clean up end date when start date is after end date
  281. if (sourceIndex === 0) {
  282. values = [startValue, null];
  283. endValue = null;
  284. } else {
  285. startValue = null;
  286. values = [null, endValue];
  287. }
  288. // Clean up cache since invalidate
  289. openRecordsRef.value = _defineProperty({}, sourceIndex, true);
  290. } else if (picker !== 'time' || order !== false) {
  291. // Reorder when in same date
  292. values = reorderValues(values, generateConfig);
  293. }
  294. }
  295. setSelectedValue(values);
  296. var startStr = values && values[0] ? formatValue(values[0], {
  297. generateConfig: generateConfig,
  298. locale: locale,
  299. format: formatList.value[0]
  300. }) : '';
  301. var endStr = values && values[1] ? formatValue(values[1], {
  302. generateConfig: generateConfig,
  303. locale: locale,
  304. format: formatList.value[0]
  305. }) : '';
  306. if (onCalendarChange) {
  307. var info = {
  308. range: sourceIndex === 0 ? 'start' : 'end'
  309. };
  310. onCalendarChange(values, [startStr, endStr], info);
  311. }
  312. // >>>>> Trigger `onChange` event
  313. var canStartValueTrigger = canValueTrigger(startValue, 0, mergedDisabled.value, allowEmpty);
  314. var canEndValueTrigger = canValueTrigger(endValue, 1, mergedDisabled.value, allowEmpty);
  315. var canTrigger = values === null || canStartValueTrigger && canEndValueTrigger;
  316. if (canTrigger) {
  317. // Trigger onChange only when value is validate
  318. setInnerValue(values);
  319. if (onChange && (!isEqual(generateConfig, getValue(mergedValue.value, 0), startValue) || !isEqual(generateConfig, getValue(mergedValue.value, 1), endValue))) {
  320. onChange(values, [startStr, endStr]);
  321. }
  322. }
  323. // >>>>> Open picker when
  324. // Always open another picker if possible
  325. var nextOpenIndex = null;
  326. if (sourceIndex === 0 && !mergedDisabled.value[1]) {
  327. nextOpenIndex = 1;
  328. } else if (sourceIndex === 1 && !mergedDisabled.value[0]) {
  329. nextOpenIndex = 0;
  330. }
  331. if (nextOpenIndex !== null && nextOpenIndex !== mergedActivePickerIndex.value && (!openRecordsRef.value[nextOpenIndex] || !getValue(values, nextOpenIndex)) && getValue(values, sourceIndex)) {
  332. // Delay to focus to avoid input blur trigger expired selectedValues
  333. triggerOpenAndFocus(nextOpenIndex);
  334. } else {
  335. _triggerOpen(false, sourceIndex);
  336. }
  337. }
  338. var forwardKeydown = function forwardKeydown(e) {
  339. if (mergedOpen && operationRef.value && operationRef.value.onKeydown) {
  340. // Let popup panel handle keyboard
  341. return operationRef.value.onKeydown(e);
  342. }
  343. /* istanbul ignore next */
  344. /* eslint-disable no-lone-blocks */
  345. {
  346. warning(false, 'Picker not correct forward Keydown operation. Please help to fire issue about this.');
  347. return false;
  348. }
  349. };
  350. // ============================= Text ==============================
  351. var sharedTextHooksProps = {
  352. formatList: formatList,
  353. generateConfig: toRef(props, 'generateConfig'),
  354. locale: toRef(props, 'locale')
  355. };
  356. var _useValueTexts = useValueTexts(computed(function () {
  357. return getValue(selectedValue.value, 0);
  358. }), sharedTextHooksProps),
  359. _useValueTexts2 = _slicedToArray(_useValueTexts, 2),
  360. startValueTexts = _useValueTexts2[0],
  361. firstStartValueText = _useValueTexts2[1];
  362. var _useValueTexts3 = useValueTexts(computed(function () {
  363. return getValue(selectedValue.value, 1);
  364. }), sharedTextHooksProps),
  365. _useValueTexts4 = _slicedToArray(_useValueTexts3, 2),
  366. endValueTexts = _useValueTexts4[0],
  367. firstEndValueText = _useValueTexts4[1];
  368. var _onTextChange = function onTextChange(newText, index) {
  369. var inputDate = parseValue(newText, {
  370. locale: props.locale,
  371. formatList: formatList.value,
  372. generateConfig: props.generateConfig
  373. });
  374. var disabledFunc = index === 0 ? disabledStartDate : disabledEndDate;
  375. if (inputDate && !disabledFunc(inputDate)) {
  376. setSelectedValue(updateValues(selectedValue.value, inputDate, index));
  377. setViewDate(inputDate, index);
  378. }
  379. };
  380. var _useTextValueMapping = useTextValueMapping({
  381. valueTexts: startValueTexts,
  382. onTextChange: function onTextChange(newText) {
  383. return _onTextChange(newText, 0);
  384. }
  385. }),
  386. _useTextValueMapping2 = _slicedToArray(_useTextValueMapping, 3),
  387. startText = _useTextValueMapping2[0],
  388. triggerStartTextChange = _useTextValueMapping2[1],
  389. resetStartText = _useTextValueMapping2[2];
  390. var _useTextValueMapping3 = useTextValueMapping({
  391. valueTexts: endValueTexts,
  392. onTextChange: function onTextChange(newText) {
  393. return _onTextChange(newText, 1);
  394. }
  395. }),
  396. _useTextValueMapping4 = _slicedToArray(_useTextValueMapping3, 3),
  397. endText = _useTextValueMapping4[0],
  398. triggerEndTextChange = _useTextValueMapping4[1],
  399. resetEndText = _useTextValueMapping4[2];
  400. var _useState = useState(null),
  401. _useState2 = _slicedToArray(_useState, 2),
  402. rangeHoverValue = _useState2[0],
  403. setRangeHoverValue = _useState2[1];
  404. // ========================== Hover Range ==========================
  405. var _useState3 = useState(null),
  406. _useState4 = _slicedToArray(_useState3, 2),
  407. hoverRangedValue = _useState4[0],
  408. setHoverRangedValue = _useState4[1];
  409. var _useHoverValue = useHoverValue(startText, sharedTextHooksProps),
  410. _useHoverValue2 = _slicedToArray(_useHoverValue, 3),
  411. startHoverValue = _useHoverValue2[0],
  412. onStartEnter = _useHoverValue2[1],
  413. onStartLeave = _useHoverValue2[2];
  414. var _useHoverValue3 = useHoverValue(endText, sharedTextHooksProps),
  415. _useHoverValue4 = _slicedToArray(_useHoverValue3, 3),
  416. endHoverValue = _useHoverValue4[0],
  417. onEndEnter = _useHoverValue4[1],
  418. onEndLeave = _useHoverValue4[2];
  419. var onDateMouseenter = function onDateMouseenter(date) {
  420. setHoverRangedValue(updateValues(selectedValue.value, date, mergedActivePickerIndex.value));
  421. if (mergedActivePickerIndex.value === 0) {
  422. onStartEnter(date);
  423. } else {
  424. onEndEnter(date);
  425. }
  426. };
  427. var onDateMouseleave = function onDateMouseleave() {
  428. setHoverRangedValue(updateValues(selectedValue.value, null, mergedActivePickerIndex.value));
  429. if (mergedActivePickerIndex.value === 0) {
  430. onStartLeave();
  431. } else {
  432. onEndLeave();
  433. }
  434. };
  435. // ============================= Input =============================
  436. var getSharedInputHookProps = function getSharedInputHookProps(index, resetText) {
  437. return {
  438. forwardKeydown: forwardKeydown,
  439. onBlur: function onBlur(e) {
  440. var _props$onBlur;
  441. (_props$onBlur = props.onBlur) === null || _props$onBlur === void 0 ? void 0 : _props$onBlur.call(props, e);
  442. },
  443. isClickOutside: function isClickOutside(target) {
  444. return !elementsContains([panelDivRef.value, startInputDivRef.value, endInputDivRef.value, containerRef.value], target);
  445. },
  446. onFocus: function onFocus(e) {
  447. var _props$onFocus;
  448. setMergedActivePickerIndex(index);
  449. (_props$onFocus = props.onFocus) === null || _props$onFocus === void 0 ? void 0 : _props$onFocus.call(props, e);
  450. },
  451. triggerOpen: function triggerOpen(newOpen) {
  452. _triggerOpen(newOpen, index);
  453. },
  454. onSubmit: function onSubmit() {
  455. if (
  456. // When user typing disabledDate with keyboard and enter, this value will be empty
  457. !selectedValue.value ||
  458. // Normal disabled check
  459. props.disabledDate && props.disabledDate(selectedValue.value[index])) {
  460. return false;
  461. }
  462. triggerChange(selectedValue.value, index);
  463. resetText();
  464. },
  465. onCancel: function onCancel() {
  466. _triggerOpen(false, index);
  467. setSelectedValue(mergedValue.value);
  468. resetText();
  469. }
  470. };
  471. };
  472. var _usePickerInput = usePickerInput(_objectSpread(_objectSpread({}, getSharedInputHookProps(0, resetStartText)), {}, {
  473. blurToCancel: needConfirmButton,
  474. open: startOpen,
  475. value: startText,
  476. onKeydown: function onKeydown(e, preventDefault) {
  477. var _props$onKeydown;
  478. (_props$onKeydown = props.onKeydown) === null || _props$onKeydown === void 0 ? void 0 : _props$onKeydown.call(props, e, preventDefault);
  479. }
  480. })),
  481. _usePickerInput2 = _slicedToArray(_usePickerInput, 2),
  482. startInputProps = _usePickerInput2[0],
  483. _usePickerInput2$ = _usePickerInput2[1],
  484. startFocused = _usePickerInput2$.focused,
  485. startTyping = _usePickerInput2$.typing;
  486. var _usePickerInput3 = usePickerInput(_objectSpread(_objectSpread({}, getSharedInputHookProps(1, resetEndText)), {}, {
  487. blurToCancel: needConfirmButton,
  488. open: endOpen,
  489. value: endText,
  490. onKeydown: function onKeydown(e, preventDefault) {
  491. var _props$onKeydown2;
  492. (_props$onKeydown2 = props.onKeydown) === null || _props$onKeydown2 === void 0 ? void 0 : _props$onKeydown2.call(props, e, preventDefault);
  493. }
  494. })),
  495. _usePickerInput4 = _slicedToArray(_usePickerInput3, 2),
  496. endInputProps = _usePickerInput4[0],
  497. _usePickerInput4$ = _usePickerInput4[1],
  498. endFocused = _usePickerInput4$.focused,
  499. endTyping = _usePickerInput4$.typing;
  500. // ========================== Click Picker ==========================
  501. var onPickerClick = function onPickerClick(e) {
  502. var _props$onClick;
  503. // When click inside the picker & outside the picker's input elements
  504. // the panel should still be opened
  505. (_props$onClick = props.onClick) === null || _props$onClick === void 0 ? void 0 : _props$onClick.call(props, e);
  506. if (!mergedOpen.value && !startInputRef.value.contains(e.target) && !endInputRef.value.contains(e.target)) {
  507. if (!mergedDisabled.value[0]) {
  508. triggerOpenAndFocus(0);
  509. } else if (!mergedDisabled.value[1]) {
  510. triggerOpenAndFocus(1);
  511. }
  512. }
  513. };
  514. var onPickerMousedown = function onPickerMousedown(e) {
  515. var _props$onMousedown;
  516. // shouldn't affect input elements if picker is active
  517. (_props$onMousedown = props.onMousedown) === null || _props$onMousedown === void 0 ? void 0 : _props$onMousedown.call(props, e);
  518. if (mergedOpen.value && (startFocused.value || endFocused.value) && !startInputRef.value.contains(e.target) && !endInputRef.value.contains(e.target)) {
  519. e.preventDefault();
  520. }
  521. };
  522. // ============================= Sync ==============================
  523. // Close should sync back with text value
  524. var startStr = computed(function () {
  525. var _mergedValue$value;
  526. return (_mergedValue$value = mergedValue.value) !== null && _mergedValue$value !== void 0 && _mergedValue$value[0] ? formatValue(mergedValue.value[0], {
  527. locale: props.locale,
  528. format: 'YYYYMMDDHHmmss',
  529. generateConfig: props.generateConfig
  530. }) : '';
  531. });
  532. var endStr = computed(function () {
  533. var _mergedValue$value2;
  534. return (_mergedValue$value2 = mergedValue.value) !== null && _mergedValue$value2 !== void 0 && _mergedValue$value2[1] ? formatValue(mergedValue.value[1], {
  535. locale: props.locale,
  536. format: 'YYYYMMDDHHmmss',
  537. generateConfig: props.generateConfig
  538. }) : '';
  539. });
  540. watch([mergedOpen, startValueTexts, endValueTexts], function () {
  541. if (!mergedOpen.value) {
  542. setSelectedValue(mergedValue.value);
  543. if (!startValueTexts.value.length || startValueTexts.value[0] === '') {
  544. triggerStartTextChange('');
  545. } else if (firstStartValueText.value !== startText.value) {
  546. resetStartText();
  547. }
  548. if (!endValueTexts.value.length || endValueTexts.value[0] === '') {
  549. triggerEndTextChange('');
  550. } else if (firstEndValueText.value !== endText.value) {
  551. resetEndText();
  552. }
  553. }
  554. });
  555. // Sync innerValue with control mode
  556. watch([startStr, endStr], function () {
  557. setSelectedValue(mergedValue.value);
  558. });
  559. // ============================ Warning ============================
  560. if (process.env.NODE_ENV !== 'production') {
  561. watchEffect(function () {
  562. var value = props.value,
  563. disabled = props.disabled;
  564. if (value && Array.isArray(disabled) && (getValue(disabled, 0) && !getValue(value, 0) || getValue(disabled, 1) && !getValue(value, 1))) {
  565. warning(false, '`disabled` should not set with empty `value`. You should set `allowEmpty` or `value` instead.');
  566. }
  567. });
  568. }
  569. expose({
  570. focus: function focus() {
  571. if (startInputRef.value) {
  572. startInputRef.value.focus();
  573. }
  574. },
  575. blur: function blur() {
  576. if (startInputRef.value) {
  577. startInputRef.value.blur();
  578. }
  579. if (endInputRef.value) {
  580. endInputRef.value.blur();
  581. }
  582. }
  583. });
  584. // ============================ Ranges =============================
  585. var rangeList = computed(function () {
  586. return Object.keys(props.ranges || {}).map(function (label) {
  587. var range = props.ranges[label];
  588. var newValues = typeof range === 'function' ? range() : range;
  589. return {
  590. label: label,
  591. onClick: function onClick() {
  592. triggerChange(newValues, null);
  593. _triggerOpen(false, mergedActivePickerIndex.value);
  594. },
  595. onMouseenter: function onMouseenter() {
  596. setRangeHoverValue(newValues);
  597. },
  598. onMouseleave: function onMouseleave() {
  599. setRangeHoverValue(null);
  600. }
  601. };
  602. });
  603. });
  604. // ============================= Panel =============================
  605. var panelHoverRangedValue = computed(function () {
  606. if (mergedOpen.value && hoverRangedValue.value && hoverRangedValue.value[0] && hoverRangedValue.value[1] && props.generateConfig.isAfter(hoverRangedValue.value[1], hoverRangedValue.value[0])) {
  607. return hoverRangedValue.value;
  608. } else {
  609. return null;
  610. }
  611. });
  612. function renderPanel() {
  613. var panelPosition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  614. var panelProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  615. var generateConfig = props.generateConfig,
  616. showTime = props.showTime,
  617. dateRender = props.dateRender,
  618. direction = props.direction,
  619. _disabledTime = props.disabledTime,
  620. prefixCls = props.prefixCls,
  621. locale = props.locale;
  622. var panelShowTime = showTime;
  623. if (showTime && _typeof(showTime) === 'object' && showTime.defaultValue) {
  624. var timeDefaultValues = showTime.defaultValue;
  625. panelShowTime = _objectSpread(_objectSpread({}, showTime), {}, {
  626. defaultValue: getValue(timeDefaultValues, mergedActivePickerIndex.value) || undefined
  627. });
  628. }
  629. var panelDateRender = null;
  630. if (dateRender) {
  631. panelDateRender = function panelDateRender(_ref2) {
  632. var date = _ref2.current,
  633. today = _ref2.today;
  634. return dateRender({
  635. current: date,
  636. today: today,
  637. info: {
  638. range: mergedActivePickerIndex.value ? 'end' : 'start'
  639. }
  640. });
  641. };
  642. }
  643. return _createVNode(RangeContextProvider, {
  644. "value": {
  645. inRange: true,
  646. panelPosition: panelPosition,
  647. rangedValue: rangeHoverValue.value || selectedValue.value,
  648. hoverRangedValue: panelHoverRangedValue.value
  649. }
  650. }, {
  651. default: function _default() {
  652. return [_createVNode(PickerPanel, _objectSpread(_objectSpread(_objectSpread({}, props), panelProps), {}, {
  653. "dateRender": panelDateRender,
  654. "showTime": panelShowTime,
  655. "mode": mergedModes.value[mergedActivePickerIndex.value],
  656. "generateConfig": generateConfig,
  657. "style": undefined,
  658. "direction": direction,
  659. "disabledDate": mergedActivePickerIndex.value === 0 ? disabledStartDate : disabledEndDate,
  660. "disabledTime": function disabledTime(date) {
  661. if (_disabledTime) {
  662. return _disabledTime(date, mergedActivePickerIndex.value === 0 ? 'start' : 'end');
  663. }
  664. return false;
  665. },
  666. "class": classNames(_defineProperty({}, "".concat(prefixCls, "-panel-focused"), mergedActivePickerIndex.value === 0 ? !startTyping.value : !endTyping.value)),
  667. "value": getValue(selectedValue.value, mergedActivePickerIndex.value),
  668. "locale": locale,
  669. "tabIndex": -1,
  670. "onPanelChange": function onPanelChange(date, newMode) {
  671. // clear hover value when panel change
  672. if (mergedActivePickerIndex.value === 0) {
  673. onStartLeave(true);
  674. }
  675. if (mergedActivePickerIndex.value === 1) {
  676. onEndLeave(true);
  677. }
  678. triggerModesChange(updateValues(mergedModes.value, newMode, mergedActivePickerIndex.value), updateValues(selectedValue.value, date, mergedActivePickerIndex.value));
  679. var viewDate = date;
  680. if (panelPosition === 'right' && mergedModes.value[mergedActivePickerIndex.value] === newMode) {
  681. viewDate = getClosingViewDate(viewDate, newMode, generateConfig, -1);
  682. }
  683. setViewDate(viewDate, mergedActivePickerIndex.value);
  684. },
  685. "onOk": null,
  686. "onSelect": undefined,
  687. "onChange": undefined,
  688. "defaultValue": mergedActivePickerIndex.value === 0 ? getValue(selectedValue.value, 1) : getValue(selectedValue.value, 0)
  689. }), null)];
  690. }
  691. });
  692. }
  693. var onContextSelect = function onContextSelect(date, type) {
  694. var values = updateValues(selectedValue.value, date, mergedActivePickerIndex.value);
  695. if (type === 'submit' || type !== 'key' && !needConfirmButton.value) {
  696. // triggerChange will also update selected values
  697. triggerChange(values, mergedActivePickerIndex.value);
  698. // clear hover value style
  699. if (mergedActivePickerIndex.value === 0) {
  700. onStartLeave();
  701. } else {
  702. onEndLeave();
  703. }
  704. } else {
  705. setSelectedValue(values);
  706. }
  707. };
  708. useProvidePanel({
  709. operationRef: operationRef,
  710. hideHeader: computed(function () {
  711. return props.picker === 'time';
  712. }),
  713. onDateMouseenter: onDateMouseenter,
  714. onDateMouseleave: onDateMouseleave,
  715. hideRanges: computed(function () {
  716. return true;
  717. }),
  718. onSelect: onContextSelect,
  719. open: mergedOpen
  720. });
  721. return function () {
  722. var _classNames2, _classNames3, _classNames4;
  723. var _props$prefixCls = props.prefixCls,
  724. prefixCls = _props$prefixCls === void 0 ? 'rc-picker' : _props$prefixCls,
  725. id = props.id,
  726. popupStyle = props.popupStyle,
  727. dropdownClassName = props.dropdownClassName,
  728. transitionName = props.transitionName,
  729. dropdownAlign = props.dropdownAlign,
  730. getPopupContainer = props.getPopupContainer,
  731. generateConfig = props.generateConfig,
  732. locale = props.locale,
  733. placeholder = props.placeholder,
  734. autofocus = props.autofocus,
  735. _props$picker = props.picker,
  736. picker = _props$picker === void 0 ? 'date' : _props$picker,
  737. showTime = props.showTime,
  738. _props$separator = props.separator,
  739. separator = _props$separator === void 0 ? '~' : _props$separator,
  740. disabledDate = props.disabledDate,
  741. panelRender = props.panelRender,
  742. allowClear = props.allowClear,
  743. suffixIcon = props.suffixIcon,
  744. clearIcon = props.clearIcon,
  745. inputReadOnly = props.inputReadOnly,
  746. renderExtraFooter = props.renderExtraFooter,
  747. onMouseenter = props.onMouseenter,
  748. onMouseleave = props.onMouseleave,
  749. onMouseup = props.onMouseup,
  750. _onOk = props.onOk,
  751. components = props.components,
  752. direction = props.direction,
  753. _props$autocomplete = props.autocomplete,
  754. autocomplete = _props$autocomplete === void 0 ? 'off' : _props$autocomplete;
  755. var arrowPositionStyle = direction === 'rtl' ? {
  756. right: "".concat(arrowLeft.value, "px")
  757. } : {
  758. left: "".concat(arrowLeft.value, "px")
  759. };
  760. function renderPanels() {
  761. var panels;
  762. var extraNode = getExtraFooter(prefixCls, mergedModes.value[mergedActivePickerIndex.value], renderExtraFooter);
  763. var rangesNode = getRanges({
  764. prefixCls: prefixCls,
  765. components: components,
  766. needConfirmButton: needConfirmButton.value,
  767. okDisabled: !getValue(selectedValue.value, mergedActivePickerIndex.value) || disabledDate && disabledDate(selectedValue.value[mergedActivePickerIndex.value]),
  768. locale: locale,
  769. rangeList: rangeList.value,
  770. onOk: function onOk() {
  771. if (getValue(selectedValue.value, mergedActivePickerIndex.value)) {
  772. // triggerChangeOld(selectedValue.value);
  773. triggerChange(selectedValue.value, mergedActivePickerIndex.value);
  774. if (_onOk) {
  775. _onOk(selectedValue.value);
  776. }
  777. }
  778. }
  779. });
  780. if (picker !== 'time' && !showTime) {
  781. var viewDate = mergedActivePickerIndex.value === 0 ? startViewDate.value : endViewDate.value;
  782. var nextViewDate = getClosingViewDate(viewDate, picker, generateConfig);
  783. var currentMode = mergedModes.value[mergedActivePickerIndex.value];
  784. var showDoublePanel = currentMode === picker;
  785. var leftPanel = renderPanel(showDoublePanel ? 'left' : false, {
  786. pickerValue: viewDate,
  787. onPickerValueChange: function onPickerValueChange(newViewDate) {
  788. setViewDate(newViewDate, mergedActivePickerIndex.value);
  789. }
  790. });
  791. var rightPanel = renderPanel('right', {
  792. pickerValue: nextViewDate,
  793. onPickerValueChange: function onPickerValueChange(newViewDate) {
  794. setViewDate(getClosingViewDate(newViewDate, picker, generateConfig, -1), mergedActivePickerIndex.value);
  795. }
  796. });
  797. if (direction === 'rtl') {
  798. panels = _createVNode(_Fragment, null, [rightPanel, showDoublePanel && leftPanel]);
  799. } else {
  800. panels = _createVNode(_Fragment, null, [leftPanel, showDoublePanel && rightPanel]);
  801. }
  802. } else {
  803. panels = renderPanel();
  804. }
  805. var mergedNodes = _createVNode(_Fragment, null, [_createVNode("div", {
  806. "class": "".concat(prefixCls, "-panels")
  807. }, [panels]), (extraNode || rangesNode) && _createVNode("div", {
  808. "class": "".concat(prefixCls, "-footer")
  809. }, [extraNode, rangesNode])]);
  810. if (panelRender) {
  811. mergedNodes = panelRender(mergedNodes);
  812. }
  813. return _createVNode("div", {
  814. "class": "".concat(prefixCls, "-panel-container"),
  815. "style": {
  816. marginLeft: "".concat(panelLeft.value, "px")
  817. },
  818. "ref": panelDivRef,
  819. "onMousedown": function onMousedown(e) {
  820. e.preventDefault();
  821. }
  822. }, [mergedNodes]);
  823. }
  824. var rangePanel = _createVNode("div", {
  825. "class": classNames("".concat(prefixCls, "-range-wrapper"), "".concat(prefixCls, "-").concat(picker, "-range-wrapper")),
  826. "style": {
  827. minWidth: "".concat(popupMinWidth.value, "px")
  828. }
  829. }, [_createVNode("div", {
  830. "ref": arrowRef,
  831. "class": "".concat(prefixCls, "-range-arrow"),
  832. "style": arrowPositionStyle
  833. }, null), renderPanels()]);
  834. // ============================= Icons =============================
  835. var suffixNode;
  836. if (suffixIcon) {
  837. suffixNode = _createVNode("span", {
  838. "class": "".concat(prefixCls, "-suffix")
  839. }, [suffixIcon]);
  840. }
  841. var clearNode;
  842. if (allowClear && (getValue(mergedValue.value, 0) && !mergedDisabled.value[0] || getValue(mergedValue.value, 1) && !mergedDisabled.value[1])) {
  843. clearNode = _createVNode("span", {
  844. "onMousedown": function onMousedown(e) {
  845. e.preventDefault();
  846. e.stopPropagation();
  847. },
  848. "onMouseup": function onMouseup(e) {
  849. e.preventDefault();
  850. e.stopPropagation();
  851. var values = mergedValue.value;
  852. if (!mergedDisabled.value[0]) {
  853. values = updateValues(values, null, 0);
  854. }
  855. if (!mergedDisabled.value[1]) {
  856. values = updateValues(values, null, 1);
  857. }
  858. triggerChange(values, null);
  859. _triggerOpen(false, mergedActivePickerIndex.value);
  860. },
  861. "class": "".concat(prefixCls, "-clear")
  862. }, [clearIcon || _createVNode("span", {
  863. "class": "".concat(prefixCls, "-clear-btn")
  864. }, null)]);
  865. }
  866. var inputSharedProps = {
  867. size: getInputSize(picker, formatList.value[0], generateConfig)
  868. };
  869. var activeBarLeft = 0;
  870. var activeBarWidth = 0;
  871. if (startInputDivRef.value && endInputDivRef.value && separatorRef.value) {
  872. if (mergedActivePickerIndex.value === 0) {
  873. activeBarWidth = startInputDivRef.value.offsetWidth;
  874. } else {
  875. activeBarLeft = arrowLeft.value;
  876. activeBarWidth = endInputDivRef.value.offsetWidth;
  877. }
  878. }
  879. var activeBarPositionStyle = direction === 'rtl' ? {
  880. right: "".concat(activeBarLeft, "px")
  881. } : {
  882. left: "".concat(activeBarLeft, "px")
  883. };
  884. // ============================ Return =============================
  885. return _createVNode(PickerTrigger, {
  886. "visible": mergedOpen.value,
  887. "popupStyle": popupStyle,
  888. "prefixCls": prefixCls,
  889. "dropdownClassName": dropdownClassName,
  890. "dropdownAlign": dropdownAlign,
  891. "getPopupContainer": getPopupContainer,
  892. "transitionName": transitionName,
  893. "range": true,
  894. "direction": direction
  895. }, {
  896. default: function _default() {
  897. return [_createVNode("div", _objectSpread({
  898. "ref": containerRef,
  899. "class": classNames(prefixCls, "".concat(prefixCls, "-range"), attrs.class, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls, "-disabled"), mergedDisabled.value[0] && mergedDisabled.value[1]), _defineProperty(_classNames2, "".concat(prefixCls, "-focused"), mergedActivePickerIndex.value === 0 ? startFocused.value : endFocused.value), _defineProperty(_classNames2, "".concat(prefixCls, "-rtl"), direction === 'rtl'), _classNames2)),
  900. "style": attrs.style,
  901. "onClick": onPickerClick,
  902. "onMouseenter": onMouseenter,
  903. "onMouseleave": onMouseleave,
  904. "onMousedown": onPickerMousedown,
  905. "onMouseup": onMouseup
  906. }, getDataOrAriaProps(props)), [_createVNode("div", {
  907. "class": classNames("".concat(prefixCls, "-input"), (_classNames3 = {}, _defineProperty(_classNames3, "".concat(prefixCls, "-input-active"), mergedActivePickerIndex.value === 0), _defineProperty(_classNames3, "".concat(prefixCls, "-input-placeholder"), !!startHoverValue.value), _classNames3)),
  908. "ref": startInputDivRef
  909. }, [_createVNode("input", _objectSpread(_objectSpread(_objectSpread({
  910. "id": id,
  911. "disabled": mergedDisabled.value[0],
  912. "readonly": inputReadOnly || typeof formatList.value[0] === 'function' || !startTyping.value,
  913. "value": startHoverValue.value || startText.value,
  914. "onInput": function onInput(e) {
  915. triggerStartTextChange(e.target.value);
  916. },
  917. "autofocus": autofocus,
  918. "placeholder": getValue(placeholder, 0) || '',
  919. "ref": startInputRef
  920. }, startInputProps.value), inputSharedProps), {}, {
  921. "autocomplete": autocomplete
  922. }), null)]), _createVNode("div", {
  923. "class": "".concat(prefixCls, "-range-separator"),
  924. "ref": separatorRef
  925. }, [separator]), _createVNode("div", {
  926. "class": classNames("".concat(prefixCls, "-input"), (_classNames4 = {}, _defineProperty(_classNames4, "".concat(prefixCls, "-input-active"), mergedActivePickerIndex.value === 1), _defineProperty(_classNames4, "".concat(prefixCls, "-input-placeholder"), !!endHoverValue.value), _classNames4)),
  927. "ref": endInputDivRef
  928. }, [_createVNode("input", _objectSpread(_objectSpread(_objectSpread({
  929. "disabled": mergedDisabled.value[1],
  930. "readonly": inputReadOnly || typeof formatList.value[0] === 'function' || !endTyping.value,
  931. "value": endHoverValue.value || endText.value,
  932. "onInput": function onInput(e) {
  933. triggerEndTextChange(e.target.value);
  934. },
  935. "placeholder": getValue(placeholder, 1) || '',
  936. "ref": endInputRef
  937. }, endInputProps.value), inputSharedProps), {}, {
  938. "autocomplete": autocomplete
  939. }), null)]), _createVNode("div", {
  940. "class": "".concat(prefixCls, "-active-bar"),
  941. "style": _objectSpread(_objectSpread({}, activeBarPositionStyle), {}, {
  942. width: "".concat(activeBarWidth, "px"),
  943. position: 'absolute'
  944. })
  945. }, null), suffixNode, clearNode, getPortal()])];
  946. },
  947. popupElement: function popupElement() {
  948. return rangePanel;
  949. }
  950. });
  951. };
  952. }
  953. });
  954. }
  955. var InterRangerPicker = RangerPicker();
  956. export default InterRangerPicker;