diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 4d65008f82..008294e9b1 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -84,7 +84,7 @@ const DefaultType = { offset: '(number|string|function)', flip: 'boolean', boundary: '(string|element)', - reference: '(string|element)', + reference: '(string|element|object)', display: 'string', popperConfig: '(null|object)' } @@ -172,6 +172,8 @@ class Dropdown extends BaseComponent { if (typeof this._config.reference.jquery !== 'undefined') { referenceElement = this._config.reference[0] } + } else if (typeof this._config.reference === 'object') { + referenceElement = this._config.reference } this._popper = Popper.createPopper(referenceElement, this._menu, this._getPopperConfig()) @@ -257,6 +259,13 @@ class Dropdown extends BaseComponent { typeCheckConfig(NAME, config, this.constructor.DefaultType) + if (typeof config.reference === 'object' && !isElement(config.reference) && + typeof config.reference.getBoundingClientRect !== 'function' + ) { + // Popper virtual elements require a getBoundingClientRect method + throw new Error(`${NAME}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`) + } + return config } diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index d2171f3697..ba1d0f4438 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -367,6 +367,58 @@ describe('Dropdown', () => { dropdown.toggle() }) + it('should toggle a dropdown with a valid virtual element reference', done => { + fixtureEl.innerHTML = [ + '
reference
'toggle'
'toggle'
, 'parent'
, or an HTMLElement reference. For more information refer to Popper's constructor docs.'toggle'
, 'parent'
, an HTMLElement reference or an object providing getBoundingClientRect
. For more information refer to Popper's constructor docs and virtual element docs.display