diff options
| author | joke2k <[email protected]> | 2020-12-12 02:54:29 +0200 |
|---|---|---|
| committer | XhmikosR <[email protected]> | 2021-01-28 12:23:33 +0200 |
| commit | 881f43a3b928e792185ed388e2589c73ea8c4be6 (patch) | |
| tree | f37402a50b60bd26be4a94a055e3a8a57f3bb9a3 | |
| parent | 51ca9a9e2f3b19ccdcd2ff4c7d0d8ec42a69d3db (diff) | |
| download | bootstrap-881f43a3b928e792185ed388e2589c73ea8c4be6.tar.xz bootstrap-881f43a3b928e792185ed388e2589c73ea8c4be6.zip | |
Restore offset option for dropdown component
| -rw-r--r-- | js/src/dropdown.js | 24 | ||||
| -rw-r--r-- | js/tests/unit/dropdown.spec.js | 48 | ||||
| -rw-r--r-- | site/content/docs/5.0/components/dropdowns.md | 10 |
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> |
