mirror of
https://github.com/twbs/bootstrap.git
synced 2025-02-19 16:54:24 +01:00
fix tests & re-set position
This commit is contained in:
parent
e428013c4c
commit
45c62bddcc
@ -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 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'
|
||||||
const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`
|
const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`
|
||||||
const SELECTOR_MENU = '.dropdown-menu'
|
const SELECTOR_MENU = '.dropdown-menu'
|
||||||
const SELECTOR_NAVBAR_NAV = '.navbar-nav'
|
|
||||||
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
|
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
|
||||||
|
|
||||||
const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'
|
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] ||
|
this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] ||
|
||||||
SelectorEngine.prev(this._element, SELECTOR_MENU)[0] ||
|
SelectorEngine.prev(this._element, SELECTOR_MENU)[0] ||
|
||||||
SelectorEngine.findOne(SELECTOR_MENU, this._parent)
|
SelectorEngine.findOne(SELECTOR_MENU, this._parent)
|
||||||
this._inNavbar = this._detectNavbar()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
@ -141,7 +139,7 @@ class Dropdown extends BaseComponent {
|
|||||||
// empty mouseover listeners to the body's immediate children;
|
// empty mouseover listeners to the body's immediate children;
|
||||||
// only needed because of broken event delegation on iOS
|
// only needed because of broken event delegation on iOS
|
||||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
// 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)) {
|
for (const element of [].concat(...document.body.children)) {
|
||||||
EventHandler.on(element, 'mouseover', noop)
|
EventHandler.on(element, 'mouseover', noop)
|
||||||
}
|
}
|
||||||
@ -304,15 +302,20 @@ class Dropdown extends BaseComponent {
|
|||||||
{
|
{
|
||||||
name: 'applyCustomStyles',
|
name: 'applyCustomStyles',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
phase: 'afterWrite',
|
phase: 'beforeRead',
|
||||||
fn: () => {
|
fn: ({ state, instance }) => {
|
||||||
this._menu.style.removeProperty('position')
|
this._menu.style.removeProperty('position')
|
||||||
const initialPosition = getComputedStyle(this._menu).position
|
const initialPosition = getComputedStyle(this._menu).position
|
||||||
if (this._config.display === 'static' || initialPosition === 'static') {
|
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?
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
@ -1093,7 +1093,7 @@ describe('Dropdown', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('update', () => {
|
describe('update', () => {
|
||||||
it('should call Popper and detect navbar on update', () => {
|
it('should call Popper on update', () => {
|
||||||
fixtureEl.innerHTML = [
|
fixtureEl.innerHTML = [
|
||||||
'<div class="dropdown">',
|
'<div class="dropdown">',
|
||||||
' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
|
' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
|
||||||
@ -1111,33 +1111,10 @@ describe('Dropdown', () => {
|
|||||||
expect(dropdown._popper).not.toBeNull()
|
expect(dropdown._popper).not.toBeNull()
|
||||||
|
|
||||||
const spyUpdate = spyOn(dropdown._popper, 'update')
|
const spyUpdate = spyOn(dropdown._popper, 'update')
|
||||||
const spyDetect = spyOn(dropdown, '_detectNavbar')
|
|
||||||
|
|
||||||
dropdown.update()
|
dropdown.update()
|
||||||
|
|
||||||
expect(spyUpdate).toHaveBeenCalled()
|
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', () => {
|
it('should not collapse the dropdown when clicking a select option nested in the dropdown', () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = [
|
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 => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = [
|
fixtureEl.innerHTML = [
|
||||||
'<nav class="navbar navbar-expand-md bg-light">',
|
'<nav class="navbar navbar-expand-md bg-light">',
|
||||||
' <div class="dropdown">',
|
' <div class="dropdown">',
|
||||||
' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
|
' <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>',
|
' <a class="dropdown-item" href="#">Secondary link</a>',
|
||||||
' </div>',
|
' </div>',
|
||||||
' </div>',
|
' </div>',
|
||||||
@ -1273,8 +1223,13 @@ describe('Dropdown', () => {
|
|||||||
const dropdown = new Dropdown(btnDropdown)
|
const dropdown = new Dropdown(btnDropdown)
|
||||||
|
|
||||||
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
||||||
expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
|
setTimeout(() => {
|
||||||
dropdown.hide()
|
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', () => {
|
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 => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = [
|
fixtureEl.innerHTML = [
|
||||||
'<div class="dropdown">',
|
'<div class="dropdown">',
|
||||||
@ -1302,7 +1257,51 @@ describe('Dropdown', () => {
|
|||||||
|
|
||||||
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
||||||
// Popper adds this attribute when we use it
|
// Popper adds this attribute when we use it
|
||||||
|
|
||||||
expect(dropdownMenu.getAttribute('data-popper-placement')).toBeNull()
|
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()
|
resolve()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1326,8 +1325,10 @@ describe('Dropdown', () => {
|
|||||||
const dropdown = new Dropdown(btnDropdown)
|
const dropdown = new Dropdown(btnDropdown)
|
||||||
|
|
||||||
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
||||||
expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
|
setTimeout(() => {
|
||||||
dropdown.hide()
|
expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
|
||||||
|
dropdown.hide()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
btnDropdown.addEventListener('hidden.bs.dropdown', () => {
|
btnDropdown.addEventListener('hidden.bs.dropdown', () => {
|
||||||
@ -1974,7 +1975,7 @@ describe('Dropdown', () => {
|
|||||||
const dropdown = new Dropdown(triggerDropdown)
|
const dropdown = new Dropdown(triggerDropdown)
|
||||||
const button = fixtureEl.querySelector('button[data-bs-toggle="dropdown"]')
|
const button = fixtureEl.querySelector('button[data-bs-toggle="dropdown"]')
|
||||||
|
|
||||||
const spy = spyOn(dropdown, 'toggle')
|
spyOn(dropdown, 'toggle')
|
||||||
|
|
||||||
// Key escape
|
// Key escape
|
||||||
button.focus()
|
button.focus()
|
||||||
@ -1984,7 +1985,7 @@ describe('Dropdown', () => {
|
|||||||
button.dispatchEvent(keydownEscape)
|
button.dispatchEvent(keydownEscape)
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(spy).not.toHaveBeenCalled()
|
expect(dropdown.toggle).not.toHaveBeenCalled()
|
||||||
expect(triggerDropdown).not.toHaveClass('show')
|
expect(triggerDropdown).not.toHaveClass('show')
|
||||||
resolve()
|
resolve()
|
||||||
}, 20)
|
}, 20)
|
||||||
|
@ -10,6 +10,68 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Dropdown <small>Bootstrap Visual Test</small></h1>
|
<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">
|
<nav class="navbar navbar-expand-md bg-light">
|
||||||
<a class="navbar-brand" href="#">Navbar</a>
|
<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">
|
<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>
|
<a class="nav-link" href="#">Link</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<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">
|
<ul class="dropdown-menu">
|
||||||
<li><a class="dropdown-item" href="#">Action</a></li>
|
<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>
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
body {
|
|
||||||
padding-top: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control-dark {
|
.form-control-dark {
|
||||||
border-color: var(--bs-gray);
|
border-color: var(--bs-gray);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user