index.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 = Popup;
  8. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
  9. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  10. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  11. var _classnames = _interopRequireDefault(require("classnames"));
  12. var _rcResizeObserver = _interopRequireDefault(require("rc-resize-observer"));
  13. var React = _interopRequireWildcard(require("react"));
  14. var _miscUtil = require("../../utils/miscUtil");
  15. var _context = _interopRequireDefault(require("../context"));
  16. var _Footer = _interopRequireDefault(require("./Footer"));
  17. var _PopupPanel = _interopRequireDefault(require("./PopupPanel"));
  18. var _PresetPanel = _interopRequireDefault(require("./PresetPanel"));
  19. function Popup(props) {
  20. var panelRender = props.panelRender,
  21. internalMode = props.internalMode,
  22. picker = props.picker,
  23. showNow = props.showNow,
  24. range = props.range,
  25. multiple = props.multiple,
  26. _props$activeInfo = props.activeInfo,
  27. activeInfo = _props$activeInfo === void 0 ? [0, 0, 0] : _props$activeInfo,
  28. presets = props.presets,
  29. onPresetHover = props.onPresetHover,
  30. onPresetSubmit = props.onPresetSubmit,
  31. onFocus = props.onFocus,
  32. onBlur = props.onBlur,
  33. onPanelMouseDown = props.onPanelMouseDown,
  34. direction = props.direction,
  35. value = props.value,
  36. onSelect = props.onSelect,
  37. isInvalid = props.isInvalid,
  38. defaultOpenValue = props.defaultOpenValue,
  39. onOk = props.onOk,
  40. onSubmit = props.onSubmit;
  41. var _React$useContext = React.useContext(_context.default),
  42. prefixCls = _React$useContext.prefixCls;
  43. var panelPrefixCls = "".concat(prefixCls, "-panel");
  44. var rtl = direction === 'rtl';
  45. // ========================= Refs =========================
  46. var arrowRef = React.useRef(null);
  47. var wrapperRef = React.useRef(null);
  48. // ======================== Offset ========================
  49. var _React$useState = React.useState(0),
  50. _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
  51. containerWidth = _React$useState2[0],
  52. setContainerWidth = _React$useState2[1];
  53. var _React$useState3 = React.useState(0),
  54. _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
  55. containerOffset = _React$useState4[0],
  56. setContainerOffset = _React$useState4[1];
  57. var _React$useState5 = React.useState(0),
  58. _React$useState6 = (0, _slicedToArray2.default)(_React$useState5, 2),
  59. arrowOffset = _React$useState6[0],
  60. setArrowOffset = _React$useState6[1];
  61. var onResize = function onResize(info) {
  62. if (info.width) {
  63. setContainerWidth(info.width);
  64. }
  65. };
  66. var _activeInfo = (0, _slicedToArray2.default)(activeInfo, 3),
  67. activeInputLeft = _activeInfo[0],
  68. activeInputRight = _activeInfo[1],
  69. selectorWidth = _activeInfo[2];
  70. var _React$useState7 = React.useState(0),
  71. _React$useState8 = (0, _slicedToArray2.default)(_React$useState7, 2),
  72. retryTimes = _React$useState8[0],
  73. setRetryTimes = _React$useState8[1];
  74. React.useEffect(function () {
  75. setRetryTimes(10);
  76. }, [activeInputLeft]);
  77. React.useEffect(function () {
  78. // `activeOffset` is always align with the active input element
  79. // So we need only check container contains the `activeOffset`
  80. if (range && wrapperRef.current) {
  81. var _arrowRef$current;
  82. // Offset in case container has border radius
  83. var arrowWidth = ((_arrowRef$current = arrowRef.current) === null || _arrowRef$current === void 0 ? void 0 : _arrowRef$current.offsetWidth) || 0;
  84. // Arrow Offset
  85. var wrapperRect = wrapperRef.current.getBoundingClientRect();
  86. if (!wrapperRect.height || wrapperRect.right < 0) {
  87. setRetryTimes(function (times) {
  88. return Math.max(0, times - 1);
  89. });
  90. return;
  91. }
  92. var nextArrowOffset = (rtl ? activeInputRight - arrowWidth : activeInputLeft) - wrapperRect.left;
  93. setArrowOffset(nextArrowOffset);
  94. // Container Offset
  95. if (containerWidth && containerWidth < selectorWidth) {
  96. var offset = rtl ? wrapperRect.right - (activeInputRight - arrowWidth + containerWidth) : activeInputLeft + arrowWidth - wrapperRect.left - containerWidth;
  97. var safeOffset = Math.max(0, offset);
  98. setContainerOffset(safeOffset);
  99. } else {
  100. setContainerOffset(0);
  101. }
  102. }
  103. }, [retryTimes, rtl, containerWidth, activeInputLeft, activeInputRight, selectorWidth, range]);
  104. // ======================== Custom ========================
  105. function filterEmpty(list) {
  106. return list.filter(function (item) {
  107. return item;
  108. });
  109. }
  110. var valueList = React.useMemo(function () {
  111. return filterEmpty((0, _miscUtil.toArray)(value));
  112. }, [value]);
  113. var isTimePickerEmptyValue = picker === 'time' && !valueList.length;
  114. var footerSubmitValue = React.useMemo(function () {
  115. if (isTimePickerEmptyValue) {
  116. return filterEmpty([defaultOpenValue]);
  117. }
  118. return valueList;
  119. }, [isTimePickerEmptyValue, valueList, defaultOpenValue]);
  120. var popupPanelValue = isTimePickerEmptyValue ? defaultOpenValue : valueList;
  121. var disableSubmit = React.useMemo(function () {
  122. // Empty is invalid
  123. if (!footerSubmitValue.length) {
  124. return true;
  125. }
  126. return footerSubmitValue.some(function (val) {
  127. return isInvalid(val);
  128. });
  129. }, [footerSubmitValue, isInvalid]);
  130. var onFooterSubmit = function onFooterSubmit() {
  131. // For TimePicker, we will additional trigger the value update
  132. if (isTimePickerEmptyValue) {
  133. onSelect(defaultOpenValue);
  134. }
  135. onOk();
  136. onSubmit();
  137. };
  138. var mergedNodes = /*#__PURE__*/React.createElement("div", {
  139. className: "".concat(prefixCls, "-panel-layout")
  140. }, /*#__PURE__*/React.createElement(_PresetPanel.default, {
  141. prefixCls: prefixCls,
  142. presets: presets,
  143. onClick: onPresetSubmit,
  144. onHover: onPresetHover
  145. }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_PopupPanel.default, (0, _extends2.default)({}, props, {
  146. value: popupPanelValue
  147. })), /*#__PURE__*/React.createElement(_Footer.default, (0, _extends2.default)({}, props, {
  148. showNow: multiple ? false : showNow,
  149. invalid: disableSubmit,
  150. onSubmit: onFooterSubmit
  151. }))));
  152. if (panelRender) {
  153. mergedNodes = panelRender(mergedNodes);
  154. }
  155. // ======================== Render ========================
  156. var containerPrefixCls = "".concat(panelPrefixCls, "-container");
  157. var marginLeft = 'marginLeft';
  158. var marginRight = 'marginRight';
  159. // Container
  160. var renderNode = /*#__PURE__*/React.createElement("div", {
  161. onMouseDown: onPanelMouseDown,
  162. tabIndex: -1,
  163. className: (0, _classnames.default)(containerPrefixCls, // Used for Today Button style, safe to remove if no need
  164. "".concat(prefixCls, "-").concat(internalMode, "-panel-container")),
  165. style: (0, _defineProperty2.default)((0, _defineProperty2.default)({}, rtl ? marginRight : marginLeft, containerOffset), rtl ? marginLeft : marginRight, 'auto')
  166. // Still wish not to lose focus on mouse down
  167. // onMouseDown={(e) => {
  168. // // e.preventDefault();
  169. // }}
  170. ,
  171. onFocus: onFocus,
  172. onBlur: onBlur
  173. }, mergedNodes);
  174. if (range) {
  175. renderNode = /*#__PURE__*/React.createElement("div", {
  176. onMouseDown: onPanelMouseDown,
  177. ref: wrapperRef,
  178. className: (0, _classnames.default)("".concat(prefixCls, "-range-wrapper"), "".concat(prefixCls, "-").concat(picker, "-range-wrapper"))
  179. }, /*#__PURE__*/React.createElement("div", {
  180. ref: arrowRef,
  181. className: "".concat(prefixCls, "-range-arrow"),
  182. style: {
  183. left: arrowOffset
  184. }
  185. }), /*#__PURE__*/React.createElement(_rcResizeObserver.default, {
  186. onResize: onResize
  187. }, renderNode));
  188. }
  189. return renderNode;
  190. }