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