aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoke2k <[email protected]>2020-12-12 02:54:29 +0200
committerXhmikosR <[email protected]>2021-01-28 12:23:33 +0200
commit881f43a3b928e792185ed388e2589c73ea8c4be6 (patch)
treef37402a50b60bd26be4a94a055e3a8a57f3bb9a3
parent51ca9a9e2f3b19ccdcd2ff4c7d0d8ec42a69d3db (diff)
downloadbootstrap-881f43a3b928e792185ed388e2589c73ea8c4be6.tar.xz
bootstrap-881f43a3b928e792185ed388e2589c73ea8c4be6.zip
Restore offset option for dropdown component
-rw-r--r--js/src/dropdown.js24
-rw-r--r--js/tests/unit/dropdown.spec.js48
-rw-r--r--site/content/docs/5.0/components/dropdowns.md10
3 files changed, 80 insertions, 2 deletions
diff --git a/js/src/dropdown.js b/js/src/dropdown.js
index bada537c9..66ff8cc4f 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 cc4139603..8b477ba38 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 = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const getOffset = jasmine.createSpy('getOffset').and.returnValue([10, 20])
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown, {
+ offset: getOffset,
+ popperConfig: {
+ onFirstUpdate: state => {
+ expect(getOffset).toHaveBeenCalledWith({
+ popper: state.rects.popper,
+ reference: state.rects.reference,
+ placement: state.placement
+ }, btnDropdown)
+ done()
+ }
+ }
+ })
+ const offset = dropdown._getOffset()
+
+ expect(typeof offset).toEqual('function')
+
+ dropdown.show()
+ })
+
+ it('should create offset modifier correctly when offset option is a string into data attribute', () => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-offset="10,20">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
+
+ expect(dropdown._getOffset()).toEqual([10, 20])
+ })
+
it('should allow to pass config to Popper with `popperConfig`', () => {
fixtureEl.innerHTML = [
'<div class="dropdown">',
diff --git a/site/content/docs/5.0/components/dropdowns.md b/site/content/docs/5.0/components/dropdowns.md
index a50dcf0f5..b2abbc7bd 100644
--- a/site/content/docs/5.0/components/dropdowns.md
+++ b/site/content/docs/5.0/components/dropdowns.md
@@ -897,6 +897,16 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<td>By default, we use Popper for dynamic positioning. Disable this with <code>static</code>.</td>
</tr>
<tr>
+ <td><code>offset</code></td>
+ <td>array | string | function</td>
+ <td><code>[0, 0]</code></td>
+ <td>
+ <p>Offset of the dropdown relative to its target.</p>
+ <p>When a function is used to determine the offset, it is called with an object containing the <code>popper</code> instance, the <code>refecence</code> Element and the <code>placement</code> as its first argument. The function must return an array with two numbers: <code>[<a href="https://popper.js.org/docs/v2/modifiers/offset/#skidding-1">skidding</a>, <a href="https://popper.js.org/docs/v2/modifiers/offset/#distance-1">distance</a>]</code>. The triggering element DOM node is passed as the second argument.</p>
+ <p>For more information refer to Popper.js's <a href="https://popper.js.org/docs/v2/modifiers/offset/#options">offset docs</a>.</p>
+ </td>
+ </tr>
+ <tr>
<td><code>popperConfig</code></td>
<td>null | object</td>
<td><code>null</code></td>