SinglePicker.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = void 0;
  8. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  9. var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
  10. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  11. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  12. var _rcUtil = require("rc-util");
  13. var _useLayoutEffect = _interopRequireDefault(require("rc-util/lib/hooks/useLayoutEffect"));
  14. var _omit = _interopRequireDefault(require("rc-util/lib/omit"));
  15. var _pickAttrs = _interopRequireDefault(require("rc-util/lib/pickAttrs"));
  16. var React = _interopRequireWildcard(require("react"));
  17. var _useToggleDates = _interopRequireDefault(require("../hooks/useToggleDates"));
  18. var _PickerTrigger = _interopRequireDefault(require("../PickerTrigger"));
  19. var _util = require("../PickerTrigger/util");
  20. var _miscUtil = require("../utils/miscUtil");
  21. var _context = _interopRequireDefault(require("./context"));
  22. var _useCellRender = _interopRequireDefault(require("./hooks/useCellRender"));
  23. var _useFieldsInvalidate3 = _interopRequireDefault(require("./hooks/useFieldsInvalidate"));
  24. var _useFilledProps3 = _interopRequireDefault(require("./hooks/useFilledProps"));
  25. var _useOpen3 = _interopRequireDefault(require("./hooks/useOpen"));
  26. var _usePickerRef = _interopRequireDefault(require("./hooks/usePickerRef"));
  27. var _usePresets = _interopRequireDefault(require("./hooks/usePresets"));
  28. var _useRangeActive3 = _interopRequireDefault(require("./hooks/useRangeActive"));
  29. var _useRangePickerValue3 = _interopRequireDefault(require("./hooks/useRangePickerValue"));
  30. var _useRangeValue3 = _interopRequireWildcard(require("./hooks/useRangeValue"));
  31. var _useShowNow = _interopRequireDefault(require("./hooks/useShowNow"));
  32. var _Popup = _interopRequireDefault(require("./Popup"));
  33. var _SingleSelector = _interopRequireDefault(require("./Selector/SingleSelector"));
  34. // TODO: isInvalidateDate with showTime.disabledTime should not provide `range` prop
  35. /** Internal usage. For cross function get same aligned props */
  36. function Picker(props, ref) {
  37. // ========================= Prop =========================
  38. var _useFilledProps = (0, _useFilledProps3.default)(props),
  39. _useFilledProps2 = (0, _slicedToArray2.default)(_useFilledProps, 6),
  40. filledProps = _useFilledProps2[0],
  41. internalPicker = _useFilledProps2[1],
  42. complexPicker = _useFilledProps2[2],
  43. formatList = _useFilledProps2[3],
  44. maskFormat = _useFilledProps2[4],
  45. isInvalidateDate = _useFilledProps2[5];
  46. var _ref = filledProps,
  47. prefixCls = _ref.prefixCls,
  48. styles = _ref.styles,
  49. classNames = _ref.classNames,
  50. order = _ref.order,
  51. defaultValue = _ref.defaultValue,
  52. value = _ref.value,
  53. needConfirm = _ref.needConfirm,
  54. onChange = _ref.onChange,
  55. onKeyDown = _ref.onKeyDown,
  56. disabled = _ref.disabled,
  57. disabledDate = _ref.disabledDate,
  58. minDate = _ref.minDate,
  59. maxDate = _ref.maxDate,
  60. defaultOpen = _ref.defaultOpen,
  61. open = _ref.open,
  62. onOpenChange = _ref.onOpenChange,
  63. locale = _ref.locale,
  64. generateConfig = _ref.generateConfig,
  65. picker = _ref.picker,
  66. showNow = _ref.showNow,
  67. showToday = _ref.showToday,
  68. showTime = _ref.showTime,
  69. mode = _ref.mode,
  70. onPanelChange = _ref.onPanelChange,
  71. onCalendarChange = _ref.onCalendarChange,
  72. onOk = _ref.onOk,
  73. multiple = _ref.multiple,
  74. defaultPickerValue = _ref.defaultPickerValue,
  75. pickerValue = _ref.pickerValue,
  76. onPickerValueChange = _ref.onPickerValueChange,
  77. inputReadOnly = _ref.inputReadOnly,
  78. suffixIcon = _ref.suffixIcon,
  79. removeIcon = _ref.removeIcon,
  80. onFocus = _ref.onFocus,
  81. onBlur = _ref.onBlur,
  82. presets = _ref.presets,
  83. components = _ref.components,
  84. cellRender = _ref.cellRender,
  85. dateRender = _ref.dateRender,
  86. monthCellRender = _ref.monthCellRender,
  87. onClick = _ref.onClick;
  88. // ========================= Refs =========================
  89. var selectorRef = (0, _usePickerRef.default)(ref);
  90. // ========================= Util =========================
  91. function pickerParam(values) {
  92. if (values === null) {
  93. return null;
  94. }
  95. return multiple ? values : values[0];
  96. }
  97. var toggleDates = (0, _useToggleDates.default)(generateConfig, locale, internalPicker);
  98. // ========================= Open =========================
  99. var _useOpen = (0, _useOpen3.default)(open, defaultOpen, [disabled], onOpenChange),
  100. _useOpen2 = (0, _slicedToArray2.default)(_useOpen, 2),
  101. mergedOpen = _useOpen2[0],
  102. triggerOpen = _useOpen2[1];
  103. // ======================= Calendar =======================
  104. var onInternalCalendarChange = function onInternalCalendarChange(dates, dateStrings, info) {
  105. if (onCalendarChange) {
  106. var filteredInfo = (0, _objectSpread2.default)({}, info);
  107. delete filteredInfo.range;
  108. onCalendarChange(pickerParam(dates), pickerParam(dateStrings), filteredInfo);
  109. }
  110. };
  111. var onInternalOk = function onInternalOk(dates) {
  112. onOk === null || onOk === void 0 || onOk(pickerParam(dates));
  113. };
  114. // ======================== Values ========================
  115. var _useInnerValue = (0, _useRangeValue3.useInnerValue)(generateConfig, locale, formatList, false, order, defaultValue, value, onInternalCalendarChange, onInternalOk),
  116. _useInnerValue2 = (0, _slicedToArray2.default)(_useInnerValue, 5),
  117. mergedValue = _useInnerValue2[0],
  118. setInnerValue = _useInnerValue2[1],
  119. getCalendarValue = _useInnerValue2[2],
  120. triggerCalendarChange = _useInnerValue2[3],
  121. triggerOk = _useInnerValue2[4];
  122. var calendarValue = getCalendarValue();
  123. // ======================== Active ========================
  124. // In SinglePicker, we will always get `activeIndex` is 0.
  125. var _useRangeActive = (0, _useRangeActive3.default)([disabled]),
  126. _useRangeActive2 = (0, _slicedToArray2.default)(_useRangeActive, 4),
  127. focused = _useRangeActive2[0],
  128. triggerFocus = _useRangeActive2[1],
  129. lastOperation = _useRangeActive2[2],
  130. activeIndex = _useRangeActive2[3];
  131. var onSharedFocus = function onSharedFocus(event) {
  132. triggerFocus(true);
  133. onFocus === null || onFocus === void 0 || onFocus(event, {});
  134. };
  135. var onSharedBlur = function onSharedBlur(event) {
  136. triggerFocus(false);
  137. onBlur === null || onBlur === void 0 || onBlur(event, {});
  138. };
  139. // ========================= Mode =========================
  140. var _useMergedState = (0, _rcUtil.useMergedState)(picker, {
  141. value: mode
  142. }),
  143. _useMergedState2 = (0, _slicedToArray2.default)(_useMergedState, 2),
  144. mergedMode = _useMergedState2[0],
  145. setMode = _useMergedState2[1];
  146. /** Extends from `mergedMode` to patch `datetime` mode */
  147. var internalMode = mergedMode === 'date' && showTime ? 'datetime' : mergedMode;
  148. // ======================= Show Now =======================
  149. var mergedShowNow = (0, _useShowNow.default)(picker, mergedMode, showNow, showToday);
  150. // ======================== Value =========================
  151. var onInternalChange = onChange && function (dates, dateStrings) {
  152. onChange(pickerParam(dates), pickerParam(dateStrings));
  153. };
  154. var _useRangeValue = (0, _useRangeValue3.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, filledProps), {}, {
  155. onChange: onInternalChange
  156. }), mergedValue, setInnerValue, getCalendarValue, triggerCalendarChange, [],
  157. //disabled,
  158. formatList, focused, mergedOpen, isInvalidateDate),
  159. _useRangeValue2 = (0, _slicedToArray2.default)(_useRangeValue, 2),
  160. /** Trigger `onChange` directly without check `disabledDate` */
  161. triggerSubmitChange = _useRangeValue2[1];
  162. // ======================= Validate =======================
  163. var _useFieldsInvalidate = (0, _useFieldsInvalidate3.default)(calendarValue, isInvalidateDate),
  164. _useFieldsInvalidate2 = (0, _slicedToArray2.default)(_useFieldsInvalidate, 2),
  165. submitInvalidates = _useFieldsInvalidate2[0],
  166. onSelectorInvalid = _useFieldsInvalidate2[1];
  167. var submitInvalidate = React.useMemo(function () {
  168. return submitInvalidates.some(function (invalidated) {
  169. return invalidated;
  170. });
  171. }, [submitInvalidates]);
  172. // ===================== Picker Value =====================
  173. // Proxy to single pickerValue
  174. var onInternalPickerValueChange = function onInternalPickerValueChange(dates, info) {
  175. if (onPickerValueChange) {
  176. var cleanInfo = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, info), {}, {
  177. mode: info.mode[0]
  178. });
  179. delete cleanInfo.range;
  180. onPickerValueChange(dates[0], cleanInfo);
  181. }
  182. };
  183. var _useRangePickerValue = (0, _useRangePickerValue3.default)(generateConfig, locale, calendarValue, [mergedMode], mergedOpen, activeIndex, internalPicker, false,
  184. // multiplePanel,
  185. defaultPickerValue, pickerValue, (0, _miscUtil.toArray)(showTime === null || showTime === void 0 ? void 0 : showTime.defaultOpenValue), onInternalPickerValueChange, minDate, maxDate),
  186. _useRangePickerValue2 = (0, _slicedToArray2.default)(_useRangePickerValue, 2),
  187. currentPickerValue = _useRangePickerValue2[0],
  188. setCurrentPickerValue = _useRangePickerValue2[1];
  189. // >>> Mode need wait for `pickerValue`
  190. var triggerModeChange = (0, _rcUtil.useEvent)(function (nextPickerValue, nextMode, triggerEvent) {
  191. setMode(nextMode);
  192. // Compatible with `onPanelChange`
  193. if (onPanelChange && triggerEvent !== false) {
  194. var lastPickerValue = nextPickerValue || calendarValue[calendarValue.length - 1];
  195. onPanelChange(lastPickerValue, nextMode);
  196. }
  197. });
  198. // ======================== Submit ========================
  199. /**
  200. * Different with RangePicker, confirm should check `multiple` logic.
  201. * This will never provide `date` instead.
  202. */
  203. var triggerConfirm = function triggerConfirm() {
  204. triggerSubmitChange(getCalendarValue());
  205. triggerOpen(false, {
  206. force: true
  207. });
  208. };
  209. // ======================== Click =========================
  210. var onSelectorClick = function onSelectorClick(event) {
  211. if (!disabled && !selectorRef.current.nativeElement.contains(document.activeElement)) {
  212. // Click to focus the enabled input
  213. selectorRef.current.focus();
  214. }
  215. triggerOpen(true);
  216. onClick === null || onClick === void 0 || onClick(event);
  217. };
  218. var onSelectorClear = function onSelectorClear() {
  219. triggerSubmitChange(null);
  220. triggerOpen(false, {
  221. force: true
  222. });
  223. };
  224. // ======================== Hover =========================
  225. var _React$useState = React.useState(null),
  226. _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
  227. hoverSource = _React$useState2[0],
  228. setHoverSource = _React$useState2[1];
  229. var _React$useState3 = React.useState(null),
  230. _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
  231. internalHoverValue = _React$useState4[0],
  232. setInternalHoverValue = _React$useState4[1];
  233. var hoverValues = React.useMemo(function () {
  234. var values = [internalHoverValue].concat((0, _toConsumableArray2.default)(calendarValue)).filter(function (date) {
  235. return date;
  236. });
  237. return multiple ? values : values.slice(0, 1);
  238. }, [calendarValue, internalHoverValue, multiple]);
  239. // Selector values is different with RangePicker
  240. // which can not use `hoverValue` directly
  241. var selectorValues = React.useMemo(function () {
  242. if (!multiple && internalHoverValue) {
  243. return [internalHoverValue];
  244. }
  245. return calendarValue.filter(function (date) {
  246. return date;
  247. });
  248. }, [calendarValue, internalHoverValue, multiple]);
  249. // Clean up `internalHoverValues` when closed
  250. React.useEffect(function () {
  251. if (!mergedOpen) {
  252. setInternalHoverValue(null);
  253. }
  254. }, [mergedOpen]);
  255. // ========================================================
  256. // == Panels ==
  257. // ========================================================
  258. // ======================= Presets ========================
  259. var presetList = (0, _usePresets.default)(presets);
  260. var onPresetHover = function onPresetHover(nextValue) {
  261. setInternalHoverValue(nextValue);
  262. setHoverSource('preset');
  263. };
  264. // TODO: handle this
  265. var onPresetSubmit = function onPresetSubmit(nextValue) {
  266. var nextCalendarValues = multiple ? toggleDates(getCalendarValue(), nextValue) : [nextValue];
  267. var passed = triggerSubmitChange(nextCalendarValues);
  268. if (passed && !multiple) {
  269. triggerOpen(false, {
  270. force: true
  271. });
  272. }
  273. };
  274. var onNow = function onNow(now) {
  275. onPresetSubmit(now);
  276. };
  277. // ======================== Panel =========================
  278. var onPanelHover = function onPanelHover(date) {
  279. setInternalHoverValue(date);
  280. setHoverSource('cell');
  281. };
  282. // >>> Focus
  283. var onPanelFocus = function onPanelFocus(event) {
  284. triggerOpen(true);
  285. onSharedFocus(event);
  286. };
  287. // >>> Calendar
  288. var onPanelSelect = function onPanelSelect(date) {
  289. lastOperation('panel');
  290. // Not change values if multiple and current panel is to match with picker
  291. if (multiple && internalMode !== picker) {
  292. return;
  293. }
  294. var nextValues = multiple ? toggleDates(getCalendarValue(), date) : [date];
  295. // Only trigger calendar event but not update internal `calendarValue` state
  296. triggerCalendarChange(nextValues);
  297. // >>> Trigger next active if !needConfirm
  298. // Fully logic check `useRangeValue` hook
  299. if (!needConfirm && !complexPicker && internalPicker === internalMode) {
  300. triggerConfirm();
  301. }
  302. };
  303. // >>> Close
  304. var onPopupClose = function onPopupClose() {
  305. // Close popup
  306. triggerOpen(false);
  307. };
  308. // >>> cellRender
  309. var onInternalCellRender = (0, _useCellRender.default)(cellRender, dateRender, monthCellRender);
  310. // >>> invalid
  311. var panelProps = React.useMemo(function () {
  312. var domProps = (0, _pickAttrs.default)(filledProps, false);
  313. var restProps = (0, _omit.default)(filledProps, [].concat((0, _toConsumableArray2.default)(Object.keys(domProps)), ['onChange', 'onCalendarChange', 'style', 'className', 'onPanelChange']));
  314. return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, restProps), {}, {
  315. multiple: filledProps.multiple
  316. });
  317. }, [filledProps]);
  318. // >>> Render
  319. var panel = /*#__PURE__*/React.createElement(_Popup.default, (0, _extends2.default)({}, panelProps, {
  320. showNow: mergedShowNow,
  321. showTime: showTime
  322. // Disabled
  323. ,
  324. disabledDate: disabledDate
  325. // Focus
  326. ,
  327. onFocus: onPanelFocus,
  328. onBlur: onSharedBlur
  329. // Mode
  330. ,
  331. picker: picker,
  332. mode: mergedMode,
  333. internalMode: internalMode,
  334. onPanelChange: triggerModeChange
  335. // Value
  336. ,
  337. format: maskFormat,
  338. value: calendarValue,
  339. isInvalid: isInvalidateDate,
  340. onChange: null,
  341. onSelect: onPanelSelect
  342. // PickerValue
  343. ,
  344. pickerValue: currentPickerValue,
  345. defaultOpenValue: showTime === null || showTime === void 0 ? void 0 : showTime.defaultOpenValue,
  346. onPickerValueChange: setCurrentPickerValue
  347. // Hover
  348. ,
  349. hoverValue: hoverValues,
  350. onHover: onPanelHover
  351. // Submit
  352. ,
  353. needConfirm: needConfirm,
  354. onSubmit: triggerConfirm,
  355. onOk: triggerOk
  356. // Preset
  357. ,
  358. presets: presetList,
  359. onPresetHover: onPresetHover,
  360. onPresetSubmit: onPresetSubmit,
  361. onNow: onNow
  362. // Render
  363. ,
  364. cellRender: onInternalCellRender
  365. }));
  366. // ========================================================
  367. // == Selector ==
  368. // ========================================================
  369. // ======================== Change ========================
  370. var onSelectorChange = function onSelectorChange(date) {
  371. triggerCalendarChange(date);
  372. };
  373. var onSelectorInputChange = function onSelectorInputChange() {
  374. lastOperation('input');
  375. };
  376. // ======================= Selector =======================
  377. var onSelectorFocus = function onSelectorFocus(event) {
  378. lastOperation('input');
  379. triggerOpen(true, {
  380. inherit: true
  381. });
  382. // setActiveIndex(index);
  383. onSharedFocus(event);
  384. };
  385. var onSelectorBlur = function onSelectorBlur(event) {
  386. triggerOpen(false);
  387. onSharedBlur(event);
  388. };
  389. var onSelectorKeyDown = function onSelectorKeyDown(event, preventDefault) {
  390. if (event.key === 'Tab') {
  391. triggerConfirm();
  392. }
  393. onKeyDown === null || onKeyDown === void 0 || onKeyDown(event, preventDefault);
  394. };
  395. // ======================= Context ========================
  396. var context = React.useMemo(function () {
  397. return {
  398. prefixCls: prefixCls,
  399. locale: locale,
  400. generateConfig: generateConfig,
  401. button: components.button,
  402. input: components.input
  403. };
  404. }, [prefixCls, locale, generateConfig, components.button, components.input]);
  405. // ======================== Effect ========================
  406. // >>> Mode
  407. // Reset for every active
  408. (0, _useLayoutEffect.default)(function () {
  409. if (mergedOpen && activeIndex !== undefined) {
  410. // Legacy compatible. This effect update should not trigger `onPanelChange`
  411. triggerModeChange(null, picker, false);
  412. }
  413. }, [mergedOpen, activeIndex, picker]);
  414. // >>> For complex picker, we need check if need to focus next one
  415. (0, _useLayoutEffect.default)(function () {
  416. var lastOp = lastOperation();
  417. // Trade as confirm on field leave
  418. if (!mergedOpen && lastOp === 'input') {
  419. triggerOpen(false);
  420. triggerConfirm();
  421. }
  422. // Submit with complex picker
  423. if (!mergedOpen && complexPicker && !needConfirm && lastOp === 'panel') {
  424. triggerConfirm();
  425. }
  426. }, [mergedOpen]);
  427. // ======================== Render ========================
  428. return /*#__PURE__*/React.createElement(_context.default.Provider, {
  429. value: context
  430. }, /*#__PURE__*/React.createElement(_PickerTrigger.default, (0, _extends2.default)({}, (0, _util.pickTriggerProps)(filledProps), {
  431. popupElement: panel,
  432. popupStyle: styles.popup,
  433. popupClassName: classNames.popup
  434. // Visible
  435. ,
  436. visible: mergedOpen,
  437. onClose: onPopupClose
  438. }), /*#__PURE__*/React.createElement(_SingleSelector.default
  439. // Shared
  440. , (0, _extends2.default)({}, filledProps, {
  441. // Ref
  442. ref: selectorRef
  443. // Icon
  444. ,
  445. suffixIcon: suffixIcon,
  446. removeIcon: removeIcon
  447. // Active
  448. ,
  449. activeHelp: !!internalHoverValue,
  450. allHelp: !!internalHoverValue && hoverSource === 'preset',
  451. focused: focused,
  452. onFocus: onSelectorFocus,
  453. onBlur: onSelectorBlur,
  454. onKeyDown: onSelectorKeyDown,
  455. onSubmit: triggerConfirm
  456. // Change
  457. ,
  458. value: selectorValues,
  459. maskFormat: maskFormat,
  460. onChange: onSelectorChange,
  461. onInputChange: onSelectorInputChange,
  462. internalPicker: internalPicker
  463. // Format
  464. ,
  465. format: formatList,
  466. inputReadOnly: inputReadOnly
  467. // Disabled
  468. ,
  469. disabled: disabled
  470. // Open
  471. ,
  472. open: mergedOpen,
  473. onOpenChange: triggerOpen
  474. // Click
  475. ,
  476. onClick: onSelectorClick,
  477. onClear: onSelectorClear
  478. // Invalid
  479. ,
  480. invalid: submitInvalidate,
  481. onInvalid: function onInvalid(invalid) {
  482. // Only `single` mode support type date.
  483. // `multiple` mode can not typing.
  484. onSelectorInvalid(invalid, 0);
  485. }
  486. }))));
  487. }
  488. var RefPicker = /*#__PURE__*/React.forwardRef(Picker);
  489. if (process.env.NODE_ENV !== 'production') {
  490. RefPicker.displayName = 'RefPicker';
  491. }
  492. var _default = exports.default = RefPicker;