Browse Source

Popover: add close-delay prop (#16671)

LachlanStuart 6 năm trước cách đây
mục cha
commit
465c38bfaa

+ 2 - 1
examples/docs/en-US/popover.md

@@ -151,7 +151,8 @@ Of course, you can nest other operations. It's more light-weight than using a di
 |  visible-arrow   |  whether a tooltip arrow is displayed or not. For more info, please refer to [Vue-popper](https://github.com/element-component/vue-popper) | boolean | — | true |
 |  popper-options        | parameters for [popper.js](https://popper.js.org/documentation.html) | object            | please refer to [popper.js](https://popper.js.org/documentation.html) | `{ boundariesElement: 'body', gpuAcceleration: false }` |
 |  popper-class        |  custom class name for popover | string | — | — |
-|  open-delay        | delay of appearance when `trigger` is hover, in milliseconds | number | — | — |
+|  open-delay        | delay before appearing when `trigger` is hover, in milliseconds | number | — | — |
+|  close-delay        | delay before disappearing when `trigger` is hover, in milliseconds | number | — | 200 |
 |  tabindex          | [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of Popover | number | — | 0 |
 
 ### Slot

+ 1 - 0
examples/docs/es/popover.md

@@ -151,6 +151,7 @@ Por supuesto, puedes anidar otras operaciones. Es más ligero que utilizar un `d
 | popper-options | parámetros para [popper.js](https://popper.js.org/documentation.html) | object         | por favor, refiérase a [popper.js](https://popper.js.org/documentation.html) | `{ boundariesElement: 'body', gpuAcceleration: false }` |
 | popper-class   | clase propia para popover                | string         | —                                        | —                                        |
 | open-delay     | retraso de la aparición cuando `trigger` es hover, en milisegundos | number         | —                                        | —                                        |
+| close-delay    | delay before disappearing when `trigger` is hover, in milliseconds | number | — | 200 |
 | tabindex       | [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) de Popover |   number           |      —      |  0    |
 
 ### Slot

+ 1 - 0
examples/docs/fr-FR/popover.md

@@ -153,6 +153,7 @@ Vous pouvez aussi imbriquer des opérations. Procéder ainsi est plus léger que
 | popper-options | Paramètres pour [popper.js](https://popper.js.org/documentation.html). | object | Référez-vous à [popper.js](https://popper.js.org/documentation.html). | `{ boundariesElement: 'body', gpuAcceleration: false }` |
 | popper-class | Classe du popover. | string | — | — |
 | open-delay | Délai d'affichage, lorsque `trigger` est 'hover', en millisecondes. | number | — | — |
+| close-delay | delay before disappearing when `trigger` is hover, in milliseconds | number | — | 200 |
 | tabindex   | [tabindex](https://developer.mozilla.org/fr/docs/Web/HTML/Attributs_universels/tabindex) de Popover | number | — | 0 |
 
 ### Slot

+ 1 - 0
examples/docs/zh-CN/popover.md

@@ -149,6 +149,7 @@ Popover 的属性与 Tooltip 很类似,它们都是基于`Vue-popper`开发的
 |  popper-options        | [popper.js](https://popper.js.org/documentation.html) 的参数 | Object            | 参考 [popper.js](https://popper.js.org/documentation.html) 文档 | `{ boundariesElement: 'body', gpuAcceleration: false }` |
 | popper-class | 为 popper 添加类名 | String | — | — |
 | open-delay | 触发方式为 hover 时的显示延迟,单位为毫秒 | Number | — | — |
+| close-delay | 触发方式为 hover 时的隐藏延迟,单位为毫秒 | number | — | 200 |
 | tabindex   | Popover 组件的 [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) | number | — | 0 |
 
 ### Slot

+ 11 - 3
packages/popover/src/main.vue

@@ -42,6 +42,10 @@ export default {
       type: Number,
       default: 0
     },
+    closeDelay: {
+      type: Number,
+      default: 200
+    },
     title: String,
     disabled: Boolean,
     content: String,
@@ -176,9 +180,13 @@ export default {
     },
     handleMouseLeave() {
       clearTimeout(this._timer);
-      this._timer = setTimeout(() => {
+      if (this.closeDelay) {
+        this._timer = setTimeout(() => {
+          this.showPopper = false;
+        }, this.closeDelay);
+      } else {
         this.showPopper = false;
-      }, 200);
+      }
     },
     handleDocumentClick(e) {
       let reference = this.reference || this.$refs.reference;
@@ -203,7 +211,7 @@ export default {
       this.doDestroy();
     },
     cleanup() {
-      if (this.openDelay) {
+      if (this.openDelay || this.closeDelay) {
         clearTimeout(this._timer);
       }
     }

+ 51 - 1
test/unit/specs/popover.spec.js

@@ -1,4 +1,4 @@
-import { createVue, triggerEvent, createTest, destroyVM } from '../util';
+import { createVue, triggerEvent, createTest, destroyVM, wait } from '../util';
 import Popover from 'packages/popover';
 
 describe('Popover', () => {
@@ -249,6 +249,56 @@ describe('Popover', () => {
     }, 50);
   });
 
+  describe('open/close delays', () => {
+    it('100ms open / instant close', async() => {
+      vm = createVue(`
+        <div>
+          <el-popover
+            ref="popover"
+            content="content"
+            trigger="hover"
+            :open-delay="100"
+            :close-delay="0">
+            <button slot="reference">reference</button>
+          </el-popover>
+        </div>
+      `, true);
+      const compo = vm.$refs.popover;
+      const button = vm.$el.querySelector('button');
+
+      triggerEvent(button, 'mouseenter');
+      expect(compo.showPopper).to.false;
+      await wait(150);
+      expect(compo.showPopper).to.true;
+      triggerEvent(button, 'mouseleave');
+      expect(compo.showPopper).to.false;
+    });
+
+    it('instant open / 100ms close', async() => {
+      vm = createVue(`
+        <div>
+          <el-popover
+            ref="popover"
+            content="content"
+            trigger="hover"
+            :open-delay="0"
+            :close-delay="100">
+            <button slot="reference">reference</button>
+          </el-popover>
+        </div>
+      `, true);
+      const compo = vm.$refs.popover;
+      const button = vm.$el.querySelector('button');
+
+      triggerEvent(button, 'mouseenter');
+      expect(compo.showPopper).to.true;
+      triggerEvent(button, 'mouseleave');
+      expect(compo.showPopper).to.true;
+      await wait(150);
+      expect(compo.showPopper).to.false;
+    });
+  });
+
   it('destroy event', () => {
     vm = createTest(Popover, {
       reference: document.createElement('div'),

+ 4 - 1
types/popover.d.ts

@@ -58,9 +58,12 @@ export declare class ElPopover extends ElementUIComponent {
   /** Custom class name for popover */
   popperClass: string
 
-  /** Delay of appearance when trigger is hover, in milliseconds */
+  /** Delay before appearing when trigger is hover, in milliseconds */
   openDelay: number
 
+  /** Delay before disappearing when trigger is hover, in milliseconds */
+  closeDelay: number
+
   /** Popover tabindex */
   tabindex: number