diff --git a/docs/_includes/tooltip-documentation.md b/docs/_includes/tooltip-documentation.md
index 877fc86d7d..76fdf54af8 100644
--- a/docs/_includes/tooltip-documentation.md
+++ b/docs/_includes/tooltip-documentation.md
@@ -34,6 +34,7 @@ Create a new Tooltip.js instance
| [options.template] | String
| '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
| Base HTML to used when creating the tooltip. The tooltip's `title` will be injected into the `.tooltip-inner` or `.tooltip__inner`. `.tooltip-arrow` or `.tooltip__arrow` will become the tooltip's arrow. The outermost wrapper element should have the `.tooltip` class. |
| options.title | String
\| HTMLElement
\| TitleFunction
| ''
| Default title value if `title` attribute isn't present. |
| [options.trigger] | String
| 'hover focus'
| How tooltip is triggered - click, hover, focus, manual. You may pass multiple triggers; separate them with a space. `manual` cannot be combined with any other trigger. |
+| options.closeOnClickOutside | Boolean
| false
| Close a popper on click outside of the popper and reference element. This has effect only when options.trigger is 'click'. |
| options.boundariesElement | String
\| HTMLElement
| | The element used as boundaries for the tooltip. For more information refer to Popper.js' [boundariesElement docs](https://popper.js.org/popper-documentation.html) |
| options.offset | Number
\| String
| 0
| Offset of the tooltip relative to its reference. For more information refer to Popper.js' [offset docs](https://popper.js.org/popper-documentation.html) |
| options.popperOptions | Object
| {}
| Popper options, will be passed directly to popper instance. For more information refer to Popper.js' [options docs](https://popper.js.org/popper-documentation.html) |
diff --git a/packages/tooltip/src/index.js b/packages/tooltip/src/index.js
index 5813a74ca0..6af168dfaf 100644
--- a/packages/tooltip/src/index.js
+++ b/packages/tooltip/src/index.js
@@ -41,6 +41,7 @@ export default class Tooltip {
* @param {String} [options.trigger='hover focus']
* How tooltip is triggered - click, hover, focus, manual.
* You may pass multiple triggers; separate them with a space. `manual` cannot be combined with any other trigger.
+ * @param {Boolean} options.closeOnClickOutside=false - Close a popper on click outside of the popper and reference element. This has effect only when options.trigger is 'click'.
* @param {String|HTMLElement} options.boundariesElement
* The element used as boundaries for the tooltip. For more information refer to Popper.js'
* [boundariesElement docs](https://popper.js.org/popper-documentation.html)
@@ -354,6 +355,19 @@ export default class Tooltip {
};
this._events.push({ event, func });
reference.addEventListener(event, func);
+ if (event === 'click' && options.closeOnClickOutside) {
+ document.addEventListener('mousedown', e => {
+ if (!this._isOpening) {
+ return;
+ }
+ const popper = this.popperInstance.popper;
+ if (reference.contains(e.target) ||
+ popper.contains(e.target)) {
+ return;
+ }
+ func(e);
+ }, true);
+ }
});
}
diff --git a/packages/tooltip/tests/functional/tooltip.js b/packages/tooltip/tests/functional/tooltip.js
index b8eef0132b..f04b03ec1b 100644
--- a/packages/tooltip/tests/functional/tooltip.js
+++ b/packages/tooltip/tests/functional/tooltip.js
@@ -512,5 +512,18 @@ describe('[tooltip.js]', () => {
expect(instance._popperOptions.modifiers.offset.offset).toBe(10);
done();
});
+
+ it('should hide on click outside with `options.closeOnClickOutside`', done => {
+ instance = new Tooltip(reference, {
+ title: 'foobar',
+ trigger: 'click',
+ closeOnClickOutside: true,
+ });
+ reference.dispatchEvent(new CustomEvent('click'));
+ then(() => expect(document.querySelector('.tooltip')).not.toBeNull());
+ then(() => document.body.dispatchEvent(new CustomEvent('mousedown')));
+ then(() => expect(document.querySelector('.tooltip').style.visibility).toBe('hidden'));
+ then(done);
+ });
});
});