diff options
author | GeoSot <geo.sotis@gmail.com> | 2022-03-03 01:55:27 +0300 |
---|---|---|
committer | GeoSot <geo.sotis@gmail.com> | 2022-10-27 00:32:31 +0300 |
commit | 15af4f1d94bb9a988a9b54cb461d8899f20d8b23 (patch) | |
tree | be7ac3778946dae20336436d8261c31cfd8f8a55 | |
parent | 0ee540e38cc1d356a40833fcb5c06e32eb64fb42 (diff) |
fix tests & re-set positiongs/support-drop-down-in-navbar
-rw-r--r-- | js/src/dropdown.js | 19 | ||||
-rw-r--r-- | js/tests/unit/dropdown.spec.js | 121 | ||||
-rw-r--r-- | js/tests/visual/dropdown.html | 64 | ||||
-rw-r--r-- | site/content/docs/5.2/examples/headers/headers.css | 4 |
4 files changed, 135 insertions, 73 deletions
diff --git a/js/src/dropdown.js b/js/src/dropdown.js index e4bcddd106..ddbf3b9774 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -55,7 +55,6 @@ const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center' const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)' const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}` const SELECTOR_MENU = '.dropdown-menu' -const SELECTOR_NAVBAR_NAV = '.navbar-nav' const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start' @@ -99,7 +98,6 @@ class Dropdown extends BaseComponent { this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent) - this._inNavbar = this._detectNavbar() } // Getters @@ -141,7 +139,7 @@ class Dropdown extends BaseComponent { // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html - if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { + if ('ontouchstart' in document.documentElement) { for (const element of [].concat(...document.body.children)) { EventHandler.on(element, 'mouseover', noop) } @@ -304,15 +302,20 @@ class Dropdown extends BaseComponent { { name: 'applyCustomStyles', enabled: true, - phase: 'afterWrite', - fn: () => { + phase: 'beforeRead', + fn: ({ state, instance }) => { this._menu.style.removeProperty('position') const initialPosition = getComputedStyle(this._menu).position if (this._config.display === 'static' || initialPosition === 'static') { - // this._menu.style.position = 'static' - this._menu.style.removeProperty('margin') - this._menu.style.removeProperty('transform') Manipulator.setDataAttribute(this._menu, 'popper', 'static') // todo:v6 remove? + instance.setOptions({ + modifiers: [{ + name: 'applyStyles', + enabled: false + }] + }) + } else { + this._menu.style.position = state.styles.popper.position // put back position } } }] diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 2bbd7c00a7..0eb0872746 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -1093,7 +1093,7 @@ describe('Dropdown', () => { }) describe('update', () => { - it('should call Popper and detect navbar on update', () => { + it('should call Popper on update', () => { fixtureEl.innerHTML = [ '<div class="dropdown">', ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>', @@ -1111,33 +1111,10 @@ describe('Dropdown', () => { expect(dropdown._popper).not.toBeNull() const spyUpdate = spyOn(dropdown._popper, 'update') - const spyDetect = spyOn(dropdown, '_detectNavbar') dropdown.update() expect(spyUpdate).toHaveBeenCalled() - expect(spyDetect).toHaveBeenCalled() - }) - - it('should just detect navbar on update', () => { - 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 btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') - const dropdown = new Dropdown(btnDropdown) - - const spy = spyOn(dropdown, '_detectNavbar') - - dropdown.update() - - expect(dropdown._popper).toBeNull() - expect(spy).toHaveBeenCalled() }) }) @@ -1185,33 +1162,6 @@ describe('Dropdown', () => { }) }) - it('should not use "static" Popper in navbar', () => { - return new Promise(resolve => { - fixtureEl.innerHTML = [ - '<nav class="navbar navbar-expand-md bg-light">', - ' <div class="dropdown">', - ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>', - ' <div class="dropdown-menu">', - ' <a class="dropdown-item" href="#">Secondary link</a>', - ' </div>', - ' </div>', - '</nav>' - ].join('') - - const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') - const dropdownMenu = fixtureEl.querySelector('.dropdown-menu') - const dropdown = new Dropdown(btnDropdown) - - btnDropdown.addEventListener('shown.bs.dropdown', () => { - expect(dropdown._popper).not.toBeNull() - expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static') - resolve() - }) - - dropdown.show() - }) - }) - it('should not collapse the dropdown when clicking a select option nested in the dropdown', () => { return new Promise(resolve => { fixtureEl.innerHTML = [ @@ -1255,13 +1205,13 @@ describe('Dropdown', () => { }) }) - it('should manage bs attribute `data-bs-popper`="static" when dropdown is in navbar', () => { + it('should manage bs attribute `data-bs-popper`="static" when dropdown has position=static', () => { return new Promise(resolve => { fixtureEl.innerHTML = [ '<nav class="navbar navbar-expand-md bg-light">', ' <div class="dropdown">', ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>', - ' <div class="dropdown-menu">', + ' <div class="dropdown-menu" style="position:static;">', ' <a class="dropdown-item" href="#">Secondary link</a>', ' </div>', ' </div>', @@ -1273,8 +1223,13 @@ describe('Dropdown', () => { const dropdown = new Dropdown(btnDropdown) btnDropdown.addEventListener('shown.bs.dropdown', () => { - expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static') - dropdown.hide() + setTimeout(() => { + expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static') + expect(dropdownMenu.style.getPropertyValue('margin')).toEqual('') + expect(dropdownMenu.style.getPropertyValue('position')).toEqual('') + expect(dropdownMenu.style.getPropertyValue('transform')).toEqual('') + dropdown.hide() + }) }) btnDropdown.addEventListener('hidden.bs.dropdown', () => { @@ -1286,7 +1241,7 @@ describe('Dropdown', () => { }) }) - it('should not use Popper if display set to static', () => { + it('should handle Popper if display set to static', () => { return new Promise(resolve => { fixtureEl.innerHTML = [ '<div class="dropdown">', @@ -1302,7 +1257,51 @@ describe('Dropdown', () => { btnDropdown.addEventListener('shown.bs.dropdown', () => { // Popper adds this attribute when we use it + expect(dropdownMenu.getAttribute('data-popper-placement')).toBeNull() + setTimeout(() => { + expect(dropdownMenu.style.getPropertyValue('margin')).toEqual('') + expect(dropdownMenu.style.getPropertyValue('position')).toEqual('') + expect(dropdownMenu.style.getPropertyValue('transform')).toEqual('') + resolve() + }) + }) + + btnDropdown.click() + }) + }) + + it('should handle Popper if css position is set to static', () => { + return new Promise(resolve => { + fixtureEl.innerHTML = [ + '<style>', + ' .dropdown-menu { position: static }', + '</style>', + '<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 btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') + const dropdownMenu = fixtureEl.querySelector('.dropdown-menu') + + btnDropdown.addEventListener('shown.bs.dropdown', () => { + // Popper adds this attribute when we use it + expect(dropdownMenu.getAttribute('data-popper-placement')).toBeNull() + setTimeout(() => { + expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static') + expect(dropdownMenu.style.getPropertyValue('margin')).toEqual('') + expect(dropdownMenu.style.getPropertyValue('position')).toEqual('') + expect(dropdownMenu.style.getPropertyValue('transform')).toEqual('') + btnDropdown.click() + }) + }) + + btnDropdown.addEventListener('hidden.bs.dropdown', () => { + expect(dropdownMenu.getAttribute('data-bs-popper')).toBeNull() resolve() }) @@ -1326,8 +1325,10 @@ describe('Dropdown', () => { const dropdown = new Dropdown(btnDropdown) btnDropdown.addEventListener('shown.bs.dropdown', () => { - expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static') - dropdown.hide() + setTimeout(() => { + expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static') + dropdown.hide() + }) }) btnDropdown.addEventListener('hidden.bs.dropdown', () => { @@ -1974,7 +1975,7 @@ describe('Dropdown', () => { const dropdown = new Dropdown(triggerDropdown) const button = fixtureEl.querySelector('button[data-bs-toggle="dropdown"]') - const spy = spyOn(dropdown, 'toggle') + spyOn(dropdown, 'toggle') // Key escape button.focus() @@ -1984,7 +1985,7 @@ describe('Dropdown', () => { button.dispatchEvent(keydownEscape) setTimeout(() => { - expect(spy).not.toHaveBeenCalled() + expect(dropdown.toggle).not.toHaveBeenCalled() expect(triggerDropdown).not.toHaveClass('show') resolve() }, 20) diff --git a/js/tests/visual/dropdown.html b/js/tests/visual/dropdown.html index 04cf06d7b6..498bb7fe33 100644 --- a/js/tests/visual/dropdown.html +++ b/js/tests/visual/dropdown.html @@ -10,6 +10,68 @@ <div class="container"> <h1>Dropdown <small>Bootstrap Visual Test</small></h1> + + <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> + <div class="container-fluid"> + <a class="navbar-brand" href="#">Expand at lg</a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample05" aria-controls="navbarsExample05" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarsExample05"> + <ul class="navbar-nav me-auto mb-2 mb-lg-0"> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="#">Home</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="#">Link</a> + </li> + <li class="nav-item"> + <a class="nav-link disabled">Disabled</a> + </li> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" id="dropdown05" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a> + <ul class="dropdown-menu" aria-labelledby="dropdown05"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + </ul> + </li> + </ul> + <form role="search"> + <input class="form-control" type="search" placeholder="Search" aria-label="Search"> + </form> + <div class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> + Positioned dropdown + </a> + <ul class="dropdown-menu" aria-labelledby="navbarDropdown"> + <li><a class="dropdown-item" href="#">Action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><a class="dropdown-item" href="#">Another action</a></li> + <li><hr class="dropdown-divider"></li> + <li><a class="dropdown-item" href="#">Something else here</a></li> + </ul> + </div> + </div> + </div> + </nav> + <nav class="navbar navbar-expand-md bg-light"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> @@ -28,7 +90,7 @@ <a class="nav-link" href="#">Link</a> </li> <li class="nav-item dropdown"> - <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a> + <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-offset="0,20" aria-expanded="false">Dropdown</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#">Action</a></li> <li><a class="dropdown-item" href="#">Another action</a></li> diff --git a/site/content/docs/5.2/examples/headers/headers.css b/site/content/docs/5.2/examples/headers/headers.css index 8cc52db064..8230c9a5f5 100644 --- a/site/content/docs/5.2/examples/headers/headers.css +++ b/site/content/docs/5.2/examples/headers/headers.css @@ -1,7 +1,3 @@ -body { - padding-top: 5rem; -} - .form-control-dark { border-color: var(--bs-gray); } |