diff --git a/js/src/dropdown.js b/js/src/dropdown.js index bada537c9c8e..66ff8cc4fcf7 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/src/tooltip.js b/js/src/tooltip.js index 909cb0f8a7d5..6d85fde26942 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -50,6 +50,7 @@ const DefaultType = { html: 'boolean', selector: '(string|boolean)', placement: '(string|function)', + offset: '(array|string|function)', container: '(string|element|boolean)', fallbackPlacements: 'array', boundary: '(string|element)', @@ -80,6 +81,7 @@ const Default = { html: false, selector: false, placement: 'top', + offset: [0, 0], container: false, fallbackPlacements: ['top', 'right', 'bottom', 'left'], boundary: 'clippingParents', @@ -473,6 +475,20 @@ class Tooltip extends BaseComponent { return context } + _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(attachment) { const defaultBsConfig = { placement: attachment, @@ -484,6 +500,12 @@ class Tooltip extends BaseComponent { fallbackPlacements: this.config.fallbackPlacements } }, + { + name: 'offset', + options: { + offset: this._getOffset() + } + }, { name: 'preventOverflow', options: { diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index cc41396034cb..8b477ba38f80 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. You can pass a string in data attributes with comma separated values like: data-bs-offset="10,20"
When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding, distance]
.
For more information refer to Popper's offset docs.
+popperConfig
null
offset
[0, 0]
Offset of the popover relative to its target. You can pass a string in data attributes with comma separated values like: data-bs-offset="10,20"
When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding, distance]
.
For more information refer to Popper's offset docs.
+popperConfig
null
offset
[0, 0]
Offset of the tooltip relative to its target. You can pass a string in data attributes with comma separated values like: data-bs-offset="10,20"
When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding, distance]
.
For more information refer to Popper's offset docs.
+popperConfig