dropdown.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. "use strict";
  2. "use client";
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  4. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
  5. Object.defineProperty(exports, "__esModule", {
  6. value: true
  7. });
  8. exports.default = void 0;
  9. var React = _interopRequireWildcard(require("react"));
  10. var _LeftOutlined = _interopRequireDefault(require("@ant-design/icons/LeftOutlined"));
  11. var _RightOutlined = _interopRequireDefault(require("@ant-design/icons/RightOutlined"));
  12. var _classnames = _interopRequireDefault(require("classnames"));
  13. var _rcDropdown = _interopRequireDefault(require("rc-dropdown"));
  14. var _useEvent = _interopRequireDefault(require("rc-util/lib/hooks/useEvent"));
  15. var _useMergedState = _interopRequireDefault(require("rc-util/lib/hooks/useMergedState"));
  16. var _omit = _interopRequireDefault(require("rc-util/lib/omit"));
  17. var _useZIndex = require("../_util/hooks/useZIndex");
  18. var _isPrimitive = _interopRequireDefault(require("../_util/isPrimitive"));
  19. var _placements = _interopRequireDefault(require("../_util/placements"));
  20. var _PurePanel = _interopRequireDefault(require("../_util/PurePanel"));
  21. var _reactNode = require("../_util/reactNode");
  22. var _warning = require("../_util/warning");
  23. var _zindexContext = _interopRequireDefault(require("../_util/zindexContext"));
  24. var _configProvider = require("../config-provider");
  25. var _useCSSVarCls = _interopRequireDefault(require("../config-provider/hooks/useCSSVarCls"));
  26. var _menu = _interopRequireDefault(require("../menu"));
  27. var _OverrideContext = require("../menu/OverrideContext");
  28. var _internal = require("../theme/internal");
  29. var _style = _interopRequireDefault(require("./style"));
  30. const _Placements = ['topLeft', 'topCenter', 'topRight', 'bottomLeft', 'bottomCenter', 'bottomRight', 'top', 'bottom'];
  31. const Dropdown = props => {
  32. var _a;
  33. const {
  34. menu,
  35. arrow,
  36. prefixCls: customizePrefixCls,
  37. children,
  38. trigger,
  39. disabled,
  40. dropdownRender,
  41. popupRender,
  42. getPopupContainer,
  43. overlayClassName,
  44. rootClassName,
  45. overlayStyle,
  46. open,
  47. onOpenChange,
  48. // Deprecated
  49. visible,
  50. onVisibleChange,
  51. mouseEnterDelay = 0.15,
  52. mouseLeaveDelay = 0.1,
  53. autoAdjustOverflow = true,
  54. placement = '',
  55. overlay,
  56. transitionName,
  57. destroyOnHidden,
  58. destroyPopupOnHide
  59. } = props;
  60. const {
  61. getPopupContainer: getContextPopupContainer,
  62. getPrefixCls,
  63. direction,
  64. dropdown
  65. } = React.useContext(_configProvider.ConfigContext);
  66. const mergedPopupRender = popupRender || dropdownRender;
  67. // Warning for deprecated usage
  68. const warning = (0, _warning.devUseWarning)('Dropdown');
  69. if (process.env.NODE_ENV !== 'production') {
  70. const deprecatedProps = {
  71. visible: 'open',
  72. onVisibleChange: 'onOpenChange',
  73. overlay: 'menu',
  74. dropdownRender: 'popupRender',
  75. destroyPopupOnHide: 'destroyOnHidden'
  76. };
  77. Object.entries(deprecatedProps).forEach(([deprecatedName, newName]) => {
  78. warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
  79. });
  80. if (placement.includes('Center')) {
  81. warning.deprecated(!placement.includes('Center'), `placement: ${placement}`, `placement: ${placement.slice(0, placement.indexOf('Center'))}`);
  82. }
  83. }
  84. const memoTransitionName = React.useMemo(() => {
  85. const rootPrefixCls = getPrefixCls();
  86. if (transitionName !== undefined) {
  87. return transitionName;
  88. }
  89. if (placement.includes('top')) {
  90. return `${rootPrefixCls}-slide-down`;
  91. }
  92. return `${rootPrefixCls}-slide-up`;
  93. }, [getPrefixCls, placement, transitionName]);
  94. const memoPlacement = React.useMemo(() => {
  95. if (!placement) {
  96. return direction === 'rtl' ? 'bottomRight' : 'bottomLeft';
  97. }
  98. if (placement.includes('Center')) {
  99. return placement.slice(0, placement.indexOf('Center'));
  100. }
  101. return placement;
  102. }, [placement, direction]);
  103. const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
  104. const rootCls = (0, _useCSSVarCls.default)(prefixCls);
  105. const [wrapCSSVar, hashId, cssVarCls] = (0, _style.default)(prefixCls, rootCls);
  106. const [, token] = (0, _internal.useToken)();
  107. const child = React.Children.only((0, _isPrimitive.default)(children) ? /*#__PURE__*/React.createElement("span", null, children) : children);
  108. const popupTrigger = (0, _reactNode.cloneElement)(child, {
  109. className: (0, _classnames.default)(`${prefixCls}-trigger`, {
  110. [`${prefixCls}-rtl`]: direction === 'rtl'
  111. }, child.props.className),
  112. disabled: (_a = child.props.disabled) !== null && _a !== void 0 ? _a : disabled
  113. });
  114. const triggerActions = disabled ? [] : trigger;
  115. const alignPoint = !!(triggerActions === null || triggerActions === void 0 ? void 0 : triggerActions.includes('contextMenu'));
  116. // =========================== Open ============================
  117. const [mergedOpen, setOpen] = (0, _useMergedState.default)(false, {
  118. value: open !== null && open !== void 0 ? open : visible
  119. });
  120. const onInnerOpenChange = (0, _useEvent.default)(nextOpen => {
  121. onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(nextOpen, {
  122. source: 'trigger'
  123. });
  124. onVisibleChange === null || onVisibleChange === void 0 ? void 0 : onVisibleChange(nextOpen);
  125. setOpen(nextOpen);
  126. });
  127. // =========================== Overlay ============================
  128. const overlayClassNameCustomized = (0, _classnames.default)(overlayClassName, rootClassName, hashId, cssVarCls, rootCls, dropdown === null || dropdown === void 0 ? void 0 : dropdown.className, {
  129. [`${prefixCls}-rtl`]: direction === 'rtl'
  130. });
  131. const builtinPlacements = (0, _placements.default)({
  132. arrowPointAtCenter: typeof arrow === 'object' && arrow.pointAtCenter,
  133. autoAdjustOverflow,
  134. offset: token.marginXXS,
  135. arrowWidth: arrow ? token.sizePopupArrow : 0,
  136. borderRadius: token.borderRadius
  137. });
  138. const onMenuClick = (0, _useEvent.default)(() => {
  139. if ((menu === null || menu === void 0 ? void 0 : menu.selectable) && (menu === null || menu === void 0 ? void 0 : menu.multiple)) {
  140. return;
  141. }
  142. onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false, {
  143. source: 'menu'
  144. });
  145. setOpen(false);
  146. });
  147. const renderOverlay = () => {
  148. // rc-dropdown already can process the function of overlay, but we have check logic here.
  149. // So we need render the element to check and pass back to rc-dropdown.
  150. let overlayNode;
  151. if (menu === null || menu === void 0 ? void 0 : menu.items) {
  152. overlayNode = /*#__PURE__*/React.createElement(_menu.default, Object.assign({}, menu));
  153. } else if (typeof overlay === 'function') {
  154. overlayNode = overlay();
  155. } else {
  156. overlayNode = overlay;
  157. }
  158. if (mergedPopupRender) {
  159. overlayNode = mergedPopupRender(overlayNode);
  160. }
  161. overlayNode = React.Children.only(typeof overlayNode === 'string' ? /*#__PURE__*/React.createElement("span", null, overlayNode) : overlayNode);
  162. return /*#__PURE__*/React.createElement(_OverrideContext.OverrideProvider, {
  163. prefixCls: `${prefixCls}-menu`,
  164. rootClassName: (0, _classnames.default)(cssVarCls, rootCls),
  165. expandIcon: /*#__PURE__*/React.createElement("span", {
  166. className: `${prefixCls}-menu-submenu-arrow`
  167. }, direction === 'rtl' ? (/*#__PURE__*/React.createElement(_LeftOutlined.default, {
  168. className: `${prefixCls}-menu-submenu-arrow-icon`
  169. })) : (/*#__PURE__*/React.createElement(_RightOutlined.default, {
  170. className: `${prefixCls}-menu-submenu-arrow-icon`
  171. }))),
  172. mode: "vertical",
  173. selectable: false,
  174. onClick: onMenuClick,
  175. validator: ({
  176. mode
  177. }) => {
  178. // Warning if use other mode
  179. process.env.NODE_ENV !== "production" ? warning(!mode || mode === 'vertical', 'usage', `mode="${mode}" is not supported for Dropdown's Menu.`) : void 0;
  180. }
  181. }, overlayNode);
  182. };
  183. // =========================== zIndex ============================
  184. const [zIndex, contextZIndex] = (0, _useZIndex.useZIndex)('Dropdown', overlayStyle === null || overlayStyle === void 0 ? void 0 : overlayStyle.zIndex);
  185. // ============================ Render ============================
  186. let renderNode = /*#__PURE__*/React.createElement(_rcDropdown.default, Object.assign({
  187. alignPoint: alignPoint
  188. }, (0, _omit.default)(props, ['rootClassName']), {
  189. mouseEnterDelay: mouseEnterDelay,
  190. mouseLeaveDelay: mouseLeaveDelay,
  191. visible: mergedOpen,
  192. builtinPlacements: builtinPlacements,
  193. arrow: !!arrow,
  194. overlayClassName: overlayClassNameCustomized,
  195. prefixCls: prefixCls,
  196. getPopupContainer: getPopupContainer || getContextPopupContainer,
  197. transitionName: memoTransitionName,
  198. trigger: triggerActions,
  199. overlay: renderOverlay,
  200. placement: memoPlacement,
  201. onVisibleChange: onInnerOpenChange,
  202. overlayStyle: Object.assign(Object.assign(Object.assign({}, dropdown === null || dropdown === void 0 ? void 0 : dropdown.style), overlayStyle), {
  203. zIndex
  204. }),
  205. autoDestroy: destroyOnHidden !== null && destroyOnHidden !== void 0 ? destroyOnHidden : destroyPopupOnHide
  206. }), popupTrigger);
  207. if (zIndex) {
  208. renderNode = /*#__PURE__*/React.createElement(_zindexContext.default.Provider, {
  209. value: contextZIndex
  210. }, renderNode);
  211. }
  212. return wrapCSSVar(renderNode);
  213. };
  214. // We don't care debug panel
  215. const PurePanel = (0, _PurePanel.default)(Dropdown, 'align', undefined, 'dropdown', prefixCls => prefixCls);
  216. /* istanbul ignore next */
  217. const WrapPurePanel = props => (/*#__PURE__*/React.createElement(PurePanel, Object.assign({}, props), /*#__PURE__*/React.createElement("span", null)));
  218. Dropdown._InternalPanelDoNotUseOrYouWillBeFired = WrapPurePanel;
  219. if (process.env.NODE_ENV !== 'production') {
  220. Dropdown.displayName = 'Dropdown';
  221. }
  222. var _default = exports.default = Dropdown;