diff --git a/js/src/dropdown/dropdown.js b/js/src/dropdown/dropdown.js
index 2c30ba740a..26bcf2aa3a 100644
--- a/js/src/dropdown/dropdown.js
+++ b/js/src/dropdown/dropdown.js
@@ -83,7 +83,8 @@ const Default = {
flip: true,
boundary: 'scrollParent',
reference: 'toggle',
- display: 'dynamic'
+ display: 'dynamic',
+ popperConfig: null
}
const DefaultType = {
@@ -91,7 +92,8 @@ const DefaultType = {
flip: 'boolean',
boundary: '(string|element)',
reference: '(string|element)',
- display: 'string'
+ display: 'string',
+ popperConfig: '(null|object)'
}
/**
@@ -339,7 +341,7 @@ class Dropdown {
}
_getPopperConfig() {
- const popperConfig = {
+ let popperConfig = {
placement: this._getPlacement(),
modifiers: {
offset: this._getOffset(),
@@ -359,6 +361,13 @@ class Dropdown {
}
}
+ if (this._config.popperConfig) {
+ popperConfig = {
+ ...popperConfig,
+ ...this._config.popperConfig
+ }
+ }
+
return popperConfig
}
diff --git a/js/src/dropdown/dropdown.spec.js b/js/src/dropdown/dropdown.spec.js
index 92d8fea033..e99e992f3d 100644
--- a/js/src/dropdown/dropdown.spec.js
+++ b/js/src/dropdown/dropdown.spec.js
@@ -99,6 +99,28 @@ describe('Dropdown', () => {
expect(dropdown.toggle).toHaveBeenCalled()
})
+
+ it('should allow to pass config to popper.js thanks to popperConfig', () => {
+ fixtureEl.innerHTML = [
+ '
',
+ ' ',
+ ' ',
+ '
'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown, {
+ popperConfig: {
+ placement: 'left'
+ }
+ })
+
+ const popperConfig = dropdown._getPopperConfig()
+
+ expect(popperConfig.placement).toEqual('left')
+ })
})
describe('toggle', () => {
diff --git a/js/src/tooltip/tooltip.js b/js/src/tooltip/tooltip.js
index 33f0173a3f..8bf998468c 100644
--- a/js/src/tooltip/tooltip.js
+++ b/js/src/tooltip/tooltip.js
@@ -56,7 +56,8 @@ const DefaultType = {
boundary: '(string|element)',
sanitize: 'boolean',
sanitizeFn: '(null|function)',
- whiteList: 'object'
+ whiteList: 'object',
+ popperConfig: '(null|object)'
}
const AttachmentMap = {
@@ -84,7 +85,8 @@ const Default = {
boundary: 'scrollParent',
sanitize: true,
sanitizeFn: null,
- whiteList: DefaultWhitelist
+ whiteList: DefaultWhitelist,
+ popperConfig: null
}
const HoverState = {
@@ -129,10 +131,6 @@ const Trigger = {
class Tooltip {
constructor(element, config) {
- /**
- * Check for Popper dependency
- * Popper - https://popper.js.org
- */
if (typeof Popper === 'undefined') {
throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org)')
}
@@ -247,7 +245,7 @@ class Tooltip {
this._timeout = null
this._hoverState = null
this._activeTrigger = null
- if (this._popper !== null) {
+ if (this._popper) {
this._popper.destroy()
}
@@ -301,27 +299,7 @@ class Tooltip {
EventHandler.trigger(this.element, this.constructor.Event.INSERTED)
- this._popper = new Popper(this.element, tip, {
- placement: attachment,
- modifiers: {
- offset: this._getOffset(),
- flip: {
- behavior: this.config.fallbackPlacement
- },
- arrow: {
- element: `.${this.constructor.NAME}-arrow`
- },
- preventOverflow: {
- boundariesElement: this.config.boundary
- }
- },
- onCreate: data => {
- if (data.originalPlacement !== data.placement) {
- this._handlePopperPlacementChange(data)
- }
- },
- onUpdate: data => this._handlePopperPlacementChange(data)
- })
+ this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))
tip.classList.add(ClassName.SHOW)
@@ -482,6 +460,40 @@ class Tooltip {
// Private
+ _getPopperConfig(attachment) {
+ const defaultBsConfig = {
+ placement: attachment,
+ modifiers: {
+ offset: this._getOffset(),
+ flip: {
+ behavior: this.config.fallbackPlacement
+ },
+ arrow: {
+ element: `.${this.constructor.NAME}-arrow`
+ },
+ preventOverflow: {
+ boundariesElement: this.config.boundary
+ }
+ },
+ onCreate: data => {
+ if (data.originalPlacement !== data.placement) {
+ this._handlePopperPlacementChange(data)
+ }
+ },
+ onUpdate: data => this._handlePopperPlacementChange(data)
+ }
+
+ let resultConfig = defaultBsConfig
+ if (this.config.popperConfig) {
+ resultConfig = {
+ ...defaultBsConfig,
+ ...this.config.popperConfig
+ }
+ }
+
+ return resultConfig
+ }
+
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`)
}
diff --git a/js/src/tooltip/tooltip.spec.js b/js/src/tooltip/tooltip.spec.js
index 1e858d369a..e4bddcf003 100644
--- a/js/src/tooltip/tooltip.spec.js
+++ b/js/src/tooltip/tooltip.spec.js
@@ -108,6 +108,21 @@ describe('Tooltip', () => {
tooltipInContainerEl.click()
})
+
+ it('should allow to pass config to popper.js thanks to popperConfig', () => {
+ fixtureEl.innerHTML = ''
+
+ const tooltipEl = fixtureEl.querySelector('a')
+ const tooltip = new Tooltip(tooltipEl, {
+ popperConfig: {
+ placement: 'left'
+ }
+ })
+
+ const popperConfig = tooltip._getPopperConfig('top')
+
+ expect(popperConfig.placement).toEqual('left')
+ })
})
describe('enable', () => {
diff --git a/site/content/docs/4.3/components/dropdowns.md b/site/content/docs/4.3/components/dropdowns.md
index 42bc1bb56c..6d0f094b57 100644
--- a/site/content/docs/4.3/components/dropdowns.md
+++ b/site/content/docs/4.3/components/dropdowns.md
@@ -855,6 +855,12 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
'dynamic' |
By default, we use Popper.js for dynamic positioning. Disable this with static . |
+
+ popperConfig |
+ null | object |
+ null |
+ To change Bootstrap default Popper.js config, see Popper.js configuration |
+
diff --git a/site/content/docs/4.3/components/popovers.md b/site/content/docs/4.3/components/popovers.md
index dfd4904e06..04ba2f15ce 100644
--- a/site/content/docs/4.3/components/popovers.md
+++ b/site/content/docs/4.3/components/popovers.md
@@ -281,6 +281,12 @@ Note that for security reasons the `sanitize`, `sanitizeFn` and `whiteList` opti
null |
Here you can supply your own sanitize function. This can be useful if you prefer to use a dedicated library to perform sanitization. |
+
+ popperConfig |
+ null | object |
+ null |
+ To change Bootstrap default Popper.js config, see Popper.js configuration |
+
diff --git a/site/content/docs/4.3/components/tooltips.md b/site/content/docs/4.3/components/tooltips.md
index 373cc45d52..880e761851 100644
--- a/site/content/docs/4.3/components/tooltips.md
+++ b/site/content/docs/4.3/components/tooltips.md
@@ -278,6 +278,12 @@ Note that for security reasons the `sanitize`, `sanitizeFn` and `whiteList` opti
null |
Here you can supply your own sanitize function. This can be useful if you prefer to use a dedicated library to perform sanitization. |
+
+ popperConfig |
+ null | object |
+ null |
+ To change Bootstrap default Popper.js config, see Popper.js configuration |
+