diff --git a/js/src/dropdown.js b/js/src/dropdown.js index bada537c9c..66ff8cc4fc 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -72,7 +72,7 @@ const PLACEMENT_RIGHT = isRTL ? 'left-start' : 'right-start' const PLACEMENT_LEFT = isRTL ? 'right-start' : 'left-start' const Default = { - offset: 0, + offset: [0, 0], flip: true, boundary: 'clippingParents', reference: 'toggle', @@ -81,7 +81,7 @@ const Default = { } const DefaultType = { - offset: '(number|string|function)', + offset: '(array|string|function)', flip: 'boolean', boundary: '(string|element)', reference: '(string|element|object)', @@ -298,6 +298,20 @@ class Dropdown extends BaseComponent { return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null } + _getOffset() { + const { offset } = this._config + + if (typeof offset === 'string') { + return offset.split(',').map(val => Number.parseInt(val, 10)) + } + + if (typeof offset === 'function') { + return popperData => offset(popperData, this._element) + } + + return offset + } + _getPopperConfig() { const popperConfig = { placement: this._getPlacement(), @@ -313,6 +327,12 @@ class Dropdown extends BaseComponent { options: { fallbackPlacements: ['top', 'right', 'bottom', 'left'] } + }, + { + name: 'offset', + options: { + offset: this._getOffset() + } }] } diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index cc41396034..8b477ba38f 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -54,6 +54,54 @@ describe('Dropdown', () => { expect(dropdown.toggle).toHaveBeenCalled() }) + it('should create offset modifier correctly when offset option is a function', done => { + fixtureEl.innerHTML = [ + '
'dynamic'
static
.offset
[0, 0]
Offset of the dropdown relative to its target.
+When a function is used to determine the offset, it is called with an object containing the popper
instance, the refecence
Element and the placement
as its first argument. The function must return an array with two numbers: [skidding, distance]
. The triggering element DOM node is passed as the second argument.
For more information refer to Popper.js's offset docs.
+popperConfig