Trigger.js 21 KB

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