Trigger.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import { Fragment as _Fragment, createVNode as _createVNode, resolveDirective as _resolveDirective } from "vue";
  3. import { computed, defineComponent, inject, provide, ref } from 'vue';
  4. import PropTypes from '../_util/vue-types';
  5. import contains from '../vc-util/Dom/contains';
  6. import raf from '../_util/raf';
  7. import { hasProp, getComponent as _getComponent, getEvents, filterEmpty, getSlot, findDOMNode } from '../_util/props-util';
  8. import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout';
  9. import addEventListener from '../vc-util/Dom/addEventListener';
  10. import Popup from './Popup';
  11. import { getAlignFromPlacement, getAlignPopupClassName } from './utils/alignUtil';
  12. import BaseMixin from '../_util/BaseMixin';
  13. import Portal from '../_util/Portal';
  14. import classNames from '../_util/classNames';
  15. import { cloneElement } from '../_util/vnode';
  16. import supportsPassive from '../_util/supportsPassive';
  17. import { useInjectTrigger, useProvidePortal } from './context';
  18. function noop() {}
  19. function returnEmptyString() {
  20. return '';
  21. }
  22. function returnDocument(element) {
  23. if (element) {
  24. return element.ownerDocument;
  25. }
  26. return window.document;
  27. }
  28. var ALL_HANDLERS = ['onClick', 'onMousedown', 'onTouchstart', 'onMouseenter', 'onMouseleave', 'onFocus', 'onBlur', 'onContextmenu'];
  29. export default defineComponent({
  30. compatConfig: {
  31. MODE: 3
  32. },
  33. name: 'Trigger',
  34. mixins: [BaseMixin],
  35. inheritAttrs: false,
  36. props: {
  37. action: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]).def([]),
  38. showAction: PropTypes.any.def([]),
  39. hideAction: PropTypes.any.def([]),
  40. getPopupClassNameFromAlign: PropTypes.any.def(returnEmptyString),
  41. onPopupVisibleChange: Function,
  42. afterPopupVisibleChange: PropTypes.func.def(noop),
  43. popup: PropTypes.any,
  44. popupStyle: {
  45. type: Object,
  46. default: undefined
  47. },
  48. prefixCls: PropTypes.string.def('rc-trigger-popup'),
  49. popupClassName: PropTypes.string.def(''),
  50. popupPlacement: String,
  51. builtinPlacements: PropTypes.object,
  52. popupTransitionName: String,
  53. popupAnimation: PropTypes.any,
  54. mouseEnterDelay: PropTypes.number.def(0),
  55. mouseLeaveDelay: PropTypes.number.def(0.1),
  56. zIndex: Number,
  57. focusDelay: PropTypes.number.def(0),
  58. blurDelay: PropTypes.number.def(0.15),
  59. getPopupContainer: Function,
  60. getDocument: PropTypes.func.def(returnDocument),
  61. forceRender: {
  62. type: Boolean,
  63. default: undefined
  64. },
  65. destroyPopupOnHide: {
  66. type: Boolean,
  67. default: false
  68. },
  69. mask: {
  70. type: Boolean,
  71. default: false
  72. },
  73. maskClosable: {
  74. type: Boolean,
  75. default: true
  76. },
  77. // onPopupAlign: PropTypes.func.def(noop),
  78. popupAlign: PropTypes.object.def(function () {
  79. return {};
  80. }),
  81. popupVisible: {
  82. type: Boolean,
  83. default: undefined
  84. },
  85. defaultPopupVisible: {
  86. type: Boolean,
  87. default: false
  88. },
  89. maskTransitionName: String,
  90. maskAnimation: String,
  91. stretch: String,
  92. alignPoint: {
  93. type: Boolean,
  94. default: undefined
  95. },
  96. autoDestroy: {
  97. type: Boolean,
  98. default: false
  99. },
  100. mobile: Object,
  101. getTriggerDOMNode: Function,
  102. // portal context will change
  103. tryPopPortal: Boolean // no need reactive
  104. },
  105. setup: function setup(props) {
  106. var align = computed(function () {
  107. var popupPlacement = props.popupPlacement,
  108. popupAlign = props.popupAlign,
  109. builtinPlacements = props.builtinPlacements;
  110. if (popupPlacement && builtinPlacements) {
  111. return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign);
  112. }
  113. return popupAlign;
  114. });
  115. var _useInjectTrigger = useInjectTrigger(props.tryPopPortal),
  116. setPortal = _useInjectTrigger.setPortal,
  117. popPortal = _useInjectTrigger.popPortal;
  118. var popupRef = ref(null);
  119. var setPopupRef = function setPopupRef(val) {
  120. popupRef.value = val;
  121. };
  122. return {
  123. popPortal: popPortal,
  124. setPortal: setPortal,
  125. vcTriggerContext: inject('vcTriggerContext', {}),
  126. popupRef: popupRef,
  127. setPopupRef: setPopupRef,
  128. triggerRef: ref(null),
  129. align: align,
  130. focusTime: null,
  131. clickOutsideHandler: null,
  132. contextmenuOutsideHandler1: null,
  133. contextmenuOutsideHandler2: null,
  134. touchOutsideHandler: null,
  135. attachId: null,
  136. delayTimer: null,
  137. hasPopupMouseDown: false,
  138. preClickTime: null,
  139. preTouchTime: null,
  140. mouseDownTimeout: null,
  141. childOriginEvents: {}
  142. };
  143. },
  144. data: function data() {
  145. var _this = this,
  146. _this$setPortal;
  147. var props = this.$props;
  148. var popupVisible;
  149. if (this.popupVisible !== undefined) {
  150. popupVisible = !!props.popupVisible;
  151. } else {
  152. popupVisible = !!props.defaultPopupVisible;
  153. }
  154. ALL_HANDLERS.forEach(function (h) {
  155. _this["fire".concat(h)] = function (e) {
  156. _this.fireEvents(h, e);
  157. };
  158. });
  159. (_this$setPortal = this.setPortal) === null || _this$setPortal === void 0 ? void 0 : _this$setPortal.call(this, _createVNode(Portal, {
  160. "key": "portal",
  161. "getContainer": this.getContainer,
  162. "didUpdate": this.handlePortalUpdate
  163. }, {
  164. default: this.getComponent
  165. }));
  166. return {
  167. prevPopupVisible: popupVisible,
  168. sPopupVisible: popupVisible,
  169. point: null
  170. };
  171. },
  172. watch: {
  173. popupVisible: function popupVisible(val) {
  174. if (val !== undefined) {
  175. this.prevPopupVisible = this.sPopupVisible;
  176. this.sPopupVisible = val;
  177. }
  178. }
  179. },
  180. created: function created() {
  181. provide('vcTriggerContext', {
  182. onPopupMouseDown: this.onPopupMouseDown
  183. });
  184. useProvidePortal(this);
  185. },
  186. deactivated: function deactivated() {
  187. this.setPopupVisible(false);
  188. },
  189. mounted: function mounted() {
  190. var _this2 = this;
  191. this.$nextTick(function () {
  192. _this2.updatedCal();
  193. });
  194. },
  195. updated: function updated() {
  196. var _this3 = this;
  197. this.$nextTick(function () {
  198. _this3.updatedCal();
  199. });
  200. },
  201. beforeUnmount: function beforeUnmount() {
  202. this.clearDelayTimer();
  203. this.clearOutsideHandler();
  204. clearTimeout(this.mouseDownTimeout);
  205. raf.cancel(this.attachId);
  206. },
  207. methods: {
  208. updatedCal: function updatedCal() {
  209. var props = this.$props;
  210. var state = this.$data;
  211. // We must listen to `mousedown` or `touchstart`, edge case:
  212. // https://github.com/ant-design/ant-design/issues/5804
  213. // https://github.com/react-component/calendar/issues/250
  214. // https://github.com/react-component/trigger/issues/50
  215. if (state.sPopupVisible) {
  216. var currentDocument;
  217. if (!this.clickOutsideHandler && (this.isClickToHide() || this.isContextmenuToShow())) {
  218. currentDocument = props.getDocument(this.getRootDomNode());
  219. this.clickOutsideHandler = addEventListener(currentDocument, 'mousedown', this.onDocumentClick);
  220. }
  221. // always hide on mobile
  222. if (!this.touchOutsideHandler) {
  223. currentDocument = currentDocument || props.getDocument(this.getRootDomNode());
  224. this.touchOutsideHandler = addEventListener(currentDocument, 'touchstart', this.onDocumentClick, supportsPassive ? {
  225. passive: false
  226. } : false);
  227. }
  228. // close popup when trigger type contains 'onContextmenu' and document is scrolling.
  229. if (!this.contextmenuOutsideHandler1 && this.isContextmenuToShow()) {
  230. currentDocument = currentDocument || props.getDocument(this.getRootDomNode());
  231. this.contextmenuOutsideHandler1 = addEventListener(currentDocument, 'scroll', this.onContextmenuClose);
  232. }
  233. // close popup when trigger type contains 'onContextmenu' and window is blur.
  234. if (!this.contextmenuOutsideHandler2 && this.isContextmenuToShow()) {
  235. this.contextmenuOutsideHandler2 = addEventListener(window, 'blur', this.onContextmenuClose);
  236. }
  237. } else {
  238. this.clearOutsideHandler();
  239. }
  240. },
  241. onMouseenter: function onMouseenter(e) {
  242. var mouseEnterDelay = this.$props.mouseEnterDelay;
  243. this.fireEvents('onMouseenter', e);
  244. this.delaySetPopupVisible(true, mouseEnterDelay, mouseEnterDelay ? null : e);
  245. },
  246. onMouseMove: function onMouseMove(e) {
  247. this.fireEvents('onMousemove', e);
  248. this.setPoint(e);
  249. },
  250. onMouseleave: function onMouseleave(e) {
  251. this.fireEvents('onMouseleave', e);
  252. this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay);
  253. },
  254. onPopupMouseenter: function onPopupMouseenter() {
  255. this.clearDelayTimer();
  256. },
  257. onPopupMouseleave: function onPopupMouseleave(e) {
  258. var _this$popupRef;
  259. if (e && e.relatedTarget && !e.relatedTarget.setTimeout && contains((_this$popupRef = this.popupRef) === null || _this$popupRef === void 0 ? void 0 : _this$popupRef.getElement(), e.relatedTarget)) {
  260. return;
  261. }
  262. this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay);
  263. },
  264. onFocus: function onFocus(e) {
  265. this.fireEvents('onFocus', e);
  266. // incase focusin and focusout
  267. this.clearDelayTimer();
  268. if (this.isFocusToShow()) {
  269. this.focusTime = Date.now();
  270. this.delaySetPopupVisible(true, this.$props.focusDelay);
  271. }
  272. },
  273. onMousedown: function onMousedown(e) {
  274. this.fireEvents('onMousedown', e);
  275. this.preClickTime = Date.now();
  276. },
  277. onTouchstart: function onTouchstart(e) {
  278. this.fireEvents('onTouchstart', e);
  279. this.preTouchTime = Date.now();
  280. },
  281. onBlur: function onBlur(e) {
  282. if (!contains(e.target, e.relatedTarget || document.activeElement)) {
  283. this.fireEvents('onBlur', e);
  284. this.clearDelayTimer();
  285. if (this.isBlurToHide()) {
  286. this.delaySetPopupVisible(false, this.$props.blurDelay);
  287. }
  288. }
  289. },
  290. onContextmenu: function onContextmenu(e) {
  291. e.preventDefault();
  292. this.fireEvents('onContextmenu', e);
  293. this.setPopupVisible(true, e);
  294. },
  295. onContextmenuClose: function onContextmenuClose() {
  296. if (this.isContextmenuToShow()) {
  297. this.close();
  298. }
  299. },
  300. onClick: function onClick(event) {
  301. this.fireEvents('onClick', event);
  302. // focus will trigger click
  303. if (this.focusTime) {
  304. var preTime;
  305. if (this.preClickTime && this.preTouchTime) {
  306. preTime = Math.min(this.preClickTime, this.preTouchTime);
  307. } else if (this.preClickTime) {
  308. preTime = this.preClickTime;
  309. } else if (this.preTouchTime) {
  310. preTime = this.preTouchTime;
  311. }
  312. if (Math.abs(preTime - this.focusTime) < 20) {
  313. return;
  314. }
  315. this.focusTime = 0;
  316. }
  317. this.preClickTime = 0;
  318. this.preTouchTime = 0;
  319. // Only prevent default when all the action is click.
  320. // https://github.com/ant-design/ant-design/issues/17043
  321. // https://github.com/ant-design/ant-design/issues/17291
  322. if (this.isClickToShow() && (this.isClickToHide() || this.isBlurToHide()) && event && event.preventDefault) {
  323. event.preventDefault();
  324. }
  325. if (event && event.domEvent) {
  326. event.domEvent.preventDefault();
  327. }
  328. var nextVisible = !this.$data.sPopupVisible;
  329. if (this.isClickToHide() && !nextVisible || nextVisible && this.isClickToShow()) {
  330. this.setPopupVisible(!this.$data.sPopupVisible, event);
  331. }
  332. },
  333. onPopupMouseDown: function onPopupMouseDown() {
  334. var _this4 = this;
  335. var _this$vcTriggerContex = this.vcTriggerContext,
  336. vcTriggerContext = _this$vcTriggerContex === void 0 ? {} : _this$vcTriggerContex;
  337. this.hasPopupMouseDown = true;
  338. clearTimeout(this.mouseDownTimeout);
  339. this.mouseDownTimeout = setTimeout(function () {
  340. _this4.hasPopupMouseDown = false;
  341. }, 0);
  342. if (vcTriggerContext.onPopupMouseDown) {
  343. vcTriggerContext.onPopupMouseDown.apply(vcTriggerContext, arguments);
  344. }
  345. },
  346. onDocumentClick: function onDocumentClick(event) {
  347. if (this.$props.mask && !this.$props.maskClosable) {
  348. return;
  349. }
  350. var target = event.target;
  351. var root = this.getRootDomNode();
  352. var popupNode = this.getPopupDomNode();
  353. if (
  354. // mousedown on the target should also close popup when action is contextMenu.
  355. // https://github.com/ant-design/ant-design/issues/29853
  356. (!contains(root, target) || this.isContextMenuOnly()) && !contains(popupNode, target) && !this.hasPopupMouseDown) {
  357. // https://github.com/vuejs/core/issues/4462
  358. // vue 动画bug导致 https://github.com/vueComponent/ant-design-vue/issues/5259,
  359. // 改成延时解决
  360. this.delaySetPopupVisible(false, 0.1);
  361. }
  362. },
  363. getPopupDomNode: function getPopupDomNode() {
  364. var _this$popupRef2;
  365. // for test
  366. return ((_this$popupRef2 = this.popupRef) === null || _this$popupRef2 === void 0 ? void 0 : _this$popupRef2.getElement()) || null;
  367. },
  368. getRootDomNode: function getRootDomNode() {
  369. var getTriggerDOMNode = this.$props.getTriggerDOMNode;
  370. if (getTriggerDOMNode) {
  371. var domNode = findDOMNode(this.triggerRef);
  372. return findDOMNode(getTriggerDOMNode(domNode));
  373. }
  374. try {
  375. var _domNode = findDOMNode(this.triggerRef);
  376. if (_domNode) {
  377. return _domNode;
  378. }
  379. } catch (err) {
  380. // Do nothing
  381. }
  382. return findDOMNode(this);
  383. },
  384. handleGetPopupClassFromAlign: function handleGetPopupClassFromAlign(align) {
  385. var className = [];
  386. var props = this.$props;
  387. var popupPlacement = props.popupPlacement,
  388. builtinPlacements = props.builtinPlacements,
  389. prefixCls = props.prefixCls,
  390. alignPoint = props.alignPoint,
  391. getPopupClassNameFromAlign = props.getPopupClassNameFromAlign;
  392. if (popupPlacement && builtinPlacements) {
  393. className.push(getAlignPopupClassName(builtinPlacements, prefixCls, align, alignPoint));
  394. }
  395. if (getPopupClassNameFromAlign) {
  396. className.push(getPopupClassNameFromAlign(align));
  397. }
  398. return className.join(' ');
  399. },
  400. getPopupAlign: function getPopupAlign() {
  401. var props = this.$props;
  402. var popupPlacement = props.popupPlacement,
  403. popupAlign = props.popupAlign,
  404. builtinPlacements = props.builtinPlacements;
  405. if (popupPlacement && builtinPlacements) {
  406. return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign);
  407. }
  408. return popupAlign;
  409. },
  410. getComponent: function getComponent() {
  411. var _this5 = this;
  412. var mouseProps = {};
  413. if (this.isMouseEnterToShow()) {
  414. mouseProps.onMouseenter = this.onPopupMouseenter;
  415. }
  416. if (this.isMouseLeaveToHide()) {
  417. mouseProps.onMouseleave = this.onPopupMouseleave;
  418. }
  419. mouseProps.onMousedown = this.onPopupMouseDown;
  420. mouseProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onPopupMouseDown;
  421. var handleGetPopupClassFromAlign = this.handleGetPopupClassFromAlign,
  422. getRootDomNode = this.getRootDomNode,
  423. getContainer = this.getContainer,
  424. $attrs = this.$attrs;
  425. var _this$$props = this.$props,
  426. prefixCls = _this$$props.prefixCls,
  427. destroyPopupOnHide = _this$$props.destroyPopupOnHide,
  428. popupClassName = _this$$props.popupClassName,
  429. popupAnimation = _this$$props.popupAnimation,
  430. popupTransitionName = _this$$props.popupTransitionName,
  431. popupStyle = _this$$props.popupStyle,
  432. mask = _this$$props.mask,
  433. maskAnimation = _this$$props.maskAnimation,
  434. maskTransitionName = _this$$props.maskTransitionName,
  435. zIndex = _this$$props.zIndex,
  436. stretch = _this$$props.stretch,
  437. alignPoint = _this$$props.alignPoint,
  438. mobile = _this$$props.mobile,
  439. forceRender = _this$$props.forceRender;
  440. var _this$$data = this.$data,
  441. sPopupVisible = _this$$data.sPopupVisible,
  442. point = _this$$data.point;
  443. var popupProps = _objectSpread(_objectSpread({
  444. prefixCls: prefixCls,
  445. destroyPopupOnHide: destroyPopupOnHide,
  446. visible: sPopupVisible,
  447. point: alignPoint ? point : null,
  448. align: this.align,
  449. animation: popupAnimation,
  450. getClassNameFromAlign: handleGetPopupClassFromAlign,
  451. stretch: stretch,
  452. getRootDomNode: getRootDomNode,
  453. mask: mask,
  454. zIndex: zIndex,
  455. transitionName: popupTransitionName,
  456. maskAnimation: maskAnimation,
  457. maskTransitionName: maskTransitionName,
  458. getContainer: getContainer,
  459. class: popupClassName,
  460. style: popupStyle,
  461. onAlign: $attrs.onPopupAlign || noop
  462. }, mouseProps), {}, {
  463. ref: this.setPopupRef,
  464. mobile: mobile,
  465. forceRender: forceRender
  466. });
  467. return _createVNode(Popup, popupProps, {
  468. default: this.$slots.popup || function () {
  469. return _getComponent(_this5, 'popup');
  470. }
  471. });
  472. },
  473. attachParent: function attachParent(popupContainer) {
  474. var _this6 = this;
  475. raf.cancel(this.attachId);
  476. var _this$$props2 = this.$props,
  477. getPopupContainer = _this$$props2.getPopupContainer,
  478. getDocument = _this$$props2.getDocument;
  479. var domNode = this.getRootDomNode();
  480. var mountNode;
  481. if (!getPopupContainer) {
  482. mountNode = getDocument(this.getRootDomNode()).body;
  483. } else if (domNode || getPopupContainer.length === 0) {
  484. // Compatible for legacy getPopupContainer with domNode argument.
  485. // If no need `domNode` argument, will call directly.
  486. // https://codesandbox.io/s/eloquent-mclean-ss93m?file=/src/App.js
  487. mountNode = getPopupContainer(domNode);
  488. }
  489. if (mountNode) {
  490. mountNode.appendChild(popupContainer);
  491. } else {
  492. // Retry after frame render in case parent not ready
  493. this.attachId = raf(function () {
  494. _this6.attachParent(popupContainer);
  495. });
  496. }
  497. },
  498. getContainer: function getContainer() {
  499. var props = this.$props;
  500. var getDocument = props.getDocument;
  501. var popupContainer = getDocument(this.getRootDomNode()).createElement('div');
  502. // Make sure default popup container will never cause scrollbar appearing
  503. // https://github.com/react-component/trigger/issues/41
  504. popupContainer.style.position = 'absolute';
  505. popupContainer.style.top = '0';
  506. popupContainer.style.left = '0';
  507. popupContainer.style.width = '100%';
  508. this.attachParent(popupContainer);
  509. return popupContainer;
  510. },
  511. setPopupVisible: function setPopupVisible(sPopupVisible, event) {
  512. var alignPoint = this.alignPoint,
  513. prevPopupVisible = this.sPopupVisible,
  514. onPopupVisibleChange = this.onPopupVisibleChange;
  515. this.clearDelayTimer();
  516. if (prevPopupVisible !== sPopupVisible) {
  517. if (!hasProp(this, 'popupVisible')) {
  518. this.setState({
  519. sPopupVisible: sPopupVisible,
  520. prevPopupVisible: prevPopupVisible
  521. });
  522. }
  523. onPopupVisibleChange && onPopupVisibleChange(sPopupVisible);
  524. }
  525. // Always record the point position since mouseEnterDelay will delay the show
  526. if (alignPoint && event && sPopupVisible) {
  527. this.setPoint(event);
  528. }
  529. },
  530. setPoint: function setPoint(point) {
  531. var alignPoint = this.$props.alignPoint;
  532. if (!alignPoint || !point) return;
  533. this.setState({
  534. point: {
  535. pageX: point.pageX,
  536. pageY: point.pageY
  537. }
  538. });
  539. },
  540. handlePortalUpdate: function handlePortalUpdate() {
  541. if (this.prevPopupVisible !== this.sPopupVisible) {
  542. this.afterPopupVisibleChange(this.sPopupVisible);
  543. }
  544. },
  545. delaySetPopupVisible: function delaySetPopupVisible(visible, delayS, event) {
  546. var _this7 = this;
  547. var delay = delayS * 1000;
  548. this.clearDelayTimer();
  549. if (delay) {
  550. var point = event ? {
  551. pageX: event.pageX,
  552. pageY: event.pageY
  553. } : null;
  554. this.delayTimer = requestAnimationTimeout(function () {
  555. _this7.setPopupVisible(visible, point);
  556. _this7.clearDelayTimer();
  557. }, delay);
  558. } else {
  559. this.setPopupVisible(visible, event);
  560. }
  561. },
  562. clearDelayTimer: function clearDelayTimer() {
  563. if (this.delayTimer) {
  564. cancelAnimationTimeout(this.delayTimer);
  565. this.delayTimer = null;
  566. }
  567. },
  568. clearOutsideHandler: function clearOutsideHandler() {
  569. if (this.clickOutsideHandler) {
  570. this.clickOutsideHandler.remove();
  571. this.clickOutsideHandler = null;
  572. }
  573. if (this.contextmenuOutsideHandler1) {
  574. this.contextmenuOutsideHandler1.remove();
  575. this.contextmenuOutsideHandler1 = null;
  576. }
  577. if (this.contextmenuOutsideHandler2) {
  578. this.contextmenuOutsideHandler2.remove();
  579. this.contextmenuOutsideHandler2 = null;
  580. }
  581. if (this.touchOutsideHandler) {
  582. this.touchOutsideHandler.remove();
  583. this.touchOutsideHandler = null;
  584. }
  585. },
  586. createTwoChains: function createTwoChains(event) {
  587. var fn = function fn() {};
  588. var events = getEvents(this);
  589. if (this.childOriginEvents[event] && events[event]) {
  590. return this["fire".concat(event)];
  591. }
  592. fn = this.childOriginEvents[event] || events[event] || fn;
  593. return fn;
  594. },
  595. isClickToShow: function isClickToShow() {
  596. var _this$$props3 = this.$props,
  597. action = _this$$props3.action,
  598. showAction = _this$$props3.showAction;
  599. return action.indexOf('click') !== -1 || showAction.indexOf('click') !== -1;
  600. },
  601. isContextMenuOnly: function isContextMenuOnly() {
  602. var action = this.$props.action;
  603. return action === 'contextmenu' || action.length === 1 && action[0] === 'contextmenu';
  604. },
  605. isContextmenuToShow: function isContextmenuToShow() {
  606. var _this$$props4 = this.$props,
  607. action = _this$$props4.action,
  608. showAction = _this$$props4.showAction;
  609. return action.indexOf('contextmenu') !== -1 || showAction.indexOf('contextmenu') !== -1;
  610. },
  611. isClickToHide: function isClickToHide() {
  612. var _this$$props5 = this.$props,
  613. action = _this$$props5.action,
  614. hideAction = _this$$props5.hideAction;
  615. return action.indexOf('click') !== -1 || hideAction.indexOf('click') !== -1;
  616. },
  617. isMouseEnterToShow: function isMouseEnterToShow() {
  618. var _this$$props6 = this.$props,
  619. action = _this$$props6.action,
  620. showAction = _this$$props6.showAction;
  621. return action.indexOf('hover') !== -1 || showAction.indexOf('mouseenter') !== -1;
  622. },
  623. isMouseLeaveToHide: function isMouseLeaveToHide() {
  624. var _this$$props7 = this.$props,
  625. action = _this$$props7.action,
  626. hideAction = _this$$props7.hideAction;
  627. return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseleave') !== -1;
  628. },
  629. isFocusToShow: function isFocusToShow() {
  630. var _this$$props8 = this.$props,
  631. action = _this$$props8.action,
  632. showAction = _this$$props8.showAction;
  633. return action.indexOf('focus') !== -1 || showAction.indexOf('focus') !== -1;
  634. },
  635. isBlurToHide: function isBlurToHide() {
  636. var _this$$props9 = this.$props,
  637. action = _this$$props9.action,
  638. hideAction = _this$$props9.hideAction;
  639. return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1;
  640. },
  641. forcePopupAlign: function forcePopupAlign() {
  642. if (this.$data.sPopupVisible) {
  643. var _this$popupRef3;
  644. (_this$popupRef3 = this.popupRef) === null || _this$popupRef3 === void 0 ? void 0 : _this$popupRef3.forceAlign();
  645. }
  646. },
  647. fireEvents: function fireEvents(type, e) {
  648. if (this.childOriginEvents[type]) {
  649. this.childOriginEvents[type](e);
  650. }
  651. var event = this.$props[type] || this.$attrs[type];
  652. if (event) {
  653. event(e);
  654. }
  655. },
  656. close: function close() {
  657. this.setPopupVisible(false);
  658. }
  659. },
  660. render: function render() {
  661. var _this8 = this;
  662. var $attrs = this.$attrs;
  663. var children = filterEmpty(getSlot(this));
  664. var alignPoint = this.$props.alignPoint;
  665. var child = children[0];
  666. this.childOriginEvents = getEvents(child);
  667. var newChildProps = {
  668. key: 'trigger'
  669. };
  670. if (this.isContextmenuToShow()) {
  671. newChildProps.onContextmenu = this.onContextmenu;
  672. } else {
  673. newChildProps.onContextmenu = this.createTwoChains('onContextmenu');
  674. }
  675. if (this.isClickToHide() || this.isClickToShow()) {
  676. newChildProps.onClick = this.onClick;
  677. newChildProps.onMousedown = this.onMousedown;
  678. newChildProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onTouchstart;
  679. } else {
  680. newChildProps.onClick = this.createTwoChains('onClick');
  681. newChildProps.onMousedown = this.createTwoChains('onMousedown');
  682. newChildProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.createTwoChains('onTouchstart');
  683. }
  684. if (this.isMouseEnterToShow()) {
  685. newChildProps.onMouseenter = this.onMouseenter;
  686. if (alignPoint) {
  687. newChildProps.onMousemove = this.onMouseMove;
  688. }
  689. } else {
  690. newChildProps.onMouseenter = this.createTwoChains('onMouseenter');
  691. }
  692. if (this.isMouseLeaveToHide()) {
  693. newChildProps.onMouseleave = this.onMouseleave;
  694. } else {
  695. newChildProps.onMouseleave = this.createTwoChains('onMouseleave');
  696. }
  697. if (this.isFocusToShow() || this.isBlurToHide()) {
  698. newChildProps.onFocus = this.onFocus;
  699. newChildProps.onBlur = this.onBlur;
  700. } else {
  701. newChildProps.onFocus = this.createTwoChains('onFocus');
  702. newChildProps.onBlur = function (e) {
  703. if (e && (!e.relatedTarget || !contains(e.target, e.relatedTarget))) {
  704. _this8.createTwoChains('onBlur')(e);
  705. }
  706. };
  707. }
  708. var childrenClassName = classNames(child && child.props && child.props.class, $attrs.class);
  709. if (childrenClassName) {
  710. newChildProps.class = childrenClassName;
  711. }
  712. var trigger = cloneElement(child, _objectSpread(_objectSpread({}, newChildProps), {}, {
  713. ref: 'triggerRef'
  714. }), true, true);
  715. if (this.popPortal) {
  716. return trigger;
  717. } else {
  718. var portal = _createVNode(Portal, {
  719. "key": "portal",
  720. "getContainer": this.getContainer,
  721. "didUpdate": this.handlePortalUpdate
  722. }, {
  723. default: this.getComponent
  724. });
  725. return _createVNode(_Fragment, null, [portal, trigger]);
  726. }
  727. }
  728. });